c # - решение комплексного набора ODE

2

Введение Некоторые наборы ODE не могут быть решены аналитически. В этом случае существует множество хорошо известных методов, особенно в типичном научном программном обеспечении, таком как MATLAB. Пока вы остаетесь с этим, все в порядке. Но проблема начинается, если вы попытаетесь перенести эту функцию в другую среду. В моем случае мне это нужно в С#.

Некоторые детали Конечно, есть некоторые библиотеки С# для ODE, но в большинстве случаев (по крайней мере, в этом, с которыми я знаком), они довольно ограничены. Давайте посмотрим на библиотеку OSLO, вот пример запроса:

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

Как видите, он не позволяет предоставлять дополнительную поддержку не-OD-уравнений или встроенных алгоритмов. Это немного ограничено, если мы, например, должны решить настройку следующим образом:

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

В этом случае представленная выше библиотека кажется неэффективной. В C++ я использую библиотеку odeint by boost. Я могу определить структуру как это:

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

И назовите это так:

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

Эта проблема

Вопрос в том, какая библиотека для С# предоставит мне эту функциональность в дополнение к решению жестких наборов од? Производительность очень важна, так как набор од может содержать 25+ уравнения + много вспомогательных алгебраических уравнений. Чтобы быть более конкретным - я не могу рассчитать даже аналитический якобиан, поскольку он не будет постоянным во времени, поэтому выбор потенциальных решателей ограничен.

  • 0
    Почему бы вам не взять свой собственный решатель Рунге-Кутта?
  • 0
    Вы имеете в виду построить алгоритм с нуля? В том числе решение, уточнение данных до определенных шагов и т. Д.? Это похоже на изобретение колеса.
Показать ещё 7 комментариев
Теги:
algorithm
ode
numerical-methods

1 ответ

0
Лучший ответ

Вы должны быть в состоянии использовать

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

как длинная форма определения лямбда-делегата, то есть использование этого x => x*x сокращенно для x => { return x*x; } x => { return x*x; } что является сокращением для delegate(x) { return x*x; } delegate(x) { return x*x; } и так далее.

  • 0
    Это работает, что ясно доказывает, что я должен много узнать о лямбда-выражениях. Тем не менее, кажется, что использование Ode.GearBDF может быть лучше для жестких наборов ODE (требуется больше испытаний, чтобы сказать это наверняка). Это не проблема, так как синтаксис тот же. Я надеюсь, что эта информация будет полезна для других, как это было для меня.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню