-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sin and cos inaccurate at arguments with small imaginary components #2889
Comments
For now, perhaps you could use the complex sine and cosine in libgsl, currently wrapped by GSL.jl:
|
The easier solution would be to use the complex versions of these functions in openlibm. I am not sure if I have imported these yet from FreeBSD's msun, but that is easy to do. |
Similar problem with |
Hi @jiahao. I agree that the old tan had the same problem, but I think your new one is also broken. Try for example: julia> tan(complex(2)) julia> tan(2) julia> sin(complex(2))/cos(complex(2)) |
Seems like sinh, cosh, and tanh also have the problem. |
Here is a demo of a tool that can help to check the accuracy of complex step differentiation (and therefore also of functions of complex arguments). I spent the day implementing a new Number type, namely a 'dual number' (see Wikipedia). It is very similar to a complex number, except that the 2nd component is a multiple of 'du', the infinitessimally small 'differential unit', having the property du*du=0. julia> g(x)=-2sin(x/2)_cos(x^2)+log(2^x)-exp(x) So for the new sin() and cos() and these simple arithmetic operations, everything works and agrees. |
Thanks @bsxfan . All the complex trig functions should be ok now --- could you apply your test to confirm? |
@bsxfan, if you haven't already, please take a look at and consider contributing to https://github.com/scidom/AutoDiff.jl. |
I wrote this script https://github.com/scidom/AutoDiff.jl/blob/master/src/dual.jl with the Dual type for representing dual numbers. I also wrote a test in the test folder of the prospective AutoDiff package to test forward automatic differentiation on a univariate function. The |
Julia version: 0.2.0
Examples of problem:
0.0
0.0
Reason: complex.jl does as a first step of its sin(z) and cos(z) implementations: u = exp(imag(z)). This becomes exactly u==1.0 for small imag(z), while the imaginary part of z is not referenced again in the rest of the implementation.
Comparison: Python and MATLAB give non-zero values.
Why this is important:
The 'complex-step differentiation' trick is a powerful and very convenient way of implementing 'forward-mode automatic differentiation'. It can be used to get extremely accurate derivatives of complicated functions, with no programmer effort. For some function f(x), we can get a very accurate derivative at x by doing something like:
A Taylor series expansion will show why. Currectly this trick fails with Julia's complex sin and cos implementations. (It does work for log and exp).
The text was updated successfully, but these errors were encountered: