how to do this?
i want to place a specific number, like number 2 randomly into a 3x3 of zeros array,
it did came out, but the coding still not right and somehow number 1 also appear.
rows = 3;
cols = 3;
M = zeros(rows,cols);
p = randi(2);
rV = randperm(rows);
cV = randperm(cols);
M(rV(2),cV(2))=p
where did i do wrong? any suggestion
You could also use randi together with linear indexing
m = zeros(3);
m(randi(numel(m))) = 2;
No need - I've already solved it!
a=[2];
m=zeros(3);
m(randperm(numel(m),numel(a)))=a
Related
How can I delete all-zero pages from a 3D matrix in a loop?
I have come up with the following code, though it is not 'entirely' correct, if at all. I am using MATLAB 2019b.
%pseudo data
x = zeros(3,2,2);
y = ones(3,2,2);
positions = 2:4;
y(positions) = 0;
xy = cat(3,x,y); %this is a 3x2x4 array; (:,:,1) and (:,:,2) are all zeros,
% (:,:,3) is ones and zeros, and (:,:,4) is all ones
%my aim is to delete the arrays that are entirely zeros i.e. xy(:,:,1) and xy(:,:,2),
%and this is what I have come up with; it doesn't delete the arrays but instead,
%all the ones.
for ii = 1:size(xy,3)
for idx = find(xy(:,:,ii) == 0)
xy(:,:,ii) = strcmp(xy, []);
end
end
Use any to find indices of the slices with at least one non-zero value. Use these indices to extract the required result.
idx = any(any(xy)); % idx = any(xy,[1 2]); for >=R2018b
xy = xy(:,:,idx);
I am unsure what you'd expect your code to do, especially given you're comparing strings in all-numerical arrays. Here's a piece of code which does what you desire:
x = zeros(3,2,2);
y = ones(3,2,2);
positions = 2:4;
y(positions) = 0;
xy = cat(3,x,y);
idx = ones(size(xy,3),1,'logical'); % initialise catching array
for ii = 1:size(xy,3)
if sum(nnz(xy(:,:,ii)),'all')==0 % If the third dimension is all zeros
idx(ii)= false; % exclude it
end
end
xy = xy(:,:,idx); % reindex to get rid of all-zero pages
The trick here is that sum(xy(:,:,ii),'all')==0 is zero iff all elements on the given page (third dimension) are zero. In that case, exclude it from idx. Then, in the last row, simply re-index using logical indexing to retain only pages whit at least one non-zero element.
You can do it even faster, without a loop, using sum(a,[1 2]), i.e. the vectorial-dimension sum:
idx = sum(nnz(xy),[1 2])~=0;
xy = xy(:,:,idx);
In common arrays the intersection function would have worked great, but for tall arrays this function has not been implemented yet. So is there an other way to find the common elements of these two?
Use a for-loop to do the checks
n = 1e4;
m = 1e3; %Batchsize
a = tall(randi(n,n,1));
b = tall(randi(n,1,n));
idx = tall(false(n,1));
for ii = 1:n/m
idx = idx | any(a==b(1,(ii-1)*m+1:ii*m),2);
end
inter = a(idx);
Where m controls how much of the array you can load into the memory at the time. The more the faster, but you will need to have enough memory for it.
I have an array sorted in ascended order. I want to replace the biggest m numbers found even positions in the array with 0.
My algorithm that I thought looks like this:
k=1;
for j=n:1 %%starting from last position to first
if(rem(j,2)==0 && (k<=m)) %%checking if the position is even & not getting over m numbers
B(j) = 0;
k = k + 1;
end
end
Can anyone point out why it is not working? Thank you!
A bit more complex
even = (n-rem(n,2)) : -2 : 1; % even indices in descending order
B( even(1:m) ) = 0; % set to zero
Note how n-rem(n,2) ensures that we start from the last even index into B.
PS,
It is best not to use j as a variable name in Matlab.
I believe this should do the trick. This works for vectors with both odd and even number of elements.
n = numel(B);
B((n-mod(n,2)):-2:(n-mod(n,2)-2*M)) = 0
or
n = mod(numel(B),2);
B((end-n:-2:end-n-2*M)) = 0
I prefer Shai's solution, but if your vector is huge, and M is relatively small, I would go with this approach, as it avoids creating a vector of length numel(B)/2
I need to sum consecutive 96 value blocks in a vector of n (in one case 14112) values. The background is that the values are 15-min temperature measurements and I want to average 96 at a time (1 to 96, 96+1 to 2*96 ... n*96+1 to (n+1)*96) to produce a daily average. This could of course be done in a loop stepping 96 but my question is if there is a more efficient way to accomplish this in Matlab.
By using reshape and mean:
data = randn(1,14112); % example data. Row vector
m = 96; % block size. It is assumed that m divides length(data)
result = mean(reshape(data,m,[]));
As #Dan points out, if the number of elements is not a multiple of the block size some padding is necessary. The following code, due to him, does the necessary padding in the last block while keeping the mean of that block. Thanks also to #DennisJaheruddin for his sugggestion not to modifiy original variable:
data = randn(1,14100); % example data. Row vector
m = 96; % block size
n = length(data);
result = mean(reshape([data repmat(mean(data(n-mod(n,m)+1:n)), 1, m - mod(n, m))], m, []));
Here is an alternate way to nicely deal with the problem, it also works if the lenght of the data is not a nice multiple of the window size:
data = randn(1,14112);
w = 96;
N = numel(data);
M = NaN(w,ceil(N/w));
M(1:N) = data;
nanmean(M)
If you don't want to include partial days at the end, use fix instead of ceil.
I need to sort these values randomly in an array.
int [] d = new int[26];
d[0]=1;
d[1]=5;
d[2]=10;
d[3]=25;
d[4]=50;
d[5]=75;
d[6]=100;
d[7]=200;
d[8]=300;
d[9]=400;
d[10]=500;
d[11]=750;
d[12]=1000;
d[13]=2000;
d[14]=3000;
d[15]=4000;
d[16]=5000;
d[17]=7500;
d[18]=10000;
d[19]=25000;
d[20]=50000;
d[21]=100000;
d[22]=250000;
d[23]=500000;
d[24]=750000;
d[25]=1000000;
Assuming you are writing this in C++ you can use random_shuffle function template from the Standard library. http://www.cppreference.com/wiki/algorithm/random_shuffle
If you want to write your own function, simply take two random indices and swap their values. Put that in a loop and do it as many times as think necessary for the array to be well shuffled (I would say a number of times equal to two times the number of elements in the array).
In psudo-code (since you haven't indicated the language)
NUMBER_OF_SHUFFLES = 2;
for(ix = 0; ix < NUMBER_OF_SHUFFLES * myArray.length; ix++)
index1 = random(myArray.length)
index2 = random(myArray.length)
temp = index1
myArray[index1] = myArray[index2]
myArray[index2] = temp
There are more sophisticated ways of doing it as well. Check out this discussion: An Efficient way of randomizing an array - Shuffle code
If it's java you may use
Arrays.shuffle(d);