mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Clang-format tests, examples, libraries, benchmarks, etc.
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
3252ecc7a4
commit
46e9cdb7fe
@@ -9,81 +9,70 @@ using Eigen::SparseMatrix;
|
||||
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
// MatrixReplacement looks-like a SparseMatrix, so let's inherit its traits:
|
||||
template<>
|
||||
struct traits<MatrixReplacement> : public Eigen::internal::traits<Eigen::SparseMatrix<double> >
|
||||
{};
|
||||
}
|
||||
}
|
||||
// MatrixReplacement looks-like a SparseMatrix, so let's inherit its traits:
|
||||
template <>
|
||||
struct traits<MatrixReplacement> : public Eigen::internal::traits<Eigen::SparseMatrix<double> > {};
|
||||
} // namespace internal
|
||||
} // namespace Eigen
|
||||
|
||||
// Example of a matrix-free wrapper from a user type to Eigen's compatible type
|
||||
// For the sake of simplicity, this example simply wrap a Eigen::SparseMatrix.
|
||||
class MatrixReplacement : public Eigen::EigenBase<MatrixReplacement> {
|
||||
public:
|
||||
public:
|
||||
// Required typedefs, constants, and method:
|
||||
typedef double Scalar;
|
||||
typedef double RealScalar;
|
||||
typedef int StorageIndex;
|
||||
enum {
|
||||
ColsAtCompileTime = Eigen::Dynamic,
|
||||
MaxColsAtCompileTime = Eigen::Dynamic,
|
||||
IsRowMajor = false
|
||||
};
|
||||
enum { ColsAtCompileTime = Eigen::Dynamic, MaxColsAtCompileTime = Eigen::Dynamic, IsRowMajor = false };
|
||||
|
||||
Index rows() const { return mp_mat->rows(); }
|
||||
Index cols() const { return mp_mat->cols(); }
|
||||
|
||||
template<typename Rhs>
|
||||
Eigen::Product<MatrixReplacement,Rhs,Eigen::AliasFreeProduct> operator*(const Eigen::MatrixBase<Rhs>& x) const {
|
||||
return Eigen::Product<MatrixReplacement,Rhs,Eigen::AliasFreeProduct>(*this, x.derived());
|
||||
template <typename Rhs>
|
||||
Eigen::Product<MatrixReplacement, Rhs, Eigen::AliasFreeProduct> operator*(const Eigen::MatrixBase<Rhs>& x) const {
|
||||
return Eigen::Product<MatrixReplacement, Rhs, Eigen::AliasFreeProduct>(*this, x.derived());
|
||||
}
|
||||
|
||||
// Custom API:
|
||||
MatrixReplacement() : mp_mat(0) {}
|
||||
|
||||
void attachMyMatrix(const SparseMatrix<double> &mat) {
|
||||
mp_mat = &mat;
|
||||
}
|
||||
void attachMyMatrix(const SparseMatrix<double>& mat) { mp_mat = &mat; }
|
||||
const SparseMatrix<double> my_matrix() const { return *mp_mat; }
|
||||
|
||||
private:
|
||||
const SparseMatrix<double> *mp_mat;
|
||||
private:
|
||||
const SparseMatrix<double>* mp_mat;
|
||||
};
|
||||
|
||||
|
||||
// Implementation of MatrixReplacement * Eigen::DenseVector though a specialization of internal::generic_product_impl:
|
||||
namespace Eigen {
|
||||
namespace internal {
|
||||
|
||||
template<typename Rhs>
|
||||
struct generic_product_impl<MatrixReplacement, Rhs, SparseShape, DenseShape, GemvProduct> // GEMV stands for matrix-vector
|
||||
: generic_product_impl_base<MatrixReplacement,Rhs,generic_product_impl<MatrixReplacement,Rhs> >
|
||||
{
|
||||
typedef typename Product<MatrixReplacement,Rhs>::Scalar Scalar;
|
||||
template <typename Rhs>
|
||||
struct generic_product_impl<MatrixReplacement, Rhs, SparseShape, DenseShape,
|
||||
GemvProduct> // GEMV stands for matrix-vector
|
||||
: generic_product_impl_base<MatrixReplacement, Rhs, generic_product_impl<MatrixReplacement, Rhs> > {
|
||||
typedef typename Product<MatrixReplacement, Rhs>::Scalar Scalar;
|
||||
|
||||
template<typename Dest>
|
||||
static void scaleAndAddTo(Dest& dst, const MatrixReplacement& lhs, const Rhs& rhs, const Scalar& alpha)
|
||||
{
|
||||
// This method should implement "dst += alpha * lhs * rhs" inplace,
|
||||
// however, for iterative solvers, alpha is always equal to 1, so let's not bother about it.
|
||||
eigen_assert(alpha==Scalar(1) && "scaling is not implemented");
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(alpha);
|
||||
template <typename Dest>
|
||||
static void scaleAndAddTo(Dest& dst, const MatrixReplacement& lhs, const Rhs& rhs, const Scalar& alpha) {
|
||||
// This method should implement "dst += alpha * lhs * rhs" inplace,
|
||||
// however, for iterative solvers, alpha is always equal to 1, so let's not bother about it.
|
||||
eigen_assert(alpha == Scalar(1) && "scaling is not implemented");
|
||||
EIGEN_ONLY_USED_FOR_DEBUG(alpha);
|
||||
|
||||
// Here we could simply call dst.noalias() += lhs.my_matrix() * rhs,
|
||||
// but let's do something fancier (and less efficient):
|
||||
for(Index i=0; i<lhs.cols(); ++i)
|
||||
dst += rhs(i) * lhs.my_matrix().col(i);
|
||||
}
|
||||
};
|
||||
// Here we could simply call dst.noalias() += lhs.my_matrix() * rhs,
|
||||
// but let's do something fancier (and less efficient):
|
||||
for (Index i = 0; i < lhs.cols(); ++i) dst += rhs(i) * lhs.my_matrix().col(i);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // namespace internal
|
||||
} // namespace Eigen
|
||||
|
||||
int main()
|
||||
{
|
||||
int main() {
|
||||
int n = 10;
|
||||
Eigen::SparseMatrix<double> S = Eigen::MatrixXd::Random(n,n).sparseView(0.5,1);
|
||||
S = S.transpose()*S;
|
||||
Eigen::SparseMatrix<double> S = Eigen::MatrixXd::Random(n, n).sparseView(0.5, 1);
|
||||
S = S.transpose() * S;
|
||||
|
||||
MatrixReplacement A;
|
||||
A.attachMyMatrix(S);
|
||||
@@ -93,7 +82,7 @@ int main()
|
||||
|
||||
// Solve Ax = b using various iterative solver with matrix-free version:
|
||||
{
|
||||
Eigen::ConjugateGradient<MatrixReplacement, Eigen::Lower|Eigen::Upper, Eigen::IdentityPreconditioner> cg;
|
||||
Eigen::ConjugateGradient<MatrixReplacement, Eigen::Lower | Eigen::Upper, Eigen::IdentityPreconditioner> cg;
|
||||
cg.compute(A);
|
||||
x = cg.solve(b);
|
||||
std::cout << "CG: #iterations: " << cg.iterations() << ", estimated error: " << cg.error() << std::endl;
|
||||
@@ -121,9 +110,10 @@ int main()
|
||||
}
|
||||
|
||||
{
|
||||
Eigen::MINRES<MatrixReplacement, Eigen::Lower|Eigen::Upper, Eigen::IdentityPreconditioner> minres;
|
||||
Eigen::MINRES<MatrixReplacement, Eigen::Lower | Eigen::Upper, Eigen::IdentityPreconditioner> minres;
|
||||
minres.compute(A);
|
||||
x = minres.solve(b);
|
||||
std::cout << "MINRES: #iterations: " << minres.iterations() << ", estimated error: " << minres.error() << std::endl;
|
||||
std::cout << "MINRES: #iterations: " << minres.iterations() << ", estimated error: " << minres.error()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user