Eigen对QDebug 的输出接口
QEigenExt.h
#ifndef QEIGENEXT_H
#define QEIGENEXT_H
#pragma once
#include <QDebug>
#include <Eigen/Eigen>
namespace Eigen {
namespace internal {
template<typename Derived>
QDebug & print_matrix(QDebug & s, const Derived& _m, const IOFormat& fmt);
}// end namespace internal
} // end namespace Eigen
#define DECLARE_OSTREAM_OPERATOR(T) \
QDebug & operator << (QDebug & s, const T & m);
DECLARE_OSTREAM_OPERATOR( Eigen::Vector2f )
DECLARE_OSTREAM_OPERATOR( Eigen::Vector3f )
DECLARE_OSTREAM_OPERATOR( Eigen::Vector4f )
DECLARE_OSTREAM_OPERATOR( Eigen::VectorXf )
DECLARE_OSTREAM_OPERATOR( Eigen::Matrix2f )
DECLARE_OSTREAM_OPERATOR( Eigen::Matrix3f )
DECLARE_OSTREAM_OPERATOR( Eigen::Matrix4f )
DECLARE_OSTREAM_OPERATOR( Eigen::MatrixXf )
#endif // QEIGENEXT_H
QEigenExt.cpp
#include "QEigenExt.h"
#include <QString>
#include <Eigen/Eigen>
namespace Eigen {
namespace internal {
/** \internal
* print the matrix \a _m to the output stream \a s using the output format \a fmt */
template<typename Derived>
QDebug & print_matrix(QDebug & qDbg, const Derived& _m, const IOFormat& fmt)
{
std::stringstream s;
using internal::is_same;
using internal::conditional;
if(_m.size() == 0)
{
qDbg << QString::fromStdString(fmt.matPrefix) << QString::fromStdString(fmt.matSuffix);
return qDbg;
}
typename Derived::Nested m = _m;
typedef typename Derived::Scalar Scalar;
typedef typename
conditional<
is_same<Scalar, char>::value ||
is_same<Scalar, unsigned char>::value ||
is_same<Scalar, numext::int8_t>::value ||
is_same<Scalar, numext::uint8_t>::value,
int,
typename conditional<
is_same<Scalar, std::complex<char> >::value ||
is_same<Scalar, std::complex<unsigned char> >::value ||
is_same<Scalar, std::complex<numext::int8_t> >::value ||
is_same<Scalar, std::complex<numext::uint8_t> >::value,
std::complex<int>,
const Scalar&
>::type
>::type PrintType;
Index width = 0;
std::streamsize explicit_precision;
if(fmt.precision == StreamPrecision)
{
explicit_precision = 0;
}
else if(fmt.precision == FullPrecision)
{
if (NumTraits<Scalar>::IsInteger)
{
explicit_precision = 0;
}
else
{
explicit_precision = significant_decimals_impl<Scalar>::run();
}
}
else
{
explicit_precision = fmt.precision;
}
std::streamsize old_precision = 0;
if(explicit_precision) old_precision = s.precision(explicit_precision);
bool align_cols = !(fmt.flags & DontAlignCols);
if(align_cols)
{
// compute the largest width
for(Index j = 0; j < m.cols(); ++j)
for(Index i = 0; i < m.rows(); ++i)
{
std::stringstream sstr;
sstr.copyfmt(s);
sstr << static_cast<PrintType>(m.coeff(i,j));
width = std::max<Index>(width, Index(sstr.str().length()));
}
}
std::streamsize old_width = s.width();
char old_fill_character = s.fill();
s << fmt.matPrefix;
for(Index i = 0; i < m.rows(); ++i)
{
if (i)
s << fmt.rowSpacer;
s <<fmt.rowPrefix;
if(width) {
s.fill(fmt.fill);
s.width(width);
}
s << static_cast<PrintType>(m.coeff(i, 0));
for(Index j = 1; j < m.cols(); ++j)
{
s << fmt.coeffSeparator;
if(width) {
s.fill(fmt.fill);
s.width(width);
}
s << static_cast<PrintType>(m.coeff(i, j));
}
s << fmt.rowSuffix;
if( i < m.rows() - 1)
s << fmt.rowSeparator;
}
s << fmt.matSuffix;
if(explicit_precision) s.precision(old_precision);
if(width) {
s.fill(old_fill_character);
s.width(old_width);
}
qDbg << QString::fromStdString( s.str() );
return qDbg;
}
} // end namespace internal
} // end namespace Eigen
#define DEFINE_OSTREAM_OPERATOR(T) \
QDebug & operator << (QDebug & s, const T & m) { \
return Eigen::internal::print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); \
}
DEFINE_OSTREAM_OPERATOR( Eigen::Vector2f )
DEFINE_OSTREAM_OPERATOR( Eigen::Vector3f )
DEFINE_OSTREAM_OPERATOR( Eigen::Vector4f )
DEFINE_OSTREAM_OPERATOR( Eigen::VectorXf )
DEFINE_OSTREAM_OPERATOR( Eigen::Matrix2f )
DEFINE_OSTREAM_OPERATOR( Eigen::Matrix3f )
DEFINE_OSTREAM_OPERATOR( Eigen::Matrix4f )
DEFINE_OSTREAM_OPERATOR( Eigen::MatrixXf )