How to solve Ax=B with some knowns in x and B

32 views (last 30 days)
Hello everyone,
I want to create a function to compute an Ax=B problem with some knowns in x and some knows in B. The solution shall be seperate for each x and B as a column vector.
A=randi(100,8,8);
x=NaN(8,1);
x(1)=1; x(2)=3;
B=NaN(8,1);
B(3)=4; B(4)=5 B(5)=6; B(6)=4; B(7)=2; B(8)=4;
% Solution
I=eye(size(A));
xj=isnan(x); Bj=isnan(B) % Where x and B are unknown is identified
Now how can i solve for x and B seperately?

Answers (4)

David Goodmanson
David Goodmanson on 14 Oct 2020
Edited: David Goodmanson on 21 May 2023
Hi Derek,
the method below uses y instead of B so that A*x = y, and does not assume that the known values of x are contiguous to each other, same for y. It does assume that if A is an nxn matrix, then [number of unknown values of x] + [number of unknown values of y] = n so that there are just as many equations as unknowns. the code uses indices so that effectively
A = [C D]
[E F]
where C,D,E,F are block matrices of the apprpriate size so that
[C D] * [x_u] = [y_k]
[E F] [x_k] [y_u]
Here x_u = column vector of unknown x, concatenated vertically with x_k = column vector of known x, same for y. Note that the number of unknown x's is the same as the number of known y's and consequently C and F are square matrices.
n = 7;
A = rand(n,n);
x = rand(n,1);
y = rand(n,1)
kx = [5 2]; % index of known values of x
ky = [2 4 6 3 1]; % index of known values of y
% solution procedure
alli = 1:n;
alli(kx)=[];
ux = alli; % index of unknown values of x
alli = 1:n;
alli(ky)=[];
uy = alli; % index of unknown values of y
C = A(ky,ux);
D = A(ky,kx);
E = A(uy,ux);
F = A(uy,kx);
x(ux) = C \(y(ky) - D*x(kx));
y(uy) = E*x(ux) + F*x(kx);
A*x-y % should be small
  1 Comment
Ashley
Ashley on 26 Apr 2023
Thank you so very much! Used this to solve a Finite Element Method Axial Force problem for a Civil Engineering class. David, you are a real one.

Sign in to comment.


Ameer Hamza
Ameer Hamza on 13 Oct 2020
I gyess there must be a more efficient way to solve this using linprog(), however, following shows a solution using fsolve()
A=randi(100,8,8);
x=zeros(8,1);
x(1)=1; x(2)=3;
B=NaN(8,1);
B(3)=4; B(5)=6; B(6)=4; B(7)=2; B(8)=4;
sol = fsolve(@(x_) A*[x(1:2); x_(1:6)]-[x_(7:8); B(3); x_(9); B(5:8)], rand(9,1));
x_sol = [x(1:2); sol(1:6)];
B_sol = [sol(7:8); B(3); sol(9); B(5:8)];
Result
>> A*x_sol-B_sol
ans =
1.0e-07 *
0.0197
0.0589
-0.1768
-0.0070
-0.0349
0.1264
-0.0591
-0.0137
  2 Comments
John D'Errico
John D'Errico on 13 Oct 2020
Edited: John D'Errico on 13 Oct 2020
You may be missing an important point here...
Derek Cooper
Derek Cooper on 13 Oct 2020
Thank you Ameer but i wanted to sove the problem in a more generelized way, so my initial plan was to create a function .

Sign in to comment.


John D'Errico
John D'Errico on 13 Oct 2020
Edited: John D'Errico on 13 Oct 2020
This is a moderately complex question, because I'm not sure you fully appreciate the problem, and I am also sure this is not your real problem. At least, it never is. :)
I'll start with the problem you posed.
You have 8 equations. But you have too many unknowns to solve the problem, as you wrote it.
A=randi(100,8,8);
x=NaN(8,1);
x(1)=1; x(2)=3;
B=NaN(8,1);
B(3)=4; B(5)=6; B(6)=4; B(7)=2; B(8)=4;
So effectively there are 3 unknown elements of the right hand side vector B. But there are also 6 unknown elements of the vector x.
The equations with unknown elements in B are essentially useless. you have an equation, equl to some unknown number B(1).
B(1) is used in no other way, in no other place. There is nothign you can do with that equation. It is essentially meaningless, adding no information context to the problem.
So really, you have a problem with 5 equations.
B(3)=4; B(5)=6; B(6)=4; B(7)=2; B(8)=4;
But there are 6 unknown values for x, thus x(3:8). This is an underdetermined problem. There are infinitely many sets of vectors x that will satisfy the problem, where the first two elements are known.
Perhaps I can give a simple example. Consider this problem:
A = randi(10,2,2)
A =
1 5
3 9
Now, suppose we wantd to solve the problem A*x = B, where x is avector of length 2. I'll assume both elements of x are unknown. So we could write this as a linear system of two equations,
1*x1 + 5*x2 = b1
3*x1 + 9*x2 = b2
If both b1 and b2 are known values, then all is good. The system has a unique solution because rank(A) here is 2.
But suppose you were willing to tell us the value of only b1? b2 is itself an unknown? Then really, we only have ONE equation, but one equation in two unknowns. Or, you could think of it as two equations, with three unknowns. Now there is insufficient information to solve the problem. Nothing you can do will make the problem have a unique solution.
It is possible, if you wanted to have b2 as an unknown, you could solve the problem, as a FUNCTION of b2. For example, we might do this:
syms x1 x2 b2
b1 = 5;
[x1,x2] = solve(sym(A)*[x1;x2] == [b1;b2])
x1 =
(5*b2)/6 - 15/2
x2 =
5/2 - b2/6
I've used a symbolic solve here, to make it explicit the result is a function of b2. As you see, now we have a solution in terms of the unknown b2. Change the value for b2, and you get a different result. So the result is now essentially a function of b2.
And if there were fixed values for some of the elements of x, we could also handle that. But really, I would need more specifics to know if the problem has an solution or not.
(One final question does arise, are you looking for integer solutions to this problem? That seems possible, given the ay you phrased it, but I am not sure. It does not change anything I said in any materialway, except for making the solutions slightly less common. There will still be infinitely many solutions, but a lower order of infinitely.)
Now, suppose you added one more known value for x, say x(3)?
Here we sould now have 5 unknown values for x, and essentially 5 pieces of information. Now you could solve the problem, as a unique solution for x(4:8). Then you could recover the unknown values for B.
Perhaps if you have more specifics, I can help more, but for the problem as posed, this is about all that can be said.
  1 Comment
Derek Cooper
Derek Cooper on 13 Oct 2020
Edited: Derek Cooper on 13 Oct 2020
Thank you very much for the answer. This is a very common engineering problem where u have some knowns at left hand side and on the right handside as well. I have 8 equations and in vector x, i have 6 unknowns. In vector B i have two unknowns. In total i have 8 equations with 8 unknowns. Now i want to sove the system in a generlized way so i can make a function out of it.

Sign in to comment.


Paul
Paul on 13 Oct 2020
Edited: Paul on 14 Oct 2020
The original question that you asked is inconsistent with your comment to John's answer. The question specfies only a total of 7 unknowns, but the comment says you have 8 unknowns (6 in x and 2 in b). If you're really interested in the problem in your comment, consider the following approach to isolate the knowns on the RHS and solve:
A=randi(100,8,8) % generate some sample data
A =
82 96 43 68 28 44 71 96
91 97 92 76 5 39 76 35
13 16 80 75 10 77 28 59
92 98 96 40 83 80 68 23
64 96 66 66 70 19 66 76
10 49 4 18 32 49 17 26
28 81 85 71 96 45 12 51
55 15 94 4 4 65 50 70
x(1:2,1) = (1:2).'; b(3:8,1) = (3:8).';
x1 = x(1:2); b2=b(3:8); % partitions of x and b that are known
A11=A(1:2,1:2);A12=A(1:2,3:8);A21=A(3:8,1:2);A22=A(3:8,3:8); % partition A compatibly with x and b
M = [A12 -eye(2);A22 zeros(6,2)] % define M such that M*[x2;b1] = [-A11*x1;-A21*x1 + b2]
M =
43 68 28 44 71 96 -1 0
92 76 5 39 76 35 0 -1
80 75 10 77 28 59 0 0
96 40 83 80 68 23 0 0
66 66 70 19 66 76 0 0
4 18 32 49 17 26 0 0
85 71 96 45 12 51 0 0
94 4 4 65 50 70 0 0
rank(M) % check that M is invertible
ans =
8
Z=M\[-A11*x1;-A21*x1 + b2]; % solve for [x2;b1]
x2 = Z(1:6);b1=Z(7:8); % pull out x2 and b1 from the solution
x=[x1;x2]; b=[b1;b2]; % form x and b from their known and solved-for partitions
A*x - b % check the result
ans =
1.0e-13 *
0
-0.8527
0.0977
-0.2887
0.2753
-0.0533
0.0355
-0.3819
Whether or not there will be zero, one, or infinitely many solutions for Z will depend on the properties of your specific data.

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!