2013-03-10 2 views
2

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

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

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

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

ответ

1

Использование 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: Если вам также требуется управление размером шага, и вы решите взять векторный тип с шаблонами экспресса, то оператор / должен существовать, и они должны выполнять элементное разделение и макс. Это может быть сложно реализовать. Если вам нужна помощь, не стесняйтесь обращаться к нам снова.

+0

Благодарим вас за быстрый и подробный ответ и за предоставление такой большой библиотеки.Как вы правильно догадались, мне действительно нужен контроль размера шага, и поэтому самое легкое предложение не будет работать для меня. Учитывая объем работы, необходимой для выполнения этой работы с boost :: fusion, я, вероятно, придерживаюсь комбинированного вектора значений_значения. Альтернативно, может быть, есть простой способ использования valarray state_type? Valarray не предоставляет итератор и, следовательно, не может работать из коробки? – floyd85

+0

Я никогда не пользовался ванариями. Было бы интересно узнать, работает ли с odeint. Но я бы не рекомендовал использовать валерьяны. Они редко используются. Для векторов или некоторых продвинутых векторных типов из MTL, ublas, Eigen, ... обычно является лучшей альтернативой. – headmyshoulder