问题
Introduction Some sets od ODE can't be solved analytically. In this case there are plenty of well-know methods, especially in typical scientific software like MATLAB. As long as you stay with it, all is fine. But the problem starts if you try to port this functionality to other environment. In my case I need it in C#.
Some details Of course, there are some C# libs for ODE's but in most cases (at least in this which i'm familiar with), there are quite limited. Let's look at OSLO library, here's an example query:
var sol = Ode.RK547M(0, new Vector(5.0, 1.0),
(t, x) => new Vector(
x[0] - x[0] * x[1],
-x[1] + x[0] * x[1]));
As you can see, it doesn't allow to provide any additional support non-OD equations, nor embedded algorithms. It's a bit to limited if we for example have to solve setup like this:
a=x*2+7
b=y*x+3
c- need to be calculated with external algorithm basing and "b" and "x"
dx/dt=x - xy + a + c
dx/dt=-y +xy + b
In this case presented above lib seems to be not efficient. In C++ I use odeint library by boost. I can define a struct like this:
struct solveODE
{
void operator()( const vector_type &y , vector_type &ODE , const double t )
{
double x=y[0];
double y=y[1];
a=x*2+7;
b=y*x+3;
additional_solve(b, x);
ODE[0]=x - xy + a + c;
ODE[1]=-y +xy + b;
}
};
And call it like this:
integrate_const(make_dense_output<stepper_type>( 1E-12, 1E-6 ),
solveODE(),
y, 0.0, t_end, dt ,
std::bind(&calc::printResults , std::ref(*this) , pl::_1 , pl::_2));
The problem
The question is which library for C# will me provide this functionality, in addition with solving stiff ode sets? The performance is quite important as ode set may contain 25+ equations + a lot of support algebraic equations. To be more specific - I can't calculate even analytic Jacobian as it will be not constant in time, so the selection of potential solvers is limited.
回答1:
You should be able to use
var sol = Ode.RK547M(0, new Vector(5.0, 1.0),
(t, u) => {
double x=u[0], y=u[1];
double a=x*2+7, b=y*x+3;
double c = additional_solve(b, x);
return new Vector(
x - x*y + a + c,
-y +x*y + b
);
});
as the long form of a lambda delegate definition, that is, using that x => x*x
is short for x => { return x*x; }
which is short for delegate(x) { return x*x; }
and so on.
来源:https://stackoverflow.com/questions/54609747/c-sharp-solving-complexed-ode-set