Re: [Python-ideas] Fix some special cases in Fractions?

2018-09-03 Thread Jacco van Dorp
If we wanted to be mathematically correct, taking a 4th root should give
you 4 answers. You could return a tuple of (4, -4, 4j, -4j) for a 4th root
of 256. It actually makes power to a Fraction(2, 4) unequal with a
Fraction(1, 2) calculating this way. (which, from what I can tell, is
exactly your point - don't just take a power and a square root for a
fractional power, reduce it to a float or whatever first to get
well-defined behaviour. )

But full mathematical correctness is probably not what we want either.
Current behaviour IMO is the only solution that returns only 1 answer but
does something sensible in all cases.

Op za 1 sep. 2018 om 20:35 schreef Jonathan Fine :

> Greg Ewing and Jonathan Goble wrote
>
> >> Also, Fraction(1) for the second case would be flat-out wrong.
>
> > How? Raising something to the 2/3 power means squaring it and then taking
> > the cube root of it. -1 squared is 1, and the cube root of 1 is 1. Or am
> I
> > having a 2:30am brain fart?
>
> Let's see. What about computing the Fraction(2, 4) power by first
> squaring and then taking the fourth root. Let's start with (-16).
> Square to get +256. And then the fourth root is +4. I've just followed
> process Jonathan G suggested, without noticing that Fraction(2, 4) is
> equal to Fraction(1, 2).
>
> But Fraction(1, 2) is the square root. And -16 requires complex
> numbers for its square root. The problem, I think, may not be doing
> something sensible in any particular case. Rather, it could be doing
> something sensible and coherent in all cases. A bit like trying to fit
> a carpet that is cut to the wrong size for the room.
>
> --
> Jonathan
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-09-01 Thread Jonathan Fine
Greg Ewing and Jonathan Goble wrote

>> Also, Fraction(1) for the second case would be flat-out wrong.

> How? Raising something to the 2/3 power means squaring it and then taking
> the cube root of it. -1 squared is 1, and the cube root of 1 is 1. Or am I
> having a 2:30am brain fart?

Let's see. What about computing the Fraction(2, 4) power by first
squaring and then taking the fourth root. Let's start with (-16).
Square to get +256. And then the fourth root is +4. I've just followed
process Jonathan G suggested, without noticing that Fraction(2, 4) is
equal to Fraction(1, 2).

But Fraction(1, 2) is the square root. And -16 requires complex
numbers for its square root. The problem, I think, may not be doing
something sensible in any particular case. Rather, it could be doing
something sensible and coherent in all cases. A bit like trying to fit
a carpet that is cut to the wrong size for the room.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-31 Thread Oscar Benjamin
On Thu, 30 Aug 2018 at 17:36, Stephan Houben  wrote:
>
> I would also like to point out that the current behavior of Fraction
> is 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 what
> the operation would in general return for that input type,
> as opposed to a more specific type which only applies
> to the specific input value.

An exception is integer exponentiation:

>>> 1 ** 1
1
>>> 1 ** -1
1.0

Given two rationals q1 and q2 usually q1 ** q2 will not be a rational
number. Integer exponentiation results in an integer for half of all
possible integer pairs.

To do the same with Fraction(a, b) ** Fraction(c, d) would require
verifying that both a and b have exact integer dth roots which is more
complicated than simply checking the sign of an integer exponent. The
extra complexity would slow things down a bit but then again the
fractions module is there for precisely those people who are happy to
have substantial slow-down for the sake of exactness.

>From a backwards compatibility perspective the old behaviour would
still be available in a way that works already: float(q1) **
float(q2).

Also it would also be straight-forward to implement this given the
integer maths (iroot etc) functions that were discussed in a recent
thread on this list:
https://mail.python.org/pipermail/python-ideas/2018-July/051917.html

However: Why would you do this operation if you wanted an exact
result? I have at some point wanted (for ints or Fractions) a function
root(q, n) that gives an exact root or an error. This proposal would
mean that q1 ** q2 would be exact occasionally and would return a
float the rest of the time though. If you care about
exactness/accuracy in the code you write then it is not okay to be
unsure whether your variable is float or Fraction. You need to know
because it makes a big difference to how you calculate things (it
isn't generally possible to write optimal polymorphic code over
exact/inexact arithmetic).

The proposed behaviour would look nicer in an interactive session but
might not be any more useful in situations where you *really* care
about exactness.

--
Oscar
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-31 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 9:03 AM Steven D'Aprano  wrote:

> 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.4998+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 don't think it's that big a problem since Fraction < numbers.Real


> 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.998 instead of Fraction(9) isn't.
>
> You're right, it would have been better in my example (linked above) to
support all of those things.

>
>
> --
> Steve
> ___
> Python-ideas mailing list
> Python-ideas@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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Greg Ewing

Neil Girdhar wrote:
Powers of other numbers have to keep the same behavior since in general 
those kinds of expressions don't create rational numbers.


There are infinitely many other rational numbers that *could*
be given the same treatment, though, e.g. (-8) ** (2/3). If
you don't want to include those you'll have to explain your
rationale.

--
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Brendan Barnwell

On 2018-08-30 00:07, Greg Ewing wrote:> 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).

	The problem is that in the minds of most people who know enough math to 
know about fractional exponents, but still don't enough to want to deal 
with complex numbers, the standard procedure when taking a fractional 
power of a real number is:


1) choose a positive real value if there is one
2) choose a negative real value otherwise
3) give up if the answer would be nonreal

	But if you're willing to go to complex numbers, then the logic shifts 
to "take the principal root", which is the root in the complex plane 
that you get to first when going in the mathematically positive 
direction (counterclockwise) from the positive real axis.


	In addition, I think having 2 in the numerator in the fractional power 
is a red herring as far as understanding the confusion.  This is already 
going to be surprising to people:


>>> (-1) ** (1/3)
(0.5001+0.8660254037844386j)

	In high school math, people are taught that (-1)^(1/3) = -1, because 
that's the only real value.  But if you open up to the complex numbers, 
then you'll start defining (-1)^(1/3) as (-1 + sqrt(3)i)/2 since that is 
the more mathematically defensible principal value.  (Interestingly, 
Wolfram Alpha by default gives -1 for "cube root of -1", but gives the 
complex value for "(-1)^(1/3)".  If only we had a way to type an 
nth-root symbol instead of having to indicate roots with exponents!)


	Personally I think I was happier with the way things worked in Python 
2, where (-1)**(1/3) would raise an error, and you had to explicitly do 
(-1 + 0j)**(1/3) if you wanted a complex root.  I'm willing to bet that 
the vast majority of users doing arithmetic with Python never want nor 
can make any use of a complex value for any operation, ever; it is more 
likely they want an error message to alert them that their data has gone 
awry.


--
Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is no 
path, and leave a trail."

   --author unknown
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Stephan Houben
I would also like to point out that the current behavior of Fraction
is 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 what
the operation would in general return for that input type,
as opposed to a more specific type which only applies
to the specific input value.

Stephan

Op do 30 aug. 2018 om 15:03 schreef Steven D'Aprano :

> 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.4998+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.998 instead of Fraction(9) isn't.
>
>
>
> --
> Steve
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Paul Moore
On Thu, 30 Aug 2018 at 14:06, Nicolas Rolin  wrote:

> 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.
>

You could do lots of things. But are any of them useful enough to warrant
changing documented behaviour, breaking backward compatibility, and
introducing a much more complex rule on how the arguments to
Fraction.__pow__ affect the type of the return value?

At the moment, there are no known use cases for this change - beyond Neil's
statement that he'd "like" the values to be as he quoted (with no
justification given).


> 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.
>

This (what behaviour is "expected" and/or natural) is the sort of detail
that can't be answered without knowing use cases - both use cases for the
proposed behaviour *and* use cases that rely on the existing behaviour.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Nicolas Rolin
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.

2018-08-30 13:31 GMT+02:00 Neil Girdhar :

> Thanks for the feedback.
>
> On Thu, Aug 30, 2018 at 7:13 AM Paul Moore  wrote:
>
>> (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  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?
>
>
> Powers of other numbers have to keep the same behavior since in general
> those kinds of expressions don't create rational numbers.
>
>
>> 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?
>>
>
> Here's my proposed method:
>
> class Fraction:
> def __pow__(a, b):
> """a ** b
> If b is not an integer, the result will be a float or complex
> since roots are generally irrational. If b is an integer, the
> result will be rational.
> """
> if isinstance(b, numbers.Rational):
> if b.denominator == 1:
> power = b.numerator
> if power >= 0:
> return Fraction(a._numerator ** power,
> a._denominator ** power,
> _normalize=False)
> elif a._numerator >= 0:
> return Fraction(a._denominator ** -power,
> a._numerator ** -power,
> _normalize=False)
> else:
> return Fraction((-a._denominator) ** -power,
> (-a._numerator) ** -power,
> _normalize=False)
> elif a == -1 and b.denominator % 2 == 1:
> return Fraction(-1 if b.numerator % 2 == 1 else 1)
> elif a == 0:
> if b > 0:
> return Fraction(0)
> else:
> raise ZeroDivisionError(
> "0 cannot be raised to a negative power")
> elif a == 1:
> return Fraction(1)
> else:
> # A fractional power will generally produce an
> # irrational number.
> return float(a) ** float(b)
> else:
> return float(a) ** b
>
> Compare it with https://github.com/python/cpython/blob/3.7/Lib/
> fractions.py#L448
>
>
>>
>> > 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.
>>
>
> Fair enough.
>
>>
>> Paul
>>
>
> ___
> Python-ideas mailing list
> Python-ideas@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.ro...@tiime.fr 


*15 rue Auber, **75009 Paris*
*www.tiime.fr *

Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Steven D'Aprano
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.4998+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.998 instead of Fraction(9) isn't.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Paul Moore
On Thu, 30 Aug 2018 at 12:04, Jonathan Fine  wrote:
> First, the docs for the fraction module could be improved. Here's the
> page and it's history.
>
> https://docs.python.org/3/library/fractions.html
> https://github.com/python/cpython/commits/3.7/Doc/library/fractions.rst
>
> Already, doing this will help users.

While the documentation is pretty terse and could be expanded, it's
worth noting that the class also has docstrings. And whether we feel
that docstrings are sufficiently accessible for users (certainly I
often forget to check them) they *are* part of the module
documentation. In particular:

>>> help(fractions.Fraction.__pow__)
Help on function __pow__ in module fractions:

__pow__(a, b)
a ** b

If b is not an integer, the result will be a float or complex
since roots are generally irrational. If b is an integer, the
result will be rational.

That's clear, concise, and explains the current behaviour precisely.
Neil's proposal is definitely a functional change (not that he was
denying this) in that it alters already documented behaviour. And I
think that's something we should remember. This isn't undocumented (or
even badly documented) behaviour - it's clearly defined behaviour
noted in the official documentation (just in a part of that
documentation that's easy to overlook).

> In particular, for a different
> approach, point them to
>
> https://www.sympy.org/en/index.html

I don't honestly think that sympy is a comparable tool to the stdlib
Fraction class. I suspect that most people who need the Fraction class
are not even remotely in the target audience for sympy. The ones who
are, likely already know about it.

> And finally, thank you for drawing to our attention this blemish in
> the fractions module (or its documentation).

I wouldn't describe it as a blemish. Rather, it's somewhere we could
maybe improve the discoverability of the existing documentation. Or an
opportunity to review how we make it easier for users to get access to
documentation that is held in docstrings, as opposed to the manuals.
Maybe a pydoc instance available online, linked from the manual
entries?

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
Hey, no worries.  I do think though that people should feel free to suggest
ideas even if they have never contributed anything.  I read python-ideas
for the discussion.  Thank you for your feedback about my suggestion.


On Thu, Aug 30, 2018 at 8:18 AM Jonathan Fine  wrote:

> Hi Neil
>
> When I wrote my previous message, I didn't know who you were, or your
> previous contributions. Perhaps I should have. But I didn't.
>
> If I had known, my remarks would have been different. In particular, I
> would have acknowledged your previous contributions. I apologise for
> any offence I may have caused you.
>
> Better late than never. Thank you for your contributions to
> implementing PEP 448.
>
> with best regards
>
> Jonathan
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jonathan Fine
Hi Neil

When I wrote my previous message, I didn't know who you were, or your
previous contributions. Perhaps I should have. But I didn't.

If I had known, my remarks would have been different. In particular, I
would have acknowledged your previous contributions. I apologise for
any offence I may have caused you.

Better late than never. Thank you for your contributions to
implementing PEP 448.

with best regards

Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
Yeah, you're right, my original mail was posted on google groups.  Sorry
for the trouble.

On Thu, Aug 30, 2018 at 8:15 AM Paul Moore  wrote:

> Thu, 30 Aug 2018 at 12:55, Neil Girdhar  wrote:
> >
> > On Thu, Aug 30, 2018 at 7:13 AM Paul Moore  wrote:
> >>
> >> (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).
> >
> >
> > Sorry about that, I don't understand where it's coming from.   I'm never
> using google groups. I'm only replying to the emails that are sent to me.
> I guess gmail's reply-all is gathering the google groups mail from the
> thread.
>
> Your original mail was sent to Google Groups. Do you have the wrong
> address for the list in your mail client?
>
> Message ID<0067a655-4f82-479f-9970-5b72dc079...@googlegroups.com>
> Created on:30 August 2018 at 05:39 (Delivered after 74 seconds)
> From:Neil Girdhar 
> To:python-ideas 
> Subject:[Python-ideas] Fix some special cases in Fractions?
>
> Paul
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Paul Moore
Thu, 30 Aug 2018 at 12:55, Neil Girdhar  wrote:
>
> On Thu, Aug 30, 2018 at 7:13 AM Paul Moore  wrote:
>>
>> (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).
>
>
> Sorry about that, I don't understand where it's coming from.   I'm never 
> using google groups. I'm only replying to the emails that are sent to me.  I 
> guess gmail's reply-all is gathering the google groups mail from the thread.

Your original mail was sent to Google Groups. Do you have the wrong
address for the list in your mail client?

Message ID<0067a655-4f82-479f-9970-5b72dc079...@googlegroups.com>
Created on:30 August 2018 at 05:39 (Delivered after 74 seconds)
From:Neil Girdhar 
To:python-ideas 
Subject:[Python-ideas] Fix some special cases in Fractions?

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 7:13 AM Paul Moore  wrote:

> (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).
>

Sorry about that, I don't understand where it's coming from.   I'm never
using google groups. I'm only replying to the emails that are sent to me.
I guess gmail's reply-all is gathering the google groups mail from the
thread.


> On Thu, 30 Aug 2018 at 11:28, Neil Girdhar  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
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 7:03 AM Jonathan Fine  wrote:

> Hi Neil
>
> Summary: You say something should be done. But by who? Perhaps the
> should starts with you.
>

What does this mean?  Are you asking who is going to do the
implementation?  I posted here to get feedback about whether it would be a
good idea.


>
> Warning: This has been written quickly, and might have rough edges. If
> so, I apologise.
>
> You wrote
>
> > But I'm only asking for fractional powers of -1, 0, and 1.  Is that
> really a
> > complex issue?
>
> > You are right that the fractional power of -1 and 1 has multiple values,
> but
> > the fractional power of zero has a unique value.
>
> >> 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).
>
> > That's how I use the fractions package.  If you look at my example code,
> > that seems like the kind of problem Fraction should make it easy to work
> > with.  And yet, there was a wrinkle where I had to calculate
> Fraction(-1) **
> > Fraction(a, b).
>
> Let's try to make the best of what we've got.
>
> First, the docs for the fraction module could be improved. Here's the
> page and it's history.
>
> https://docs.python.org/3/library/fractions.html
>
> https://github.com/python/cpython/commits/3.7/Doc/library/fractions.rst
>
> Already, doing this will help users. In particular, for a different
> approach, point them to
>
> https://www.sympy.org/en/index.html
>
> Second, assume you're right, when you say
>
> > [This sort of problem], Fraction should make it easy [...]
>
> The problem is, Python development resources are finite. They should
> be more, but they're not. It's hard to go from 'Fraction should' to
> ' should'. Perhaps the best one can come up with
> is the developers of fraction.py. Here's the page and history.
>
> https://github.com/python/cpython/blob/3.7/Lib/fractions.py
> https://github.com/python/cpython/commits/3.7/Lib/fractions.py


Thanks for linking the github.  I'm only posting on ideas to get feedback.
I think this is what the group is for.  Also, I don't know why you keep
bringing up the finite Python developer resources.  Like I said above, this
is a small change, (one that I coded below).  Besides that bit of code, I
could add a few tests, and modify the docs.  Someone would have to review
it, but it's not a big job.  The only question is: should it be done?  And
that's why I posted it here.

>
>
> 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.
>

Before I do that, I want to get feedback here.  The way I understand the
usual order with feature requests is that they are discussed, they turn
into PEPs, they are approved, they are implemented, they are reviewed, they
are checked in.  Someone will definitely correct me.  No one wants to spend
time writing documentation for code that will never be checked in.


> 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.


Maybe I'm interpreting this wrong, but what do you mean by "accept some
responsibility"?  The last time I felt strongly about a feature (PEP 448),
and after it had been approved by Guido, I spent a few months implementing
it along with Joshua Landau (https://bugs.python.org/issue2292).  Compared
to this tiny change, that was a huge change involving the parser, the
compiler, and the grammar.  I really don't understand what you're driving
at with this "accept some responsibility" comment.


>
And finally, thank you for drawing to our attention this blemish in
> the fractions module (or its documentation).
>
> --
> Jonathan
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
Thanks for the feedback.

On Thu, Aug 30, 2018 at 7:13 AM Paul Moore  wrote:

> (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  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?


Powers of other numbers have to keep the same behavior since in general
those kinds of expressions don't create rational numbers.


> 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?
>

Here's my proposed method:

class Fraction:
def __pow__(a, b):
"""a ** b
If b is not an integer, the result will be a float or complex
since roots are generally irrational. If b is an integer, the
result will be rational.
"""
if isinstance(b, numbers.Rational):
if b.denominator == 1:
power = b.numerator
if power >= 0:
return Fraction(a._numerator ** power,
a._denominator ** power,
_normalize=False)
elif a._numerator >= 0:
return Fraction(a._denominator ** -power,
a._numerator ** -power,
_normalize=False)
else:
return Fraction((-a._denominator) ** -power,
(-a._numerator) ** -power,
_normalize=False)
elif a == -1 and b.denominator % 2 == 1:
return Fraction(-1 if b.numerator % 2 == 1 else 1)
elif a == 0:
if b > 0:
return Fraction(0)
else:
raise ZeroDivisionError(
"0 cannot be raised to a negative power")
elif a == 1:
return Fraction(1)
else:
# A fractional power will generally produce an
# irrational number.
return float(a) ** float(b)
else:
return float(a) ** b

Compare it with
https://github.com/python/cpython/blob/3.7/Lib/fractions.py#L448


>
> > 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.
>

Fair enough.

>
> Paul
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Paul Moore
(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  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
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jonathan Fine
Hi Neil

Summary: You say something should be done. But by who? Perhaps the
should starts with you.

Warning: This has been written quickly, and might have rough edges. If
so, I apologise.

You wrote

> But I'm only asking for fractional powers of -1, 0, and 1.  Is that really a
> complex issue?

> You are right that the fractional power of -1 and 1 has multiple values, but
> the fractional power of zero has a unique value.

>> 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).

> That's how I use the fractions package.  If you look at my example code,
> that seems like the kind of problem Fraction should make it easy to work
> with.  And yet, there was a wrinkle where I had to calculate Fraction(-1) **
> Fraction(a, b).

Let's try to make the best of what we've got.

First, the docs for the fraction module could be improved. Here's the
page and it's history.

https://docs.python.org/3/library/fractions.html
https://github.com/python/cpython/commits/3.7/Doc/library/fractions.rst

Already, doing this will help users. In particular, for a different
approach, point them to

https://www.sympy.org/en/index.html

Second, assume you're right, when you say

> [This sort of problem], Fraction should make it easy [...]

The problem is, Python development resources are finite. They should
be more, but they're not. It's hard to go from 'Fraction should' to
' should'. Perhaps the best one can come up with
is the developers of fraction.py. Here's the page and history.

https://github.com/python/cpython/blob/3.7/Lib/fractions.py
https://github.com/python/cpython/commits/3.7/Lib/fractions.py

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.

And finally, thank you for drawing to our attention this blemish in
the fractions module (or its documentation).

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 5:51 AM Nicolas Rolin 
wrote:

>
>
>
>>> 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.
>

But I'm only asking for fractional powers of -1, 0, and 1.  Is that really
a complex issue?

You are right that the fractional power of -1 and 1 has multiple values,
but the fractional power of zero has a unique value.

>
> 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).
>

That's how I use the fractions package.  If you look at my example code,
that seems like the kind of problem Fraction should make it easy to work
with.  And yet, there was a wrinkle where I had to calculate Fraction(-1)
** Fraction(a, b).


>
> --
>
> *Nicolas Rolin*
>
> --
>
> ---
> 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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
> ___
> Python-ideas mailing list
> Python-ideas@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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jonathan Fine
Jeroen Demeyer wrote

 from sympy import Rational
 Rational(1,2) ** Rational(2,3)
> 2**(1/3)/2
 Rational(1,1) ** Rational(2,3)
> 1
 Rational(-1,1) ** Rational(2,3)
> (-1)**(2/3)
 Rational(0,1) ** Rational(2,3)
> 0

Thank you very much for this, Jeroen. Most helpful.

Perhaps revising https://docs.python.org/3/library/fractions.html, to
mention sympy's symbolic Rational number class, would meet the
original poster's request.

Neil Girdhar - how does this sound to you?

Short of migrating part of sympy into Python's standard library, I
don't know what else we could reasonably do.

-- 
Jonathan
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread 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*
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 5:27 AM Greg Ewing 
wrote:

> 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.
>
> 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.

-- 
> Greg
> ___
> Python-ideas mailing list
> Python-ideas@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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jeroen Demeyer

With gmpy2 (note that mpq=fractions, mpfr=floating-point reals):

>>> from gmpy2 import mpq
>>> mpq("1/1") ** mpq("2/3")
mpfr('1.0')
>>> mpq("-1/1") ** mpq("2/3")
mpfr('nan')
>>> mpq("0/1") ** mpq("2/3")
mpfr('0.0')

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jeroen Demeyer

On 2018-08-30 11:11, Jonathan Fine wrote:

If anyone has time and ready access, it would help to know what
https://www.sympy.org/en/index.html does with this.


It handles such powers symbolically, not actually returning a numerical 
result:


>>> from sympy import Rational
>>> Rational(1,2) ** Rational(2,3)
2**(1/3)/2
>>> Rational(1,1) ** Rational(2,3)
1
>>> Rational(-1,1) ** Rational(2,3)
(-1)**(2/3)
>>> Rational(0,1) ** Rational(2,3)
0
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Greg Ewing

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-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 5:11 AM Jonathan Fine  wrote:

> 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).
>

It's online for everyone to use:
http://www.wolframalpha.com/input/?i=(-1)+%5E+(1%2F3)


>
> 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.
>

Well, rational numbers.  Although an algebraic number type would be
interesting.  And, the way I see it, Fraction is the type corresponding to
the field of rational numbers.


>
> --
> best regards
>
> Jonathan
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jeroen Demeyer

On 2018-08-30 11:05, Jonathan Fine wrote:

I'm used to using a number theory computer algebra system
https://pari.math.u-bordeaux.fr/.


I don't think that a comparison with PARI is very relevant because PARI 
doesn't really have a type system the way that Python does. For example 
the fraction 3/1 doesn't really exist in PARI, only the integer 3 does.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jonathan Fine
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
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jonathan Fine
Hi Neil

You 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.4998+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).

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.0

? 1^(2/3)
%5 = 1.0

? (-1)^(2/3)
%6 = -0.50 +
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
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 4:38 AM Stephen J. Turnbull <
turnbull.stephen...@u.tsukuba.ac.jp> wrote:

> 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


Right, I meant real root.   It just happens the principal square root is
the real root.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Stephen J. Turnbull
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

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 4:01 AM Paul Moore  wrote:

> On Thu, 30 Aug 2018 at 08:38, Neil Girdhar  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.
>
>
Just so you know, it already does depend on the type of the arguments.

In [4]: Fraction(2) ** Fraction(1, 2)
Out[4]: 1.4142135623730951

In [5]: Fraction(2) ** Fraction(3, 1)
Out[5]: Fraction(8, 1)

Like a lot of types, Fraction tries to return a Fraction if it can.  This
is consistent with how math.sqrt of a float returns a float and never a
complex, and same for numpy.cbrt.

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.4998+0.8660254037844387j)
>

But -1 ** Fraction(2, 3) is closer to cube_root(-1 ** 2) than it is to the
floating behavior.

The reason the floating behavior returns what it does is, if I understand
correctly, to try to stay on the same complex branch as the power varies.
In other words, 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?

>>> (1)**(2/3)
> 1.0
> >>> (0)**(2/3)
> 0.0


> So current behaviour of Fraction is correct on that basis, IMO.
>
> Paul
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Paul Moore
Sorry if this gets double posted. Can people using Google Groups
*please* adjust the mail headers so that mailing list posters can
reply without getting errors? Ideally stop using Google Groups, but if
you have to, please consider those that don't. Specifically, please
remove the Google Groups address from the reply-to header, so that
replies go direct to the mailing list and not to the Google Groups
address :-(

(Google Groups messages also don't filter properly, so I end up also
having to manually re-file messages that come via that route. While I
doubt GG users can do much about that, it is another downside of using
the GG interface, and one that GG users should be aware of).

Sorry, feeling grumpy about GG today.

On Thu, 30 Aug 2018 at 09:01, Paul Moore  wrote:
>
> On Thu, 30 Aug 2018 at 08:38, Neil Girdhar  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.4998+0.8660254037844387j)
> >>> (1)**(2/3)
> 1.0
> >>> (0)**(2/3)
> 0.0
>
> So current behaviour of Fraction is correct on that basis, IMO.
>
> Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Paul Moore
On Thu, 30 Aug 2018 at 08:38, Neil Girdhar  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.4998+0.8660254037844387j)
>>> (1)**(2/3)
1.0
>>> (0)**(2/3)
0.0

So current behaviour of Fraction is correct on that basis, IMO.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
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.

Normally, in Python, we return the principal square root (
http://mathworld.wolfram.com/PrincipalSquareRoot.html).  We would do the
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.

---

> For positive numbers, I believe you're correct. For negative numbers, no.

Actually, Jonathan is right.

>>> (-2)**(2/3)
(-0.7937005259840993+1.3747296369986026j)

This is just giving you one of the other two cube roots.

> Rounding error aside, raising -2 to 2/3 power and then raising the result
to 3/2 power gives back -2, as it should.

There is no way to guarantee that "it should do this".  A fractional power
is not a function, and so it has no inverse function.

> Doing it in two steps loses the negation, and then (again, within
rounding error) the end result is positive two.

I think you would see your mistake if you applied this logic to -1 ** 2 **
(1/2).


On Thu, Aug 30, 2018 at 3:08 AM Greg Ewing 
wrote:

> 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).
>

Python gives you the principle root when you do 1 ** (3/2), which is
exactly what I'm proposing for Fraction.


> If you want a solution that round-trips, you need
> complex numbers.


There is no solution that round trips since in general fractional powers
are not functions.  The case in which you can always round trip is when you
are taking a power c ** (a/b) where a is odd, and either c is positive or b
is odd.  Then, the result to the power of (b/a) gives you c.

That's what Python does when you use
> floats. Making Fractions do something different would
> make it inconsistent with floats.
>

Actually, my cases are all examples of the principal roots and are
consistent with floats.


>
> My calculator (which only does real floats) reports an
> error when trying to evaluate (-1) ** (2/3).
>

Yes, which is what Python does with reals.  The difference is the the
Fraction type has exact values, and it knows that the unique answer in the
field of Fraction objects is 1.

>
> --
> Greg
>
> ___
> Python-ideas mailing list
> Python-ideas@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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Greg Ewing

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-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Chris Angelico
On Thu, Aug 30, 2018 at 4:30 PM, Jonathan Goble  wrote:
> On Thu, Aug 30, 2018, 2:08 AM Greg Ewing 
> wrote:
>>
>> Also, Fraction(1) for the second case would be flat-out wrong.
>
>
> How? Raising something to the 2/3 power means squaring it and then taking
> the cube root of it. -1 squared is 1, and the cube root of 1 is 1. Or am I
> having a 2:30am brain fart?
>

For positive numbers, I believe you're correct. For negative numbers, no.

>>> (-2)**(2/3)
(-0.7937005259840993+1.3747296369986026j)
>>> _**(3/2)
(-1.9993+2.4492935982947054e-16j)
>>> ((-2)**2)**(1/3)
1.5874010519681994
>>> _**(3/2)
1.9998

Rounding error aside, raising -2 to 2/3 power and then raising the
result to 3/2 power gives back -2, as it should. Doing it in two steps
loses the negation, and then (again, within rounding error) the end
result is positive two.

ChrisA
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Neil Girdhar
On Thu, Aug 30, 2018 at 2:09 AM Greg Ewing 
wrote:

> 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.
>

No, it's not "wrong".  1 is one of the cube roots of 1.  It's consistent
with 1 ** (2/3) == 1.

-- 
> Greg
> ___
> Python-ideas mailing list
> Python-ideas@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+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Jonathan Goble
On Thu, Aug 30, 2018, 2:08 AM Greg Ewing 
wrote:

> Also, Fraction(1) for the second case would be flat-out wrong.
>

How? Raising something to the 2/3 power means squaring it and then taking
the cube root of it. -1 squared is 1, and the cube root of 1 is 1. Or am I
having a 2:30am brain fart?

>
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-30 Thread Greg Ewing

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-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Fix some special cases in Fractions?

2018-08-29 Thread Jeroen Demeyer

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.


I consider it a feature to know in advance the type of the output of an 
operation, given the types of the input. Having an unexpected type 
suddenly show up because you happen to hit a special case is a recipe 
for bugs.



Jeroen.
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/