ccode atan2 generates nan

6 ビュー (過去 30 日間)
Vincenzo Calabro
Vincenzo Calabro 2017 年 8 月 30 日
回答済み: Vincenzo Calabrò 2019 年 1 月 29 日
Hi!
I have the following question related to the ccode function of the symbolic toolbox.
Let us consider the following piece of code:
syms a b real
ccode(atan2(a,b))
the result is:
' t0 = log((a*sqrt(-1.0)+b)/fabs(a*sqrt(-1.0)+b))*-sqrt(-1.0);'
Questions for the MathWorks:
1. Why ccode replace the atan2 function (which is available in c) with such log implementation?
2. There is a way to prevent such replacement (some additional optional parameter?)
The following Matlab script has been written to generate I/O pairs for the atan2 function to compare the output of the Matlab atan2 vs the C vs the ccode output:
p = -2:1:2;
[X,Y] = meshgrid(p,p);
Z = zeros(size(X));
for i=1:size(X,1)
for j=1:size(X,2)
Z(i,j) = atan2(Y(i,j),X(i,j));
end
end
And with those data I ran the following C code (Visual Studio)
#include "stdafx.h"
#include "math.h"
#include "complex.h"
double Atan2(double a, double b) {
return log((a*sqrt(-1.0) + b) / fabs(a*sqrt(-1.0) + b))*-sqrt(-1.0);
}
int main()
{
const unsigned int nTest = 25;
const double adX[nTest] = { -2.000000, -2.000000, -2.000000, -2.000000, -2.000000, -1.000000, -1.000000, -1.000000, -1.000000, -1.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 2.000000, 2.000000, 2.000000, 2.000000, 2.000000, };
const double adY[nTest] = { -2.000000, -1.000000, 0.000000, 1.000000, 2.000000, -2.000000, -1.000000, 0.000000, 1.000000, 2.000000, -2.000000, -1.000000, 0.000000, 1.000000, 2.000000, -2.000000, -1.000000, 0.000000, 1.000000, 2.000000, -2.000000, -1.000000, 0.000000, 1.000000, 2.000000, };
const double adZ[nTest] = { -2.356194, -2.677945, 3.141593, 2.677945, 2.356194, -2.034444, -2.356194, 3.141593, 2.356194, 2.034444, -1.570796, -1.570796, 0.000000, 1.570796, 1.570796, -1.107149, -0.785398, 0.000000, 0.785398, 1.107149, -0.785398, -0.463648, 0.000000, 0.463648, 0.785398, };
unsigned int nIdx = 0;
for (nIdx = 0; nIdx < nTest; nIdx++) {
printf("atan2(%+05.5f,%+05.5f)= Matlab(%+05.5f) C(%+05.5f) CCODE(%+05.5f)\n",
adY[nIdx], adX[nIdx],
adZ[nIdx],
atan2(adY[nIdx], adX[nIdx]),
Atan2(adY[nIdx], adX[nIdx]));
}
scanf("%d", &nIdx);
return 0;
}
The results are presented here:
atan2(-2.00000,-2.00000)= Matlab(-2.35619) C(-2.35619) CCODE(-nan(ind))
atan2(-1.00000,-2.00000)= Matlab(-2.67794) C(-2.67795) CCODE(-nan(ind))
atan2(+0.00000,-2.00000)= Matlab(+3.14159) C(+3.14159) CCODE(-nan(ind))
atan2(+1.00000,-2.00000)= Matlab(+2.67794) C(+2.67795) CCODE(-nan(ind))
atan2(+2.00000,-2.00000)= Matlab(+2.35619) C(+2.35619) CCODE(-nan(ind))
atan2(-2.00000,-1.00000)= Matlab(-2.03444) C(-2.03444) CCODE(-nan(ind))
atan2(-1.00000,-1.00000)= Matlab(-2.35619) C(-2.35619) CCODE(-nan(ind))
atan2(+0.00000,-1.00000)= Matlab(+3.14159) C(+3.14159) CCODE(-nan(ind))
atan2(+1.00000,-1.00000)= Matlab(+2.35619) C(+2.35619) CCODE(-nan(ind))
atan2(+2.00000,-1.00000)= Matlab(+2.03444) C(+2.03444) CCODE(-nan(ind))
atan2(-2.00000,+0.00000)= Matlab(-1.57080) C(-1.57080) CCODE(-nan(ind))
atan2(-1.00000,+0.00000)= Matlab(-1.57080) C(-1.57080) CCODE(-nan(ind))
atan2(+0.00000,+0.00000)= Matlab(+0.00000) C(+0.00000) CCODE(-nan(ind))
atan2(+1.00000,+0.00000)= Matlab(+1.57080) C(+1.57080) CCODE(-nan(ind))
atan2(+2.00000,+0.00000)= Matlab(+1.57080) C(+1.57080) CCODE(-nan(ind))
atan2(-2.00000,+1.00000)= Matlab(-1.10715) C(-1.10715) CCODE(-nan(ind))
atan2(-1.00000,+1.00000)= Matlab(-0.78540) C(-0.78540) CCODE(-nan(ind))
atan2(+0.00000,+1.00000)= Matlab(+0.00000) C(+0.00000) CCODE(-nan(ind))
atan2(+1.00000,+1.00000)= Matlab(+0.78540) C(+0.78540) CCODE(-nan(ind))
atan2(+2.00000,+1.00000)= Matlab(+1.10715) C(+1.10715) CCODE(-nan(ind))
atan2(-2.00000,+2.00000)= Matlab(-0.78540) C(-0.78540) CCODE(-nan(ind))
atan2(-1.00000,+2.00000)= Matlab(-0.46365) C(-0.46365) CCODE(-nan(ind))
atan2(+0.00000,+2.00000)= Matlab(+0.00000) C(+0.00000) CCODE(-nan(ind))
atan2(+1.00000,+2.00000)= Matlab(+0.46365) C(+0.46365) CCODE(-nan(ind))
atan2(+2.00000,+2.00000)= Matlab(+0.78540) C(+0.78540) CCODE(-nan(ind))
How can I fix this? Hoping to receive a valid answer asap.
Vincenzo

回答 (7 件)

Jan
Jan 2017 年 8 月 30 日
編集済み: Jan 2017 年 8 月 30 日
There is no imaginary value for doubles in C. Then sqrt(-1.0) cannot be resolved with anything but NaN.
You are asking for atan2 in the title, but the symbolic expression contains atan. Is this a typo?
Questions for the MathWorks:
This is the public forum. If you want to ask MathWorks, use the "Contact Us" button on this page.

Vincenzo Calabro
Vincenzo Calabro 2017 年 8 月 30 日
編集済み: Vincenzo Calabro 2017 年 8 月 30 日
Thanks to Jan Simon to highlight a typo.
The problem is still there and no valuable answer have been provided so far.
I hope someone will come forward with a solution to this bug.
  2 件のコメント
Karan Gill
Karan Gill 2017 年 8 月 30 日
As Jan mentioned, to contact MathWorks, please use the "Contact Us" button at the top right of the page.
Jan
Jan 2017 年 8 月 30 日
@Vincenzo: At least I can confirm that
log((a * 1i + b) / abs(a * 1i + b)) * -1i
calculates atan2, but only if complex numbers are used. Now you know, why the created C code fails. I consider this information and the hint to contact MathWorks directly as useful. Please post here, what they reply. Thanks.

サインインしてコメントする。


Vincenzo Calabro
Vincenzo Calabro 2018 年 3 月 21 日
Matlab confirmed that is actually a bug and no estimate of time to fix has been provided during last contact I had.
Btw, I made an add-on for the symbolic toolbox (sym2code) in which I solved several bugs and I provided support for C/Mex/C#/Java/Python/LabVIEW targets as well ;)

Christophe Glinel
Christophe Glinel 2019 年 1 月 28 日
I've the same issue with Matlab R2015b, is there is a fix now with the latest version ?

Vincenzo Calabrò
Vincenzo Calabrò 2019 年 1 月 28 日
編集済み: Vincenzo Calabrò 2019 年 1 月 28 日
to the best of my knowledge the bug is still there. you should use a different code generator to avoid this issue. check for example this third party addon:
  1 件のコメント
Christophe Glinel
Christophe Glinel 2019 年 1 月 28 日
Thanks
Is it a commercial addon ?

サインインしてコメントする。


Vincenzo Calabrò
Vincenzo Calabrò 2019 年 1 月 28 日
yes it is a cloud service to generate code from symbolic toolbox into C/C++/C#/Java/Python/Labview.
go to: cybertronics.cloud
to get more info and examples.
  1 件のコメント
Christophe Glinel
Christophe Glinel 2019 年 1 月 29 日
I got an answer from mathworks support and it is fixed in matlab 2018a

サインインしてコメントする。


Vincenzo Calabrò
Vincenzo Calabrò 2019 年 1 月 29 日
oh finally :)
good to know. btw sym2code offers more possibilities ;)

カテゴリ

Help Center および File ExchangeSignal Integrity Kits for Industry Standards についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by