Diff does not work with non trivial expression with vectors

3 views (last 30 days)
Consider the following example:
syms row1 row2 [1,5] matrix
syms col [5,1] matrix
diff(row1*(row2.'+col), row2)
ans = 
diff(row1*row2.'+row1*col, row2)
ans = 
The two expressions are equivalent, but in the first case, diff is unable to compute the derivative.
I found that the following workaround works, but I am concerned that it may cause issues when dealing with more complex expressions:
diff(row1*(row2.'+col), row2.').'
ans = 
Is there a specific reason why the first command does not work, or should this be reported as a bug? Do you know of a better workaround?
Thank you.
  2 Comments
Paul
Paul on 26 Mar 2025
I think reaching out to Tech Support would be appropriate.
There's nothing in the documentation for diff to indicate that there should be any issue differentiating a scalar wrt to a row vector, at least as far as I can tell. To the contrary, it even states, "For example, if f is a 1-by-1 scalar and mvar is a 1-by-3 row vector ...."
If you do decide to open a Tech Support case, it would be great if you posted back here with a summary of their response.
TED MOSBY
TED MOSBY on 26 Mar 2025
@Paul thats right, one can always differentiate a scalar with a row vector infact mostly all expression should work fine, but the documentation does not cover every corner case, this might be one of them. So it is possible it might just be a limitation and not a bug. @GIOSUÉ can verify this using some other examples as well and see if the issue persists. Nonetheless, getting a confirmation from the Tech Support will be great if Giosue wants to.

Sign in to comment.

Answers (1)

TED MOSBY
TED MOSBY on 26 Mar 2025
Edited: TED MOSBY on 26 Mar 2025
Mathematically, the two expressions are identical:
row1(row2+col)  =  row1row2⊤  +  row1col
However, the symbolic engine might treat it differently. In the form
row1*(row2.+ col)
the engine sees a product of a 1×5 row vector (row1) and a 5×1 subexpression (row2+col).
When you then say diff(..., row2) ,MATLAB tries to interpret “differentiate w.r.t. row2 (a 1×5 matrix variable),” but inside that product, it finds row2⊤ (5×1) plus another column vector. It does not automatically expand or reconcile the shapes. This sometimes leads the engine to get confused as it can’t see how row2 (1×5) is showing up in this subexpression (5×1), and it fails or returns an unevaluated derivative.
Expanding the product helps the engine sometimes:
Once you rewrite:
row1*(row2.+ col)  →  row1*row2.+ row1*col
now it’s two simpler terms:
row1row2
row1col
In this form, MATLAB can more easily see how each term depends on the entries of row2 and can take partial derivatives with respect to them. That’s why
diff(row1*row2.+ row1*col, row2)
succeeds.
By contrast, when you write
diff( expression, row2.' )
you are telling MATLAB to “differentiate w.r.t. the column vector” version of row2. That column vector has dimension (N×1). Symbolically, that’s more natural for the engine—it sees “N separate scalar entries in a column.”
After doing that differentiation, MATLAB’s result is typically an (N×1) column vector. If you want it back in a row shape, you then do another transpose:
diff(expression, row2.').'
which flips the result from (N×1) back to (1×N).
MATLAB likes to differentiate with respect to columns of scalar variables. A column vector is the simplest shape for partial derivatives in the engine’s logic.
If your variable is defined as a row vector, the symbolic engine may get confused and fail or yield unexpected results in some cases.
From the documentation(reference link below):
“When differentiating a scalar function f with respect to a vector or matrix mvar, diff uses the convention of returning an output size that is the transpose of the input size mvar.”
  • This statement tells you that if mvar is 1×5, the result is supposed to be 5×1.
  • In practice, if your expression references mvar in a transposed form (e.g., a 5×1 subexpression) but you still pass in the 1×5 version as the differentiation target, the engine may fail to unify those shapes. That’s exactly what happens with diff(row1*(row2.' + col), row2): the internal shapes mismatch, so it behaves unexpectedly.
Here is the link to the documenetation of "diff" :
Hope this helps!
  1 Comment
GIOSUÉ
GIOSUÉ on 28 Mar 2025
Thank you so much for you answer.
Summarizing, if it is possible is always better to differentiate with respect to columns, than with respect of row. Got it.
However, I think it should be possible to differentiate along row, and probably could be interesting to open a tech support case. Eventually I will post the update.

Sign in to comment.

Tags

Products


Release

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!