Effacer les filtres
Effacer les filtres

Summation with syms not returning a single value

2 vues (au cours des 30 derniers jours)
Spyros Polychronopoulos
Spyros Polychronopoulos le 9 Mar 2018
I would expect the code below to return (O) just one value for zd=(A(:,3)) as I am summing the matrices.
A = ones(10,3);
syms x y zd
p = sum((x-A(:,1)).^2+(y-A(:,2)).^2+zd);
x = 2;
y = 3;
O = @(zd) double(subs(p));
O(A(:,3))
It rather returns 10 values as if it's not doing the summation. I think there must be an issue with setting the x and y values because the same code without symbols returns, as expected, a single value:
A = ones(10,3);
p = sum((2-A(:,1)).^2+(3-A(:,2)).^2+A(:,3))
Any ideas why the first code doesn't return a single value?

Réponse acceptée

Walter Roberson
Walter Roberson le 9 Mar 2018
Modifié(e) : Walter Roberson le 9 Mar 2018
Your O(A(:,3)) is essentially requesting that double(subs(p)) be executed once for each value of A(:,3) with zd being set to each value in turn, so you are going to get one answer for each A(:,3) value. [This is not how it is actually implemented, but the result is the same.]
When you create a symbolic expression involving a variable, then there is no way to tell the Symbolic toolbox that the variable is standing in for something that will later be replaced by an array and that you want array operations used in conjunction with the arrays that are already in the expression. As far as the symbolic toolbox is concerned, every symbolic variable name (that is not a function) represents a scalar, and it will use scalar logic for it.
Consider for example,
syms x y
x * y
y * x
ans =
x*y
ans =
x*y
Notice you get the same response for the two different orders. This is acceptable under the assumption that x and y are scalars, because scalars are commutative under matrix multiplication. It would, however, be unacceptable if x and y were standing in for arrays, because matrix multiplication of arrays is not commutative.
When you subs() in a matrix for a symbol in an expression, the entire expression is evaluated once for each value of the matrix, even if what you are subs() in is the same size as the original expression
> syms x
A = [1 + x, 2 + x; 3 + x, 4 + x]
X = [9 10; 11 12]
A =
[ x + 1, x + 2]
[ x + 3, x + 4]
X =
9 10
11 12
>> subs(A,x,X)
ans =
[ 10, 11, 11, 12]
[ 12, 13, 13, 14]
[ 12, 13, 13, 14]
[ 14, 15, 15, 16]
>> subs(A,x,[100 200])
ans =
[ 101, 201, 102, 202]
[ 103, 203, 104, 204]
When you subs() in multiple variables in the same subs() call, then corresponding elements of the input matrices are used.
>> syms x y
>> A = [x+y, x+2*y]
A =
[ x + y, x + 2*y]
>> subs(A,{x,y}, {[100 200], [1000 2000]})
ans =
[ 1100, 2200, 2100, 4200]
This is not the same as doing the two subs() sequentially:
>> subs(subs(A,x,[100 200]),y,[1000 2000])
ans =
[ 1100, 2100, 1200, 2200, 2100, 4100, 2200, 4200]
  3 commentaires
Walter Roberson
Walter Roberson le 10 Mar 2018
To work with matrices at the symbolic level, you have to specialize each formula according to the expected matrix size.
A1 = rand(64,1);
A2 = rand(2,1);
zd = sym('zd', [size(A1,1), 1]);
syms x y
p64 = sum((A1(:,1)-A2(1)).^2+(zd-A2(2)).^2);
O64 = @(ZD) double(subs(p64, zd, ZD));
Notice here that the zd in the O64 definition is an array of symbols. Each symbol is substituted with the corresponding value of ZD
You can often instead usefully use
On64 = matlabFunction(p64, 'vars', {zd});
which will return a function handle that expects a column vector of length 64 and will do the calculation numerically.
Spyros Polychronopoulos
Spyros Polychronopoulos le 10 Mar 2018
Thank you so much Walter! It worked! Or I could use this method for just zd that is a matrix
A = ones(10,3);
syms x y
p = @(zd) sum((x-A(:,1)).^2+(y-A(:,2)).^2+zd);
x = 2;
y = 3;
O = @(zd) double(subs(p(zd)));
O(A(:,3))
Would you maybe also know how could I store various versions of O with different x and y depended only from zd? When I am doing that seems like that every time x and y change value they are affecting O{1} and O{2}. That tells me that O{1} is not only depended on zd and have a set value of x and y so O{1}(2) is equal to Q{2}(2). Please see the example code below:
A = ones(10,3);
Tx=[2 4];
Ty=[1 2];
syms x y zd
p = (sum((x-A(:,1)).^2+(y-A(:,2)).^2+zd));
for a=1:2
x = Tx(a);
y = Ty(a);
O{a} = @(zd) double(subs(p));
end
O{1}(2)
O{2}(2)

Connectez-vous pour commenter.

Plus de réponses (0)

Community Treasure Hunt

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

Start Hunting!

Translated by