Solving Unknowns with Symbolic Toolbox

16 ビュー (過去 30 日間)
J.D. Johnston
J.D. Johnston 2022 年 9 月 23 日
回答済み: Walter Roberson 2022 年 9 月 23 日
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.

採用された回答

KSSV
KSSV 2022 年 9 月 23 日
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 件のコメント
J.D. Johnston
J.D. Johnston 2022 年 9 月 23 日
Thank you so much. I never would have considered pinv.

サインインしてコメントする。

その他の回答 (1 件)

Walter Roberson
Walter Roberson 2022 年 9 月 23 日
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 = 

カテゴリ

Help Center および File ExchangeNumbers and Precision についてさらに検索

製品


リリース

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by