From feb6b827a33390ffaeb348eef4259c4a73ab34bd Mon Sep 17 00:00:00 2001 From: Christoph Lehmann <christoph.lehmann@ufz.de> Date: Wed, 24 Aug 2016 11:32:50 +0200 Subject: [PATCH] [MaL] templated EigenMapTools --- MathLib/LinAlg/Eigen/EigenMapTools.cpp | 67 ---------- MathLib/LinAlg/Eigen/EigenMapTools.h | 175 +++++++++++++++++++++++-- 2 files changed, 161 insertions(+), 81 deletions(-) delete mode 100644 MathLib/LinAlg/Eigen/EigenMapTools.cpp diff --git a/MathLib/LinAlg/Eigen/EigenMapTools.cpp b/MathLib/LinAlg/Eigen/EigenMapTools.cpp deleted file mode 100644 index 42ed4394238..00000000000 --- a/MathLib/LinAlg/Eigen/EigenMapTools.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/** - * \copyright - * Copyright (c) 2012-2016, OpenGeoSys Community (http://www.opengeosys.org) - * Distributed under a Modified BSD License. - * See accompanying file LICENSE.txt or - * http://www.opengeosys.org/project/license - * - */ - -#include "EigenMapTools.h" -#include <cassert> - -namespace MathLib -{ -Eigen::Map< - Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> -toZeroedMatrix(std::vector<double>& data, - Eigen::MatrixXd::Index rows, - Eigen::MatrixXd::Index cols) -{ - assert(data.empty()); // in order that resize fills the vector with zeros. - data.resize(rows * cols); - return {data.data(), rows, cols}; -} - -Eigen::Map<const Eigen:: - Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> -toMatrix(std::vector<double> const& data, - Eigen::MatrixXd::Index rows, - Eigen::MatrixXd::Index cols) -{ - assert(static_cast<Eigen::MatrixXd::Index>(data.size()) == rows * cols); - return {data.data(), rows, cols}; -} - -Eigen::Map< - Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> -toMatrix(std::vector<double>& data, - Eigen::MatrixXd::Index rows, - Eigen::MatrixXd::Index cols) -{ - assert(static_cast<Eigen::MatrixXd::Index>(data.size()) == rows * cols); - return {data.data(), rows, cols}; -} - -Eigen::Map<Eigen::VectorXd> toZeroedVector(std::vector<double>& data, - Eigen::VectorXd::Index rows) -{ - assert(data.empty()); // in order that resize fills the vector with zeros. - data.resize(rows); - return {data.data(), rows}; -} - -Eigen::Map<const Eigen::VectorXd> toVector(std::vector<double> const& data, - Eigen::VectorXd::Index rows) -{ - assert(static_cast<Eigen::VectorXd::Index>(data.size()) == rows); - return {data.data(), rows}; -} - -Eigen::Map<Eigen::VectorXd> toVector(std::vector<double>& data, - Eigen::VectorXd::Index rows) -{ - assert(static_cast<Eigen::VectorXd::Index>(data.size()) == rows); - return {data.data(), rows}; -} -} // MathLib diff --git a/MathLib/LinAlg/Eigen/EigenMapTools.h b/MathLib/LinAlg/Eigen/EigenMapTools.h index 77fcb74b410..4887a9bb0c5 100644 --- a/MathLib/LinAlg/Eigen/EigenMapTools.h +++ b/MathLib/LinAlg/Eigen/EigenMapTools.h @@ -7,37 +7,184 @@ * */ -#pragma once +#ifndef MATHLIB_EIGENMAPTOOLS_H +#define MATHLIB_EIGENMAPTOOLS_H +#include <cassert> #include <vector> #include <Eigen/Core> namespace MathLib { -Eigen::Map< +/*! Creates an Eigen mapped matrix from the given data vector. + * + * \return An Eigen mapped matrix of the given size. All values of the matrix + * are set to zero. + * + * \pre The passed \c data vector must have zero size. + * \post The \c data has size \c rows * \c cols. + * + * \note The data vector will have the same storage order (row or column major) + * as the requested matrix type. + */ +template <typename Matrix> +Eigen::Map<Matrix> toZeroedMatrix(std::vector<double>& data, + Eigen::MatrixXd::Index rows, + Eigen::MatrixXd::Index cols) +{ + static_assert(Matrix::IsRowMajor || Matrix::IsVectorAtCompileTime, + "The default storage order in OGS is row major storage for " + "dense matrices."); + assert(Matrix::RowsAtCompileTime == Eigen::Dynamic || + Matrix::RowsAtCompileTime == rows); + assert(Matrix::ColsAtCompileTime == Eigen::Dynamic || + Matrix::ColsAtCompileTime == cols); + assert(data.empty()); // in order that resize fills the vector with zeros. + + data.resize(rows * cols); + return {data.data(), rows, cols}; +} + +/*! Creates an Eigen mapped matrix from the given data vector. + * + * This is a convienence method which makes the specification of dynamically + * allocated Eigen matrices as return type easier. + */ +inline Eigen::Map< Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> toZeroedMatrix(std::vector<double>& data, Eigen::MatrixXd::Index rows, - Eigen::MatrixXd::Index cols); + Eigen::MatrixXd::Index cols) +{ + return toZeroedMatrix< + Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>( + data, rows, cols); +} -Eigen::Map<const Eigen:: - Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> +/*! Creates an Eigen mapped matrix from the given data vector. + * + * \attention The data vector must have the same storage order (row or column + * major) as the requested matrix type. + */ +template <typename Matrix> +Eigen::Map<const Matrix> toMatrix(std::vector<double> const& data, + Eigen::MatrixXd::Index rows, + Eigen::MatrixXd::Index cols) +{ + static_assert(Matrix::IsRowMajor || Matrix::IsVectorAtCompileTime, + "The default storage order in OGS is row major storage for " + "dense matrices."); + assert(Matrix::RowsAtCompileTime == Eigen::Dynamic || + Matrix::RowsAtCompileTime == rows); + assert(Matrix::ColsAtCompileTime == Eigen::Dynamic || + Matrix::ColsAtCompileTime == cols); + assert(static_cast<Eigen::MatrixXd::Index>(data.size()) == rows * cols); + + return {data.data(), rows, cols}; +} + +/*! Creates an Eigen mapped matrix from the given data vector. + * + * This is a convienence method which makes the specification of dynamically + * allocated Eigen matrices as return type easier. + */ +inline Eigen::Map< + const Eigen:: + Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> toMatrix(std::vector<double> const& data, Eigen::MatrixXd::Index rows, - Eigen::MatrixXd::Index cols); + Eigen::MatrixXd::Index cols) +{ + return toMatrix< + Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>( + data, rows, cols); +} -Eigen::Map< +/*! Creates an Eigen mapped matrix from the given data vector. + * + * \attention The data vector must have the same storage order (row or column + * major) as the requested matrix type. + */ +template <typename Matrix> +Eigen::Map<Matrix> toMatrix(std::vector<double>& data, + Eigen::MatrixXd::Index rows, + Eigen::MatrixXd::Index cols) +{ + static_assert(Matrix::IsRowMajor || Matrix::IsVectorAtCompileTime, + "The default storage order in OGS is row major storage for " + "dense matrices."); + assert(Matrix::RowsAtCompileTime == Eigen::Dynamic || + Matrix::RowsAtCompileTime == rows); + assert(Matrix::ColsAtCompileTime == Eigen::Dynamic || + Matrix::ColsAtCompileTime == cols); + assert(static_cast<Eigen::MatrixXd::Index>(data.size()) == rows * cols); + + return {data.data(), rows, cols}; +} + +/*! Creates an Eigen mapped matrix from the given data vector. + * + * This is a convienence method which makes the specification of dynamically + * allocated Eigen matrices as return type easier. + */ +inline Eigen::Map< Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>> toMatrix(std::vector<double>& data, Eigen::MatrixXd::Index rows, - Eigen::MatrixXd::Index cols); + Eigen::MatrixXd::Index cols) +{ + return toMatrix< + Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>( + data, rows, cols); +} + +/*! Creates an Eigen mapped vector from the given data vector. + * + * \return An Eigen mapped vector of the given size. All values of the vector + * are set to zero. + * + * \pre The passed \c data vector must have zero size. + * \post The \c data has size \c size. + */ +template <typename Vector> +Eigen::Map<Vector> toZeroedVector(std::vector<double>& data, + Eigen::VectorXd::Index size) +{ + static_assert(Vector::IsVectorAtCompileTime, "A vector type is required."); + assert(Vector::SizeAtCompileTime == Eigen::Dynamic || + Vector::SizeAtCompileTime == size); + assert(data.empty()); // in order that resize fills the vector with zeros. -Eigen::Map<Eigen::VectorXd> toZeroedVector(std::vector<double>& data, - Eigen::VectorXd::Index rows); + data.resize(size); + return {data.data(), size}; +} + +//! Creates an Eigen mapped vector from the given data vector. +template <typename Vector> +Eigen::Map<const Vector> toVector(std::vector<double> const& data, + Eigen::VectorXd::Index size) +{ + static_assert(Vector::IsVectorAtCompileTime, "A vector type is required."); + assert(Vector::SizeAtCompileTime == Eigen::Dynamic || + Vector::SizeAtCompileTime == size); + assert(static_cast<Eigen::VectorXd::Index>(data.size()) == size); -Eigen::Map<const Eigen::VectorXd> toVector(std::vector<double> const& data, - Eigen::VectorXd::Index rows); + return {data.data(), size}; +} + +//! Creates an Eigen mapped vector from the given data vector. +template <typename Vector> +Eigen::Map<Vector> toVector(std::vector<double>& data, + Eigen::VectorXd::Index size) +{ + static_assert(Vector::IsVectorAtCompileTime, "A vector type is required."); + assert(Vector::SizeAtCompileTime == Eigen::Dynamic || + Vector::SizeAtCompileTime == size); + assert(static_cast<Eigen::VectorXd::Index>(data.size()) == size); + + return {data.data(), size}; +} -Eigen::Map<Eigen::VectorXd> toVector(std::vector<double>& data, - Eigen::VectorXd::Index rows); } // MathLib + +#endif // MATHLIB_EIGENMAPTOOLS_H -- GitLab