C# reference of 2nd dim array to 1d array - c#

I have a function that can take a 1d array (double[]) as an argument while my source data is a 2d array (double[,]) of 'cnt' number of 3d points, like so
double[,] points = new double[3,cnt]
But what I actually want to do is to pass on each of the three 2nd dim arrays to the function gpu.Average(double[] arg), preferably without having to copy the content of the arrays value[i] by value[i]. Is that possible in C#?
EXAMPLE CODE
This works:
double[] points1d = new double[cnt];
// ... fill points1d with data, then
double a = gpu.Average(points1d); // <- Alea.gpu.Average() accepts a 1d array
But as said, I want to pass on the second dimension to the function gpu.Average() whithout having to run for-loops three times to copy into 1d arrays:
double[,] points2d = new double[3,cnt];
// ... fill points2d with 'cnt' items of data and
// then pass it on
double x = gpu.Average(points2d[0,??]); // How to pass on 2nd dim?
double y = gpu.Average(points2d[1,??]);
double z = gpu.Average(points2d[2,??]);
Is this possible without having to copy the data into 1d arrays?
(BTW, calculating average is not a good example use of gpu parallel library, this is just a test case comparing execution times for different data types & structures).
// Rolf

No this is not possible in managed code without copying the contents of e.g. points2d[1,*] to a new single dimensional array.
In managed code every array has to know its length, so that every index access can be checked and ArrayIndexOutOfBounds exception thrown if the index is out of bounds. The length (integer value) is stored before the first element of the array, so that the runtime knows where to find it. Now with this I guess one can see why you cannot split array into several parts and treat those as new arrays. Note that the story is even more complicated for multidimensional arrays, which have to store the number of dimensions and the size of each dimension...
What you can do is to use jagged array:
double[][] points2d = new double[3][];
points2[0] = new double[cnt];
...
gpu.Average(points2d[0]);
Jagged arrays are faster than multidimensional arrays and are recommended to be used instead of multidimensional arrays even by MS.

Related

In C#, Procedure that modifies incoming array by reversing it?

I've been trying to find a solution to this problem in particular.
Write a procedure that modifies the incoming array of ints by reversing it. Because this is a procedure, it will not return anything. Instead, I will have to modify the array directly, and because arrays are reference type variables, the array will be permanently changed even after this procedure. To reverse an array, imagine the array with an imaginary line in the middle of it, and then swap the numbers on the left with the numbers on the right side.
At the moment, this is the only code I've written down for the problem. Based on the code I've written so far, I don't think I'm approaching it towards the correct solution for it.
public void Test10(int[] numbers)
{
for (int i = 0; i < numbers.Length; i++)
{
}
You could use built-in Array.Reverse method, which reverses the sequence of the elements in the entire one-dimensional Array.
Array.Reverse(array); // reverse supplied array
Please note, System.Array.Reverse() does in place transformation.
There are 2 options based on your preference and need
int[] array = {1,3};
Array.Reverse(array);
This will reverse the original array
int[] array = {1,3};
var reversedArray = array.Reverse().ToArray();
This will use linq and new reversed array will be returned and original array will remain as it is

Maximum array dimension like a[1][1][1][1]....[1] in C#

I just saw this question and infact tried to answer it as well. But while answering I thought what could be the answer in case of C#? I am looking for some MSDN doc or any relevant source like in Java
What is the maximum dimension allowed for an array in C# like a[1][1][1][1]....[1]. I tried to search on SO but was not able to find.
The best I got up to was that "An array could theoretically have at most 2,147,483,647 elements, since it uses an int for indexing."
Also I am aware of the fact that Maximum Size that an Array can hold is
System.Int32.MaxValue
Kindly do let me know if this is a duplicate I will delete my question.
The limit is 32. I checked it with the code:
var b = Array.CreateInstance(typeof (int), new int[32]);
var a = Array.CreateInstance(typeof (int), new int[33]);
It applies for both 64 and 32-bit targeted applications.
Actually, I needn't have googled it. Straight from MSDN:
An element is a value in an Array. The length of an Array is the total number of elements it can contain. The rank of an Array is the number of dimensions in the Array. The lower bound of a dimension of an Array is the starting index of that dimension of the Array; a multidimensional Array can have different bounds for each dimension. An array can have a maximum of 32 dimensions.
About jagged arrays
However, I just noticed that the syntax you used in your edit (and also the syntax Peter used in the comments below) isn't how multi-dimensional arrays are defined in C#. Multi-dimensional arrays are defined as:
int[,,,] arr = new int[0,0,0];
And they are arrays of regular integers, that happen to have multiple dimensions. The syntax:
int[][][] = new int[0][][];
Defines something that in C# is called a jagged array. Jagged arrays are just regular, single-dimensional arrays that happen to have other arrays as elements. You can have multi-dimensional arrays of jagged arrays, or the other way around, as the MSDN article points out.
They are treated differently, however. Jagged arrays are just arrays of (effectiely) regular* objects, and as such, aren't regulated in the same way as multi-dimensional arrays. There is no theoretical limit to the number of "dimensions" a jagged array can have, and in fact the CLR happily let me run the following code:
Array arr = new int[0];
for (int i = 0; i < Int32.MaxValue - 1; i++) {
var newArr = Array.CreateInstance(arr.GetType(), 1);
newArr.SetValue(arr, 0);
arr = newArr;
}
Right up until my system became completely unresponsive and crashed. No exception was thrown.
Limiting the loop to 1000 iterations, you find that the type of the resulting array is:
System.Int32[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]...
In addition, although I can't find a source for this, the number of dimensions a jagged array can have probably isn't even limited by the single object memory limitation, because each array only has references to objects. For example, a jagged array of (eventually) Int32 with a nesting factor of, say, 1000 and 2 elements per array, would take up a negligible amount of memory (that is, on its own), but all the arrays combined would take up an exponential amount.
* With a little bit of syntax sugar. A more syntactically correct way of encoding jagged arrays would be: int[][] arr = new int[][0]; because int[] is the element type.
It's implementation defined
The number of dimensions an array can have appears to be implementation-defined. The number doesn't appear anywhere in the CLI specification, and the code provided by Peter below runs fine on Ideone's mono-2.8, where it appears the limit is 255.

Array written as name[x, y] rather than name[x][y] [duplicate]

This question already has answers here:
Differences between a multidimensional array "[,]" and an array of arrays "[][]" in C#?
(12 answers)
Closed 9 years ago.
What is the difference between the two syntaxes?
The first one is a multi dimensional array while the second is a jagged array. You can take a look at this question to get a description of the diffrerence between the two, but here is an important snippit:
A multidimensional array creates a nice linear memory layout while a
jagged array implies several extra levels of indirection.
Looking up the value jagged[3][6] in a jagged array var jagged = new
int[10][5] works like this: Look up the element at index 3 (which is
an array) and look up the element at index 6 in that array (which is a
value). For each dimension in this case, there's an additional look up
(this is an expensive memory access pattern).
A multidimensional array is laid out linearly in memory, the actual
value is found by multiplying together the indexes. However, given the
array var mult = new int[10,30] the Length property of that
multidimensional array returns the total number of elements i.e. 10 *
30 = 300.
The Rank property of a jagged array is always 1, but a
multidimensional array can have any rank. The GetLength method of any
array can be used to get the length of each dimension. For the
multidimensional array in this example mult.GetLength(1) returns 30.
Indexing the multidimensional array is faster e.g. given the
multidimensional array in this example mult[1,7] = 30 * 1 + 7 = 37,
get the element at that index 37. This is a better memory access
pattern because only one memory location is involved, which is the
base address of the array.
A multidimensional array therefore allocates a continuous memory
block, while a jagged array does not have to be square like. e.g.
jagged1.Length does not have to equal jagged[2].Length which would
be true for any multidimensional array.
Update:
One major difference between the multi and jagged array is that a multi must always be "square", meaning that any two indexes will have the same number of elements in their child arrays. A jagged array does not have this requirement. Take a look at the code below:
var jagged = new int[3][]; //not defining the size of the child array...
var multi = new int[3,8]; //defining a 3x8 "square"
var multiBad = new int[3,]; //Syntax error!
var jaggedSquare= new int[3][8]; //another 3x8 "square"
The former is a two dimensional array. The latter is an array whose elements are also arrays.
The first is for a multidimentional array
the second is for array of arrays

Cannot convert from double[][] to double[*,*]

I have a code that looks like (more or less) :
public void INeedHolidaysNow(double[,]){
//... Code to take a break from coding and fly to Hawaii
}
double[][] WageLossPerVacationDay = new double[10][5];
INeedHolidays(WageLossPerVacationDay); // >>throws the Exception in the Title
I found the solution on this post which consists in looping rather thant trying a savage cast
So my question is : WHY ? what happens behind the scenes in the memory allocation that prevents what may seem - at least at first glance, to be a feasible cast ? I mean structurally, both expression seem to be quite identic. What is it that I am missing here ?
EDIT:
I have to use "double[ ][ ]" as it is provided by an external library.
One is a jagged array, the other is one big block.
double[][] is an array that contains arrays of double. Its form is not necessarily rectangular. In c terms its similar to a double**
double[,] is just one big block of memory, and it is always rectangular. In c terms it's just a double* where you use myArray[x+y*width] to access an element.
One is called multidimensional array (double[*,*]) and other is called jagged array (double[][]).
Here is a good discussion over differences between them.
What is differences between Multidimensional array and Array of Arrays in C#?
Quite simply, [,] arrays (2D arrays) and [][] arrays (jagged arrays) aren't the same.
A [,] array can be visually represented by a rectangle (hence it's also known as a rectangular array), while a [][] array is a 1D array that contains other 1D arrays.
It wouldn't make much sense to be able to cast one to the other.
You should define your double array like this:
double[,] WageLossPerVacationDay = new double[3, 5];
Then it should work!
hth

Efficiently shrinking a two dimensional array in C#

What is an efficient way to shrink a two dimensional array to a smaller size in C#?
For example:
var bigArray = new object[100, 100];
var smallArray = new object[10, 10];
bigArray[0, 0] = 1;
bigArray[0, 1] = 2;
...
bigArray[99, 99] = 100000;
startRowIndex = 0;
startColumnIndex = 0;
endRowIndex = 9;
endColumnIndex = 9;
smallArray = bigArray.SomeShirnkingMethod(startRowIndex, startColumnIndex, endRowIndex, endColumnIndex);
How will you write SomeShrinkingMethod() ?
Thanks!
EDIT: I'm simply trying to get the first 10 rows and columns of the bigArray into the smallArray but I'm not sure if a looping through the array is the most efficient method.
You've got to create a new array of the desired size (in your code, you've already done this) and copy the content. I'm not sure what the “shrinking” operation needs to do in your case. However, you cannot modify the dimensions of an existing array.
The function you proposed is defective because it can't know the dimensions of the target array. Either you pass it the dimensions and dimension the new array internally or you pass it the target array and simply copy the contents.
Edit:
In response to your edit: Yes, looping will be the reasonable way to do this and this is also reasonably fast. I'm not aware of a block-copying mechanism in .NET that can be applied to multidimensional arrays.
Depends on what you want your shrinking function to do. You've got to make a new array and do the copy based on whatever your criteria is. My assumption is that you've got a 2d array for a reason, right? The copy could either be trivia (find the next location that has a non-zero value and put it in the next available location in the target) or based on something else. Can you provide more info?
Yes the best method is almost certainly to loop over each cell, although it might be possible to copy a sequence of each 'row'. The method would need to know lower indices of the square to be copied from the source square, and the size (which might be implicit in the destination square definition).

Categories