Octave: Not all numerical integrations are created equal - matlab

I wrote a script to compare the answers between integrating an equation exactly, summing it, and using various built-in numerical integration functions.
Here is my program:
xmin = -2*pi;
xmax = -xmin;
dx = 0.01;
x = [xmin:dx:xmax];
f = sin(x);
fstar = conj(f);
y = fstar.*f; %for the sum
fy = #(x) y;
fsum1 = sum(y.*dx); %approximation by treating integral as a sum
%definite integral (specific to int(sin^2(x)))
fsum2 = 0.5.*(xmax - sin(xmax).*cos(xmax) - xmin + sin(xmin).*cos(xmin));
%numerical integrations:
fsum3 = quad(fy,xmin,xmax);
fsum4 = quadv(fy,xmin,xmax);
fsum5 = quadl(fy,xmin,xmax);
fsum6 = quadgk(fy,xmin,xmax);
fsum7 = quadcc(fy,xmin,xmax);
Everything runs fine until it hangs on fsum4. Well, I should say that fsum1 and fsum2 work. However, fsum3 = 7.53812e-031 (wrong) and fsum4 = a matrix the same size as x. When I plot fsum4 vs. x I get a (sin(x))^2 function with an amplitude of a little over 12.
I've gotten the quad integration function to work before, but I don't understand what I'm doing wrong here.

Related

I cant get the result of y

I have this questions but my result is different with the exact result what is the wrong?
this is what i tried.
x = 2;
z = 3;
y = x^2*x*z+12*x*z+((exp(x)/log(x*z)-log(x*z)*nthroot(x*z,2)))*nthroot(x*z,3);
result of y is 95.5185 not equal to -21.455
MATLAB Logarithm Conventions
Breaking up long equations into separate terms is useful for debugging. Here the case was the logarithmic functions that were used.
log → log10() (base-10 logarithm)
ln → log() (natural logarithm)
x = 2;
z = 3;
Term_1 = (x^2)*x*z;
Term_2 = 12*x*z;
Term_3 = (exp(x))/(log(x*z) - log10(x*z)*sqrt(x*z));
Term_4 = nthroot(x*z,3);
y = Term_1 + Term_2 + Term_3*Term_4;
y
Ran using MATLAB R2019b

SIR model using fsolve and Euler 3BDF

Hi i've been asked to solve SIR model using fsolve command in MATLAB, and Euler 3 point backward. I'm really confused on how to proceed, please help. This is what i have so far. I created a function for 3BDF scheme but i'm not sure how to proceed with fsolve and solve the system of nonlinear ODEs. The SIR model is shown as and 3BDF scheme is formulated as
clc
clear all
gamma=1/7;
beta=1/3;
ode1= #(R,S,I) -(beta*I*S)/(S+I+R);
ode2= #(R,S,I) (beta*I*S)/(S+I+R)-I*gamma;
ode3= #(I) gamma*I;
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
R0=0;
I0=10;
S0=8e6;
odes={ode1;ode2;ode3}
fun = #root2d;
x0 = [0,0];
x = fsolve(fun,x0)
function [xs,yb] = ThreePointBDF(f,x0, xmax, h, y0)
% This function should return the numerical solution of y at x = xmax.
% (It should not return the entire time history of y.)
% TO BE COMPLETED
xs=x0:h:xmax;
y=zeros(1,length(xs));
y(1)=y0;
yb(1)=y0+f(x0,y0)*h;
for i=1:length(xs)-1
R =R0;
y1(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - R, y1(i-1,:)+2*h*F(i,:))
S = S0;
y2(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - S, y2(i-1,:)+2*h*F(i,:))
I= I0;
y3(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - I, y3(i-1,:)+2*h*F(i,:))
end
end
You have an implicit equation
y(i+1) - 2*h/3*f(t(i+1),y(i+1)) = G = (4*y(i) - y(i-1))/3
where the right-side term G is constant in the call to fsolve, that is, during the solution of the implicit step equation.
Note that this is for the vector valued system y'(t)=f(t,y(t)) where
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
To solve this write
G = (4*y(i,:) - y(i-1,:))/3
y(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - G, y(i-1,:)+2*h*F(i,:))
where a midpoint step is used to get an order 2 approximation as initial guess, F(i,:)=f(t(i),y(i,:)). Add solver options for error tolerances as necessary, you want the error in the implicit equation smaller than the truncation error O(h^3) of the step. One can also keep only a short array of function values, then one has to be careful for the correspondence of the position in the short array to the time index.
Using all that and a reference solution by a higher order standard solver produces the following error graphs for the components
where one can see that the first order error of the constant first step results in a first order global error, while with a second order error in the first step using the Euler method results in a clear second order global error.
Implement the method in general terms
from scipy.optimize import fsolve
def BDF2(f,t,y0,y1):
N, h = len(t)-1, t[1]-t[0];
y = (N+1)*[np.asarray(y0)];
y[1] = y1;
for i in range(1,N):
t1, G = t[i+1], (4*y[i]-y[i-1])/3
y[i+1] = fsolve(lambda u: u-2*h/3*f(t1,u)-G, y[i-1]+2*h*f(t[i],y[i]), xtol=1e-3*h**3)
return np.vstack(y)
Set up the model to be solved
gamma=1/7;
beta=1/3;
print beta, gamma
y0 = np.array([8e6, 10, 0])
P = sum(y0); y0 = y0/P
def f(t,y): S,I,R = y; trns = beta*S*I/(S+I+R); recv=gamma*I; return np.array([-trns, trns-recv, recv])
Compute a reference solution and method solutions for the two initialization variants
from scipy.integrate import odeint
tg = np.linspace(0,120,25*128)
yg = odeint(f,y0,tg,atol=1e-12, rtol=1e-14, tfirst=True)
M = 16; # 8,4
t = tg[::M];
h = t[1]-t[0];
y1 = BDF2(f,t,y0,y0)
e1 = y1-yg[::M]
y2 = BDF2(f,t,y0,y0+h*f(0,y0))
e2 = y2-yg[::M]
Plot the errors, computation as above, but embedded in the plot commands, could be separated in principle by first computing a list of solutions
fig,ax = plt.subplots(3,2,figsize=(12,6))
for M in [16, 8, 4]:
t = tg[::M];
h = t[1]-t[0];
y = BDF2(f,t,y0,y0)
e = (y-yg[::M])
for k in range(3): ax[k,0].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
y = BDF2(f,t,y0,y0+h*f(0,y0))
e = (y-yg[::M])
for k in range(3): ax[k,1].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
for k in range(3):
for j in range(2): ax[k,j].set_ylabel(["$e_S$","$e_I$","$e_R$"][k]); ax[k,j].legend(); ax[k,j].grid()
ax[0,0].set_title("Errors: first step constant");
ax[0,1].set_title("Errors: first step Euler")

MATLAB Perceptron

I've been struggling with this for quite some time now. I cant seem to figure out why I have a percentage error in the thousands. I'm trying to figure out a perceptron between X1 and X2 which are Gaussian distributed data sets with distinct means and identical covariances. My code:
N=200;
X = [X1; X2];
X = [X ones(N,1)]; %bias
y = [-1*ones(N/2,1); ones(N/2,1)]; %classification
%Split data into training and test
ii = randperm(N);
Xtr = X(ii(1:N/2),:);
ytr = X(ii(1:N/2),:);
Xts = X(ii(N/2+1:N),:);
yts = y(ii(N/2+1:N),:);
w = randn(3,1);
eta = 0.001;
%learn from training set
for iter=1:500
j = ceil(rand*N/2);
if( ytr(j)*Xtr(j,:)*w < 0)
w = w + eta*Xtr(j,:)';
end
end
%apply what you have learnt to test set
yhts = Xts * w;
disp([yts yhts])
PercentageError = 100*sum(find(yts .*yhts < 0))/Nts;
Any help would be appreciated. Thank you
You have a bug in your error calculation.
On this line:
PercentageError = 100*sum(find(yts .*yhts < 0))/Nts;
The find is returning indices of the matching items. For your accuracy measure you don't want those, you just want the count:
PercentageError = 100*sum( yts .*yhts < 0 )/Nts;
If I generate X1 = randn(100,2); X2 = randn(100,2); and assume Nts=100, I get 2808% for your code, and expected 50% error (no better than guessing because my test data cannot be separated) for the corrected version.
Update - the perceptron model had a more subtle bug too, see: https://datascience.stackexchange.com/questions/2353/matlab-perceptron

Trapezoidal Numerical Integration in MATLAB without using a FOR loop?

I'm following a Numerical Methods course and I made a small MATLAB script to compute integrals using the trapezoidal method. However my script uses a FOR loop and my friend told me I'm doing something wrong if I use a FOR loop in Matlab. Is there a way to convert this script to a Matlab-friendly one?
%Number of points to use
N = 4;
%Integration interval
a = 0;
b = 0.5;
%Width of the integration segments
h = (b-a) / N;
F = exp(a);
for i = 1:N-1
F = F + 2*exp(a+i*h);
end
F = F + exp(b);
F = h/2*F
Vectorization is important speed and clarity, but so is using built-in functions whenever possible. Matlab has a built in function for trapezoidal numerical integration called trapz. Here is an example.
x = 0:.125:.5
y = exp(x)
F = trapz(x,y)
It is recommended to vectorize your code.
%Number of points to use
N = 4;
%Integration interval
a = 0;
b = 0.5;
%Width of the integration segments
h = (b-a) / N;
x = 1:1:N-1;
F = h/2*(exp(a) + sum(2*exp(a+x*h)) + exp(b));
However, I've read that Matlab is no longer slow at for loops.

change a m-file matlab into mathematica

I've written a matlab m-file to draw a double integral as below. Does everybody can show me its equivalent in mathematica???
tetha = pi/4;
lamb = -1;
h = 4;
tetha0 = 0;
syms x y l
n = [h.*((cos(tetha)).^2)./sin(tetha); h.*abs(cos(tetha)); 0];
ft = ((tetha - pi/2)./sin(tetha)).^4;
Rt = [cos(tetha) -sin(tetha); sin(tetha) cos(tetha)];
zt = [cos(tetha0) -sin(tetha0); sin(tetha0) cos(tetha0)];
lt = [x;y];
integrand = #(x,y)(ft.*h.*((abs(cos(tetha)).* (x.*cos(tetha)-y.*sin(tetha)))-((cos(tetha)).^2/sin(tetha)).*(x.*sin(tetha)+y.*cos(tetha))));
PhiHat = #(a,b)(dblquad(integrand,0,a,0,b));
ezsurfc(PhiHat,[0,5,0,5])
Here you go (only minimal changes made), but you'll have to do your homework to understand function definitions, integration, plotting etc. in Mathematica. Also, this is not idiomatic Mathematica, but let's not go there...
tetha=Pi/4;
lamb=-1;
h=4;
tetha0=0;
n={h*((Cos[tetha])^2)/Sin[tetha],h*Abs[Cos[tetha]],0};
ft=((tetha-Pi/2)/Sin[tetha])^4;
Rt={{Cos[tetha], -Sin[tetha]}, {Sin[tetha], Cos[tetha]}};
zt={{Cos[tetha0], -Sin[tetha0]}, {Sin[tetha0], Cos[tetha0]}};
integrand[x_,y_]:= (ft*h*((Abs[Cos[tetha]]*(x*Cos[tetha]-y*Sin[tetha]))-((Cos[tetha])^2/Sin[tetha])*(x*Sin[tetha]+y*Cos[tetha])));
PhiHat[a_,b_]:=NIntegrate[integrand[x,y],{x,0,a},{y,0,b}];
Plot3D[PhiHat[x,y],{x,0,5},{y,0,5}]