2017-06-08 11 views
-2

ファイルを処理しています。以下のようなコンテンツのフォーマットは次のとおりです。Fortransと同等のC++構文

name - problem name (A string value) 
m  - number or rows (int value) 
n  - number of columns (int value) 
Ap  - pointers to the begining of storage of column (size n+1)(an array of size (n+1)) 
Ai  - row indices for each non zero entry (input, nnz A) 
Ax  - non zero entries (input, nnz A) 
b  - right hand side (input, size m)(an double array of size m) 
c  - objective vector (minimize, size n) (an double array of size n)) 
z0  - initial fixed value for objective (double value) 
lobnd - lower bounds on variables (size n) (an double array of size n) 
upbnd - upper bounds on variables (size n) (an double array of size n) 

を構文はFORTRANでこのファイルを読み込むための、次のとおりです。

Ap (j) = location of start of column j 
Ai (Ap (j)) through Ai (Ap (j+1)-1) are the row indices in column j 
Ax (Ap (j)) through Ax (Ap (j+1)-1) are the numerical values in column j 

     read(file,'(a8)') name 
     read(file,*) m,n 
     read(file,*) (ia(i),i=1,n+1) 
     read(file,*) (ja(i),i=1,ia(n+1)-1) 
     read(file,*) (a(i),i=1,ia(n+1)-1) 
     read(file,*) (b(i),i=1,m) 
     read(file,*) (c(i),i=1,n) 
     read(file,*) z0 
     read(file,*) (lobnd(i),i=1,n) 
     read(file,*) (upbnd(i),i=1,n) 

私はC++で対応する構文を知りたいです。このプログラムをFortranからC++に変換する方法は誰にも分かりますか? Here is an example of an file .

ここでは、ファイル形式の説明によると、上記のファイル内

name = 'BLEND' 
m  = 74 
n  = 114 
upbnd = I can see the n or 114 double values at the end of the file 
lobnd = I can see the n or 114 double values before the values of upbnd 
z0  = here I can see 0. is the value of z0 
c  = I can see n or 114 values before z0 in the file and understand this 
b  = I understand the right hand side and I can see the m or 74 values 
Ai  - I understand row indices for each non zero entry (input, nnz A) 
Ax  - non zero entries (input, nnz A) 

Now I can not understand the following values in the file: 
Ap  = I can not understand what do these (n+1) or 115 integers mean 

私は、ファイルにこののAβ値を理解したいです。ありがとうございます。

+1

これまでに何を試しましたか? –

+0

いくつかのファイルのリンクを提供してください –

+1

**間違ったアプローチ** Fortranで思考しながらC++でコード化しないでください。良いC++プログラミング(http://stroustrup.com/Programming/)の本を読んで、標準のC++ [コンテナ](http://en.cppreference.com/w/cpp/container)を使って週を過ごす –

答えて

3

read(file,'(a8)') nameは、おおよそscanf("%8s", name);のように変換されます。

read(file,*) m,nfile >> m >> n;

のようなものとほぼ同等であるread(file,*) (ia(i),i=1,n+1)のようなラインは、間違いなく最も難しいです。最初のコンマの後の部分は暗黙のDOループです。私は、残りは1以上で示されたものの他の単なる繰り返していると信じて

for (int i=1; i<n+1; i++) 
    file >> ia[i]; 

:それは基本的に、これは程度の何かとほぼ同等であることを意味します。

ただし、注意しなければならない点がもう1つあります。Fortranは配列を列の大きな順序で格納します。 CおよびC++では配列を行優先順序で格納します。つまり、CまたはC++で配列をトラバースすると、通常、行ごとにそれを横断したいと考えています。これは、とりわけ、各行がメモリ内に連続して格納されるため、キャッシュの使用を最適化します。

Fortranは列メジャーです。これは、各列がメモリ内で連続していることを意味し、配列をトラバースする自然な方法は一度に1つの列であるということです。各列はメモリ内で連続しているので、これは(もちろん)キャッシュ使用を最適化します。

Apの値には、各列の先頭の位置が含まれます。つまり、Ap(1)は最初の列の最初の項目のインデックスです。 Ap(2)は2番目の列の最初の項目のインデックスで、以下同様です。 N 番目の列を読み取る必要がある場合、読み込みを開始する主配列の場所をAp(N)が通知して、その列のデータを取得します。 Ap(N + 1)は列N + 1の開始点であるため、列Nの最後の項目はAp(N + 1)-1にあります。

したがって、メインデータ配列をフラット(1D)配列に読み込むとします。この配列はdataと呼ばれます。 N の列をdataに読み込むには、Apを使用できます。例えば、Nから番目の列を印刷するには、我々はこのようなコード記述することができます。

void print_column(int n) { 
    for (int i=Ap[n]; i<Ap[n+1]; i++) 
     std::cout << data[i] << '\t'; 
} 

をこれは、動的に2次元配列の割り当てに対処することを避けるため、代わりにnew/malloc /つだけを使用することができますvectorにはデータを保持し、もう1つは各列の先頭のインデックスを保持します。C++では、vectorに格納されたデータに2Dアドレス指定を行うためにoperator()をオーバーロードする2Dマトリックスクラスを作成するのは簡単です。 Apによって提供される余分なレベルのインダイレクションを使用するか、または乗算を使用して正しい位置に到達することができます。現在のプロセッサでは、乗算はおそらくメモリ参照より高速ですが、古いプロセッサでは乗算はメモリアクセスに比べてずっと遅くなることがあります。

+0

Apに例を挙げることはできますか? –

関連する問題