ccode atan2 generates nan
조회 수: 11 (최근 30일)
이전 댓글 표시
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
댓글 수: 0
답변 (7개)
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.
댓글 수: 0
Vincenzo Calabro
2017년 8월 30일
편집: Vincenzo Calabro
2017년 8월 30일
댓글 수: 2
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
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.
Christophe Glinel
2019년 1월 28일
I've the same issue with Matlab R2015b, is there is a fix now with the latest version ?
댓글 수: 0
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:
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
2019년 1월 29일
I got an answer from mathworks support and it is fixed in matlab 2018a
Vincenzo Calabrò
2019년 1월 29일
oh finally :)
good to know. btw sym2code offers more possibilities ;)
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Signal Integrity Kits for Industry Standards에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!