29 views (last 30 days)

Show older comments

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.

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.

Walter Roberson
on 11 Mar 2020

No no, cell arrays is perfectly valid and necessary if substituting in more than one array.

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.

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.

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

Start Hunting!