10 #ifndef MRPT_EIGEN_PLUGINS_IMPL_H 11 #define MRPT_EIGEN_PLUGINS_IMPL_H 21 template <
int R,
int C>
24 template <
typename S,
int Opt,
int MaxR,
int MaxC>
26 Eigen::Matrix<S, R, C, Opt, MaxR, MaxC>& mat,
size_t new_rows,
30 Eigen::Matrix<S, R, C, Opt, MaxR, MaxC>,
31 Eigen::Matrix<S, R, C, Opt, MaxR, MaxC>::SizeAtCompileTime>::
32 internal_resize(mat, new_rows, new_cols);
39 template <
typename S,
int Opt,
int MaxR,
int MaxC>
41 Eigen::Matrix<S, R, 1, Opt, MaxR, MaxC>& mat,
size_t new_rows,
size_t)
44 Eigen::Matrix<S, R, 1, Opt, MaxR, MaxC>,
45 Eigen::Matrix<S, R, 1, Opt, MaxR, MaxC>::SizeAtCompileTime>::
46 internal_resize(mat, new_rows);
53 template <
typename S,
int Opt,
int MaxR,
int MaxC>
55 Eigen::Matrix<S, 1, C, Opt, MaxR, MaxC>& mat,
size_t,
size_t new_cols)
58 Eigen::Matrix<S, 1, C, Opt, MaxR, MaxC>,
59 Eigen::Matrix<S, 1, C, Opt, MaxR, MaxC>::SizeAtCompileTime>::
60 internal_resize(mat, new_cols);
66 template <
typename S,
int Opt,
int MaxR,
int MaxC>
68 Eigen::Matrix<S, 1, 1, Opt, MaxR, MaxC>& mat,
size_t,
size_t new_cols)
71 Eigen::Matrix<S, 1, 1, Opt, MaxR, MaxC>,
72 Eigen::Matrix<S, 1, 1, Opt, MaxR, MaxC>::SizeAtCompileTime>::
73 internal_resize(mat, new_cols);
81 template <
class Derived>
82 template <
class MATRIX1,
class MATRIX2>
84 MATRIX1& eVecs, MATRIX2& eVals)
const 86 Matrix<Scalar, Dynamic, 1> evals;
88 eVals.resize(evals.size(), evals.size());
90 eVals.diagonal() = evals;
97 template <
class Derived>
98 template <
class MATRIX1,
class VECTOR1>
100 MATRIX1& eVecs, VECTOR1& eVals)
const 102 Eigen::EigenSolver<Derived> es(*
this,
true);
103 if (es.info() != Eigen::Success)
return false;
105 es.eigenvectors().real();
107 es.eigenvalues().real();
110 std::vector<std::pair<Scalar, Index>> D;
111 D.reserve(eVals.size());
112 for (Index i = 0; i < eVals.size(); i++)
113 D.push_back(std::pair<Scalar, Index>(eVals.coeff(i, 0), i));
114 std::sort(D.begin(), D.end());
116 sortedEigs.resizeLike(eVecs);
117 for (
int i = 0; i < eVals.size(); i++)
119 eVals.coeffRef(i, 0) = D[i].first;
120 sortedEigs.col(i) = eVecs.col(D[i].second);
129 template <
class Derived>
130 template <
class MATRIX1,
class MATRIX2>
132 MATRIX1& eVecs, MATRIX2& eVals)
const 134 Matrix<Scalar, Dynamic, 1> evals;
136 eVals.resize(evals.size(), evals.size());
138 eVals.diagonal() = evals;
144 template <
class Derived>
145 template <
class MATRIX1,
class VECTOR1>
147 MATRIX1& eVecs, VECTOR1& eVals)
const 151 eVecs = eigensolver.eigenvectors();
152 eVals = eigensolver.eigenvalues();
155 template <
class Derived>
160 if (Derived::RowsAtCompileTime == Eigen::Dynamic) (*this) = Derived();
163 size_t ini =
s.find_first_not_of(
" \t\r\n");
164 if (ini == std::string::npos ||
s[ini] !=
'[')
169 size_t end =
s.find_last_not_of(
" \t\r\n");
170 if (
end == std::string::npos ||
s[
end] !=
']')
return false;
172 if (ini >
end)
return false;
174 std::vector<Scalar> lstElements;
182 size_t end_row =
s.find_first_of(
";]", i);
183 if (end_row == std::string::npos)
189 std::stringstream ss(
s.substr(i, end_row - i));
197 if (ss.bad() || ss.fail())
break;
198 lstElements.push_back(
val);
206 if (lstElements.empty())
214 if (Derived::RowsAtCompileTime == Eigen::Dynamic)
220 const size_t N = lstElements.size();
223 if ((nRow > 0 &&
size_t(cols()) != N) ||
224 (nRow == 0 && Derived::ColsAtCompileTime != Eigen::Dynamic &&
225 Derived::ColsAtCompileTime !=
int(N)))
227 if (dump_errors_here)
228 (*dump_errors_here) <<
"[fromMatlabStringFormat] Row " 230 <<
" has invalid number of columns.\n";
235 if (Derived::RowsAtCompileTime == Eigen::Dynamic ||
236 Derived::ColsAtCompileTime == Eigen::Dynamic)
238 Derived::RowsAtCompileTime,
239 Derived::ColsAtCompileTime>::doit(derived(), nRow + 1, N);
241 Derived::RowsAtCompileTime != Eigen::Dynamic &&
242 int(nRow) >= Derived::RowsAtCompileTime)
244 if (dump_errors_here)
245 (*dump_errors_here) <<
"[fromMatlabStringFormat] Read more " 246 "rows than the capacity of the " 247 "fixed sized matrix.\n";
251 for (
size_t q = 0;
q < N;
q++) coeffRef(nRow,
q) = lstElements[
q];
260 if (Derived::RowsAtCompileTime != Eigen::Dynamic &&
261 int(nRow) != Derived::RowsAtCompileTime)
263 if (dump_errors_here)
264 (*dump_errors_here) <<
"[fromMatlabStringFormat] Read less rows " 265 "than the capacity of the fixed sized " 272 template <
class Derived>
274 const size_t decimal_digits)
const 277 s <<
"[" << std::scientific;
278 s.precision(decimal_digits);
279 for (Index i = 0; i < rows(); i++)
281 for (Index j = 0; j < cols(); j++)
s << coeff(i, j) <<
" ";
282 if (i < rows() - 1)
s <<
";";
288 template <
class Derived>
291 bool appendMRPTHeader,
const std::string& userHeader)
const 293 #if defined(_MSC_VER) && \ 294 (_MSC_VER >= 1400) // Use a secure version in Visual Studio 2005+ 296 if (0 != ::fopen_s(&f, file.c_str(),
"wt")) f =
nullptr;
298 FILE* f =
::fopen(file.c_str(),
"wt");
301 throw std::runtime_error(
302 std::string(
"saveToTextFile: Error opening file ") + file +
305 if (!userHeader.empty())
fprintf(f,
"%s", userHeader.c_str());
307 if (appendMRPTHeader)
311 #if defined(_MSC_VER) && \ 312 (_MSC_VER >= 1400) // Use a secure version in Visual Studio 2005+ 313 struct tm timeinfo_data;
315 if (0 != ::localtime_s(&timeinfo_data, &rawtime))
318 timeinfo = &timeinfo_data;
320 struct tm* timeinfo = ::localtime(&rawtime);
323 #if defined(_MSC_VER) && \ 324 (_MSC_VER >= 1400) // Use a secure version in Visual Studio 2005+ 325 char strTimeBuf[100];
326 if (0 != asctime_s(strTimeBuf,
sizeof(strTimeBuf), timeinfo))
327 strTimeBuf[0] =
'\0';
328 char* strTime = &strTimeBuf[0];
330 char* strTime = asctime(timeinfo);
334 "%% File generated with %s at " 335 "%s\n%%------------------------------------------------------------" 340 for (Index i = 0; i < rows(); i++)
342 for (Index j = 0; j < cols(); j++)
347 ::fprintf(f,
"%.16e", static_cast<double>(coeff(i, j)));
350 ::fprintf(f,
"%.16f", static_cast<double>(coeff(i, j)));
353 ::fprintf(f,
"%i", static_cast<int>(coeff(i, j)));
356 throw std::runtime_error(
357 "Unsupported value for the parameter 'fileFormat'!");
367 template <
class Derived>
370 std::ifstream f(file.c_str());
372 throw std::runtime_error(
373 std::string(
"loadFromTextFile: can't open file:") + file);
377 template <
class Derived>
382 std::vector<double> fil(512);
384 while (!f.eof() && !f.fail())
386 std::getline(f, str);
387 if (str.size() && str[0] !=
'#' && str[0] !=
'%')
390 const char* ptr = str.c_str();
391 char* ptrEnd =
nullptr;
394 while (ptr[0] && ptr != ptrEnd)
398 (ptr[0] ==
' ' || ptr[0] ==
',' || ptr[0] ==
'\t' ||
399 ptr[0] ==
'\r' || ptr[0] ==
'\n'))
401 if (fil.size() <= i) fil.resize(fil.size() + (fil.size() >> 1));
403 fil[i] = strtod(ptr, &ptrEnd);
414 if ((Derived::ColsAtCompileTime != Eigen::Dynamic &&
415 Index(i) != Derived::ColsAtCompileTime))
416 throw std::runtime_error(
417 "loadFromTextFile: The matrix in the text file does not " 418 "match fixed matrix size");
419 if (Derived::ColsAtCompileTime == Eigen::Dynamic && nRows > 0 &&
421 throw std::runtime_error(
422 "loadFromTextFile: The matrix in the text file does not " 423 "have the same number of columns in all rows");
426 if (Derived::RowsAtCompileTime == Eigen::Dynamic ||
427 Derived::ColsAtCompileTime == Eigen::Dynamic)
429 if (rows() < static_cast<int>(nRows + 1) ||
430 cols() < static_cast<int>(i))
432 const size_t extra_rows =
433 std::max(static_cast<size_t>(1), nRows >> 1);
435 Derived::ColsAtCompileTime>::
436 doit(derived(), nRows + extra_rows, i);
440 Derived::RowsAtCompileTime != Eigen::Dynamic &&
441 int(nRows) >= Derived::RowsAtCompileTime)
442 throw std::runtime_error(
443 "loadFromTextFile: Read more rows than the capacity of the " 444 "fixed sized matrix.");
446 for (
size_t q = 0;
q < i;
q++) coeffRef(nRows,
q) =
Scalar(fil[
q]);
453 if (Derived::RowsAtCompileTime == Eigen::Dynamic ||
454 Derived::ColsAtCompileTime == Eigen::Dynamic)
456 Derived::RowsAtCompileTime,
457 Derived::ColsAtCompileTime>::doit(derived(), nRows, cols());
461 throw std::runtime_error(
462 "loadFromTextFile: Error loading from text file");
465 #endif // guard define
std::string inMatlabFormat(const size_t decimal_digits=6) const
Dump matrix in matlab format.
engineering format 'e'
EIGEN_STRONG_INLINE bool eigenVectors(MATRIX1 &eVecs, MATRIX2 &eVals) const
[For square matrices only] Compute the eigenvectors and eigenvalues (sorted), both returned as matric...
int void fclose(FILE *f)
An OS-independent version of fclose.
GLdouble GLdouble GLdouble GLdouble q
void saveToTextFile(const std::string &file, mrpt::math::TMatrixTextFileFormat fileFormat=mrpt::math::MATRIX_FORMAT_ENG, bool appendMRPTHeader=false, const std::string &userHeader=std::string()) const
Save matrix to a text file, compatible with MATLAB text format (see also the methods of matrix classe...
EIGEN_STRONG_INLINE void eigenVectorsSymmetricVec(MATRIX1 &eVecs, VECTOR1 &eVals) const
[For symmetric matrices only] Compute the eigenvectors and eigenvalues (in no particular order)...
EIGEN_STRONG_INLINE bool eigenVectorsVec(MATRIX1 &eVecs, VECTOR1 &eVals) const
[For square matrices only] Compute the eigenvectors and eigenvalues (sorted), eigenvectors are the co...
static void doit(Eigen::Matrix< S, 1, 1, Opt, MaxR, MaxC > &mat, size_t, size_t new_cols)
EIGEN_STRONG_INLINE void eigenVectorsSymmetric(MATRIX1 &eVecs, MATRIX2 &eVals) const
[For symmetric matrices only] Compute the eigenvectors and eigenvalues (in no particular order)...
static void doit(Eigen::Matrix< S, R, 1, Opt, MaxR, MaxC > &mat, size_t new_rows, size_t)
GLsizei const GLchar ** string
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
bool fromMatlabStringFormat(const std::string &s, std::ostream *dump_errors_here=nullptr)
Read a matrix from a string in Matlab-like format, for example "[1 0 2; 0 4 -1]" The string must star...
void loadFromTextFile(const std::string &file)
Load matrix from a text file, compatible with MATLAB text format.
Internal resize which compiles to nothing on fixed-size matrices.
static void doit(Eigen::Matrix< S, R, C, Opt, MaxR, MaxC > &mat, size_t new_rows, size_t new_cols)
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
static void doit(Eigen::Matrix< S, 1, C, Opt, MaxR, MaxC > &mat, size_t, size_t new_cols)
std::string MRPT_getVersion()
Returns a string describing the MRPT version.
fixed floating point 'f'