c# - solving complexed ODE set

我的梦境 提交于 2019-11-30 20:41:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!