2011-11-14 15 views
11

私は数多くの科学プログラミングを行っており、Boost.Unitsの両方で非常に良い経験をしています。それによって古典的な物理的次元分析で多くのエラーを捕捉する)、線形代数のために固有2を使用する。線形代数ライブラリをBoost :: Unitsと組み合わせる

しかし、Eigenには単位の概念はなく、Eigenの行列にスカラー量を設定することはできますが、2つの数の乗算で同じタイプになることが予想されます。たとえば、次のようなコード:

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

記録のために、少し自分自身を検索しなければならなかったので:[The blitz manual 3.7.1](http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC90)では、ユーザーを宣伝する方法を説明しています定義された型。ヒントをありがとう。 – thiton

1

あなたはこのWikiページをチェックする必要があります http://eigen.tuxfamily.org/dox-devel/TopicCustomizingEigen.html

を固有のプリミティブデータ型以外を使用するために、いくつかの作業が必要ですが、それは一般的に可能です。

+2

ヒントをお寄せいただきありがとうございます。ページを読んでヒントに従っていた。要は、operator +はうまく動作しますが、たとえばメーター*メーターはメーターではないため、演算子*は間違っています。 – 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 *演算子は入力と同じ "型"を返します。これが問題です。

もう1つの選択肢は、量を行列内に埋め込むのではなく、数量内に固有行列を埋め込むことです。

関連する問題