how to store looping data in a single array or matrix? - matlab

i have a program with nested loop. i want all the values after each loop is completed, to
be stored in a single matrix A or array A.
display should be like
A= value1
value2
value3
etc...
where value1,value2,value3 are answers got at the end of each loop.
here is the program
load('b2.txt');
[M,N]=size(b2);
amp=[1.75,2,2.25,2.5,2.75,3,3.25,3.5,3.75,4];
%defining threshold
m=10501;
for i=10575:75:21000
a=b2(m:i,:);
time=b2(i,2)
t=40;
sum1=0;
sum2=0;
sum3=0;
sum4=0;
sum5=0;
sum6=0;
sum7=0;
sum8=0;
sum9=0;
sum10=0;
for R=1:75
if (a(R,3)>=t) && (a(R,3)<t+5)
sum1=sum1+a(R,1);
elseif (a(R,3)>=t+5) && (a(R,3)<t+10)
sum2=sum2+a(R,1);
elseif (a(R,3)>=t+10) && (a(R,3)<t+15)
sum3=sum3+a(R,1);
elseif (a(R,3)>=t+15) && (a(R,3)<t+20)
sum4=sum4+a(R,1);
elseif (a(R,3)>=t+20) && (a(R,3)<t+25)
sum5=sum5+a(R,1);
elseif (a(R,3)>=t+25) && (a(R,3)<t+30)
sum6=sum6+a(R,1);
elseif (a(R,3)>=t+30) && (a(R,3)<t+35)
sum7=sum7+a(R,1);
elseif (a(R,3)>=t+35) && (a(R,3)<t+40)
sum8=sum8+a(R,1);
elseif (a(R,3)>=t+40) && (a(R,3)<t+45)
sum9=sum9+a(R,1);
elseif (a(R,3)>=t+45) && (a(R,3)<t+50)
sum10=sum10+a(R,1);
end
cumulative_hits=[sum1,sum2,sum3,sum4,sum5,sum6,sum7,sum8,sum9,sum10];
for count=1:10
if cumulative_hits(1,count)<= 0
amplitude(1,count)= 0;
else
amplitude(1,count)=amp(1,count);
end
end
cumulative_hits(cumulative_hits==0)=[];
amplitude(amplitude==0)=[];
y=log10(cumulative_hits);
p=polyfit(amplitude,y,1);
f=polyval(p,amplitude);
end
%disp(p(1,1))
abs(p(1))
m=m+75;
end
need this asap.. thanks :)

You need to provide informations about which variable to store in the resulting array A, but just for your information:
You can always easily append values to it via:
A = [A; new_value];
which works either if new_value is a scalar or if it's a column-vector with identical number of elements like number of columns of A

Related

Is it possible to vectorize a function script in matlab?

If I have explicit function, I can vectorise it. How about if I have a function script? For example, if I have a script Fun.m such that Fun(x,y,z) gives a value and I want to compute x=[1,2,3] and y=[4,5] (i.e. (1,4), (1,5), (2,4), (2,5),(3,4), (3,5)) when z=10, are there any possible way to do it apart from using for-loop? Indeed, I may need to compute x,y for a long vector. I want to use bsxfun(#(x,y)Fun(x,y,10),[1,2,3],[4,5]') but it does not work. It says matrix dimension does not match.
Let me post the function Fun.m I have:
function density=HittingDensityOUlevel0(beta,r0,sigma,lambda,t0,i,p,MinOrMax)
g=zeros(1,i);
g(:,1)=-1.*MinOrMax.*2.*Integrand(r0,sigma,lambda,t0+p,t0,beta,r0);
for k=2:size(g,2)
Sum=0;
weight=zeros(1,k-1);
for m=1:k-1
R1=mod(k,2); Q1=floor(k./2);
R2=mod(m,2); Q2=floor(m./2);
if R1==0 && R2==1 && Q2<=Q1-1
weight(:,m)=4./3;
elseif R1==0 && R2==0 && Q2<=Q1-2
weight(:,m)=2./3;
elseif R1==1 && R2==1 && Q2<=Q1-2
weight(:,m)=4./3;
elseif R1==1 && R2==0 && Q2<=Q1-3 && Q1>=3
weight(:,m)=2./3;
elseif R1==1 && R2==0 && m==2*(Q1-1)
weight(:,m)=17./24;
elseif R1==1 && m==2*Q1-1 && Q1>=1
weight(:,m)=9./8;
elseif R1==1 && m==2*Q1 && Q1>=1
weight(:,m)=9./8;
end
end
TimeTicker=(t0+p):p:(t0+(k-1)*p);
Sum=Sum+2.*p.*sum(weight.*g(:,1:(k-1)).*arrayfun(#(t)Integrand(r0,sigma,lambda,t0+k.*p,t,beta,beta),TimeTicker));
g(:,k)=-1.*MinOrMax.*2.*...
Integrand(r0,sigma,lambda,t0+k.*p,t0,beta,r0)+MinOrMax.*Sum;
end
density=g(:,end);
function ret=Integrand(r0,sigma,lambda,t,tau,x,y)
ret=(lambda.*r0.*exp(-lambda.*t)./2+...
(x-r0.*exp(-lambda.*t))./2.*lambda.*cosh(lambda.*(tau-t))./sinh(lambda.*(tau-t))-...
(y-r0.*exp(-lambda.*tau))./2.*lambda./sinh(lambda.*(tau-t))).*...
...
(1./sqrt(pi.*sigma.^2./lambda.*(1-exp(-2.*lambda.*(t-tau))))).*...
...
(exp(-((x-r0.*exp(-lambda.*t)-exp(-lambda.*(t-tau)).*(y-r0.*exp(-lambda.*tau))).^2)./...
(sigma.^2./lambda.*(1-exp(-2.*lambda.*(t-tau))))));
I want to vectorize this Fun with (for example) t0=[1,2,3] and r0=[4,5]. But it does not work.
Use meshgrid to generate all possible pairs of inputs to your function.
[tt0,rr0] = meshgrid([1,2,3],[4,5])
so that tt0 = [1,2,3,1,2,3] and rr0 = [4,4,4,5,5,5]
Then pass that to bsxfun.

Matlab '&&' error

i need help about my code.
i cant figure out what im doing wrong.
here is the criterias i try to code (http://imgur.com/a/iU3bl)
and data file ( https://drive.google.com/file/d/0ByYia_19kCK4SXJMT2Q2ZHJHLVU/view?usp=sharing )
so i code this for solve it. but code always say 'NS' and i want "regime" data respect my table.
thx for all who try to help
data = xlsread('Data.xls');
PP=data(:,2);
TP=data(:,4);
BP=data(:,6);
region={ };
for i=1:length(data)
if PP(i)>=52 && 35>=TP(i);
region{i}='NF';
elseif 40<=PP(i) & PP(i)<52 & (TP(i)<=20);
region{i}='NS';
elseif (40>PP(i)) && (BP(i)>=45) && TP(i)<=20;
region{i}='SS';
elseif (PP(i)<=20) && (45<=BP(i)) && (TP(i)<=40);
region{i}='SS';
elseif (PP(i)<=20) && (40<=TP(i) && TP(i)<=52) ;
region{i}='TS';
elseif (PP(i) <=32) && (TP(i)>=52);
region{i}='NF';
else
region{i}='UN';
end
end
Your P_plunge is only between 40 & 52. It makes perfect sense that they all fall under NS.
Perhaps you might want to use column 1 for the data?
Also use && instead of &.
Good luck!

Creating a for-loop that stores values in a new variable

I'm quite new to Matlab so excuse me for the basic question.
I need to make a for-loop that repeats it's self 384 times.
So :
for i=1:384
I now need the for loop to check if 2 certain variables have the value 1 through 10, and then let them store this in a new variable with that value.
So:
if x==1
somevariable = 1
elseif x== 2
saomevariable = 2
..
..
..
elseif y = 1
someothervariable = 1
etc etc.
Is there a way to write this more efficient?
Thank you!
The first think you can do is:
if(x >= 1 && x <= 10)
somevariable=x;
end
if(y >= 1 && y <= 10)
someohtervariable=y;
end
If you could post more information about "x" and "y", perhaps your script can be further "improved".
Hope this helps.

using special characters in variable name Matlab

i have a function which returns a struct, and i want the return to have a meaningful names hence i wanted it to have names such as
sec.t<0.25
i.e t<0.25 being my variable and for this to return.
any help really appreciated.
function sec = sepfunc(intensdata)
lengthofdata=length(intensdata);
count1=0;
count_2=0;
count_3=0;
count_4=0;
count_5=0;
count_6=0;
count_7=0;
count_8=0;
for i= 1:lengthofdata %loop to seperate count number of data in 5 groups
if (intensdata(i,1)<0.025)
count1=count1+1;
elseif (intensdata(i,1)>=0.025 && intensdata(i,1)<0.05)
count_2=count_2+1;
elseif (0.05<=intensdata(i,1) && intensdata(i,1)<0.1)
count_3=count_3+1;
elseif (0.1<=intensdata(i,1) && intensdata(i,1)<0.125)
count_4=count_4+1;
elseif (0.125<=intensdata(i,1) && intensdata(i,1)<0.15)
count_5=count_5+1;
elseif (0.15<=intensdata(i,1) && intensdata(i,1)<0.175)
count_6=count_6+1;
elseif (0.175<=intensdata(i,1) && intensdata(i,1)<0.2)
count_7=count_7+1;
elseif (intensdata(i,1)>=0.2 )
count_8=count_8+1;
end
end
disp(count1);
disp(count_2);
disp(count_3);
disp(count_4);
disp(count_5);
disp(count_6);
disp(count_7);
disp(count_8);
j=1;
k=1;
l=1;
m=1;
n=1;
o=1;
p=1;
x=1;
low_sec=[count1];
lowmid_sec=[count_2];
middle_sec=[count_3];
upmid_sec=[count_4];
upper_sec=[count_5];
for i= 1:lengthofdata %to seperate original data into 5 different sub-groups.
if (intensdata(i,1)<0.05)
low_sec(j,1)=intensdata(i,1);
j=j+1 ;
elseif(0.05<=intensdata(i,1) && intensdata(i,1)<0.1)
lowmid_sec(k,1)=intensdata(i,1);
k=k+1;
elseif(0.1<=intensdata(i,1) && intensdata(i,1)<0.15)
middle_sec(m,1)=intensdata(i,1);
m=m+1;
elseif(0.15<=intensdata(i,1) && intensdata(i,1)<0.2)
upmid_sec(n,1)=intensdata(i,1);
n=n+1;
elseif( intensdata(i,1)>=0.2)
upper_sec(x,1)=intensdata(i,1);
x=x+1;
end
end
sec.low_sec = low_sec;
sec.lowmid_sec = lowmid_sec;
sec.middle_sec = middle_sec;
sec.upmid_sec = upmid_sec;
sec.upper_sec = upper_sec;
end
so i want to change low_sec to something like t<0.025 and 0.025
You cannot do this. Quoting from The MathWorks guidelines on variable names:
A valid variable name starts with a letter, followed by letters, digits, or underscores.
The < character is an operator. Most other programming languages don't allow this either. A suggestion would be to use the function name for the < operator: lt (help lt).
As you cannot put unusual characters in variable names I can see two ways to do this:
Descriptive: t_lt_0_025
Via a struct: s.name='t<0.025'

Using switch statement and while loop in conjunction

I am trying to complete the following task:
Create
a
script
that
will
repeatedly
create
a
random
integer
K
in
the
range
of
0
to
20
until
every
case
has
been
entered
at
least
once.
You
have
3
possible
cases.
Case
A
is
entered
when
the
range
of
the
random
integer
K
is
between
or
equal
to
0
and
7.
Case
B
is
entered
when
the
range
of
the
random
integer
K
is
between
or
equal
to
8
and
14.
Case
C
is
entered
when
the
range
of
the
random
integer
K
is
between
or
equal
to
15
and
20.
Rules:
When
a
case
is
entered
you
must
print
to
the
user
“Congratulations
you
entered
Case
(A,
B,
or
C)”.
You
can
only
enter
each
case
once.
If
the
program
attempts
to
enter
the
same
case
more
than
once,
you
must
print.
“Invalid,
that
case
has
already
been
entered”.
The
program
will
end
once
all
the
cases
have
been
entered
and
the
program
will
print
“Good
job,
you
have
entered
all
cases”.
If
the
program
attempts
to
enter
any
already
entered
cases
more
than
3
times
(3
total
times
not
just
for
one
specific
case),
the
program
will
end
and
print
to
the
user
“That
random
generator
wasn’t
random
enough”.
Here is the code I have so fa. It has taken me a couple hours to debug. Am I approaching this the wrong way????Please let me know.
K = round(rand*(20))
flag = 0;
counterA =0;
counterB=0;
counterC=0;
switch K
case {0,1,2,3,4,5,6,7}
fprintf('Congratulations you entered Case A\n')
flag = 1;
counterA = 1
case {8,9,10,11,12,13,14}
fprintf('Congratulations you entered Case B\n')
flag =2;
counterB = 1
case {15,16,17,18,19,20}
fprintf ('Congratulations you entered Case C\n')
flag = 3;
counterC = 1
end
while flag == 1 || flag == 2 || flag ==3
K = round(rand*(20))
if K >=0 && K<=7 && flag==1
disp ('Invalid, that case has already been entered')
counterA = counterA+1
elseif K >=8 && K<=14 && flag ==2
disp ('Invalid, that case has already been entered')
counterB=counterB+1
elseif K >=15 && K<=20 && flag==3
disp ('Invalid, that case has already been entered')
counterC =counterC+1
elseif K >=0 && K<=7 && flag ~=1
counterA =counterA+1
flag == 1;
if counterA==1&&counterB~=2 ||counterA==1&&counterC~=2
fprintf('COngrats guacamole A\n')
end
elseif K >=8 && K<=14 && flag ~=2
counterB=counterB+1
flag == 2;
if counterB ==1&&counterA~=2||counterB==1&&counterC~=2
fprintf('COngratsavacado B\n')
end
elseif K >=15 && K<=20 && flag~=3
counterC=counterC+1
flag == 3;
if counterC==1&&counterA~=2||counterC==1&&counterB~=2
fprintf ('Congratscilantro C\n')
end
end
if counterA==1 && counterB==1 && counterC==1
flag=100;
disp('DONE')
elseif counterA == 3|| counterB==3 || counterC==3
disp ('That random generator wasnt random enough')
flag =99;
elseif counterA==2||counterB==2||counterC==2
disp('Inval')
end
Some words about your code:
Don't use variable names like counterA,counterB,counterC, use a array with 3 elements instead. In this case: You need only a total limit, thus one variable is enough.
rand*20 generates random values between 0 and 20, but using round(rand*20) causes a lower probability for 0 and 20. Use randi if you need integers.
Use "Start indent" to format your code clean, it makes it easier to read.
This is not a full solution, the part with the 3 errors is missing. I think you will get this on your own.
caseNames={'A','B','C'};
caseEntered=[false,false,false];
%while there exist a case which is not entered and limit is not reached, continue
while ~all(caseEntered)
K = randi([0,20]);
switch K
case {0,1,2,3,4,5,6,7}
cs=1;
case {8,9,10,11,12,13,14}
cs=2;
case {15,16,17,18,19,20}
cs=3;
end
if caseEntered(cs)
%case has previously been entered, tdb
else
%case is entered frist time
fprintf('Congratulations you entered Case %s\n',caseNames{cs});
caseEntered(cs)=true;
end
end