On Tue, Jun 1, 2021 at 6:28 AM Oscar Benjamin
<oscar.j.benja...@gmail.com> wrote:
>
> On Tue, 1 Jun 2021 at 10:53, Neil Girdhar <mistersh...@gmail.com> wrote:
> >
> > On Tue, Jun 1, 2021 at 5:39 AM Oscar Benjamin
> > <oscar.j.benja...@gmail.com> wrote:
> > >
> > > On Tue, 1 Jun 2021 at 05:16, Neil Girdhar <mistersh...@gmail.com> wrote:
> > > >
> > > > Hi Oscar,
> > > >
> > > > The problem that the original poster was trying to address with
> > > > additional syntax is the automatic naming of symbols.  He wants to
> > > > omit this line:
> > > >
> > > > x = symbols("x")
> > > >
> > > > You're right that if you have many one-character symbol names, you can
> > > > use a shortcut, but this benefit is lost if you want descriptive names
> > > > like:
> > > >
> > > > momentum = symbols('momentum')
> > > >
> > > > He is proposing new syntax to eliminate the repeated name.  The
> > > > function approach specifies each name exactly once.  This is one of
> > > > the benefits of JAX over TensorFLow.
> > > >
> > > > Second, the function approach allows the function to be a single
> > > > object that can be used in calcuations.   You might ask for:
> > > >
> > > > grad(equation, 2)(2, 3, 4 5)  # derivative with respect to parameter 2
> > > > of equation evaluated at (2, 3, 4, 5)
> > > >
> > > > With the symbolic approach, you need to keep the equation object as
> > > > well as the symbols that compose it to interact with it.
> > >
> > > This makes more sense in a limited context for symbolic manipulation
> > > where symbols only represent function parameters so that all symbols
> > > are bound. How would you handle the situation where the same symbols
> > > are free in two different expressions that you want to manipulate in
> > > tandem though?
> > >
> > > In this example we have two different equations containing the same
> > > symbols and we want to solve them as a system of equations:
> > >
> > > p, m, h = symbols('p, m, h')
> > > E = p**2 / 2*m
> > > lamda = h / p
> > >
> > > E1 = 5
> > > lamda1 = 2
> > > [(p1, m1)] = solve([Eq(E, E1), Eq(lamda, lamda1)], [p, m])
> > >
> > > I don't see a good way of doing this without keeping track of the
> > > symbols as separate objects. I don't think this kind of thing comes up
> > > in Jax because it is only designed for the more limited symbolic task
> > > of evaluating and differentiating Python functions.
> >
> > This is a really cool design question.
> >
> > One of the things I like about JAX is that they stayed extremely close
> > to NumPy's interface.  In NumPy, comparison operators applied to
> > matrices return Boolean matrices.
> >
> > I would ideally express what you wrote as
> >
> > def E(p, m): ...
> >
> > def lamda(h, p): ...
> >
> > def f(p, m):
> >     return jnp.all(E(p, m) == E1) and jnp.all(lamda(h, p) == lamda1)
> >
> > p1, m1 = solve(f)
>
> So how does solve know to solve for p and m rather than h?

Because those are the parameters of f.
>
> Note that I deliberately included a third symbol and made the
> parameter lists of E and lamda inconsistent.
>
> Should Jax recognise that the 2nd parameter of lamda has the same name
> as the 1st parameter of E? Or should symbols at the same parameter
> index be considered the same regardless of their name?

It doesn't need to because the same variable p (which will ultimately
point to a tracer object) is passed to the functions E and lamda.
It's not using the names.
>
> In Jax everything is a function so I would expect it to ignore the
> symbol names so that if
>     args = solve([f1, f2])
> then f1(*args) == f2(*args) == 0.
>
> This is usually how the API works for numerical rather than symbolic
> root-finding algorithms. But then how do I solve a system of equations
> that has a symbolic parameter like `h`?

I assumed that h was a constant and was being closed over by f.  If h
is a symbol, I think to stay consistent with functions creating
symbols, we could do:


def f(p, m, h):
    return E(p, m) == E1 and lamda(h, p) == lamda1

def g(h):
    return solve(partial(f, h=h))

g is now a symbolic equation that returns p, m in terms of h.

By the way, it occured to me that it might be reasonable to build a
system like this fairly quickly using sympy as a backend.

Although, there are some other benefits of Jax's symbolic
expression-builder that might be a lot harder to capture: Last time I
used sympy though (years ago), I had a really hard time making
matrices of symbols, and there were some incongruities between numpy
and sympy functions.

Best,

Neil
>
> --
> 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/AN37BNIJQNVFEW27CQ5T5RJJHKGLCD3H/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to