I want to generate an array using two loops and a given equation. In my code, the first for-loop overwrites each time the elements that were generated in the previous run. My array ends up having only the last set of elements (for a=9). Here is the code:
%Pixel information generated
n=3
m=3
for a=7:9
for r=1:3
k(r)=a+ (r-1)*(n*m)
disp(k);
r=r+1
end
a=a+1
end
How can I avoid this and obtain all values of K for each value of "a"?
Thanks
Manoj
Since r is your index, your index will only vary from 1 to 3. And this each time you go through the first loop. Therefore, you need an independent index. You also don't need to increase r and a because the for-loop function does this automatically. Last, it's better to work with a cell array for k because it keeps growing throughout the for-loops.
Code:
n=3;
m=3;
k = cell(1,1); % cell array
index = 1; % independent index
for a=7:9
for r=1:3
k{index}=a+(r-1)*(n*m);
index = index + 1;
end
end
k = cell2mat(k)
Output:
k =
7 16 25 8 17 26 9 18 27
Related
I want to only use "randi" this function to produce the 6 different number randomly in matlab ,and the range of these 6 number is 1 ~ 12.
number=randi([1,12],1,6)
c=0;
for n=1:6%when "n" is 1 to 6
while c <= 6 %while c is less equal than 6,do the program below
c = c + 1; %c=c+1
if number(n) == number(c) %when the nth element is equal to cth element
number(n) = randi(12); %produce a random integer in the nth element
c = 0; %the reason why i set c=0 again is because i want to check again whether the new random integer is the same as cth element or not
end
end
end
final_number=number
but the result still show me like
1 "2" 6 11 "2" 3
5 "8" "8" 12 3 1
How do i improve my code to produce 6 different numbers.i don't want to always rely on the convenient matlab instruction too much,so my tags will also write c.hoping someone can help me to improve this
If you're trying to reproduce randsample (or randperm), why not just reproduce the algorithm MATLAB uses? (As far as we can tell...)
This is the Fisher-Yates shuffle. If you have a vector v, each iteration selects a random, previously unused element and puts it at the end of the unselected elements. If you do k iterations, the last k elements of the list are your random sample. If k equals the number of elements in v, you've shuffled the entire array.
function sample = fisher_yates_sample(v, k)
% Select k random elements without replacement from vector v
% if k == numel(v), this is simply a fisher-yates shuffle
for n = 0:k-1
randnum = randi(numel(v)-n); % choose from unused values
% swap elements v(end-n) and v(randnum)
v([end-n, randnum]) = v([randnum, end-n]);
end
sample = v(end-k+1:end);
end
Unlike MATLAB's version, mine requires a vector as input, so to get 6 random values in the range 1:12 you'd call the function like this:
>> fisher_yates_sample(1:12,6)
ans =
5 11 6 10 8 4
Since you're re-selecting single random numbers, when there is one occuring multiple times, why not just re-selecting all numbers at once?
% Initial selecting of random numbers.
number = randi([1, 12], 1, 6)
% While the amount of unique elements in numbers is less than 6:
while (numel(unique(number)) < 6)
% Re-select random numbers.
number = randi([1, 12], 1, 6)
end
And since you wrote, you specifically want to use the randi method, I guess there is a reason, you don't want to use randperm(12, 6)!?
What you are looking for is randperm. It produces a random permutation of a range of integers, so that if you select the first k numbers, you are sure that you get k unique integers in the range [1;n].
In your case, simply call:
randperm(12,6)
I am trying to build a submatrix by iterating on the rows of the last column in the main matrix which is of size (50000, 21), and if the value inside is greater than 1000 then the whole corresponding y(i,:) row will be added to the new submatrix and add to it more 33 consecutive rows from the main matrix.
I wrote this code below but it is returning only a 33x21 size and I think i am iterating through the j index but not the i index:
for i=1:50000
if y(i,21)>1000
for j=1:33
n(j,:)=y(j+i,:)
j=j+1
end
i=i+1
end
end
What am I doing wrong?
try this:
k=1;
for i=1:50000
if y(i,21)>1000
for j=0:33 %watch this out i am not sure how many rows you want to keep and if these involve the one with the last element greater than 1000 or not..%
n(k,:)=y(j+i,:);
j=j+1;
k=k+1;
end
i=i+1;
end
end
Problem is that every new set of 33 rows overwrites the previous one.The above code i think will do the trick.
this is a vectorized verison that needs no loop:
%find elements that are greater than 1000
lo = find(y(:,21) > 1000);
%indeices of 33th row after the lo,
%since it may take a value that is greater than the size of matrix we limit this value by min
up = min(size(y,1), lo + 33);
% create indices based on ranges
%see http://stackoverflow.com/a/39434045/6579744
index=cumsum(accumarray(cumsum([1;up(:)-lo(:)+1]),[lo(:);0]-[0;up(:)]-1)+1);
index= index(1:end-1);
n = y(index, :)
This question already has answers here:
Element-wise array replication in Matlab
(7 answers)
Closed 6 years ago.
This is a basic program but since I'm new to MATLAB, I'm not able to figure out the solution.
I have a column vector "Time" in which I want to print value "1" in first 147 cells, followed by "2" in 148 to 2*147 cells and so on. For that, I have written the following script:
Trial>> c=1;
Trial>> k=0;
Trial>> for i = c:146+c
Time(i,1)=1+k;
c=i;
k=k+1;
end
I know I need to iterate the loop over "Time(i,1)=1+k;" before it executes the next statement. I tried using break but that's not supposed to work. Can anyone suggest me the solution to get the desired results?(It was quite simple in C with just the use of curly braces.)
I am sure you don't want to run c=i; in every iteration.
My code should work for you:
x = 10; % Replace 10 by the max number you need in your array.
k = 1;
for i = 1 : x * 147
Time(i, 1) = k;
if rem(i, 147) == 0
k = k + 1;
end
end
This is the prime example of a piece of code that should be vectorized can help you understand vectorization. Your code can be written like this:
n = 147;
reps = 10; %% Replace this by the maximum number you want your matrix to have
Time = reshape(bsxfun(#plus, zeros(n,1), 0:reps), 1, []);
Explanation:
Let A be a column vector (1 column, n rows), and B be a row vector (1 row, m columns.
What bsxfun(#plus, A, B) will do here is to add all elements in A with all elements in B, like this:
A(1)+B(1) A(1)+B(2) A(1)+B(3) ... A(1)+B(m)
A(2)+B(1) A(2)+B(2) ............. A(2)+B(m)
............................................
A(n)+B(1) A(n)+B(2) .............. A(n)+B(m)
Now, for the two vectors we have: zeros(n,1), and 0:reps, this will give us;
0+0 0+1 0+2 0+reps
0+0 0+1 0+2 0+reps
% n rows of this
So, what we need to do now is place each column underneath each other, so that you will have the column with zeros first, then the row with ones, ... and finally the one with reps (147 in your case).
This can be achieved by reshaping the matrix:
reshape(bsxfun(#plus, zeros(n,1), 0:reps), [], 1);
^ ^ ^ ^
| | | Number of rows in the new matrix. When [] is used, the appropriate value will be chosen by Matlab
| | Number of rows in the new matrix
| matrix to reshape
reshape command
Another approach is using kron:
kron(ones(reps+1, 1) * 0:(n-1)
For the record, a review of your code:
You should always preallocate memory for matrices that are created inside loops. In this case you know it will become a matrix of dimensions ((reps+1)*n-by-1). This means you should do Time = zeros((reps+1)*n, 1);. This will speed up your code a lot.
You shouldn't use i and j as variable names in Matlab, as they denote the imaginary unit (sqrt(-1)). You can for instance do: for ii = 1:(n*147) instead.
You don't want c=i inside the loop, when the loop is supposed to go from c to c + 146. That doesn't make much sense.
You can use repmat,
x = 10; % Sequence length (or what ever it can be called)
M = repmat(1:x,147,1); % Replicate array 1:x for 147 columns
M = M(:); % Reshape the matrix so that is becomes a column vector.
I can assume that this is a task to practice for loops, but this will work.
An alternative solution may be to do
n = 147;
reps = 10;
a = ceil( (1:(n*reps)) / n);
You first construct an array with the length you want. Then you divide, and round of upwards. 1 to 147 will then become 1.
Can someone explain to me the meaning/significance of this code line by line? I am a beginner in MATLAB/programming so please use simple terminology particularly when explaining the fprintf function. (I tried to use the 'help' function in MATLAB to understand the 'fprintf' function and I still dont understand it... also if its simple enough, what is the expected output?
A = zeros(1,3); %pre-allocate space
k = 1; %count loop iterations
valueMatrix = [1 2 3; 5 6 7];
for jj = valueMatrix
fprintf('iteration %d:\n', k)
A(k) = jj(1) + jj(2);
jj, A %display variables on terminal
k = k + 1;
end
Sure. Let's go through each line of code separately. Bear in mind that I'm answering mainly because the for loop uses a matrix instead of a vector, and not many people know what that actually does.
A = zeros(1,3); %pre-allocate space
This creates an empty vector of three elements and this is stored in A.
k = 1; %count loop iterations
This I will explain later.
valueMatrix = [1 2 3; 5 6 7];
Declare a matrix of size 2 x 3, which looks like this:
1 2 3
5 6 7
for jj = valueMatrix
This is a for loop. I'm assuming you know what that is. for loops allow you to execute a piece of code inside the for syntax a given number of times. You specify a vector or a matrix and the loop executes the piece of code within the for construct again and again... and each time it executes, it pulls each value from the vector or matrix and stores it into a loop counter variable. In this case, that variable is jj. For example, if we did this:
for jj = 1 : 8
disp(jj);
end
This loop will start with jj = 1, and we will display this in the console. Next, we go jj = 2 and we display this in the console and we will keep going until jj = 8 then we stop. Now with a matrix this is slightly different. How it works is that at each iteration, we pull out a column at a time. For example, if we did:
for jj = [1 2 3; 4 5 6; 7 8 9]
disp(jj);
end
We would display:
1
4
7
... at the first iteration, then:
2
5
8
... then finally at the last iteration:
3
6
9
As such, if we did:
for jj = valueMatrix
... this means that we will run this loop three times. At the first iteration, jj would be:
1
5
The next iteration:
2
6
The last iteration:
3
7
What's important is that at each iteration, jj is a 2 element vector.
fprintf('iteration %d:\n', k)
fprintf stands for formatted print to file. However, the way it is being called prints to the screen instead of a text file. This may look unfamiliar to you because this is essentially the same way you'd call printf in C. The first parameter to this function is a string that you want to display to the screen. What you can also do is display the contents of a variable by putting the right specifiers inside the string. You use what are known as formatting strings. In this case, %d specifies an integer you want to print out, and \n means to move to the next line. Each formatting string is accompanied by the variable you want to print. In our case, %d is paired with the variable k, so you want to print out the variable k at each iteration. It would look like this at each iteration:
iteration 1:
iteration 2:
iteration 3:
A(k) = jj(1) + jj(2);
You'll notice that k starts at 1 and increments by 1 each time the loop iterates (the k = k + 1 statement two lines later). Therefore, at each iteration, we populate each entry in A with the addition of the two elements in jj.
jj, A %display variables on terminal
Self-explanatory. We show these variables to the screen, on top of the iteration print out statements... a bit messy IMHO.
k = k + 1;
Talked about this already. Increments at each iteration.
end
End the loop.
Therefore, the expected result that the three element vector stored in A has its contents changed, where each element sums from a column from valueMatrix. As such, for A you should get:
A = [6 8 10];
I have this code:
for h= 1:length ( bb1{CH(i)})
for k= 1:length( bb2{CH(j)})
if NN(bb1{CH(i)}(h),bb2{CH(j)}(k))==1
d = [bb1{CH(i)}(h),bb2{CH(j)}(k)]
end
end
end
When I run this code, the value of d takes the value of the last iteration. I want to save its value for all the iterations. For example, I want to have a rows_nb by 2 matrix.
This is highly unoptimized code, but the reason is pretty obvious. Your code is assigning to d at every iteration in that code and it keeps overwriting itself.
As such, you need to append to d if you want to save all of the values in the matrix. Therefore, do this:
for h= 1:length ( bb1{CH(i)})
for k= 1:length( bb2{CH(j)})
if NN(bb1{CH(i)}(h),bb2{CH(j)}(k))==1
d = [d; bb1{CH(i)}(h),bb2{CH(j)}(k)]; %// Concatenate
end
end
end
This way, you are adding two columns every time to the matrix and add an additional row at each iteration.