Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get 1D column array and 1D row array from 2D array? (C# .NET)

Tags:

arrays

c#

.net

2d

rows

i have double[,] Array;. Is it possible to get something like double[] ColumnArray0 = Array[0,].toArray() and double[] RowArray1 = Array[,1].toArray() without making a copy of every elemet(using for)?

Thanks.

like image 579
Jose Kiwi Avatar asked May 19 '13 14:05

Jose Kiwi


2 Answers

Arrays are a memory area where all entries are stored in a consecutive way. Depending on the data layout in memory this is only possible for either rows or columns.

Instead of the 2d array double[,] type it is in your case better to use an array of arrays double[][]

double[][] Array2d = new double[10][];
Array2d[0] = new double[10];
Array2d[1] = new double[10];
...

and then:
double[] RowArray0 = Array2d[0];

Depending on how you put the data in your array, you can also treat the Array2d as a column array. But to have both at the same time is not possible.

Also have a look here: Multidimensional Array [][] vs [,]

like image 57
thalm Avatar answered Oct 11 '22 20:10

thalm


Although being very late, I want to provide an alternative answer to the question.

The first important part of the question was to be able to access complete rows OR columns of the matrix. One possibility of doing this is by using extension methods:

public static class MatrixExtensions
{
  /// <summary>
  /// Returns the row with number 'row' of this matrix as a 1D-Array.
  /// </summary>
  public static T[] GetRow<T>(this T[,] matrix, int row)
  {
    var rowLength = matrix.GetLength(1);
    var rowVector = new T[rowLength];

    for (var i = 0; i < rowLength; i++)
      rowVector[i] = matrix[row, i];

    return rowVector;
  }



  /// <summary>
  /// Sets the row with number 'row' of this 2D-matrix to the parameter 'rowVector'.
  /// </summary>
  public static void SetRow<T>(this T[,] matrix, int row, T[] rowVector)
  {
    var rowLength = matrix.GetLength(1);

    for (var i = 0; i < rowLength; i++)
      matrix[row, i] = rowVector[i];
  }



  /// <summary>
  /// Returns the column with number 'col' of this matrix as a 1D-Array.
  /// </summary>
  public static T[] GetCol<T>(this T[,] matrix, int col)
  {
    var colLength = matrix.GetLength(0);
    var colVector = new T[colLength];

    for (var i = 0; i < colLength; i++)
      colVector[i] = matrix[i, col];

    return colVector;
  }



  /// <summary>
  /// Sets the column with number 'col' of this 2D-matrix to the parameter 'colVector'.
  /// </summary>
  public static void SetCol<T>(this T[,] matrix, int col, T[] colVector)
  {
    var colLength = matrix.GetLength(0);

    for (var i = 0; i < colLength; i++)
      matrix[i, col] = colVector[i];
  }
}

Usage example:

double[,] myMatrix = ... // Initialize with desired size and values.
double[] myRowVector = myMatrix.GetRow(2); // Gets the third row.
double[] myColVector = myMatrix.GetCol(1); // Gets the second column.
myMatrix.SetCol(2, myColVector); // Sets the third column to the second column.

First thing to note is that you can use these generic methods with any kind of [,]-matrices and corresponding []-vectors. Imagine replacing the Ts with doubles, and you would get the specific version for 'double' (as was asked by the OP).

Second thing is, that getting and setting the rows uses Array.Copy, while getting and setting the columns uses a loop. This is due to the Row-Major order of C#, which allows the first, but not the second. Of course both can be implemented with a loop, as seen commented out.

Make sure to pass correct dimensions for the set-Methods, or the program will crash (error and dimension checking can be added easily). The whole logic could as well be implemented for jagged arrays like double[][], however, the OP specificially asked for multidimensional ones.

As for the second part of the question: If your matrix consists of double, and since double is a value type, the values will always be copied. So your desired behaviour of not copying the values would not be possible. However, if using objects as T, only the reference pointing to the object will be copied, and not the object itself (so beware of mutating the 'copied' object).

Lastly, if you really don't want to copy the double-values, I'd suggest passing your whole matrix (only the reference is passed), and then directly looping through the desired columns and/or rows.

like image 36
Timitry Avatar answered Oct 11 '22 21:10

Timitry