Состояние типа boost: fusion in boost: odeint

Я хочу использовать boost::odeint решать дифференциальные уравнения для различных наборов переменных, скажем std::vector введите параллельно. Конечно, одним из решений было бы объединение всех переменных в большой вектор, который затем используется в качестве переменной состояния.

Тем не менее, я бы предпочел более элегантное решение, как использование boost::fusion как тип состояния, который затем содержит различные векторы. Насколько я понял из проводка и реализация для связанная проблема, в принципе нет никаких препятствий для этого. Я только пропускаю несколько советов для конкретной реализации, в частности, относительно правильной спецификации

алгебра, операции и изменение размера

требуется для создания например ошибки степпера. Какая из существующих реализаций — например, odeint::fusion_algebra— можно ли использовать напрямую, и что еще предстоит сделать в этом случае?

2

Решение

С помощью boost::fusion компилировать время контейнеры, если хорошо с fusion_algebra и default_operationsДо тех пор, пока каждый из его элементов поддерживает

  • Умножение со скаляром (*)
  • Сложение и вычитание (+, -)
  • Изменение размера

Это относится к элементарным типам с плавающей запятой, таким как double, float, или даже std::complex, Это также относится к типам, поддерживающим шаблоны выражений, таким как векторные и матричные типы из MTL, boost :: ublas, или vexcl и viennacl. Но это не возможно для std::vector, поскольку векторы не реализуют или не перегружают соответствующие операторы + * — /. В этом случае у вас есть три возможности

  1. Выберите тип вектора, поддерживающий шаблоны выражений
  2. Реализуйте вложенную алгебру, которая повторяет последовательность слияния с for_each и называет правильный for_each из подалгебры
  3. Реализуйте пользовательскую операцию, которая перебирает элементы последовательности слияния.

Примечание 1: Изменение размера обычно означает, что, если ваш тип требует изменения размера, вы специализируетесь is_resizable до времени компиляции, например, через

template<>
is_resizable< YourType > : boost::true_type { };

и специализироваться resize_impl<> а также same_size<>, Посмотрите на реализации по умолчанию. Это действительно легко и должно быть только одной строкой.

Примечание 2: Если вам также требуется контроль размера шага, и вы решили использовать векторный тип с шаблонами выражений, оператор / и функция max должны существовать, и они должны выполнять поэлементное деление и поэтапное макс. Это может быть сложно реализовать. Если вам нужна помощь, не стесняйтесь обращаться к нам снова.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]