Lambdify with multiple outputs.
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.
@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?
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?
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
If possible, let's keep the API the same as in SymPy, or change it in both.