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

2

13

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.

Statvolt answered 19/5, 2013 at 14:58 Comment(3)
I don't get your question, but why would you need to do that anyway?Agrippina
Im trying to implement FFT on image (2D array) and its implemented by 1D FFT calling on rows and then on colums. It would be nice not to make any unnecessary arrays or cycles.(FFT is time and memory consuming)Statvolt
I guess you shouldn't implement image processing algorithms yourself, look for FFT for images in C# and you may find people already made it. it might be implemented for OpenCV for C# or if it's not for a production purpose, just stick with matlab or something like thatAgrippina
E
6

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 [,]

Eer answered 19/5, 2013 at 15:55 Comment(1)
So, is there no way to do this if the array is defined using [,]?Eisele
W
15

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.

Webster answered 9/8, 2016 at 9:11 Comment(0)
E
6

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 [,]

Eer answered 19/5, 2013 at 15:55 Comment(1)
So, is there no way to do this if the array is defined using [,]?Eisele

© 2022 - 2024 — McMap. All rights reserved.