Issue with step in the code. Require assistance - matlab

Good evening,
I have a code working just fine as follows:
r=1.6;
M=0.000207;
D=-0.0256;
kappa=0.5;
gamma=20;%\W\km
Pp=0.2;
L=462.5;
SQ=sqrt(-(0.5*D)^2 +M);
z=0:0.1:L;
A=kappa*SQ.*(z-L);
B=((sqrt(M)/r)+(D/2))/(SQ);
C=EA(B);
E=SQ*cot(A+C);
Pminus=E-(D/2);
Pplus=M./Pminus;
P0=Pplus+Pminus+D;
CST1=Pplus.*Pminus;
CST2=P0-Pplus-Pminus;
dP0dz=kappa.*P0.*(Pplus-Pminus);
figure
set(gca,'fontsize',18)
plot(z,Pplus*1000, 'b',z,Pminus*1000,'r',z,P0*1000,'k','Linewidth',4);
xlabel('z(m)')
ylabel('Power (mW)')
legend('P_+','P_-','P_0','D','M','r','Orientation','horizontal')
%str = sprintf('D = %.4f , M = %.9f, and r =%.3f ',D,M,r);
%title(str);
xlim([0 L])
N=gamma.*Pp;%gamma Pp with units \km
y1=0.5*kappa.*1000*(Pplus+Pminus);
y2 =y1./N;
figure
hax=axes;
[ax,p1,p2] = plotyy(z,y1,z,y2,'plot','plot');
set(ax,{'ycolor'},{'k';'k'})
set(ax,{'fontsize'},{18;18})
set(p1,'linewidth',4)% to change the first line
set(p2,'linewidth',4) % to change the second line
set(p1,'Color','b')% to change the first line
set(p2,'Color','b') % to change the second line
%str = sprintf('D = %.6f ',D);
%title(str);
ylabel(ax(1),'K_{SBS}(km^{-1})','fontsize',18,...
'Color','k') % label left y-axis
ylabel(ax(2),'K_{SBS}( \gamma P )','fontsize',18,...
'Color','k') % label right y-axis
xlabel(ax(2),'z(m)','fontsize',18,...
'Color','k')% label x-axis
set(ax(1),'XLim',[0 L])
set(ax(2),'XLim',[0 L])
set(ax(1),'YLim',[min(y1) max(y1)])
set(ax(2),'YLim',[min(y2) max(y2)])
zz1=(max(y1)-min(y1))./4;
zz2=(max(y2)-min(y2))./4;
set(ax(1),'YTick',min(y1):zz1: max(y1) )
set(ax(2),'YTick',min(y2):zz2: max(y2) )
legend('K_{SBS}(km^{-1})')
% figure
% set(gca,'fontsize',18)
% plot(z,1000*dP0dz,'Linewidth',4);
% xlabel('z(m)')
% ylabel('dP_0/dz')
% xlim([0 L])
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N=gamma.*Pp;%\km
lamdazero=1550;
lamdapump=linspace(1535,1560,100000);
lamdasignal=1545;
beta3=0.06;
beta4=-1*10^-4;
c=2*pi*299792458/1000;
A0=(1./lamdapump) -(1./lamdazero);
B0=(1./lamdapump) -(1./lamdasignal);
Third0=beta3.*(c.^3).*A0.*(B0.^2);
Fourth0=beta4.*(1./2).*c.^4.*(A0.^2).*(B0.^2);
Fourorder=c.^4.*beta4.*(1/12).*(B0).^4;
deltabeta=Third0+Fourth0+Fourorder;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%NO SBS
total0=deltabeta+(2.*N);
g0=((sqrt((N.^2)-(total0./2).^2)));
Gain0=((((N./(g0)).^2).*(sinh(g0.*L/1000)).^2));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
g0=1.1*10^-11;
Aeff=1.1*10^-11;
PSBS=0.016;
SBS=(g0.*PSBS.*1000)./Aeff;
totalsbs=deltabeta+(2.*N)-SBS/2;
gsbs=((sqrt((N.^2)-(totalsbs./2).^2)));
Gainsbs=((((N./(gsbs)).^2).*(sinh(gsbs.*L/1000)).^2));
n=35;
first=round(1*(L/n));
step=round(L/n);
last=L;
for jj=1:length(deltabeta)
M = eye(2);
for ii = first:step:last;
tsv=deltabeta(jj)+(2*N)-(y1(z==(ii-round(0.5*(L/n)))));
gsv=((sqrt((N.^2)-(tsv./2).^2)));
F1=1i*tsv;
F2=2*gsv;
F3=F1./F2;
F4=1i*(N./gsv);
M1=cosh(gsv.*(step/1000))+(F3.*sinh(gsv.*(step/1000)));
M2=F4.*sinh(gsv.*(step/1000));
M3=-F4.*sinh(gsv.*(step/1000));
M4=cosh(gsv.*(step/1000))-(F3.*sinh(gsv.*(step/1000)));
M=M*[M1 M2;M3 M4];
TeRm=P0(z==ii)/P0(z==(ii-step));
M=[sqrt(TeRm) 0;0 1]*M;
end
Gv(1,jj)=M(1,1).*conj(M(1,1));
end
FigHandle = figure;
figureh=plot(lamdapump,10*log10(1+Gain0),'b',lamdapump,10*log10(1+Gainsbs),'g',lamdapump,10*log10(Gv),'r','Linewidth',5);
hold on
xlabel('\lambda_P (nm)','Fontsize',18)
ylabel('Signal Gain (dB)','Fontsize',18)
legend('Without SBS',' With SBS ideal ',' With SBS actual')
% title('Gain curves with SBS','fontsize',18)
set(gca,'XTick',1536:3:1560)
set(gca,'fontsize',18)
ylim([0 12])
hold off
My issue is that when changing the parameter L into a value smaller than one like with some changes in the parameters:
r=1.8;
M=0.80322;
D=-1.69;
kappa=700/4.6;
gamma=5285;%\W\km
Pp=7.6;
L=0.045333;
SQ=sqrt(-(0.5*D)^2 +M);
z=0:0.00001:L;
A=kappa*SQ.*(z-L);
B=((sqrt(M)/r)+(D/2))/(SQ);
C=EA(B);
E=SQ*cot(A+C);
Pminus=E-(D/2);
Pplus=M./Pminus;
P0=Pplus+Pminus+D;
CST1=Pplus.*Pminus;
CST2=P0-Pplus-Pminus;
dP0dz=kappa.*P0.*(Pplus-Pminus);
figure
set(gca,'fontsize',18)
plot(z,Pplus*1000, 'b',z,Pminus*1000,'r',z,P0*1000,'k','Linewidth',4);
xlabel('z(m)')
ylabel('Power (mW)')
legend('P_+','P_-','P_0','D','M','r','Orientation','horizontal')
%str = sprintf('D = %.4f , M = %.9f, and r =%.3f ',D,M,r);
%title(str);
xlim([0 L])
N=gamma.*Pp;%gamma Pp with units \km
y1=0.5*kappa.*1000*(Pplus+Pminus);
y2 =y1./N;
figure
hax=axes;
[ax,p1,p2] = plotyy(z,y1,z,y2,'plot','plot');
set(ax,{'ycolor'},{'k';'k'})
set(ax,{'fontsize'},{18;18})
set(p1,'linewidth',4)% to change the first line
set(p2,'linewidth',4) % to change the second line
set(p1,'Color','b')% to change the first line
set(p2,'Color','b') % to change the second line
%str = sprintf('D = %.6f ',D);
%title(str);
ylabel(ax(1),'K_{SBS}(km^{-1})','fontsize',18,...
'Color','k') % label left y-axis
ylabel(ax(2),'K_{SBS}( \gamma P )','fontsize',18,...
'Color','k') % label right y-axis
xlabel(ax(2),'z(m)','fontsize',18,...
'Color','k')% label x-axis
set(ax(1),'XLim',[0 L])
set(ax(2),'XLim',[0 L])
set(ax(1),'YLim',[min(y1) max(y1)])
set(ax(2),'YLim',[min(y2) max(y2)])
zz1=(max(y1)-min(y1))./4;
zz2=(max(y2)-min(y2))./4;
set(ax(1),'YTick',min(y1):zz1: max(y1) )
set(ax(2),'YTick',min(y2):zz2: max(y2) )
legend('K_{SBS}(km^{-1})')
% figure
% set(gca,'fontsize',18)
% plot(z,1000*dP0dz,'Linewidth',4);
% xlabel('z(m)')
% ylabel('dP_0/dz')
% xlim([0 L])
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
N=gamma.*Pp;%\km
lamdazero=1556;
lamdapump=linspace(1300,1800,100000);
lamdasignal=1536;
beta3=1.26;
beta4=0;
c=2*pi*299792458/1000;
A0=(1./lamdapump) -(1./lamdazero);
B0=(1./lamdapump) -(1./lamdasignal);
Third0=beta3.*(c.^3).*A0.*(B0.^2);
Fourth0=beta4.*(1./2).*c.^4.*(A0.^2).*(B0.^2);
Fourorder=c.^4.*beta4.*(1/12).*(B0).^4;
deltabeta=Third0+Fourth0+Fourorder;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%NO SBS
total0=deltabeta+(2.*N);
g0=((sqrt((N.^2)-(total0./2).^2)));
Gain0=((((N./(g0)).^2).*(sinh(g0.*L/1000)).^2));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
g0=0.7*10^-9;
Aeff=2.3*10^-12;
PSBS=Pp*4/57.5;
SBS=(g0.*PSBS.*1000)./Aeff;
totalsbs=deltabeta+(2.*N)-SBS/2;
gsbs=((sqrt((N.^2)-(totalsbs./2).^2)));
Gainsbs=((((N./(gsbs)).^2).*(sinh(gsbs.*L/1000)).^2));
n=35;
first=(1*(L/n));
step=(L/n);
last=L;
for jj=1:length(deltabeta)
M = eye(2);
for ii = first:step:last;
tsv=deltabeta(jj)+(2*N)-(y1(z==(ii-(0.5*(L/n)))));
gsv=((sqrt((N.^2)-(tsv./2).^2)));
F1=1i*tsv;
F2=2*gsv;
F3=F1./F2;
F4=1i*(N./gsv);
M1=cosh(gsv.*(step/1000))+(F3.*sinh(gsv.*(step/1000)));
M2=F4.*sinh(gsv.*(step/1000));
M3=-F4.*sinh(gsv.*(step/1000));
M4=cosh(gsv.*(step/1000))-(F3.*sinh(gsv.*(step/1000)));
M=M*[M1 M2;M3 M4];
TeRm=P0(z==ii)/P0(z==(ii-step));
M=[sqrt(TeRm) 0;0 1]*M;
end
Gv(1,jj)=M(1,1).*conj(M(1,1));
end
FigHandle = figure;
figureh=plot(lamdapump,10*log10(1+Gain0),'b',lamdapump,10*log10(1+Gainsbs),'g',lamdapump,10*log10(Gv),'r','Linewidth',5);
hold on
xlabel('\lambda_P (nm)','Fontsize',18)
ylabel('Signal Gain (dB)','Fontsize',18)
legend('Without SBS',' With SBS ideal ',' With SBS actual')
title('Gain curves with SBS','fontsize',18)
%set(gca,'XTick',1300:10:1800)
set(gca,'fontsize',18)
%ylim([0 12])
hold off
The code does not work. The reason in my opinion is that when using the function round it rounds to zero. If i remove the round function it no longer works. Any thoughts on how can I make my code work again?
Is there any chance to work around round function because i need to take n steps. However I simply can not do so because L is very small. I need the value of L to stay small.
My apologizes for the long codes and explanations. Be free to ask !]1

Related

How to avoid "surf error X, Y, Z, and C cannot be complex"

I've already tried to change x, y, z but it still does not work.
The error said that there is problem in
(line 72) surf(t/sigma,x*sqrt(P/sigma)/sqrt(phi),abs(Y(:,1:M)));
My full code is:
clc
M = input ('M = ');
N = input ('N = ');
epsilon = input ('epsilon = ');
dx = 0.01;
dt = 2.5000e-005;
x0 = -N/2*dx;
r = dt/dx^2;
D = 0.1*1.6e5;
mass=5.1e-13;
a=3e-2;
k=24;
K=8;
l=340;
lambda=10*1;
q=2*pi/lambda;
h=4;
sigma=1e10;
tau=0;
e2=0.001;
wg = 2*a*sqrt(D/mass);
w = sqrt(wg+(2*k*(1-cos(q*1))+2*K*(cos(q*l*h)+1))/mass);
Vg=(1*(k*sin(1*q)-K*h*sin(l*q*h))/(mass*w));
alfa = (-3*a)/sqrt(2);
beta = 7*a^2/3;
miu=-2*alfa/(1+4*K/ (mass*wg.^2));
delta=(wg.^2)*alfa/(4*w^2+2*k*(cos(2*q*1-1)/mass-2*K*(cos(2*h*q*l)+1)/mass-wg^2));
P=(((1^2)*(k*cos(1*q)-K*(h^2)*cos(l*q*h))/mass)-Vg^2)/(2*w);
Q=(-wg.^2*(2*alfa*(miu+delta)+3*beta)/(2*w));
phi= 0.0005;
psi=0.03;
F=zeros(N,M);
Y=zeros(N,M);
for n=1:N
x(n,1)=x0+(n-1)*dx;
F(n,1)=((sqrt(2)/psi)*sech(x(n,1))/sqrt(phi));
end
%running program
for m=1:M
for n=2:N-1
if n==2
F(n-1,m)=3*F(n,m)-3*F(n+1,m)+F(n+2,m);
end
if n==N-1
F(n+1,m)=3*F(n,m)-3*F(n-1,m)+F(n-2,m);
end
if m==1
F(n,m+1)=1i*((phi^2*r*(F(n+1,m)-2*(F(n,m))+F(n-1,m))+(psi^2*dt*(conj(F(n,m))*(F(n,m)^2))+F(n,m))));
else
F(n,m+1)=2*1i*((phi^2*r*(F(n+1,m)-2*(F(n,m))+F(n-1,m))+(psi^2*dt*(conj(F(n,m))*(F(n,m)^2))+F(n,m-1))));
end
t(m) = (m-1)*dt;
theta(n,m)=(n*q*l)-(w*t(m)/e2);
Y(n,m) = ((e2*(psi*F(n,m)/(sqrt(Q/sigma))))*(2*(cos((sigma*tau)+theta(n,m)))))+((e2^2*((psi*F(n,m)/(sqrt(Q/sigma)))^2))*(miu+(2*delta*(cos(2*((sigma*tau)+theta(n,m)))))));
end
%grafik 3 dimensi
figure
surf(t/sigma,x*sqrt(P/sigma)/sqrt(phi),abs(Y(:,1:M)));
view(0,90);
colorbar
shading interp
xlabel ('T');
ylabel ('x');
zlabel ('y');
%grafik hubungan Y terhadap x
figure
plot((x*sqrt(P/sigma)),abs(Y(:,0)));
xlabel ('x(pm)');
ylabel ('Y(pm)');
figure
plot((x*sqrt(P/sigma)),abs(Y(:,M)));
xlabel ('x(pm)');
ylabel ('Y(pm)');
It makes the figure not shown. Please what should I do?
Taking Real Components and MATLAB Indexing
To avoid errors referring to imaginary components add the real() function to only use the real components while surface plotting:
surf(t/sigma,real(x*sqrt(P/sigma)/sqrt(phi)),abs(Y(:,1:M)));
MATLAB indexing begins at "1" rather than the "0" that many languages use. Changing abs(Y(:,0)) to abs(Y(:,1)) may sole the problem.
plot((real(x*sqrt(P/sigma))),abs(Y(:,1)));
Adding additional end to close the nested for-loop.
for m=1:M
for n=2:N-1
if n==2
F(n-1,m)=3*F(n,m)-3*F(n+1,m)+F(n+2,m);
end
if n==N-1
F(n+1,m)=3*F(n,m)-3*F(n-1,m)+F(n-2,m);
end
if m==1
F(n,m+1)=1i*((phi^2*r*(F(n+1,m)-2*(F(n,m))+F(n-1,m))+(psi^2*dt*(conj(F(n,m))*(F(n,m)^2))+F(n,m))));
else
F(n,m+1)=2*1i*((phi^2*r*(F(n+1,m)-2*(F(n,m))+F(n-1,m))+(psi^2*dt*(conj(F(n,m))*(F(n,m)^2))+F(n,m-1))));
end
t(m) = (m-1)*dt;
theta(n,m)=(n*q*l)-(w*t(m)/e2);
Y(n,m) = ((e2*(psi*F(n,m)/(sqrt(Q/sigma))))*(2*(cos((sigma*tau)+theta(n,m)))))+((e2^2*((psi*F(n,m)/(sqrt(Q/sigma)))^2))*(miu+(2*delta*(cos(2*((sigma*tau)+theta(n,m)))))));
end
end

Translate Braille into matlab (after filtering)

As shown in the picture above, the Braille X,Y locations are complete. However, I don't know how to divide the zones in 3x2 rows to match the average size of the objects. Please let me know.
If there are any other coding methods other than Matlab, please recommend them.
centroids =
1.0e+03 *
0.1515 0.1635
0.2419 0.0806
0.3619 0.2506
0.3624 0.0804
0.3640 0.1652
0.4492 0.2505
0.4503 0.1661
0.4518 0.0822
0.5705 0.1669
0.5748 0.0806
0.6598 0.2502
0.9878 0.0809
1.0748 0.0796
1.0768 0.1646
1.1979 0.1630
1.2830 0.2476
1.2855 0.0772
1.4911 0.1603
1.6120 0.0774
1.6141 0.1608
1.7034 0.2460
1.8217 0.0756
1.8272 0.2453
1.9147 0.1622
2.0306 0.1578
2.1241 0.2462
This is my coordinates. However, the coordinates are only about this picture, and the values of the coordinates change when you insert another picture.
```matlab code
I = imread('sample1.png'); % 이미지 불러오기
H = imgaussfilt(I, 2); % 흐림 필터
T = rgb2gray(H); % 회색조 필터
Q = imadjust(T,[0.5 0.8],[]); % 명암 조절
BW = imbinarize(Q); % 흑백화 필터
bw2 = imcomplement(BW); % 흑백 반전 필터
BW2 = bwareaopen(bw2, 800); % 800픽셀 이하 객체 제거
s = regionprops(BW2,'centroid'); % 객체 중앙 좌표 찍기
centroids = cat(1,s.Centroid);
imshow(BW2)
hold on
plot(centroids(:,1),centroids(:,2),'ro')
hold off
```

Saving values in a vector inside a loop, and finding the specific loop at which a certain element is saved

I have a code that calculates the minimum distance between two line segments by discretizing t, and s between 0 and 1 with h. The code saves the distance for each value of s and t in a vector and the smallest value is picked out at the end.
I would like to find the corresponding t and s for which the minimum distance occurs. For example, if the minimum distance is located at index 3000 in the 'mindist' vector, which value of t and s does this correspond?
Thanks in advance!
/Arian
Edit: I provided the entire code with some comments aswell. I've changed it a bit and this seems to do the trick:
% Start and end points of line segments
P0=[-0.43256 -1.6656 0.12533];
P1=[0.28768 -1.1465 1.1909];
Q0=[1.1892 -0.037633 0.32729];
Q1=[0.17464 -0.18671 0.72579];
% Direction vectors
u=P1-P0;
v=Q1-Q0;
w0=P0-Q0;
% Dot products
a=dot(u,u);
b=dot(u,v);
c=dot(v,v);
d=dot(u,w0);
e=dot(v,w0);
F=a*c-b^2;
h=0.01;
t=0:h:1;
s=0:h:1;
mindist=[];
for i=1:length(t)
for j=1:length(s)
if F==0
t(i)=e/c;
mindist(i,j)=norm((P0+s(j)*u)-(Q0+t(i)*v));
else
mindist(i,j)=norm((P0+s(j)*u)-(Q0+t(i)*v));
end
end
end
[minval,loc]=min(mindist(:));
[i, j] = ind2sub(size(mindist), loc);
minval=norm((P0+s(j)*u)-(Q0+t(i)*v))
minval =
1.0710
you do not need nested cycles, thanks to Matlab's pdist2() function. Here is an example:
h=0.01;
% Random vectors
P0 = [0;0];
Q0 = [0;2];
u = [1;0];
v = [0.707 ; -0.707];
t = 0:h:1; % Do not really need "s"
U = P0+t.*u;
V = Q0+t.*v;
% The lines above work in Matlab 2016b and beyond. For older versions use:
% U = P0 + [t.*u(1) ; t.*u(2)];
% V = Q0 + [t.*v(1) ; t.*v(2)];
d = pdist2(U',V'); % Pairwise distance between two sets of observations
[min_dist , position] = min2(d);
% Plot problem and result
figure
plot([P0(1) , P0(1)+u(1)] , [P0(2) , P0(1)+u(2)] , 'r-')
hold on; axis equal;
plot([Q0(1) , Q0(1)+v(1)] , [Q0(2) , Q0(2)+v(2)] , 'g-')
plot([U(1,position(1)) , V(1,position(2))] , [U(2,position(1)) V(2,position(2))] , 'b-')
title(['Minimal distance: ' num2str(min_dist) '. t=' num2str(t(position(1))) '. s = ' num2str(t(position(2)))])
legend('Vector 1' , 'Vector 2' , 'Shortest distance')

Out of memory when restart a code

I made a matlab code including some symbolic functions
First I run this code, it gives me a result.
But trying to run the same code again, Out of memory message comes up.
Does anybody have an idea to solve this problem?
Below is my code.
clc;
clear;
tic;
rng('shuffle');
p=2; % AR order
yr=normrnd(0,1,1000,1);
T=max(size(yr));
for k=25:35;
intnum=k/10;
fore=100;
int=((max(yr)-min(yr))/intnum);
fin=T-fore;
% Initial setting matrix
y_T1=zeros(fore,1);
y_fore_w=zeros(fore,1); y_diff_w=zeros(fore,1);
y_fore_o=zeros(fore,1);y_diff_o=zeros(fore,1);
y_fore_f=zeros(fore,1);y_diff_f=zeros(fore,1);
y_fore_wl=zeros(fore,1);y_diff_wl=zeros(fore,1);
y_fore_m=zeros(fore,1);y_diff_m=zeros(fore,1);
y_gap=zeros(fore,1);
for e=fin:T-1 ;
y_1=yr(p+1:e);x_1=yr(p:e-1);x_2=yr(p-1:e-2);
A=[y_1 x_1 x_2];
st=1;
ye=yr(st:e);
coordinate = zeros(length(y_1), 3); % Giving new indices to A
y_1_diff=max(y_1)-min(y_1);x_1_diff=max(x_1)-min(x_1);x_2_diff=max(x_2)-min(x_2);
y_1_int=y_1_diff/int;x_1_int=x_1_diff/int;x_2_int=x_2_diff/int;
y_1_int_num=round(y_1_int);x_1_int_num=round(x_1_int);x_2_int_num=round(x_2_int);
for i=1:y_1_int_num;
coordinate(A(:,1) >= (i-1)*int+min(A(:,1)) & A(:,1) < i*int+min(A(:,1)), 1) = i ; % Terrific idea for some conditions in ROW
end
for i=1:x_1_int_num;
coordinate(A(:,2) >= (i-1)*int+min(A(:,2)) & A(:,2) < i*int+min(A(:,2)), 2) = i ; % Terrific idea for some conditions in ROW
end
for i=1:x_2_int_num;
coordinate(A(:,3) >= (i-1)*int+min(A(:,3)) & A(:,3) < i*int+min(A(:,3)), 3) = i; % Terrific idea for some conditions in ROW
end
sz=[y_1_int_num x_1_int_num x_2_int_num];
nucu=max(sz)^(p+1);
y_int_sub_num=zeros(nucu,1); % Number of frequency
yfunc=cell(nucu,1); % Cell of functions
c=1:max(sz);
C=combvec(c,c,c)'; % Generate a reference matrix to coordinate
d=sortrows(C);
syms c b1 b2;
for i=1:nucu;
a=ismember(coordinate, d(i,:), 'rows');
s=sum(a);
y_int_sub_num(i)=s;
B=A(a,:);
func=symfun((B(:,1)-c-b1*B(:,2)-b2*B(:,3)).^2, [c,b1,b2]);
yfunc1=sum(func);
yfunc{i}=yfunc1*y_int_sub_num(i);
clear func; clear yfunc1;
end
yfuncs=symfun(sym('f(c,b1,b2)'),[c,b1,b2]);
for j=1:nucu;
yfuncs=yfuncs+yfunc{j};
end
yfuncs= yfuncs-'f(c,b1,b2)';
y_trans = matlabFunction(yfuncs,'Vars',{[c;b1;b2]});
% WLLS
options = optimset('Algorithm','Interior-point',...
'TolFun',1e-8, 'MaxFunEvals',1000000,'MaxIter',1000000); % Set option
[b_w,fval] = fminsearch(y_trans, [0;0;0], options);
% OLS
c=ones(T-p,1);y_c=zeros(T-p,4);
y_c(:,1)=yr(p+1:T);y_c(:,2)=c;y_c(:,3)=yr(2:end-(p-1));y_c(:,4)=yr(1:end-2);
[b_0,bint_0,e_0,rint,stats] = regress(y_c(:,1), y_c(:,2:4));
% WLS
e_0_w=e_0.^2/sum(e_0.^2); %normalization required for Matlab
[bw,se_bw] = lscov(y_c(:,1), y_c(:,2:4), e_0_w);
% FGLS_iterated
[bf, Sigma] = lscov(y_c(:,1), y_c(:,2:4), e_0_w);
% [bf, Sigma]=fglsi(y_c(:,1), y_c(:,3), y_c(:,4), y_c(:,3));
% MLE
[b_m, b_mm, mu, sig] = regress(y_c(:,1), y_c(:,2:4)); % Since error, OL
% Foracast and Differences
n=e-(fin-1);
y_T1(n)=yr(e+1);
y_fore_w(n)=b_w(1)+b_w(2)*ye(end)+b_w(3)*ye(end-1);y_diff_w(n)=y_T1(n)-y_fore_w(n);
y_fore_o(n)=b_0(1)+b_0(2)*ye(end)+b_0(3)*ye(end-1);y_diff_o(n)=y_T1(n)-y_fore_o(n);
y_fore_wl(n)=bw(1)+bw(2)*ye(end)+bw(3)*ye(end-1);;y_diff_wl(n)=y_T1(n)-y_fore_wl(n);
y_fore_f(n)=bf(1)+bf(2)*ye(end)+bf(3)*ye(end-1);;y_diff_f(n)=y_T1(n)-y_fore_f(n);
y_fore_m(n)=b_m(1)+b_m(2)*ye(end)+b_m(3)*ye(end-1);;y_diff_m(n)=y_T1(n)-y_fore_m(n);
y_gap(n)=abs(y_diff_w(n))-abs(y_diff_o(n));ygap(n)=(y_gap(n)<=0);
end
toc
a=1;filename = [ 'comp', num2str(a), '.mat' ];
save(filename);
if mean(y_diff_w.^2) <=mean(y_diff_o.^2)
[int mean(y_diff_w.^2)]
beep;
end
z1=zeros(y_1_int+1,1);
for i=1:y_1_int+1;
z=(yr>=(i-1)*int+min(yr) & yr<i*int+min(yr));
z1(i)=sum(z);
end
z1
end
sort(yr)
[max(yr) min(yr)]

ode45 solving of diff.equation with further fitting to exp.results

I am building a code to solve a diff. equation:
function dy = KIN1PARM(t,y,k)
%
% version : first order reaction
% A --> B
% dA/dt = -k*A
% integrated form A = A0*exp(-k*t)
%
dy = -k.*y;
end
I want this equation to be solved numerically and the results (y as a function of t, and k) to be used for minimization with respect to the experimental values to get the optimal value of parameter k.
function SSE = SSE_minimization_1parm(tspan_inp,val_exp,k_inp,y0_inp)
f = #(Tt,Ty) KIN1PARM(Tt,Ty,k_inp); %function to call ode45
size_limit = length(y0_inp);
options = odeset('NonNegative',1:size_limit,'RelTol',1e-4,'AbsTol', 1e-4);
[ts,val_theo] = ode45(f, tspan_inp, y0_inp,options); %Cexp is the state variable predicted by the model
err = val_exp - val_theo;
SSE = sum(err.^2); %sum squared-error
The main code to plot the experimental and calculated data is:
% Analyzing first order kinetics
clear all; clc;
figure_title = 'Experimental Data';
label_abscissa = 'Time [s]';
label_ordinatus = 'Concentration [mol/L]';
%
abscissa = [ 0;
240;
480;
720;
960;
1140;
1380;
1620;
1800;
2040;
2220;
2460;
2700;
2940];
ordinatus = [ 0;
19.6;
36.7;
49.0;
57.1;
64.5;
71.4;
75.2;
78.7;
81.3;
83.3;
85.5;
87.0;
87.7];
%
title_string = [' Time [s]', ' | ', ' Complex [mol/L] ', ' '];
disp(title_string);
for i=1:length(abscissa)
report_raw_data{i} = sprintf('%1.3E\t',abscissa(i),ordinatus(i));
disp([report_raw_data{i}]);
end;
%---------------------/plotting dot data/-------------------------------------
%
f = figure('Position', [100 100 700 500]);
title(figure_title,'FontName','arial','FontWeight','bold', 'FontSize', 12);
xlabel(label_abscissa, 'FontSize', 12);
ylabel(label_ordinatus, 'FontSize', 12);
%
grid on; hold on;
%
marker_style = { 's'};
%
plot(abscissa,ordinatus, marker_style{1},...
'MarkerFaceColor', 'black',...
'MarkerEdgeColor', 'black',...
'MarkerSize',4);
%---------------------/Analyzing/----------------------------------------
%
options = optimset('Display','iter','TolFun',1e-4,'TolX',1e-4);
%
CPUtime0 = cputime;
Time_M = abscissa;
Concentration_M = ordinatus;
tspan = Time_M;
y0 = 0;
k0 = rand(1);
[k, fval, exitflag, output] = fminsearch(#(k) SSE_minimization_1parm(tspan,Concentration_M,k,y0),k0,options);
CPUtimex = cputime;
CPUtime_delay = CPUtimex - CPUtime0;
%
%---------------------/plotting calculated data/-------------------------------------
%
xupperlimit = Time_M(length(Time_M));
xval = ([0:1:xupperlimit])';
%
yvector = data4plot_1parm(xval,k,y0);
plot(xval,yvector, 'r');
hold on;
%---------------------/printing calculated data/-------------------------------------
%
disp('RESULTS:');
disp(['CPU time: ',sprintf('%0.5f\t',CPUtime_delay),' sec']);
disp(['k: ',sprintf('%1.3E\t',k')]);
disp(['fval: ',sprintf('%1.3E\t',fval)]);
disp(['exitflag: ',sprintf('%1.3E\t',exitflag)]);
disp(output);
disp(['Output: ',output.message]);
The corresponding function, which uses the optimized parameter k to yield the calculated y = f(t) data :
function val = data4plot_1parm(tspan_inp,k_inp,y0_inp)
f = #(Tt,Ty) KIN1PARM(Tt,Ty,k_inp);
size_limit = length(y0_inp);
options = odeset('NonNegative',1:size_limit,'RelTol',1e-4,'AbsTol',1e-4);
[ts,val_theo] = ode45(f, tspan_inp, y0_inp, options);
The code runs optimization cycles always giving different values of parameter k, which are different from the value calculated using ln(y) vs t (should be around 7.0e-4 for that series of exp. data).
Looking at the outcome of the ode solver (SSE_minimization_1parm => val_theo) I found that the ode function gives me a vector of zeroes.
Could someone help me , please, to figure out what's going with the ode solver ?
Thanks much in advance !
So here comes the best which I can get right now. For my way I tread ordinatus values as time and the abscissa values as measured quantity which you try to model. Also, you seem to have set alot of options for the solver, which I all omitted. First comes your proposed solution using ode45(), but with a non-zero y0 = 100, which I just "guessed" from looking at the data (in a semilogarithmic plot).
function main
abscissa = [0;
240;
480;
720;
960;
1140;
1380;
1620;
1800;
2040;
2220;
2460;
2700;
2940];
ordinatus = [ 0;
19.6;
36.7;
49.0;
57.1;
64.5;
71.4;
75.2;
78.7;
81.3;
83.3;
85.5;
87.0;
87.7];
tspan = [min(ordinatus), max(ordinatus)]; % // assuming ordinatus is time
y0 = 100; % // <---- Probably the most important parameter to guess
k0 = -0.1; % // <--- second most important parameter to guess (negative for growth)
k_opt = fminsearch(#minimize, k0) % // optimization only over k
% nested minimization function
function e = minimize(k)
sol = ode45(#KIN1PARM, tspan, y0, [], k);
y_hat = deval(sol, ordinatus); % // evaluate solution at given times
e = sum((y_hat' - abscissa).^2); % // compute squarederror
end
% // plot with optimal parameter
[T,Y] = ode45(#KIN1PARM, tspan, y0, [], k_opt);
figure
plot(ordinatus, abscissa,'ko', 'markersize',10,'markerfacecolor','black')
hold on
plot(T,Y, 'r--', 'linewidth', 2)
% // Another attempt with fminsearch and the integral form
t = ordinatus;
t_fit = linspace(min(ordinatus), max(ordinatus))
y = abscissa;
% create model function with parameters A0 = p(1) and k = p(2)
model = #(p, t) p(1)*exp(-p(2)*t);
e = #(p) sum((y - model(p, t)).^2); % minimize squared errors
p0 = [100, -0.1]; % an initial guess (positive A0 and probably negative k for exp. growth)
p_fit = fminsearch(e, p0); % Optimize
% Add to plot
plot(t_fit, model(p_fit, t_fit), 'b-', 'linewidth', 2)
legend('location', 'best', 'data', 'ode45 with fixed y0', ...
sprintf ('integral form: %5.1f*exp(-%.4f)', p_fit))
end
function dy = KIN1PARM(t,y,k)
%
% version : first order reaction
% A --> B
% dA/dt = -k*A
% integrated form A = A0*exp(-k*t)
%
dy = -k.*y;
end
The result can be seen below. Quit surprisingly to me, the initial guess of y0 = 100 fits quite well with the optimal A0 found. The result can be seen below: