Clear Filters
Clear Filters

A symbolic implementation issue

9 views (last 30 days)
Hello,
I need to define a system of symbolic functions for a set of state variables. I explain by the following example:
syms x y
syms mu(x,y) [2 1]
syms sigma(x,y) [2 2]
par=sym('par', [1 6]);
mu(x,y)=[par(1)*x+par(2)*y;par(3)*x+par(4)*y];
sigma(x,y)=[par(5) 0;0 par(6)];
Here, it wotks well. However, as you see in above the function mu(x) is a vector which serves as a bi-variate function for me. A rather unprofessional way to define mu(x) would be as follows
syms mu1(x,y) mu2(x,y)
mu1(x,y)=par(1)*x+par(2)*y;mu2(x,y)=par(3)*x+par(4)*y
Likewise, for the function sigma(x) I could define 4 sub-functions (which is not so beautiful). What I wish to do is to repeat the same trick I used for symbolic functions mu(x,y) and sigma(x,y) for the symbolic variables x and y. I mean to say the following
syms x [2 1]
syms mu(x) [2 1]
syms sigma(x) [2 2]
par=sym('par', [1 6]);
mu(x)=[par(1)*x(1)+par(2)*x(2);par(3)*x(1)+par(4)*x(2)];
sigma(x)=[par(5) 0;0 par(6)];
Unfortunately, MATLAB does not accept this.
I am wondering if thisa is possible?
Thanks,
Babak

Accepted Answer

Walter Roberson
Walter Roberson on 26 Dec 2022
I need to define a system of symbolic functions for a set of state variables.
In MATLAB, it is not possible to define a ()-indexable array of symbolic functions.
syms mu(x,y) [2 1]
That defines a single symbolic function named mu that expects two parameters and returns a 2 x 1 array whose entries are invocations of other symbolic functions. If you were to try to use mu(1) then that would attempt to invoke the single symbolic function with a scalar input of 1 -- which would give you an error if y is used inside the function definition.
syms mu(x) [2 1]
That defines a single symbolic function named mu that expects one parameter and returns a 2 x 1 array whose entries are invocations of other symbolic functions.
It is not possible in MATLAB to define a symbolic function as expecting a vector input that you index into. You can define things like
syms x
mu(x) = x'*x
mu(x) = 
mu([2 5 -1])
ans = 
but notice that the conjugate got moved and that the elements got processed individually, instead of the parameter being treated as a vector that was being matrix multiplied by its transpose.
When you define a symbolic function, MATLAB processes the right hand side first as an expression, then it uses symfun() to wrap the result into a symbolic function. When the right hand side is being processed, any named variable is immediately expanded to its current value, and any remaining named variables after that are treated as scalar variables. So x'*x can be converted to effectively x.*x' because MATLAB treats the x as a scalar .
If you had done
syms x [1 3]
mu(x) = x'*x
mu(x1, x2, x3) = 
then the right hand side is evaluated first, the name x is expanded to its vector of symbolic variables, those are operated on, and symfun() is used to wrap the resulting matrix into a function of individual variables, not into a function of one variable.
What can you do if you want a single variable input? Well, you can, for example,
MU = matlabFunction(mu, 'vars', {x})
MU = function_handle with value:
@(in1)reshape([in1(:,1).*conj(in1(:,1)),in1(:,1).*conj(in1(:,2)),in1(:,1).*conj(in1(:,3)),in1(:,2).*conj(in1(:,1)),in1(:,2).*conj(in1(:,2)),in1(:,2).*conj(in1(:,3)),in1(:,3).*conj(in1(:,1)),in1(:,3).*conj(in1(:,2)),in1(:,3).*conj(in1(:,3))],[3,3])
When you use matlabFunction with a 'vars' option, and you pass a cell array, then each entry in the array designates a set of variables that is to be packed into a single parameter. The generated anonymous function MU can have a 1 x 3 vector passed into it and will return the 3 x 3 matrix when invoked. But notice this is not a symbolic function.

More Answers (1)

Karim
Karim on 25 Dec 2022
I'm not fully sure I understand what your are looking for. However, if the goal is to create arrays which hold symbolic equations you can try the method below. μand σ are intialized as just symbolic expressions witouth dimmensions etc. Afterwards we can fill them in. Does this work for you?
syms x [2 1]
syms par [1 6]
syms mu sigma
% create mu
mu(x) = [par(1)*x(1)+par(2)*x(2); par(3)*x(1)+par(4)*x(2)]
mu(x1, x2) = 
% create sigma
sigma(x) = [par(5) 0; 0 par(6)]
sigma(x1, x2) = 
  4 Comments
Walter Roberson
Walter Roberson on 26 Dec 2022
gradient is not defined for a vector-valued function.
If you have a vector valued symbolic function then you first need to invoke the symbolic function on specific values (which might be symbolic variables.) This will return a symbolic array. You can then arrayfun gradient over the members of the array, with UniformOutput false. Then splice together the results along whatever dimension seems appropriate.
Paul
Paul on 26 Dec 2022
Insofar as mu(x) is a vector valued function, perhaps you mean to compute the jacobian?
syms x [2 1]
syms par [1 6]
mu(x) = [par(1)*x(1)+par(2)*x(2); par(3)*x(1)+par(4)*x(2)];
jacobian(mu,x)
ans(x1, x2) = 

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!