2
// common types, funcs, includes; should be included by all other files
4
/* change to float for single-precision */
7
// BEGIN workaround for
8
// * http://eigen.tuxfamily.org/bz/show_bug.cgi?id=528
9
// * https://sourceforge.net/tracker/index.php?func=detail&aid=3584127&group_id=202880&atid=983354
10
// (only needed with gcc <= 4.7)
17
#include<Eigen/Geometry>
18
#include<Eigen/Eigenvalues>
21
// integral type for indices, to avoid compiler warnings with int
22
typedef Eigen::Matrix<int,1,1>::Index Index;
25
typedef Eigen::Matrix<int ,2,1> Vector2i;
26
typedef Eigen::Matrix<Real,2,1> Vector2r;
27
typedef Eigen::Matrix<int ,3,1> Vector3i;
28
typedef Eigen::Matrix<Real,3,1> Vector3r;
29
typedef Eigen::Matrix<int ,6,1> Vector6i;
30
typedef Eigen::Matrix<Real,6,1> Vector6r;
31
typedef Eigen::Matrix<Real,3,3> Matrix3r;
32
typedef Eigen::Matrix<Real,6,6> Matrix6r;
34
typedef Eigen::Matrix<Real,Eigen::Dynamic,Eigen::Dynamic> MatrixXr;
35
typedef Eigen::Matrix<Real,Eigen::Dynamic,1> VectorXr;
37
typedef Eigen::Quaternion<Real> Quaternionr;
38
typedef Eigen::AngleAxis<Real> AngleAxisr;
39
typedef Eigen::AlignedBox<Real,3> AlignedBox3r;
40
typedef Eigen::AlignedBox<Real,2> AlignedBox2r;
42
#define _COMPLEX_SUPPORT
44
#ifdef _COMPLEX_SUPPORT
47
typedef Eigen::Matrix<complex<Real>,2,1> Vector2cr;
48
typedef Eigen::Matrix<complex<Real>,3,1> Vector3cr;
49
typedef Eigen::Matrix<complex<Real>,6,1> Vector6cr;
50
typedef Eigen::Matrix<complex<Real>,Eigen::Dynamic,1> VectorXcr;
51
typedef Eigen::Matrix<complex<Real>,3,3> Matrix3cr;
52
typedef Eigen::Matrix<complex<Real>,6,6> Matrix6cr;
53
typedef Eigen::Matrix<complex<Real>,Eigen::Dynamic,Eigen::Dynamic> MatrixXcr;
64
#include<boost/python.hpp>
65
namespace py=boost::python;
66
#include<boost/lexical_cast.hpp>
67
using boost::lexical_cast;
68
#include<boost/static_assert.hpp>
70
/**** double-conversion helpers *****/
71
#include"double-conversion/double-conversion.h"
73
static double_conversion::DoubleToStringConverter doubleToString(
74
double_conversion::DoubleToStringConverter::NO_FLAGS,
75
"inf", /* infinity symbol */
76
"nan", /* NaN symbol */
77
'e', /*exponent symbol*/
78
-5, /* decimal_in_shortest_low: 0.0001, but 0.00001->1e-5 */
79
7, /* decimal_in_shortest_high */
80
/* the following are irrelevant for the shortest representation */
81
6, /* max_leading_padding_zeroes_in_precision_mode */
82
6 /* max_trailing_padding_zeroes_in_precision_mode */
85
/* optionally pad from the left */
86
static inline string doubleToShortest(double d, int pad=0){
87
/* 32 is perhaps wasteful */
88
/* it would be better to write to the string's buffer itself, not sure how to do that */
90
double_conversion::StringBuilder sb(buf,32);
91
doubleToString.ToShortest(d,&sb);
92
string ret(sb.Finalize());
93
if(pad==0 || (int)ret.size()>=pad) return ret;
94
return string(pad-ret.size(),' ')+ret; // left-padded if shorter
98
/* generic function to print numbers, via lexical_cast plus padding -- used for ints */
100
string num_to_string(const T& num, int pad=0){
101
string ret(lexical_cast<string>(num));
102
if(pad==0 || (int)ret.size()>=pad) return ret;
103
return string(pad-ret.size(),' ')+ret; // left-pad with spaces
106
// for doubles, use the shortest representation
107
static inline string num_to_string(const double& num, int pad=0){ return doubleToShortest(num,pad); }
109
#ifdef _COMPLEX_SUPPORT
110
// for complex numbers (with any scalar type, though only doubles are really used)
112
string num_to_string(const complex<T>& num, int pad=0){
114
// both components non-zero
115
if(num.real()!=0 && num.imag()!=0){
116
// don't add "+" in the middle if imag is negative and will start with "-"
117
string ret=num_to_string(num.real(),/*pad*/0)+(num.imag()>0?"+":"")+num_to_string(num.imag(),/*pad*/0)+"j";
118
if(pad==0 || (int)ret.size()>=pad) return ret;
119
return string(pad-ret.size(),' ')+ret; // left-pad with spaces
121
// only imaginary is non-zero: skip the real part, and decrease padding to accomoadate the trailing "j"
123
return num_to_string(num.imag(),/*pad*/pad>0?pad-1:0)+"j";
125
// non-complex (zero or not)
126
return num_to_string(num.real(),pad);
131
/*** getters and setters with bound guards ***/
132
static inline void IDX_CHECK(Index i,Index MAX){ if(i<0 || i>=MAX) { PyErr_SetString(PyExc_IndexError,("Index "+lexical_cast<string>(i)+" out of range 0.." + lexical_cast<string>(MAX-1)).c_str()); py::throw_error_already_set(); } }
133
static inline void IDX2_CHECKED_TUPLE_INTS(py::tuple tuple,const Index max2[2], Index arr2[2]) {Index l=py::len(tuple); if(l!=2) { PyErr_SetString(PyExc_IndexError,"Index must be integer or a 2-tuple"); py::throw_error_already_set(); } for(int _i=0; _i<2; _i++) { py::extract<Index> val(tuple[_i]); if(!val.check()){ PyErr_SetString(PyExc_ValueError,("Unable to convert "+lexical_cast<string>(_i)+"-th index to integer.").c_str()); py::throw_error_already_set(); } Index v=val(); IDX_CHECK(v,max2[_i]); arr2[_i]=v; } }
135
static inline string object_class_name(const py::object& obj){ return py::extract<string>(obj.attr("__class__").attr("__name__"))(); }