2013-05-19 22 views
6

私はdouble[,] Array;を持っています。とdouble[] RowArray1 = Array[,1].toArray()のようなものを入手することは可能ですか(forを使用して)すべてのelemetのコピーを作成する必要はありませんか?2D配列から1D列配列と1D行配列を取得する方法は? (C#.NET)

ありがとうございました。

+0

私はあなたの質問を得ることはありませんが、どうしてあなたはそれをやる必要がありますか? –

+0

Im(2次元配列)にFFTを実装しようとしていて、1D FFTで行を呼び出した後に列を呼び出して実装しました。不要な配列やサイクルを作らないのはいいことです。(FFTは時間とメモリを消費します) –

+1

自分で画像処理アルゴリズムを実装するべきではないと思います.C#で画像のFFTを探してみてください。 C# のOpenCV用に実装されているかもしれませんし、生産目的でない場合はmatlabなどのようなものをつけてください –

答えて

2

アレイは、すべてのエントリが連続して格納されるメモリ領域です。メモリ内のデータレイアウトに応じて、これは行または列に対してのみ可能です。代わりに、あなたがあなたの配列にデータを置く方法に応じて配列double[][]

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

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

の配列を使用するために、あなたのケースで優れている2次元配列double[,]タイプの

、あなたはまた、Array2dを扱うことができます列配列。しかし、同時に両方を持つことは不可能です。であることが非常に遅く、私は質問への代替答えを提供したいが Multidimensional Array [][] vs [,]

+11

したがって、配列が '[、]'を使って定義されている場合、これを行う方法はありませんか? – AdamMc331

3

もここで見ています。

質問の最初の重要な部分は、行列の完全な行または列にアクセスできることでした。これを行う1つの可能性は、拡張メソッドを使用することです:

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]; 
    } 
} 

使用例:注意すべき

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. 

まず最初は、あなたがあらゆる種類のこれらの一般的な方法を使用できることである[、] - 行列と対応する[] - ベクトル。 Tdoubleに置き換えたとしたら、(OPによって尋ねられたように)特定のバージョンの 'double'が得られるでしょう。

2番目のことは、行を取得して設定するとArray.Copyが使用され、列を取得および設定するにはループが使用されます。これは、C#のRow-Major orderが原因で、最初のものが許可されますが、2番目のものは許可されません。もちろん、どちらもコメントアウトされているように、ループで実装できます。

set-Methodsの正しい寸法を渡すことを忘れないでください。そうしないと、プログラムがクラッシュします(エラーと寸法チェックを簡単に追加できます)。 double[][]のようなぎざぎざの配列に対しては、ロジック全体を実装することもできますが、OPは具体的には多次元配列を要求しました。

質問の第2の部分について:行列がdoubleで構成され、doubleが値型なので、値は常にコピーされます。したがって、値をコピーしないというあなたの望む動作は不可能です。しかし、オブジェクトをTとして使用する場合は、オブジェクトを指す参照のみがコピーされ、オブジェクト自体はコピーされません(したがって、コピーされたオブジェクトを変更することに注意してください)。

最後に、二重値をコピーしたくない場合は、行列全体を渡す(参照のみが渡される)ようにして、目的の列や行を直接ループすることをお勧めします。

関連する問題