[eigen] new types / NumTraits |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
Dear All,
first I would like to thank everyone involved in the Eigen library.
I'm using Eigen more and more for projects I traditionally used octave.
It's really fun using Eigen.
In return I've started to look closer into possible applications. One interest
of mine consists in using Eigen for user defined types. In the attached example
I'm trying to to use Eigen for the following struct:
struct TpFloat
{
TpFloat() {};
explicit TpFloat( const int r) : v(r), Counter(0) {};
TpFloat( const TpFloatBase r) : v(r), Counter(0) {};
TpFloat( const TpFloatBase r, const int n ) : v(r), Counter(n) {};
TpFloatBase v;
int Counter;
TpFloat operator-() { return TpFloat( -v, Counter+1) ; }
};
The initialization of a matrix works fine, however I have compilation problems for
std::cout << A << std::endl;
getting errors like
$ g++ -std=c++11 -march=native -DNDEBUG -I $HOME/Eigen/eigen E.C -o E -lm && ./E
In file included from /home/peter/Eigen/eigen/Eigen/Core:259:0,
from /home/peter/Eigen/eigen/Eigen/Dense:1,
from E.C:5:
/home/peter/Eigen/eigen/Eigen/src/Core/MathFunctions.h: In instantiation of ‘static NewType Eigen::internal::cast_impl<OldType, NewType>::run(const OldType&) [with OldType = TpFloat; NewType = int]’:
/home/peter/Eigen/eigen/Eigen/src/Core/MathFunctions.h:339:44: required from ‘NewType Eigen::internal::cast(const OldType&) [with OldType = TpFloat; NewType = int]’
/home/peter/Eigen/eigen/Eigen/src/Core/IO.h:132:97: required from ‘static int Eigen::internal::significant_decimals_default_impl<Scalar, IsInteger>::run() [with Scalar = TpFloat; bool IsInteger = false]’
/home/peter/Eigen/eigen/Eigen/src/Core/IO.h:180:67: required from ‘std::ostream& Eigen::internal::print_matrix(std::ostream&, const Derived&, const Eigen::IOFormat&) [with Derived = Eigen::Matrix<TpFloat, -1, -1, 1>;
std::ostream = std::basic_ostream<char>]’
/home/peter/Eigen/eigen/Eigen/src/Core/IO.h:245:69: required from ‘std::ostream& Eigen::operator<<(std::ostream&, const Eigen::DenseBase<Derived>&) [with Derived = Eigen::Matrix<TpFloat, -1, -1, 1>; std::ostream =
std::basic_ostream<char>]’
E.C:78:15: required from here
/home/peter/Eigen/eigen/Eigen/src/Core/MathFunctions.h:330:34: error: invalid static_cast from type ‘const TpFloat’ to type ‘int’
return static_cast<NewType>(x);
Is it necessary to define a cast from the user defined type to int?
I'm using g++ v. 4.8 and eigen v. 3.2.9.
Any help is appreciated,
thanks in advance,
Peter
#include <stdlib.h>
#include <iostream>
#include <cmath>
#include <Eigen/Dense>
// g++ -std=c++11 -march=native -DNDEBUG -I $HOME/Eigen/eigen E.C -o E -lm && ./E
typedef double TpFloatBase;
struct TpFloat;
struct TpFloat
{
TpFloat() {};
explicit TpFloat( const int r) : v(r), Counter(0) {};
TpFloat( const TpFloatBase r) : v(r), Counter(0) {};
TpFloat( const TpFloatBase r, const int n ) : v(r), Counter(n) {};
TpFloatBase v;
int Counter;
TpFloat operator-() { return TpFloat( -v, Counter+1) ; }
};
// https://eigen.tuxfamily.org/dox/TopicCustomizingEigen.html
namespace Eigen
{
template<> struct NumTraits<TpFloat> : NumTraits<TpFloatBase>
{
typedef TpFloat Real;
typedef TpFloat NonInteger;
typedef TpFloat Nested;
enum
{
IsComplex = 0,
IsInteger = 0,
IsSigned = 1,
RequireInitialization = 0,
};
static inline Real epsilon() { return TpFloat( NumTraits<TpFloatBase>::epsilon() ,0 ); }
static inline Real dummy_precision() { return TpFloat( NumTraits<TpFloatBase>::dummy_precision() ,0 ); }
};
}
namespace std
{
std::ostream& operator<<(std::ostream &s, const TpFloat& rE)
{
s << "[ " << rE.v << ", " << rE.Counter << "]";
return s;
}
}
TpFloat ceil( const TpFloat& a) { return TpFloat( ceil( a.v), a.Counter ) ; }
TpFloat log ( const TpFloat& a) { return TpFloat( log ( a.v), a.Counter ) ; }
TpFloat operator/( const TpFloat& a, const TpFloat& b) { return TpFloat( a.v/b.v, a.Counter+1) ; }
typedef Eigen::Matrix< TpFloat, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> TpMatrix;
int main( const int argc, const char *argv[] )
{
TpMatrix A(3,3);
A << 1,2,3,4,5,6,7,8,9;
std::cout << -TpFloat(0.123456789) / TpFloat(1.0) << std::endl;
std::cout << A << std::endl;
return 0;
}