How do I turn a 2x3 matrix into a 3x3 matrix - matlab

I'm sorry if this is a stupid question but I just can't find the answer I need.
I have the following matrix:-
A |6 6 0|
|9 0 0|
Each column represents co-ordinates on a grid.
Now to find the inverse of "A" I need to create this into a 3x3 square matrix, to do this I add 001 as the 3rd row...
B |6 6 0|
|9 0 0|
|0 0 1|
I do this simply because it is what I have seen in the online examples.
My question is, what is the method to calculate/add the 3rd row of a 2x3 matrix in this situation?

It is not possible to take the inverse of a matrix that is not squared..
I assume that would like to just extend the matrix in order to make i squared, the reason why you use the [0 0 1] is to make the matrix consistent..
Actually you matrix represent two equations with three variables..
A:
6*x_1 + 6*x_2 + 0*x_3 = 0
9*x_1 + 0*x_2 + 0*x_3 = 0
this is not consistent
but by adding the last row you get
B:
6*x_1 + 6*x_2 + 0*x_3 = 0
9*x_1 + 0*x_2 + 0*x_3 = 0
0*x_1 + 0*x_2 + 1*x_3 = 0
this matrix exists on echelon form
[1 0 0]
[0 1 0]
[0 0 1]
so by adding the last row you are not changing the matrix
you would properly get same result just by reduce it to
[6 6]
[9 0]

Here is a simple way to do it:
s = size(A);
B = eye(max(s));
B(1:s(1),1:s(2)) = A

Related

Sort matlab matrix rows based on function

Let's say I have a Nx3 matrix M.
Consider, for example, a function Map(v) that receives as input a 1x3 array and returns a double.
How can I sort the rows of M so that the rows with smallest Map should come first?
That is, the row i should be the first if Map(M(i,:)) ≤ Map(M(j,:)) for all 1 ≤ j ≤ N and j ≠ i ?
example:
M = |1 2 3|
|4 5 6|
|7 8 9|
Map(v){
if (v(1) == 1 && v(2) == 2 && v(3) == 3) return 2
if (v(1) == 4 && v(2) == 5 && v(3) == 6) return 3
if (v(1) == 7 && v(2) == 8 && v(3) == 9) return 1
}
So the sorting should leave M like this:
M = |7 8 9|
|1 2 3|
|4 5 6|
% initialize an N-by-3 matrix where N=10...
M = [
1 0 3;
4 2 2;
0 1 0;
7 5 6;
3 3 8;
2 1 4;
0 0 6;
3 1 2;
5 0 0;
1 6 2
];
% sum its rows...
M_sum = sum(M,2);
% sort the vector of sums in ascending order...
[~,idx] = sort(M_sum);
% reorder the matrix rows based on the sorting result...
M = M(idx,:);

Accumarray with non-scalar subscripts in Matlab?

I have a matrix A in Matlab of dimension m x 3, e.g. m=18
A=[ 2| 1 1;
3| 1 2;
-8| 1 3;
-------
-5| 1 1;
2| 1 2;
6| 1 3;
-------
7| 2 1;
3| 2 2;
1| 2 3;
5| 2 4;
-------
3| 2 1;
-8| 2 2;
1| 2 3;
0| 2 4;
-------
1| 2 1;
2| 2 2;
7| 2 3;
9| 2 4]
The characteristics of A are the following:
It is composed by t submatrices. In the example t=5.
Each submatrix t has dimension b x 3 with b<=m and b can take any value in {3,4,5,...,m} (clearly, in a way such that the sum of all rows is m). In the example, the first and the second submatrices have dimension 3 x 3, the last three submatrices have dimension 4 x 3.
All submatrices of the same dimension are stacked one after the other. In the example, firstly we have the submatrices 3 x 3 and then the submatrices 4 x 3.
I want to compute the vector B of dimension f x 1 where f=size(unique(A(:,2:end),'rows','stable'),1), (in the example f=7), such that B(i,1) is obtained by summing the elements j of A(:,1) having A(j,2:end) equal to the i-th row of unique(A(:,2:end),'rows','stable'), i.e.
B=[2-5;
3+2;
-8+6
7+3+1;
3-8+2;
1+1+7;
5+0+9]
Use the third output of unique when examining A over the rows and with the 'stable' flag, then use this as input into accumarray. The third output assigns a unique ID for each unique occurrence of a row vector seen in your matrix A, which is very suitable for use in accumarray:
[~,~,f] = unique(A(:,2:end), 'rows', 'stable');
B = accumarray(f, A(:,1));
We get:
B =
-3 %// 2-5
5 %// 3+2
-2 %// -8+6
11 %// 7+3+1
-3 %// 3-8+2
9 %// 1+1+7
14 %// 5+0+9

Reduce matrix by adding every n

Not sure how to explain it so here it goes as an example:
A=[1 0 0 1 4 4 4 4
0 0 0 0 2 3 2 2
0 0 0 0 0 0 0 1
2 3 4 5 2 3 4 1 ]
result:
b=[ 1 1 13 12
5 9 5 6];
Each of the elements is computed by adding a N size submatrix inside the original, in this case N=2.
so b(1,1) is A(1,1)+A(1,2)+A(2,1)+A(2,2), and b(1,4) is A(1,7)+A(2,7)+A(1,8)+A(2,8).
Visually and more clearly:
A=[|1 0| 0 1| 4 4| 4 4|
|0 0| 0 0| 2 3| 2 2|
____________________
|0 0| 0 0| 0 0| 0 1|
|2 3| 4 5| 2 3| 4 1| ]
b is the sum of the elements on those squares, in this example of size 2.
I can imagine how to make it with loops, but its just feels vectorizable. Any ideas of how it could be done?
Assume that the matrix A has sizes that are multipliers of N.
If you have the Image processing toolbox blockproc could be an option as well:
B = blockproc(A,[2 2],#(x) sum(x.data(:)))
Method 1:
Using mat2cell and cellfun
n = 2;
AC = mat2cell(A,repmat(n,size(A,1)/n,1),repmat(n,size(A,2)/n,1));
out = cellfun(#(x) sum(x(:)), AC)
Method 2:
Using permute and reshape
n = 2;
[rows,cols] = size(A);
out = reshape(sum(sum(permute(reshape(A,n,rows/n,n,[]),[1 3 2 4]))),rows/n,[]);
PS: Here is a close question related to this one, which you might find useful. That question is to find mean while this one is to find sum.
Here are two alternative methods:
Method #1 - im2col
Another method using the image processing toolbox is to use im2col with the distinct flag and sum over all of the resulting columns. You would then need to reshape the matrix back to the right size:
n = 2;
B = im2col(A, [n n], 'distinct');
C = reshape(sum(B, 1), size(A,1)/n, size(A,2)/n);
We get for C:
>> C
C =
1 1 13 12
5 9 5 6
Method #2 - accumarray and kron
We can generate an index matrix with kron which we can use as bins into accumarray and invoke sum as the custom function. We would again have to reshape the matrix back to the right size:
n = 2;
M = reshape(1:prod([size(A,1)/n, size(A,2)/n]), size(A,1)/n, size(A,2)/n);
ind = kron(M, ones(n));
C = reshape(accumarray(ind(:), A(:), [], #sum), size(A,1)/n, size(A,2)/n);
Again we get for C:
C =
1 1 13 12
5 9 5 6

Split 2 x N matrix into two submatrices in MATLAB

I have a matrix 2 x N (lets call it MyMatrix) containing pairs of elements (element in (1,1) corresponds to element (2,1), element in (1,2) correspords to element (2,2) and so on.) Entries in first row are sorted in ascending order. What I would like to do is split this matrix into 2 matrices 2 x K and 2 x N-K. First matrix will contain part of MyMatrix where entries in row 1 are less than some given value (in my example it will be (max-min)/2 , where max = maximum value in row 1, min = minimum walue in row 1) and second matrix will consist of the rest of MyMatrix. I'm sorry if it is confusing but I tried my best to explain to you what I would like to achieve.
Here is an example:
MyMat =
|1 2 4 6 13 52 65 120 125|
|4 132 53 1 64 34 5 2 66 |
min = 1 , max = 125, avg = (125-1)/2 = 62.
so result will be as follows:
a =
|1 2 4 6 13 52 |
|4 132 53 1 64 34 |
b=
|65 120 125|
|5 2 66 |
Thanks in advance for your help.
Kind regards,
Tom.
You can simply do
a=MyMat(:,MyMat(1,:)<avg);
b=MyMat(:,MyMat(1,:)>=avg);

How to subtract each item of a matrix from each coressponding row of another matrix

A = [1 2 3; 7 6 5]
B = [3 7];
A-B = [1-3 2-3 3-3; 7-7 6-7 5-7];
ans =[-2 -1 0; 0 -1 -2]
This is the operation I want to have done. How could I do it by matrix functions other than the iterative solutions?
You do this most conveniently with bsxfun, which automatically expands the arrays to match in size (so that you don't need to use repmat). Note that I need to transpose B so that it's a 2-by-1 array.
A = [1 2 3; 7 6 5]
B = [3 7];
result = bsxfun(#minus,A,B')
result =
-2 -1 0
0 -1 -2
I think that Jonas answer is the best. But just for the record, here is the solution using an explicit repmat:
A = [1 2 3; 7 6 5];
B = [3 7];
sz = size(A);
C = A - repmat(B', [1 sz(2:end)]);
Not only is Jonas' answer simpler, it is actually faster by a factor of 2 for large matrices on my machine.
It's also interesting to note that in the case where A is an n-d array, both these solutions do something quite reasonable. The matrix C will have the following property:
C(k,:,...,:) == A(k,:,...,:) - B(k)
In fact, Jonas' answer will run, and very likely do what you want, in the case where B is m-d, as long as the initial dimensions of A and B' have the same size. You can change the repmat solution to mimic this ... at which point you are starting to reimplement bsxfun!
Normally you can't. Iterative solutions will be necessary, because the problem is poorly defined. Matrix addition/subtraction is only defined for matrices of the same dimensions.
ie:
A = | 1 2 3 |
| 7 6 5 |
B = | 3 7 |
It makes no sense to subtract a 1x2 matrix from a 2x3 matrix.
However, if you multiplied B by some intermediate matrix to make the result a 2x3 matrix, that would work, ie:
B' * Y = | 3 3 3 |
| 7 7 7 |
eg:
B' = diag(B)
= | 3 0 |
| 0 7 |
B' * Y = | 3 3 3 |
| 7 7 7 |
Y = | 1 1 1 |
| 1 1 1 |
Therefore, A-B'*Y gives a valid, non-iterative solution.
A-(B'*Y) = | 1 2 3 | - | 3 3 3 |
| 7 6 5 | | 7 7 7 |
= A - (diag(B) * Y )
The only "cheat" here is the use of the diag() function, which converts a vector to a strictly-diagonal-matrix. There is a way to manually decompose a set of matrix/vector multiplication operations to manually re-create the diag() function, but that would be more work than my solution above itself.
Good luck!