Runge-Kutta(RK4) for stiff IVP - python

I need a solver of stiff Inital-Value Problems (IVP) in python exploiting RK4 preferably explicit. I have been searching for past few days but could not find it. Following are my queries:
Does the solver, i.e. any module, exist?
If no, will it be reasonable to code one? I am asking this because I can't find any reference for using RK4-explicit for stiff problems.

scipy seems to be able to do it (http://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.ode.html) if you set the set_integratorto dopri5 you get a RK4 solver

RK4 or the classical Runge-Kutta method is one specific integration method. As an explicit method, it is imminently unsuitable for stiff problems. As a one-method method, it has no intrinsic features for step size control.
For stiff problems, you want implicit RK methods with step size control.

Related

Getting dual solutions in pyscipopt

If we need dual solutions of a LP solve, is it necessary to switch off presolve and disable propagation? Is there some other (more relaxed) setting which achieves the same goal?
Also, can we get the entire dual solution vector instead of calling getDualsolLinear for every constraint?
Thanks!
Yes, I think you need to turn them off, since SCIP does not offer dual postsolving (since it is itself not an LP solver). Therefore, you will not be able to retrieve dual solutions of constraints that get removed/changed/etc during presolving or propagation.
If you really need presolving, I suggest to just directly use an LP solver (e.g. SoPlex or HiGHS) although I'm not sure about the availability of a Python interface in those cases.
There is no method that returns the entire solutions vector (though it would of course be easy to just implement a small wrapper yourself that calls getDualSolLinear on every constraint.

How can I limit the order of the integration that the scipy solve_ivp integrator is allowed to build to nothing higher than 1st order?

Question is as above. After reading the documentation, I can change the integrator itself (RK45,RK23, DOP853, etc), however I cannot find information on the order of these integrators, or on ways to limit the integrator to 1st order.
How can this be done? Do I have to use a particular ODE solver method that is by default 1st order, or can I edit any method to be 1st order?
For many integrators, the order is a fixed property. There are some methods – let’s call them meta integrators – that switch between different integrators, but they are still limited to the order of these integrators. Thus, you cannot simply control the order of the integrator and leave everything else the same.
If you really want a first-order method, it’s easy to implement the Euler method – unless you want step-size adaption.
Mind that the order of an integrator denotes how its error behaves for small step sizes. In this respect, a higher order is nothing that should cause a problem per se. I would therefore find it remarkable if using a first-order method solves a problem. Sometimes, individual methods can have problems or the problem is stiff, but here the solution is to use another solver (for stiff problems), not a first-order solver. If you consistently observe a result for all solvers, it is by far more likely that this your true result or you made a mistake defining your derivative or similar.

Solving first-order ODE, which contains another ODE (odeint / solve_ivp in Python)

I'm trying to set up a fast numerical solver in Python for a differential problem of the form:
where r is some constant.
I want to integrate A over some time period, t of interest. However, this is complicated by the fact that the dA/dt equation includes another variable B, which itself is described by an ODE dB/dt. B is actually a vector, but I've simplified the expression to try and highlight my problems more clearly.
I currently have a solution using a manual Euler method: ie compute dB/dt (then use B = B_previous + dB/dt * dt) and manually step along using a fixed time step size dt. However, this is slow and unreliable. I imagine it would be far better to use the built-in ODE solvers in Numpy, but I'm not sure this is possible given the coupled nature of the problem I'm trying to solve?
Is this possible using Numpy odeint or solve_ivp please? And if so, can anyone suggest any pointers please! Thanks.
What you have is a coupled differential equation which are standard to solve using Runge kutta, Eulers, and many other methods. You can use this example to guide you in writting your python code:
https://scipy-cookbook.readthedocs.io/items/CoupledSpringMassSystem.html
Keep in mind that that not all equations can be solved with ODEINT. If your ODE is a "stiff" ODE then you will have to choose your algorithm precisely. The definition of a stiff ODE is not completely defined but usually they arise if you have large or non-integral powers of your dependent variable in your ODE.
The first step in solving a coupled ODE though is to use standard methods. If they don't work then look into something else.

How to solve a stiff ode with Python?

I'm a Python beginner. I'm trying to switch some programs that I have in matlab.
I need solve a stiff ode equation, whose inputs are all matrices. In matlab I use
[ttT,uT] = ode23s('SST',t,fT);
For most things you do in Matlab, you can do them with the NumPy module in Python. It can be found here.
You might also find the related module SciPy useful as well.
PyDSTool might also be of relevance to you. It's a wrapper around the Radau solver.
Then you might like to try matplotlib for plotting. It works quite like Matlab's plotting thing.
The following links might help, too:
http://www.ews.uiuc.edu/~mrgates2/ode/
http://wiki.python.org/moin/NumericAndScientific?action=show&redirect=SciPy
Integrate stiff ODEs with Python
If you show me the differential equations I can help you a little more, but in general, a good way to solve a stiff ODE system is through the next sentence:
solution = scipy.integrate.solve_ivp(function, [t_0, t_f], y0, method='BDF', first_step =0.0001, dense_output=True)
where your function has to be defined previously in this way: function(t,variable,parameters)
t_0 = initial value for time
t_f = final value for time
y0 = value of your variables at t_0
For stiff ODE system, I suggest use the method 'BDF' (is typically used in the solve of microkinetic systems in reactors, where the importance of the time could change a lot)
for more infomation about the options of the code: https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html

Integrate stiff ODEs with Python

I'm looking for a good library that will integrate stiff ODEs in Python. The issue is, scipy's odeint gives me good solutions sometimes, but the slightest change in the initial conditions causes it to fall down and give up. The same problem is solved quite happily by MATLAB's stiff solvers (ode15s and ode23s), but I can't use it (even from Python, because none of the Python bindings for the MATLAB C API implement callbacks, and I need to pass a function to the ODE solver). I'm trying PyGSL, but it's horrendously complex. Any suggestions would be greatly appreciated.
EDIT: The specific problem I'm having with PyGSL is choosing the right step function. There are several of them, but no direct analogues to ode15s or ode23s (bdf formula and modified Rosenbrock if that makes sense). So what is a good step function to choose for a stiff system? I have to solve this system for a really long time to ensure that it reaches steady-state, and the GSL solvers either choose a miniscule time-step or one that's too large.
If you can solve your problem with Matlab's ode15s, you should be able to solve it with the vode solver of scipy. To simulate ode15s, I use the following settings:
ode15s = scipy.integrate.ode(f)
ode15s.set_integrator('vode', method='bdf', order=15, nsteps=3000)
ode15s.set_initial_value(u0, t0)
and then you can happily solve your problem with ode15s.integrate(t_final). It should work pretty well on a stiff problem.
(See also Link)
Python can call C. The industry standard is LSODE in ODEPACK. It is public-domain. You can download the C version. These solvers are extremely tricky, so it's best to use some well-tested code.
Added: Be sure you really have a stiff system, i.e. if the rates (eigenvalues) differ by more than 2 or 3 orders of magnitude. Also, if the system is stiff, but you are only looking for a steady-state solution, these solvers give you the option of solving some of the equations algebraically. Otherwise, a good Runge-Kutta solver like DVERK will be a good, and much simpler, solution.
Added here because it would not fit in a comment: This is from the DLSODE header doc:
C T :INOUT Value of the independent variable. On return it
C will be the current value of t (normally TOUT).
C
C TOUT :IN Next point where output is desired (.NE. T).
Also, yes Michaelis-Menten kinetics is nonlinear. The Aitken acceleration works with it, though. (If you want a short explanation, first consider the simple case of Y being a scalar. You run the system to get 3 Y(T) points. Fit an exponential curve through them (simple algebra). Then set Y to the asymptote and repeat. Now just generalize to Y being a vector. Assume the 3 points are in a plane - it's OK if they're not.) Besides, unless you have a forcing function (like a constant IV drip), the MM elimination will decay away and the system will approach linearity. Hope that helps.
PyDSTool wraps the Radau solver, which is an excellent implicit stiff integrator. This has more setup than odeint, but a lot less than PyGSL. The greatest benefit is that your RHS function is specified as a string (typically, although you can build a system using symbolic manipulations) and is converted into C, so there are no slow python callbacks and the whole thing will be very fast.
I am currently studying a bit of ODE and its solvers, so your question is very interesting to me...
From what I have heard and read, for stiff problems the right way to go is to choose an implicit method as a step function (correct me if I am wrong, I am still learning the misteries of ODE solvers). I cannot cite you where I read this, because I don't remember, but here is a thread from gsl-help where a similar question was asked.
So, in short, seems like the bsimp method is worth taking a shot, although it requires a jacobian function. If you cannot calculate the Jacobian, I will try with rk2imp, rk4imp, or any of the gear methods.

Categories