This is part of my continuing my work on making sympy capable of generating code for evaluating matrix functions. So far the codeprinters and codegen is done(ish); all that's left is autowrap.
Questions:
1. Should functions created by autowrap create matrices that would be in-out parameters in the resulting C code?
Suppose the C header is:
void func(double a, double b, double c, double mat[3][4])
Should `mat` be created in the wrapper code, so that the python function header is func(a, b, c)? The performance benefits vs pythonic-ness really have to do with the nature of the calculations. If `mat` is small, but has elements with lots of operations (as seen in sympy.physics.mechanics) then the performance hit is neglible. In contrast, if `mat` is big, but has simple elements, the hit is relatively large.
Perhaps a kwarg? Or maybe if autowrap is passed (Eq(x, mat)) it will set an input matrix `x` to `mat`, otherwise it will return matrix `mat`?
2. What should `ufuncify` do with matrices? Jason messaged me earlier with a thought on this, I'll just paste his use case here as it explains it fairly well.
A very common use case that I'm finding in all my
dynamics work is to evaluate matrices in a tight loop for millions of
iterations. It would be cool to pass in a sympy matrix and generate a
function that would return a 3D numpy array when you evaluate the
function with equal length arrays (or scalars) as args. For example:
expr = Matrix([[a, b], [c, d]])
f = ufuncify((a, b, c, d), expr)
out = f(rand(1e6), rand(1e6), rand(1e6), 1.5)
out.shape == (1e6, 4, 4)
This kind of broadcasting would be doable (but maybe complicated? I'm not sure.). The big question is, does this kind of behavior for `ufuncify` make sense?