简体   繁体   中英

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM