I have two single column matrices named Matrix1 and Matrix2 in Excel, for instance:
Matrix1 Matrix 2
0 7
3 8
9 3
5 2
1 6
I want to determine the maximum value of the sums of each row and I think this is possible using an array formula but I can't get to a working solution. So basically what I want to do is the following, but in a single cell:
Matrix1 Matrix2 Matrix3
0 7 =index(Matrix1;1) + index(Matrix2;1)
3 8 =index(Matrix1;2) + index(Matrix2;2)
9 3 =index(Matrix1;3) + index(Matrix2;3)
5 2 =index(Matrix1;4) + index(Matrix2;4)
1 6 =index(Matrix1;5) + index(Matrix2;5)
Result = Max(Matrix3)
Is this possible in a singel cell?
Maybe for some inspiration, take a look at this post:
https://superuser.com/questions/373588/how-do-i-calculate-the-sum-of-2-columns-using-the-max-from-each-row
Try,
=MAX(INDEX((A2:A6)+(B2:B6), , ))
Related
Given a logical column vector (size n x 1) v and an array a (size m x n) how do I generate a new array consisting of all the columns in a where the numerical index of said column (1...n) is 1 at the corresponding location in v.
So for example if v was
1
0
0
1
and a was
1 4 7 10
2 5 8 11
3 6 9 12
the new array would be
1 10
2 11
3 12
because the first and fourth elements of v are 1 (true), so the new array should contain the first and fourth columns of a.
I have tried a bunch of things involving normal logical indexing and transpose but I can't get it to work. All help is appreciated
You want to use the logical indexing to select the columns and select all rows. In the example below, I have explicitly cast v as a logical just in case it's not a logical matrix already.
new = a(:, logical(v))
1 10
2 11
3 12
I will try to explain what I need through an example.
Suppose you have a matrix x as follows:
1 2 3
4 5 6
And another matrix y as follows:
1 4 5
7 4 8
What I need is (without looping over the rows) to perform an intersection between each 2 corresponding rows in x & y. So I wish to get a matrix z as follows:
1
4
The 1st rows in x and y only have 1 as the common value. The 2nd rows have 4 as the common value.
EDIT:
I forgot to add that in my case, it is guaranteed that the intersection results will have the same length and the length is always 1 actually.
I am thinking bsxfun -
y(squeeze(any(bsxfun(#eq,x,permute(y,[1 3 2])),2)))
Sample runs -
Run #1:
>> x
x =
1 2 3
4 5 6
>> y
y =
1 4 5
7 4 8
>> y(squeeze(any(bsxfun(#eq,x,permute(y,[1 3 2])),2)))
ans =
1
4
Run #2:
>> x
x =
3 5 7 9
2 7 9 0
>> y
y =
6 4 3
6 0 2
>> y(squeeze(any(bsxfun(#eq,x,permute(y,[1 3 2])),2)))
ans =
0
3
2
The idea is to put the matrices together and to look for duplicates in the rows. One idea to find duplicated numeric values is to diff them; the duplicates will be marked by the value 0 in result.
Which leads to:
%'Initial data'
A = [1 2 3; 8 5 6];
B = [1 4 5; 7 4 8];
%'Look in merged data'
V = sort([A,B],2); %'Sort matrix values in rows'
R = V(diff(V,1,2)==0); %'Find duplicates in rows'
This should work with any number of matrices that can be concatenated horizontally. It will detect all the duplicates, but it will return a column the same size as the number of rows only if there is one and only one duplicate per row in the matrices.
Suppose A is a 3-D matrix as below (2 rows-2 columns-2 pages).
A(:,:,1)=[1,2;3,4];
A(:,:,2)=[5,6;7,8];
I want to have a vector, say "a", whose inputs are the average of diagonal elements of matrices on each page. So in this simple case, a=[(1+4)/2;(5+8)/2].
But I have difficulties in matlab to do so. I tried the codes below but failed.
mean(A(1,1,:),A(2,2,:))
You can use "partially linear indexing" in the two dimensions that define the diagonal, as follows:
Since partially linear indexing can only be applied on trailing dimensions, you first need to apply permute to rearrange dimensions, so that the first and second dimensions become second and third.
Now you leave the first dimension untouched, linearly-index the diagonals in the second and third dimensions (which effectly reduces those two dimensions to one), and apply mean along the (combined) second dimension.
Code:
B = permute(A, [3 1 2]); %// step 1: permute
result = mean(B(:,1:size(A,1)+1:size(A,1)*size(A,2)), 2); %// step 2: index and mean
In your example,
A(:,:,1)=[1,2;3,4];
A(:,:,2)=[5,6;7,8];
this gives
result =
2.5000
6.5000
You can use bsxfun for a generic solution -
[m,n,r] = size(A)
mean(A(bsxfun(#plus,[1:n+1:n^2]',[0:r-1]*m*n)),1)
Sample run -
>> A
A(:,:,1) =
8 4 1
7 6 3
1 5 8
A(:,:,2) =
1 7 6
8 5 2
1 2 7
A(:,:,3) =
6 2 8
1 1 6
1 4 5
A(:,:,4) =
8 1 6
1 5 1
9 2 7
>> [m,n,r] = size(A);
>> sum(A(bsxfun(#plus,[1:n+1:n^2]',[0:r-1]*m*n)),1)
ans =
22 13 12 20
>> mean(A(bsxfun(#plus,[1:n+1:n^2]',[0:r-1]*m*n)),1)
ans =
7.3333 4.3333 4 6.6667
I've two matrix a and b and I'd like to combine the rows in a way that in the first row I got no duplicate value and in the second value, columns in a & b which have the same row value get added together in new matrix. i.e.
a =
1 2 3
8 2 5
b =
1 2 5 7
2 4 6 1
Desired outputc =
1 2 3 5 7
10 6 5 6 1
Any help is welcomed,please.
For two-row matrices
You want to add second-row values corresponding to the same first-row value. This is a typical use of unique and accumarray:
[ii, ~, kk] = unique([a(1,:) b(1,:)]);
result = [ ii; accumarray(kk(:), [a(2,:) b(2,:)].').'];
General case
If you need to accumulate columns with an arbitrary number of columns (based on the first-row value), you can use sparse as follows:
[ii, ~, kk] = unique([a(1,:) b(1,:)]);
r = repmat((1:size(a,1)-1).', 1, numel(kk));
c = repmat(kk.', size(a,1)-1, 1);
result = [ii; full(sparse(r,c,[a(2:end,:) b(2:end,:)]))];
I have a 2D matrix and want to sort rows and columns based on two other vectors i.e. one for ordering rows another for ordering columns in MATLAB
Example: A (Matrix to order)
0 1 2 3 4
1 1 8 9 7
2 3 4 6 2
3 1 2 0 8
Row Vector (Order for sorting rows of matrix A)
1
4
2
3
And column vector
1 5 4 2 3
Modified A
0 4 3 1 2
3 8 0 1 2
1 7 9 1 8
2 2 6 3 4
How about:
ModifiedA=A(RowVector,ColumnVector);
Note: Matab's indexing starts at 1 not at 0, adapt your indexing vectors accordingly.
In MATLAB, you can use the second output of sort to get the 1-based indexes that MATLAB is looking for (in this case you could have just added 1, but using sort works even if the row and column vectors are not consecutive).
[~,rowIdx] = sort(rowVector);
[~,colIdx] = sort(colVector);
And then you can apply the indexing operation to the matrix:
modifiedA = A(rowIdx, colIdx);