#12074 closed enhancement (fixed)
real nth root function
Reported by: | burcin | Owned by: | burcin |
---|---|---|---|
Priority: | minor | Milestone: | sage-9.2 |
Component: | symbolics | Keywords: | |
Cc: | mjo, kcrisman, karsten.naert@…, eviatarbach, slelievre | Merged in: | |
Authors: | Burcin Erocal, Kwankyu Lee | Reviewers: | Karl-Dieter Crisman, Nils Bruin, Kwankyu Lee |
Report Upstream: | N/A | Work issues: | |
Branch: | f8cb7a0 (Commits, GitHub, GitLab) | Commit: | |
Dependencies: | Stopgaps: |
Description (last modified by )
See sage-devel threads at:
http://groups.google.com/group/sage-devel/t/cea9b562ea49c9c1
and
https://groups.google.com/forum/#!topic/sage-devel/Q8VLKBypcJk
Attachments (1)
Change History (55)
comment:1 Changed 10 years ago by
- Cc kcrisman added
- Work issues set to needs tests and documentation
comment:2 follow-up: ↓ 3 Changed 10 years ago by
Changed 10 years ago by
comment:3 in reply to: ↑ 2 Changed 10 years ago by
Replying to jdemeyer:
Is there any chance this could be made into a function that we can do calculus with, like computing derivatives, integrals, solving equations... (I'm afraid the answer will be no though because we need maxima).
This is already a symbolic function, so it plays well with symbolics generally (as opposed to piecewise functions for instance):
sage: v = nth_root(x,3) sage: v*sin(x) + x^2 x^2 + real_nth_root(x, 3)*sin(x)
I updated the patch to add custom exponentiation and derivative methods as well:
sage: v^2 real_nth_root(x, 3/2) sage: v*v real_nth_root(x, 3/2) sage: v.diff(x) 1/3*real_nth_root(x, -3/2)
This all needs a lot of work of course.
For integration and solving equations we call out to maxima. One way to get sensible results from these calls would be to convert this function to a regular (base)^(exp)
representation when passing it to maxima. I don't think there is any way to read it back from the maxima result though.
comment:4 Changed 10 years ago by
- Cc karsten.naert@… added
comment:5 Changed 9 years ago by
- Cc eviatarbach added
comment:6 Changed 9 years ago by
- Milestone changed from sage-5.11 to sage-5.12
comment:7 Changed 8 years ago by
- Milestone changed from sage-6.1 to sage-6.2
comment:8 Changed 8 years ago by
- Milestone changed from sage-6.2 to sage-6.3
comment:9 Changed 8 years ago by
- Milestone changed from sage-6.3 to sage-6.4
comment:10 Changed 3 years ago by
- Cc slelievre added
- Milestone changed from sage-6.4 to sage-wishlist
See also sympy's real_root
comment:11 Changed 2 years ago by
There is some interest in this again, due to an upcoming book's 2nd edition.
Sympy's solution may be more elegant in some ways, because it uses Abs(x)**(1/3)*sign(x)
for real_root(x,3)
, apparently. If that solution (in Sage, of course, with translations to Sympy) has better support overall in Sage we could just do that instead (for odd roots).
Here's the full Sympy code. They have better handling of complicated piecewise things, I guess.
from sympy.functions.elementary.complexes import Abs, im, sign from sympy.functions.elementary.piecewise import Piecewise if n is not None: return Piecewise( (root(arg, n, evaluate=evaluate), Or(Eq(n, S.One), Eq(n, S.NegativeOne))), (Mul(sign(arg), root(Abs(arg), n, evaluate=evaluate), evaluate=evaluate), And(Eq(im(arg), S.Zero), Eq(Mod(n, 2), S.One))), (root(arg, n, evaluate=evaluate), True)) rv = sympify(arg) n1pow = Transform(lambda x: -(-x.base)**x.exp, lambda x: x.is_Pow and x.base.is_negative and x.exp.is_Rational and x.exp.p == 1 and x.exp.q % 2) return rv.xreplace(n1pow)
comment:12 Changed 2 years ago by
- Branch set to public/12074
comment:13 Changed 2 years ago by
- Commit set to 5028e22e1d4bbd112a14983efd13f7aa43adf168
Branch pushed to git repo; I updated commit sha1. New commits:
5028e22 | Add real_nth_root symbolic function
|
comment:14 Changed 2 years ago by
Revived Burcin's implementation of real_nth_root
symbolic function.
It is in public. Feel free to improve.
comment:15 Changed 2 years ago by
- Keywords nth_root removed
- Milestone changed from sage-wishlist to sage-9.2
- Work issues needs tests and documentation deleted
comment:16 Changed 2 years ago by
comment:17 Changed 2 years ago by
- Status changed from new to needs_review
comment:18 Changed 2 years ago by
- Description modified (diff)
comment:19 follow-up: ↓ 24 Changed 2 years ago by
Kwankyu (관규?), thanks so much for getting that ball rolling, and the doctests/doc looks good so far.
Here are some questions/comments (for anyone, not necessarily for klee):
- See this list of plot methods for this in the plot doc. We should add this, perhaps as the first-order approximation.
- The file faq-usage.rst also should be amended since it mentions the same issue.
- Maybe even there should be a plot example in this file, and then a link to this function from the plot doc?
- Does this one work with derivatives/integrals? Maybe in the meantime we don't need the custom method.
- Apparently Mathematica now has something like this, called Surd which, while perhaps technically a correct name, is not exactly inspiring to anyone who has taken math since 1950 ... Perhaps this is because Maple also has the same name though not capitalized. I like the Sage/Sympy name much better, but anyway these can be added to the conversions. (I don't think Maxima has an equivalent for now.)
comment:20 follow-ups: ↓ 25 ↓ 31 Changed 2 years ago by
- Cc mjo added
The current behavior of integer/float exponentiation is due to python, I guess?
$ python Python 3.7.7 (default, May 8 2020, 10:21:17) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> (-1)**(1/3) (0.5000000000000001+0.8660254037844386j)
Otherwise the question can be asked: why not make that return real numbers when the argument is real? Which leads me to this question: would it make sense to call this function nth_root
, and to have it return the real/complex answer depending on whether or not the argument is real/complex?
(I also like having the codomain of a function be explicit, so I'm not really advocating for this, just wondering out loud.)
comment:21 follow-up: ↓ 26 Changed 2 years ago by
Some comments:
- I think evalf needs some care to work properly on real ball fields and real interval fields.
- I think we need a derivative implementation. I'd say just the formal rule
d/dx real_nth_root(x,n) = 1/n*sgn(x)*real_nth_root(x,n)^(1/n-1)
. Naturally, we don't have to support differentiation with respect to the second variable. - I think
real_nth_root(x,n)^m
should not simplify toreal_nth_root(x^m,n)
. For instance, forreal_nth_root(-1,2)^2
this goes wrong.
comment:22 follow-up: ↓ 27 Changed 2 years ago by
More concretely, then, for this ticket:
- Current branch + things that are probably necessary just to use:
- Derivative and evaluation (can follow Sympy or Nils with the former, perhaps). Can we just use the syntax in Burcin's patch for the derivative, or do we no longer have that underscore method?
- I can't remember if we support a custom integration but could include something in the documentation saying to use Sympy if you have to integrate?
- Possibly fix the simplification - is the one in the branch the same as Burcin's, or Nils'? (Indeed, should we have this function work for
n
even and negativex
?) - Might as well add the extra conversions.
After all, the point of this function (note how Sympy and the Ms handle this) is for something we know doesn't really behave well with respect to branch cuts etc., intentionally. So no one should necessarily be using it for production symbolics, but rather really mostly just for classroom usage in situations (which are legion) where we have to explicitly exclude complex stuff. Luckily for the logarithm this is a little easier to hide from the student, except for in an antiderivative of 1/x, but here it's not as "nice".
Then a separate ticket could do:
- Improve things like simplification/codomains from the most necessary.
comment:23 Changed 2 years ago by
- Commit changed from 5028e22e1d4bbd112a14983efd13f7aa43adf168 to e188fa24b1857152b234551950eab526870811ca
Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:
e188fa2 | Add real_nth_root symbolic function
|
comment:24 in reply to: ↑ 19 Changed 2 years ago by
Replying to kcrisman:
Kwankyu (관규?)
Correct!
Here are some questions/comments (for anyone, not necessarily for klee):
- See this list of plot methods for this in the plot doc. We should add this, perhaps as the first-order approximation.
Done.
- The file faq-usage.rst also should be amended since it mentions the same issue.
Done.
- Maybe even there should be a plot example in this file, and then a link to this function from the plot doc?
Made a link from the plot doc.
- Does this one work with derivatives/integrals? Maybe in the meantime we don't need the custom method.
Almost.
sage: f = real_nth_root(x,3) sage: f.diff() 1/3*real_nth_root(x^(-2), 3) sage: f.integrate(x) integrate(abs(x)^(1/3)*sgn(x), x) sage: _.diff() abs(x)^(1/3)*sgn(x)
- Apparently Mathematica now has something like this, called Surd which, while perhaps technically a correct name, is not exactly inspiring to anyone who has taken math since 1950 ... Perhaps this is because Maple also has the same name though not capitalized. I like the Sage/Sympy name much better, but anyway these can be added to the conversions. (I don't think Maxima has an equivalent for now.)
Done. But I could not test them as I have no Mathematica nor Maple.
comment:25 in reply to: ↑ 20 Changed 2 years ago by
Replying to mjo:
The current behavior of integer/float exponentiation is due to python, I guess?
$ python Python 3.7.7 (default, May 8 2020, 10:21:17) [GCC 9.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> (-1)**(1/3) (0.5000000000000001+0.8660254037844386j)
This convention is shared by other symbolic algebra systems.
comment:26 in reply to: ↑ 21 Changed 2 years ago by
Replying to nbruin:
Some comments:
- I think evalf needs some care to work properly on real ball fields and real interval fields.
Now it works for real ball fields:
sage: a = RBF(-2) sage: real_nth_root(a, 3) [-1.259921049894873 +/- 3.92e-16]
and for real interval fields:
sage: a = RIF(-2) sage: real_nth_root(a, 3) -1.259921049894873?
- I think we need a derivative implementation. I'd say just the formal rule
d/dx real_nth_root(x,n) = 1/n*sgn(x)*real_nth_root(x,n)^(1/n-1)
. Naturally, we don't have to support differentiation with respect to the second variable.
I guess you meant d/dx real_nth_root(x,n) = 1/n*real_nth_root(x,n)^(1-n)
. Done.
- I think
real_nth_root(x,n)^m
should not simplify toreal_nth_root(x^m,n)
. For instance, forreal_nth_root(-1,2)^2
this goes wrong.
real_nth_root(-1,2)
now raises ValueError
. The simplification is valid for other cases.
comment:27 in reply to: ↑ 22 Changed 2 years ago by
Replying to kcrisman:
After all, the point of this function (note how Sympy and the Ms handle this) is for something we know doesn't really behave well with respect to branch cuts etc., intentionally. So no one should necessarily be using it for production symbolics, but rather really mostly just for classroom usage in situations (which are legion) where we have to explicitly exclude complex stuff. Luckily for the logarithm this is a little easier to hide from the student, except for in an antiderivative of 1/x, but here it's not as "nice".
School math just works:
sage: f = real_nth_root(x^2, 2) sage: g = f.diff() sage: f.plot() Launched png viewer for Graphics object consisting of 1 graphics primitive sage: g.plot() Launched png viewer for Graphics object consisting of 1 graphics primitive
comment:28 Changed 2 years ago by
- Commit changed from e188fa24b1857152b234551950eab526870811ca to 7cef50b2542c2b90e8a60b88beb6fc6d09d0d380
Branch pushed to git repo; I updated commit sha1. New commits:
7cef50b | Fix a typo in FAQ
|
comment:29 Changed 2 years ago by
Okay, this is ready enough that I will (try to) upgrade my Sage develop branch just for this ticket. I still have a few thoughts - notably about seeing whether we can get Sympy to give us an integral for this, and about the derivative. Maybe we can get someone to even test out the M* conversion... Thanks for this work. Only took us how many years?
comment:30 Changed 2 years ago by
- Commit changed from 7cef50b2542c2b90e8a60b88beb6fc6d09d0d380 to d12ab31283e8bf8905fb1534d653df97619ba575
Branch pushed to git repo; I updated commit sha1. New commits:
d12ab31 | Fix for a pyflakes warning
|
comment:31 in reply to: ↑ 20 ; follow-up: ↓ 32 Changed 2 years ago by
Replying to mjo:
Otherwise the question can be asked: why not make that return real numbers when the argument is real? Which leads me to this question: would it make sense to call this function
nth_root
, and to have it return the real/complex answer depending on whether or not the argument is real/complex?
It is possible to get this behavior
sage: f = x^(1/3) sage: f(-8) 2*(-1)^(1/3) sage: f(-2.) 0.629960524947437 + 1.09112363597172*I sage: assume(x, 'real') sage: g = x^(1/3) sage: g(-2.) -1.25992104989487 sage: g real_nth_root(x, 3) sage: g.diff() 1/3*real_nth_root(x^(-2), 3) sage: g.plot() Launched png viewer for Graphics object consisting of 1 graphics primitive
by injecting some code into expression.pyx
. The question is whether we want this.
comment:32 in reply to: ↑ 31 ; follow-up: ↓ 36 Changed 2 years ago by
by injecting some code into
expression.pyx
. The question is whether we want this.
I'm gonna say no on that - not without some healthy sage-devel discussion. I do think some people use the assume command for precisely this purpose, though.
I'm going to look at this branch later today, thank you again for putting it in "modern" shape!
comment:33 follow-up: ↓ 37 Changed 2 years ago by
Here come a bunch of questions now that I have played around with this. They don't necessarily all need changes, but I think they are reasonable to ask even if they end up not needing change. But I'm not letting the perfect be the enemy of the good; as long as we document and open new tickets, that would be the important part.
- Do we want a latex method? E.g.
latex_name=r"\mathrm{abs}"
used elsewhere in this file. This is obviously not ideal:sage: latex(F) {\rm real}_{{\rm nth}_{{\rm root}}}\left(x, 5\right)
But I'm not sure whether just using the usual root syntax is "correct" either since we have a different function now. - Integration, perhaps surprisingly, works, as you mention above:
sage: f = real_nth_root(x,3) sage: f.diff() 1/3*real_nth_root(x^(-2), 3) sage: f.integrate(x) integrate(abs(x)^(1/3)*sgn(x), x) sage: _.diff() abs(x)^(1/3)*sgn(x)
Apparently integration now tries Maxima, Giac, and then Sympy, so that explains it. We should probably document this behavior. - Upon further consideration, maybe the derivative can be a little better. Because aren't we sort of assuming this is real input? Maybe we aren't. Here is Sympy.
>>> from sympy import root, real_root, Rational >>> from sympy.abc import x, n >>> real_root(x,5) Piecewise((Abs(x)**(1/5)*sign(x), Eq(im(x), 0)), (x**(1/5), True)) >>> diff(real_root(x,5),x) Piecewise((Abs(x)**(1/5)*Derivative(sign(x), x) + (re(x)*Derivative(re(x), x) + im(x)*Derivative(im(x), x))*sign(x)**2/(5*x*Abs(x)**(4/5)), Eq(im(x), 0)), (1/(5*x**(4/5)), True)) >>> x = Symbol('x', real=True) >>> diff(real_root(x,5),x) 2*Abs(x)**(1/5)*DiracDelta(x) + sign(x)**2/(5*Abs(x)**(4/5))
and here is Sagesage: G = abs(x)^(1/5)*sgn(x) sage: G abs(x)^(1/5)*sgn(x) sage: G.diff(x) 2*abs(x)^(1/5)*dirac_delta(x) + 1/10*(x + conjugate(x))*sgn(x)/abs(x)^(9/5) sage: G.diff(x).simplify() 2*abs(x)^(1/5)*dirac_delta(x) + 1/5*x*sgn(x)/abs(x)^(9/5)
at leastsage: assume(x,'real') sage: F.diff(x) 1/5*real_nth_root(x^(-4), 5)
should mimic this, if not perhaps always. Any thoughts on this? - To elaborate, Sympy's function somehow allows complex input, but do we want to?
sage: real_nth_root(3.*I,5) 1.18476052767182 + 0.384952030759866*I # should this happen?
That's of course related to Nils question regarding negative input too.sage: H = real_nth_root(x,2) sage: (H.subs(x=-1))^2 --------------------------------------------------------------------------- ... ValueError: no real nth root of negative real number with even n sage: ((H)^2).subs(x=-1) 1
I'm not sure the latter should be allowed or not.
comment:34 Changed 2 years ago by
sage -t src/doc/en/faq/faq-usage.rst ********************************************************************** File "src/doc/en/faq/faq-usage.rst", line 692, in doc.en.faq.faq-usage Failed example: plot(x^(1/3), (x, -1, 1)) Expected nothing Got: verbose 0 (3834: plot.py, generate_plot_points) WARNING: When plotting, failed to evaluate function at 100 points. verbose 0 (3834: plot.py, generate_plot_points) Last error message: 'can't convert complex to float' Graphics object consisting of 1 graphics primitive **********************************************************************
So you'll have to make that not tested (I think there is a way to mark it as such other than # not tested
but anyway...).
comment:35 Changed 2 years ago by
- Status changed from needs_review to needs_work
comment:36 in reply to: ↑ 32 ; follow-up: ↓ 39 Changed 2 years ago by
Replying to kcrisman:
by injecting some code into
expression.pyx
. The question is whether we want this.I'm gonna say no on that - not without some healthy sage-devel discussion. I do think some people use the assume command for precisely this purpose, though.
Injecting the code incur many doctest failures in other places. So I give up this idea.
comment:37 in reply to: ↑ 33 ; follow-up: ↓ 40 Changed 2 years ago by
Replying to kcrisman:
- Do we want a latex method? E.g.
latex_name=r"\mathrm{abs}"
used elsewhere in this file. This is obviously not ideal:sage: latex(F) {\rm real}_{{\rm nth}_{{\rm root}}}\left(x, 5\right)But I'm not sure whether just using the usual root syntax is "correct" either since we have a different function now. Usingabs(x)^(1/3)*sgn(x)
doesn't work for evenn
, else I'd recommend that for latex.
I see real_nth_root
as representing the real function x1/n with variable x taking real numbers (possibly negative for odd n). The latex print is for humans. So why not just print x1/n?
- Integration, perhaps surprisingly, works, as you mention above:
sage: f = real_nth_root(x,3) sage: f.diff() 1/3*real_nth_root(x^(-2), 3) sage: f.integrate(x) integrate(abs(x)^(1/3)*sgn(x), x) sage: _.diff() abs(x)^(1/3)*sgn(x)Apparently integration now tries Maxima, Giac, and then Sympy, so that explains it. We should probably document this behavior.
Done.
- Upon further consideration, maybe the derivative can be a little better. Because aren't we sort of assuming this is real input? Maybe we aren't. Here is Sympy.
>>> from sympy import root, real_root, Rational >>> from sympy.abc import x, n >>> real_root(x,5) Piecewise((Abs(x)**(1/5)*sign(x), Eq(im(x), 0)), (x**(1/5), True)) >>> diff(real_root(x,5),x) Piecewise((Abs(x)**(1/5)*Derivative(sign(x), x) + (re(x)*Derivative(re(x), x) + im(x)*Derivative(im(x), x))*sign(x)**2/(5*x*Abs(x)**(4/5)), Eq(im(x), 0)), (1/(5*x**(4/5)), True)) >>> x = Symbol('x', real=True) >>> diff(real_root(x,5),x) 2*Abs(x)**(1/5)*DiracDelta(x) + sign(x)**2/(5*Abs(x)**(4/5))and here is Sagesage: G = abs(x)^(1/5)*sgn(x) sage: G abs(x)^(1/5)*sgn(x) sage: G.diff(x) 2*abs(x)^(1/5)*dirac_delta(x) + 1/10*(x + conjugate(x))*sgn(x)/abs(x)^(9/5) sage: G.diff(x).simplify() 2*abs(x)^(1/5)*dirac_delta(x) + 1/5*x*sgn(x)/abs(x)^(9/5)at leastsage: assume(x,'real') sage: F.diff(x) 1/5*real_nth_root(x^(-4), 5)should mimic this, if not perhaps always. Any thoughts on this?
I don't get your concern. I think there is nothing wrong with
sage: f = real_nth_root(x,3) sage: f.diff() 1/3*real_nth_root(x^(-2), 3)
- To elaborate, Sympy's function somehow allows complex input, but do we want to?
sage: real_nth_root(3.*I,5) 1.18476052767182 + 0.384952030759866*I # should this happen?That's of course related to Nils question regarding negative input too.sage: H = real_nth_root(x,2) sage: (H.subs(x=-1))^2 --------------------------------------------------------------------------- ... ValueError: no real nth root of negative real number with even n sage: ((H)^2).subs(x=-1) 1I'm not sure the latter should be allowed or not.
No. real_nth_root
takes real input and outputs real. For the symbolic function 1/x
, we assume x
takes nonzero value. Likewise, we assume real value x for real_nth_root(x, 3)
.
comment:38 Changed 2 years ago by
- Commit changed from d12ab31283e8bf8905fb1534d653df97619ba575 to 00380b09135e8171593108059f17490a23f554ad
Branch pushed to git repo; I updated commit sha1. New commits:
00380b0 | Fixes for reviewer comments
|
comment:39 in reply to: ↑ 36 ; follow-up: ↓ 41 Changed 2 years ago by
Replying to klee:
Injecting the code incur many doctest failures in other places. So I give up this idea.
I was thinking of something simpler, like
sage: nth_root(RR(-1), 3) -1.00000000000000 sage: nth_root(CC(-1), 3) 0.500000000000000 + 0.866025403784439*I
comment:40 in reply to: ↑ 37 ; follow-up: ↓ 46 Changed 2 years ago by
Thanks for all these fixes - we are converging :-) Couple more questions/comments:
- I don't think you needed to make this one not tested; it should have passed fine. Only the subsequent one would have thrown an error.
- sage: plot(real_nth_root(x, 3), (x, -1, 1)) - Graphics object consisting of 1 graphics primitive + sage: plot(real_nth_root(x, 3), (x, -1, 1)) # not tested
- latex:
I see
real_nth_root
as representing the real function x1/n with variable x taking real numbers (possibly negative for odd n). The latex print is for humans. So why not just print x1/n?
- calculus:
Done.
_init_
method doc (and apparently not the tests?).
If you are up for it, I'd recommend making a more "narrative" structure which includes examples of calculus, plotting, etc., more like real_part does. If you'd prefer me to do that, I can - might just take a little longer as I recall how to add to a public branch :-)
- diff output:
sage: assume(x,'real') sage: F.diff(x) 1/5*real_nth_root(x^(-4), 5)
should mimic this, if not perhaps always. Any thoughts on this?
I don't get your concern. I think there is nothing wrong with
sage: f = real_nth_root(x,3) sage: f.diff() 1/3*real_nth_root(x^(-2), 3)
n
is odd, though,2*abs(x)^(1/5)*dirac_delta(x) + 1/5*x*sgn(x)/abs(x)^(9/5)
is somehow "better", and available. Just thinking out loud; could be for a followup ticket.
- input:
sage: H = real_nth_root(x,2) sage: (H.subs(x=-1))^2 --------------------------------------------------------------------------- ... ValueError: no real nth root of negative real number with even n sage: ((H)^2).subs(x=-1) 1
I'm not sure the latter should be allowed or not.
No.
real_nth_root
takes real input and outputs real. For the symbolic function1/x
, we assumex
takes nonzero value. Likewise, we assume real value x forreal_nth_root(x, 3)
.x=-1
to be evaluated? Because1/x
blows up if we injectx=0
- though then again Sage simplifies1/x*x =1
which isn't technically correct. Anyway, I think this is Nils' point.
comment:41 in reply to: ↑ 39 ; follow-up: ↓ 42 Changed 2 years ago by
I was thinking of something simpler, like
sage: nth_root(RR(-1), 3) -1.00000000000000 sage: nth_root(CC(-1), 3) 0.500000000000000 + 0.866025403784439*I
I feel like this would be another ticket, and need sage-devel discussion. This ticket is about adding something to aid in plotting, and then making sure it has enough bells and whistles that it doesn't end up causing confusion. I'm a little uncomfortable with this since
sage: RR(-1) == CC(-1) True
and the point of the function is strictly for pedagogical purposes (which should also be made clear in the documentation).
comment:42 in reply to: ↑ 41 ; follow-up: ↓ 43 Changed 2 years ago by
Replying to kcrisman:
I feel like this would be another ticket, and need sage-devel discussion. This ticket is about adding something to aid in plotting, and then making sure it has enough bells and whistles that it doesn't end up causing confusion. I'm a little uncomfortable with this since
sage: RR(-1) == CC(-1) Trueand the point of the function is strictly for pedagogical purposes (which should also be made clear in the documentation).
We run into that same problem whenever we have a subclass method that does something different from its superclass method. I was only trying to clear up my previous suggestion. If the authors/reviewers don't think this is a good idea, feel free to ignore it.
comment:43 in reply to: ↑ 42 ; follow-up: ↓ 44 Changed 2 years ago by
I was only trying to clear up my previous suggestion.
Fair enough.
If the authors/reviewers don't think this is a good idea, feel free to ignore it.
If this gets merged, why not open a new ticket for an nth_root
function if you think it's more generally useful? SymPy has some explicit warnings about these things for its function but we could follow that model (its function is intended for more than the current ticket, I believe).
comment:44 in reply to: ↑ 43 Changed 2 years ago by
Replying to kcrisman:
If this gets merged, why not open a new ticket for an
nth_root
function if you think it's more generally useful? SymPy has some explicit warnings about these things for its function but we could follow that model (its function is intended for more than the current ticket, I believe).
I'm not 100% convinced it's the right thing to do either. Especially if we already have real_nth_root
, then we have ^(1/n)
for the complex root, and... presumably you know which one you want? I dunno. But until someone finds the existing methods lacking, adding them proactively just increases the chances that we'll have gotten it wrong when the need does arise.
comment:45 Changed 2 years ago by
- Commit changed from 00380b09135e8171593108059f17490a23f554ad to f8cb7a0429c2e696dc69db8466ecc077b0bf0f32
Branch pushed to git repo; I updated commit sha1. New commits:
f8cb7a0 | Refactored docs
|
comment:46 in reply to: ↑ 40 ; follow-up: ↓ 47 Changed 2 years ago by
Replying to kcrisman:
However, that brings up the related issue that the online documentation is only going to show the
_init_
method doc (and apparently not the tests?).If you are up for it, I'd recommend making a more "narrative" structure which includes examples of calculus, plotting, etc., more like real_part does. If you'd prefer me to do that, I can - might just take a little longer as I recall how to add to a public branch :-)
Done.
- input:
Wait, so are you saying that we should disallow that function withsage: H = real_nth_root(x,2) sage: (H.subs(x=-1))^2 --------------------------------------------------------------------------- ... ValueError: no real nth root of negative real number with even n sage: ((H)^2).subs(x=-1) 1I'm not sure the latter should be allowed or not.
No.
real_nth_root
takes real input and outputs real. For the symbolic function1/x
, we assumex
takes nonzero value. Likewise, we assume real value x forreal_nth_root(x, 3)
.x=-1
to be evaluated?
Yes. What should real_nth_root(-1, 2)
evaluate to?
Sage simplifies
1/x*x =1
which isn't technically correct.
Why is it not correct? It is correct but you should not evaluate 1/x at x=0.
comment:47 in reply to: ↑ 46 ; follow-up: ↓ 48 Changed 2 years ago by
Done.
Thanks, I'll check that out momentarily to confirm it builds properly. Looks good so far.
- input:
Wait, so are you saying that we should disallow that function withsage: H = real_nth_root(x,2) sage: (H.subs(x=-1))^2 --------------------------------------------------------------------------- ... ValueError: no real nth root of negative real number with even n sage: ((H)^2).subs(x=-1) 1I'm not sure the latter should be allowed or not.
No.
real_nth_root
takes real input and outputs real. For the symbolic function1/x
, we assumex
takes nonzero value. Likewise, we assume real value x forreal_nth_root(x, 3)
.x=-1
to be evaluated?Yes. What should
real_nth_root(-1, 2)
evaluate to?
I meant ((real_nth_root(x, 2))^2).subs(x=-1)
. Are you saying this should be allowed or not allowed?
Sage simplifies
1/x*x =1
which isn't technically correct.Why is it not correct? It is correct but you should not evaluate 1/x at x=0.
Depends on whether such expressions are meant to include domains - but anyway that is not directly relevant.
comment:48 in reply to: ↑ 47 ; follow-up: ↓ 49 Changed 2 years ago by
- Reviewers set to Karl-Dieter Crisman, Nils Bruin, Kwanyku Lee
Thank you for all the good work - this is really long since overdue.
Yes. What should
real_nth_root(-1, 2)
evaluate to?I meant
((real_nth_root(x, 2))^2).subs(x=-1)
. Are you saying this should be allowed or not allowed?
Again, see comment:21. It is good that real_nth_root(-1, 2)
does not evaluate, but the question is whether the symbolic simplification should do this when ((real_nth_root(x, 2))^2)
doesn't really make sense for x=-1
. Here is another example.
sage: ((real_nth_root(x, 2))^2) real_nth_root(x^2, 2) sage: f(x) = _ sage: f x |--> real_nth_root(x^2, 2) sage: f(-1) 1
I think if in _power_
we had something like
if exp % 2 == 1: return self(base**power_param, exp) else: ....
that might solve it (suitable tests included). What do you think? Unfortunately the most naive things I tried for the else
clause led to nasty errors; I wasted about 20 minutes on abort errors, so I have a feeling that what I did leads to Pynac problems. (Anyone else interested in this particular question other than me or Kwankyu?)
Probably we don't need to assert
that n
is a positive integer since the documentation clearly says so and since why would anyone use it any other way? (Famous last words.)
comment:49 in reply to: ↑ 48 ; follow-up: ↓ 50 Changed 2 years ago by
Replying to kcrisman:
Thank you for all the good work - this is really long since overdue.
Yes. What should
real_nth_root(-1, 2)
evaluate to?I meant
((real_nth_root(x, 2))^2).subs(x=-1)
. Are you saying this should be allowed or not allowed?
Allowed. This is exactly the same problem with
sage: (1/x)*x 1 sage: _.subs(x=0) 1
which we don't bother to fix in any way. If you argue the cases are different because the difference of the domains of definition is of measure zero, then how about this:
sage: f = 1/floor(abs(x))*floor(abs(x)) sage: f.subs(x=1/2) 1
Perhaps it is important that these things do not cause real problems because the domain of definition never gets smaller from the initial domain of definition that one starts with.
comment:50 in reply to: ↑ 49 ; follow-up: ↓ 51 Changed 2 years ago by
- Status changed from needs_work to positive_review
Allowed. This is exactly the same problem with
Okay, I'll roll with that. Haven't heard from any of the other people regarding that here, I don't have a big commitment here since this isn't really switchable to "regular" root functions. Thank you!
comment:51 in reply to: ↑ 50 Changed 2 years ago by
Thank you!
comment:52 Changed 23 months ago by
Thank you very much for making this happen!
comment:53 Changed 23 months ago by
- Branch changed from public/12074 to f8cb7a0429c2e696dc69db8466ecc077b0bf0f32
- Resolution set to fixed
- Status changed from positive_review to closed
comment:54 Changed 19 months ago by
- Commit f8cb7a0429c2e696dc69db8466ecc077b0bf0f32 deleted
- Reviewers changed from Karl-Dieter Crisman, Nils Bruin, Kwanyku Lee to Karl-Dieter Crisman, Nils Bruin, Kwankyu Lee
Is there any chance this could be made into a function that we can do calculus with, like computing derivatives, integrals, solving equations... (I'm afraid the answer will be no though because we need maxima).