2017-11-18 12 views
0

この2つのコードはC++で書かれていて、2番目のコードはFortranで2番目のものでは説明しません...FortranコードとC++コードとの結果が異なります

C++:

# include <iosfwd> 
# include <vector> 
# include <cmath> 
# include <iomanip> 
# include <iostream> 

std::vector<double> dot(int size, std::vector<double> x, 
         std::vector<double> aa, std::vector<int> ja) 
{  

     std::vector<double> y(x.size()); 

     for(auto i = 0; i < size ; i++) 
      y.at(i) = aa.at(i) * x.at(i); 

     for(auto i=0 ; i < size ; i++) 
     { 
     //for(auto k=ja.at(i) ; k< ja.at(i+1)-1 ; k++) 
     auto k = ja.at(i); 

     do 
     { 
      y.at(i) += y.at(i) + aa.at(k) * x.at(ja.at(k)) ; 
      k++; 
     } 
     while(k < ja.at(i+1)-1) ; 

     } 

} 


int main() 
{ 
    std::vector<double> x = {0.,1.3,4.2,0.8} ; 

    std::vector<double> aa = {1.01,4.07,6.08,9.9,0.,2.34,3.12,1.06,2.2}; 
    std::vector<int> ja = {6,7,7,8,10,3,1,1,3}; 

    std::vector<double> y = dot(x.size(), x , aa , ja); 

    for(auto& i : x) 
     std::cout << i << ' ' ; 
    std::cout << std::endl; 
} 

Fortranコードは、私は、cは1 で0およびFortranでインデックス++を起動していることを知っているが、私はこのことを考慮してきたと思います!ところで、正しいものは以下のようなFortranコードです:

MODULE MSR 
IMPLICIT NONE 

CONTAINS 
    subroutine amuxms (n, x, y, a,ja) 
     real*8 x(*), y(*), a(*) 
     integer n, ja(*) 
     integer i, k 
     do 10 i=1, n 
     y(i) = a(i)*x(i) 
10  continue 
     do 100 i = 1,n 

     do 99 k=ja(i), ja(i+1)-1 
      y(i) = y(i) + a(k) *x(ja(k)) 
99  continue 
100 continue 

     return 

     end 

END MODULE 

PROGRAM MSRtest 
USE MSR 
IMPLICIT NONE 
INTEGER :: i 
REAL(KIND(0.D0)), DIMENSION(4) :: y, x= (/0.,1.3,4.2,0.8/) 

REAL(KIND(0.D0)), DIMENSION(9) :: AA = (/ 1.01, 4.07, 6.08, 9.9, 0., 2.34, 3.12, 1.06, 2.2/) 
INTEGER , DIMENSION(9)   :: JA = (/6, 7, 7, 8, 10, 3, 1, 1, 3/) 
CALL amuxms(4,x,y,aa,ja) 

WRITE(6,FMT='(4F8.3)') (y(I), I=1,4)  

END PROGRAM 

私は解決しました、私は荒いミスを犯しました!インデックスとしてja_を使用して..私はsubtrac 1を忘れてしまった!

ので、作業関数である:

# include <iosfwd> 
# include <vector> 
# include <cmath> 
# include <iomanip> 
# include <iostream> 

std::vector<double> dot(int size, std::vector<double> x, 
         std::vector<double> aa, std::vector<int> ja) 
{  

     std::vector<double> y(x.size()); 

     for(auto i = 0; i < size ; i++) 
      y.at(i) = aa.at(i) * x.at(i); 

     for(auto i=0 ; i < size ; i++) 
     { 

     auto k = ja.at(i)-1; 

     do 
     { 
      y.at(i) += aa.at(k) * x.at(ja.at(k)-1) ; 
      k++; 
     } 
     while(k < ja.at(i+1)-1) ; 

     } 
     return y; 
} 

2つのコードの差は、Fortranコードja_(1)で私たちja_の最初の値を与えることを考慮することなく、他のベクトルのインデックスとしてja_(index)の使用中にあります2番目のC++で! @ウラジミールFそれは今明らかですか?

+0

どちらの違いがありますか?違いを説明する必要があります。コードを実行しても、表示されるものとは異なるものが表示される可能性があります。結果を表示してコメントしてください。 [ask]と[mcve]を読んでください。 –

+2

初期化された配列の数字は、倍精度ではなく単精度です(重複しています)。しかし、実際には、あなたが話している違いを私たちに示す必要があります。 –

+0

多分重複しているかもしれない:https://stackoverflow.com/questions/6146005/is-there-a-better-double-precision-assignment-in-fortran-90 https://groups.google.com/を参照してください。フォーラム/#!トピック/ comp.lang.fortran/IoI5Mes2Se4 [151-175] –

答えて

1

私が見ているC++コードにはいくつかの問題があります。

まず、dot関数は何も返しません。最後にreturn y;ステートメントが必要です。

もう1つは、その関数の最も内側のループにあるy.at(i)の計算です。 y.at(i) = y.at(i) + aa...またはy.at(i) += aa...のいずれかである必要がありますが、両方ではありません。

第3の問題は、出力ループで、間違った配列(yの代わりにx)を使用していることです。

その他の問題がある可能性があります。デバッガでプログラムを実行し、それらの実行を比較することで、それらを見つけることができます。

+0

私はすべてのja_(i)とja(k)からインデックスを使って1を減算しました! –

関連する問題