2011-11-14 61 views
11

相結合我正在做大量的科學編程工作,並對Boost.Units提供了非常好的體驗,Boost.Units提供了編譯時間量的量綱分析(即標記數量與單位和從而通過經典的物理尺寸分析捕捉許多誤差)並且使用特徵2作爲線性代數。然而,Eigen沒有單位的概念,雖然你可以在特徵矩陣中設置標量,但它期望兩個量的乘法產生相同的類型,這對於單位來說顯然是不真實的。例如,代碼如:將一個線性代數庫與Boost :: Units

using boost::units::quantity; 
namespace si = boost::units::si; 
Eigen::Matrix< quantity<si::length>, 2, 1 > meter_vector; 
quantity<si::area> norm = meter_vector.squaredNorm(); 

不起作用,即使它在邏輯上是正確的。

有支持單位的任何矩陣庫嗎?我知道這在過去是很難實現的,C++ 11和decltype將使這更容易,但它肯定可以用C++ 03和模板特化。

回答

7

我相信Blitz ++支持很多Boost.Units功能。

編輯由OP:對於這裏的參考文獻是與我測試的閃電矩陣乘法功能完整的測試代碼:

#include <blitz/array.h> 
#include <boost/units/systems/si/area.hpp> 
#include <boost/units/systems/si/length.hpp> 
#include <boost/units/quantity.hpp> 

using boost::units::quantity; 
namespace si = boost::units::si; 

namespace blitz { 
template< typename U1, typename T1, typename U2, typename T2> 
struct Multiply< quantity<U1,T1>, quantity<U2,T2> > 
{ 
    typedef typename boost::units::multiply_typeof_helper< quantity<U1,T1>, quantity<U2,T2> >::type T_numtype; 

    static inline T_numtype apply(quantity<U1,T1> a, quantity<U2,T2> b) { return a*b; } 
}; 

} 

using namespace blitz; 

int main() { 
    Array< quantity<si::length>, 1 > matrix; 
    Array< quantity<si::area>, 1 > area; 
    area = matrix * matrix; 
    return 0; 
} 
+0

爲了記錄,因爲我必須自己搜索一下:[閃電手冊3.7.1](http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC90)告訴你如何提升用戶 - 定義的類型。感謝提示。 – thiton

0

使用標準的本徵庫插件選項的困難,是需要使用現有的運營商+, - ,*等進行升級單位數量的更換。

例如,對於壓單元自定義類型與*乘法運算符的工作,對於任意CUSTOM_TYPE,它需要像這樣:

template<class X,class Y> 
CUSTOM_TYPE<typename boost::units::multiply_typeof_helper<X,Y>::type> 
operator*(const CUSTOM_TYPE<X>& x,const CUSTOM_TYPE<Y>& y) 
{ 
    typedef typename boost::units::multiply_typeof_helper<X,Y>::type type; 

    return CUSTOM_TYPE<type>(...); 
} 

注意返回類型是多麼的不一樣輸入類型。在這裏你使用模板助手multiply_typeof_helper來創建返回類型。這是因爲乘以秒數不會給你任何單位的數量。但是,默認的Eigen *操作符會返回與輸入相同的「類型」 - 這是問題所在。

另一種選擇是將Eigen矩陣嵌入到數量中,而不是將數量嵌入矩陣內。