5-th order differential equation with BVP5c - matlab

I am trying to solve this differential equation :
In order to do so : there is a mathematical part consisting on determining the boundary conditions of this problem that are defined as :
More precisely, the first BC is formulated differently since we need an extra condition in order to "close" the system.
We choose to write : . Then, we solve asymptotically the new problem : . Therefore, there are 5 roots as a solution to this differential equation : 2 of these roots are growing exponentials that the following condition allows to eliminate :
We deduce two BC written as :
In addition to the BC :
And : F(0) = 1
I have tried to implement this problem by using bvp5c of Matlab but I haven't succeeded. Here is my code :
eta0 = 20;
etamesh = [linspace(-eta0,0,100),linspace(0,eta0,100)];
Finit = [1; 0.5; 1; 0; 0];
solinit = bvpinit(etamesh,Finit)
sol = bvp5c(#fun_ode, #bc, solinit);
figure()
plot(sol.x,sol.y(1,:),'linewidth',1.5) % Plotting F
ylim([-2 2]);
hold on
plot(sol.x,sol.y(3,:),'linewidth',1.5) % Plotting F''
plot(sol.x,sol.y(5,:),'linewidth',1.5) % Plotting F''''
grid on
legend("F","F''","F''''",'location','northwest')
function dFdeta = fun_ode(eta,F,region)
dFdeta=[F(2);F(3);F(4);F(5);(1-F(1))/F(1)^3];
end
% Boundary conditions :
% F'''(-eta0) = F''''(-eta0) = 0
% F(0) = 1
% [1] = [2] = 0 in eta = eta0
function res = bc(FL,FR)
alpha = cos(3*pi/5) + 1i*sin(3*pi/5);
beta = cos(7*pi/5) + 1i*sin(7*pi/5);
gamma = abs(alpha);
res = [FL(4,1) ; FL(5,1);...
FR(1,1) - 1 ;...
FR(1,1)-FL(1,2) ; FR(2,1)-FL(2,2) ; FR(3,1)-FL(3,2) ; FR(4,1)-FL(4,2) ; FR(5,1)-FL(5,2) ;...
(1-(beta+alpha))*FR(3,2) + (-(alpha+beta)+gamma^2)*FR(2,2) ; (-(beta+alpha)+gamma^2)*FR(3,2) + (FR(2,2))*gamma^2];
end
I am mainly struggling with the implementation of the two coupled BC written above and the continuity condition for F(0)...
I have commented my code and I would be grateful if someone give some time to look for potential errors or providing some advices.
Thank you very much.

Related

Why " The boundary condition function BCFUN should return a column vector of length 5" error message is came?

function Y6
solinit = bvpinit(linspace(0,1),[0;3;1;1],2);
sol = bvp4c(#ode, #bc, solinit);
y = sol.y;
time = sol.parameters*sol.x;
ut = -y(4,:);
figure(1);
plot(time,y([1 2],:)','-'); hold on;
plot(time, ut, 'k:');
axis([0 time(1,end) -1.5 3]);
text(1.3,2.5,'x_1(t)');
text(1.3,.9,'x_2(t)');
text(1.3,-.5,'u(t)');
xlabel('time');
ylabel('states');
title('Numerical solution');
hold off;
% -------------------------------------------------------------------------
% ODE's of augmented states
function dydt = ode(t,y,T)
dydt = T*[2*y(2);4*y(4);0;-2*y(3)];
% -------------------------------------------------------------------------
% boundary conditions: x1(0)=11;p2(0)=2; x2(tf)=3; 3*p1(tf)+p2(2)^2=0
function res = bc(ya,yb,T)
res = [ ya(1) - 11; ya(4); yb(2) - 3; 3*yb(3)+yb(4)^2];
I don't know why The boundary condition function BCFUN should return a column vector of length 5 error message is came.
Can you explain to me please? Thank you so much
The unknown parameters or constants, here T, also count as components. Thus your state has overall 4+1=5 components, requiring the setting of 5 boundary conditions.
Sometimes that is obvious, for instance in a Sturm-Liouville eigenvalue computation with the eigenvalue as parameter you want to avoid the zero solution, so demand that, e.g., the square integral has value 1.
In a ballistic shot with the flight time as parameter where you fix the location of the canon and the target as obvious boundary conditions it is not that obvious what to select as additional BC, but possibilities are to fix the initial speed or the initial angle.
I might be rusty, but I get from the variation of
L = 3*(x1(T)-9)^2 + integral(0,T, 2*u^2 +p^T*(F(x,u)-x') )
the saddle point conditions
T : 0 = 12*x2(T)*(x1(T)-9) + 2*u(T)^2 (BC5)
x(t) : 0 = p'(t)+F_x(x,u)^T*p
p1'(t) = -2*p2(t) (DE3)
p2'(t) = 0 (DE4)
p(t) : x'(t) = F(x,u)
x1'(t) = 2*x2(t) (DE1)
x2'(t) = 4*u(t) (DE2)
u(t) : 0 = 4*u + p^T*F_u(x,u)
u(t) = -p2(t) (OPT)
x1(T): -p1(T)+6*(x1(T)-9) (BC3)
x2(0): 0 = p2(0) (BC4)
This can be directly evaluated as p2=-u=0 (BC4+DE4+OPT) are constant, likewise p1 = 6*(x1(T)-9) (BC3+DE3). This in turn forces x1(T)=9 (BC5) As now x2(t)=3 is constant, we get x1(t)=11+6*t. Then the remaining expression of the functional 3*(2+6*T)^2 is minimal for T=-1/3. For T=0 the minimal value of the functional is L=12.

Implementing a Gaussian blur kernel in MATLAB from scratch

I recently implemented a box average filter in MATLAB. I found it to be a fun exercise. I wanted to do the same thing with a Gaussian blur filter, so as to eventually solve some super-resolution problems. But I have found this much more challenging. There are several questions on here about such a topic. All of the answers in those topics have been very helpful. However, I have not been able to create the kernel successfully. Currently my code simply implements an averaging filter. Wiki page for Gaussian blur: https://en.wikipedia.org/wiki/Gaussian_blur
Here is my code:
function out_im = GaussianBlur(in_im, sigma, N) %input image, sigma, Number of iterations
[rows, cols] = size(in_im);
orig_im = in_im;
Filter = zeros(rows,cols);
w2 = 0;
for k = 1 : N
for LR_ROWS = 2 : 1 : rows - 1
for LR_COLS = 2 : 1 : cols -1
for i = -1 : 1
for j = -1 : 1
w1 = exp(-(orig_im(LR_ROWS, LR_COLS).^2/(2*sigma^2)));
w2 = w2 + w1;
Filter(LR_ROWS, LR_COLS) = Filter(LR_ROWS, LR_COLS) + ...
w1*orig_im(LR_ROWS+i, LR_COLS+j);
end
end
Filter(LR_ROWS, LR_COLS) = Filter(LR_ROWS, LR_COLS)./w2;
w2 = 0;
end
end
orig_im = Filter;
Filter = zeros(rows, cols);
end
out_im = orig_im;
end
Any suggestions or advice is greatly appreciated! Thank you.

Matlab - Solving a system of 2 matricial equations : building each element of matrix solution

With Matlab, I have a matrix solution to find from 2 matricial equations (size matrix is 7x7). Here the 2 equations to solve with "a" and "b" are the unknow matrices and where F1, F2, P1 and P2, D, D2, D are known. Solving "a" and "b" would allow me to build a new matrix P = a . P1 + b . P2 . (remark : D matrix is equal to : D = a.a.D1 + b.b.D2 with D1and D2 diagonal matrices) :
a.a + a.P1.b.P2^T + b.P2.a.P1^T + b.b - Id = 0 (equation 1)
F1.a.P1 + F1.b.P2 + F2.a.P1 + F2.b.P2 − (a.P1 + b.P2).D = 0 (equation 2)
Question 1) Is there a solver in Matlab that would allow to directly find matrices "a" and "b" ?
Question 2) If there is no directly solving, I think that I have to solve each solution a(i,j) and b(i,j) by using a double loop on i and j indices and call fsolve in inner loop.
The problem is that I have to respect the order in matricial product and it is difficult to not make errors when I implement the code.
Here the 2 equations that I must solve on "a" and "b" unknown :
equation(1)
equation(2)
So I tried to implement the solving of each matrix element, i.e a(i,j) and b(i,j)
For this, I am using a symbolic array x[7 7 2] and did :
% eigenv_sp = P1
% eigenv_xc = P2
% FISH_sp = F1
% FISH_xc = F2
% FISH_eigen_sp = D1
% FISH_eigen_xc = D2
% Fisher matrices
F1 = FISH_sp;
F2 = FISH_xc;
% Transposed matrix
transp_eigenv_sp = eigenv_sp'
transp_eigenv_xc = eigenv_xc'
% Symbolic variables
x = sym([7 7 2]);
aP1 = sym([7 7]);
aP1T = sym([7 7]);
bP2 = sym([7 7]);
bP2T = sym([7 7]);
d1 = sym([7 7]);
d2 = sym([7 7]);
d = sym([7 7]);
ad1 = sym([7 7]);
bd2 = sym([7 7]);
for k=1:7
for l=1:7
aP1(k,l) = sum(x(k,1:7,1).*eigenv_sp(1:7,l));
bP2(k,l) = sum(x(k,1:7,2).*eigenv_xc(1:7,l));
aP1T(k,l) = sum(x(k,1:7,1).*transp_egeinv_sp(1:7,l));
bP2T(k,l) = sum(x(k,1:7,2).*transp_egeinv_xc(1:7,l));
a2(k,l) = sum(x(k,1:7,1).*x(1:7,l,1));
b2(k,l) = sum(x(k,1:7,2).*x(1:7,l,2));
d1(k,l) = FkSH_ekgen_sp(k,l);
d2(k,l) = FkSH_ekgen_xc(k,l);
d(k,l) = d1(k,l) + d2(k,l);
ad1(k,l) = sum(x(k,1:7,1).d1(1:7,l));
bd2(k,l) = sum(x(k,1:7,2).d2(1:7,l));
end
end
% Function that represents `(a,b)(i,j)` unknown element represented by `(y(i,j,1),y(i,j,2))`
myfun=#(x,i,j) [
% First equation
sum(x(i,1:7,1).*x(1:7,j)) + sum(aP1(i,1:7).*bP2T(1:7,j)) + sum(bP2(i,1:7).*aP1T(1:7,j)) + sum(x(i,1:7).*x(1:7,2)) - eq(i,j);
% second equation
sum(F1(i,1:7).*aP1(1:7,j)) + sum(F1(i,1:7).*bP2(1:7,j)) + sum(F2(i,1:7).*aP1(1:7,j)) + sum(F2(i,1:7).*bP2(1:7,j)) - ...
sum(aP1(i,1:7).*ad1(1:7,j)) + sum(bP2(i,1:7).*ad1(1:7,j)) + sum(adP1(i,1:7).*dP2(1:7,j)) + sum(bP2(i,1:7).*dP2(1:7,j));
]
% Solution of system of non linear equations with loop
y = zeros(7, 7, 2);
for i=1:7
for j=1:7
a0 = 1e7;
b0 = 1e7;
x0 = [ a0 b0];
y(i,j,:) = fsolve(#(x)myfun(x,i,j),x0)
end
end
But at the execution, I have the following error :
Index exceeds matrix dimensions.
Error in sym/subsref (line 814)
R_tilde = builtin('subsref',L_tilde,Idx);
Error in compute_solving_Matricial_Equations_dev (line 60)
aP1(k,l) = sum(x(k,1:7,1).*eigenv_sp(1:7,l));
I don't understand where is the issue, I only iterate on index 1:7, if someone could see what's wrong ?
Update 1
I wonder if I have the right to use for a given index i the symbolic expression x(1:7,i,1) whereas this array is not known numerically but defined only from a symbolic point of view.
Update 2
Maybe I have a clue.
If I do an expand of the symbolic array x (of size (7,7,2)), I get :
>> expand(sum(x(1,1:7).*x(1:7,1)))
Index exceeds matrix dimensions.
Error in sym/subsref (line 814)
R_tilde = builtin('subsref',L_tilde,Idx);
So, the only thing to done I think is to explicitly write the 7x7 equations
with 7x7 = 49 couples unknown x(i,j,1) and x(i,j,2) which corresponds to a(i,j) and b(i,j) matrices.
Update 3
I think the key point is to put into function myfun the 2 matrical equations but with taking into account of the 49 (7x7) couples (a(i,j) and b(i,j)) unknown that I defined previously as symbolic variables with array x[7 7 2].
And second point, I must to "make understand" to fsolve that we are searching for each iteration (double loop on (i,j)) the value of a(i,j) and b(i,j) given the whole 49 equations. Maybe it would be necessary to expand for example the expression of x(i,1:7) or x(1:7,j) in myfun function but I don't know how to proceed.

Solving Coupled partial differential equations of stiff nature using MATLAB

I want to solve coupled partial differential equations of first order, which are of stiff nature. I have coded in MATLAB to solve this pde's, I have used Method of line to convert PDE into ODE, and i have used beam and warmings(second order upwind) method to discritize the spatial derivative. The discretization method is total variation diminishing(TVD) to eliminate the oscillation. But rather using TVD and ode15s solver to integrate resultant stiff ode's the resultant plot is oscillatory(not smooth). What should i do to eliminate this oscillation and get correct results.
I have attached my MATLAB code.. please see it and suggest some improvement.
∂y(1)/∂t=-0.1 ∂y(1)/∂x + (0.5*e^(15*(y(2)⁄(1+y(2))))*(1- y(1))
∂y(2)/∂t=-0.1 ∂y(2)/∂x - (0.4*e^(15*(y(2)⁄(1+y(2))))*(1- y(1))-0.4
Initial condition: at t = 0 y(1)= y(2)=0
Boundary condition: y(1)= y(2) = 0 at x=0
I have attached my MATLAB code.. please see it and suggest some improvement.
function brussode(N)
if nargin<1
N = 149;
end
tspan = [0 10];
m = 0.00035
t = (1:N)/(N+1)*m;
y0 = [repmat(0,1,N); repmat(0,1,N)];
p = 0.5
q = 0.4
options = odeset('Vectorized','on','JPattern',jpattern(N));
[t,y] = ode15s(#f,tspan,y0,options);
a = size(y,2)
u = y(:,1:2:end);
x = (1:N)/(N+1);
figure;
%surf(x,t(end,:),u);
plot(x,u(end,:))
xlabel('space');
ylabel('solution');
zlabel('solution u');
%--------------------------------------------------------------
%Nested function -- N is provided by the outer function.
%
function dydt = f(t,y)
%Derivative function
dydt = zeros(2*N,size(y,2)); %preallocate dy/dt
x = (1:N)/(N+1);
% Evaluate the 2 components of the function at one edge of the grid
% (with edge conditions).
i = 1;
%y(1,:) = 0;
%y(2,:) = 0;
dydt(i,:) = -0.1*(N+1)*(y(i+2,:)-0)+ (0.01/2)*m*((N+1).^3)*(y(i+2,:)-0) + p*exp(15*(0/(1+0)))*(1-0);
dydt(i+1,:) = -0.1*(N+1)*(y(i+3,:)-0)+ (0.01/2)*m*((N+1).^3)*(y(i+3,:)-0) - q*exp(15*(0/(1+0)))*(1-0)+0.25;
i = 3;
%y(1,:) = 0;
%y(2,:) = 0;
dydt(i,:) = -0.1*(N+1)*(y(i+2,:)-y(i,:)) + (0.01/2)*m*((N+1).^3)*(y(i+3,:)-y(i,:)) + p*exp(15*(y(i+1,:)/(1+y(i+1,:))))*(1-y(i,:));
dydt(i+1,:) = -0.1*(N+1)*(y(i+3,:)-y(i+1,:)) + (0.01/2)*m*((N+1).^3)*(y(i+3,:)-y(i,:)) - q*exp(15*(y(i+1,:)/(1+y(i+1,:))))*(1-y(i,:))+0.25;
%Evaluate the 2 components of the function at all interior grid
%points.
i = 5:2:2*N;
%y(1,:) = 0;
% y(2,:) = 0;
dydt(i,:) = (-0.1/2)*(N+1)*(3*y(i,:)-4*y(i-2,:)+y(i-4,:)) +(0.01/2)*m*((N+1).^3)*(y(i,:)-2*y(i-2,:)+y(i-4,:))+ p*exp(15*(y(i+1,:)/(1+y(i+1,:))))*(1-y(i,:));
dydt(i+1,:) = (-0.1/2)*(N+1)*(3*y(i+1,:)-4*y(i-1,:)+y(i-3,:))+(0.01/2)*m*((N+1).^3)*(y(i+1,:)-2*y(i-1,:)+y(i-3,:)) - q*exp(15*(y(i+1,:)/(1+y(i+1,:))))*(1-y(i,:))+0.25;
end
%-------------------------------------------------------------
end %brussode
%-------------------------------------------------------------
% Subfunction -- the sparsity pattern
%
function S = jpattern(N)
% Jacobian sparsity patter
B = ones(2*N,5);
B(2:2:2*N,2) = zeros(N,1);
B(1:2:2*N-1,4) = zeros(N,1);
S = spdiags(B,-2:2,2*N,2*N);
end
%-------------------------------------------------------------

Matlab - Unexpected Results from Differential Equation Solver Ode45

I am trying to solve a differential equation with the ode solver ode45 with MATLAB. I have tried using it with other simpler functions and let it plot the function. They all look correct, but when I plug in the function that I need to solve, it fails. The plot starts off at y(0) = 1 but starts decreasing at some point when it should have been an increasing function all the way up to its critical point.
function [xpts,soln] = diffsolver(p1x,p2x,p3x,p1rr,y0)
syms x y
yp = matlabFunction((p3x/p1x) - (p2x/p1x) * y);
[xpts,soln] = ode45(yp,[0 p1rr],y0);
p1x, p2x, and p3x are polynomials and they are passed into this diffsolver function as parameters.
p1rr here is the critical point. The function should diverge after the critical point, so i want to integrate it up to that point.
EDIT: Here is the code that I have before using diffsolver, the above function. I do pade approximation to find the polynomials p1, p2, and p3. Then i find the critical point, which is the root of p1 that is closest to the target (target is specified by user).
I check if the critical point is empty (sometimes there might not be a critical point in some functions). If its not empty, then it uses the above function to solve the differential equation. Then it plots the x- and y- points returned from the above function basically.
function error = padeapprox(m,n,j)
global f df p1 p2 p3 N target
error = 0;
size = m + n + j + 2;
A = zeros(size,size);
for i = 1:m
A((i + 1):size,i) = df(1:(size - i));
end
for i = (m + 1):(m + n + 1)
A((i - m):size,i) = f(1:(size + 1 - i + m));
end
for i = (m + n + 2):size
A(i - (m + n + 1),i) = -1;
end
if det(A) == 0
error = 1;
fprintf('Warning: Matrix is singular.\n');
end
V = -A\df(1:size);
p1 = [1];
for i = 1:m
p1 = [p1; V(i)];
end
p2 = [];
for i = (m + 1):(m + n + 1)
p2 = [p2; V(i)];
end
p3 = [];
for i = (m + n + 2):size
p3 = [p3; V(i)];
end
fx = poly2sym(f(end:-1:1));
dfx = poly2sym(df(end:-1:1));
p1x = poly2sym(p1(end:-1:1));
p2x = poly2sym(p2(end:-1:1));
p3x = poly2sym(p3(end:-1:1));
p3fullx = p1x * dfx + p2x * fx;
p3full = sym2poly(p3fullx); p3full = p3full(end:-1:1);
p1r = roots(p1(end:-1:1));
p1rr = findroots(p1r,target); % findroots eliminates unreal roots and chooses the one closest to the target
if ~isempty(p1rr)
[xpts,soln] = diffsolver(p1x,p2x,p3fullx,p1rr,f(1));
if rcond(A) >= 1e-10
plot(xpts,soln); axis([0 p1rr 0 5]); hold all
end
end
I saw some examples using another function to generate the differential equation but i've tried using the matlabFunction() method with other simpler functions and it seems like it works. Its just that when I try to solve this function, it fails. The solved values start becoming negative when they should all be positive.
I also tried using another solver, dsolve(). But it gives me an implicit solution all the time...
Does anyone have an idea why this is happening? Any advice is appreciated. Thank you!
Since your code seems to work for simpler functions, you could try to increase the accuracy options of the ode45 solver.
This can be achieved by using odeset:
options = odeset('RelTol',1e-10,'AbsTol',1e-10);
[T,Y] = ode45(#function,[tspan],[y0],options);