How to access a symbolic variable created by sym?

37 views (last 30 days)
Basically I need to create two sets of "y" symbolic variables that are defined by the user. Doing so with the function
u=sym('u',[y 1]);
r=sym('r',[y 1]);
After running, asking for r(1) returns r1, but asking for r1 gives the error "Undefined function or variable 'r1'.". This code is meant to end up with three matrices: u, r and K so that K*u=r, where K a numerical double symmetrical matrix. I'm assigning some values to some of the matrices so that the u matrix at the end is [0; u2; u3; u4;0] and the r is [r1;0;1000;0;r5] but I can't find a way to solve this problem. Using the function
s=solve(K*u==r,u,r)
returns the error
Error using sym.getEqnsVars>checkVariables (line 88)
The second argument must be a vector of symbolic variables.
Does anyone have any idea how to properly assign these variables and how to solve the system at the end? Thank you in advance.
  2 Comments
madhan ravi
madhan ravi on 19 Jul 2018
Edited: madhan ravi on 19 Jul 2018
r=sym('r',[1 10]);
Because the vector array has to be integers?
Israel Solha
Israel Solha on 20 Jul 2018
The problem isn't creating the vector. It works fine using y, the problem is accessing the variables created by it. Let's say y=10 it's going to create r1 r2 r3 ... r10 but if I try to access any of those by typing r1 I just get the error message "undefined function or variable"

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 19 Jul 2018
subs(expression, u([1 4]), [0 0])
In most circumstances it is better to avoid assigning a value to an existing symbolic variable that has been used in an expression.
  2 Comments
Israel Solha
Israel Solha on 20 Jul 2018
I thought this could cause problems, but the first thing that seems wrong comes before that. After creating the r and u vectors, I can't access any of its components. typing r(5) will return r5 but typing r5 will just give the undefined variable error. I just don't understand why I can't access these variables and what I should do to be able to do so.
Walter Roberson
Walter Roberson on 20 Jul 2018
r=sym('r',[y 1]); does not create variables r1, r2, r3, r4, and so on.
r=sym('r',[y 1]) creates a vector of references to the workspace that lives inside the symbolic engine, each one referring to an entity with the corresponding name there.
The vector of references is then assigned to the variable named r in the MATLAB workspace. This does not trigger the existence of a variable named r inside the symbolic engine.
If you were to do
syms t
then syms would be very much equivalent (except for flag processing) to
function syms(varargin)
for K = 1 : nargin
assignin('caller', varargin{K}, sym(varargin{K}))
end
which is to say that
syms t
effectively is the same as
t = sym('t');
This creates a reference to the variable t that lives inside the symbolic engine, and assigns the reference to the variable t that lives in the function workspace.
If you were to now command
t = 0
then this would overwrite the reference with the new numeric value, but would not have any effect on the variable t that lives inside the symbolic engine.
If you had done
syms t
f = t^2 + 5;
then the content of t in the workspace would be looked up, and would be found to be a reference into the symbolic engine. The symbolic engine would be invoked to square whatever value is associated with the reference, and then to add 5 to the result. Unless you do some fancy bashing inside the symbolic engine, the variable t inside the symbolic engine is going to refer to itself, and what would be built would be a symbolic expression inside the symbolic engine that had reference to the symbolic variable t that lives inside the symbolic engine, and a reference to that symbolic expression would be returned from the symbolic engine. The assignment would then assign the reference to the symbolic expression (inside the symbolic engine) to f.
If you then proceeded to
t = 0;
then, as indicated above, this overwrites the reference that is stored in the MATLAB workspace, and in no way changes anything inside the symbolic engine, so f in the MATLAB workspace would continue to refer to a symbolic expression that lives in the symbolic engine, and that expression would continue to have a reference to the t that lives in the symbolic engine, which has not been changed. So after the
t = 0;
then asking for f would continue to print out
t^2 + 5
and that t shown there is the one from the symbolic engine, not the one in the MATLAB workspace that is now numeric. So the t = 0 does not result in f becoming 0^2 + 5 .
Thus when you did
u = sym('u', 5, 1);
then the only variable changed in the MATLAB workspace is u, and the MATLAB workspace does not gain variables u1, u2, u3, u4, u5, and the symbolic engine does not gain variable u, but the symbolic engine does gain variable u1, u2, u3, u4, u5.
When you then try to refer to u1 inside the MATLAB workspace, that is an error, because you never created u1 inside the MATLAB workspace. You could -- you could, for example,
u1 = u(1);
u2 = u(2);
and so on.
So to get
w = [u1; 0; 0; 0; u5]
you could do those assignments to u1, and so on and then execute that assignment to w. Or you could do
w = zeros(5, 1, 'sym') %not supported on older MATLAB
or
w = sym(zeros(5,1));
and then
w(1) = u(1); w(5) = u(5);
Or, you could do
w = subs(u, u(2:4), zeros(3,1))
There is hardly anything you can do at the MATLAB level that can change the value associated with a symbolic variable inside the symbolic engine. Changing the assumptions on a variable does communicate through to the symbolic engine, affecting the properties associated with the name. Any assignment you do at the MATLAB level might trigger evaluation at the symbolic engine but that will return a reference to the symbolic expression that results, and the assignment of the reference will take place at the MATLAB workspace without any assignment taking place in the Symbolic Engine.
The only thing you can do at the MATLAB level that can change the value associated with a symbolic variable inside the symbolic engine, is to use evalin(symengine) or feval(symengine) to dispatch MuPAD assignment statements.
Because the MATLAB level only holds references into the symbolic engine, if you want to make a change to a variable that has been used in a symbolic expression, the best way is to use subs(). subs() evaluates the input expression, making the replacements you indicate, and returning a reference to the evaluated expression -- leaving the original expression intact.
In the above example of
syms t
f = t^2 + 5
then, as indicated above,
t = 0;
would not have any effect on f. You should instead do
subs(f, t, 0)
without the assignment to t.
If you assign a new value to a symbolic name that has been used to construct an expression, chances are that you are making a mistake (unless you are promptly overwriting that other expression)

Sign in to comment.

More Answers (0)

Products


Release

R2015a

Community Treasure Hunt

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

Start Hunting!