2013-05-19 16 views
6

ho double[,] Array;. È possibile ottenere qualcosa come double[] ColumnArray0 = Array[0,].toArray() e double[] RowArray1 = Array[,1].toArray() senza fare una copia di ogni elemet (usando per)?Come ottenere un array di colonne 1D e un array di righe 1D dall'array 2D? (C# .NET)

Grazie.

+0

Non capisco la tua domanda, ma perché dovresti farlo comunque? –

+0

Sto cercando di implementare FFT sull'immagine (array 2D) e il suo implementato da FF 1D chiamando su righe e poi su colonne. Sarebbe bello non creare array o cicli inutili.(FFT consuma tempo e memoria) –

+1

Immagino che non dovresti implementare da solo gli algoritmi di elaborazione delle immagini, cercare FFT per le immagini in C# e potresti trovare persone già create. potrebbe essere implementato per OpenCV per C# o se non è per uno scopo di produzione, basta attaccare con matlab o qualcosa di simile –

risposta

2

Le matrici sono un'area di memoria in cui tutte le voci sono memorizzate in modo consecutivo. A seconda del layout dei dati in memoria, ciò è possibile solo per righe o colonne.

Invece del 2d matrice double[,] tipo è nel vostro caso meglio usare un array di array double[][]

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

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

A seconda di come si mettono i dati nella propria matrice, si può anche trattare il Array2d come array di colonne. Ma avere entrambi allo stesso tempo non è possibile.

hanno anche uno sguardo qui: Multidimensional Array [][] vs [,]

+11

Quindi, non c'è modo di farlo se l'array è definito usando '[,]'? – AdamMc331

3

Pur essendo molto tardi, voglio fornire una risposta alternativa alla domanda.

La prima parte importante della domanda era quella di poter accedere a righe o colonne complete della matrice. Una possibilità di fare questo è quello di utilizzare metodi di estensione: esempio

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:

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. 

La prima cosa da notare è che è possibile utilizzare questi metodi generici con qualsiasi tipo di [,] - matrici e corrispondenti [] -vettori. Immaginate di sostituire i T s con double s e otterrete la versione specifica per "doppio" (come richiesto dall'OP).

La seconda cosa è che ottenere e impostare le righe utilizza Array.Copy, mentre ottenere e impostare le colonne utilizza un ciclo. Ciò è dovuto allo Row-Major order di C#, che consente il primo, ma non il secondo. Ovviamente entrambi possono essere implementati con un ciclo, come visto commentato.

Assicurarsi di trasmettere le dimensioni corrette per i metodi set, altrimenti il ​​programma si bloccherà (errore e controllo delle dimensioni possono essere aggiunti facilmente). L'intera logica potrebbe anche essere implementata per array frastagliati come double[][], tuttavia, l'OP chiedeva specificatamente quelli multidimensionali.

Come per la seconda parte della domanda: Se la matrice è composta da doppio e poiché il doppio è un tipo di valore, i valori verranno sempre copiati. Quindi il tuo comportamento desiderato di non copiare i valori non sarebbe possibile. Tuttavia, se si usano oggetti come T, verrà copiato solo il riferimento che punta all'oggetto, e non l'oggetto stesso (quindi fate attenzione a mutare l'oggetto "copiato").

Infine, se davvero non si desidera copiare i valori doppi, suggerirei di passare l'intera matrice (viene passato solo il riferimento) e quindi di eseguire direttamente il ciclo delle colonne e/o delle righe desiderate.

Problemi correlati