I'm looking for a smooth way to assign a Vector3D[] array using LINQ (and not looping). Is this possible?
I'm new to LINQ methods and I just started figuring out how to assign a whole array in a single line of code. For example:
double[] angle_in_radians = angle_in_degrees .Select(x => x / 180 * Math.PI).ToArray();
Suppose now I have the angle_in_radians array above and I want to use it in a vector3D array:
Vector3D[] example_vector = new Vector3D[n];
the way I solve the problem today is using a for loop:
for (int i = 0; i < n; i++)
{
example_vector[i] = new Vector3D(Math.Cos(angle_in_radians[i]), Math.Sin(angle_in_radians[i]), 0);
}
I can't really figure out how to use linq (if it's even possible). I want to somehow put:
angle_in_radians.Select(x => Math.Cos(x)).ToArray();
in all of the Vector3D X positions and the same with Y and Z.
You could replace a for loop by linq select like that :
var example_vectors = angle_in_radians.Select(x => new Vector3D(Math.Cos(x), Math.Sin(x), 0);
Related
I want to perform a point-wise multiplication of a column array with each column array/vector in a given Matrix in C# using the Math.Net Numerics library.
There is little documentation on operations like this, so far I have the code below which doesn't work. I am trying to use LINQ as I prefer that over for loops. the problem I'm having with LINQ is I can't reassign my matrix when I try to enumerate each column of my matrix as a vector and do the PointwiseMultiply() method.
Matrix fitKernel is my matrix, and I want to point-wise multiply each column by the wF column array and update my matrix fitKernel using LINQ. fitKernel is 9 x 5 Matrix, and wF is a 9 x 1 double[] array that I convert to a Vector in the LINQ below.
Matrix<double> fitKernel = Matrix<double>.Build.DenseOfColumnArrays(c1, c2, c3, c4, ones);
double[] wF = Enumerable.Repeat(1.0, 9).ToArray();
fitKernel = fitKernel.EnumerateColumns()
.Select(v => v.PointwiseMultiply(Vector<double>.Build.DenseOfArray(wF)));
The above code using the EnumerateColumns() returns an IEnumerable of vectors, but when I try to assign the value to fitKernel it complains about assigning a type of Enumerable to a Matrix.
If you are going to write a for loop, you might as well write two.
// a = double[9];
// c = Matrix<double>
for (int ic = 0; ic < c.ColumnCount; ic++)
{
for (int ir = 0; ir < c.RowCount; ir++) c[ir, ic] = a[ir] * c[ir, ic];
}
It's probably the quickest and briefest solution, but I understand it doesn't tell the reader what you have in mind. OTOH, if you going to use an enumerator, it makes sense to let it control the loop.
var va = Vector<double>.Build.DenseOfArray(a);
var ColEnum = c.EnumerateColumnsIndexed() ;
foreach (System.Tuple<int,Vector<double>> col in ColEnum)
{
Vector<double> v = (Vector<double>)col.Item2.PointwiseMultiply((Vector<double>)va);
c.SetColumn(col.Item1, v);
}
The closest I could get to your first formulation is this:
var r = c.EnumerateColumns().Select(v => v.PointwiseMultiply(va));
int i = 0;
foreach (Vector ri in r) c.SetColumn(i++, ri);
The first line returns your new columns, but you still have to insert them into your Matrix. Note that we are trusting the enumerator to bring back the columns in their natural order. It's possible to reduce this to two lines using EnumerateColumnsIndexed. It requires more detail, but eliminates possible ambiguity about column order.
By the way, it does not work to combine the PointwiseMultiply and the SetColumn in one statement like this:
var r = c.EnumerateColumnsIndexed().Select((v) => c.SetColumn(v.Item1, v.Item2.PointwiseMultiply(va)));
apparently because SetColumn is void. If anyone has a workaround, please post it.
I think I figured it out but you have to use a for loop; doesn't seem to be any easy way using LINQ:
for (int i = 0; i < fitKernel.ColumnCount; i++)
{
var v = fitKernel.Column(i);
v = v.PointwiseMultiply(Vector<double>.Build.DenseOfArray(wF));
fitKernel.SetColumn(i, v);
}
I'm trying to create a empty array of points, for this i'm using the following
Point[] listapontos = new[]; //should create a empty point array for later use but doesn't.
Point ponto = new Point(); //a no coordinates point for later use
for (int i = 1; i <= 100; i++) //cycle that would create 100 points, with X and Y coordinates
{
ponto.X = i * 2 + 20;
ponto.Y = 20;
listapontos[i] = ponto;
}
I'm having some trouble, because I can't create a empty array of points. I could create a empty array of strings using a list, but since i will need two elements, a list isn't useful here.
Any hints? (hints for the problem are also welcome)
// should create a empty point array for later use but doesn't.
No, what you've specified just isn't valid syntax. If you want an empty array, you could use any of:
Point[] listapontos = new Point[0];
Point[] listapontos = new Point[] {};
Point[] listapontos = {};
However, then you've got an array with 0 elements, so this statement:
listapontos[i] = ponto;
... will then throw an exception. It sounds like you should either use a List<Point>, or create an array of size 101:
Point[] listapontos = new Point[101];
(Or create an array of size 100, and change the indexes you use - currently you're not assigning anything to index 0.)
It's important to understand that in .NET, an array object doesn't change its size after creation. That's why it's often convenient to use List<T> instead, which wraps an array, "resizing" (by creating a new array and copying values) when it needs to.
I could create a empty array of strings using a list, but since i will
need two elements, a list isn't useful here.
You can define a class like this:
public class Point
{
public double X {get;set;}
public double Y {get;set;}
}
Then you can use a List<Point>:
List<Point> points = new List<Point>();
points.Add(new Point(){X=10, Y=20});
The reason this doesn't work is 2-fold.
Firstly, when you say
Point[] listapontos = new[];
you are using invalid syntax. It should be more like
Point[] listapontos = new Point[100];
Now, secondly, when you are writing into the array, you are never creating a new point.
Point is a class, which means it is passed by reference. This means that whenever you are writing Ponto's address in, but not a new Ponto.
Instead what you should do is something more like
for(int i = 0; i < 100; i++)
{
listapontos[i] = new Point(i * 2 + 20, 20);
}
By using the new keyword, you are creating a new point in memory and storing that point's address in the array, instead of writing the address to the same point 100 times into the array.
To process data from a log file, I read the data into a list.
When I tried to convert from the list to an array for the graphing routine, I ran into trouble.
For the sake of this discussion, let's say the log file contains three values* - x, y and theta. In the routine that does file I/O, I read the three values, assign them to a struct and add the struct to PostureList.
The plotting routine, wants the x, y and theta to be in individual arrays. My thought was to use the ToArray() method to do the conversion but when I tried the syntax below, I got an error - see error in comment below. I have an alternate approach to do the conversion but wanted to get advice on better approaches.
I'm very new to C#. Thanks in advance for your help.
NOTE: * In reality, the log file contains many different pieces of information that have varying payload sizes.
struct PostureStruct
{
public double x;
public double y;
public double theta;
};
List<PostureStruct> PostureList = new List<PostureStruct>();
private void PlotPostureList()
{
double[] xValue = new double[PostureList.Count()];
double[] yValue = new double[PostureList.Count()];
double[] thetaValue = new double[PostureList.Count()];
// This syntax gives an error:
// Error 1 'System.Collections.Generic.List<TestNameSpace.Test.PostureStruct>'
// does not contain a definition for 'x' and no extension method 'x' accepting a first
// argument of type 'System.Collections.Generic.List<TestNameSpace.Test.PostureStruct>'
// could be found (are you missing a using directive or an assembly reference?)
xValue = PostureList.x.ToArray();
yValue = PostureList.y.ToArray();
thetaValue = PostureList.theta.ToArray();
// I could replace the statements above with something like this but I was wondering if
// if there was a better way or if I had some basic mistake in the ToArray() syntax.
for (int i = 0; i < PostureList.Count(); i++)
{
xValue[i] = PostureList[i].x;
yValue[i] = PostureList[i].y;
thetaValue[i] = PostureList[i].theta;
}
return;
}
The ToArray extension method can only be used on IEnumerables. To transform an IEnumerable, for example from your struct to a single value, you can use the Select extension method.
var xValues = PostureList.Select(item => item.x).ToArray();
var yValues = PostureList.Select(item => item.y).ToArray();
var thetaValues = PostureList.Select(item => item.theta).ToArray();
You don't need to define the size of the arrays or create them with new, the extension method will take care of that.
you are trying to reference x directly on list.
PostureList.y
you need to do it on specific member like
PostureList[0].y
i guess you need to select all the x from your list. For that you can do this
xValue = PostureList.Select(x => x.x).ToArray();
You can use this way to convert your List<PostureStruct> to individual arrays:
double[] xValue = PostureList.Select(a => a.x).ToArray();
double[] yValue = PostureList.Select(a => a.y).ToArray();
double[] thetaValue = PostureList.Select(a => a.theta).ToArray();
This is all you have to do and the arrays will have the right size (same as the list's lenght).
You can either loop through the list:
double[] xValue = new double[PostureList.Count()];
double[] yValue = new double[PostureList.Count()];
double[] thetaValue = new double[PostureList.Count()];
foreach (int i = 0; i < PostureList.Count; ++i) {
xValue[i] = PostureList[i].x;
yValue[i] = PostureList[i].y;
thetaValue[i] = PostureList[i].theta;
}
...
Or use Linq, but in different manner:
double[] xValue = PostureList.Select(item => item.x).ToArray();
double[] yValue = PostureList.Select(item => item.y).ToArray();
double[] thetaValue = PostureList.Select(item => item.theta).ToArray();
...
Working on a clustering project, I stumbled upon this, and I'm trying to figure out if there's a better solution than the one I've come up with.
PROBLEM : Given a List<Point> Points of points in R^n ( you can think at every Point as a double array fo dimension n), a double minDistance and a distance Func<Point,Point,double> dist , write a LINQ expression that returns, for each point, the set of other points in the list that are closer to him than minDistance according to dist.
My solution is the following:
var lst = Points.Select(
x => Points.Where(z => dist(x, z) < minDistance)
.ToList() )
.ToList();
So, after noticing that
Using LINQ is probably not the best idea, because you get to calculate every distance twice
The problem doesn't have much practical use
My code, even if bad looking, works
I have the following questions:
Is it possible to translate my code in query expression? and if so, how?
Is there a better way to solve this in dot notation?
The problem definition, that you want "for each point, the set of other points" makes it impossible to solve without the inner query - you could just disguise it in clever manner. If you could change your data storage policy, and don't stick to LINQ then, in general, there are many approaches to Nearest Neighbour Search problem. You could for example hold the points sorted according to their values on one axis, which can speed-up the queries for neighbours by eliminating early some candidates without full distance calculation. Here is the paper with this approach: Flexible Metric Nearest Neighbor Classification.
Because Points is a List you can take advantage of the fact that you can access each item by its index. So you can avoid comparing each item twice with something like this:
var lst =
from i in Enumerable.Range(0, Points.Length)
from j in Enumerable.Range(i + 1, Points.Length - i - 1)
where dist(Points[i], Points[j]) < minDistance
select new
{
x = Points[i], y = Points[j]
};
This will return a set composed of all points within minDistance of each other, but not exactly what the result you wanted. If you want to turn it into some kind of Lookup so you can see which points are close to a given point you can do this:
var lst =
(from i in Enumerable.Range(0, Points.Length)
from j in Enumerable.Range(i + 1, Points.Length - i - 1)
where dist(Points[i], Points[j]) < minDistance
select new { x = Points[i], y = Points[j] })
.SelectMany(pair => new[] { pair, { x = pair.y, y = pair.x })
.ToLookup(pair => pair.x, pair => pair.y);
I think you could add some bool Property to your Point class to mark it's has been browsed to prevent twice calling to dist, something like this:
public class Point {
//....
public bool IsBrowsed {get;set;}
}
var lst = Points.Select(
x => {
var list = Points.Where(z =>!z.IsBrowsed&&dist(x, z) < minDistance).ToList();
x.IsBrowsed = true;
return list;
})
.ToList();
Basically I have x amount of matrices I need to establish of y by y size. I was hoping to name the matrices: matrixnumber1 matrixnumber2..matrixnumbern
I cannot use an array as its matrices I have to form.
Is it possible to use a string to name a string (or a matrix in this case)?
Thank you in advance for any help on this!
for (int i = 1; i <= numberofmatricesrequired; i++)
{
string number = Convert.ToString(i);
Matrix (matrixnumber+number) = new Matrix(matrixsize, matrixsize);
}
You can achieve a similar effect by creating an array of Matrices and storing each Matrix in there.
For example:
Matrix[] matrices = new Matrix[numberofmatricesrequired];
for (int i = 0; i < numberofmatricesrequired; i++)
{
matrices[i] = new Matrix(matrixsize, matrixsize);
}
This will store a bunch of uniques matrices in the array.
If you really want to you could create a Dictionary<String, Matrix> to hold the matrices you create. The string is the name - created however you like.
You can then retrieve the matrix by using dict["matrix1"] (or whatever you've called it).
However an array if you have a predetermined number would be far simpler and you can refer to which ever you want via it's index:
Matrix theOne = matrix[index];
If you have a variable number a List<Matrix> would be simpler and if you always added to the end you could still refer to individual ones by its index.
I'm curious why you cannot use an array or a List, as it seems like either of those are exactly what you need.
Matrix[] matrices = new Matrix[numberofmatricesrequired];
for (int i = 0; i < matrices.Length; i++)
{
matrices[i] = new Matrix(matrixsize, matrixsize);
}
If you really want to use a string, then you could use a Dictionary<string, Matrix>, but given your naming scheme it seems like an index-based mechanism (ie. array or List) is better suited. Nonetheless, in the spirit of being comprehensive...
Dictionary<string, Matrix> matrices = new Dictionary<string, Matrix>();
for (int i = 1; i <= numberofmatricesrequired; i++)
{
matrices.Add("Matrix" + i.ToString(), new Matrix(matrixsize, matrixsize));
}