symengine.py icon indicating copy to clipboard operation
symengine.py copied to clipboard

Lambdify with multiple outputs.

Open isuruf opened this issue 9 years ago • 4 comments

Currently, Lambdify generates only one output. For LLVM backend to make full use of cse, Lambdify should be able to do this in one go.

isuruf avatar Oct 17 '16 15:10 isuruf

@bjodah wrote

But Lambdify does not support use cases which looks something like this:

>>> scalar_a, scalar_b, matrix_c, vector_d = my_callback(x)

then lambdify is much better suited.

The strength (as I see it) with Lambdify is broadcasting:

>>> Lambdify([x], [x**2, x+3])(np.arange(8.0)).shape
(8, 2)

it is (quite?) hard (and confusing?) to support both use cases with one function, so I believe there is a place for both lambdify and Lambdify (maybe we need better names for these, though). (Or maybe we can support broadcasting and heterogeneous output at the same time? - I couldn't say for sure without implementing it and using it for a while)

So in order to enable lambdify to fully benefit from LLVM, I believe we need to ravel all expressions, chain them and then repack before output (which is what Lambdify is doing but only assuming 1 n-dimensional array as output). But we could do this internally in a cython version of lambdify so that LLVMDoubleVisitor actually gets all the expressions at once. Thoughts?

isuruf avatar Oct 17 '16 15:10 isuruf

I've been thinking about the API for this, right now we have:

def Lambdify(args, exprs, bool real=True, backend="lambda")

I think if we change this to (don't know how cython handles keyword only arguments, we might need to use **kwargs for real and backend but that's not a big deal):

def Lambdify(args, *exprs, bool real=True, backend="lambda")

and have __call__ return a tuple of equal length as exprs, the interface will feel natural. We can even support broadcasting. Any thoughts?

This would be a breaking change btw. where calling instances of Lambdify with len(exprs) == 1 would now return length-1 tuples. But I'd much rather break Lambdify for consistency than to special case len(exprs) == 1. Do we know if anyone else is actually using Lambdify yet?

bjodah avatar Nov 02 '16 13:11 bjodah

Sounds good. One argument against returning a length-1 tuple would be that since Lambdify is meant to be used as a callback function in other libraries, we would want to just return the value. This is pretty minor and we can discuss this more later.

Do we know if anyone else is actually using Lambdify yet?

Not that I know of

isuruf avatar Nov 02 '16 14:11 isuruf

If possible, let's keep the API the same as in SymPy, or change it in both.

certik avatar Nov 02 '16 17:11 certik