how can i deal with empty matrix: 0-by-any number resulting from simulation? - matlab

I have made a simulation and the result each time of the simulation is a matrix and i choose a certain row from the matrix, so if the simulation run=500, i'll have a 500 matrix and ,the row i choose each time will be (at the end of the simulation) 500 rows [one row from the first matrix...last row from the last matrix]...
the problem is some times a matrix dose not contain the certain row i want , the answer is for example empty matrix: 0-by-6
i want to ignor this answer
Note: the row i choose is not necessary to be exist in all matrices
so if the run=600 , result in 600 matrix , the row i choose maybe =400 only and the other 200 will be zero
the simulation STOP when the result is empty matrix: 0-by-any number
I use Matlab

you can use isempty to detect empty arrays, for example
a=zeros(0,5)
isempty(a)
a =
Empty matrix: 0-by-5
ans =
1
For when the index exceeds matrix dimensions, you can add a condition that tests the size of your matrix, specifically, how man rows using size(m,1)
So all together, in your for loop you can code something like:
for n=1:blah
if ~isempty(M) % continue if matrix is non-empty
if size(M,1)<=n % continue if index doesn't exceeds matrix dimensions
....
....

Related

Creating new rows in a matrix, where the elements of these rows have to be different from previous rows(same row cannot occur twice) Matlab

I'm trying to generate a 3x2 matrix. Each row is generated using randperm(3,2). This means each row is generated as a vector with 2 unique integers with values between 1 and 3.
The problem is that I want each new row to be different than all the previous. For example, if one row is [1 3] then no other row can be:
[1 3], nor
[3 1].
I tried checking the sum AND the multiplied value of each newly created row. (Using our example 1+3=4 and 1*3=3)
My idea is that the multiplied value and the sum value of each new generated row is compared to the multiplied value and sum value of every other row that comes before it. If any of these values are the same (which means we will get a repetition), we keep generating a new row using randperm(3,2) until a completely new row is obtained.
My code checks each each row before one at a time, and "forgets" every other row that it previously checked. It does not take into consideration ALL the previous rows, instead it only iterates back one step at a time. I tried using something like parents(i:-1:1) instead of parents(i-k,1) etc but couldn't make it work.
Question: How can I do this comparison?
parents=randperm(3,2);
for i=2:3
parents=[parents; randperm(3,2)]
for k=1:i-1
while prod(parents(i,:))==prod(parents(i-k,:)) && sum(parents(i,:))==sum(parents(i-k,:))
parents(i,:)=randperm(3,2)
end
end
i=i+1;
end
Download this function, then use it as follows:
% generate all the possible permutations
p = permn(1:3,2);
% generate a random permutation of the indices and take the first three
r = randperm(size(p,1));
idx = r(1:3);
% take three random rows from the possible permutations using the indices
result = p(idx,:);
This way:
you will never obtain a row identical to another one in your result matrix
you won't be forced to use a "shuffle until condition is met" approach
you have a reusable and flexible approach

Changing those elements of a matrix to zero which are not in a column of another matrix

I have a 100x100 matrix A (containing values ​​from 0 to 150) and a 35x4 matrix B. In matrix A, I want to keep only those values ​​that are present in column 3 of B i.e. B(:,3) and change all other values in A to zero. So the size of A will remain unchanged. Is this achievable?
I started to make a code beginning with a loop traversing the matrix A, another one going through column 3 of B and an if-statement to signify the equality condition that I want but how to correctly define the finality of the loop?
for i=1:size(A,1)
for j=1:size(B,3)
if ismember (A(i,i),B(j,3))
A(B(j,3))=A; % it's false
end
end
end
This can be done without loops using ismember as follows:
A=A.*ismember(A,B(:,3))

Accessing the layers of a multidimensional array and performing some function on each layers

I have this code
A = unidrnd(2,100,30)-1;
B = reshape(A, 100, 3, 10);
B is a multidimensional array with 10 layers of 100x3 Matrices. Now I want to perform this code,
C = length(nonzeros(all(B,2)))/100;
where the function on the right hand side of the code is suppose to generate 10 values corresponding to the result of the 10 layers, but all I get is a single value. The right hand of the code checks how many rows are all 1's. It takes the number of rows that are all 1's and divides it by 100 to obtain the fraction of the number of rows that are all 1's.
How can I obtain the result of every 100 x 3 layers of the 3D matrix using the single line of code I have shown above such that I do not have to use a loop? The result C had to be array of the results as expected.
You started out well. all(B,2) is good, it gives you the 100x1x10 matrix that's 1 where the corresponding rows are all 1's and 0 otherwise.
nonzeros, however, simply lists all of the nonzero elements of the entire matrix, in your case, a string of 1's, completely disregarding the dimensions of the array. You'd get the same results with nonzeros(A(:)) as with nonzeros(A).
[Note: nnz(A) would get you the same results as length(nonzeros(A)), but that's not what we want to do anyway.]
Since your matrix is binary (the output of all is a logical array), we can count the number of non-zero elements by summing the matrix elements. And sum gives us a dimension argument just like all, so we just sum the columns that all gave us.
C = sum(all(B,2),1)/100;
This gives you a 1x1x10 array of percentages. If you wanted that to just be a normal vector, you could use squeeze.
C = squeeze(sum(all(B,2),1)/100);

How do I efficiently multiply every 2 columns and sum the row

Maybe I should just go with a for loop but I want to see if there is a more efficient/faster way to do it.
I have a matrix of numbers, let's say 10x10. I want to multiply 1,1 by 1,2, then 1,3 times 1,4, etc and then sum those results for row 1. Then move to the next row and do the same thing. The end result would be a vector of 10.
It is possible for this matrix to be 1000x1000 so I want it to be as fast as possible. Thanks!
I would use
v = sum(M(:,1:2:end-1).*M(:,2:2:end),2);
Here M(:,1:2:end-1).*M(:,2:2:end) does multiplication: every element of an odd-numbered column of M is multiplied by its neighbor to the right. (This assumes even number of columns, otherwise the process you described is ill-defined.) Then every row is added up by the sum command.
On my computer, doing this for a 1000 by 1000 matrix takes 0.04 seconds.

Creating all possible combination of rows in matlab

I have a matrix which is 9x10000 size.
So rows are R1, R2, upto R9.
I want to generate all possible combination of the rows such as
[R1;R2] [R1;R3].. [R1;R9]
[R1;R2;R3]...[R1;R2;R4]... [R1;R2:R3;R4;..R8]
I am currently doing this using for loops.
Is there any better way of doing this.
Basically, counting up the binary from 1 to 2^9-i indicates which rows need to be selected:
M=... your matrix
S=dec2bin(1:2^size(M,1)-1)=='1';
allSubsets=cell(size(S,1),1);
for ix=1:size(S,1)
allSubsets{ix}=M(find(S(ix,:)),:);
end
As in the comment, I'm not sure if you always want the first row. This code doesn't do that, but you can modify it for that easily enough. It still uses for loops, but relies on the "nchoosek" function for the row index generation.
%generate data matrix
nMax=9; %number of rows
M=rand(nMax,1e4); %the data
%cell array of matrices with row combinations
select=cell(2^nMax-nMax-1,1); %ignore singletons, empty set
%for loop to generate the row selections
idx=0;
for i=2:nMax
%I is the matrix of row selections
I=nchoosek(1:nMax,i);
%step through the row selections and form the new matrices
for j=1:size(I,1)
idx=idx+1; %idx tracks number of entries
select{idx}=M(I(j,:),:); %select{idx} is the new matrix with selected rows
%per Floris' comment above you could do
%select{idx}=I(j,:); %save the selection for later
end
end
The function nchoosek, when given a vector, will return all possible ways to choose k values from that vector. You can trick it into giving you what you want with
allCombis = unique(nchoosek([zeros(1,9) 1:9], 9), 'rows');
This will include all possible ways to select 9 values from the set that includes nine zeros, plus the indices of each of the rows. Now you have every possible combination (including "no row at all"). With this matrix generated just once, you can find any combination easily - without having to store them all in memory. You can now pick you combination:
thisNumber = 49; % pick any combination
rows = allCombis(thisNumber, :);
rows(rows==0)=[]; % get rid of the zeros
thisCombination = myMatrix(rows, :); % pick just the rows corresponding to this combination