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.

Jose Kiwi
  • 133
  • 1
  • 1
  • 4
  • I don't get your question, but why would you need to do that anyway? – Mokhtar Ashour May 19 '13 at 15:35
  • 2
    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) – Jose Kiwi May 19 '13 at 16:02
  • 1
    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 that – Mokhtar Ashour May 19 '13 at 21:15

2 Answers2

14

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.

Timitry
  • 2,646
  • 20
  • 26
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 [,]

Community
  • 1
  • 1
thalm
  • 2,738
  • 2
  • 35
  • 49