How to generate all possible nxm arrays, if each element is binary (can only take on 0 or 1). Preferably in matlab - matlab

I am essentially trying to generate all possible nxm matrices. I have seen some codes in R and Python that kind of does this with a single function, but I cant find anything similar for matlab :(

here's a way to do that in matlab:
n=4;
m=3;
for c=0:2^(n*m)-1
A(:,c+1)=str2double(split(dec2bin(c,n*m),'',1));
end
A(1,:)=[]; A(end,:)=[];
A=reshape(A,n,m,[]);
the logic, it doesnt matter if it is an nxm array or a 1D vector of length nxm, we can later reshape the vector to an nxm array (last line). Then, the # of possible permutation for a binary string of Length L is just all the decimal # from 0 to 2^L-1 transformed to binary string of length nxm. This is what the dec2bin(...) function does. Then we get a long string (for example '010001010111') that needs to be split to individual elements('0','1',...) , so we can later convert this strings to numbers using str2double. The split(...) function does that but generates NaN at the edges, so we get rid of them in the row before the last one...
so for this example I chose n=4, m=3, which generates just 2^(nxm)=4096 possible array...
you can see them if if you try A(:,:,j) with j being a # from 1 to 4096

Related

Get numbers in a matrix in different set positions

I have a matrix 1x5000 with numbers. Now I am interested in getting values from the matrix in different positions, more precisely in six different places of the matrix. The places should be based on the length, these are the numbers I want to get out:
Number in 1/6 of the matrix length
Number in 2/6 of the matrix length
Number in 3/6 of the matrix length
Number in 4/6 of the matrix length
Number in 5/6 of the matrix length
Number in 6/6 of the matrix length
These values could be printed out in another matrix, so assume the matrix is 1x5000, 3/6 would give the number in the middle of the matrix. I am new in Matlab and therefore the help is much appreciated!
Since your question is unclear I can try to give you an example.
First of all you can use numel function to get matrix's size.
It's easy to get necessary element in Matlab: you can address directly to any element if you know its number (index). So:
x(100) returns 100th element.
Now you got size and know what to do. Last moment - what to do if numel(x) / 6 return non integer?
You can use rounding functions: ceil, floor or round.
index = ceil(numel(x)/6) %if you want NEXT element always
result = x(index)
Next step: there are a lot of ways to divide data. For example now you have just 6 numbers (1/6, 2/6 and so on) but what if there are 1000 of them? You can't do it manually. So you can use for loop, or you can use matrix of indexes or perfect comment Stewie Griffin.
My example:
divider = [6 5 4 3 2 1] % lets take 1/6 1/5 1/4 1/3 1/2 and 1/1
ind = ceil( numel(x)./divider)
res = x(ind)
The colon notation in MATLAB provides an easy way to extract a range of elements from v:
v(3:7) %Extract the third through the seventh elements
You could either manually input range or use a function to convert fractions into suitable ranges

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);

Write a program which takes a character string input and returns penultimate character. Whats wrong with my code?

New to Matlab and using the an e-book to learn.
This was the question:
Write a MATLAB program which takes as its input a character string and print out its
penultimate character.
The code I worked out:
A=char('X');
X=input('Please enter a string of characters: ','s');
disp(X(Size-1));
What am I doing wrong?
When I run it, the input part happens and then I get an error, I assume this is due to incorrect index reference?
Thanks
Size is a function, not a variable. Therefore, it would need arguments, like size(X) which would return [1 5] for a 1x5 matrix.
Try X(length(X)-1) or more concisely, X(end-1)
More info:
size(matrix) returns the dimensions of a matrix.
size(matrix, dimension) returns the number of elements in a dimension (row, column, etc) of a matrix.
numel(matrix) returns the number of elements of a matrix. For a 2D matrix, this is #rows * #cols. For any matrix, this is equivalent to prod(size(matrix)).
length(matrix) finds the number of elements along the largest dimension of a matrix. It is equivalent to max(size(matrix))

How to generate unique random numbers in Matlab?

I need to generate m unique random numbers in range 1 to n. Currently what I have implemented is:
round(rand(1,m)*(n-1)+1)
However, some numbers are repeated in the array. How can I get only unique numbers?
You can use randperm.
From the description:
p = randperm(n,k) returns a row vector containing k unique integers
selected randomly from 1 to n inclusive.
Thus, randperm(6,3)
might be the vector
[4 2 5]
Update
The two argument version of randperm only appeared in R2011b, so if you are using an earlier version of MATLAB then you will see that error. In this case, use:
A = randperm(n);
A = A(1:m);
As pointed out above, in Matlab versions older than R2011b randperm only accepts one input argument. In that case the easiest approach, assuming you have the Statistics Toolbx, is to use randsample:
randsample(n,m)
The randperm approach described by #Stewie appears to be the way to go in most cases. However if you can only use Matlab with 1 input argument and n is really large, it may not be feasible to use randperm on all numbers and select the first few. In this case here is what you can do:
Generate an integer between 1 and n
Generate an integer between 1 and n-1, this is the choice out of the available integers.
Repeat until you have m numbers
This can be done with randi and could even be vectorized by just drawing a lot of random numbers at each step until the unique amount is correct.
Use Shuffle, from the MATLAB File Exchange.
Index = Shuffle(n, 'index', m);
This can be done by sorting a random vector of floats:
[i,i]=sort(rand(1,range));
output=i(1:m);

What's an appropriate data structure for a matrix with random variable entries?

I'm currently working in an area that is related to simulation and trying to design a data structure that can include random variables within matrices. To motivate this let me say I have the following matrix:
[a b; c d]
I want to find a data structure that will allow for a, b, c, d to either be real numbers or random variables. As an example, let's say that a = 1, b = -1, c = 2 but let d be a normally distributed random variable with mean 0 and standard deviation 1.
The data structure that I have in mind will give no value to d. However, I also want to be able to design a function that can take in the structure, simulate a uniform(0,1), obtain a value for d using an inverse CDF and then spit out an actual matrix.
I have several ideas to do this (all related to the MATLAB icdf function) but would like to know how more experienced programmers would do this. In this application, it's important that the structure is as "lean" as possible since I will be working with very very large matrices and memory will be an issue.
EDIT #1:
Thank you all for the feedback. I have decided to use a cell structure and store random variables as function handles. To save some processing time for large scale applications, I have decided to reference the location of the random variables to save time during the "evaluation" part.
One solution is to create your matrix initially as a cell array containing both numeric values and function handles to functions designed to generate a value for that entry. For your example, you could do the following:
generatorMatrix = {1 -1; 2 #randn};
Then you could create a function that takes a matrix of the above form, evaluates the cells containing function handles, then combines the results with the numeric cell entries to create a numeric matrix to use for further calculations:
function numMatrix = create_matrix(generatorMatrix)
index = cellfun(#(c) isa(c,'function_handle'),... %# Find function handles
generatorMatrix);
generatorMatrix(index) = cellfun(#feval,... %# Evaluate functions
generatorMatrix(index),...
'UniformOutput',false);
numMatrix = cell2mat(generatorMatrix); %# Change from cell to numeric matrix
end
Some additional things you can do would be to use anonymous functions to do more complicated things with built-in functions or create cell entries of varying size. This is illustrated by the following sample matrix, which can be used to create a matrix with the first row containing a 5 followed by 9 ones and the other 9 rows containing a 1 followed by 9 numbers drawn from a uniform distribution between 5 and 10:
generatorMatrix = {5 ones(1,9); ones(9,1) #() 5*rand(9)+5};
And each time this matrix is passed to create_matrix it will create a new 10-by-10 matrix where the 9-by-9 submatrix will contain a different set of random values.
An alternative solution...
If your matrix can be easily broken into blocks of submatrices (as in the second example above) then using a cell array to store numeric values and function handles may be your best option.
However, if the random values are single elements scattered sparsely throughout the entire matrix, then a variation similar to what user57368 suggested may work better. You could store your matrix data in three parts: a numeric matrix with placeholders (such as NaN) where the randomly-generated values will go, an index vector containing linear indices of the positions of the randomly-generated values, and a cell array of the same length as the index vector containing function handles for the functions to be used to generate the random values. To make things easier, you can even store these three pieces of data in a structure.
As an example, the following defines a 3-by-3 matrix with 3 random values stored in indices 2, 4, and 9 and drawn respectively from a normal distribution, a uniform distribution from 5 to 10, and an exponential distribution:
matData = struct('numMatrix',[1 nan 3; nan 2 4; 0 5 nan],...
'randIndex',[2 4 9],...
'randFcns',{{#randn , #() 5*rand+5 , #() -log(rand)/2}});
And you can define a new create_matrix function to easily create a matrix from this data:
function numMatrix = create_matrix(matData)
numMatrix = matData.numMatrix;
numMatrix(matData.randIndex) = cellfun(#feval,matData.randFcns);
end
If you were using NumPy, then masked arrays would be the obvious place to start, but I don't know of any equivalent in MATLAB. Cell arrays might not be compact enough, and if you did use a cell array, then you would have to come up with an efficient way to find the non-real entries and replace them with a sample from the right distribution.
Try using a regular or sparse matrix to hold the real values, and leave it at zero wherever you want a random variable. Then alongside that store a sparse matrix of the same shape whose non-zero entries correspond to the random variables in your matrix. If you want, the value of the entry in the second matrix can be used to indicate which distribution (ie. 1 for uniform, 2 for normal, etc.).
Whenever you want to get a purely real matrix to work with, you iterate over the non-zero values in the second matrix to convert them to samples, and then add that matrix to your first.