This question already has answers here:
Multiple loop variables Matlab
(3 answers)
Closed 7 years ago.
I need to make a for loop in MATLAB to divide each column in a matrix by a separate column vector. I only want to do this for a selection of the columns in the matrix, not all the columns.
This is what I'd like to do, where Indexes is a 19x1 vector of integers (not all consecutive numbers), big_matrix is 82x24, and other_column is 82x1:
matrix_to_fill = zeros(82,length(Indexes));
for x = Indexes
new_column = big_matrix(:,x)./other_column;
new_index = find(Indexes==x);
matrix_to_fill(:,new_index) = new_column;
end
When I run this I get the following error:
Error using ./
Matrix dimensions must agree.
I can run each iteration separately without getting errors, so I know that the matrix dimensions agree. What's more, if I type out the Indexes as a vector it works fine:
matrix_to_fill = zeros(82,length(Indexes));
for x = [1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,23]
new_column = big_matrix(:,x)./other_column;
new_index = find(Indexes==x);
matrix_to_fill(:,new_index) = new_column;
end
And I think the "x=Indexes" syntax is fine because I've tested that using just:
for x = Indexes
disp(x)
end
So I'm completely stumped. Any help would be much appreciated!
The problem is in your definition of the for loop. When you say that you think the "x=Indexes" syntax is correct you haven't been observant enough to see that it is not correct.
What you need is
for x = Indexes'
% Do your looping
end
Note the transpose in the above.
If you do
for x = Indexes
disp(x)
end
Then the loop is executed once, with x taking on the value of the whole vector.
If you do
for x = Indexes'
disp(x)
end
then x will take on the individual elements of the matrix and you'll have 19 scalars displayed, once each time through the loop.
Related
I have already learning to use downsample() function inside Matlab. However, I am wondering if it can be implemented using basic for loop or if statement. Can anyone help me?
P.S Below is the code I have worked out, I would like to know if there is a different way to do it.
for i=1:M:length(x)
y=[y x(i)];
end
end
`
If M is a scalar integer value, and x is a vector, then x(1:M:end) takes every Mth element.
x = 1:14;
M = 4;
x(1:M:end)
ans =
1 5 9 13
You can start at a different value too: x(3:M:end).
if (hidden_layer>1)
for i =1 :hidden_layer
start_hidden_layer(i) = rand([gk(i+1),(gk(i)+1)])-0.5 ;
end
end
hi Friends.
I know every iteration was changed start_hidden_layer matrix dimensional.But all start_hidden_layer values must saved. How to solve this problem?
firstly hidden_layer>1
gk(i) is integer value for example 5 , 3, 8
Since you're calling rand with different matrix sizes on each iteration, you cannot save the results into a normal matrix. You need to use a cell matrix to store the result, like this:
%//preallocate the cell array
start_hidden_layer = cell(1, hidden_layer);
for i = 1:hidden_layer
start_hidden_layer{i} = rand([gk(i+1), (gk(i)+1)]) - 0.5;
end
For more on cell arrays and how to use them, see this Mathworks help doc.
The matlab documentation explains vectorization with
i = 0;
for t = 0:.01:10
i = i + 1;
y(i) = sin(t);
end
This is a vectorized version of the same code:
t = 0:.01:10;
y = sin(t);
Can I apply vectorization to a function with non-scalar inputs and outputs? As a toy example, take the function foo
function out = foo(in)
out(1) = in(1);
out(2) = in(2);
end
It's just the identity. I'd like to do something like
inputs = [1,2; 3,4; 5,6];
t = 1:3;
outputs = foo(inputs(t,:))
and get
ans =
1 2
3 4
5 6
Instead I end up with
ans =
1 3
Clearly, I'm either doing it wrong or it's not possible. Help!
It is possible to vectorize in Matlab in N-dimensions. As it was mentioned by Andrew you can simply writte a function like:
function out = foo(in)
out(:,1:size(in,2)) = in(:,1:size(in,2));
end
Output will be as desired.
Using the (:) index operator on n-dimensional arrays allows you to perform vectorized operations on all elements. You can use e.g. reshape to put the result back into the same form as the input.
function out=foo(in)
out=reshape(in(:),size(in));
The unexpected output
The reason your output is [1 3] has to do with linear indexing of matrixes. In particular this means that you can access the full matrix with a vector, where you first count through the first column, then the second column and so on. For a 3x2 matrix this would be:
1 4
2 5
3 6
Therefore in(1) = 1 is the first element in the first column. in(2) = 3 is the second element in the first column. Find the full documentation for matrix indexing here.
The input
Secondly writing outputs = foo(inputs(t,:)) means that you take all rows specified in t with no condition to the columns. Therefore in your example it is equivalent to write outputs = foo(inputs) and outputs = foo(inputs(t,:)) as you put in all 3 rows. What you could do is let foo() have two arguments.
function out = foo(t,in)
out = in(t,:)
To have access to the rows inside the function you could write something like:
function out = foo(in);
[x,y] = size(in);
for t = 1:x
out(t,:) = in(t,:);
end
Normally vectorization is used to avoid looping through scalars. There are a lot of clever ways to simplify code and reduce it's computation time. Most techniques like .* ,.^, bsxfun() are already presented in the documentation about vectorization you already found. The tricky part is to find the right way to apply these methods. It takes a lot of experience and a sharp eye to fully utilize them, as in every case you need to adjust to the specific logic of your opperations.
Feel free to ask if you still struggle with your problem.
I am trying to add a row to a matrix every time an iterative loop in MATLAB produces an answer from fsolve function.
Say, fsolve produces an answer 3 and 2 (2 elements), and then I want to add these into a 1x2 matrix.
After a second loop fsolve produces an answer 5 and 3 (2 new elements) and I want to add these to the old solution matrix but as a new row so that a new matrix is a 2x2 matrix.
and on and on.
any ideas?
You can also use end to add an extra column to your matrix, so A(:,end+1) = [x1; x2]; adds an extra column to the matrix A. This also works for rows of course.
To augment:
Before the loop:
A = [];
In the loop, for example:
A = [A; 3 2];
A better way is to pre-allocate the array given you know how many times you gonna run the loop.
For example,
A = zeros(n,2);
A(i,:) = [3 2];
This question already has an answer here:
Subscript indices must either be real positive integers or logicals?
(1 answer)
Closed 8 years ago.
I have a for loop which generates a vector. i want to store these vectors in a matrix.
normally i would do:
for r=1:100
vec=[x:y]+r;
mat(:,r)=vec
end
But this doesnt work, because i have something like:
dr=10/20
for r=1:dr:20
vec=[x;y]+r;
...
How would I store the vectors in a matrix now? Because i cant use r for the column indices, because the values of r arent integers most of the time.
Many options eg:
r=1:dr:20
for rr=1:length(r)
vec=[x;y]+r(rr);
mat(:,rr)=vec;
...
or
col = 1;
for r=1:dr:20
vec=[x;y]+r;
mat(:,col)=vec;
col = col + 1;
....
But whatever you choose you must preallocate mat before your for loop like this:
mat = zeros(length(x) + length(y), length(1:dr:20))
Pre-allocation is essential when using loops in Matlab or they will run very inefficiently.