[eigen] Re: Eigen::Array initialization with long double and mpreal type

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


UpdatedHi again Eigen,

​I discovered a mistake I made when using long double types by not appending all values with "L",  so the issue is only with mpreal type initializations.  My apologies for that oversight.

I am guessing this is probably driven by when the mpreal set_default_prec() call takes place versus what happens with the static arrays at compile time although that is just my guess...

Is there any way around this issue with static arrays and variables and mpreal types?

Thanks for any advice you can offer!

As a reference, here is output from an updated test:

myArray1:
   0.11111111111111110494320541874913033097982406616211
1..0000000000000000076162237057823428575993091641927e-50

myArray2:
0.11111111111111111111111111111111111111111111111111
                                               1e-50

myArray3:
0.11111111111111111111111111111111111111111111111111
                                               1e-50

myScalar1: 0.11111111111111110494320541874913033097982406616211
myScalar2: 0.11111111111111111111111111111111111111111111111111
myDouble:  0.11111111111111110494320541874913033097982406616211

myArray1(0): 0.11111111111111110494320541874913033097982406616211
myScalar1:   0.11111111111111110494320541874913033097982406616211
myDouble:    0.11111111111111110494320541874913033097982406616211


myArray1 is static, declared in the class and initialized outside of the class.
myArray2 is non-static, declared and initialized within the class.
myArray3 is a local array declared and defined within the method.

myScalar1 is static, declared in the class and initialized outside of the class.
myScalar2 is a local variable declared and defined within the method.
myDouble demonstrates double precision.


-Mark

​Updated test code:

/**
 * This file is a test for value initializations.
 * To compile from the terminal, save as test.cpp and run the following command
 *     g++ test.cpp -I /usr/include/eigen3 -lmpfr -lgmp -o test
 */

#include <mpfr.h>
#include <gmp.h>
#include <Eigen/Eigenvalues>
#include <unsupported/Eigen/MPRealSupport>

#include <iostream>
#include <iomanip>

using namespace Eigen;

// typedef long double Scalar;
typedef mpfr::mpreal Scalar;

template <typename Scalar>
class MyClass
{
public:
    static Array<Scalar, 2, 1> myArray1;
    static Scalar myScalar1;

    Array<Scalar, 2, 1> myArray2 =
        (Array<Scalar, 2, 1>() <<
            "0.11111111111111111111111111111111111111111111111111",
            "0.00000000000000000000000000000000000000000000000001"
        ).finished();
};

template <typename Scalar>
    Array<Scalar, 2, 1> MyClass<Scalar>::myArray1 =
        (Array<Scalar, 2, 1>() <<
            "0.11111111111111111111111111111111111111111111111111",
            "0.00000000000000000000000000000000000000000000000001"
        ).finished();

template <typename Scalar>
    Scalar MyClass<Scalar>::myScalar1 = "0.11111111111111111111111111111111111111111111111111";

int main(void)
{
    Scalar::set_default_prec(256);
   
    MyClass<Scalar> myclass;
   
    Array<Scalar, 2, 1> myArray3 =
        (Array<Scalar, 2, 1>() <<
            "0.11111111111111111111111111111111111111111111111111",
            "0.00000000000000000000000000000000000000000000000001"
        ).finished();

    Scalar myScalar2 = "0.11111111111111111111111111111111111111111111111111";
    double myDouble = 0.11111111111111111111111111111111111111111111111111;

    std::cout << std::setprecision(50) << std::endl;
    std::cout << "myArray1:" << std::endl;
    std::cout << MyClass<Scalar>::myArray1 << std::endl << std::endl;

    std::cout << "myArray2:" << std::endl;
    std::cout << myclass.myArray2 << std::endl << std::endl;

    std::cout << "myArray3:" << std::endl;
    std::cout << myArray3 << std::endl << std::endl;

    std::cout << "myScalar1: " << MyClass<Scalar>::myScalar1 << std::endl;
    std::cout << "myScalar2: " << myScalar2 << std::endl;
    std::cout << "myDouble:  " << myDouble << std::endl << std::endl;

    std::cout << "myArray1(0): " << MyClass<Scalar>::myArray1(0) << std::endl;
    std::cout << "myScalar1:   " << MyClass<Scalar>::myScalar1 << std::endl;
    std::cout << "myDouble:    " << myDouble << std::endl;
}​




-Mark

On Thu, Mar 30, 2017 at 12:10 PM, Mark Sauder <mcsauder@xxxxxxxxx> wrote:
Hi Eigen,

I am observing value truncation during static array initialization that I am hoping for advice on.

Given a static array declared within a class then defined/initialized outside of class, the initialized values are truncated to double precision.  I observe this with long double types and mpreal types in the same manner within Eigen::Arrays.

When declared and initialized within the class I observe no truncation of the values.

Below is code that can be compiled/executed to illustrate what I observe; it shows the issue with long double types, but uncommenting/commenting a few lines and adding quotes for values as string literals will reveal the same issue with mpreal types.

Is there perhaps another method I should be initializing the array with?

Thank you for any advice you can offer!

​Best regards,
Mark

​​

/**
 * This file is a test for value initializations.
 * To compile from the terminal, save as test.cpp and run the following command
 *     g++ test.cpp -I /usr/include/eigen3 -lmpfr -lgmp -o test
 */

#include <mpfr..h>
#include <gmp.h>
#include <Eigen/Eigenvalues>
#include <unsupported/Eigen/MPRealSupport>

#include <iostream>
#include <iomanip>

using namespace Eigen;

typedef long double Scalar;
// typedef mpfr::mpreal Scalar;

template <typename Scalar>
class MyClass
{
public:
    static Array<Scalar, 2, 1> myArray1;
    static Scalar myScalar1;
};

template <typename Scalar>
    Array<Scalar, 2, 1> MyClass<Scalar>::myArray1 =
        (Array<Scalar, 2, 1>() <<
            0.11111111111111111111111111111111111111111111111111,
            0.00000000000000000000000000000000000000000000000001
        ).finished();

template <typename Scalar>
    Scalar MyClass<Scalar>::myScalar1 = 0.11111111111111111111111111111111111111111111111111L;

int main(void)
{
    // Scalar::set_default_prec(256);

    Array<Scalar, 2, 1> myArray2 =
        (Array<Scalar, 2, 1>() <<
            0.11111111111111111111111111111111111111111111111111,
            0.00000000000000000000000000000000000000000000000001
        ).finished();

    long double myScalar2 = 0.11111111111111111111111111111111111111111111111111L;
    double myDouble = 0.11111111111111111111111111111111111111111111111111;

    std::cout << std::setprecision(50) << std::endl;
    std::cout << "myArray1:" << std::endl;
    std::cout << MyClass<Scalar>::myArray1 << std::endl << std::endl;

    std::cout << "myArray2:" << std::endl;
    std::cout << myArray2 << std::endl << std::endl;

    std::cout << "myScalar1: " << MyClass<Scalar>::myScalar1 << std::endl;
    std::cout << "myScalar2: " << myScalar2 << std::endl;
    std::cout << "myDouble:      " << myDouble << std::endl << std::endl;

    std::cout << "myArray1(0): " << MyClass<Scalar>::myArray1(0) << std::endl;
    std::cout << "myScalar1:   " << MyClass<Scalar>::myScalar1 << std::endl;
    std::cout << "myDouble:    " << myDouble << std::endl;
}



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/