Solving Unknowns with Symbolic Toolbox

2 views (last 30 days)
I have a relatively simple problem to solve with the symbolic toolbox which works fine with X = lsqminnorm(a,b), but not this toolbox. The knowns are as follows (A=1,B=2,C=3,D=4), which I am trying to solve with the relationships below:
syms A B C D
eqn_1 = 3 == A + B;
eqn_2 = 7 == C + D;
eqn_3 = 4 == A + C;
eqn_4 = 6 == B + D;
eqns = [eqn_1
eqn_2
eqn_3
eqn_4];
[a,b] = equationsToMatrix(eqns, [A B C D]);
X = linsolve(a,b);
I get the following error:
Warning: Solution is not unique because the system is rank-deficient.
> In symengine
In sym/privBinaryOp (line 1214)
In sym/linsolve (line 63)
X =
-3
6
7
0
Works fine though if I use X = lsqminnorm(a,b)
>> X = lsqminnorm(double(a),double(b))
X =
1.0000
2.0000
3.0000
4.0000
The issue is that I can't use lsqminnorm with double() as the other similar equations organized in this format contain other symbolic variables/unknowns. Any help would be greatly appreciated. I apologize in advance if this is a silly question.

Accepted Answer

KSSV
KSSV on 23 Sep 2022
A = [1 1 0 0 ;
0 0 1 1 ;
1 0 1 0 ;
0 1 0 1] ;
b = [3;7;4;6] ;
x = pinv(A)*b
x = 4×1
1.0000 2.0000 3.0000 4.0000
Note that rank of A is 3, so with A\b you will not get solution.
With symbolic tool box:
syms A B C D
eqn_1 = 3 == A + B;
eqn_2 = 7 == C + D;
eqn_3 = 4 == A + C;
eqn_4 = 6 == B + D;
eqns = [eqn_1
eqn_2
eqn_3
eqn_4];
[a,b] = equationsToMatrix(eqns, [A B C D]);
X = pinv(a)*b
X = 
  1 Comment
J.D. Johnston
J.D. Johnston on 23 Sep 2022
Thank you so much. I never would have considered pinv.

Sign in to comment.

More Answers (1)

Walter Roberson
Walter Roberson on 23 Sep 2022
syms A B C D real
eqn_1 = 3 == A + B;
eqn_2 = 7 == C + D;
eqn_3 = 4 == A + C;
eqn_4 = 6 == B + D;
eqns = [eqn_1
eqn_2
eqn_3
eqn_4];
sol = solve(eqns, [A, B, C, D], 'returnconditions', true)
sol = struct with fields:
A: x - 3 B: 6 - x C: 7 - x D: x parameters: x conditions: in(x, 'real')
sol.A
ans = 
sol.B
ans = 
sol.C
ans = 
sol.D
ans = 
x
sol.parameters
ans = 
x
Your system is not full rank. It can be rewritten in terms of a parameter, here written as x which is equivalent to D. So every different D value has a different solution.
lsqminnorm() "minimizes the value of norm(A*X-B). If several solutions exist to this problem, then lsqminnorm returns the solution that minimizes norm(X)" and those are things you can potentially compute yourself
[a, b] = equationsToMatrix(eqns)
a = 
b = 
syms X [4 1]
n = norm(a*X - b)
n = 
We can minimize the norm by minimizing the individual parts... but that is the same system of equations as we solved earlier, so we get
Xbest = [sol.A; sol.B; sol.C; sol.D]
Xbest = 
and we can proceed to minimize it in accordance with the second clause about which solution is chosen. For ease of use we will restrict to real values
nXbest = norm(Xbest)
nXbest = 
syms FREE real
dnXbest = simplify(subs(diff(nXbest, sol.parameters), sol.parameters, FREE))
dnXbest = 
best_free_parameter_value = solve(dnXbest, FREE)
best_free_parameter_value = 
4
subs(Xbest, sol.parameters, best_free_parameter_value)
ans = 

Community Treasure Hunt

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

Start Hunting!