On Tue, 18 May 2021 at 15:56, Paul Moore <p.f.mo...@gmail.com> wrote:
>
> On Tue, 18 May 2021 at 15:16, Martin Teichmann
> <martin.teichm...@gmail.com> wrote:
> >
> > Because reality. People would like to write 1/2 * m * v**2 to mean the 
> > obvious thing, without having to think about the details. And there are 
> > many people like this, this is why it shows up on this mailing list 
> > regularly. I have never felt the urge to write two/three * m * v**two.
>
> I'd actually prefer to write (m*v**2)/2. Or (m/2)*v**2. But those
> wouldn't work, the way you describe your proposal. And I'd be very
> concerned if they behaved differently than 1/2 * m * v**2...

In SymPy these do behave differently right now:

>>> from sympy import symbols
>>> m, v = symbols('m, v')
>>> (m*v**2)/2
m*v**2/2
>>> (m/2)*v**2
m*v**2/2
>>> 1/2 * m * v**2
0.5*m*v**2

The problem is that while SymPy expressions can define __div__(self,
int) to be exact there isn't a way for SymPy to hook into an
expression like 1/2 which is just a Python expression using the int
type whose __div__ returns floats. SymPy itself treats floats as being
different from the exact rational numbers that they represent which is
important for users who *do* want to use floats (although I think many
users do this just because they want decimal display without
understanding the issues that imprecise arithmetic can bring).

There is a function in sympy that can "convert" a float to rational
with heuristics that allow it to undo decimal-to-binary rounding
errors e.g.:

>>> from sympy import nsimplify
>>> nsimplify(1/2 * m * v**2)
m*v**2/2
>>> nsimplify(0.1)
1/10

Note that the Python float 0.1 is not exactly equal to the rational
number 1/10 which can not be represented exactly in binary floating
point. So that is not an exact conversion although it is necessarily
within 1 ulp (in this case). It would be possible to have a mode in
SymPy that can do this automatically but then some people wouldn't
want that so it possibly shouldn't be on by default. Really there is
no way to get around the fact that sometimes you want to use floating
point and sometimes you want exact rational arithmetic so both need to
be possible in some way.

Some other programming languages have special syntax for rational
numbers e.g. 1//2 in Julia or 1%2 in Haskell but I don't know of a
programming language that uses 1/2 syntax for rational numbers apart
from things like Maple/Mathematica. I think that Matlab just does the
equivalent of nsimplify above so you can do e.g. sym(1/3) and get 1/3
as an exact rational number even though the original Matlab expression
1/3 gives an approximate floating point result. The Matlab docs
acknowledge that this is not always reliable though (the suggestion is
to use 1/sym(3) instead):
"""
Use sym on subexpressions instead of the entire expression for better
accuracy. Using sym on entire expressions is inaccurate because MATLAB
first converts the expression to a floating-point number, which loses
accuracy. sym cannot always recover this lost accuracy.
"""
https://uk.mathworks.com/help/symbolic/sym.html#bu1rs8g-1

I think that maybe the best solution here is something more like a
domain-specific language that can be used with ipython/jupyter as an
alternative profile. In the DSL 1/2 could be a Fraction and 2x^2 could
be the equivalent of 2*x**2 etc. You'd probably want to be able to
write things like √2 and x'' and so on. Maybe you could have a better
syntax for creating matrices than the clunky list of lists. Basically
there are lots of things that you can't quite do in Python but that
you might want to do if you were making a language specifically for
the purpose of doing stuff with equations.

--
Oscar
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/ZHFSDQKDVD7SRREWHC4XEC5KACKILHZC/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to