How to substitute multiple array syms easily?

35 visualizaciones (últimos 30 días)
Elias Hasle
Elias Hasle el 12 de Oct. de 2019
Comentada: Walter Roberson el 11 de Mzo. de 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.

Respuestas (2)

Walter Roberson
Walter Roberson el 11 de Mzo. de 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 comentario
Walter Roberson
Walter Roberson el 11 de Mzo. de 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.

Iniciar sesión para comentar.


Charan Jadigam
Charan Jadigam el 11 de Mzo. de 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 comentario
Walter Roberson
Walter Roberson el 11 de Mzo. de 2020
No no, cell arrays is perfectly valid and necessary if substituting in more than one array.

Iniciar sesión para comentar.

Etiquetas

Productos


Versión

R2018b

Community Treasure Hunt

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

Start Hunting!

Translated by