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

Operation between Scalar and Matrix

Tags: None
(comma "," separated)
vkubicki
Registered Member
Posts
14
Karma
0

Operation between Scalar and Matrix

Fri Aug 14, 2015 3:06 pm
Hi,

I wanted to implement a scalar / matrix operator, to be able to use this kind of syntax: "2 + mat". And then extend it to have "1 / mat" and so on.

I declared this:

Code: Select all
/** Element-wise + between scalar and matrix */
template<typename Scalar,
         typename Derived>
inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<Scalar>,
                                 const Derived>
operator+(const Scalar& scalar, const Eigen::MatrixBase<Derived>& matrix)
{
  return Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<Scalar>,
                             const Derived>(matrix.derived(),
                                            Eigen::internal::scalar_add_op<Scalar>(scalar));
}


The compilation failed, and I got this error message:

Code: Select all
In file included from ../eigen/Eigen/Core:297:0,
                 from ../eigen/Eigen/Dense:1,
                 from utest/../src/LinAlg/mixt_LinAlg.h:27,
                 from utest/UTestLinAlg.cpp:25:
../eigen/Eigen/src/Core/CwiseUnaryOp.h: In instantiation of ‘Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::PacketScalar Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::packet(Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index) const [with int LoadMode = 1; UnaryOp = Eigen::internal::scalar_add_op<int>; XprType = const Eigen::Matrix<double, -1, 1>; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::PacketScalar = __vector(2) double; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index = long int]’:
../eigen/Eigen/src/Core/DenseCoeffsBase.h:537:7:   required from ‘void Eigen::DenseCoeffsBase<Derived, 1>::copyPacket(Eigen::DenseCoeffsBase<Derived, 1>::Index, const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<int>, const Eigen::Matrix<double, -1, 1> >; int StoreMode = 1; int LoadMode = 1; Derived = Eigen::Matrix<double, -1, 1>; Eigen::DenseCoeffsBase<Derived, 1>::Index = long int]’
../eigen/Eigen/src/Core/Assign.h:410:7:   required from ‘static void Eigen::internal::assign_impl<Derived1, Derived2, 3, 0, Version>::run(Derived1&, const Derived2&) [with Derived1 = Eigen::Matrix<double, -1, 1>; Derived2 = Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<int>, const Eigen::Matrix<double, -1, 1> >; int Version = 0]’
../eigen/Eigen/src/Core/Assign.h:500:111:   required from ‘Derived& Eigen::DenseBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<int>, const Eigen::Matrix<double, -1, 1> >; Derived = Eigen::Matrix<double, -1, 1>]’
../eigen/Eigen/src/Core/PlainObjectBase.h:414:46:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::lazyAssign(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<int>, const Eigen::Matrix<double, -1, 1> >; Derived = Eigen::Matrix<double, -1, 1>]’
../eigen/Eigen/src/Core/Assign.h:520: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_add_op<int>, const Eigen::Matrix<double, -1, 1> >]’
../eigen/Eigen/src/Core/PlainObjectBase.h:621:105:   required from ‘Derived& Eigen::PlainObjectBase<Derived>::_set_noalias(const Eigen::DenseBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<int>, const Eigen::Matrix<double, -1, 1> >; Derived = Eigen::Matrix<double, -1, 1>]’
../eigen/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_add_op<int>, const Eigen::Matrix<double, -1, 1> >; _Scalar = double; int _Rows = -1; int _Cols = 1; int _Options = 0; int _MaxRows = -1; int _MaxCols = 1]’
utest/../src/LinAlg/mixt_LinAlg.h:62:43:   required from ‘mixt::Matrix<T, _Rows, _Cols>::Matrix(const Eigen::MatrixBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<int>, const Eigen::Matrix<double, -1, 1> >; T = double; int _Rows = -1; int _Cols = 1]’
utest/../src/LinAlg/mixt_LinAlg.h:105:32:   required from ‘mixt::Vector<T, _Rows>::Vector(const Eigen::MatrixBase<OtherDerived>&) [with OtherDerived = Eigen::CwiseUnaryOp<Eigen::internal::scalar_add_op<int>, const Eigen::Matrix<double, -1, 1> >; T = double; int _Rows = -1]’
utest/UTestLinAlg.cpp:45:27:   required from here
../eigen/Eigen/src/Core/CwiseUnaryOp.h:120:104: error: no matching function for call to ‘Eigen::internal::scalar_add_op<int>::packetOp(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1> >::PacketScalar) const’
       return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
                                                                                                        ^
../eigen/Eigen/src/Core/CwiseUnaryOp.h:120:104: note: candidate is:
In file included from ../eigen/Eigen/Core:276:0,
                 from ../eigen/Eigen/Dense:1,
                 from utest/../src/LinAlg/mixt_LinAlg.h:27,
                 from utest/UTestLinAlg.cpp:25:
../eigen/Eigen/src/Core/Functors.h:673:23: note: const Packet Eigen::internal::scalar_add_op<Scalar>::packetOp(const Packet&) const [with Scalar = int; Eigen::internal::scalar_add_op<Scalar>::Packet = __vector(2) long long int]
   inline const Packet packetOp(const Packet& a) const
                       ^
../eigen/Eigen/src/Core/Functors.h:673:23: note:   no known conversion for argument 1 from ‘Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1> >::PacketScalar {aka __vector(2) double}’ to ‘const Packet& {aka const __vector(2) long long int&}’
In file included from ../eigen/Eigen/Core:297:0,
                 from ../eigen/Eigen/Dense:1,
                 from utest/../src/LinAlg/mixt_LinAlg.h:27,
                 from utest/UTestLinAlg.cpp:25:
../eigen/Eigen/src/Core/CwiseUnaryOp.h: In member function ‘Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::PacketScalar Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::packet(Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index) const [with int LoadMode = 1; UnaryOp = Eigen::internal::scalar_add_op<int>; XprType = const Eigen::Matrix<double, -1, 1>; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::PacketScalar = __vector(2) double; Eigen::CwiseUnaryOpImpl<UnaryOp, XprType, Eigen::Dense>::Index = long int]’:
../eigen/Eigen/src/Core/CwiseUnaryOp.h:121:5: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
make: *** [utest/UTestLinAlg.o] Error 1


Did I miss something obvious ? Is there an easy way to implement what I want ?

Thank you for you help !
vkubicki
Registered Member
Posts
14
Karma
0
I did not see that this is a simple example provided by http://eigen.tuxfamily.org/dox-devel/To ... Eigen.html, which works.

Is there a simple that could make my first solution work without without defining a friend function in MatrixBaseAddons.h, out of curiosity ?
vkubicki
Registered Member
Posts
14
Karma
0
I added this function:

Code: Select all
/** Element-wise - between a scalar and a matrix */
friend inline const CwiseUnaryOp<internal::scalar_add_op<Scalar>,
                                 const Derived>
operator-(const Scalar& scalar,
          const MatrixBase<Derived>& mat)
{
  return CwiseUnaryOp<internal::scalar_add_op<Scalar>,
                      const Derived>(- mat.derived(),
                                     internal::scalar_add_op<Scalar>(scalar));
}


However this code:

Code: Select all
Vector<Real> vecA(3);
vecA << 32., 3., 7.;
std::cout << 10.  -  vecA << std::endl;


outputs:

Code: Select all
10
7
3


I do not understand why the operation is correctly applied on all elements of the vector but the first ?
vkubicki
Registered Member
Posts
14
Karma
0
The correct implementation is described in this post: viewtopic.php?f=74&t=127727.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Note that what your are looking for is Array<>, not Matrix<>, for which all these operations are already available. See: http://eigen.tuxfamily.org/dox/group__T ... Class.html


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], q.ignora, watchstar