Consider the script
syms a b;
f = a.*b;
a = [1 2];
b = [0 2];
subs(f)
This yields a vector as output ([0, 4]), but the intended output is a scalar (4), given the element-wise multiplication that should be performed.
How can I properly utilize vectors when substituting symbolic functions?
I believe you're making two mistakes. The first is that you're overwriting your symbolic variables with double arrays, so you're not actually calling subs for a symbolic object:
>> syms a;
>> class(a)
ans =
sym
>> a = [1 2];
>> class(a)
ans =
double
The second is that preventing this will still give a wrong answer:
>> syms a b;
>> f = a.*b
f =
a*b
>> subs(f,{a,b},{[1, 2], [0,2]})
ans =
0 4
That's because, as you see in the printed version of f, the symbolic engine treats a and b as scalars.
So to do what you probably want to do you need to define your syms to be 2-element arrays:
> a = sym('a',[1 2])
a =
[ a1, a2]
>> b = sym('b',[1 2])
b =
[ b1, b2]
>> f = a.*b
f =
[ a1*b1, a2*b2]
>> subs(f,[a,b],[[1,2],[0,2]])
ans =
0 4
But anyway, as you can see, the result is still an array since .* (or symbolic *) is elementwise multiplication. In order to get a scalar product, use sym/dot:
>> dot(a,b)
ans =
b1*conj(a1) + b2*conj(a2)
>> subs(dot(a,b),[a,b],[[1,2],[0,2]])
ans =
4
Related
I have created a function containing symbolic expressions. The expressions make use of a symbolic matrix. I want to solve the function passing the numeric matrix which replaces the symbolic matrix and provides a numeric answer. I can't seem to understand how to pass the numeric matrix.
function example
R= sym('R',[3 3])
r_b= R([1 2], [3])
R_bar= R([1 2], [1 2])
R_til=R([2 3],[2 3])
syms alpha_bar beta_bar
a_bar= [1;alpha_bar]
b_bar= [beta_bar;1]
P= sym(R_bar*a_bar)
Q= sym(R_til*b_bar)
syms E_a E_b
u_bar= [1; 0]
v_bar= [0;1]
W = sym(E_a*u_bar)
X= sym(E_b*v_bar)
C= sym(P==W)
D= sym(Q==X)
[alpha_bar_, E_a_] = solve(P==W,[alpha_bar,E_a])
[beta_bar_, E_b_] = solve(Q==X,[beta_bar,E_b])
a_bar= [1;alpha_bar_]
b_bar=[beta_bar_;1]
delta= (a_bar)'*r_b
gamma_b = delta/E_b_
gamma_a= delta/E_a_
a= [a_bar;0]-(gamma_b*[0;b_bar])
b= [0;b_bar]-gamma_a*[a_bar;0]
end
My R is R = [1 1 0; 1 3 2; 0 2 3].
I am trying to take the dot product of a symbolic vector and another vector. I did the following:
>> rac = sym('rac',[3 1])
rac =
rac1
rac2
rac3
>> i = [1;0;0]
i =
1
0
0
>> dot(rac,i)
ans =
conj(rac1)
However my desired outcome is rac1. Why is it not behaving like I want it to? And how do I achieve this output?
You need to specify that your symbolic vector is real:
rac = sym('rac', [3 1], 'real');
dot(rac, [1; 0; 0])
ans =
rac1
Consider the following code:
A = sym('a', [1, 2]);
b = sym('b');
ans = A.^2 + b;
A = [1, 2];
b = 4;
subs(ans)
This yields the output
ans = [ a1^2 + 4, a2^2 + 4]
Whereas I would have wanted it to produce
ans = [ 5, 8]
What is required for the vector to be converted to numeric values aswell?
Here's a simpler solution:
syms A b; %Initializing symbolic variables
expr = A^2 + b; %Your expression (element-wise square is taken by default for sym class)
A = [1 2]; b=4; %Assigning the values
subs(expr) %Substituting symbolic variables with corresponding assigned values
Output as desired:
ans =
[ 5, 8]
Comments:
Always avoid dynamic variables. In your code, you're specifying A to be [1, 2] but your expression doesn't actually have A in it. It has a1 and a2 (and b obviously).
Don't name your variables/functions after the reserved variable names or in-built functions. ans is used for the Most Recent Answer when expressions are not assigned to anything else. (That's why I replaced ans in your code with expr)
In a previous question, a user asked about iterating over a cell array of anonymous functions. I am wondering whether there is a way to evaluate a set of functions without the explicit use of a for loop.
As an example, the following code creates an array of (simple) functions, evaluates them for a fixed value and stores the results:
fcnList = {#(x) (x+1), #(x) (x+2)};
a = 2;
for i = 1:numel(fcnList)
y(i) = fcnList{i}(a);
end
Is there a way to do this without looping?
For your example, you could do the following using the cellfun function:
fcnList = {#(x) (x+1), #(x) (x+2)};
a = 2;
cellfun(#(func) func(a),fcnList)
ans =
3 4
Where I have created a handle called func which accepts as input a function from the fcnList variable. Each function is then evaluated for a.
If you need to pass a vector instead of a scalar, for instance b, you will need to set the 'UniformOutput' option to false:
b=[3 4]
fcnList = {#(x) (x+1), #(x) (x+2)};
cellfun(#(func) func(b),fcnList,'UniformOutput',false)
ans =
{
[1,1] =
4 5
[1,2] =
5 6
}
To avoid a for loop or cellfun (which is more or less the same as a loop), you can define a single function with vector output:
fcn = #(x) [x+1, x+2];
Then fcn(a) gives you a vector cointaining the results:
>> fcn = #(x) [x+1, x+2];
>> a = 2;
>> fcn(a)
ans =
3 4
If the results of each original function have different sizes you can define a single function with cell array output:
>> fcn = #(x) {x+1, [x+2; x+3]};
>> a = 2;
>> x = fcn(a)
x =
[3] [2x1 double]
>> celldisp(x)
x{1} =
3
x{2} =
4
5
EDIT:
In regards to the linked question referenced above, I'm trying to describe a different computation than the one above. The one above is of form:
func1 >> func2 >> func3
where >> denotes continuation. Most importantly, func2 do not bind to any variable output by func1, and so on.
My function is of form:
func1 >>=# x func2(x) >>=# y func3(y)
where >>=# denotes continuation from func1 and func2, and func2 binds to the output of func1. So the key here is variable assignment needs to persist between function calls.
Question Proper.
I have this function declaration:
function[y] = distR3(x,c)
a = bsxfun(#minus, x, reshape(c, [1 1 3]));
b = a .* a;
c = b(:,:,1) + b(:,:,2) + b(:,:,3);
y = sqrt(c);
end
That I would like to convert to some anonymous function, perhaps like:
% Incorrect syntax
distRN = #(x,c)
a = bsxfun(#minus, x, reshape(c, [1 1 3]));
b = a .* a;
c = b(:,:,1) + b(:,:,2) + b(:,:,3);
y = sqrt(c);
return y
The key thing to note here is that there's multiple lines in the function, with variable assignment and possibly in-place update of variables.
Is such a thing possible?
EDIT EDIT:
I seem to have found an answer that uses "higher-order-functions". Here's the final code:
distRN = #(x,y) sqrt(c((b(a(x,y)))));
a = #(x,c) bsxfun(#minus, x, reshape(c, [1 1 3]));
b = #(a) a .* a;
c = #(b) b(:,:,1) + b(:,:,2) + b(:,:,3);
Note the indentations over a,b,and c are mine and have no effect.