2011-11-14 32 views
11

Tôi đang thực hiện một số lượng lớn lập trình khoa học và thực hiện các trải nghiệm rất tốt với cả Boost.Units, cung cấp phân tích chiều thời gian biên dịch cho số lượng (tức là số lượng thẻ với đơn vị và do đó bắt được nhiều lỗi với phân tích kích thước vật lý cổ điển) và sử dụng Eigen 2 cho đại số tuyến tính. Tuy nhiên, Eigen không có khái niệm về đơn vị, và trong khi bạn có thể thiết lập đại lượng vô hướng trong ma trận cho Eigen, thì phép nhân của hai đại lượng tạo ra cùng một loại, rõ ràng là không đúng đối với các đơn vị. Ví dụ: mã như:Kết hợp thư viện đại số tuyến tính với Boost :: Đơn vị

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(); 

không hoạt động, mặc dù chính xác về mặt logic.

Có thư viện ma trận nào hỗ trợ các đơn vị không? Tôi biết rằng điều này sẽ rất khó thực hiện trong quá khứ, và C++ 11 và decltype sẽ làm cho điều đó dễ dàng hơn nhiều, nhưng chắc chắn là có thể với C++ 03 và các chuyên môn về mẫu.

Trả lời

7

Tôi tin rằng Blitz ++ hỗ trợ nhiều chức năng Boost.Units.

Sửa bởi OP: Đối với các tài liệu tham khảo ở đây là mã kiểm tra đầy đủ với mà tôi đã thử nghiệm chức năng Blitz nhân ma trận:

#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

Vì lý do này, vì tôi phải tự tìm kiếm một chút: [Hướng dẫn sử dụng blitz 3.7.1] (http://www.oonumerics.org/blitz/docs/blitz_3.html#SEC90) cho bạn biết cách quảng bá người dùng các loại được xác định. Cảm ơn gợi ý. – thiton

1

Bạn nên kiểm tra trang Wiki này: http://eigen.tuxfamily.org/dox-devel/TopicCustomizingEigen.html

Eigen đòi hỏi một số công việc sử dụng khác hơn là các kiểu dữ liệu nguyên thủy, nhưng nó thường càng tốt.

+2

Cảm ơn gợi ý. Đã đọc trang và làm theo các gợi ý. Vấn đề là, toán tử + chỉ hoạt động tốt, nhưng ví dụ: toán tử * sai, vì đồng hồ * mét * không * một mét. – thiton

0

Khó khăn của việc sử dụng tùy chọn Plugin thư viện chuẩn Eigen, là các toán tử hiện tại +, -, *, v.v ... cần được thay thế cho số lượng Đơn vị Tăng cường được sử dụng.

Ví dụ, đối với một đơn vị Boost tùy chỉnh gõ để làm việc với các nhà điều hành * nhân, cho một CUSTOM_TYPE tùy ý, nó cần phải trông như thế này:

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>(...); 
} 

Thông báo như thế nào kiểu trả về là không giống như các kiểu đầu vào. Ở đây bạn sử dụng trình trợ giúp mẫu multiply_typeof_helper để tạo kiểu trả về. Điều này là do nhân số mét với giây sẽ không cung cấp cho bạn một số lượng của một trong hai đơn vị. Tuy nhiên, toán tử Eigen * mặc định sẽ trả về cùng một kiểu "" giống như của các đầu vào - đây là vấn đề.

Tùy chọn khác là nhúng ma trận Eigen bên trong số lượng, thay vì nhúng số lượng bên trong ma trận.

Các vấn đề liên quan