Also, Fraction(1) for the second case would be flat-out wrong.
Jeroen Demeyer wrote:
> On 2018-08-30 06:39, Neil Girdhar wrote:
>
>> I'd like these to be Fraction(1), Fraction(1), and Fraction(0).
>
> Why? I cannot think of any natural use case why you would want Fractions
> for a few special cases on an operation which returns non-Fractions
> generically.
Also, Fraction(1) for the second case would be flat-out wrong.
--
Greg
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
--
---
You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/aZIHpPhe0mw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python-ideas...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Jonathan Goble wrote:
> How? Raising something to the 2/3 power means squaring it and then
> taking the cube root of it.
On reflection, "wrong" is not quite accurate. A better
word might be "surprising".
(-1) ** (2/3) == 1 would imply that 1 ** (3/2) == -1.
I suppose that could be considered true if you take the
negative solution of the square root, but it seems a
bit strange, and it's not what Python gives you for
the result of 1 ** (3/2).
If you want a solution that round-trips, you need
complex numbers.
That's what Python does when you use
floats. Making Fractions do something different would
make it inconsistent with floats.
My calculator (which only does real floats) reports an
error when trying to evaluate (-1) ** (2/3).
--
Greg
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
On Thu, 30 Aug 2018 at 08:38, Neil Girdhar <miste...@gmail.com> wrote:
>
> There are a lot of misunderstandings in this thread. It's probably best to start by reading up on the roots of unity (https://en.wikipedia.org/wiki/Root_of_unity). The key ideas are that a real number has two complex square roots, three complex cube roots, and so on.
The complexities of fractional powers aside, the type of a result
should not depend on the values of the arguments. So I'm -1 on this
change for that reason alone.
Questions of which root it's appropriate to take are separate, and IMO
the sensible option is to follow the behaviour of float, for which we
have
>>> (-1)**(2/3)
(-0.4999999999999998+0.8660254037844387j)
I think this may be a hard problem, that looks easy.
I'm used to using a number theory computer algebra system
https://pari.math.u-bordeaux.fr/. Here's what it does with your
examples. (First I show that it's default number type is whole numbers
and fractions.)
$ gp
GP/PARI CALCULATOR Version
2.5.5 (released)
? 1/2 + 1/2
%1 = 1
? 2^3
%2 = 8
? 2^(6/2)
%3 = 8
? 4^(1/2)
%4 = 2.0000000000000000000000000000000000000
? 1^(2/3)
%5 = 1.0000000000000000000000000000000000000
? (-1)^(2/3)
%6 = -0.50000000000000000000000000000000000000 +
0.86602540378443864676372317075293618347*I
? (0/1)^(2/3)
%7 = 0
This gives the same results as Python's Fraction, except for your
example [6]. There, it gives the Fraction(0) you ask for.
If the smart mathematicians and computer scientists that wrote gp/pari
get the same answers, it suggests to me that improvement would be
hard.
That said, a case can be made for the value given by [6] being a bug.
Or a poorly documented feature.
--
best regards
Jonathan
Neil Girdhar writes:
> There are a lot of misunderstandings in this thread. It's probably
> best to start by reading up on the roots of unity (
> https://en.wikipedia.org/wiki/Root_of_unity).
That's not very polite, especially in context where somebody has
already conceded that his "wrong" was over the top.
Speaking of courtesy, please stop clean up your addressee list. If
you don't, GoogleGroups spams people who reply with "you're not a
member".
> same for the cube root I imagine if we had a cube root function Let's call
> that the principal cube root, which is always real for a
> real-valued input.
That doesn't seem to be how Wolfram sees it:
http://mathworld.wolfram.com/PrincipalRootofUnity.html
Hi Neil
We wrote
>> This gives the same results as Python's Fraction, except for your
>> example [6]. There, it gives the Fraction(0) you ask for.
>>
>> If the smart mathematicians and computer scientists that wrote gp/pari
>> get the same answers, it suggests to me that improvement would be
>> hard.
> That's because these are just floating point numbers. These are not being
> processed symbolically. Wolfram Alpha gives all three roots, including the
> real root.
I've not used Wolfram Alpha, nor I think have many people on this
list. Please copy and paste the input and output from Alpha, so we can
see for ourselves (and so there's a record on this list).
If anyone has time and ready access, it would help to know what
https://www.sympy.org/en/index.html does with this.
Perhaps your innocent request conceals a request for symbolic handling
of simple algebraic numbers.
--
best regards
Jonathan
Neil Girdhar wrote:
> we want branch continuity in the power.
> After all, floating point values have some inaccuracy, and we wouldn't
> want chaotic behavior, i.e., small changes to the power to have drastic
> changes to the result.
>
> This is not like Fraction where we know that x ** Fraction(1, 3) is a
> genuine cube root, and so why not return the principal cube, which we
> know to be real valued for real valued x?
Because that would be possible only for a few special combinations
of Fractions ** Fractions that happen to have rational solutions. All
the others would still have to return float or complex results,
which could then be discontinuous with the rational ones.
--
Greg
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
Right, but we already have some special cases:In [8]: Fraction(2, 3) ** Fraction(3, 1)Out[8]: Fraction(8, 27)Fraction.__pow__ already tries to return Fraction objects where possible.
Nicolas Rolin
Right, but we already have some special cases:In [8]: Fraction(2, 3) ** Fraction(3, 1)Out[8]: Fraction(8, 27)Fraction.__pow__ already tries to return Fraction objects where possible.I think the main point to see here is what the scope of a built-in function should be.For a fraction module in the stdlib, I would expect that it handle "symbolically" any fraction multiplication or division of fractions, and integer power of fractions.Those are simple and useful cases, that can arise a bit anywhere. Power of non-integer is a way more complex issue (notably because power of a non-integer is not a function), and returning the same output as float is at least an honest way of dealing with those cases.
I'm not really sure a stdlib should even try do deal with that. If I want to have a symbolic way of handling complex power of fractions, I should import a specific math library whose specific job is to get this right (the same way if you want to do matrix stuff you have to import numpy).
--Nicolas Rolin
(You're still not fixing your mail headers. Please do, it's hard to be
bothered responding if I keep having to fix your mails in order to do
so).
On Thu, 30 Aug 2018 at 11:28, Neil Girdhar <miste...@gmail.com> wrote:
>
> But I'm only asking for fractional powers of -1, 0, and 1. Is that really a complex issue?
Yes. (Even ignoring the oh-so-tempting complex number joke ;-)). As
has been seen here there's no agreement on the "right" choice of which
root of -1 to choose. Or possibly more accurately, no-one else is
agreeing with your suggestion that we choose a different option for
the case you're arguing over.
And to be 100% precise, you asked for the results of three *very
specific* calculations to change. I guess you actually want something
more general - or are you really OK with (for example)
Fraction(-1,1)**Fraction(2,3) changing as you request, but
Fraction(-2,1)**Fraction(2,3) remaining as it currently is?
You still
haven't clarified (no-one has particularly asked yet - you may
consider this a request to do so if you like) how you propose in
general that the result of
Fraction(-1,1) ** Fraction(a, b)
and/or
Fraction(1,1) ** Fraction(a, b)
or maybe even more generally
Fraction(c,d) ** Fraction(a,b)
would change. What exactly are the special cases you want to define
different results for? What is the process for choosing the result?
> You are right that the fractional power of -1 and 1 has multiple values, but the fractional power of zero has a unique value.
And that part of your proposal has not generated much controversy.
Maybe if you proposed only that, you might get that change made? I
haven't considered the ramifications of that because the discussions
about -1 are obscuring it, but it might be relatively uncontroversial.
Paul
Hi Neil
Summary: You say something should be done. But by who? Perhaps the
should starts with you.
Third, there is a way to go from 'Fraction should' to a group of
persons. If you're correct, that 'Fraction should', then I'm happy to
say that it follows that 'the Python community should'.
Now, the Python community is vast. It's more than the core developers.
I'm a member. You're a member. Everyone participating on this list is
a member. It's got lots of resources.
You want this problem solved. You've got clear ideas what should be
done. You say it should be done. And you're a member of the Python
community, who 'should fix this problem'.
The module fractions.py is pure Python. You can fork it to develop
your own solution, written as it should be. You can use this solution
and share it with the community. And you can submit it as a pull
request, for inclusion in the standard library.
To summarise. You're part of the Python community, who you believe
should solve this problem. Please, as a member of the community,
accept some responsibility for do what you think should be done.
(You're still not fixing your mail headers. Please do, it's hard to be
bothered responding if I keep having to fix your mails in order to do
so).
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
--
Nicolas Rolin | Data Scientist
+ 33 631992617 - nicolas.rolin@tiime.fr
15 rue Auber, 75009 Paris
www.tiime.fr
I think you could take the implementation further and decide that any power of Fraction(1) is Fraction(1) and any positive power of Fraction(0) is Fraction(0).I woudn't be shocked that Fraction(1) ** 3.7 == Fraction(1) and Fraction(0) ** 3.7 == 0.
However the implementation for Fraction(-1) seems a bit to "ad hoc", and break some expected behavior of the powers.For exemple in your code Fraction(-2) ** Fraction(2, 3) != Fraction(-1) ** Fraction(2, 3) * Fraction(2) ** Fraction(2, 3), whereas floats respect this.You could change the code so that the property (a *b) ** c == a**c *b**c, but idk how hard it is.
I would also like to point out that the current behavior of Fractionis consistent with other parts of the numeric system, e.g.1/1 produces 1.0 (rather than 1)math.sqrt(4) produces 2.0 (rather than 2)1j-1j produces 0j (rather than 0.0 or 0)
So in general the type of the output is determined by whatthe operation would in general return for that input type,as opposed to a more specific type which only appliesto the specific input value.
--
---
You received this message because you are subscribed to a topic in the Google Groups "python-ideas" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/python-ideas/aZIHpPhe0mw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to python-ideas...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
On Wed, Aug 29, 2018 at 09:39:05PM -0700, Neil Girdhar wrote:
> Would there be any problem with changing:
>
> In [4]: Fraction(1, 1) ** Fraction(2, 3)
> Out[4]: 1.0
>
> In [5]: Fraction(-1, 1) ** Fraction(2, 3)
> Out[5]: (-0.4999999999999998+0.8660254037844387j)
>
> In [6]: Fraction(0, 1) ** Fraction(2, 3)
> Out[6]: 0.0
>
> I'd like these to be Fraction(1), Fraction(1), and Fraction(0).
If anyone else has mentioned the backward-compatibility issue by now, I
haven't see it. I believe that would make it a fairly big problem.
I expect that there is code out in the wild which (for good or ill) now
expects 1**Fraction(2, 3) to return 1.0, rather than Fraction(1), and
similarly for the other examples. Changing that could break people's
code.
Even if we had consensus that this was a good idea, or at least
consensus from the maths-folk who care about this sort of thing (I'd
like to know what Uncle Timmy and Mark think of this idea), it would
still probably need a "__future__" import to activate it, or a
deprecation period. Or some other annoyance.
Possibly the simpler approach would be to add a subclass that does what
you want. UnitRootFraction or something.
Then the only argument will be whether such a subclass ought to go into
the fractions module, or your own personal toolkit :-)
I must admit though, I'm a bit curious as to what you are doing that
having 1**Fraction(2,3) return 1.0 is an annoyance, but having
27**Fraction(2,3) return 8.999999999999998 instead of Fraction(9) isn't.
--
Steve
_______________________________________________
Python-ideas mailing list
Python...@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/