Is there a good way to map vectors? Here's an example of what I mean:
vec0 = [0,0,0,0,0,0,0,0,0,0,0]
vec1 = [1,4,2,7,3,2]
vec2 = [0,0,0,0,0,0,0,0,0]
vec2 = [7,2,7,9,9,6,1,0,4]
vec4 = [0,0,0,0,0,0]
mainvec =
[0,0,0,0,0,0,0,0,0,0,0,1,4,2,7,3,2,0,0,0,0,0,0,0,0,0,7,2,7,9,9,6,1,0,4,0,0,0,0,0,0]
Lets say mainvec doesn't exist (I'm just showing it to you so you can see the general data structure in mind.
Now say I want mainvec(12) which would be 4. Is there a good way to map the call of these vectors without just stitching them together into a mainvec? I realize I could make a bunch of if statements that test the index of mainvec and I can then offset each call depending on where the call is within one of the vectors, so for instance:
mainvec(12) = vec1(1)
which I could do by:
mainvec(index)
if (index >=13)
vect1(index-11);
I wonder if there's a concise way of doing this without if statements. Any Ideas?
Are you looking for something like this?
using System.Collections.Generic;
namespace Test
{
class Program
{
static void Main(string[] args)
{
int[] vec0 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] vec1 = { 1, 4, 2, 7, 3, 2 };
int[] vec2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] vec3 = { 7, 2, 7, 9, 9, 6, 1, 0, 4 };
int[] vec4 = { 0, 0, 0, 0, 0, 0 };
List<int> temp = new List<int>();
temp.AddRange(vec0);
temp.AddRange(vec1);
temp.AddRange(vec2);
temp.AddRange(vec3);
temp.AddRange(vec4);
int[] mainvec = temp.ToArray();
}
}
}
I would create a class that would receive array of lengths, and have a method to give you Array number and Index inside the array for a given index in the combined list.
It would be wrapped by a class that will get references to the actual arrays and an indexer to bring you to the right element.
It looks like your doing basic list concatenation, in which case the Concat function would seem to be the most straight forward way of doing things. In real-live code terms, somethng like:
var vec0 = new[] {0,0,0,0,0,0,0,0,0,0,0};
var vec1 = new[] {1,4,2,7,3,2};
var vec2 = new[] {0,0,0,0,0,0,0,0,0};
var vec3 = new[] {7,2,7,9,9,6,1,0,4};
var vec4 = new[] { 0, 0, 0, 0, 0, 0 };
var mainvec = vec0.Concat(vec1).Concat(vec2).Concat(vec3).Concat(vec4).ToList();
mainvec[12] == 1;
I'm not really sure of the context behind what you are wanting to do, so there may be a more direct way of doing things, but based on what you've got, this seems the simplest to me.
I would use a jagged array.
You still have to have a loop, but you can keep the separate vectors without redundancy:
var mainvec = new int[][]{vec0, vec1, vec2, vec3, vec4};
int desiredInd = 12, totalInd = 0, rowInd = 0, result;
while(rowInd < mainvec.Length && (totalInd + mainvec[rowInd].Length) <= desiredInd)
{
totalInd += mainvec[rowInd++].Length;
}
if(rowInd < mainvec.Length && (desiredInd - totalInd) < mainvec[rowInd].Length)
{
result = mainvec[rowInd][desiredInd - totalInd];
}
Related
I need a map of positive values.
And looking for one-line equivalent of following example:
int[] workplace = new int[]{1, 3, 5, 0, 7, 0, 9, 0, 3, 2, 0, 4};
int map = 0;
for (int i = 0; i < workplace.Length; i++)
map |= workplace[i] > 0 ? 1 << i : 0;
like:
int[] workplace = new int[]{1, 3, 5, 0, 7, 0, 9, 0, 3, 2, 0, 4};
int map = bla bla bla...;
Int32 map = workplace.Select( ( n, idx ) => ( n > 0 ) ? ( 1 << idx ) : 0 ).Aggregate( seed: 0, func: ( agg, n ) => agg | n );
Works for me:
I would suggest that you replace your current map calculation with a method call. By giving the method a descriptive name and clarifying your intention in the method body, I would argue that you are better off than by compressing logic inside a one-liner of code.
One possible approach is:
int[] workplace = new int[] { 1, 3, 5, 0, 7, 0, 9, 0, 3, 2, 0, 4 };
int map = GetPositiveFlagMapFor(workplace);
private static int GetPositiveFlagMapFor(int[] source)
{
int map = 0;
for (int i = 0; i < source.Length; i++)
{
if (source[i] > 0) // Easy to see that we only care about positive numbers
{
map |= 1 << i; // Easy to see what the calculation actually is
}
}
return map;
}
(Without knowing the actual purpose of the map calculation, the suggested method name is most likely not on point, but I trust that you get my intention.)
I'm trying to solve a non square linear system with Math.net.
But I get an error Matrix dimensions must agree: 3x7.
Here is some example code:
using MathNet.Numerics.LinearAlgebra;
var mBuilder = Matrix<double>.Build;
var vBuilder = Vector<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
var b = vBuilder.DenseOfArray(new double[] { -3, -5, -2 });
Vector<double> x;
x = A.Solve(b);
Cleary the system has a solution (e.g. X = {0, 0, 0, 0, 3, 5, 2}).
How can I solve such a system with Math.Net?
You can not use the Matrix.Solve function with a non-square matrix because there is no inverse and no unique solutions for a rectangular matrix. Google "inverse of rectangular matrix" for explanations galore. You can use pseudoinverse however, as shown below.
var mBuilder = Matrix<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
Matrix<double> b = Matrix<double>.Build.Dense(3, 1);
b[0, 0] = -3.0;
b[1, 0] = -5.0;
b[2, 0] = -2.0;
var p = A.PseudoInverse();
var x = p * b;
// verify
var o = A * x;
I am trying to implement in C# the dot product, to do so, I am using Accord.Math and its method Dot as follows:
using Accord.Math;
namespace VectorOperations
{
class DotProduct
{
private static double CalculateDotProduct(Sparse<double> Vector1, Sparse<double> Vector2)
{
double DotProduct = Vector.Dot(Vector1, Vector2);
return DotProduct;
}
}
}
However I am not able to create an example where I can test if it is working correctly fine because I don't know how to create a variable of type Sparse<double>. How could I create one as an example? Ideally, I would like to have:
Sparse<double> Vector1 = new Sparse<double>();
Sparse<double> Vector2 = new Sparse<double>();
// Vector1 = [1, 2, 3];
// Vector2 = [1, 2, 3];
So I can call this.CalculateDotProduct(Vector1, Vector2) and check if it works correctly.
If you know any other method to compute the dotproduct with vectors of type List<double> are welcome too.
The unit tests show a couple of ways to create and fill an instance:
var s = new Sparse<double>();
s[0] = 1;
s[99] = 99;
s[10] = 42;
v = new double[] { 1, 2, 3, 0, 0, 6 };
d = Sparse.FromDense(v);
Another way is using the Sparse(int[] indices, T[] values) constructor:
Sparse<double> Vector1 = new Sparse<double>(new[] { 0, 1, 2 }, new[] { 1, 2, 3 });
My program currently loads a csv file and converts each line to different strings and int values. The problem is, while I can easily convert a simple number, it needs to be able to convert an equation with variables.
My current code for this is -
string[] values = line.Split(new string[] { "," }, StringSplitOptions.None)
.Select(p => p.Trim()).ToArray();
if (values.Length != 8) continue;
var species = new SpeciesClasses()
{
Species = values[0],
Description= values[1],
Strength = int.Parse(values[2]),
Intelligence = int.Parse(values[3]),
Dexerity = int.Parse(values[4]),
Charisma = int.Parse(values[5]),
Endurance = int.Parse(values[6]),
Initiative = int.Parse(values[7]),
};
And my csv file is
Pilot, Trained to handle all vehicle types., 0, 6, 0, 0, 0, 0
Medic, Trained to cure and heal others., 0, 0, 5, 0, 0, 0
Which works fine, now the tricky part is a line like this -
Berzerker, The closer to death this crew gets - the stronger they hit., (15-HP)/4, 0, 0, 0, 0, 0
Focused, Using their mass intellect - this crew can aim more accurately., 0, 0, INTEL, 0, 0, 0
So I not only need to convert the string to an int equation with different variables - in this case an HP and INTEL int.
If int.Parse() fails (btw try int.TryParse(...)) fallback to a more specialized tool:
More info here:
Equation (expression) parser with precedence?
EDIT:
After fixing the syntax error and working with this algorithm I found the MKL provider is not the matrix multiplication needed. This algorithm simply multiplies element by element and does not compute the dot(row_n,column_n) as I had originally thought.
other source
End Edit
I can't get this passed the compiler. I have looked all over for a good example but have come up short. The documentation I'm referencing is MklLinearAlgebraProvider
MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider
I'm trying to write a simple method to compute the rotation matrix R = rz*ry*rx from Euler angles. The problem is the compiler won't take ryXrx or resultMat arrays I'm trying to pass it. I've tried out keyword as well.
inputMat is a 1-D array of the form {x,y,z,rx,ry,rz} where x,y and z are translations and rx,ry and rz are rotation angles in degrees.
private float[,] EulerToHMat(float[] inputMat)
{
var linalg = new MathNet.Numerics.Algorithms.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
double rzRad = ((double)inputMat[5])*Math.PI/180;
double cosZ = Math.Cos(rzRad);
double sinZ = Math.Sin(rzRad);
double ryRad = ((double)inputMat[4])*Math.PI/180;
double cosY= Math.Cos(ryRad);
double sinY = Math.Sin(ryRad);
double rxRad = ((double)inputMat[3])*Math.PI/180;
double cosX= Math.Cos(rxRad);
double sinX = Math.Sin(rxRad);
var rz = new float[,] { { (float)cosZ, -(float)sinZ, 0 }, { (float)sinZ, (float)cosZ , 0 }, {0,0,1 } };
var ry = new float[,] { { (float)cosY , 0 , (float)sinY }, { 0, 1 , 0 }, { -(float)sinY, 0, (float)cosY } };
var rx = new float[,] { {1,0,0 }, {0,(float)cosX,-(float)sinX }, {0,(float)sinX,(float)cosX } };
var ryXrx = new float[3,3];
var resultMat = new float[3, 3];
// won't take the matrix --ryXrx-- here
linalg.MatrixMultiply(ry, 3, 3, rx, 3, 3,ryXrx);
// won't take the matrix --resultMat-- here
linalg.MatrixMultiply(rz, 3, 3, ryXrx, 3, 3,resultMat);
return resultMat;
}
This seems like it should be simple.... Please ignore the casting mess.
According to the reference you linked, the method works on matrices that are stored in a SINGLE-dimensional array, you are trying to pass two-dimensionals.
Try this:
var rz = new float[] { (float)cosZ, -(float)sinZ, 0, (float)sinZ, (float)cosZ, 0, 0, 0, 1 };
var ry = new float[] { (float)cosY, 0, (float)sinY, 0, 1, 0, -(float)sinY, 0, (float)cosY };
var rx = new float[] { 1, 0, 0, 0, (float)cosX, -(float)sinX, 0, (float)sinX, (float)cosX };
int size = 3;
var ryXrx = new float[size * size];
var resultMat = new float[size * size];
// won't take the matrix --ryXrx-- here
linalg.MatrixMultiply(ry, size, size, rx, size, size,ryXrx);