This question already has answers here:
How to populate/instantiate a C# array with a single value?
(26 answers)
All possible array initialization syntaxes
(19 answers)
Closed 9 years ago.
I need to initialize an array of three points.
I want to write it like below, but only once for three elements.
Point P = new Point { X = 0, Y = 1 };
Point[] P = new Point[3];// <---- ?
How to write correctly?
Here is the code for creating the array of 3 different points:
Point[] points = new Point[] { new Point { X = 0, Y = 1 }, new Point { X = 2, Y = 1 }, new Point { X = 0, Y = 3 } };
There’s not really a shorthand for that. For three, just write it three times:
Point initial = new Point { X = 0, Y = 1 };
Point[] P = new Point[3] { initial, initial, initial };
Example below you can create 10 Point using Enumerable.Range
var points = Enumerable.Range(0, 10)
.Select(x => new Point {X = 0, Y = 1})
.ToArray();
Because you question deals about a static fixed length array of point with static coordinates, no needs to bother with LINQ and loops in this context when array initialization is that simple.
So you can initialize an array this way:
Point[] P = new Point[]
{
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
...
};
or use duck typing type inference (thanks minitech):
var P = new []
{
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
new Point { X = 0, Y = 1 },
...
};
Here is the shortest solution:
Point[] points = Enumerable.Repeat<Point>(new Point(0, 1), 3).ToArray();
Related
I am looking for the shortest way in terms of writing to declare an array of points.
My problem is that I have humongous point data that I want to hardcode as an initialization.
These initializations repeat the 'new Point' multiple times:
Point[] points1 = new[] { new Point { X = 0, Y = 0 }, new Point { X = 20, Y = 120 }, new Point { X = 40, Y = 60 }, }; // kinda long typing
Point[] points2 = { new Point(0, 0), new Point(20, 120), new Point(40, 60) }; // better
Alternatively I could declare the array like so:
int[,] arr = new int[,] { { 0, 0 }, { 20, 120 }, { 40, 60 } }; // so far shortest typing
But how can I cast int[,] to Point[] ?
Are there other alternatives (like using lists) ?
You can change new[] to new Point[]. This way, you can use target-typed new in the array elements:
Point[] points1 = new Point[] {
new() { X = 0, Y = 0 },
new() { X = 20, Y = 120 },
new() { X = 40, Y = 60 },
};
If Point has a 2-parameter constructor, this can be even shorter:
Point[] points1 = new Point[] {
new(0, 0),
new(20, 120),
new(40, 160)
};
If points1 is a local variable, you can make it even shorter by making the variable implicitly typed:
var points1 = new Point[] {
new(0, 0),
new(20, 120),
new(40, 160)
};
If you want to make this really short in the long run, you can make a (int, int)[], then convert to Point[]:
Point[] points1 = new[] {
(0, 0),
(20, 120),
(40, 160)
}.Select(x => new Point(x.Item1, x.Item2)).ToArray();
Definitely not the shortest way, But this approach has its own advantages. and it's only a one-time effort.
Making it configuration-driven will help in modifying the points. if in future you want to add/delete/modify points. It will help you in testing and also provide different02 points.
second, you can manage different points based on the environment as well.
public class Point
{
public int X { get; set; }
public int Y { get; set; }
}
public class Root
{
public Point[] Points { get; set; }
}
string json = File.ReadAllText("inut.json");
Root obj = JsonConvert.DeserializeObject<Root>(json); //Use NewtonSoft.json library to deserialize the JSON to object.
Sample JSON:
{
"Points": [{
"X": 0,
"Y": 0
},
{
"X": 10,
"Y": 20
}
]
}
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 });
I have three lists which each list represents only 0s and 1s which related to the pixel values of three images.
My question is how can I get the sum (average) of those three lists and represent it in a new list?
here is example of my image1:
List<int> image1 = new List<int>();
int blackColor = 0;
for (int x = 0; x < bmp1.Width; x++)
{
for (int y = 0; y < bmp1.Height; y++)
{
Color color = bmp1.GetPixel(x, y);
if (color.ToArgb() == Color.Black.ToArgb())
{
image1.Add(0);
blackColor++;
}
else
{
image1.Add(1);
}
}
}
Let me makes sure I understand the problem. You have three lists of the same length:
list A: 1, 2, 4, 3
list B: 3, 2, 4, 1
List C: 2, 7, 1, 8
and you wish to get a third list that is the average of each:
List D: 2, 4, 3, 4
Yes?
This is a job for zip join.
var sumOfFirstTwo = list1.Zip(list2, (x, y)=>x + y);
sumOfFirstTwo is now the sequence that is the sum of the first two lists.
var sumOfAllThree = sumOfFirstTwo.Zip(list3, (x, y)=>x + y);
sumOfAllThree is now the sequence that is the sum of all three lists.
var average = sumOfAllThree.Select(x=>x/3).ToList();
Make sense?
This works for an arbitrary number of lists
var firstList = new[] { 1, 2, 3, 1 };
var secondList = new[] { 2, 3, 1, 1 };
var thirdList = new[] { 3, 1, 2, 2 };
var lists = new[] { firstList, secondList, thirdList };
var listLengths = lists.Select(x => x.Count());
if (listLengths.Distinct().Count() != 1)
throw new Exception("Line lengths must be the same");
var lengthOfEachList = listLengths.First();
var averages = new List<double>();
for (var i = 0; i != lengthOfEachList; ++i) {
averages.Add(lists.Average(x => x[i]));
}
The LINQ way would be
var averages = Enumerable.Range(0, lengthOfEachList).Select(x => lists.Average(y => y[x]));
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);
I have a list of lists that I have created from a "tab" delimited string. Instead of a 2d array i use list of lists as I dont know the size to create the array.
It will be something like,
0 0
16.0000 0
15.0000 15.0000
0 15.0000
2.7217 5.6904
3.7217 5.6904
I now want to find the maximum and minimum from each of the columns.
So if you take the above example,
maximum would be : 16.0000 15.0000
and minimum would be : 0 0
for (int i = 0; i < size[0]; i++)
{
// Create size[0] x size[1] array
obstVertex.Add(new List<double>());
for (int y = 0; y < size[1]; y++)
{
obstVertex[i].Add(Convert.ToDouble(split[i+(y*size[0])]));
}
}
How can I find the maximum or the minimum value using linq ???
Thanks in advance
List<List<double>> myList;
myList.Add(new List(new double[] { 0, 16, 15, 0, 2.7217, 3.7217 }));
myList.Add(new List(new double[] { 0, 0, 15, 15, 5.6904, 5.6904 }));
List<double> maxList = myList.Select(l => l.Max()).ToList();
List<double> minList = myList.Select(l => l.Min()).ToList();
Try the following:
class Program
{
static void Main(string[] args)
{
var l = new List<List<double>>() {new List<Double>() {0, 16.0000, 15.0000, 0, 2.7217, 3.7217},
new List<Double>() {0, 0, 15.0000, 15.0000, 5.6904, 5.6904}};
int i = 1;
var result = from sublist in l
select new { min = sublist.Min(), max = sublist.Max(), index = i++ };
foreach (var r in result)
Console.WriteLine(String.Format("Index: {0} Min: {1} Max: {2}",r.index, r.min, r.max));
Console.ReadKey();
}
}
It will get the min- and max-value for each sub-list in the list of lists.
I assume obstVertex is declared like this:
List<List<double>> obstVertex;
Then you can do this
var minima = Enumerable.Range(0, obstVertex[0].Count - 1)
.Select (colIndex => obstVertex.Select(row => row[colIndex]).Min())
to get all the minimum values of each column.
static void Main(string[] args)
{
List<List<double>> lists = new List<List<double>>() {
new List<double>(){0 , 0 } ,
new List<double>(){16.0000 , 0 } ,
new List<double>(){16.0000 , 15.0000 } ,
new List<double>(){0 , 15.0000 } ,
new List<double>(){2.7217 , 5.6904 } ,
new List<double>(){3.7217 , 5.6904 }
};
var r = new {
col1_max = (from x in lists select x[0]).Max(),
col1_min = (from x in lists select x[0]).Min(),
col2_max = (from x in lists select x[1]).Max(),
col2_min = (from x in lists select x[1]).Min(),
};
Console.WriteLine(string.Format("col1_max = {0}\r\ncol1_min = {1}\r\ncol2_max = {2}\r\ncol3_max = {3}", r.col1_max , r.col1_min , r.col2_max , r.col2_min));
Console.Read();
}