Search code examples
arraysmatlabsymbolic-math

When symbolic array gets updated, another variable that uses an element of the first array cannot be updated anymore


To simplify my actual problem, let's define the following symbolic expressions.

a=sym('a',[1,3]);
b=a(1);

If I somehow assign a new thing to a, I cannot get b to update. What is the proper way of doing this?

Example 1:

a=sym('a',[1,3]);
b=a(1);
a=sym([1,2,3]);
b
subs(b)
subs(b,a(1),100)

Example 1 Output:

b =

a1


ans =

a1


ans =

a1

Example 2:

a=sym('a',[1,3]);
b=a(1);
a=subs(a,a(1),3);
b
subs(b)
subs(b,a(1),100)

Example 2 Output:

b =

a1


ans =

a1


ans =

a1

Example 3:

a=sym('a',[1,3]);
b=a(1);
a(1)=sym(3);
b
subs(b)
subs(b,a(1),100)

Example 3 Output:

b =

a1


ans =

a1


ans =

a1

My actual problem is the following. I have N unknowns

a=sym('a',[1,N]);

and N equations.

EQN=sym('EQN',[1,N]);

N is defined according to user input and I don't know what it will be beforehand. I also have other variables that are dependent on a.

% some code here such as b = [2*a(1),3*a(2),..] etc.

Then I solve the equations for the unknowns

% some code here to derive EQN(1), EQN(2), ... EQN(N).
SOL=solve(EQN,a);

and substitute the solutions to a

SOL = struct2cell(SOL);
SOL = [SOL{:}];
a=subs('a',a,SOL);

Now I want to get rid of unknowns in b but I cannot due to the reason I tried to explain in the beginning.


Solution

  • The problem is that you are overwriting a instead of assigning a new value to a1, a2 and a3. So, you should change the underlying variable instead of a itself.

    a=sym('a',[1,3]);
    b = a(1)
    a1 = 1; 
    subs(b) % returns 1
    subs(b, 'a1', a1) % returns 1
    subs(a) % [ 1, a2, a3]
    

    If you want to use it to substitute the result of a solve operation, the best solution is to use subs with the output structure of solve as input:

    sol = solve(a == [1 2 3], a);
    subs(b, sol) % returns 1
    

    Note that you can also manually construct this structure as follows:

    sol.(char(a(1))) = 1 % sol.a1 = 1;