How can I divide each row of a matrix by a fixed row? - matlab

Suppose I have a matrix like:
100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60
...
I wish to divide each row by the second row (each element by the corresponding element), so I'll get:
100 100 100 100 100 100
1 1 1 1 1 1
10 10 10 10 10 10
...
Hw can I do it (without writing an explicit loop)?

Use bsxfun:
outMat = bsxfun (#rdivide, inMat, inMat(2,:));
The 1st argument to bsxfun is a handle to the function you want to apply, in this case right-division.

Here's a couple more equivalent ways:
M = [100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60];
%# BSXFUN
MM = bsxfun(#rdivide, M, M(2,:));
%# REPMAT
MM = M ./ repmat(M(2,:),size(M,1),1);
%# repetition by multiplication
MM = M ./ ( ones(size(M,1),1)*M(2,:) );
%# FOR-loop
MM = zeros(size(M));
for i=1:size(M,1)
MM(i,:) = M(i,:) ./ M(2,:);
end
The best solution is the one using BSXFUN (as posted by #Itamar Katz)

You can now use array vs matrix operations.
This will do the trick :
mat = [100 200 300 400 500 600
1 2 3 4 5 6
10 20 30 40 50 60];
result = mat ./ mat(2,:)
which will output :
result =
100 100 100 100 100 100
1 1 1 1 1 1
10 10 10 10 10 10
This will work in Octave and Matlab since R2016b.

Related

Reshaping a vector into a larger matrix with arbitrary m and n

I'm attempting to create a function that takes a vector of any length and uses its entries to generate a matrix of size mxn, where m and n are arbitrary numbers. If the matrix has a greater number of entries that the original vector, the entries should repeat. E.g. A vector, (1,2,3,4) would make a 3x3 matrix (1,2,3;4,1,2;3,4,1).
So far I have this function:
function A = MyMatrix(Vector,m,n)
A = reshape([Vector,Vector(1:(m*n)-length(Vector))],[m,n]);
end
which is successful in some cases:
>> m=8;n=5;Vector=(1:20);
>> A = MyMatrix(Vector,m,n)
A =
1 9 17 5 13
2 10 18 6 14
3 11 19 7 15
4 12 20 8 16
5 13 1 9 17
6 14 2 10 18
7 15 3 11 19
8 16 4 12 20
However this only works for values of m and n that multiply to a number less than or equal to twice the number of entries in 'Vector', so 40 in this case. When mn is larger than 40, this code yields:
>> m=8;n=6;Vector=(1:20);
>> A = MyMatrix(Vector,m,n)
Index exceeds the number of array elements (20).
Error in MyMatrix (line 3)
A = reshape([Vector,Vector(1:(m*n)-length(Vector))],[m,n]);
I have tried to create a workaround using functions such as repmat, however, so far I have not been able to create a matrix with larger m and n.
You only need to
index the vector using "modular", 1-based indexing;
reshape it taking into account that Matlab is column-major, so you need to swap m and n;
transpose to swap m and n back.
V = [10 20 30 40 50 60]; % vector
m = 4; % number of rows
n = 5; % number of columns
A = reshape(V(mod(0:m*n-1, numel(V))+1), n, m).';
This gives
A =
10 20 30 40 50
60 10 20 30 40
50 60 10 20 30
40 50 60 10 20

Reshaping 3 dimensional array to 2 by stacking matrixes horizontally [duplicate]

This question already has an answer here:
Reshape matrix from 3d to 2d keeping specific order
(1 answer)
Closed 5 years ago.
I have 4x3x2 array:
A(:,:,1) =
1 10 100
2 20 200
3 30 300
4 40 400
A(:,:,2) =
5 50 500
6 60 600
7 70 700
8 80 800
I want to reshape it to B matrix with size 8x3 preserving the structure of each matrix as:
B =
1 10 100
2 20 200
3 30 300
4 40 400
5 50 500
6 60 600
7 70 700
8 80 800
Any idea how to do it in a simple and neat way?
As seen here.
Method 1: permute and reshape
B = reshape(permute(A, [2 1 3]), size(A, 2), [])'
Method 2: cell -> matrix
B = num2cell(A, [1 2]);
B = vertcat(B{:})

Matlab isn't incrementing my variable

I have the following matrix declared in Matlab:
EmployeeData =
1 20 100000 42 14
2 15 95000 35 14
3 18 70000 28 14
4 10 85000 35 14
5 10 40000 21 12
6 4 45000 14 8
7 3 50000 21 10
8 5 55000 21 14
9 1 25000 14 7
10 2 50000 21 9
42 4 100000 42 10
Where column 1 represents ID numbers, 2 represents years, 3 is salary, 4 is vacation days, and 5 is sick days. I am trying to find the maximum value of a column (in this case the salary column), and print out the ID associated with that value. If more than one employee has the maximum value, all the IDs with that maximum are supposed to be shown. So here is how I naively implemented a way to do it:
>> maxVal = [];
>> j = 1;
>> for i = EmployeeData(:, 3)
if i == max(EmployeeData(:, 3))
maxVal = [maxVal EmployeeData(j, 1)];
end
j = j + 1;
end
But it shows maxVal to be [] in my workspace variables, instead of [1 42] as I expected. Upon inserting a disp(i) in the for loop above the if to debug, I get the following output:
100000
95000
70000
85000
40000
45000
50000
55000
25000
50000
Just like I expected. But when I switch out that disp(i) with a disp(j), I get this for my output:
1
What am I doing wrong? Should this not work?
MATLAB for loops operate on rows, not columns. You should try replacing your for loop with:
for i = EmployeeData(:, 3)' % NOTE THE TRANSPOSE
...
end
EDIT: Note that you can do what you're trying to do without a forloop:
maxVal = EmployeeData(EmployeeData(:,3) == max(EmployeeData(:,3)),1);
Is this what you want?
>> EmployeeData(EmployeeData(:,3)==max(EmployeeData(:,3)),1)
ans =
1
42

Multiply each value in rows of Matrix A by each corresponding value of a specfic row in Matrix B

I have a A=[m,n] matrix and a B=[n,l] matrix.
A =
[1 2 3
4 5 6
7 8 9
10 11 12]
For the sake of simplicity, let's assume l=1, so B is in fact a vector B=[n,1]
B = [100 10 1]
I would like multiply all the values in each row of A by a corresponding value of B - column-wise.
I know how to do it "manually":
C=[A(:,1)*B(:,1), A(:,2)*B(:,2), A(:,3)*B(:,3)]
This is the result I want:
C = [100 20 3
400 50 6
700 80 9
1000 110 12]
Unfortunately my real life matrices are a bit bigger e.g. (D=[888,1270]) so I'm looking for smarter/faster way to do this.
Pre R2016b:
C=bsxfun(#times,A,B)
C =
100 20 3
400 50 6
700 80 9
1000 110 12
R2016b and later:
In MATLABĀ® R2016b and later, you can directly use operators instead of bsxfun , since the operators independently support implicit expansion of arrays.
C = A .* B
If I > 1, then you will have to reorder the dimensions of B first with a permute,
>> B = [100 10 1; 1 10 100];
>> C = bsxfun(#times, A, permute(B, [3 2 1]));
>> C
C(:,:,1) =
100 20 3
400 50 6
700 80 9
1000 110 12
C(:,:,2) =
1 20 300
4 50 600
7 80 900
10 110 1200

"Find and replace" from a matrix MATLAB

I have a matrix that is like the following:
a = [10 0; 12 5; 10 0; 12 0; 15 0; 15 2];
a =
10 0
12 5
10 0
12 0
15 0
15 2
I am looking to create a new matrix which find and replaces the zeros with a value that is dependent on the first column's value. The key is this matrix:
Key =
10 100
12 200
15 300
If the value is already greater than zero in the first column I would like to leave it. The output would look like this:
Output =
10 100
12 5
10 100
12 200
15 300
15 2
You can do it in one line using logical indexing smartly:
a(~a(:,2),2)=arrayfun(#(x)Key(Key(:,1)==x,2),a(~a(:,2),1))
%a =
% 10 100
% 12 5
% 10 100
% 12 200
% 15 300
% 15 2