2011-11-14 26 views
11

के साथ एक रैखिक बीजगणित लाइब्रेरी का संयोजन। मैं अच्छी तरह से वैज्ञानिक प्रोग्रामिंग कर रहा हूं और बूस्ट.इनिट्स दोनों के साथ बहुत अच्छे अनुभव कर रहा हूं, जो मात्राओं के लिए संकलन-समय आयामी विश्लेषण प्रदान करता है (यानी इकाइयों के साथ टैग मात्राएं और इस प्रकार शास्त्रीय भौतिक आयाम विश्लेषण के साथ कई त्रुटियों को पकड़ता है) और रैखिक बीजगणित के लिए ईजिन 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(); 

काम नहीं करता है, भले ही यह तर्कसंगत रूप से सही है।

क्या कोई मैट्रिक्स लाइब्रेरी है जो इकाइयों का समर्थन करती है? मुझे पता है कि अतीत में इसे लागू करना कुख्यात रूप से कठिन होगा, और सी ++ 11 और decltype इतना आसान बना देगा, लेकिन यह निश्चित रूप से सी ++ 03 और टेम्पलेट विशेषज्ञता के साथ संभव था।

उत्तर

7

मुझे विश्वास है कि ब्लिट्ज ++ Boost.Units कार्यक्षमता का समर्थन करता है।

ओपी द्वारा संपादित करें:

#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

1

आप इस विकी पेज की जाँच करनी चाहिए: http://eigen.tuxfamily.org/dox-devel/TopicCustomizingEigen.html

Eigen आदिम डेटा प्रकार के अलावा अन्य उपयोग करने के लिए कुछ मेहनत करनी होगी, लेकिन यह आम तौर पर संभव है।

+2

संकेत के लिए धन्यवाद। पृष्ठ पढ़ा था और संकेतों का पालन किया था। मुद्दा यह है कि ऑपरेटर + ठीक काम करता है, लेकिन उदा। ऑपरेटर * गलत है, क्योंकि मीटर * मीटर * मीटर * नहीं है। – thiton

0

मानक Eigen पुस्तकालय प्लगइन विकल्प का उपयोग करने की कठिनाई, वह है: संदर्भ यहाँ के लिए पूर्ण परीक्षण कोड है जिससे मैं ब्लिट्ज आव्यूह गुणन कार्यक्षमता का परीक्षण किया है मौजूदा ऑपरेटर +, -, *, आदि को बूस्ट इकाइयों की मात्रा के लिए प्रतिस्थापित करने की आवश्यकता है।

उदाहरण के लिए, के लिए एक बूस्ट इकाइयों कस्टम, * गुणा ऑपरेटर के साथ काम करने के लिए एक मनमाना 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>(...); 
} 

सूचना कैसे वापसी प्रकार के समान नहीं है इनपुट प्रकार। यहां आप वापसी प्रकार बनाने के लिए टेम्पलेट सहायक मल्टीप्ली_typeof_helper का उपयोग करते हैं। ऐसा इसलिए है क्योंकि सेकेंड के साथ मीटर गुणा करने से आपको इकाई की मात्रा नहीं मिलती है। हालांकि, डिफ़ॉल्ट Eigen * ऑपरेटर इनपुट के समान "प्रकार" को वापस कर देगा - यह समस्या है।

दूसरा विकल्प मैट्रिक्स के अंदर मात्रा को एम्बेड करने के बजाय मात्रा के अंदर ईजिन मैट्रिक्स को एम्बेड करना है।