how to use a 'loop' for certain counts

I have 15 areas in my power data if i plot. want to calculate each area by using trapz function. can calculate each area manually(is shown in the code), but want to find these area automatically. maybe loop can be the solution.
there are 16 zero crossing indices. so from 1:16, there are 15 areas. used this below written loop, but it's showing the final value. I want to get every area from 1 to 16.
i=0;
for i=1:length(zeroaxes)
time(i:zeroaxes(i))=time(i:zeroaxes(i));
power(i:zeroaxes(i),1)=power(i:zeroaxes(i));
areaone=trapz(time,power);
end
would you please let me know any way ? attached the mat file.
thank you very much
Code(area calculated manually):
A=load('power.mat');
power=A.power;
time=1:length(power);
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Zero-Crossing Indices
zeroaxes = zci(power);
%% Area Calculation
time1=time(1:zeroaxes(2)); % time for area1
power1=power(1:zeroaxes(2)); % time for area1
area1=trapz(time1,power1); % integrated area1
time2=time(zeroaxes(2):zeroaxes(3));
power2=power(zeroaxes(2):zeroaxes(3));
area2=trapz(time2,power2);
time3=time(zeroaxes(3):zeroaxes(4));
power3=power(zeroaxes(3):zeroaxes(4));
area3=trapz(time3,power3);
time4=time(zeroaxes(4):zeroaxes(5));
power4=power(zeroaxes(4):zeroaxes(5));
area4=trapz(time4,power4);
time5=time(zeroaxes(5):zeroaxes(6));
power5=power(zeroaxes(5):zeroaxes(6));
area5=trapz(time5,power5);
time6=time(zeroaxes(6):zeroaxes(7));
power6=power(zeroaxes(6):zeroaxes(7));
area6=trapz(time6,power6);
time7=time(zeroaxes(7):zeroaxes(8));
power7=power(zeroaxes(7):zeroaxes(8));
area7=trapz(time7,power7);
time8=time(zeroaxes(8):zeroaxes(9));
power8=power(zeroaxes(8):zeroaxes(9));
area8=trapz(time8,power8);
time9=time(zeroaxes(9):zeroaxes(10));
power9=power(zeroaxes(9):zeroaxes(10));
area9=trapz(time9,power9);
time10=time(zeroaxes(10):zeroaxes(11));
power10=power(zeroaxes(10):zeroaxes(11));
area10=trapz(time10,power10);
time11=time(zeroaxes(11):zeroaxes(12));
power11=power(zeroaxes(11):zeroaxes(12));
area11=trapz(time11,power11);
time12=time(zeroaxes(12):zeroaxes(13));
power12=power(zeroaxes(12):zeroaxes(13));
area12=trapz(time12,power12);
time13=time(zeroaxes(13):zeroaxes(14));
power13=power(zeroaxes(13):zeroaxes(14));
area13=trapz(time13,power13);
time14=time(zeroaxes(14):zeroaxes(15));
power14=power(zeroaxes(14):zeroaxes(15));
area14=trapz(time14,power14);
time15=time(zeroaxes(15):zeroaxes(16));
power15=power(zeroaxes(15):zeroaxes(16));
area15=trapz(time15,power15);

 Accepted Answer

Rik
Rik on 14 Dec 2021
Edited: Rik on 14 Dec 2021
You were attempting to overwrite elements of your array.
You were also trying to create numbered variables, instead of using arrays. This is an instinct many new users have, and every time it should be discouraged. It forces you to use eval, which is a very effective way to write slow buggy code.
A=load(websave('power.mat','https://www.mathworks.com/matlabcentral/answers/uploaded_files/833630/power.mat'));
power=A.power;
time=1:length(power);
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Zero-Crossing Indices
zerosaxes = zci(power);
zerosaxes(1)=1;
%% Area Calculation
area=zeros(1,(numel(zerosaxes)-1));
for n=1:(numel(zerosaxes)-1)
time_current=time(zerosaxes(n):zerosaxes(n+1));
power_current=power(zerosaxes(n):zerosaxes(n+1));
area(n)=trapz(time_current,power_current); % integrated area
end
disp(area)
1.0e+07 * -0.6504 0.0001 -0.0898 0.1127 -0.4425 0.1308 -0.6012 0.1300 -0.3523 0.1563 -0.0001 0.0433 -0.6827 0.0181 -5.4040
If you want to store each iteration, you should use a cell array, which you can index with curly braces.

5 Comments

Comment posted as answer by @Mohammad Ariful Hoq:
thank you very much. i got the slight idea about for loop. but still i have to go a long way. I have some questions on your answers.
  1. i can run the code. but it's not showing any result either in command window or in the workspace.even there is no error messages. but i can see the result in the end of your code.
  2. "If you want to store each iteration, you should use a cell array, which you can index with curly braces":--- it will be greatly appreciated if you kindly provide the "syntax" here .I have used the below code,but showing no result, no errors.
A=load('power.mat');
power=A.power;
time=1:length(power);
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Zero-Crossing Indices
zeroaxes = zci(power);
zerosaxes(1)=1;
%% Area Calculation
area=zeros(1,(numel(zerosaxes)-1));
for n=1:(numel(zerosaxes)-1)
time_current{n}=time(zerosaxes(n):zerosaxes(n+1));
power_current{n}=power(zerosaxes(n):zerosaxes(n+1));
area{n}=trapz(time_current,power_current); % integrated area
end
disp(area)
You were too quick to copy my code. Because you were inconsistent with naming your variable either zerosaxes or zeroaxes, but initial code was not correct.
You are providing the entire cell array to trapz, that is not what you meant. You should index it there as well.
You are also using curly braces to index the area variable. It is a double array, so that will result in an error. You should think of a cell as a container. You use {} to get to the thing inside the container, and () to deal with the container itself.
This is basic Matlab syntax, which any tutorial worth your time should teach you.
Please also have a read here to see how to format your posts properly.
i solved it. thank you very much for suggesting to make a cell array. using cell array is easy and fast i guess.
A=load('power');
power=A.power;
time=(1:length(power))';
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Zero-Crossing Indices
zeroaxes = zci(power);
N=length(zeroaxes);
C=cell(N-1,3);
for k=1:N-1
C{k,1}=time(zeroaxes(k):zeroaxes(k+1));
C{k,2}=power(zeroaxes(k):zeroaxes(k+1));
C{k,3}=trapz( C{k,1},C{k,2});
end
power_area=[C{:,3}];
You're welcome. Two things: please format your code as code. That will improve readability of your post. Secondly, if my answer solved the problem, please consider marking it as accepted answer. That will make it easier for others with similar issues to find an answer.
noted your suggestion.
actually you have opended my eyes to solve this type of probelm. but your answer is not so much close to the solution.however, i am accepting your answer as you told me how to solve.
thank you so much again.

Sign in to comment.

More Answers (1)

Can you try with this for loop?
for i=1:length(zeroaxes)
try
eval(['time_',num2str(i),'=time(i:zeroaxes(i))']);
eval(['power_',num2str(i),'=power(i:zeroaxes(i))']);
power(i:zeroaxes(i),1)=power(i:zeroaxes(i));
eval(['area_',num2str(i),'=trapz(time_',num2str(i),',power_',num2str(i),')']);
catch
continue;
end
end

5 Comments

Thanks. I am not sure actually. I need to cross check the result. the result seems ok but not closed to the actual value. i can figure it out maybe. but its taking time to execute. any other easiest way ?
In addition to what I wrote in my answer about numbered variables, you also shouldn't be using length. It does max(size(___)). I have never found a situation where this was actually the intended syntax, instead of using numel or (size with a second input argument).
Using numbered variable names is a sign that you are doing something wrong.
Accessing variable names dynamically is slow, complex, inefficient, liable to bugs, and difficult to debug.
The simpler and more efficient MATLAB approach is to use indexing.
Thanks@Stephen. already read some documents from this link..thats so much informative.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Asked:

on 14 Dec 2021

Commented:

on 21 Dec 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!