I have a matrix of the following form:
d1 0 0 0 0 0 0 x1 b1
a1 d2 0 0 0 0 0 x2 b2
0 a2 d3 0 0 0 0 x3 b3
0 0 a3 d4 a4 0 0 * x4 = b4
0 0 0 0 d5 a5 0 x5 b5
0 0 0 0 0 d6 a6 x6 b6
0 0 0 0 0 0 d7 x7 b7
I need to write a code to solve this system without forward elimination. I was assuming you could just solve for x7 = b7/d7. Then solve for d6 by setting d6 = b6-a6*x7 = b6-a6*(b7/d7) from our first iteration... then carrying the rest backwards to the first row. However, I am experiencing a block:
1) How to hardcore the confusing differences in indices
2) How to start from a reverse order down from d7 up to the first equation
3) Moreover, how do I generalize this for any system of n? According to personal readings I am doing for recreation, n is odd.
Can anyone assist me in coding this?
EDIT: The coefficient matrix is A, the x column vector can be denoted as X, and the b column vector can be denoted as B for convenience if needed.
Let A be your n-by-n bi-diagonal matrix and B your right-hand-side of the equation. You can solve using this loop:
n = size(A,1);
x = zeros(n,1); %// pre-allocate for solution x
x(n) = B(n)/A(n,n); %// get the last element
for ii=(n-1):-1:1
x(ii) = (B(ii)-x(ii+1)*A(ii,ii+1))/A(ii,ii); %// iteratively solve
end
Of course, it is always best to use built-in functions
x = A\B;
Related
A1 and A2 are two arrays of integers with the same dimensions 6000x2000.
I want to find a third matrix B by following these steps:
for i=1:1:6000
for j=1:2000
a1 = fliplr(dec2binvec(A1(i,j),14)); % Convert A1(i,j) to a binary vector
a2 = fliplr(dec2binvec(A2(i,j),32)); % Convert A2(i,j) to a binary vector
b = [a1 a2];
B(i,j) = sum(b.*2.^(numel(b)-1:-1:0)); % Convert b to decimal
end
end
my problem is the computation time to find B.
Is there a way to avoid loops in order to reduce the computation time ?
Example:
A1 = [2 3 A2 = [7 6
4 5] 2 9]
A1(1,1) = 2 and A2(1,1) = 7
a1 = [0 0 0 1 0] (eg 5 bits) a2 = [0 0 0 1 1 1] (eg 6 bits)
b = [a1 a2] = [0 0 0 1 0 0 0 0 1 1 1]
B1(1,1) = sum(b.*2.^(numel(b)-1:-1:0)) = 135
Using your example:
A1 = [2 3;
4 5];
A2 = [7 6;
2 9];
B=bitshift(A1,6)+A2
Output:
B =
135 198
258 329
I assume the example contains what you want. Simply use math ;)
A1 = [2 3;4,5]
A2=[7 6;2 9]
A1.*2^6+A2
Please be aware that doubles can hold up to 53 bits without precision loss. Recent versions of matlab support uint64. For even longer numbers check vpa, but vpa will result in slow code.
If I understand your example correctly, you only need to bit-shift A1 (i.e. multiply by a power of 2):
M = 5; %// not used actually
N = 6;
B = A1 * 2^N + A2;
In your example, this gives
B =
135 198
258 329
I have a system of three equations that I'd like to solve via MATLAB, and I'm a bit confused on how to go about doing it.
I have three equations:
A = R*P1
B = R*P2
C = R*P3
A, B, C, and P1, P2, and P3 are 3x1 matrices, while R is a 3x3 matrix. R is the same for all three equations.
I need to find R, and am given A, B, C, and the P's.
I wanted to use fsolve, but it seems that fsolve doesn't work when the variables are matrices. What is an alternative method that you would recommend using?
Just making up some numbers to work with:
P1 = [1;1;1];
P2 = [2;3;4];
P3 = [5;4;3];
R = [2 4 5; 1 5 4; 1 2 3];
Which would mean that:
A = [11;10;6];
B = [36;33;20];
C = [41;37;22];
If A, B, C, P1, P2, P3 are all numerical, why don't you simply use the ldivide or \ operator? This will allow you to solve your linear system directly. I can see that you have the following relationships:
R*P1 = A
R*P2 = B
R*P3 = C
You can see that each matrix equation yields three constraints. What you can do is create one system that encapsulates all matrix equations together thus yielding 9 constraints. As such, you'll need to reformulate this to be able to solve for your coefficients in your matrix R differently. To do this, we need to reshape your matrix R such that it becomes a 9-element vector. In other words, we can then reformulate your system like so:
[P1 0 0 0 0 0 0] [R1] [ ]
[0 0 0 P1 0 0 0] [R2] [ A ]
[0 0 0 0 0 0 P1] [R3] [ ]
[P2 0 0 0 0 0 0] [R4] [ ]
[0 0 0 P2 0 0 0] * [R5] = [ B ]
[0 0 0 0 0 0 P2] [R6] [ ]
[P3 0 0 0 0 0 0] [R7] [ ]
[0 0 0 P3 0 0 0] [R8] [ C ]
[0 0 0 0 0 0 P3] [R9] [ ]
P * R = D
You'll see that we have a 9 x 9 matrix called P, our matrix R which is reshaped into a vector so that we can solve for the coefficients and D are A,B,C concatenated together into one vector. R1 to R9 are the coefficients of the matrix R that are read from left to right and top to bottom.
Therefore, to find your coefficients in your matrix, simply do:
R = P^{-1}*D
As such, simply construct the matrix P and vector D like so:
P = [P1.' zeros(1,6); zeros(1,3) P1.' zeros(1,3); zeros(1,6) P1.'; ...
P2.' zeros(1,6); zeros(1,3) P2.' zeros(1,3); zeros(1,6) P2.'; ...
P3.' zeros(1,6); zeros(1,3) P3.' zeros(1,3); zeros(1,6) P3.'];
D = [A; B; C];
Now, simply solve for R and reshape it back into a 3 x 3 matrix. Therefore:
R = P \ D;
R = reshape(R, 3, 3).';
reshape turns our vector into a 3 x 3 matrix, but it constructs the matrix in column-major format, so you need to transpose the result after you call reshape. With your example, this is what we get. I construct P1, P2, P3, A, B, C, then use the code I had from before:
P1 = [1;1;1];
P2 = [2;3;4];
P3 = [5;4;3];
A = [11;10;6];
B = [36;33;20];
C = [41;37;22];
P = [P1.' zeros(1,6); zeros(1,3) P1.' zeros(1,3); zeros(1,6) P1.'; ...
P2.' zeros(1,6); zeros(1,3) P2.' zeros(1,3); zeros(1,6) P2.'; ...
P3.' zeros(1,6); zeros(1,3) P3.' zeros(1,3); zeros(1,6) P3.'];
D = [A; B; C];
R = P \ D;
R = reshape(R, 3, 3).';
To verify that R is correct, do:
A1 = R*P1;
B1 = R*P2;
C1 = R*P3;
We get for each:
A1 =
11
10
6
B1 =
36
33
20
C1 =
41
37
22
This matches up with your example. However, note that you may get a warning that R is ill-conditioned. This is because you may not have enough constraints to properly find a unique inverse. You may have to add more constraints to get a unique inverse, but if you can't, then use this with caution.
Have you tried to flatten out the matrices inside of the solve function? There is a collect function in MATLAB that collects coefficients, but you need to check if it works with supplying a row matrix, as opposed to a sum. (maybe sum(row matrix) - if it also combines like terms)
Something like:
[x,y,x] = solve(sum(R*P1)==A, sum(R*P2)==B, sum(R*P3)==C, x,y,z)
or the fsolve function
Suppose I have a matrix defined as follows
M = [C1 C2 C3 C4]
Where the C's are column vectors
I want some efficient (i.e. no for loops) way of producing A vector such that
ResultVec = [C1 C2;
C1 C3;
C1 C4;
C2 C3;
C2 C4;
C3 C4]
Thanks in advance!
That is, what nchoosek does:
M = [ 1 2 3 4 ];
R = nchoosek(M,2);
returns:
R =
1 2
1 3
1 4
2 3
2 4
3 4
I don't know if it's your intention but nchoosek is Matlabs implementation of The number of k-combinations from a given set S of n elements without repetition (Wikipedia)
The function nchoosek is performance wise not very efficient though. But there are equivalents on File Exchange, which are much(!!) faster and doing the same.
Just to make it clear, it's not just working for the fairly simple example above, and is not returning any indices. It directly transforms the matrix as desired.
M = [ 21 42 123 17 ];
returns:
R =
21 42
21 123
21 17
42 123
42 17
123 17
This is the simplest way I've come up with:
n = size(M, 2);
[j, i] = ind2sub([n n], find(~triu(ones(n))));
ResultVec = M(:, [i j]);
ResultVec = reshape(ResultVec, [], 2)
I have two diagonal matrices. I am trying to build a larger block diagonal matrix from them. For example if I had this:
D = diag(zeros(3,1)+1)
D =
1 0 0
0 1 0
0 0 1
and...
E = diag(zeros(2,1)+2, -1) + diag(zeros(2,1)+2, +1) + diag(zeros(3,1)+4)
E =
4 2 0
2 4 2
0 2 4
I have an equation that says A*U = X
Where A is
[E D 0
D E D
0 D E]
This is for 3x3. 5x5 would look like this:
A =
[E D 0 0 0
D E D 0 0
0 D E D 0
0 0 D E D
0 0 0 D E]
A would be another diagonal matrix consisting of these matrices. I need to produce a 40x40 and it would take a VERY LONG TIME to do manually, of course.
How can I define that? I haven't figured out how to use blkdiag to construct.
I solved this on my own manually because I could never find a Matlab function to help me.
for n = 1:Distance_Resolution
A(((n-1)*Distance_Resolution +1):n*Distance_Resolution, ((n-1)*Distance_Resolution +1):n*Distance_Resolution) = A1;
if n == Distance_Resolution
else
A((n*Distance_Resolution+1):(n+1)*(Distance_Resolution), ((n-1)*Distance_Resolution+1:n*Distance_Resolution)) = A2;
A((n-1)*Distance_Resolution+1:n*Distance_Resolution, (n*Distance_Resolution+1):(n+1)*(Distance_Resolution)) = A2;
end
end
This will produce a block matrix that has the above specified demands and is of length Distance_Resolution x Distance_Resolution x Distance_Resolution. I defined A1 and A2 through help from above poster (Fo is just a constant here):
vector = zeros(Distance_Resolution,1) - Fo;
A2 = diag(vector);
A1 = toeplitz([1+4*Fo, -Fo, zeros(1,Distance_Resolution-2)]);
This is a workable code snippet, but I am still looking for a smarter way to code it.
I want to solve this linear programming (simplex) problem using MATLAB 7, but it returns
Exiting: the problem is unbounded.
This function
f = 2(15 s0 + 8s1 + 2576s2 + 744s3 + 427s4 + 8s5)
Should be minimized in such a way that two constraints for each observation are
satisfied
0.1s0 + 0.1s1 + 14.5s2 + 4s3 + 2.4s4 – a0 − a1 − 145a2 − 40a3 − 24a4 ≥ −2.2
0.1s0 + 0.1s1 + 14.5s2 + 4s3 + 2.4s4 + a0 + a1 + 145a2 + 40a3 + 24a4 ≥ 2.2
S5 and a5 are 0. I used
f = [15 8 2576 744 427 8 15 8 2576 744 427 8];
b = [-2.2; 2.2];
a = [0.1 0.1 14.5 0.4 2.4 0 -1 -1 -145 -40 -24 0 ; 0.1 0.1 14.5 4 2.4 0 1 1 145 40 24 0];
[x, fval, exitflag, output, lambda] = linprog(f, a, b)
What is the right way to solve this problem?
You didn't constrain your s5 and a5 to actually be zero, since you set the corresponding coefficients in the a matrix to zero. Thus, they can take on any value, and the LP is unbounded.
To fix, add an equality constraint:
beq = [0; 0];
aeq = [0 0 0 0 0 1 0 0 0 0 0 0; 0 0 0 0 0 0 0 0 0 0 0 1];
[x,fval,exitflag,output,lambda] = linprog(f,a,b,aeq,beq)
Or, just drop s5 and a5 from the LP since they don't contribute at all.