Getting unexpected results while using ode45 - matlab
I am trying to solve a system of differential equations by writing code in Matlab. I am posting on this forum, hoping that someone might be able to help me in some way.
I have a system of 10 coupled differential equations. It is a vector-host epidemic model, which captures the transmission of a disease between human population and insect population. Since it is a simple system of differential equations, I am using solvers (ode45) for non-stiff problem type.
There are 10 differential equations, each representing 10 different state variables. There are two functions which have the same system of 10 coupled ODEs. One is called NoEffects_derivative_6_15_2012.m which contains the original system of ODEs. The other function is called OnlyLethal_derivative_6_15_2012.m which contains the same system of ODEs with an increased withdrawal rate starting at time, gamma=32 %days and that withdrawal rate decays exponentially with time.
I use ode45 to solve both the systems, using the same initial conditions. Time vector is also the same for both systems, going from t0 to tfinal. The vector tspan contains the time values going from t0 to tfinal, each with a increment of 0.25 days, making a total of 157 time values.
The solution values are stored in matrices ye0 and yeL. Both these matrices contain 157 rows and 10 columns (for the 10 state variable values). When I compare the value of the 10th state variable, for the time=tfinal, in the matrix ye0 and yeL by plotting the difference, I find it to be becoming negative for some time values. (using the command: plot(te0,ye0(:,10)-yeL(:,10))). This is not expected. For all time values from t0 till tfinal, the value of the 10 state variable, should be greater, as it is the solution obtained from a system of ODEs which did not have an increased withdrawal rate applied to it.
I am told that there is a bug in my matlab code. I am not sure how to find out that bug. Or maybe the solver in matlab I am using (ode45) is not efficient and does give this kind of problem. Can anyone help.
I have tried ode23 and ode113 as well, and yet get the same problem. The figure (2), shows a curve which becomes negative for time values 32 and 34 and this is showing a result which is not expected. This curve should have a positive value throughout, for all time values. Is there any other forum anyone can suggest ?
Here is the main script file:
clear memory; clear all;
global Nc capitalambda muh lambdah del1 del2 p eta alpha1 alpha2 muv lambdav global dims Q t0 tfinal gamma Ct0 b1 b2 Ct0r b3 H C m_tilda betaHV bitesPERlanding IC global tspan Hs Cs betaVH k landingARRAY muARRAY
Nhh=33898857; Nvv=2*Nhh; Nc=21571585; g=354; % number of public health centers in Bihar state %Fix human parameters capitalambda= 1547.02; muh=0.000046142; lambdah= 0.07; del1=0.001331871263014; del2=0.000288658; p=0.24; eta=0.0083; alpha1=0.044; alpha2=0.0217; %Fix vector parameters muv=0.071428; % UNIT:2.13 SANDFLIES DEAD/SAND FLY/MONTH, SOURCE: MUBAYI ET AL., 2010 lambdav=0.05; % UNIT:1.5 TRANSMISSIONS/MONTH, SOURCE: MUBAYI ET AL., 2010
Ct0=0.054;b1=0.0260;b2=0.0610; Ct0r=0.63;b3=0.0130;
dimsH=6; % AS THERE ARE FIVE HUMAN COMPARTMENTS dimsV=3; % AS THERE ARE TWO VECTOR COMPARTMENTS dims=dimsH+dimsV; % THE TOTAL NUMBER OF COMPARTMENTS OR DIFFERENTIAL EQUATIONS
gamma=32; % spraying is done of 1st feb of the year
Q=0.2554; H=7933615; C=5392890;
m_tilda=100000; % assumed value 6.5, later I will have to get it for sand flies or mosquitoes betaHV=66.67/1000000; % estimated value from the short technical report sent by Anuj bitesPERlanding=lambdah/(m_tilda*betaHV); betaVH=lambdav/bitesPERlanding; IC=zeros(dims+1,1); % CREATES A MATRIX WITH DIMS+1 ROWS AND 1 COLUMN WITH ALL ELEMENTS AS ZEROES
t0=1; tfinal=40; for j=t0:1:(tfinal*4-4) tspan(1)= t0; tspan(j+1)= tspan(j)+0.25; end clear j;
% INITIAL CONDITION OF HUMAN COMPARTMENTS q1=0.8; q2=0.02; q3=0.0005; q4=0.0015; IC(1,1) = q1*Nhh; IC(2,1) = q2*Nhh; IC(3,1) = q3*Nhh; IC(4,1) = q4*Nhh; IC(5,1) = (1-q1-q2-q3-q4)*Nhh; IC(6,1) = Nhh; % INTIAL CONDITIONS OF THE VECTOR COMPARTMENTS IC(7,1) = 0.95*Nvv; %80 PERCENT OF TOTAL ARE ASSUMED AS SUSCEPTIBLE VECTORS IC(8,1) = 0.05*Nvv; %20 PRECENT OF TOTAL ARE ASSUMED AS INFECTED VECTORS IC(9,1) = Nvv; IC(10,1)=0;
Hs=2000000; Cs=3000000; k=1; landingARRAY=zeros(tfinal*50,2); muARRAY=zeros(tfinal*50,2);
[te0 ye0]=ode45(#NoEffects_derivative_6_15_2012,tspan,IC); [teL yeL]=ode45(#OnlyLethal_derivative_6_15_2012,tspan,IC);
figure(1) subplot(4,3,1); plot(te0,ye0(:,1),'b-',teL,yeL(:,1),'r-'); xlabel('time'); ylabel('S'); legend('susceptible humans'); subplot(4,3,2); plot(te0,ye0(:,2),'b-',teL,yeL(:,2),'r-'); xlabel('time'); ylabel('I'); legend('Infectious Cases'); subplot(4,3,3); plot(te0,ye0(:,3),'b-',teL,yeL(:,3),'r-'); xlabel('time'); ylabel('G'); legend('Cases in Govt. Clinics'); subplot(4,3,4); plot(te0,ye0(:,4),'b-',teL,yeL(:,4),'r-'); xlabel('time'); ylabel('T'); legend('Cases in Private Clinics'); subplot(4,3,5); plot(te0,ye0(:,5),'b-',teL,yeL(:,5),'r-'); xlabel('time'); ylabel('R'); legend('Recovered Cases');
subplot(4,3,6);plot(te0,ye0(:,6),'b-',teL,yeL(:,6),'r-'); hold on; plot(teL,capitalambda/muh); xlabel('time'); ylabel('Nh'); legend('Nh versus time');hold off;
subplot(4,3,7); plot(te0,ye0(:,7),'b-',teL,yeL(:,7),'r-'); xlabel('time'); ylabel('X'); legend('Susceptible Vectors');
subplot(4,3,8); plot(te0,ye0(:,8),'b-',teL,yeL(:,8),'r-'); xlabel('time'); ylabel('Z'); legend('Infected Vectors');
subplot(4,3,9); plot(te0,ye0(:,9),'b-',teL,yeL(:,9),'r-'); xlabel('time'); ylabel('Nv'); legend('Nv versus time');
subplot(4,3,10);plot(te0,ye0(:,10),'b-',teL,yeL(:,10),'r-'); xlabel('time'); ylabel('FS'); legend('Total number of human infections');
figure(2) plot(te0,ye0(:,10)-yeL(:,10)); xlabel('time'); ylabel('FS(without intervention)-FS(with lethal effect)'); legend('Diff. bet. VL cases with and w/o intervention:ode45');
The function file: NoEffects_derivative_6_15_2012
function dx = NoEffects_derivative_6_15_2012( t , x )
global Nc capitalambda muh del1 del2 p eta alpha1 alpha2 muv global dims m_tilda betaHV bitesPERlanding betaVH
dx = zeros(dims+1,1); % t % dx
dx(1,1) = capitalambda-(m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-muh*x(1,1);
dx(2,1) = (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-(del1+eta+muh)*x(2,1);
dx(3,1) = p*eta*x(2,1)-(del2+alpha1+muh)*x(3,1);
dx(4,1) = (1-p)*eta*x(2,1)-(del2+alpha2+muh)*x(4,1);
dx(5,1) = alpha1*x(3,1)+alpha2*x(4,1)-muh*x(5,1);
dx(6,1) = capitalambda -del1*x(2,1)-del2*x(3,1)-del2*x(4,1)-muh*x(6,1);
dx(7,1) = muv*(x(7,1)+x(8,1))-bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc)-muv*x(7,1);
%dx(8,1) = lambdav*x(7,1)*x(2,1)/(x(6,1)+Nc)-muvIOFt(t)*x(8,1);
dx(8,1) = bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc)-muv*x(8,1);
dx(9,1) = (muv-muv)*x(9,1);
dx(10,1) = (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/x(9,1);
The function file: OnlyLethal_derivative_6_15_2012
function dx=OnlyLethal_derivative_6_15_2012(t,x)
global Nc capitalambda muh del1 del2 p eta alpha1 alpha2 muv global dims m_tilda betaHV bitesPERlanding betaVH k muARRAY
dx=zeros(dims+1,1);
% the below code saves some values into the second column of the two arrays % t muARRAY(k,1)=t; muARRAY(k,2)=artificialdeathrate1(t); k=k+1;
dx(1,1)= capitalambda-(m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-muh*x(1,1);
dx(2,1)= (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/(x(7,1)+x(8,1))-(del1+eta+muh)*x(2,1);
dx(3,1)=p*eta*x(2,1)-(del2+alpha1+muh)*x(3,1);
dx(4,1)=(1-p)*eta*x(2,1)-(del2+alpha2+muh)*x(4,1);
dx(5,1)=alpha1*x(3,1)+alpha2*x(4,1)-muh*x(5,1);
dx(6,1)=capitalambda -del1*x(2,1)-del2*( x(3,1)+x(4,1) ) - muh*x(6,1);
dx(7,1)=muv*( x(7,1)+x(8,1) )- bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc) - (artificialdeathrate1(t) + muv)*x(7,1);
dx(8,1)= bitesPERlanding*betaVH*x(7,1)*x(2,1)/(x(6,1)+Nc)-(artificialdeathrate1(t) + muv)*x(8,1);
dx(9,1)= -artificialdeathrate1(t) * x(9,1);
dx(10,1)= (m_tilda)*bitesPERlanding*betaHV*x(1,1)*x(8,1)/x(9,1);
The function file: artificialdeathrate1
function art1=artificialdeathrate1(t)
global Q Hs H Cs C
art1= Q*Hs*iOFt(t)/H + (1-Q)*Cs*oOFt(t)/C ;
The function file: iOFt
function i = iOFt(t)
global gamma tfinal Ct0 b1
if t>=gamma && t<=tfinal
i = Ct0*exp(-b1*(t-gamma));
else
i =0;
end
The function file: oOFt
function o = oOFt(t)
global gamma Ct0 b2 tfinal
if (t>=gamma && t<=tfinal)
o = Ct0*exp(-b2*(t-gamma));
else
o = 0;
end
If your working code is even remotely as messy as the code you posted, then that should IMHO the first thing you should address.
I cleaned up iOFt, oOFt a bit for you, since those were quite easy to handle. I tried my best at NoEffects_derivative_6_15_2012. What I'd personally change to your code is using decent indexes. You have 10 variables, there is no way that if you let your code rest for a few weeks or months, that you will remember what state 7 is for example. So instead of using (7,1), you might want to rewrite your ODE either using verbose names and then retrieving/storing them in the x and dx vectors. Or use indexes that make it clear what is happening.
E.g.
function ODE(t,x)
insectsInfected = x(1);
humansInfected = x(2);
%etc
dInsectsInfected = %some function of the rest
dHumansInfected = %some function of the rest
% etc
dx = [dInsectsInfected; dHumansInfected; ...];
or
function ODE(t,x)
iInsectsInfected = 1;
iHumansInfected = 2;
%etc
dx(iInsectsInfected) = %some function of x(i...)
dx(iHumansInfected) = %some function of x(i...)
%etc
When you don't do such things, you might end up using x(6,1) instead of e.g. x(3,1) in some formulas and it might take you hours to spot such a thing. If you use verbose names, it takes a bit longer to type, but it makes debugging a lot easier and if you understand your equations, it should be more obvious when such an error happens.
Also, don't hesitate to put spaces inside your formulas, it makes reading much easier. If you have some sub-expressions that are meaningful (e.g. if (1-p)*eta*x(2,1) is the number of insects that are dying of the disease, just put it in a variable dyingInsects and use that everywhere it occurs). If you align your assignments (as I've done above), this might add to code that is easier to read and understand.
With regard to the ODE solver, if you are sure your implementation is correct, I'd also try a solver for stiff problems (unless you are absolutely sure you don't have a stiff system).
Related
Matlab implementation of Perceptron - can't seem to fix plotting
This is my first go with ML (and Matlab) and I'm following "Learning From Data" by Yaser S. Abu-Mostafa. I'm trying to implement the Perceptron algorithm, after trying to go through the pseudocode, using other people's solutions I can't seem to fix my problem (I went through other threads too). The algorithm separates the data fine, it works. However, I want to plot a single line, but it seems as it separates them in a way so the '-1' cluster is divided to a second cluster or more. This is the code: iterations = 100; dim = 3; X1=[rand(1,dim);rand(1,dim);ones(1,dim)]; % class '+1' X2=[rand(1,dim);1+rand(1,dim);ones(1,dim)]; % class '-1' X=[X1,X2]; Y=[-ones(1,dim),ones(1,dim)]; w=[0,0,0]'; % call perceptron wtag=weight(X,Y,w,iterations); % predict ytag=wtag'*X; % plot prediction over origianl data figure;hold on plot(X1(1,:),X1(2,:),'b.') plot(X2(1,:),X2(2,:),'r.') plot(X(1,ytag<0),X(2,ytag<0),'bo') plot(X(1,ytag>0),X(2,ytag>0),'ro') legend('class -1','class +1','pred -1','pred +1') %Why don't I get just one line? plot(X,Y); The weight function (Perceptron): function [w] = weight(X,Y,w_init,iterations) %WEIGHT Summary of this function goes here % Detailed explanation goes here w = w_init; for iteration = 1 : iterations %<- was 100! for ii = 1 : size(X,2) %cycle through training set if sign(w'*X(:,ii)) ~= Y(ii) %wrong decision? w = w + X(:,ii) * Y(ii); %then add (or subtract) this point to w end end sum(sign(w'*X)~=Y)/size(X,2); %show misclassification rate end I don't think the problem is in the second function but I added it regardless I'm pretty sure the algorithm separates it to more than one cluster but I can't tell why most of the learning I've done so far was math and theory and not actual coding so I'm probably missing something obvious..
Matlab 1D wave equation FDM second order in time, fourth order in space
I wrote a function to solve the 1D wave equation with FDM. Therefore i used second order accuracy in time and fourth order in space and an explicit FD scheme. I already implemented the solver function in Matlab with an matrix-vector-multiplication approach (alternative this can be done iterative) with periodic boundary conditions. To verify the code i used the Method of Manufactured Solution. My approach is to assume the solution as p(t,x)=sin(x+t)+sin(x-t) which is periodic and sufficient smooth and differentiable. I implemented a source term f which is as well as the initial data input for the following function function [x,t,P_End]= MMS(f,I,G,L,v,T,J,CFL,x) % Initialisation deltax=x(2)-x(1); deltat=CFL*deltax/abs(v); c=(v*deltat/deltax)^2; t=(0:deltat:T); N=length(t); A=zeros(J,J); for k=1:J % periodic boundary condition if k==1 A(1,1)=-c*5/2; A(1,2)=c*4/3; A(1,3)=c/12; A(1,J-1)=c/12; A(1,J)=c*4/3; elseif k==J A(J,1)=c*4/3; A(J,2)=c/12; A(J,J-2)=c/12; A(J,J-1)=c*4/3; A(J,J)=-c*5/2; elseif k==2 A(2,J)=c/12; A(2,1)=c*4/3; A(2,2)=-c*5/2; A(2,3)=c*4/3; A(2,4)=c/12; elseif k==J-1 A(J-1,1)=c*1/12; A(J-1,J-1)=-c*5/2; A(J-1,J)=c*4/3; A(J-1,J-2)=c*4/3; A(J-1,J-3)=c*1/12; else A(k,k-2)=c/12; A(k,k-1)=c*4/3; A(k,k)=-c*5/2; A(k,k+1)=c*4/3; A(k,k+2)=c/12; end end %Allocate memory P_0=zeros(J,1); b=zeros(J,1); H=zeros(J,1); %Initial data read in for i=1:J P_0(i)=I(x(i)); b(i)=f(x(i),t(1)); H(i)=G(x(i)); end %Calculation of first time step separate because to time steps back %are needed in the iteration P_1=0.5*A*P_0+(deltat^2/2)*b+2*deltat*H+P_0; P_n_minus_1=P_0; P_n=P_1; P_End=zeros(N,J); % Solution matrix P_End(1,:)=P_0; P_End(2,:)=P_1; for n=2:N for i=1:J b(i)=f(x(i),t(n)); end %Iterative calculation for t_2,...,t_N P_n_plus_1=A*P_n+(deltat^2)*b-P_n_minus_1+2*P_n; %Overwriting P_n_minus_1=P_n; P_n=P_n_plus_1; P_End(n,:)=P_n_plus_1; end end The function call is then clear all; clc; close all; %% Initialisierung % Grid points in space x_0,...x_L x = -2 : 0.01 : 2; J = length(x); xDelta = x(2) - x(1); T = 2; v = 0.5; %velocity constant CFL = 0.5; %Courant Friedrich Lewis number %Source term right-hand side of the wave equation f = #(x,t) abs(v^2-1)*(sin(x+t)+sin(x-t)); %Initial data for the estimated sound pressure function p(t,x), t=0 I = #(x) 2*sin(x); % \partial p/ \partial t , t=0 G = #(x) 0; [x,t,P_End]= MMS(f,I,G,v,T,J,CFL,x); This initial data and source term input leads to a solution that proceed like the assumed solution but in range ob `+/- 10^24. What an i doing wrong here? I already reviewed the code hundred of times but could not detect any code mistakes. Thanks for any hints!
Passing matrix to another function, storing element
I am having a problem, I have a function popmesh1 that calculates a matrix P( , ). I then use sens_analysis to store a element of that matrix and continue. How do I output P( , ) so that it is kept track of? I keep getting that the matrix is size (0,0). Also, how do I pass the matrix into another function? Sorry to post whole code, I want to concrete and clear, I'm pretty new to MATLAB function pdemeshpop(varargin) global par; global re; global P; global par_n; global a1; clc clear %INIITIALIZE MESH:- Can change time and age for refining of mesh time=linspace(0,800,4000); age=linspace(0,time(end),4000); dt=time(2)-time(1); dtao=dt; P=zeros(length(time),9); % State matrix over time. P1=zeros(length(time),length(age)); % Mesh for population of P1mod. prodrev=zeros(length(time),length(age)); p1tot=zeros(length(time)); p2tot=zeros(length(time)); f=zeros(length(time)); A_1=zeros(length(time),1); %Parameters G=log(2)/30; %This growth rate had been set to nthroot(2,20), but I think it should be log(2)/20 for a doubling time of 20 mins. Units 1/min R=.75; %Reduction in growth rate due to viral production, range from 0.5-0.75 global A_s; %Number of virus produced each minute from one cell? Units 1/min A_s = 35; %Source for this? global re; re = varargin(1); %Reduction in efficiency of virus production in P1mod c=1.5e9; %Concentration of cells in saturated culture. Units 1/cm^3 Source: http://bionumbers.hms.harvard.edu/bionumber.aspx?&id=100984&ver=2 K=3e-11; %Adsorption rate. Units cm^3/min. Source: Tzagoloff, H., and D. Pratt. 1964. The initial steps in infection with coliphage M13. Virology 24:372?380. i = 1; %Is flipping of switch induced or not induced? if i==1 then switch is induced. if i==1 S_i=0.5; %S_i is probability that a switch will flip during a timestep in a p1ori cell. Units pure number (a probablility). Ranges from 0 to 1. elseif i==0 S_i= 0.005; end %IC and BC implementation for the 9 dependent variables <<<10? P0=zeros(9,1); P0(1)=100; %Initial concentration of senders. Units: cells/ml. P0(2)=10000; %Initial concentration of primary receivers. Units: cells/ml. P0(3)=10000; %Initial concentration of secondary receivers. Units: cells/ml. %The loop below covers the initial conditions and BC of t=0,all ages for i=1:9 P(1,i)=P0(i); end %Iterative solution for m=1:length(time)-1 % m is timestep %Simplifications p1tot(m)=P(m,2)+P(m,4)+P(m,6); p2tot(m)=P(m,3)+P(m,5)+P(m,7); f(m)=1-(P(m,1)+p1tot(m)+p2tot(m))/c; %Senders P(m+1,1)=dt*(P(m,1)*G*R*f(m))+P(m,1); %Primary Receivers P(m+1,2)=dt*((P(m,2)*G*f(m))-K*(P(m,8)+P(m,9))*P(m,2))+P(m,2); %Secondary Receivers P(m+1,3)=dt*((P(m,3)*G*f(m))-K*(P(m,8)+P(m,9))*P(m,3))+P(m,3); %Primary Original P(m+1,4)=dt*((P(m,4)*G*f(m))+K*P(m,8)*P(m,2)-S_i*P(m,4))+P(m,4); %Secondary Original P(m+1,5)=dt*((P(m,5)*G*f(m))+K*P(m,8)*P(m,3))+P(m,5); for n=1:m t=(m-1)*dt; %Why not t=m*dt? tao=(n-1)*(dtao);%Determines current age basket prodrev(m,n)=rate(t-tao); %Calculates corresponding rate of production of phage (reversed) %Primary Modified if n==1 P1(m+1,n)=dt*(K*P(m,2)*P(m,9)+S_i*P(m,4)); %Left hand side boundary (New cells at age zero) else P1(m+1,n)=dt*(-((P1(m,n)-P1(m,n-1))/dtao)+P1(m,n)*G*R*f(m))+P1(m,n); end end P(m+1,6)=sum(P1(m+1,:)); %phi1mod %Secondary Modified P(m+1,7)=dt*((P(m,7)*G*f(m))+K*P(m,9)*P(m,3))+P(m,7); %Original P(m+1,8)=dt*(A_s*P(m,1))+P(m,8); if m<2 A_1(m)=0; else convolution(m,:)=prodrev(m,:).*P1(m,:); %A_1(m)=dtao*trapz(conv(prod1(m,:), P1(m,:))); A_1(m)=dtao*trapz([convolution(m,:) 0]); %A_1 obtained by convolving the discrete vectors of P1 and prod1 %then finding the area under the curve end %Modified P(m+1,9)=dt*A_1(m)+P(m,9); end P1; end function prod=rate(tao) %Function generates production rate values of the infected cells based on their age global A_s; global re; a=re*A_s; %Max production rate ageofcell=tao; if ageofcell<=10 prod=0; elseif ageofcell<=50 prod=(a/40)*(ageofcell-10); else prod=a; end end and my other code that calls the above function, and that I want to pass P(time(length),7) to: function sens_analysis global par; global re; global par_n; global P; time=linspace(0,800,4000); pdemeshpop_final_re_sens; re_0 = re; par = re; s_nom_ss = a1; delta = 0.05; par_n = par*(1+delta); pdemeshpop_final_re_sens_par(par_n); % similar to pdemeshpop_final_re_sens s_pert_ss = P(length(time),7); abs_sens = (s_pert_ss - s_nom_ss)/(delta*re_0); rel_sens = abs_sens*(re_value/s_nom_ss); end Again, sorry to post whole code, felt it was a necessary evil. The global variables might also be unnecessary. Could be something obvious. I might need to store P first somehow. Can someone please explain this carefully? Thank you!
At the beginning of function pdemeshpop you have a clear statement which is erasing from your workspace the variables declared by the global statements. Comment out that clear statement and you'll circumvent that problem.
The first thing I noticed in your code is that you use global variables. In general this is not recommended if it can be avoided. Consider giving them as input to your functions instead, either separately or in a struct. Of course the clear is removing your variables, but in general if you want to see what is happening, try placing some breakpoints in your code. That allows you to inspect all existing variables. With f10 you can then step through the code and see how everything goes on. Furthermore, I would always recommend you to use dbstop if error, this way you can efficiently deal with the errors that you will encounter.
tensile tests in matlab
The problem says: Three tensile tests were carried out on an aluminum bar. In each test the strain was measured at the same values of stress. The results were where the units of strain are mm/m.Use linear regression to estimate the modulus of elasticity of the bar (modulus of elasticity = stress/strain). I used this program for this problem: function coeff = polynFit(xData,yData,m) % Returns the coefficients of the polynomial % a(1)*x^(m-1) + a(2)*x^(m-2) + ... + a(m) % that fits the data points in the least squares sense. % USAGE: coeff = polynFit(xData,yData,m) % xData = x-coordinates of data points. % yData = y-coordinates of data points. A = zeros(m); b = zeros(m,1); s = zeros(2*m-1,1); for i = 1:length(xData) temp = yData(i); for j = 1:m b(j) = b(j) + temp; temp = temp*xData(i); end temp = 1; for j = 1:2*m-1 s(j) = s(j) + temp; temp = temp*xData(i); end end for i = 1:m for j = 1:m A(i,j) = s(i+j-1); end end % Rearrange coefficients so that coefficient % of x^(m-1) is first coeff = flipdim(gaussPiv(A,b),1); The problem is solved without a program as follows MY ATTEMPT T=[34.5,69,103.5,138]; D1=[.46,.95,1.48,1.93]; D2=[.34,1.02,1.51,2.09]; D3=[.73,1.1,1.62,2.12]; Mod1=T./D1; Mod2=T./D2; Mod3=T./D3; xData=T; yData1=Mod1; yData2=Mod2; yData3=Mod3; coeff1 = polynFit(xData,yData1,2); coeff2 = polynFit(xData,yData2,2); coeff3 = polynFit(xData,yData3,2); x1=(0:.5:190); y1=coeff1(2)+coeff1(1)*x1; subplot(1,3,1); plot(x1,y1,xData,yData1,'o'); y2=coeff2(2)+coeff2(1)*x1; subplot(1,3,2); plot(x1,y2,xData,yData2,'o'); y3=coeff3(2)+coeff3(1)*x1; subplot(1,3,3); plot(x1,y3,xData,yData3,'o'); What do I have to do to get this result?
As a general advice: avoid for loops wherever possible. avoid using i and j as variable names, as they are Matlab built-in names for the imaginary unit (I really hope that disappears in a future release...) Due to m being an interpreted language, for-loops can be very slow compared to their compiled alternatives. Matlab is named MATtrix LABoratory, meaning it is highly optimized for matrix/array operations. Usually, when there is an operation that cannot be done without a loop, Matlab has a built-in function for it that runs way way faster than a for-loop in Matlab ever will. For example: computing the mean of elements in an array: mean(x). The sum of all elements in an array: sum(x). The standard deviation of elements in an array: std(x). etc. Matlab's power comes from these built-in functions. So, your problem. You have a linear regression problem. The easiest way in Matlab to solve this problem is this: %# your data stress = [ %# in Pa 34.5 69 103.5 138] * 1e6; strain = [ %# in m/m 0.46 0.95 1.48 1.93 0.34 1.02 1.51 2.09 0.73 1.10 1.62 2.12]' * 1e-3; %# make linear array for the data yy = strain(:); xx = repmat(stress(:), size(strain,2),1); %# re-formulate the problem into linear system Ax = b A = [xx ones(size(xx))]; b = yy; %# solve the linear system x = A\b; %# modulus of elasticity is coefficient %# NOTE: y-offset is relatively small and can be ignored) E = 1/x(1) What you did in the function polynFit is done by A\b, but the \-operator is capable of doing it way faster, way more robust and way more flexible than what you tried to do yourself. I'm not saying you shouldn't try to make these thing yourself (please keep on doing that, you learn a lot from it!), I'm saying that for the "real" results, always use the \-operator (and check your own results against it as well). The backslash operator (type help \ on the command prompt) is extremely useful in many situations, and I advise you learn it and learn it well. I leave you with this: here's how I would write your polynFit function: function coeff = polynFit(X,Y,m) if numel(X) ~= numel(X) error('polynFit:size_mismathc',... 'number of elements in matrices X and Y must be equal.'); end %# bad condition number, rank errors, etc. taken care of by \ coeff = bsxfun(#power, X(:), m:-1:0) \ Y(:); end I leave it up to you to figure out how this works.
difference equations in MATLAB - why the need to switch signs?
Perhaps this is more of a math question than a MATLAB one, not really sure. I'm using MATLAB to compute an economic model - the New Hybrid ISLM model - and there's a confusing step where the author switches the sign of the solution. First, the author declares symbolic variables and sets up a system of difference equations. Note that the suffixes "a" and "2t" both mean "time t+1", "2a" means "time t+2" and "t" means "time t": %% --------------------------[2] MODEL proc-----------------------------%% % Define endogenous vars ('a' denotes t+1 values) syms y2a pi2a ya pia va y2t pi2t yt pit vt ; % Monetary policy rule ia = q1*ya+q2*pia; % ia = q1*(ya-yt)+q2*pia; %%option speed limit policy % Model equations IS = rho*y2a+(1-rho)*yt-sigma*(ia-pi2a)-ya; AS = beta*pi2a+(1-beta)*pit+alpha*ya-pia+va; dum1 = ya-y2t; dum2 = pia-pi2t; MPs = phi*vt-va; optcon = [IS ; AS ; dum1 ; dum2; MPs]; Edit: The equations that are going into the matrix, as they would appear in a textbook are as follows (curly braces indicate time period values, greek letters are parameters): First equation: y{t+1} = rho*y{t+2} + (1-rho)*y{t} - sigma*(i{t+1}-pi{t+2}) Second equation: pi{t+1} = beta*pi{t+2} + (1-beta)*pi{t} + alpha*y{t+1} + v{t+1} Third and fourth are dummies: y{t+1} = y{t+1} pi{t+1} = pi{t+1} Fifth is simple: v{t+1} = phi*v{t} Moving on, the author computes the matrix A: %% ------------------ [3] Linearization proc ------------------------%% % Differentiation xx = [y2a pi2a ya pia va y2t pi2t yt pit vt] ; % define vars jopt = jacobian(optcon,xx); % Define Linear Coefficients coef = eval(jopt); B = [ -coef(:,1:5) ] ; C = [ coef(:,6:10) ] ; % B[c(t+1) l(t+1) k(t+1) z(t+1)] = C[c(t) l(t) k(t) z(t)] A = inv(C)*B ; %(Linearized reduced form ) As far as I understand, this A is the solution to the system. It's the matrix that turns time t+1 and t+2 variables into t and t+1 variables (it's a forward-looking model). My question is essentially why is it necessary to reverse the signs of all the partial derivatives in B in order to get this solution? I'm talking about this step: B = [ -coef(:,1:5) ] ; Reversing the sign here obviously reverses the sign of every component of A, but I don't have a clear understanding of why it's necessary. My apologies if the question is unclear or if this isn't the best place to ask.
I think the key is that the model is forward-looking, so the slopes (the partial derivatives) need to be reversed to go backward in time. One way to think of it is to say that the jacobian() function always calculates derivatives in the forward-time direction. You've got an output vector of states called optcon = [IS;AS;dum1;dum2;MPs], and two vectors of input states [y2 pi2 y pi v]. The input vector at time t+1 is [y2a pi2a ya pia va], and the input vector at time t is [y2t pi2t yt pit vt]. These two are concatenated into a single vector for the call to jacobian(), then separated after. The same thing could have been done in two calls. The first 5 columns of the output of jacobian() are the partial derivatives of optcon with respect to the input vector at time t+1, and the second 5 columns are with respect to the input vector at time t. In order to get the reduced form, you need to come up with two equations for optcon at time t+1. The second half of coef is just what is needed. But the first half of coef is the equation for optcon at time t+2. The trick is to reverse the signs of the partial derivatives to get linearized coefficients that take the input vector at t+1 to the output optcon at t+1.