How to replace multiple values in a matrix in matlab - matlab

I'm trying to turn N number of zeros into a "1". My code works to change only one zero at a time. What is the best way to simultaneously change the zeros into a "1" N number of times?
N=4;
board=zeros(N);
board(randi(numel(board)))=1
Thank you
Edit:
N=4;
board=zeros(N);
x=1;
while (x<=N)
board(randi(numel(board)))=1;
x=x+1;
end
Would it be possible to get this to work? It's not giving me an error, but it's not giving me an output either...

I am suggesting a small improvement over atru's answer. All you need to do is this:
N=4;
board=zeros(N);
board(randperm(numel(board), N)) = 1;
Here randperm will basically generate N random numbers from the set 1:(N*N) to fill your matrix

You can generate an NxN matrix of 0s with M randomly placed 1s in a single line
myMatrix = reshape(randperm(N^2)<=M, N, N);
Just replace M with N in your specific case.

This is one way to do it while avoiding an explicit for loop
N=4;
board=zeros(N);
ind_1s = randperm(N*N);
board(ind_1s(1:N)) = 1;
This generates random permutations of all matrix indices and then it fills first N with 1s.
Your solution will work too but it needs a condition for cases when the newly chosen index already has a 1 in there
N=4;
board=zeros(N);
x=1;
while (x<=N)
ind_1s = randi(numel(board));
if board(ind_1s)==0
board(ind_1s)=1;
x=x+1;
end
end
For large matrices the first one may be better performance wise, but that would need to be check with matlab profiler or simple timing.

Related

Filling a matrix with vectors in loop and apply operation

I am working on matlab with a matrix. I would like to reproduce this matrix and apply sum for elements in rows.
I have two vectors defined by this code:
unitsvector=1:5;
reordervector=1:3;
Then, I create an empty matrix to store the values:
resultvec=zeros(size(unitsvector,2)*size(reordervector,2),3);
Finally, here is the loop I use but it is not working:
for a=1:length(resultvec)
for b=reordervector
for c=unitsvector
resultvec(a,1)=b;
resultvec(a,2)=c;
resultvec(a,3)=b+c;
end
end
end
How could I reproduce this matrix in matlab. Thanks for your help.
You can use meshgrid for this without a for loop.
[a,b] = meshgrid(1:5,1:3);
M = [a(:) b(:)];
M(:,3) = sum(M,2); % Create third column by summing first two
Why are you looping at all? sum actually has vector support; a simple resultvec = [a(:,1),a(:,2),sum(a,2)] would work.
As to your code: of course it doesn't work. What do you expect to be the contents of a? You create a as a loop index, which runs over the range 1:length(resultvec). Ergo, within each loop iteration a is a scalar. You try to call it like it is a three-element vector. Nor do you define b and c. This might be possible in R, judging where you're coming from, but not in MATLAB.

Looping through values in a matrix

I have a Matrix M and I want to run a loop in Matlab whereby the loop variables i,j run through all M(i,j). Can someone provide the syntax please?
First you should first look whether there is a way you could do something using vector operations rather than loops, this is Matlab's strength and usually runs faster. However, if you need to use loops (which sometimes you cannot get around), there are two ways you could do this, the first is to use a single indexing variable (numel is the number of elements in the matrix), this goes through the matrix column by column.
for i = 1:numel(M)
M(i) = %your code here
end
or through each row and column the way you specified (size(M, n) where n is an integer is the size of the nth dimension (1st is number of rows, 2nd is number of columns, 3rd is the number of levels, ...))
for i = 1:size(M, 1)
for j = 1:size(M, 2)
M(i, j) = %your code here
end
end

How can I calculate dyadics in matlab without using for loops?

I was wondering if someone could help me with my problem.
Let say that I have the coordinates of MxN vectors in a tensor r of dimensions [M,N,3]. I would like to save in a 3M-by-3N block matrix all dyadic products r_0'*r_0, where r_0 is the vector r_0 = r(m,n,:) for some m and n, and I would like to do this without using for loops.
If haven't explain myself correctly, here is an example code that shows what I would like to obtain (but using for loops, of course):
N=10;
M=5;
r=rand(M,N,3);
Dyadic=zeros(3*M,3*N);
for m=1:M
a1=3*m-2;
a2=3*m;
for n=1:N
b1=3*n-2;
b2=3*n;
aux(3)=r(m,n,3);
aux(2)=r(m,n,2);
aux(1)=r(m,n,1);
Dyadic(a1:a2,b1:b2)=transpose(aux)*aux
end
end
Thanks in advance!
You need to use bsxfun(#times and then re-arrange elements to have the desired output -
%// Get the multipliication result
mat_mult = bsxfun(#times,permute(r,[1 2 4 3]),r);
%// OR if you would like to keep mat_mult as 3D that could be potentially faster -
%// mat_mult = bsxfun(#times,reshape(r,[],3),permute(reshape(r,[],3),[1 3 2]));
%// Re-arrange elements to have them the way you are indexing in nested loops
Dyadic = reshape(permute(reshape(mat_mult,M,N,3,[]),[3 1 4 2]),M*3,N*3);
The major play about this solution is really the re-arrangement of elements after we have the multiplication result.
Quick runtime tests with the input r as 1000 x 1000 x 3 sized array, show that this bsxfun based approach gives over 20x speedup over the nested loop code listed in the question!

Vectorizing Arithmetic Operations

I am trying to improve the performance of my code by converting some iterations into matrix operations in Matlab. One of these is the following code and I need to figure out how can I avoid using loop in the operation.
Here gamma_ic & bow are two dimensional matrices.
c & z are variables set from outer iterations.
for z=1:maxNumber,
for c=1:K,
n = 0;
for y2=1:number_documents,
n = n+(gamma_ic(y2,c)*bow(y2,z));
end
mu(z,c) = n / 2.3;
end
end
Appreciate your assistance.
Edit. Added The loop for c and z. The iteration goes on till the maximum indices in gamma_ic & bow. Added mu which is another two dimensional matrix to show usage of n.
This should work for you to get mu, which seems to be the desired output -
mu = bow(1:number_documents,1:maxNumber).'*gamma_ic(1:number_documents,1:K)./2.3

Correlation coefficient between rows of two matrices

I have the following code, how will I be able to simplify it using the function as it currently runs pretty slow, assume X is 10x7 and Y is 4x7 and D is a matrix stores the correlation between each pair of vectors. If the solution is to use the xcorr2 function can someone show me how it is done?
for i = 1:4
for j = 1:10
D(j,i) = corr2(X(j,:),Y(i,:));
end
end
Use pdist2 (Statistics toolbox) with 'correlation' option. It's faster than your code (even with preallocation), and requires just one line:
D = 1-pdist2(X,Y,'correlation');
Here is how I would do it:
First of all, store/process your matrix transposed. This makes for easier use of the correlation function.
Now assuming you have matrices X and Y and want to get the correlations between combinations of columns, this is easily achieved with a single loop:
Take the first column of X
use corrcoef to determine the correlation with all columns of Y at once.
As long as there is one, take the next column of X
Alternate to this, you can check whether it helps to replace corr2 in your original code with corr, xcorr or corrcoef and see which one runs fastest.
With corrcoef you can do this without a loop, and without using a toolbox:
D = corrcoef([X', Y']);
D = D(1 : size(X, 1), end - size(Y, 1) + 1 : end);
A drawback is that more coefficients are computed than necessary.
The transpose is necessary because your matrices do not follow the Matlab convention to enumerate samples with the first index and variables with the second.