2017-11-16 26 views
1

行列は動的配列、つまりdouble * inputMatとして格納されています。私は、特定の列を抽出できる行と列の数を知っています。今問題は、私は抽出され、別の動的配列に格納される列のセットを持っているということです。これを行う方法?は行列から特定の列を抽出し、Cの新しい行列として格納します

double *extractMatrix(double *inputMat,int rows, int *columnIndex, int columnTotal) 
{  
    double *outputMat=malloc(sizeof(double)*rows*columnTotal); 
    for(int i=0; i<columnTotal; i++) 
     memcpy(outputMat, &inputMat[rows*columnIndex[i]],rows*sizeof(double)); 
    return outputMat; 
} 

columnIndexには、行列から抽出する列のインデックスが含まれています。 ColumnTotalはcolumnIndex配列のサイズです。しかし、これはinputMatの特定の1つの列だけをoutputMatにコピーし、おそらく上書きされます。私はcolumnIndexのすべての列の完全な配列を必要とします。私はlapackとBLASライブラリを扱っています。これを行うための組み込み方法がある場合は、共有してください。

+0

何もありません。 colはinputMatの列数を表します。現在のシナリオでは必要ありません。私はそれを削除します。編集されたバージョンをご覧ください。 – user402940

+0

'memcpy(outputMat、...'デスティネーションは常に同じ、 'i'で変更する必要があります。 – chux

+0

' double * 'をパラメータとして渡す場合、' rows'と 'columnTotal'はなぜ必要なのですか?あなたは本質的に倍精度*の配列を持っています(技術的には*倍精度*へのポインタでもありますが、単に 'size'と' columnIndex'というポインタが必要です)。インデックスを作成して、好きなように列を抽出することができます。 –

答えて

1

それは2次元配列であるかのようにあなたの基本的な目標は、インデックスにダブル(を倍増するために、実際にポインタ)のご配列です。これを行うには、特定の列columnIndexを抽出し、その列を構成する値を保持するメモリブロック(rowsの値)を動的に割り当てて、新しく割り当てられたブロックへのポインタを返します。

あなたのアプローチは正しい方向にあります。インデックスはちょうどオフです。 forループ自体でインデックスを処理する方がはるかに簡単です。基本的なアプローチは次のとおりです。

int n = 0; 
for (int i = colindex; i < rows * cols; i += cols) 
    output[n++] = input[i]; 

(つまり、列内n < INT_MAX値をとる - 必要に応じて調整)

は、あなたがやろうとしているように見えるものを、あなたが行うことができない小さな例をまとめます次のようなもの:

#include <stdio.h> 
#include <stdlib.h> 

int *getcol (const int *a, const int rows, const int col, const int ncols) 
{ 
    int sz = rows * ncols, 
     n = 0, /* output index */ 
     *out = malloc (rows * sizeof *a); 

    if (out) 
     for (int i = col; i < sz; i += ncols) /* index with loop vars */ 
      out[n++] = a[i];     /* assign column values */ 

    return out; 
} 

int main (void) { 

    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }, 
     rows = 3,     /* simulate a 3x3 with 9 values */ 
     cols = sizeof a/(rows * sizeof *a), 
     colidx = 1,     /* zero based index of wanted column */ 
     *output = NULL; 

    if ((output = getcol (a, rows, colidx, cols))) { 
     for (int i = 0; i < rows; i++) 
      printf (" %2d\n", output[i]); 
     free (output); /* don't forget to free memory */ 
    } 

    return 0; 
} 

注:関数のパラメータは、あなたが列挙されている順序になっている - しかし、短い名前を使用して好ましくはあなたがように順番を入れ替えますが最後ですが、それはあなた次第です。あなたが望む列はポインタとして渡される必要はなく、単純割り当てが動作するmemcpyの必要はありません。また、あなたがしたい列のインデックスはゼロベースのインデックス

使用例/出力として渡される)9つの値からシミュレートされた3×3アレイの2列目にある

$ ./bin/array_idx_1d_as_2d 
    2 
    5 
    8 

ご不明な点がありましたらお気軽にお問い合わせください。

+0

memcpyは" forループ "インデックスより高速です。私が扱っている行列は非常に大きいので(サイズ> = 500x500)、実際のアルゴリズムで何度もこの関数を何度も呼び出すと、通常の "forループ"ではコピーが少し遅くなることがあります。私が望むのは、異なる列をマージすることです。私はmemcpyでそれをやる方法を知らない。明示的に "n"個の要素の後にコピーするような、イテレータのようなものが必要です。 – user402940

+0

あなたの情報がどこにあるのか分かりませんが、非シーケンシャルなバイトを 'memcpy'することはできませんので、' memcpy'を使用して各ブロック列の値は 'cols * sizeof val'バイトで区切られます。あなたの問題が間違っていると私は理解しています –

+0

ここで、500列の2D配列から500列を別々の500列2D配列にマージする必要がある場合、一度に500の値をmemcpyすることができるので、 'memcpy'は便利です(隣の列の値は隣接している)が、隣接していない列を選択するにはそれは役に立たない。 –

関連する問題