Sum of top 2 numbers in matlab - matlab

I have three vectors in a function, each of size 2. I want to get the sum of the top 2 numbers at each index. What I mean is this:
A = [4,4];
B = [3,5];
C = [5,6];
Sum = [9,11];
I would like to skip if-else statements if possible.

A simple way is to
concatenate the row vectors into a matrix: [A; B; C]
apply maxk along the first dimension: maxk(..., 2, 1), where 2 is the desired number of elements
then apply sum along the first dimension: sum(..., 1.
Thus:
result = sum(maxk([A; B; C], 2, 1), 1);

First, you concatenate your three vectors through
vectors = [A; B; C];
Then, you sort it through
s = sort(vectors, 'descent');
Finally, you sum the two bigger element of each column through
SUM = s(1, :) + s(2, :)

Related

Comparing matrices of different size in matlab and storing values that are close

I have two matrices A and B. A(:,1) corresponds to an x-coordinate, A(:,2) corresponds to a y-coordinate, and A(:,3) corresponds to a certain radius. All three values in a row describe the same circle. Now let's say...
A =
[1,4,3]
[8,8,7]
[3,6,3]
B =
[1,3,3]
[1, 92,3]
[4,57,8]
[5,62,1]
[3,4,6]
[9,8,7]
What I need is to be able to loop through matrix A and determine if there are any rows in matrix B that are "similar" as in the x value is within a range (-2,2) of the x value of A (Likewise with the y-coordinate and radius).If it satisfies all three of these conditions, it will be added to a new matrix with the values that were in A. So for example I would need the above data to return...
ans =
[1,4,3]
[8,8,7]
Please help and thank you in advance to anyone willing to take the time!
You can use ismembertol.
result = A(ismembertol(A,B,2,'ByRows',1,'DataScale',1),:)
Manual method
A = [1,4,3;
8,8,7;
3,6,3];
B = [1,3,3;
1,92,3;
4,57,8;
5,62,1;
3,4,6;
9,8,7]; % example matrices
t = 2; % desired threshold
m = any(all(abs(bsxfun(#minus, A, permute(B, [3 2 1])))<=t, 2), 3);
result = A(m,:);
The key is using permute to move the first dimension of B to the third dimension. Then bsxfun computes the element-wise differences for all pairs of rows in the original matrices. A row of A should be selected if all the absolute differences with respect to any column of B are less than the desired threshold t. The resulting variable m is a logical index which is used for selecting those rows.
Using pdist2 (Statistics and Machine Learning Toolbox)
m = any(pdist2(A, B, 'chebychev')<=t, 2);
result = A(m,:);
Ths pdist2 function with the chebychev option computes the maximum coordinate difference (Chebychev distance, or L∞ metric) between pairs of rows.
With for loop
It should work:
A = [1,4,3;
8,8,7;
3,6,3]
B = [1,3,3;
1,92,3;
4,57,8;
5,62,1;
3,4,6;
9,8,7]
index = 1;
for i = 1:size(A,1)
C = abs(B - A(i,:));
if any(max(C,[],2)<=2)
out(index,:) = A(i,:);
index = index + 1
end
end
For each row of A, computes the absolute difference between B and that row, then checks if there exists a row in which the maximum is less than 2.
Without for loop
ind = any(max(abs(B - permute(A,[3 2 1])),[],2)<=2);
out = A(ind(:),:);

modifying matrix multiplication in matlab

I would like to have MATLAB perform matrix multiplication, where all multiply operations are replace by plus operation.
Here is an example:
a = [3,4; 5,6];
b = [1;2];
c = modified_multiplication(a,b); % = [3+1+4+2 ; 5+1+6+2] = [10 , 14].
How can I do this as efficient as the original * operation?
Your best bet is going to be to combine bsxfun with sum.
c = sum(bsxfun(#plus, a, b.'), 1);
% 10 14
The bsxfun call adds the first entry of b to all elements in the first row of a and the second entry of b to all the elements in the second row of a, etc..
bsxfun(#plus, a, b.')
% 4 6
% 6 8
Then the application of sum, sums down the columns.
For a and b of arbitrary sizes, it can be done as follows:
c = bsxfun(#plus, sum(a,2), sum(b,1));
This exploits the associative property of addition: first compute the sum of each row of a and of each column of b, and then compute all pairwise additions.

Using elements of a vector to set elements of a matrix

I have a vector whose elements identify the indices (per column) that I need to set in a different matrix. Specifically, I have:
A = 7
1
2
and I need to create a matrix B with some number of rows of zeros, except for the elements identified by A. In other words, I want B:
B = zeros(10, 3); % number of rows is known; num columns = size(A)
B(A(1), 1) = 1
B(A(2), 2) = 1
B(A(3), 3) = 1
I would like to do this without having to write a loop.
Any pointers would be appreciated.
Thanks.
Use linear indexing:
B = zeros(10, 3);
B(A(:).'+ (0:numel(A)-1)*size(B,1)) = 1;
The second line can be written equivalently with sub2ind (may be a little slower):
B(sub2ind(size(B), A(:).', 1:numel(A))) = 1;

Treat each row of a matrix as a vector in a MATLAB function

Say I have a nxm matrix and want to treat each row as vectors in a function. So, if I have a function that adds vectors, finds the Cartesian product of vectors or for some reason takes the input of several vectors, I want that function to treat each row in a matrix as a vector.
This sounds like a very operation in Matlab. You can access the ith row of a matrix A using A(i, :). For example, to add rows i and j, you would do A(i, :) + A(j, :).
Given an nxm matrix A:
If you want to edit a single column/row you could use the following syntax: A(:, i) for the ith-column and A(i, :) for ith-row.
If you want to edit from a column/row i to a column/row j, you could use that syntax: A(:, i:j) or A(i:j, :)
If you want to edit (i.e.) from the penultimate column/row to the last one, you could you: A(:, end-1:end) or A(end-1:end, :)
EDIT:
I can't add a comment above because I don't have 50 points, but you should post the function setprod. I think you should be able to do what you want to do, by iterating the matrix you're passing as an argument, with a for-next statement.
I think you're going to have to loop:
Input
M = [1 2;
3 4;
5 6];
Step 1: Generate a list of all possible row pairs (row index numbers)
n = size(M,1);
row_ind = nchoosek(1:n,2)
Step 2: Loop through these indices and generate the product set:
S{n,n} = []; //% Preallocation of cell matrix
for pair = 1:size(row_ind,1)
p1 = row_ind(pair,1);
p2 = row_ind(pair,2);
S{p1,p2} = setprod(M(p1,:), M(p2,:))
end
Transform the matrix into a list of row vectors using these two steps:
Convert the matrix into a cell array of the matrix rows, using mat2cell.
Generate a comma-separated list from the cell array, using linear indexing of the cell contents.
Example: let
v1 = [1 2];
v2 = [10 20];
v3 = [11 12];
M = [v1; v2; v3];
and let fun be a function that accepts an arbitrary number of vectors as its input. Then
C = mat2cell(M, ones(1,size(M,1)));
result = fun(C{:});
is the same as result = fun(v1, v2, v3).

Multiply two matrices element wise with summation

I have two matrices 4x2. How can I achieve such multiplication: the output should be a matrix 4x1, where each element is a sum of products of elements in rows in the original matrices.
Like this:
[1 2;
A = 3 4;
5 6;
7 8]
[1 2;
B = 3 4;
5 6;
7 8]
result C matrix will be:
[1*1 + 2*2;
C = 3*3 + 4*4;
5*5 + 6*6;
7*7 + 8*8]
Here is an even neater answer:
C = dot(A, B, 2);
You essentially want the dot product of the rows. This is one vectorized operation in MATLAB, so more efficient than element-wise product then a sum operation.
My matlab is a little rusty, but try
D = A .* B;
C = D(:,1) + D(:,2);
The first operation would produce a 4x2 matrix that contains the products of the corresponding elements from A and B, while the second operation adds the products from the same row.
The results you are seeking are also the diagonal elements from the matrix product, so you could use
C = diag(A * transpose(B));
although that would be terribly inefficient for larger matrices.
Aasmund Eldhuset is mostly correct but I believe the last line should be
C = D(:,1) + D(:,2);
as you want to sum each row in the final column