Can someone explain why substitution not working.

25 views (last 30 days)
I don't know why substitution is not working to find values of X1 X2 and X3.I'm familiar with subs command but still there is an issue with this code:
% clc;clear;close;
%Solution using Gauss-Seidal method
%define all variables
syms x1 x2 x3
%write all linear equations
%In diagonally dominant form(If possible)
eqn1 = 5*x1 - 2*x2 + 3*x3 == -1;
eqn2 = -3*x1 + 9*x2 + x3 == 2;
eqn3 = 2*x1 - x2 - 7*x3 == 3;
%determine x1, x2, and x3 in symbolic form
x1 = solve(eqn1, x1)
x2 = solve(eqn2, x2)
x3 = solve(eqn3, x3)
%initialse values
X1 = 0; X2 = 0; X3 = 0;
%apply loop for fixed no. of iterations
for i = 1:7
%solve for X1
X1 = subs(x1,{x2,x3},{X2,X3})
%solve for X2
X2 = subs(x2,{x1,x3},{X1,X3})
%solve for X3
X3 = subs(x3,{x1,x2},{X1,X2})
ajeet sahu
ajeet sahu on 6 Oct 2021
I'm repeating same process 7 times.Is there any other way to do the same?

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 6 Oct 2021
syms x1 x2 x3
When you do that, MATLAB talks to the Symbolic Engine and tells it to create a symbolic variable named x1 that lives inside the Symbolic Engine. The Symbolic Engine returns an internal reference to the variable that lives inside the Symbolic Engine; the reference is in the form of a character vector that might look something like '_ans_[31458,134532]' . That reference is then stored inside the MATLAB-level variable x1 . Likewise for x2 and x3 . Notice that in each case, the MATLAB-level variable only contains a reference to the actual symbolic variable (that lives inside the symbolic engine.)
eqn1 = 5*x1 - 2*x2 + 3*x3 == -1;
MATLAB sees 5*x1 and looks up the datatype for x1 and sees that it is a symbolic variable. So it recalls the internal symbolic reference stored inside the MATLAB level variable, and asks the Symbolic Engine to calculate _mult(5, _ans_[31458,134532]) inside the Symbolic Engine. The Symbolic Engine looks up _ans_[31458,134532] and sees that it is the Symbolic Engine variable x1 and calculates 5 * symbolic engine variable x1 with a symbolic engine expression 5 * x1 as the result. The symbolic engine assigns that to an internal variable, such as _ans_[295,40283157] and returns that internal reference to MATLAB . MATLAB continues, sees the - but knows that is lower priority than the * so it asks the symbolic engine to calculate 2*x2 by refering to the internal reference it was handed for x2, symbolic engine returns another _* variable reference to the resulting symbolic engine expression. Then the MATLAB level continues, sees the +, knows it is the same priority as the - . So now the MATLAB level takes the reference it was given, _ans_[295,40283157], and the one for 2*x2, and sends them to the Symbolic engine to calculate the difference, getting back another _ans* character vector. Then the 3*x3 sent to be calculated by the symbolic engine, getting back another _* reference, MATLAB then sees the == is lower priority than the pending + so it sends the _* references to the symbolic engine to do the addition.. Eventually you get the final symbolic engine result of building the equation, which is another _* character vector, and that gets stored in the MATLAB level variable eqn1
At no point here does MATLAB itself know what is really being calculated. All it knows is the priorities of the operators, and it knows to pull out the appropriate _* variables and the names of the operators and send the combinations to the symbolic engine, and it trusts that the symbolic engine will do the correct thing. IF the symbolic engine were programmed so that symbolic * operator meant that it should play "Anchors Away" on the line printer, then MATLAB would never know: it just passes constants and object references and operator names to the symbolic engine, and stores the references that the symbolic engine returns.
eqn2 = -3*x1 + 9*x2 + x3 == 2;
eqn3 = 2*x1 - x2 - 7*x3 == 3;
Likewise for those two lines: the result of the right hand side is references to symbolic engine variables and that is what gets stored in eqn2 and eqn3, with MATLAB trusting that the symbolic engine did the right thing.
x1 = solve(eqn1, x1)
As usual, when MATLAB sees an expression, it resolves the operands first. So it looks at the MATLAB level, and sees that eqn1 is a symbolic reference with an _* character vector stored against it, so it recalls that _* character vector. Likewise it recalls the _* character vector stored in the MATLAB level variable x1. And it asks to Symbolic Engine to process a "solve" operation. The symbolic engine looks up the meaning of those _* references that live inside the symbolic engine, and does the "solve" operation based upon its knowledge of those variables, and returns another _* character vector referring to the results.
Then... the MATLAB level assigns that _* character vector reference to the MATLAB level x1 variable. This does not affect the x1 that lives inside the symbolic engine. The symbolic engine is not informed about the assignment. The x1 that lives inside the symbolic engine is completely unchanged. Any existing references inside the symbolic engine to the symbolic engine variable x1 are unchanged . In particular, where x1 was used as part of constructing eqn2, the symbolic engine variable x1 that was used as part of eqn2 is unchanged and still refers to the symbolic engine variable named x1
If you think about this, the situation is exactly like
A = 1
B = A + 2 %B is now 1+2 --> 3
A = 5
Now what is the value of B ?
Does MATLAB look at the history of how B was assigned and see that it was constructed from A and A has now changed, so does B get updated to calculate from the new value of A ? NO. When B was assigned, the current value of A was copied and used for the calculation, and then the history of how B came into being is discarded, so when A is updated, B remains exactly the same as it was.
The situation is the same for symbolic work: if you use x1 in an expression, then its identity as a reference to an symbolic engine variable named x1 is copied, and if you then assign a new value to x1 at the MATLAB level then that reference is not changed inside the symbolic engine. (There are ways to assign to a variable inside the symbolic engine itself, and that could have effects on other expressions -- but not when you assign at the MATLAB level.)
x2 = solve(eqn2, x2)
as described, eqn2 did not get its internal symbolic variable x1 updated according to the result of the solve(). So eqn2 still has references to symbolic engine variables x1, x2, x3, and you solve with respect to x2 the answer is going to be in terms of symbolic engine variables x1, and x3. The sequence of instructions you used does not eliminate x1 from eqn2.
So what can you do? Well, you can use the subs() methods I showed you in your near duplicate question . In that Question I showed you how to fix the problem; in this question you seemed to be asking for more specific explanation of why your original code did not work, so this is the explanation: updating a symbolic variable at the MATLAB level does not update any prior reference to that symbolic variable... which is consistent with the way the rest of MATLAB works.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!