This forum has been archived. All content is frozen. Please use KDE Discuss instead.

casting problem with user-defined scalar.

Tags: None
(comma "," separated)
bartekltg
Registered Member
Posts
1
Karma
0
It looks like this problem has appeared a few times, but i can't get a solution from older threads.

I'm trying to copy my matrix of qd_real type to double matrix.
QD_real is a "quad double" type from there:
http://crd-legacy.lbl.gov/~dhbailey/mpdist/

Code: Select all
#include <iostream>
#include<qd/qd_real.h>
#include <eigen3/Eigen/Core>
using namespace std;

int main() {
    const int N = 1000;
    Eigen::Matrix<qd_real,Eigen::Dynamic,Eigen::Dynamic>  M(N,N);
    M.setRandom();
    Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>  Md(N,N);
    Md = M.cast<double>();
    return 0;
}


And gcc can't figure out how to do static_cast.

Code: Select all
g++ -c -pipe -std=c++11 -pthread -fopenmp -lquadmath -fext-numeric-literals -g -D_REENTRANT -Wall -W -fPIE  -I../eigentest -I. -I../../Qt/5.4/gcc_64/mkspecs/linux-g++ -o main.o ../eigentest/main.cpp
In file included from /usr/local/include/eigen3/Eigen/Core:259:0,
                 from ../eigentest/main.cpp:6:
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h: In instantiation of 'static NewType Eigen::internal::cast_impl<OldType, NewType>::run(const OldType&) [with OldType = qd_real; NewType = double]':
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h:328:44:   required from 'NewType Eigen::internal::cast(const OldType&) [with OldType = qd_real; NewType = double]'
/usr/local/include/eigen3/Eigen/src/Core/Functors.h:392:104:   required from 'const NewType Eigen::internal::scalar_cast_op<Scalar, NewType>::operator()(const Scalar&) const [with Scalar = qd_real; NewType = double]'
/usr/local/include/eigen3/Eigen/src/Core/CwiseUnaryOp.h:114:75:   required from 'const Scalar Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::coeff(Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index) const [with UnaryOp = Eigen::internal::scalar_cast_op<qd_real, double>; XprType = const Eigen::Matrix<qd_real, -1, -1>; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Scalar = double; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index = long int]'
/usr/local/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:495:33:   required from 'void Eigen::DenseCoeffsBase<Derived, 1>::copyCoeff(Eigen::DenseCoeffsBase<Derived, 1>::Index, const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; Derived = Eigen::Matrix<double, -1, -1>; Eigen::DenseCoeffsBase<Derived, 1>::Index = long int]'
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:304:7:   required from 'static void Eigen::internal::assign_impl<Derived1, Derived2, 1, 0, Version>::run(Derived1&, const Derived2&) [with Derived1 = Eigen::Matrix<double, -1, -1>; Derived2 = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; int Version = 0]'
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:507:111:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:527:123:   required from 'static Derived& Eigen::internal::assign_selector<Derived, OtherDerived, false, false>::run(Derived&, const OtherDerived&) [with Derived = Eigen::Matrix<double, -1, -1>; OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >]'
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:623:105:   required from 'Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; Derived = Eigen::Matrix<double, -1, -1>]'
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:608:120:   required from 'void Eigen::PlainObjectBase<Derived>::_set_selector(const OtherDerived&, const Eigen::internal::false_type&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; Derived = Eigen::Matrix<double, -1, -1>]'
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:600:189:   required from 'Derived& Eigen::PlainObjectBase<Derived>::_set(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; Derived = Eigen::Matrix<double, -1, -1>]'
/usr/local/include/eigen3/Eigen/src/Core/Matrix.h:172:30:   required from 'Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::operator=(const Eigen::MatrixBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; _Scalar = double; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1]'
../eigentest/main.cpp:88:8:   required from here
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h:319:34: error: invalid static_cast from type 'const qd_real' to type 'double'
     return static_cast<NewType>(x);
                                  ^
make: *** [main.o] Error 1


The original problem I encountered was printing matrix to stream:

Code: Select all
#include <iostream>
#include<qd/qd_real.h>
#include <eigen3/Eigen/Core>
using namespace std;

int main() {
    const int N = 1000;
    Eigen::Matrix<qd_real,Eigen::Dynamic,Eigen::Dynamic>  M(N,N);
    cout<<M<<endl;
    return 0;
}
 


Code: Select all
In file included from /usr/local/include/eigen3/Eigen/Core:259:0,
                 from ../eigentest/main.cpp:6:
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h: In instantiation of 'static NewType Eigen::internal::cast_impl<OldType, NewType>::run(const OldType&) [with OldType = qd_real; NewType = int]':
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h:328:44:   required from 'NewType Eigen::internal::cast(const OldType&) [with OldType = qd_real; NewType = int]'
/usr/local/include/eigen3/Eigen/src/Core/IO.h:132:97:   required from 'static int Eigen::internal::significant_decimals_default_impl<Scalar, IsInteger>::run() [with Scalar = qd_real; bool IsInteger = false]'
/usr/local/include/eigen3/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<qd_real, -1, -1>; std::ostream = std::basic_ostream<char>]'
/usr/local/include/eigen3/Eigen/src/Core/IO.h:245:69:   required from 'std::ostream& Eigen::operator<<(std::ostream&, const Eigen::DenseBase<Derived>&) [with Derived = Eigen::Matrix<qd_real, -1, -1>; std::ostream = std::basic_ostream<char>]'
../eigentest/main.cpp:86:11:   required from here
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h:319:34: error: invalid static_cast from type 'const qd_real' to type 'int'
     return static_cast<NewType>(x);
                                  ^
make: *** [main.o] Error 1


... casting to double only change a type in error message:

cout<<M.cast<double>() <<endl;

Code: Select all
In file included from /usr/local/include/eigen3/Eigen/Core:259:0,
                 from ../eigentest/main.cpp:6:
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h: In instantiation of 'static NewType Eigen::internal::cast_impl<OldType, NewType>::run(const OldType&) [with OldType = qd_real; NewType = double]':
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h:328:44:   required from 'NewType Eigen::internal::cast(const OldType&) [with OldType = qd_real; NewType = double]'
/usr/local/include/eigen3/Eigen/src/Core/Functors.h:392:104:   required from 'const NewType Eigen::internal::scalar_cast_op<Scalar, NewType>::operator()(const Scalar&) const [with Scalar = qd_real; NewType = double]'
/usr/local/include/eigen3/Eigen/src/Core/CwiseUnaryOp.h:114:75:   required from 'const Scalar Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::coeff(Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index) const [with UnaryOp = Eigen::internal::scalar_cast_op<qd_real, double>; XprType = const Eigen::Matrix<qd_real, -1, -1>; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Scalar = double; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index = long int]'
/usr/local/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:495:33:   required from 'void Eigen::DenseCoeffsBase<Derived, 1>::copyCoeff(Eigen::DenseCoeffsBase<Derived, 1>::Index, const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; Derived = Eigen::Matrix<double, -1, -1>; Eigen::DenseCoeffsBase<Derived, 1>::Index = long int]'
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:304:7:   required from 'static void Eigen::internal::assign_impl<Derived1, Derived2, 1, 0, Version>::run(Derived1&, const Derived2&) [with Derived1 = Eigen::Matrix<double, -1, -1>; Derived2 = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; int Version = 0]'
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:507:111:   [ skipping 2 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/local/include/eigen3/Eigen/src/Core/Assign.h:527:123:   required from 'static Derived& Eigen::internal::assign_selector<Derived, OtherDerived, false, false>::run(Derived&, const OtherDerived&) [with Derived = Eigen::Matrix<double, -1, -1>; OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >]'
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:623:105:   required from 'Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; Derived = Eigen::Matrix<double, -1, -1>]'
/usr/local/include/eigen3/Eigen/src/Core/Matrix.h:281:31:   required from 'Eigen::Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::Matrix(const Eigen::MatrixBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; _Scalar = double; int _Rows = -1; int _Cols = -1; int _Options = 0; int _MaxRows = -1; int _MaxCols = -1]'
/usr/local/include/eigen3/Eigen/src/Core/DenseBase.h:369:62:   required from 'Eigen::DenseBase<Derived>::EvalReturnType Eigen::DenseBase<Derived>::eval() const [with Derived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; Eigen::DenseBase<Derived>::EvalReturnType = const Eigen::Matrix<double, -1, -1>]'
/usr/local/include/eigen3/Eigen/src/Core/IO.h:245:69:   required from 'std::ostream& Eigen::operator<<(std::ostream&, const Eigen::DenseBase<Derived>&) [with Derived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_cast_op<qd_real, double>, const Eigen::Matrix<qd_real, -1, -1> >; std::ostream = std::basic_ostream<char>]'
../eigentest/main.cpp:86:26:   required from here
/usr/local/include/eigen3/Eigen/src/Core/MathFunctions.h:319:34: error: invalid static_cast from type 'const qd_real' to type 'double'
     return static_cast<NewType>(x);
                                  ^
make: *** [main.o] Error 1


Do You have any idea how to fix it?

Edit: the problem was in qd library.
After adding
Code: Select all
 operator const double () const;

to class, and
Code: Select all
qd_real::operator const double() const
{
    return to_double(*this);
}

after functions declaration, it seems to work.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
I confirm that the solution you came up with is the right one.


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Google [Bot], Yahoo [Bot]