This project has moved. For the latest updates, please go here.

Inverse Trig Functions

Aug 7, 2009 at 5:33 AM

Hi,

I'm porting over the Iridium trig class and have a question about the inverse trig functions.  Right now they return NaN instead of a complex number for parts of the real line that should return a complex number (this is consistent with the System.Math functions).  But should we do one of the following instead:

1) Throw an AgrumentOutRanngeException
2) Change their return types to Complex
3) Move the Complex trig functions from the Complex class into the Trig class and then drop the real valued inverse functions.  Since we have an implicit double conversion operator on the Complex class, the complex version would handle real values.

I've implmented 1) but I think 3) might be a better option since all trig functions (real and complex) would be in the Trig class.

Any thoughts?

Thanks,

Marcus

Coordinator
Aug 7, 2009 at 10:20 AM

Hi Marcus,

I vote for 3 as well:

  • To refactor the complex trig functions out of the complex class. However, can we make them extension methods, at least in the complex-domain case?
  • All functions that are close over the real numbers should have an overloaded real->real function (in addition to complex->complex), i.e. all forward functions
  • If a real->complex function implementation is significantly more accurate (less introduced error) and faster, we might want to consider an overloaded real->complex (in addition to complex->complex) as well. Else, just provide complex->complex as suggested.
  • In real-only scenarios, a real->(real|NaN) method can be much easier to work with than real->complex or real->(real|exception). However, the most common inverse functions in this real case are available in System.Math anyway, so I'm fine with dropping that explicit support.
  • Do we plan to support vectorized trigonometric functions?

Thanks,
Chris

Aug 7, 2009 at 11:28 AM

Hi Chris,

OK, I'll make the changes followng your guidlines.

>Do we plan to support vectorized trigonometric functions?

We can in the Apply/Map class.  I'm not sure how to handle it yet if we are using interfaces for the native interop. I don't think it makes to P/Invoke single trig calls (we did it for dnA because Intel IPP provided high accuracy versions - but that won't be true for all the native libraries we plan on wrapping), but for a vector of them it might.

Thanks,

Marcus

Aug 11, 2009 at 12:31 PM
Edited Aug 11, 2009 at 2:26 PM

Finally checked in - took longer than I expected.

I left in the the real->(real|NaN) functions and removed the out of range exceptions I was throwing.  Users can explicilty cast a real to a complex value if they want the complex version.

There are issues with exteme values for some of the complex hyperbolic functions (take a look at the commented out tests).  For example, mpmath returns results such as xe-xxxxxx so I'm testing for 0.0 - but the code is returning a NaN.  NaN might be correct since 0.0 isn't a possible value and the correct answer is outside the range of a double. 

Regards,

Marcus

Coordinator
Aug 11, 2009 at 2:03 PM

Hi Marcus,

I've checked some of the tests with Maple, e.g:

tanh(8388608.+I*0.119209289550780998537e-6) ->  1. + I*2.227774068e-7286259

I pushed a suggestion for a small code change that we would get 1+I*0 in this case as you expected and make all commented out tests succeed:

http://github.com/cdrnet/mathnet-numerics/commit/2df9e4f0d341510968b82d9a53aa580578d3e2d5

What do you think?

Thanks,
Chris

Aug 11, 2009 at 2:22 PM

Hi Chris,

Looks good.  I'm not 100% sure 0.0 is more correct that NaN, but it seems more correct. Please apply it.

Thanks,

Marcus

Coordinator
Aug 11, 2009 at 2:59 PM

Hi Marcus,

Ok, I applied it.

My reasoning was that when x in f(x) is double.PositiveInfinity, it might be a good idea for f(x) to evaluate limit(f(x), x->infinity) instead, which is 0 in this case.

Thanks,
Chris

PS: git issues?

Aug 11, 2009 at 3:08 PM
Edited Aug 11, 2009 at 3:08 PM

Hi Chris,

Makes sense,

>PS: git issues?

I did a rebase, but git kept complaing about a merge conflict with e0dd219 (there shouldn't be a conflict) and no mater how I resolved it, it kept comming back.  Wasted an hour or so, and then I gave up and nuked my repo.  This happens once in a while - my old mv/delete commits come back to haunt me. I need to figure out what I'm doing wrong when I move or delete a file.

Thanks,

Marcus

Coordinator
Aug 12, 2009 at 4:05 PM

I just remembered I never actually posted a link to the small git wiki I started working on:

http://mathnet.opensourcedotnet.info/team/Git.ashx

There might be nothing new for you there, but it might help other and new contributors. Feel free to extend ;)

Thanks,
Chris

Coordinator
Aug 12, 2009 at 9:40 PM

ah this is brillant! Thanks for this. Very useful.

Aug 13, 2009 at 5:59 AM

Yes, that will be very helpful.

Thanks!
Marcus