MATLAB Answers

How to substitute multiple array syms easily?

29 views (last 30 days)
Elias Hasle
Elias Hasle on 12 Oct 2019
Commented: Walter Roberson on 11 Mar 2020
Setup:
A = sym('A', 4)
B = sym('B', 3)
x = A*A(1:4,1)+[B(1:3,1); 0]
subs(x, {A, B}, {diag([3,2,1,0]), diag([1,3,5])})
Output:
A =
[ A1_1, A1_2, A1_3, A1_4]
[ A2_1, A2_2, A2_3, A2_4]
[ A3_1, A3_2, A3_3, A3_4]
[ A4_1, A4_2, A4_3, A4_4]
B =
[ B1_1, B1_2, B1_3]
[ B2_1, B2_2, B2_3]
[ B3_1, B3_2, B3_3]
x =
A1_1^2 + B1_1 + A1_2*A2_1 + A1_3*A3_1 + A1_4*A4_1
B2_1 + A1_1*A2_1 + A2_1*A2_2 + A2_3*A3_1 + A2_4*A4_1
B3_1 + A1_1*A3_1 + A2_1*A3_2 + A3_1*A3_3 + A3_4*A4_1
A1_1*A4_1 + A2_1*A4_2 + A3_1*A4_3 + A4_1*A4_4
Error using sym/subs>normalize (line 231)
Entries in second argument must be scalar.
Error in sym/subs>mupadsubs (line 157)
[X2,Y2,symX,symY] = normalize(X,Y); %#ok
Error in sym/subs (line 145)
G = mupadsubs(F,X,Y);
Error in debug_sym (line 4)
subs(x, {A, B}, {diag([3,2,1,0]), diag([1,3,5])})
Attempts at using
syms A B
for the initial declaration have failed at the indexing stage (the definition of x), because the symbols are then assumed to be scalar. It seems, though, that subs can handle them correctly.
The most promising (actually the only) workaround I have found is to apply the substitutions one at a time, which connects to the common logic for dimension checking:
subs(subs(x, A, diag([3,2,1,0])), B, diag([1,3,5]))
(Output:)
ans =
10
0
0
0
but this reduces readability and I assume it will also harm performance, particularly when doing many substitutions.

  0 Comments

Sign in to comment.

Answers (2)

Charan Jadigam
Charan Jadigam on 11 Mar 2020
Hi,
The 2nd and 3rd argument of the ‘subs’ function should be either scalars or vectors but not cell arrays and they need to match in size. In your case ‘A’ and ‘B’ are of different size and so the solution would be to make the symbol arrays same size and try this
subs(x, [A B], [diag([3,2,1,0]) diag([1,3,5,0])])
with square brackets. If the arrays are of different size then it would be better to try this,
subs(subs(x, A, diag([3,2,1,0])), B, diag([1,3,5]))
as you mentioned.

  1 Comment

Walter Roberson
Walter Roberson on 11 Mar 2020
No no, cell arrays is perfectly valid and necessary if substituting in more than one array.

Sign in to comment.


Walter Roberson
Walter Roberson on 11 Mar 2020
V = @(X) X(:)
subs(x, [V(num2cell(
A)); V(num2cell(B))], [V(num2cell(diag([3,2,1,0])); V(num2cell(diag([1,3,5])))])
Although it is not obvious, this is the cell form. The second argument is constructing a cell array variable names, and the third argument is constructing a cell array of replacement values.
You can also use
V = @(X) X(:);
subs(x, [V(A);V(B)], [V(diag(3,2,1,0)); V(diag(1,3,5))])
This is the vector of variables form.
The difference between these two forms is that in this second form that does not use cells, each entry in A and B must be replaced with a scalar, whereas with the cell form I gave first, each entry could potentially be replaced with a vector or array.
Neither of these requires changing the size of B to match A.

  1 Comment

Walter Roberson
Walter Roberson on 11 Mar 2020
To expand a little:
subs() can accept an array of variables as its second parameter, and another array the same size as the third parameter, and does a substitution of scalars according to corresponding positions.
subs can also accept a cell array of variables for the second parameter, and a cell array the same size as the third parameter, and will do a simultaneous substitution of the (possibly array) contents of the cell for the corresponding variable.
But subs cannot accept a cell array that contains multiple nonscalar arrays for the second parameter. Each cell entry must be scalar.
My first code suggestion above converts the arrays of variables into cell arrays the same size, and then forms a column vector out of them so that you can concatenate multiple such cell arrays together even if they had incompatible array sizes. Then it does likewise on the replacement values, forming cell array column vector from them.
The second code reforms the array of variables into a column vector so that you can concatenate multiple such arrays together. No cell arrays involved.
If you are substituting scalars for the variables, it is not especially useful to use the cell approach.

Sign in to comment.

Tags

Products


Release

R2018b

Translated by