I'm trying to solve this numerical differential equations, can someone help?
clc;
clear;
syms A1(z) A2(z)
lamda1 = 1560*(10^-9);
c=3*(10^8);
d_eff=27*(10^-12);
omga1=(2*pi*c)/(lamda1);
omga2=omga1*2;
n=2.2;
k1=(n*omga1)/c;
k2=(n*omga2)/c;
ode1 = diff(A1) == (2*i*(omga1^2)*d_eff*A2*conj(A1)*exp(-i*(2*k1-k2)*z))/(k1*(c^2));
ode2 = diff(A2) == (i*(omga2^2)*d_eff.*(A1.^2).*exp(i*(2*k1-k2)*z))/(k2*(c^2));
odes = [ode1; ode2];
cond1 = A1(0) == 1;
cond2 = A2(0) == 0;
conds = [cond1; cond2];
M = matlabFunction(odes)
sol = ode45(M(1),[0 20],[2 0]);
in this question both ODE are coupled, hence there's only 1 ODE to solve:
1.- use 1st equation to write
A1=f(A2,dA2/dz)
and feed this expression into 2nd equation.
2.- regroup
n1=1j*k1^4/k2^2*1/deff*.25
n2=1j*3*(k1-k2)
now the ODE to solve is
y'=n1/y^2*exp(n2*z)
3.- It can obviously be done in MATLAB, but for this particular ODE in my opinion the Wolfram online ODE Symbolic Solver does a better job.
Input the obtained ODE of previous point into the ODE solver available in this link
https://www.wolframalpha.com/input?i=y%27%27+%2B+y+%3D+0
and solve
4.- The general (symbolic) solutions for A2 are
Note that I used k1 instead of n1 and k2 instead of n2 just in the Wolfram ODE Solver.
Rewording ; the k1 k2 expressions of the general solutions are not the wave numbers k1 k2 of the equations in the question. Just replace accordingly.
5.- Now get A1 using expression in point 2.
6.- I have spotted 2 possible errors in the MATLAB code posted in the question that shouldn't be ignored by the question originator:
In the far right side of the posted MATLAB code, the exponential expressions
6.1.- both show
exp(-i(2*k1-k2)z))/(k1(c^2))
there's this (k1*(c^2)) dividing the exponent wheras in the question none of the exponentials show such denominator their respective exponents.
6.2.- the dk or delta k expression in the exponentials of the question are obviously k2-k1 or k1-k2 , here there may be room for a sign ambiguity, that may shoot a wave solution onto the opposite direction, yet the point here is where
*exp(-1i*(2*k1-k2)*z)
should probably be
*exp(-1i*2*(k1-k2)*z)
or just
exp(-1i*(k1-k2)*z)
6.3.- and yes, in MATLAB (-1)^.5 can be either expressed with 1j or 1i but as written in the MATLAB code made available in the question, since only a chunk of code has been made available, it's fair to assume that no such i=1j has been done.
Related
I would like to use numerical approach to calculate the differential with singularities.
For instance, y'=y^2+1 with y(0)=0. The analytical solution is not hard to find, y=tan(x).
The problem arises when I apply the numeric method, see the code in Matlab
tspan = [0 6];
y0 = [0; 0];
ode = #(t, y) y.^2+1;
[t, y] = ode45(ode, tspan, y0);
plot(t, y(:,1))
axis([0 6 -20 20])
which gives the plot below, i.e., it missed the part of solution after the first singularity.
My question: how to find the full numeric solution of a differential equation with singularities?
Thanks in advance!
This is impossible in general. An ODE solution ends where it diverges to infinity (or leaves the domain of the ODE function in any other way).
What you can do is apply domain knowledge. This equation is a Riccati DE. If one knows one solution, one can transform it into a Bernoulli DE that has a solution formula. There is a second transform without knowledge of a particular solution, it works always but is not always helpful. Set y=p/q and select their relationship so that a system of linear equations results. Here p'q-q'p=p^2+q^2 resolves nicely to p'=q, q'=-p, or as second order DE u''+u=0, the harmonic oscillator, for u=q or u=p. This system now has no singularities and the poles of the original solution y are the roots of the denominator q.
this a question that envolves both programming and mathematics. So, I'm trying to write a code that computes the general solution of a system of linear ODEs described by . The mathematical formula it's shown above:
where the greek symbol \PHI that appers in the equation is the expm(A*t)
clear all
A=[-2]; %system matrix
t0=1; %initial time of simulation
tf=2; %final time of simulation
syms t x_0
x0=x_0;
hom=expm(A*t); %hom means "homogeneous solution"
hom_initialcond=hom*x0;%this is the homogeneous solution multiplied by the initial conditon
invhom=inv(hom); %this is the inverse of the greek letter at which, multiplied by the input of the system, composes the integrand of the integral
g=5*cos(2*t); %system input
integrand=invhom*g; %computation of the integrand
integral=int(integrand,t0,t); %computation of the definite integral from t0 to t, as shown by the math formula
partsol=hom*integral; %this is the particular solution
gen_sol=partsol+hom_initialcond %this is the general solution
x_0=1; %this is the initial condition
t=linspace(t0,tf); %vector of time from t0 to tf
y=double(subs(gen_sol)); %here I am evaluating my symbolic expression
plot(t,y)
The problem is that my plot of the ODE's solution it's not looking well, as you can see:
The solution it's wrong because the curve shown in the graph doesnt start at the initial value equals 1. But the shape it's very similar from the plot gave by the MATLAB ODE solver:
However, if I set t0=0 then the plot gave by my code and by MATLAB solver it's exacly equal to each other. So, my code it's fine for t0=0 but with any other values my code goes wrong.
The general solution in terms of fundamental matrices is
or more often seen as
But since the initial time is often taken to be zero, the inverse of the fundamental matrix is often omitted since it is the identity for linear, constant coefficient problems at zero (i.e., expm(zeros(n)) == eye(n)) and the c vector is equivalent to the initial condition vector.
Swapping some of the lines around near your symbolic declaration to this
syms t x_0 c_0
hom = expm(A*t) ;
invhom = inv(hom) ;
invhom_0 = subs(invhom,t,sym(t0)) ;
c_0 = invhom_0 * x_0 ;
hom_initialcond = hom * c_0 ;
should provide the correct solution for non-zero initial time.
I am trying to solve two equations with complex coefficients using ode45.
But iam getting an error message as "Inputs must be floats, namely single or
double."
X = sym(['[',sprintf('X(%d) ',1:2),']']);
Eqns=[-(X(1)*23788605396486326904946699391889*1i)/38685626227668133590597632 + (X(2)*23788605396486326904946699391889*1i)/38685626227668133590597632; (X(2)*23788605396486326904946699391889*1i)/38685626227668133590597632 + X(1)*(- 2500000 + (5223289665997855453060886952725538686654593059791*1i)/324518553658426726783156020576256)] ;
f=#(t,X)[Eqns];
[t,Xabc]=ode45(f,[0 300*10^-6],[0 1])
How can i fix this ? Can somebody can help me ?
Per the MathWorks Support Team, the "ODE solvers in MATLAB 5 (R12) and later releases properly handle complex valued systems." So the complex numbers are the not the issue.
The error "Inputs must be floats, namely single or double." stems from your definition of f using Symbolic Variables that are, unlike complex numbers, not floats. The easiest way to get around this is to not use the Symbolic Toolbox at all; just makes Eqns an anonymous function:
Eqns= #(t,X) [-(X(1)*23788605396486326904946699391889*1i)/38685626227668133590597632 + (X(2)*23788605396486326904946699391889*1i)/38685626227668133590597632; (X(2)*23788605396486326904946699391889*1i)/38685626227668133590597632 + X(1)*(- 2500000 + (5223289665997855453060886952725538686654593059791*1i)/324518553658426726783156020576256)] ;
[t,Xabc]=ode45(Eqns,[0 300*10^-6],[0 1]);
That being said, I'd like to point out that numerically time integrating this system over 300 microseconds (I assume without units given) will take a long time since your coefficient matrix has imaginary eigenvalues on the order of 10E+10. The extremely short wavelength of those oscillations will more than likely be resolved by Matlab's adaptive methods, and that will take a while to solve for a time span just a few orders greater than the wavelength.
I'd, therefore, suggest an analytical approach to this problem; unless it is a stepping stone another problem that is non-analytically solvable.
Systems of ordinary differential equations of the form
,
which is a linear, homogenous system with a constant coefficient matrix, has the general solution
,
where the m-subscripted exponential function is the matrix exponential.
Therefore, the analytical solution to the system can be calculated exactly assuming the matrix exponential can be calculated.
In Matlab, the matrix exponential is calculate via the expm function.
The following code computes the analytical solution and compares it to the numerical one for a short time span:
% Set-up
A = [-23788605396486326904946699391889i/38685626227668133590597632,23788605396486326904946699391889i/38685626227668133590597632;...
-2500000+5223289665997855453060886952725538686654593059791i/324518553658426726783156020576256,23788605396486326904946699391889i/38685626227668133590597632];
Eqns = #(t,X) A*X;
X0 = [0;1];
% Numerical
options = odeset('RelTol',1E-8,'AbsTol',1E-8);
[t,Xabc]=ode45(Eqns,[0 1E-9],X0,options);
% Analytical
Xana = cell2mat(arrayfun(#(tk) expm(A*tk)*X0,t,'UniformOutput',false)')';
k = 1;
% Plots
figure(1);
subplot(3,1,1)
plot(t,abs(Xana(:,k)),t,abs(Xabc(:,k)),'--');
title('Magnitude');
subplot(3,1,2)
plot(t,real(Xana(:,k)),t,real(Xabc(:,k)),'--');
title('Real');
ylabel('Values');
subplot(3,1,3)
plot(t,imag(Xana(:,k)),t,imag(Xabc(:,k)),'--');
title('Imaginary');
xlabel('Time');
The comparison plot is:
The output of ode45 matches the magnitude and real parts of the solution very well, but the imaginary portion is out-of-phase by exactly π.
However, since ode45's error estimator only looks at norms, the phase difference is not noticed which may lead to problems depending on the application.
It will be noted that while the matrix exponential solution is far more costly than ode45 for the same number of time vector elements, the analytical solution will produce the exact solution for any time vector of any density given to it. So for long time solutions, the matrix exponential can be viewed as an improvement in some sense.
I have the following differential equation which I'm not able to solve.
We know the following about the equation:
D(r) is a third grade polynom
D'(1)=D'(2)=0
D(2)=2D(1)
u(1)=450
u'(2)=-K * (u(2)-Te)
Where K and Te are constants.
I want to approximate the problem using a matrix and I managed to solve
the similiar equation: with the same limit conditions for u(1) and u'(2).
On this equation I approximated u' and u'' with central differences and used a finite difference method between r=1 to r=2. I then placed the results in a matrix A in matlab and the limit conditions in the vector Y in matlab and ran u=A\Y to get how the u value changes. Heres my matlab code for the equation I managed to solve:
clear
a=1;
b=2;
N=100;
h = (b-a)/N;
K=3.20;
Ti=450;
Te=20;
A = zeros(N+2);
A(1,1)=1;
A(end,end)=1/(2*h*K);
A(end,end-1)=1;
A(end,end-2)=-1/(2*h*K);
r=a+h:h:b;
%y(i)
for i=1:1:length(r)
yi(i)=-r(i)*(2/(h^2));
end
A(2:end-1,2:end-1)=A(2:end-1,2:end-1)+diag(yi);
%y(i-1)
for i=1:1:length(r)-1
ymin(i)=r(i+1)*(1/(h^2))-1/(2*h);
end
A(3:end-1,2:end-2) = A(3:end-1,2:end-2)+diag(ymin);
%y(i+1)
for i=1:1:length(r)
ymax(i)=r(i)*(1/(h^2))+1/(2*h);
end
A(2:end-1,3:end)=A(2:end-1,3:end)+diag(ymax);
Y=zeros(N+2,1);
Y(1) =Ti;
Y(2)=-(Ti*(r(1)/(h^2)-(1/(2*h))));
Y(end) = Te;
r=[1,r];
u=A\Y;
plot(r,u(1:end-1));
My question is, how do I solve the first differential equation?
As TroyHaskin pointed out in comments, one can determine D up to a constant factor, and that constant factor cancels out in D'/D anyway. Put another way: we can assume that D(1)=1 (a convenient number), since D can be multiplied by any constant. Now it's easy to find the coefficients (done with Wolfram Alpha), and the polynomial turns out to be
D(r) = -2r^3+9r^2-12r+6
with derivative D'(r) = -6r^2+18r-12. (There is also a smarter way to find the polynomial by starting with D', which is quadratic with known roots.)
I would probably use this information right away, computing the coefficient k of the first derivative:
r = a+h:h:b;
k = 1+r.*(-6*r.^2+18*r-12)./(-2*r.^3+9*r.^2-12*r+6);
It seems that k is always positive on the interval [1,2], so if you want to minimize the changes to existing code, just replace r(i) by r(i)/k(i) in it.
By the way, instead of loops like
for i=1:1:length(r)
yi(i)=-r(i)*(2/(h^2));
end
one usually does simply
yi=-r*(2/(h^2));
This vectorization makes the code more compact and can benefit the performance too (not so much in your example, where solving the linear system is the bottleneck). Another benefit is that yi is properly initialized, while with your loop construction, if yi happened to already exist and have length greater than length(r), the resulting array would have extraneous entries. (This is a potential source of hard-to-track bugs.)
I have to analyze 802.11 saturation throughput using matlab, and here is my problem. I'm trying to solve parametric equations below (parameters are m,W,a) using solve function and i get
Warning: Explicit solution could not be found
How could I solve above equations using matlab?
I guess you were trying to find an analytical solution for tau and p using symbolic math. Unless you're really lucky with your parameters (e.g. m=1), there won't be an analytical solution.
If you're interested in numerical values for tau and p, I suggest you manually substitue p in the first equation, and then solve an equation of the form tau-bigFraction=0 using, e.g. fzero.
Here's how you'd use fzero to solve a simple equation kx=exp(-x), with k being a parameter.
k = 5; %# set a value for k
x = fzero(#(x)k*x-exp(-x),0); %# initial guess: x=0