2011-10-11 3 views
0

私は精度に問題があります。私は私のC + +コードをmatlabと同じ精度を持つ必要があります。 matlabには私は数字などでいくつかのものを行うスクリプトがあります。私はそのスクリプトと同じことを行うC++のコードを手に入れました。私は104> = 104を試してみるとスクリプトでそれを見つけました。フォーマットを長くしようとしましたが、それがなぜ偽であるのか分かりませんでした。私はおそらくmatlabには104の真の値と103.9999のような本当の値が格納されていると思っていたので、C++で精度を整えました。高精度50.050。これら2つの値は、* +など、いくつかの計算からです。私のC++とMATLABのscripsは同じ精度を持つようにする方法はありますか?私はどのようにC + +と同じようにmatlabの精度を作ることができますか?

for i = 1:neighbors 
    y = spoints(i,1)+origy; 
    x = spoints(i,2)+origx; 
    % Calculate floors, ceils and rounds for the x and y. 
    fy = floor(y); cy = ceil(y); ry = round(y); 
    fx = floor(x); cx = ceil(x); rx = round(x); 
    % Check if interpolation is needed. 
    if (abs(x - rx) < 1e-6) && (abs(y - ry) < 1e-6) 
    % Interpolation is not needed, use original datatypes 
    N = image(ry:ry+dy,rx:rx+dx); 
    D = N >= C; 
    else 
    % Interpolation needed, use double type images 
    ty = y - fy; 
    tx = x - fx; 

    % Calculate the interpolation weights. 
    w1 = (1 - tx) * (1 - ty); 
    w2 =  tx * (1 - ty); 
    w3 = (1 - tx) * ty ; 
    w4 =  tx * ty ; 

    %Compute interpolated pixel values 
    N = w1*d_image(fy:fy+dy,fx:fx+dx) + w2*d_image(fy:fy+dy,cx:cx+dx) + ... 
    w3*d_image(cy:cy+dy,fx:fx+dx) + w4*d_image(cy:cy+dy,cx:cx+dx); 

    D = N >= d_C; 

end 

私は12行目にある他の問題点を得ました。 txとty eqauls 0.707106781186547または1 - 0.707106781186547 d_imageからの値は範囲0と255です.Nは4ピクセルを補間する値0..255です イメージから。 d_Cは値0.255である。それでも、なぜmatlabが私のようなN個のvlauesを持っているのかを示しています。x x x 140.0000 140.0000とd_C:x x x 140 x。 Dは、私はより多くの精度をしようとし、それをデバッグさ140 =!140.0000て4位に私に0を与えるが、それはまだその140.00000000000000が、それはまだない140

int Codes::Interpolation(Point_<int> point, Point_<int> center , Mat *mat) 
{ 


int x = center.x-point.x; 
int y = center.y-point.y; 

Point_<double> my; 
if(x<0) 
{ 
    if(y<0) 
    { 
     my.x=center.x+LEN; 
     my.y=center.y+LEN; 
    } 
    else 
    { 
     my.x=center.x+LEN; 
     my.y=center.y-LEN; 
    } 

} 
else 
{ 
    if(y<0) 
    { 
     my.x=center.x-LEN; 
     my.y=center.y+LEN; 
    } 
    else 
    { 
     my.x=center.x-LEN; 
     my.y=center.y-LEN; 
    } 
} 


int a=my.x; 
int b=my.y; 

double tx = my.x - a; 
double ty = my.y - b; 


double wage[4]; 
wage[0] = (1 - tx) * (1 - ty); 
wage[1] =  tx * (1 - ty); 
wage[2] = (1 - tx) *  ty ; 
wage[3] =  tx *  ty ; 



int values[4]; 

//wpisanie do tablicy 4 pixeli ktore wchodza do interpolacji 
for(int i=0;i<4;i++) 
{ 
    int val = mat->at<uchar>(Point_<int>(a+help[i].x,a+help[i].y)); 

    values[i]=val; 
} 




double moze = (wage[0]) * (values[0]) + (wage[1]) * (values[1]) + (wage[2]) * (values[2]) + (wage[3]) * (values[3]); 
return moze; 
} 

LENだという=配列の値で0.707106781186547値は100%ですmatlabの値と同じです。

+3

MatlabとC++で同じ結果が得られる同じ「double」入力で同じ計算が行われているとしますか?もしそうなら、実行している計算をMatlabとC++の両方に投稿してください。 – Praetorian

+1

あなたの問題はあなたの考えではありません。 –

+1

「104> = 104」は、すべての既知のプログラミングシステムにおいて常に真である。あなたは本当の話を私たちに伝えていません。あなたが正確な精密な詳細を見つけ出すまで、私たちは時間を無駄にしています。 –

答えて

2

Matlabは倍精度を使用します。 C++のdouble型を使うことができます。それはほとんどの事を似ているが、100%ではない。 他の誰かが指摘したように、これはおそらくあなたの問題の原因ではありません。アルゴリズムに違いがあるか、MatlabとC++で別々に定義されたライブラリ関数のようなものかもしれません。たとえば、Matlabのstd()は(n-1)で割り、コードはnで割ります。

+0

C++ライブラリには標準偏差関数がありますか? – NPE

1

まず、経験則として、直接、浮動小数点変数を比較するのは良いアイデアになることはありません。たとえば、(nr >= 104)の代わりに、(nr >= 104-e)の場合は、0.00001のようにeが小さい番号の場合の代わりに使用してください。

しかし、いくつかの深刻なアンダーサンプリングがなければならないか、一般的な浮動小数点の不正確の制限ではありません50050を取得代わりに50000ので、スクリプトのどこかに丸め誤差。例えば、Matlabは15桁の小さなステップを持つことができます。

私はあなたのコード内のいくつかのキャストの問題があると思いますが、整数の除算を持っているので、例えば

int i; 
double d; 
// ... 
d = i/3 * d; 

は、非常に不正確な結果を与えるだろう。 d = (double)i/3 * dまたはd = i/3. * dを使用すると、はるかに正確な結果が得られます。

上記の例では、デフォルトで浮動小数点数が既に存在しているため、Matlabでは問題は発生しません。同様の問題は、C++およびMatlabコードの結果の相違に起因する可能性があります。

あなたの計算を見ることは何が悪かったのか見つけるのに大いに役立つでしょう。

EDIT: cとC++では、doubleを同じ値の整数と比較すると、等しくない可能性が非常に高くなります。これは、2つのdoubleと同じだが、あなたはそれらの上に正確に同じ計算を行う場合、あなたは幸運を得るかもしれません。でも、MATLABで、それは危険だし、多分あなたは、両方のダブルスあるとして、両方が同じように切り捨てられてしまったということだけでラッキーでした。 あなたの最近の編集では、問題はあなたの配列を評価する場所であるようです。 C++(または浮動小数点変数を使用するときは任意の言語)で浮動小数点数または倍精度を比較するときは、==または!=を使用しないでください。比較を行う適切な方法は、それらが互いに小さな距離内にあるかどうかをチェックすることです。

例:==または!=を使用して2つの倍精度を比較することは、2つのオブジェクトの重さをそれらの中の原子数を数えて比較し、1つの単原子の違いがあっても等しくないと判断するそれら。

0

MATLABは、特に指定しない限り、倍精度を使用します。 C++での同じ実装で見られる相違点は、浮動小数点エラーによるものです。

関連する問題