Replacing the colon operator with an equivalent vectorizable solution - matlab

My current code does something like this:
for offset = 0:0.9:max_offset :
x = offset:step_size:max_value;
[...]
end
I would like to vectorize and remove the for loop to make it faster, but if I try making offset a vector, the colon operator on the second line is equivalent to doing
x = offset(1):step_size:max_value;
What is the most efficient way to achieve the desired result, i.e. get
x = [ 0:step_size:max_value;
0.9:step_size:max_value;
1.8:step_size:max_value; ... ]
assuming I don't know max_offset, and therefore the length of number of rows I want in x?

Since each vector will be a different size, they wont fit in a matrix easily. You will have to put them in a cell array, like so:
offset=0:.9:max_offset;
x=arrayfun(#(k) k:step_size:max_value,offset,'UniformOutput',false)
and rather than referring to rows of x by x(i,:) for a matrix, you would do x{i} to get the right vector out.

Related

Removing rows based on a condition (Matlab)

I am trying to remove rows from a matrix based on a condition. I have a 371000x5 double matrix, and a 371000x1 vector of dummies (1 and 0). I want to remove each row from the original matrix, where the value of the vector of dummies is 1.
I have tried the following, but it is taking very long:
for i = 1:size(matrix_num,1)
if missing_matrix(i,1) >=0
matrix_num(i,:) = [];
end
end
My Matlab has been busy for over 30 minutes now, so I am not even sure if the code is right. Is there a more efficient way to do this?
Additionally, I have to do the same action on a cell matrix (categorical data). Should I expect any huge difference from the numerical matrix?
The programmatic way of doing this is:
new_matrix = old_matrix(missing_vector==1,:)
for keeping lines with missing_vector 1
new_matrix = old_matrix(missing_vector==0,:)
for removing lines with missing_vector 1
For educational values, if you want the loop to work, don't do that row by row. Your solution causes the matrix to be copied and re-allocated on every row removed.
So, you would be better off if you calculate the resulting matrix size in advance:
new_matrix = zeros(sum(missing_vector), 5)
and then your iteration would work:
index_new=1
for index_old = 1:size(old_matrix,1)
if missing_vector(index_old) ==0
new_matrix(index_new,:) = old_matrix(index_old,:);
end
end
Try compact MATLAB code
matrix_num(missing_matrix>=0,:)=[]
Note : You must make a vector for missing_matrix variable. If this variable is matrix, you need other form of code .
As I know, you can use it in cell array too.

How do I reshape a non-quadratic matrix?

I have a column vector A with dimensions (35064x1) that I want to reshape into a matrix with 720 lines and as many columns as it needs.
In MATLAB, it'd be something like this:
B = reshape(A,720,[])
in which B is my new matrix.
However, if I divide 35604 by 720, there'll be a remainder.
Ideally, MATLAB would go about filling every column with 720 values until the last column, which wouldn't have 720 values; rather, 504 values (48x720+504 = 35064).
Is there any function, as reshape, that would perform this task?
Since I am not good at coding, I'd resort to built-in functions first before going into programming.
reshape preserves the number of elements but you achieve the same in two steps
b=zeros(720*ceil(35604/720),1); b(1:35604)=a;
reshape(b,720,[])
A = rand(35064,1);
NoCols = 720;
tmp = mod(numel(A),NoCols ); % get the remainder
tmp2 = NoCols -tmp;
B = reshape([A; nan(tmp2,1)],720,[]); % reshape the extended column
This first gets the remainder after division, and then subtract that from the number of columns to find the amount of missing values. Then create an array with nan (or zeros, whichever suits your purpose best) to pad the original and then reshape. One liner:
A = rand(35064,1);
NoCols = 720;
B = reshape([A; nan(NoCols-mod(numel(A),NoCols);,1)],720,[]);
karakfa got the right idea, but some error in his code.
Fixing the errors and slightly simplifying it, you end up with:
B=nan(720,ceil(numel(a)/720));
B(1:numel(A))=A;
Create a matrix where A fits in and assingn the elemnent of A to the first numel(A) elements of the matrix.
An alternative implementation which is probably a bit faster but manipulates your variable b
%pads zeros at the end
A(720*ceil(numel(A)/720))=0;
%reshape
B=reshape(A,720,[]);

remove elements with corresponding zeros in another matrix matlab

I have two matrices A & B in Matlab, for example
A=[0,0,1,2,3,0,4,2,0]
B=[2,3,1,2,2,3,4,4,1]
What I want to do is to set elements in B to zero where they have the same position as zero elements in A. So in my example:
A=[0,0,1,2,3,0,4,2,0]
B=[2,3,1,2,2,3,4,4,1]
I want B to be like this:
B=[0,0,1,2,2,0,4,4,0]
Any idea?
You can do it using logical indexing like so: B(A==0) = 0
EDIT:
You can also do it like this: B.*(A~=0) which will be easier to generalise to higher dimensions using bsxfun as per your comment below.
The only problem with doing something that Dan suggests is if A and B are not the same size. You can still however do this with a little bit of extra work.
indices = find(A==0);
indices = indices(indices <= length(B));
B(indices) = 0;

Mean value of multiple columns

I have searched a lot to find the solution, but nothing really works for me I think.
I have n data files containing two columns each (imported using uigetfile). To extract the data, I use a for loop like this:
for i=1:n
data{i}=load(filename{i});
x{i}=data{i}(:,1);
y{i}=data{i}(:,2);
end
Now, I want to get the mean value for each row of all the (let's say) x-values. E.g.:
x{1} = [1,4,7,8]
x{2} = [1,2,6,9]
Then I want something like
x_mean = [1,3,6.5,8.5]
I have tried (where k is number of rows)
for i=1:n
data{i}=load(filename{i});
x{i}=data{i}(:,1);
y{i}=data{i}(:,2);
j=1:k
x_mean=sum(x{i}(j))/n
end
But I can't use multiple counters in a for loop (as I understand). Moreover, I don't use mean as I don't see how I can use it in this case.
If someone could help me, it would be great!
You can capture the contents of each numeric array in the cell x into a new numeric array x_num like so:
x_num = [x{:}]
Computing the mean is then as simple as
mean_x = mean( [x{:}] )
For your example, that gives you the mean of all numbers in all arrays in x, which will therefore be a scalar.
If you want to compute the mean of all the rows (column-wise mean), as your example would indicate), you have to concatenate your arrays vertically, which you can do with cat:
mean_x_columnwise = mean( cat(1,x{:}) )
If you want to take the mean over all the columns (row-wise mean), you should only have to tell mean that you are looking at a different dimension:
mean_x_rowwise = mean( cat(1,x{:}), 2)

How do I create a matrix whose elements are the sum of the row and column numbers?

I need to create a 95x95 matrix in MATLAB in which each element is a sum of its row and column number.
I'm new at this so I can't really think of a way to tell MATLAB to just create a matrix without putting the elements in.
From what I understand I'll have to initiate a loop for the sum part.
No math needed if you use HANKEL:
A = hankel(2:96, 96:190);
I propose another strategy, as simple as EitanT's one:
v = 1:95;
A = bsxfun(#plus,v,v');
There is no need "reinventing the wheel" with loops. Try this:
[X, Y] = meshgrid(1:95, 1:95);
A = X + Y
The desired output is stored in matrix A.