Main MRPT website > C++ reference
MRPT logo
MPRealSupport
Go to the documentation of this file.
00001 // This file is part of a joint effort between Eigen, a lightweight C++ template library
00002 // for linear algebra, and MPFR C++, a C++ interface to MPFR library (http://www.holoborodko.com/pavel/)
00003 //
00004 // Copyright (C) 2010 Pavel Holoborodko <pavel@holoborodko.com>
00005 // Copyright (C) 2010 Konstantin Holoborodko <konstantin@holoborodko.com>
00006 // Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
00007 //
00008 // Eigen is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Lesser General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 3 of the License, or (at your option) any later version.
00012 //
00013 // Alternatively, you can redistribute it and/or
00014 // modify it under the terms of the GNU General Public License as
00015 // published by the Free Software Foundation; either version 2 of
00016 // the License, or (at your option) any later version.
00017 //
00018 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00019 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00020 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00021 // GNU General Public License for more details.
00022 //
00023 // You should have received a copy of the GNU Lesser General Public
00024 // License and a copy of the GNU General Public License along with
00025 // this library. If not, see <http://www.gnu.org/licenses/>.
00026 // 
00027 // Contributors:
00028 // Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, Heinz van Saanen, Pere Constans
00029 
00030 #ifndef EIGEN_MPREALSUPPORT_MODULE_H
00031 #define EIGEN_MPREALSUPPORT_MODULE_H
00032 
00033 #include <mpreal.h>
00034 #include <Eigen/Core>
00035 
00036 namespace Eigen {
00037 
00038   /** \defgroup MPRealSupport_Module MPFRC++ Support module  
00039  * \ingroup eigen_grp
00040  * \ingroup eigen_grp
00041     *
00042     * \code
00043     * #include <Eigen/MPRealSupport>
00044     * \endcode
00045     *
00046     * This module provides support for multi precision floating point numbers
00047     * via the <a href="http://www.holoborodko.com/pavel/?page_id=12">MPFR C++</a>
00048     * library which itself is built upon <a href="http://www.mpfr.org/">MPFR</a>/<a href="http://gmplib.org/">GMP</a>.
00049     *
00050     * You can find a copy of MPFR C++ that is known to be compatible in the unsupported/test/mpreal folder.
00051     *
00052     * Here is an example:
00053     *
00054 \code
00055 #include <iostream>
00056 #include <Eigen/Mpfrc++Support>
00057 #include <Eigen/LU>
00058 using namespace mpfr;
00059 using namespace Eigen;
00060 int main()
00061 {
00062   // set precision to 256 bits (double has only 53 bits)
00063   mpreal::set_default_prec(256);
00064   // Declare matrix and vector types with multi-precision scalar type
00065   typedef Matrix<mpreal,Dynamic,Dynamic>  MatrixXmp;
00066   typedef Matrix<mpreal,Dynamic,1>        VectorXmp;
00067 
00068   MatrixXmp A = MatrixXmp::Random(100,100);
00069   VectorXmp b = VectorXmp::Random(100);
00070 
00071   // Solve Ax=b using LU
00072   VectorXmp x = A.lu().solve(b);
00073   std::cout << "relative error: " << (A*x - b).norm() / b.norm() << std::endl;
00074   return 0;
00075 }
00076 \endcode
00077     *
00078     */
00079 
00080   template<> struct NumTraits<mpfr::mpreal>
00081     : GenericNumTraits<mpfr::mpreal>
00082   {
00083     enum {
00084       IsInteger = 0,
00085       IsSigned = 1,
00086       IsComplex = 0,
00087       RequireInitialization = 1,
00088       ReadCost = 10,
00089       AddCost = 10,
00090       MulCost = 40
00091     };
00092 
00093     typedef mpfr::mpreal Real;
00094     typedef mpfr::mpreal NonInteger;
00095 
00096     inline static mpfr::mpreal highest() { return  mpfr::mpreal_max(mpfr::mpreal::get_default_prec()); }
00097     inline static mpfr::mpreal lowest()  { return -mpfr::mpreal_max(mpfr::mpreal::get_default_prec()); }
00098 
00099     inline static Real epsilon()
00100     {
00101       return mpfr::machine_epsilon(mpfr::mpreal::get_default_prec());
00102     }
00103     inline static Real dummy_precision()
00104     {
00105       unsigned int weak_prec = ((mpfr::mpreal::get_default_prec()-1)*90)/100;
00106       return mpfr::machine_epsilon(weak_prec);
00107     }
00108   };
00109 
00110   namespace internal {
00111 
00112   template<> mpfr::mpreal random<mpfr::mpreal>()
00113   {
00114 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
00115     static gmp_randstate_t state;
00116     static bool isFirstTime = true;
00117 
00118     if(isFirstTime)
00119     {
00120       gmp_randinit_default(state);
00121       gmp_randseed_ui(state,(unsigned)time(NULL));
00122       isFirstTime = false;
00123     }
00124 
00125     return mpfr::urandom(state)*2-1;
00126 #else
00127     return mpfr::mpreal(random<double>());
00128 #endif
00129   }
00130 
00131   template<> mpfr::mpreal random<mpfr::mpreal>(const mpfr::mpreal& a, const mpfr::mpreal& b)
00132   {
00133     return a + (b-a) * random<mpfr::mpreal>();
00134   }
00135 
00136   bool isMuchSmallerThan(const mpfr::mpreal& a, const mpfr::mpreal& b, const mpfr::mpreal& prec)
00137   {
00138     return mpfr::abs(a) <= mpfr::abs(b) * prec;
00139   }
00140 
00141   inline bool isApprox(const mpfr::mpreal& a, const mpfr::mpreal& b, const mpfr::mpreal& prec)
00142   {
00143     return mpfr::abs(a - b) <= (mpfr::min)(mpfr::abs(a), mpfr::abs(b)) * prec;
00144   }
00145 
00146   inline bool isApproxOrLessThan(const mpfr::mpreal& a, const mpfr::mpreal& b, const mpfr::mpreal& prec)
00147   {
00148     return a <= b || isApprox(a, b, prec);
00149   }
00150 
00151   } // end namespace internal
00152 }
00153 
00154 #endif // EIGEN_MPREALSUPPORT_MODULE_H



Page generated by Doxygen 1.7.4 for MRPT 0.9.5 SVN:2717 at Sun Oct 16 16:08:03 PDT 2011 Hosted on:
SourceForge.net Logo