Matlab's trick to increment variable - matlab

How to increment a variable by a infinite set of numbers, in Matlab. I'v a variable which I want to increment till the loop ends by 0.1 every time but through set of range.
I'm currently doing this by: K=K*0.1; %K = 2 initially but I want this same by Matlab's trick of ranged values like [0.1:0.1:9] where 9 is the loop condination.
My Code:
K=2;
for ii=1:9
K=K*0.1;
end

If I understand correctly:
for K = 2 * 0.1.^(1:9)
%// do something with K
end

You can try using the cumprod command which returns the cumulative product of the elements in a matrix or vector. For your example, something like:
K=cumprod([2 repmat(0.1,1,9)]); % returns a row vector of 9 elements
repmat just creates a row vector of nine elements each set to the value 0.1. The last element in the vector, K(end), will be the product returned by your example. i.e.K = 2*0.1^9;

Related

MATLAB: how do I create a vector where each element is a function of the previous element

Working in Matlab.
I am trying to create a vector where each element is a function of the previous element. The goal is to put the first 50 (or so) values of a logistical function in a vector. So I start with 0.200, with r=4 (for example), the second element would then be 40.200(1-0.200)=0.640.
The third element would take the value 0.64 and perform the same function on that number, and so on...
I have tried a for-loop, but since there is no counter in the function, the loop doesn't work.
EDIT: I have created the following function:
n = 0;
x = 0.200;
for n=0:100
x=4*x*(1-x)
n=n+1
end
This gives the first 100 values. But I fail to get them as values in a vector...
Any suggestions on how to solve this would be appreciated.
You need to use indexing for the x vector you are creating. The way you currently have it coded, everything is going into a scalar x and not a vector x. E.g.,
n = 50; % the number of elements you want to fill
x = zeros(1,n); % allocate a vector to hold the numbers
x(1) = 0.200; % set the first value
for k=2:n % loop through the remaining values
x(k) = 4*x(k-1)*(1-x(k-1)); % set the next value using the previous value
end
Note that in the above code all of the usages of x other than the initial allocation involve indexing, e.g. x(1) and x(k) and x(k-1).

Mean value of each column of a matrix

I have a 64 X 64 matrix that I need to find the column-wise mean values for.
However, instead of dividing by the total number of elements in each column (i.e. 64), I need to divide by the total number of non-zeros in the matrix.
I managed to get it to work for a single column as shown below. For reference, the function that generates my matrix is titled fmu2(i,j).
q = 0;
for i = 1:64
if fmu2(i,1) ~= 0;
q = q + 1;
end
end
for i = 1:64
mv = (1/q).*sum(fmu2(i,1));
end
This works for generating the "mean" value of the first column. However, I'm having trouble looping this procedure so that I will get the mean for each column. I tried doing a nested for loop, but it just calculated the mean for the entire 64 X 64 matrix instead of one column at a time. Here's what I tried:
q = 0;
for i = 1:64
for j = 1:64
if fmu2(i,j) ~= 0;
q = q +1;
end
end
end
for i = 1:64
for j = 1:64
mv = (1/q).*sum(fmu2(i,j));
end
end
Like I said, this just gave me one value for the entire matrix instead of 64 individual "means" for each column. Any help would be appreciated.
For one thing, do not call the function that generates your matrix in each iteration of a loop. This is extremely inefficient and will cause major problems if your function is complex enough to have side effects. Store the return value in a variable once, and refer to that variable from then on.
Secondly, you do not need any loops here at all. The total number of nonzeros is given by the nnz function (short for number of non-zeros). The sum function accepts an optional dimension argument, so you can just tell it to sum along the columns instead of along the rows or the whole matrix.
m = fmu2(i,1)
averages = sum(m, 1) / nnz(m)
averages will be a 64-element array with an average for each column, since sum(m, 1) is a 64 element sum along each column and nnz(m) is a scalar.
One of the great things about MATLAB is that it provides vectorized implementations of just about everything. If you do it right, you should almost never have to use an explicit loop to do any mathematical operations at all.
If you want the column-wise mean of non-zero elements you can do the following
m = randi([0,5], 5, 5); % some data
avg = sum(m,1) ./ sum(m~=0,1);
This is a column-wise sum of values, divided by the column-wise number of elements not equal to 0. The result is a row vector where each element is the average of the corresponding column in m.
Note this is very flexible, you could use any condition in place of ~=0.

How to create a matrix with the increments within a loop in matlab?

I have created one loop inside another in matlab, and i want to create a matrix inside this second loop that gives the values of the two increments plus a parameter that is being calculated. I made the following code but the matrix is just saving the last values, so it is not a matrix is a vector:
for inclin=29:1:39
for alfa=1:1:90
Ii_perc=...
Di_perc=...
Gi_perc=...
r=...
matriz=[inclin alfa r]
end
end
So, i want to have a matrix with the different combinations of inclin/alfa/r that the loop gives in each loop, i.e, something like this:
matriz =[29 1 0.34
29 2 0.32
29 3 0.40
...........]
I really need some help to solve this problem..
Thanks!
If I correctly you understand I can offer this variation:
Matrix = zeros((39-29+1)*90,3);
count = 1;
for inclin=29:1:39
for alfa=1:1:90
r=rand();
Matrix(count,:)=[inclin alfa r];
count = count+1;
end
end
The problem is that
matriz=[inclin alfa r]
is a vector. If you want to append an additional row every loop iteration, you need to index it like this:
matriz(i, :)=[inclin alfa r]
Using the colon in this way says to assign the right hand side of the equation to the ith row of matriz.

MATLAB busy, loop works well until i=29996, when i=29997 stay Busy

I am writing code which compares the data of a vector. It should count how many positions (acc) have equal values, and save a specific value in a vector of the same length of the quantity of positions (n_T(acc)).
My data vector is [30000 x 1]. For example, first 80 positions have the same value, next 60 positions have the same value, etc., next 5 positions have the same value.
The code works well if I use just 29996 values. I do not understand why when I try to use the complete vector MATLAB stays Busy.
Checking my data vector, I noticed that the last 5 positions are equivalent [29996:30000]. Could it be the reason, and what should I change?
Following is the code
%========================================================
%ac: data vector`
%acc1: accumulator which count how much positions have the same value
%n_T: vector which presents the values I need, in the same positions the data is equal
%m: show a value where i should begin
%========================================================
i=m; %previously used`
fv=length(ac)
while i<fv %29996
acc1=0;
for i=m+1:fv
if ac(i)==ac(i-1)
acc1=acc1+1; % count how much positions are equals
else
m=i;
break
end
end
mi=m-acc1; %define where the data n_T should begin
for i=mi:m
n_T(i)=tm/acc1; %create a vector with length [acc x1] begining in mi and finishing in m
end
m=i;
end
plot(n_T)
Does it work if you do this in a vectorized way? Not completely sure what you want the program to output.
% locate repeated elements
eq_els = ac(diff(ac) == 0);
% count number of repeated elements (unique)
unique_els = unique(eq_els);
num_equal_els = numel(unique_els);
% create variable-length lists for each unique element
each_eq_list = cell(num_equal_els,1);
for (k = 1:num_equal_els)
% each vector in the cell array is equal to the elements of ac that are equal to the current unique item
each_eq_list{[k]} = ac(ac == unique_els(k));
end
The length of each_eq_list{[k]} is the length of the total number of contiguous repeated values of repeated value k.

Variable has "incorrect" value when submitted to Matlab Grader

I am struggling with my Matlab homework:
Write a script to do the following:
Generate a matrix called grades of size 8 x 25 that contains random numbers of type double in the range of 1 to 6.
Calculate the mean of matrix rows (mrow), the mean of matrix columns (mcol), and the overall mean (mall) of the matrix grades.
Copy the matrix grades to a new variable, in which you replace the elements in the 5th row and 20th to 23rd column with NaN. Compute the overall mean (mall_2) of this matrix again, i.e., the mean of the remaining values.
I am done with task 2-5, however, task 1 is not correct. I am not sure what I am doing wrong. I assume that it has something to do with the type of number (double), but I was unable to convert it.
We have to submit our homework to the online tool "Matlab Grader". The system says:
Matrix of random numbers : Variable grades has an incorrect value.
Here is my code:
% Generate matrix 'grades' with random numbers in the range 1 to 6
a = 1;
b = 6;
grades = (b-a).*rand(8,25) + a;
% calculate mean values 'mrow', 'mcol', 'mall'
mrow = mean(grades,2)
mcol = mean(grades,1)
mall = mean(grades(:))
% Replace elements with NaN
grades(5,20:23) = NaN
%Calculate mean of elements omitting NaN
mall_2 = mean(grades(:),'omitnan')
I assume your homework validation system is checking that everything in the variable grades is a (random) number in the range 1 to 6, as required by question 1.
However, by the end of your computation there are also 3 NaN values in the grades variable, because you missed this step of question 3:
Copy the matrix grades to a new variable
Instead, you overrode the elements in grades.
If you did this:
grades_mod = grades;
grades_mod(5,20:23) = NaN;
mall_2 = mean(grades_mod(:),'omitnan');
Then grades would retain its original values (no NaNs) and you can calculate mall_2.