2013-03-10 44 views
2

我想用boost::odeint來解決不同變量集合的微分方程 - 比如std::vector類型 - 並行。一種解決方案當然是將所有變量組合成一個大的矢量,然後將其用作狀態變量。狀態類型提升:融合提升:odeint

但是,我更喜歡更優雅的解決方案,如採用boost::fusion作爲狀態類型,然後保存不同的向量。據我瞭解,從postingrelated problem的實施,原則上,這樣做沒有任何障礙。我只錯過,特別是混凝土implementation-關於

代數,經營權規範和

需要創建例如錯誤步進的調整一些提示。現有的哪些實現 - 例如odeint::fusion_algebra - 可以直接使用,在這種情況下還需要做什麼?

回答

1

使用boost::fusion編譯時的容器如果細跟fusion_algebradefault_operations,只要它的每個元素支持

  • 乘以一個標量(*)
  • 加法和減法(+, - )
  • 調整大小

這是基本的浮點類型的情況下,像doublefloat,或甚至std::complex。支持表達式模板的類型也是如此,例如MTL,boost :: ublas或vexcl和viennacl中的矢量和矩陣類型。但是對於std::vector來說這是不可能的,因爲向量沒有實現或者重載相應的+ * - /運算符。在這種情況下,你有三種可能性

  1. 選擇一個矢量格式支持表達式模板
  2. 實現它迭代與融合的for_each融合序列嵌套的代數和從子代數
  3. 實現自定義調用正確for_each迭代遍歷融合序列元素的操作。

注1:調整通常意味着,如果你的類型需要調整您通過

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

專門is_resizable的編譯時間真實的,例如,專門resize_impl<>same_size<>。看看默認的實現。這很容易,應該只是一個單線。注2:如果您還需要步長控制,並且選擇帶有expresson模板的矢量類型,則運算符/和函數max必須存在,並且它們必須執行按元素劃分和按元素劃分的最大值。這可能是棘手的實施。如果您需要一些幫助,請隨時與我們聯繫。

+0

感謝您快速詳盡地回答問題並提供如此出色的圖書館。正如你猜對的那樣,我真的需要步長控制,因此最簡單的方案不適合我。考慮到使用boost :: fusion工作所需的工作量,我可能會堅持使用value_types的組合向量。另外 - 是否有一種簡單的方法來使用valarray state_type? Valarray沒有提供迭代器,因此可能無法工作? – floyd85 2013-03-11 15:21:38

+0

我從來沒有使用valarrays。知道是否可以使用odeint會很有趣。但我不會推薦使用valarrays。他們很少使用。尋找MTL,ublas,Eigen ......等載體或某些高級載體類型通常是更好的選擇。 – headmyshoulder 2013-03-12 14:09:00