This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
Bug 276 - Misc. Fixes to Get Quad-Double and Double-Double Data Types Working with Eigen v.3
Summary: Misc. Fixes to Get Quad-Double and Double-Double Data Types Working with Eige...
Status: RESOLVED FIXED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: 3.0
Hardware: All All
: --- Unknown
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-05-22 09:44 UTC by David
Modified: 2019-12-04 10:47 UTC (History)
3 users (show)



Attachments
Patch file for the changes (8.50 KB, application/octet-stream)
2011-05-22 09:44 UTC, David
no flags Details

Description David 2011-05-22 09:44:14 UTC
Created attachment 174 [details]
Patch file for the changes

I have been trying to get Eigen3 to work using the quad-double and double-double data types from the QD library (http://crd.lbl.gov/~dhbailey/mpdist/). There were several cast errors that emerged from this effort. Unfortunately, the QD library also needed to be patched to make this work, so the version on the above website will not compile, but I can send the corrected files if needed. Also, I don't see what was the standard method of casting, so I used static_cast<>.

Here's the NumTraits that I used to build Eigen with the quad-double library:
namespace Eigen
{
  template<> struct NumTraits<dd_real>
  {
    typedef dd_real Real;
    typedef dd_real NonInteger;
    typedef dd_real Nested;

    enum {
      IsComplex = 0,
      IsInteger = 0,
      IsSigned = 1,
      RequireInitialization = 0,
      ReadCost = 1,
      AddCost = 1,
      MulCost = 1
    };

    static Real epsilon() { return std::numeric_limits<dd_real>::epsilon();}
    static Real dummy_precision() { return epsilon();}
    static Real highest() {return std::numeric_limits<dd_real>::max();}
    static Real lowest() {return -std::numeric_limits<dd_real>::max();}
  };

  template<> struct NumTraits<qd_real>
  {
    typedef qd_real Real;
    typedef qd_real NonInteger;
    typedef qd_real Nested;

    enum {
      IsComplex = 0,
      IsInteger = 0,
      IsSigned = 1,
      RequireInitialization = 0,
      ReadCost = 1,
      AddCost = 1,
      MulCost = 1
    };

    static Real epsilon() { return std::numeric_limits<qd_real>::epsilon();}
    static Real dummy_precision() { return epsilon();}
    static Real highest() {return std::numeric_limits<qd_real>::max();}
    static Real lowest() {return -std::numeric_limits<qd_real>::max();}
  };
}
Comment 1 Gael Guennebaud 2011-05-23 11:29:36 UTC
hi, thanks for the patch. I'm cleaning it a bit (use constructor syntax rather than static_cast, hardcoded cast to double) and testing and committing...
Comment 2 Gael Guennebaud 2011-05-23 11:31:19 UTC
oh, it would be interesting to see the patch you applied to QD/DD to check whether something have to be improved on our side...
Comment 3 David 2011-05-23 20:08:47 UTC
(In reply to comment #2)
> oh, it would be interesting to see the patch you applied to QD/DD to check
> whether something have to be improved on our side...

There were two things that needed to be changed in QD. (1) None of the cmath functions were in the std namespace and std::sqrt was being used for the norm(). (2) There was a cast to int (I don't recall where) that needed to be added. Below are the patches for dd_real.h and qd_real.h. Let me know if you need anything else.

dd_real.h patch
@@ -75,6 +75,11 @@
     x[0] = d[0]; x[1] = d[1];
   }
 
+  operator int () const
+  {
+    return static_cast<int>(x[0]);
+  }
+
   static void error(const char *msg);
 
   double _hi() const { return x[0]; }
@@ -282,6 +287,36 @@
 
 QD_API std::ostream& operator<<(std::ostream &s, const dd_real &a);
 QD_API std::istream& operator>>(std::istream &s, dd_real &a);
+
+namespace std {
+ dd_real abs(const dd_real &dd)  {return ::abs(dd);}
+ dd_real fabs(const dd_real &dd)  {return ::fabs(dd);}
+ dd_real ceil(const dd_real &dd)  {return ::ceil(dd);}
+ dd_real floor(const dd_real &dd)  {return ::floor(dd);}
+ dd_real fmod(const dd_real &dd1, const dd_real &dd2)  {return ::fmod(dd1, dd2);}
+
+ dd_real sqrt(const dd_real &dd) {return ::sqrt(dd);}
+ dd_real pow(const dd_real &dd1, const dd_real &dd2)  {return ::pow(dd1, dd2);}
+ dd_real pow(const dd_real &dd, int i)  {return ::pow(dd, i);}
+
+ dd_real exp(const dd_real &dd)  {return ::exp(dd);}
+ dd_real ldexp(const dd_real &dd, int ex)  {return ::ldexp(dd, ex);}
+ dd_real log(const dd_real &dd)  {return ::log(dd);}
+ dd_real log10(const dd_real &dd)  {return ::log10(dd);}
+
+ dd_real sin(const dd_real &dd) {return ::sin(dd);}
+ dd_real cos(const dd_real &dd) {return ::cos(dd);}
+ dd_real tan(const dd_real &dd) {return ::tan(dd);}
+ dd_real asin(const dd_real &dd) {return ::asin(dd);}
+ dd_real acos(const dd_real &dd) {return ::acos(dd);}
+ dd_real atan(const dd_real &dd) {return ::atan(dd);}
+ dd_real atan2(const dd_real &ddy, const dd_real &ddx) {return ::atan2(ddy, ddx);}
+
+ dd_real sinh(const dd_real &dd) {return ::sinh(dd);}
+ dd_real cosh(const dd_real &dd) {return ::cosh(dd);}
+ dd_real tanh(const dd_real &dd) {return ::tanh(dd);}
+}
+
 #ifdef QD_INLINE
 #include <qd/dd_inline.h>
 #endif

qd_real.h patch
@@ -45,6 +45,11 @@
   qd_real(double x0, double x1, double x2, double x3);
   explicit qd_real(const double *xx);
 
+  operator int () const
+  {
+    return static_cast<int>(x[0]);
+  }
+
   static const qd_real _2pi;
   static const qd_real _pi;
   static const qd_real _3pi4;
@@ -286,6 +291,35 @@
 QD_API std::ostream &operator<<(std::ostream &s, const qd_real &a);
 QD_API std::istream &operator>>(std::istream &s, qd_real &a);
 
+namespace std {
+  qd_real abs(const qd_real &qd)  {return ::abs(qd);}
+  qd_real fabs(const qd_real &qd)  {return ::fabs(qd);}
+  qd_real ceil(const qd_real &qd)  {return ::ceil(qd);}
+  qd_real floor(const qd_real &qd)  {return ::floor(qd);}
+  qd_real fmod(const qd_real &qd1, const qd_real &qd2)  {return ::fmod(qd1, qd2);}
+
+  qd_real sqrt(const qd_real &qd) {return ::sqrt(qd);}
+  qd_real pow(const qd_real &qd1, const qd_real &qd2)  {return ::pow(qd1, qd2);}
+  qd_real pow(const qd_real &qd, int i)  {return ::pow(qd, i);}
+
+  qd_real exp(const qd_real &qd)  {return ::exp(qd);}
+  qd_real ldexp(const qd_real &qd, int ex)  {return ::ldexp(qd, ex);}
+  qd_real log(const qd_real &qd)  {return ::log(qd);}
+  qd_real log10(const qd_real &qd)  {return ::log10(qd);}
+
+  qd_real sin(const qd_real &qd) {return ::sin(qd);}
+  qd_real cos(const qd_real &qd) {return ::cos(qd);}
+  qd_real tan(const qd_real &qd) {return ::tan(qd);}
+  qd_real asin(const qd_real &qd) {return ::asin(qd);}
+  qd_real acos(const qd_real &qd) {return ::acos(qd);}
+  qd_real atan(const qd_real &qd) {return ::atan(qd);}
+  qd_real atan2(const qd_real &qdy, const qd_real &qdx) {return ::atan2(qdy, qdx);}
+
+  qd_real sinh(const qd_real &qd) {return ::sinh(qd);}
+  qd_real cosh(const qd_real &qd) {return ::cosh(qd);}
+  qd_real tanh(const qd_real &qd) {return ::tanh(qd);}
+}
+
 #ifdef QD_INLINE
 #include <qd/qd_inline.h>
 #endif
Comment 4 Gael Guennebaud 2011-05-23 21:39:58 UTC
> There were two things that needed to be changed in QD. (1) None of the cmath
> functions were in the std namespace and std::sqrt was being used for the
> norm(). 

this is ex
Comment 5 Gael Guennebaud 2011-05-23 21:40:51 UTC
> There were two things that needed to be changed in QD. (1) None of the cmath
> functions were in the std namespace and std::sqrt was being used for the
> norm(). 

this is exactly what I thought, this should be needed and I'm coming up with a fix for that...
Comment 6 Gael Guennebaud 2011-05-25 08:43:44 UTC
Hi, now the default qd-real lib works out of the box with eigen devel branch. No need to add overloads in the std namespace nor to specialize our internal::foo_impl....
Comment 7 Nobody 2019-12-04 10:47:17 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/276.

Note You need to log in before you can comment on or make changes to this bug.