2013-05-19 28 views
6

Mam double[,] Array;. Czy jest możliwe uzyskanie czegoś takiego jak double[] ColumnArray0 = Array[0,].toArray() i double[] RowArray1 = Array[,1].toArray() bez wykonywania kopii każdego elemet (używając for)?Jak uzyskać tablicę 1D i tablicę 1D z tablicy 2D? (C# .NET)

Dzięki.

+0

Nie dostaję twojego pytania, ale dlaczego i tak miałbyś to robić? –

+0

Próbuję zaimplementować FFT na obrazie (tablica 2D) i zaimplementowane przez 1D FFT wywołujące wiersze, a następnie na kolumnach. Byłoby miło nie robić niepotrzebnych tablic ani cykli.(FFT zajmuje dużo czasu i pamięci) –

+1

Myślę, że nie powinieneś sam wdrażać algorytmów przetwarzania obrazu, poszukaj FFT dla obrazów w C# i możesz znaleźć ludzi, którzy już je wykonali. może być zaimplementowany dla OpenCV dla C# lub jeśli nie jest to do celów produkcyjnych, po prostu trzymaj się z Matlaba lub coś w tym stylu –

Odpowiedz

2

Tablice to obszar pamięci, w którym wszystkie wpisy są przechowywane w kolejności. W zależności od układu danych w pamięci jest to możliwe tylko dla wierszy lub kolumn.

Zamiast 2d array double[,] typu to jest w twoim przypadku lepiej używać tablicę tablic double[][]

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

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

zależności od tego jak umieścić dane w tablicy, można również traktować Array2d postaci tablica kolumn. Ale jednoczesne posiadanie obu nie jest możliwe.

mają również do obejrzenia tutaj: Multidimensional Array [][] vs [,]

+11

Więc, nie ma sposobu, aby to zrobić, jeśli tablica jest zdefiniowana za pomocą '[,]'? – AdamMc331

3

Chociaż jest bardzo późno, chcę zapewnić alternatywną odpowiedź na pytanie.

Pierwszą ważną częścią pytania było uzyskanie dostępu do kompletnych wierszy LUB kolumn macierzy. Jedną z możliwości robi to za pomocą metody rozszerzenie: przykład

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

Zastosowanie:

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. 

Pierwszą rzeczą, aby pamiętać, jest to, że można korzystać z tych metod generycznych z wszelkiego rodzaju [,] - matryce i odpowiednie [] -ektory. Wyobraź sobie, że zastąpienie s z double s, a otrzymasz specjalną wersję dla "podwójny" (jak było zadawane przez OP).

Po drugie, pobieranie i ustawianie wierszy odbywa się za pomocą Array.Copy, natomiast pobieranie i ustawianie kolumn odbywa się za pomocą pętli. Jest to spowodowane wartością C# Row-Major order, która umożliwia pierwszą, ale nie drugą. Oczywiście oba mogą być zaimplementowane z pętlą, jak to zauważyłem.

Upewnij się, że przekazałeś poprawne wymiary zestawu metod, lub program się zawiesi (można łatwo dodać kontrolę błędów i wymiarów). Cała logika mogłaby być równie dobrze wdrożona dla poszarpanych tablic, takich jak double[][], jednak OP szczegółowo zapytał o te wielowymiarowe.

Co do drugiej części pytania: Jeśli twoja macierz składa się z podwójnej, a ponieważ podwójne jest typem wartości, wartości będą zawsze kopiowane. Zatem pożądane zachowanie braku kopiowania wartości nie byłoby możliwe. Jednak w przypadku używania obiektów jako T tylko odwołanie wskazujące obiekt zostanie skopiowane, a nie sam obiekt (więc uważaj na mutowanie obiektu "skopiowanego").

Wreszcie, jeśli naprawdę nie chcesz kopiować podwójnych wartości, sugerowałbym przekazanie całej macierzy (tylko referencja jest przekazywana), a następnie bezpośrednie przejście przez żądane kolumny i/lub wiersze.