Is it possible to vectorize a function script in matlab? - 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.

Related

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!

Last elseif statement does not execute

My last elseif statement does not execute even if the conditions are met:
Currency_Exchanage != 'Select...' and all other variables (ETF_Exchanage, Index_Exchanage and Stock_Exchanage) = 'Select...'
Here is the section of code that I am concerned about:
if (strcmp(ETF_Exchanage,'Select...') == 1) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1)
if db == 1 && uni == 1
tickers = gnr_bloomberg; % Analsise Bloomberg natural resources
nrm=1;
elseif db == 1 && uni == 2
tickers = all_bloomberg; % Analsise Bloomberg all
nrm=1;
elseif db == 2 && uni == 1
tickers = gnr_yahoo; % Analsise Yahoo natural resources
nrm=1;
elseif db == 2 && uni == 2
tickers = all_yahoo; % Analsise Yahoo all
nrm=1;
end
else
%Yahoo inputs
if (strcmp(ETF_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from ETF
tickers = ETF_Yahoo(:,1);
Exchanges = ETF_Yahoo(:,2);
Exchange = ETF_Exchanage;
db=2; %Yahoo Selection
elseif (strcmp(Index_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(ETF_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from Index
tickers = Index_Yahoo(:,1);
Exchanges = Index_Yahoo(:,2);
Exchange = Index_Exchanage;
db=2;
elseif (strcmp(Stock_Exchanage,'Select...') == 0) && (strcmp(ETF_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from Stock
tickers = Stock_Yahoo(:,1);
Exchanges = Stock_Yahoo(:,2);
Exchange = Stock_Exchanage;
db=2;
elseif (strcmp(Currency_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(ETF_Exchanage,'Select...') == 1); %Choose exhanges from Currency
tickers = Currency_Yahoo(:,1);
Exchanges = Currency_Yahoo(:,2);
Exchange = Currency_Exchanage;
db=2;
else
msg = 'Error occurred.\Only one Yahoo input menue must be used!';
error(msg)
end
end
Any Help would be much appropriated, I can't see where I'm going wrong here. I am using Matlab 2013a.
Put a breakpoint at the elseif statement in question and then check in the command window what your condition evaluates to.
If it does not evaluate like expected, check what the individual terms evaluate to.
It is important to actually test what the conditions evaluate to in matlab, rather than only visually comparing the string values.
Usually by that point you should get a rough idea what is wrong.
However in your case we can't do these steps for you because something is off. Your code condensed to the more reasonable minimal example
if 1 && 1 && 1...
1;
disp('I was here')
end
does not even execute in R2014a since the interpreter complains about '...' being an unexpected matlab expression.

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

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

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