Random magic matrix giving unexpected results - matlab

I was trying to create random magic square in Octave and tried something like rand(magic(3)), and it gave unexpected endless results something like this:
ans(:,:,1,1,2,1,1,1,1) =
0.894903 0.296415 0.143990
0.186976 0.305691 0.505485
0.224823 0.834031 0.285508
0.336706 0.318158 0.076293
On trying rand(magic(4)) and for 5,6,7... it gave a message something like this
error: out of memory or dimension too large for Octave's index type
What can be the possible reason for this vague result ?

What are you trying to do? magic(3) creates a 3-by-3 matrix in which all the rows and columns add up to the same number. rand(x) creates an n-dimensional matrix of uniformly distributed random numbers. If you call y = rand([1,2,3]) for example, you will get a 3-dimensional matrix of uniformly distributed numbers. The dimensions of y will match your input i.e. size(y) should return [1,2,3] and the number of elements will be prod(y). Thus the number of elements of rand(magic(3)) should be equal to prod(prod(magic(3))) which is 362880. If you do this for rand(magic(4)) then the number of elements would be over 20 trillion which is why you are running out of memory.

Related

How to generate all possible nxm arrays, if each element is binary (can only take on 0 or 1). Preferably in 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

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

Assigning the different row to another matrix after comparing two matrices

i have two matrices
r=10,000x2
q=10,000x2
i have to find out those rows of q which are one value or both values(as it is a two column matrix) different then r and allocate them in another matrix, right now i am trying this.i cannot use isequal because i want to know those rows
which are not equal this code gives me the individual elements not the complete rows different
can anyone help please
if r(:,:)~=q(:,:)
IN= find(registeredPts(:,:)~=q(:,:))
end
You can probably do this using ismember. Is this what you want? Here you get the values from q in rows that are different from r.
q=[1,2;3,4;5,6]
r=[1,2;3,5;5,6]
x = q(sum(ismember(q,r),2) < 2,:)
x =
3 4
What this do:
ismember creates an array with 1's in the positions where q == r, and 0 in the remaining positions. sum(.., 2) takes the column sum of each of these rows. If the sum is less than 2, that row is included in the new array.
Update
If the values might differ some due to floating point arithmetic, check out ismemberf from the file exchange. I haven't tested it myself, but it looks good.

Finding coordinates of maximum values of a matrix

I'm trying to find a way to find the sets of coordinates of the maximum value/s in a matrix of size [8,8], where the values in the matrix vary from 0 to 6 (generated through the rest of the script/function).
i.e. a matrix of zeros(8,8) where the value 1 is in [3,3], [3,5] and [5,3].
and I want to get returned something along the lines of ([3,3],[3,5],[5,3])
I have tried using things such as ind2sub, etc but with no luck (I keep getting things returned like [I,J] = [ [0,0,3,0,5,0,0,0] , [1,1,1,1,1,1,1,1] ])
Any ideas?
If more clarification is needed, just point out where you need it and I'd be glad to do so.
The problem you've been having with max so far is because it operates on one dimension. If you call it on a matrix, using its default parameters, it will return a single maximum element (and indices) for each column of the matrix. In your case, you want all maximums, and the global maximum at that.
Try this:
[I,J] = find(M == max(M(:)))
First, max(M(:)) finds the maximum element, then we construct a logical matrix M == max(M(:)) showing which elements are the maximum. Finally, you can use find to get the co-ordinates of those (if necessary).

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.