I have an integral expression to solve. And I need to get the final expression in the image using Matlab.
clc;close all;clear all;
syms s phis r phir
A=1;m=1;n=1;L=100;alpha=1;
k=(2*pi)/(550*10^-9);
us=A*((-1j*sqrt(2*k*alpha)*s*exp(-1j*phis))^m)*exp(-k*alpha*s*s)*laguerreL(n,m,2*k*alpha*s*s);
C=((-1j*k*exp(1j*k*L))/(2*pi*L))*exp((1j*k*r*r)/(2*L));
f = #(s,phis,r,phir) C*s*us*exp(((1j*k)/(2*L))*(-2*r*s*cos(phir-phis)+(s^2)));
g1 = #(s,phis,r,phir) int(#(phis) f(s,phis,r,phir),0,2*pi)
g2 = #(s,phis,r,phir) int(#(s) g1(s,r,phir),0,Inf)
Related
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")
i'm trying to evaluate a G11 symfun in the code below but it fails and keep showing me the variable t that I choose to be set as specified in the code, I even tried to use the 'subs' command but it failed also. I define the necessary symbols and variables but the t variable does not evaluated in just 'G11' symfun, there are another similar symfun such G12 or K12 but the t variable evaluated in them
here is my code
% Defining the variables as symbols.
clear all, close all
clc
syms x xi q_1 q_2 q_3 q_4 q_01 q_02 q_03 q_04 EI Mr M m L t Omega S1 S2 S3
...
S4 S5 S6 S7 S8 w L_dot U U_dot g L_ddot M11 M22
% Defining the general coordinates and the trial function.
L_ddot=0;
g=9.8;
Mr=M/(M+m);
PHI(x,t)=[sqrt(2).* sin(pi.*(xi)) sqrt(2).* sin(2*pi.*(xi)) sqrt(2).*
sin(3.*pi.*(xi)) sqrt(2).* sin(4.*pi.*(xi))];
q_1(t)= S1*exp(sqrt(-1)*w*t);
q_01(t)= S5*exp(sqrt(-1)*w*t);
q_2(t)= S2*exp(sqrt(-1)*w*t);
q_02(t)= S6*exp(sqrt(-1)*w*t);
q_3(t)= S3*exp(sqrt(-1)*w*t);
q_03(t)= S7*exp(sqrt(-1)*w*t);
q_4(t)= S4*exp(sqrt(-1)*w*t);
q_04(t)= S8*exp(sqrt(-1)*w*t);
Q_v(t) =[q_1;q_2;q_3;q_4];
Q_w(t) =[q_01;q_02;q_03;q_04];
V(x,t) = PHI*Q_v(t);
W(x,t) = PHI*Q_w(t);
% Defining the coeficients of the ODE.
U(x,t)=U;
L(x,t)=1+0.1*t;
L_dot(x,t)=diff(L,'t',1);
L_ddot=0;
M11=int(PHI'*PHI,'xi',[0 1]);
M22=M11;
G11=(2*(L_dot/L))* int((2-xi)*PHI'*diff(PHI,'xi',1),'xi',[0 1])+2*Mr*
(U/L)*int(PHI'*diff(PHI,'xi',1),'xi',[0 1]);
G12=-2*Omega*int(PHI'*PHI,'xi',[0 1]);
G21=-G12;
G22=G11;
K11=(EI/((M+m)*L^4))*int(PHI'*diff(PHI,'xi',4),'xi',[0 1])+ (L_dot/L)^2
*int((2-xi)^2 *...
PHI'*diff(PHI,'xi',2),'xi',[0 1])+ ((L_ddot*L-2*L_dot^2)/L^2)*int((1-
xi)*PHI'*diff(PHI,'xi',1),'xi',[0 1]) ...
+ 2*Mr*(L_dot*U/L^2)*int((2-xi)*PHI'*diff(PHI,'xi',2),'xi',[0 1])+ Mr*
(U/L)^2 *int(PHI'*diff(PHI,'xi',2),'xi',[0 1])-...
(g-((L_ddot-2*L_dot^2)/L))*int((1-xi)*PHI'*diff(PHI,'xi',2),'xi',[0 1])+
(g/L)*int(PHI'*diff(PHI,'xi',1),'xi',[0 1])-...
Omega^2 * int(PHI'*PHI,'xi',[0 1]);
K12= -2*Omega*(L_dot/L)*int((2-xi)*PHI'*diff(PHI,'xi',1),'xi',[0 1])-2*Mr*
((U*Omega)/L)*int(PHI'*diff(PHI,'xi',1),'xi',[0 1]);
K21=-K12;
K22=K11;
% evaluating the Coefficient matrices for the time history 1 to 80 seconds
by the stepping of 0.1 .
t=0:0.1:80;
m=8;
M=2;
Mr=0.2;
x=1;
U=2; % the flow velocity
Omega=90;
EI=8.9782;
FUNM11 = matlabFunction(M11);
Mmatrix11 = feval(FUNM11);
FUNG11 = matlabFunction(G11);
Gmatrix11 = feval(FUNG11,t,U,Mr,L_dot,L);
FUNG12 = matlabFunction(G12);
Gmatrix12 = feval(FUNG12, t,x,Omega);
FUNK11 = matlabFunction(K11);
Kmatrix11 = feval(FUNK11, t,M,x,Omega,m,U,EI);
FUNK12 = matlabFunction(K12);
Kmatrix12 = feval(FUNK12, t,M,x,U,m,Omega);
Mmatrix22=Mmatrix11;
Gmatrix21=-Gmatrix12;
Gmatrix22=Gmatrix11;
Kmatrix21=-Kmatrix12;
Kmatrix22=Kmatrix11;
% Assembling the Coeficient matrices
Q=[Q_v;Q_w];
Mmatrix=[Mmatrix11 ,zeros(size(Mmatrix11)); zeros(size(Mmatrix11))
Mmatrix22];
Gmatrix=[Gmatrix11 Gmatrix12; Gmatrix21 Gmatrix22];
Kmatrix=[Kmatrix11 Kmatrix12; Kmatrix21 Kmatrix22];
After assembling my coefficient matrices I try to solve this algebric equation for w:
eqn=det(-w^2.*Mmatrix+i*w.*Gmatrix+Kmatrix)==0;
which w is the frequency of the system.
Following code throws out an error.
syms z positive;
syms n;
syms m;
N = 10;
Ms = 10;
Es = 1;
pd = 0.9;
pd_dash = 1-pd;
pf = 0.1;
pf_dash = 1-pf;
pr = 0.1;
qr = 1-pr;
p = 0.005
pi = pf_dash*p;
pb = pd_dash*p;
qi = 1-pi;
qb = 1-pb;
sm = symsum( z^((n+1)*Es), n, 0, N-1 );
temp_sum = symsum(z^((n+m+1)*Es)*qr^(n+m)*pr, m, 0, N-1);
z=1; %assume a value of z
x = eval(sm); %works fine
y = eval(temp_sum);
% Error:The expression to the left of the equals sign is not a valid target for an assignment.
Please suggest a way to resolve this.
The problem that I suspect is: the temp_sum comes out to be in piecewise(...) which eval is not capable of evaluating.
What you actually did:
Create a symbolic expression
Create a variable z which is unused
Call a undocumented function sym/eval
I assume you wanted to:
Create a symbolic expression
Substitute z with 1: temp_sum=subs(temp_sum,z,1)
get the result. Here I don't know what you really have because I don't know which variables are symbolic unknowns and which constants. Try simplify(temp_sum). If you substituted all unknowns it should return a number.
I am trying to interpolate the following function using the MATLAB function spline,
at equidistant points xi = i./n, i = 0,1,...,n, and for n = 2^j, j = 4,5,...,14.
For each calculation, I record the maximum error at the points x = 0:0.001:1 and plot these errors against n using a loglog plot.
Below is the code,
index=1
for j = 4:1:14;
n = 2^j;
i = 0:1:n;
xi = i./n;
yi = ((exp(3*xi))*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
x = 0:.001:1;
ye = ((exp(3*x))*sin(200*x.^2)) ./(1+20*x.^2);
yp = spline(x,xi,yi);
err = ye - yp;
merr(index) = max(err);
index = index+1;
end
n1 = 10:10:170;
loglog(n1, merr,'.')
xlabel('n');
ylabel('errors');
title('Cubic Splines');
but when I run the code, I got the following error:
Error using * Inner matrix dimensions must agree.
Error in (line 9) yi = ((exp(3*xi))sin(200.(xi.^2)))
./(1+20.*(xi.^2));
I'm just starting learning MatLab, can anyone help?
You want element-wise multiplication (.*) for the following part of code:
yi = ((exp(3*xi))*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
should be
yi = ((exp(3*xi)).*sin(200.*(xi.^2))) ./(1+20.*(xi.^2));
The same issue is present for the computation of ye.
When you use mtimes (*), MATLAB tries to do matrix multiplication, which in your case (1-by-n times 1-by-n) is invalid.
Then you will run into a problem with your spline command. Change it to yp = spline(xi,yi,x); so that the values at which you want to interploate (x) are the last argument.
I have to determine, which filter was used on a random picture - is there a common way to detect the right one (gaussian, prewitt, sobel, average, ...) or would it be clever to code some sort of 'brute force'-detection ?
I tried to find it with Matlab, but I have no glue how to search more efficiently. At the moment it`s like finding a needle in a Haystack. I also thought of using some bash-script and imagemagick, but this would be to resource hungry.
I tought this wouldn't be a problem, but it's very time-consuming to guess a filter and try it like this
f = fspecial('gaussian', [3 3], 1);
res = imfilter(orginal, f);
corr2(res, pic);
Let f be the original image, g be the filtered one, and h the filter applied to f, so that:
f * h = g
Passing that to the frequency domain:
F.H = G, so H = G/F
The problem is that inverting F is VERY sensitive to noise.
How to implement that in MATLAB:
close all;
f = imread('cameraman.tif');
[x,y] = size(f);
figure,imshow(f);
h = fspecial('motion', 20, 40); % abitrary filter just for testing the algorithm
F = fft2(f);
H = fft2(h,x,y);
G = F.*H;
g = ifft2(G); % the filtered image
figure, imshow(g/max(g(:)));
% Inverting the original image
epsilon = 10^(-10);
small_values = find(abs(F)<epsilon);
F(small_values) = epsilon;
F_i = ones(x,y)./F;
H_calculated = G.*F_i;
h_calculated = ifft2(H_calculated);
% remove really small values to try to infer the original size of h
r = sum(h_calculated,1)<epsilon;
c = sum(h_calculated,2)<epsilon;
h_real = h_calculated(~r,~c);
% Calculate error
% redo the filtering with the found filter
figure,g_comp = ifft2(fft2(f).*fft2(h_real,x,y));
imshow(g_comp/max(g_comp(:)));
rmse = sqrt(mean(mean((double(g_comp) - double(g)).^2,2),1))
edit: Just to explain the epsilon part:
It can be that some values in F are zero, or very close to zero. If we try to invert F with these small values, we would have problems with infinity. The easy way to solve that is to truncate every value in F that is smaller than an arbitrarily small limit, epsilon on the code.
Mathematically, what was done is this:
For all F < epsilon, F = epsilon