Skip to content
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

asin(2.0) should not return NaN #15344

Open
sagetrac-davidamadore mannequin opened this issue Oct 31, 2013 · 11 comments
Open

asin(2.0) should not return NaN #15344

sagetrac-davidamadore mannequin opened this issue Oct 31, 2013 · 11 comments

Comments

@sagetrac-davidamadore
Copy link
Mannequin

sagetrac-davidamadore mannequin commented Oct 31, 2013

Currently, asin(2.0) returns NaN, whereas asin(CC(2.0)) returns the more expected value of 1.57079632679490 - 1.31695789692482*I (that's π/2 − acosh(2)·I).

I can understand the logic of not wanting to return a complex value for a real argument, but since sqrt(-1.0) already returns 1.0*I, there are already parts of Sage which break that logic.

Conversely, this convention of returning NaN causes many difficulties when plotting functions. For example, plot(imag(asin(x)),(x,0,3)) does not at all return what is expected. And, of course, plot(imag(asin(CC(x))),(x,0,3)) does not work, so one has to write plot(lambda t: imag(asin(CC(t))),(0,3)), which, in this simple example, might be a very minor inconvenience, but can become a great annoyance when dealing with more complicated situations.

The fact that Sage sometimes considers values as reals even though they were obtained by complex computations adds insult to injury:

sage: N(asin((1+I)*(1-I)))
NaN
sage: asin((1.+1.*I)*(1.-1.*I))
1.57079632679490 - 1.31695789692482*I

(if asin(2) persists in returning NaN, then at least (1+I)*(1-I) should refrain from looking too much like an integer until it is explicitly coerced as such).

Component: symbolics

Keywords: functions

Issue created by migration from https://trac.sagemath.org/ticket/15344

@sagetrac-davidamadore sagetrac-davidamadore mannequin added this to the sage-6.1 milestone Oct 31, 2013
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.1, sage-6.2 Jan 30, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.2, sage-6.3 May 6, 2014
@sagetrac-vbraun-spam sagetrac-vbraun-spam mannequin modified the milestones: sage-6.3, sage-6.4 Aug 10, 2014
@rwst rwst changed the title asin(2.0) shound not return NaN asin(2.0) should not return NaN May 15, 2017
@rwst
Copy link
Contributor

rwst commented Jun 14, 2017

comment:5

This touches several issues. Maybe we should agree for now to get different results with a float and a complex/CC type. The same difference exists with real/complex ball arguments. It's not good that there is no easy way to specify argument type when plotting, a better workaround however IMHO is to add epsilon*I, e.g. plot(imag(asin(x+I*1e-10)),(x,0,3)). This should be addressed (complex() symbolic function?) but not here.

There are already other parts where complex is returned on float input, right. However changing the output of asin(2.0) and asin(RBF(2.0)) would mean changing the interface to the mpfr and arb packages that are used here. This is possible.

Now (1+I)*(1-I) and (1.+1.*I)*(1.-1.*I) are completely differently handled than the above because they are symbolic expressions. There were recent changes in Pynac that made asin((1.+1.*I)*(1.-1.*I)) return NaN as well. Adapting this to the above numeric changes would be easy. I think asin(2) should then also return 1/2*pi - I*arccosh(2) instead of arcsin(2).

@videlec
Copy link
Contributor

videlec commented Dec 28, 2017

comment:6

Replying to @rwst:

Maybe we should agree for now to get different results with a float and a complex/CC type. The same difference exists with real/complex ball arguments.

Indeed, asin: RR -> RR (inverse of sin) is different from asin: CC -> CC (a principal value). In the same veine, the real logarithm is not defined for negative inputs

sage: import math, cmath
sage: math.log(-1r)
Traceback (most recent call last):
...
ValueError: math domain error
sage: cmath.log(-1r)
3.141592653589793j

To my mind, Sage is doing wrong here

sage: RR(-1).log()
3.14159265358979*I
sage: RDF(-1).log()
3.141592653589793*I

It's not good that there is no easy way to specify argument type when plotting, [...]

I do not think that this is the real problem. As explained before, acosh, log, etc mean different things (with various domains and ranges). This information should be known by the function (aka it should be a polymorphic function). It should also be possible to bind a well defined mathematical function from the polymorphic one such as

sage: log.bind(domain=RR, range=RR)
The real logarithm on Real Field with 53 bits of precision
sage: log.bind(domain=CC, range=CC)
The principal value of logarithm on Complex Field with 53 bits of precision

The above binded functions should know about there domain, range, singularities, etc.

@rwst
Copy link
Contributor

rwst commented Dec 29, 2017

comment:7

Replying to @videlec:

The above binded functions should know about there domain, range, singularities, etc.

All nice but before even thinking about that this should be fixed:

sage: from sage.sets.set import is_Set
sage: is_Set(RR)
False
sage: is_Set(RealSet(-oo,oo))
False

Or provide custom formal sets representing the reals/complexes.

@rwst
Copy link
Contributor

rwst commented Dec 29, 2017

comment:8

Replying to @rwst:

sage: from sage.sets.set import is_Set
sage: is_Set(RealSet(-oo,oo))
True

Oh my I totally forgot that I already implemented that as part of #24171. I'll extract it and make a separate ticket right now.

@rwst
Copy link
Contributor

rwst commented Dec 29, 2017

comment:9

Please review #24443.

@videlec
Copy link
Contributor

videlec commented Dec 29, 2017

comment:10

Replying to @rwst:

Replying to @videlec:

The above binded functions should know about there domain, range, singularities, etc.

All nice but before even thinking about that this should be fixed:

sage: from sage.sets.set import is_Set
sage: is_Set(RR)
False
sage: is_Set(RealSet(-oo,oo))
False

Or provide custom formal sets representing the reals/complexes.

You did a double mistake here. In Sage RR is not the set of real numbers but of floating point numbers with mantissa on 53 bits.

sage: RR
Real Field with 53 bits of precision

Next, is_Set checks whether the type of RR inherits from Set which is not what you want to check here. You should rather rely on categories

sage: RR in Sets()
True

@rwst
Copy link
Contributor

rwst commented Dec 29, 2017

comment:11

Replying to @videlec:

You did a double mistake here. In Sage RR is not the set of real numbers but of floating point numbers with mantissa on 53 bits.

What good does it to have that domain on a symbolic function versus having a formal real set domain? Having a domain affects not only FP evaluation but also normal immediate evaluation of symbolic argument, and only a formal domain has useful implications.

Next, is_Set checks whether the type of RR inherits from Set which is not what you want to check here. You should rather rely on categories

That shows that the documentation of is_Set is incomplete.

@videlec
Copy link
Contributor

videlec commented Dec 29, 2017

comment:12

I don't even see the point of having is_Set in the global namespace...

@videlec
Copy link
Contributor

videlec commented Dec 29, 2017

comment:13

Replying to @rwst:

Replying to @videlec:

You did a double mistake here. In Sage RR is not the set of real numbers but of floating point numbers with mantissa on 53 bits.

What good does it to have that domain on a symbolic function versus having a formal real set domain? Having a domain affects not only FP evaluation but also normal immediate evaluation of symbolic argument, and only a formal domain has useful implications.

It is good because a formal real set has a lot of concrete implementations RealField(prec), RealBallField(prec), RealIntervalField(prec) and possibly in the future some more symbolic ones.

@rwst
Copy link
Contributor

rwst commented Jan 15, 2018

comment:14

Replying to @videlec:

Replying to @rwst:

Replying to @videlec:

You did a double mistake here. In Sage RR is not the set of real numbers but of floating point numbers with mantissa on 53 bits.

What good does it to have that domain on a symbolic function versus having a formal real set domain? Having a domain affects not only FP evaluation but also normal immediate evaluation of symbolic argument, and only a formal domain has useful implications.

It is good because a formal real set has a lot of concrete implementations RealField(prec), RealBallField(prec), RealIntervalField(prec) and possibly in the future some more symbolic ones.

I don't mind other symbolic domains that are subsets of the formal reals---again, what good is it to have a purely floating-point domain like RealField(53) on a symbolic function?

@rwst
Copy link
Contributor

rwst commented Feb 25, 2018

comment:15

asin(2.0) would be fixed in #24428.

@mkoeppe mkoeppe removed this from the sage-6.4 milestone Dec 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants