ccode atan2 generates nan

6 Ansichten (letzte 30 Tage)
Vincenzo Calabro
Vincenzo Calabro am 30 Aug. 2017
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

Antworten (7)

Jan
Jan am 30 Aug. 2017
Bearbeitet: Jan am 30 Aug. 2017
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 am 30 Aug. 2017
Bearbeitet: Vincenzo Calabro am 30 Aug. 2017
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 Kommentare
Karan Gill
Karan Gill am 30 Aug. 2017
As Jan mentioned, to contact MathWorks, please use the "Contact Us" button at the top right of the page.
Jan
Jan am 30 Aug. 2017
@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.

Melden Sie sich an, um zu kommentieren.


Vincenzo Calabro
Vincenzo Calabro am 21 Mär. 2018
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 am 28 Jan. 2019
I've the same issue with Matlab R2015b, is there is a fix now with the latest version ?

Vincenzo Calabrò
Vincenzo Calabrò am 28 Jan. 2019
Bearbeitet: Vincenzo Calabrò am 28 Jan. 2019
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 Kommentar
Christophe Glinel
Christophe Glinel am 28 Jan. 2019
Thanks
Is it a commercial addon ?

Melden Sie sich an, um zu kommentieren.


Vincenzo Calabrò
Vincenzo Calabrò am 28 Jan. 2019
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 Kommentar
Christophe Glinel
Christophe Glinel am 29 Jan. 2019
I got an answer from mathworks support and it is fixed in matlab 2018a

Melden Sie sich an, um zu kommentieren.


Vincenzo Calabrò
Vincenzo Calabrò am 29 Jan. 2019
oh finally :)
good to know. btw sym2code offers more possibilities ;)

Kategorien

Mehr zu Signal Integrity Kits for Industry Standards finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by