sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.97k stars 4.43k forks source link

Derivatives of expressions with symbolic matrices mixed with explicit matrices #15651

Open Upabjojr opened 5 years ago

Upabjojr commented 5 years ago

They are not supported:

In [45]: expr
Out[45]: 
⎡X₀₀  X₀₁  X₀₂⎤  
⎢             ⎥  
⎢X₁₀  X₁₁  X₁₂⎥⋅X
⎢             ⎥  
⎣X₂₀  X₂₁  X₂₂⎦  

In [46]: expr.diff(X)

we get

AttributeError: ImmutableDenseMatrix has no attribute _eval_derivative_matrix_lines.
asmeurer commented 5 years ago

The code should give an unevaluated derivative for anything that isn't supported. AttributeError isn't good.

Upabjojr commented 5 years ago

I was also wondering about the algorithm. Maybe this should return the transposition of the explicit matrix, what do you think?

asmeurer commented 5 years ago

In your example is the X of the explicit matrix the same as the X it is multiplying?

Upabjojr commented 5 years ago

In your example is the X of the explicit matrix the same as the X it is multiplying?

That's the problem. In principle yes, but I would say no.

I guess we should use a simple rule for differentiability, i.e. if the variable is structurally equal, derive it, otherwise it's a constant.

asmeurer commented 5 years ago

I think if any of the matrix elements depend on X (like they contain MatrixElement(X)) terms, then we cannot assume it is constant wrt X. Otherwise yes, it should be constant. That's the same rule we use for normal SymPy expressions. x.diff(y) gives 0. If you want x to depend on y you have to create a function, or some other kind of object that knows that it depends on y (via free symbols, or redefining _eval_derivative, or whatever).

But suppose the elements of some explicit matrix A do depend on X. Does the matrix diff algorithm let you take the derivative of A wrt X? Or can you only do it if you can recognize A as some known function on X, like X.T or B*X where B is some transposition matrix?

Upabjojr commented 5 years ago

What about automatically turning the diff-w.r.t. variable into X.as_explicit() whenever there is an explicit matrix?

Unfortunately this introduces the problem of handling higher dimensional arrays.

asmeurer commented 5 years ago

Can we take the derivative wrt an explicit matrix? Maybe I'm misunderstanding what you are suggesting, but wouldn't that make it harder?

Upabjojr commented 5 years ago

I am suggesting to make X.as_explicit().diff(X) return the same as X.as_explicit().diff(X.as_explicit()).

asmeurer commented 5 years ago

Ah, I didn't realize you could already take derivatives with respect to explicit matrices, and it returns an NDimArray.

What if the matrix contains references to X (as MatrixElements), but X itself has symbolic shape? I suppose in that case we will just have to return unevaluated.