4#ifndef EIGEN_ACCELERATESUPPORT_H
5#define EIGEN_ACCELERATESUPPORT_H
7#include <Accelerate/Accelerate.h>
13template <
typename MatrixType_,
int UpLo_, SparseFactorization_t Solver_,
bool EnforceSquare_>
27template <
typename MatrixType,
int UpLo = Lower>
28using AccelerateLLT = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationCholesky, true>;
41template <
typename MatrixType,
int UpLo = Lower>
42using AccelerateLDLT = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationLDLT, true>;
55template <
typename MatrixType,
int UpLo = Lower>
70template <
typename MatrixType,
int UpLo = Lower>
71using AccelerateLDLTSBK = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationLDLTSBK, true>;
84template <
typename MatrixType,
int UpLo = Lower>
85using AccelerateLDLTTPP = AccelerateImpl<MatrixType, UpLo | Symmetric, SparseFactorizationLDLTTPP, true>;
97template <
typename MatrixType>
98using AccelerateQR = AccelerateImpl<MatrixType, 0, SparseFactorizationQR, false>;
110template <
typename MatrixType>
115struct AccelFactorizationDeleter {
116 void operator()(T* sym)
const {
125template <
typename DenseVecT,
typename DenseMatT,
typename SparseMatT,
typename NumFactT>
126struct SparseTypesTraitBase {
127 typedef DenseVecT AccelDenseVector;
128 typedef DenseMatT AccelDenseMatrix;
129 typedef SparseMatT AccelSparseMatrix;
131 typedef SparseOpaqueSymbolicFactorization SymbolicFactorization;
132 typedef NumFactT NumericFactorization;
134 typedef AccelFactorizationDeleter<SymbolicFactorization> SymbolicFactorizationDeleter;
135 typedef AccelFactorizationDeleter<NumericFactorization> NumericFactorizationDeleter;
138template <
typename Scalar>
139struct SparseTypesTrait {};
142struct SparseTypesTrait<double> : SparseTypesTraitBase<DenseVector_Double, DenseMatrix_Double, SparseMatrix_Double,
143 SparseOpaqueFactorization_Double> {};
146struct SparseTypesTrait<float>
147 : SparseTypesTraitBase<DenseVector_Float, DenseMatrix_Float, SparseMatrix_Float, SparseOpaqueFactorization_Float> {
152template <
typename MatrixType_,
int UpLo_, SparseFactorization_t Solver_,
bool EnforceSquare_>
153class AccelerateImpl :
public SparseSolverBase<AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_> > {
155 using Base = SparseSolverBase<AccelerateImpl>;
157 using Base::m_isInitialized;
160 using Base::_solve_impl;
162 typedef MatrixType_ MatrixType;
163 typedef typename MatrixType::Scalar Scalar;
164 typedef typename MatrixType::StorageIndex StorageIndex;
165 enum { ColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic };
166 enum { UpLo = UpLo_ };
168 using AccelDenseVector =
typename internal::SparseTypesTrait<Scalar>::AccelDenseVector;
169 using AccelDenseMatrix =
typename internal::SparseTypesTrait<Scalar>::AccelDenseMatrix;
170 using AccelSparseMatrix =
typename internal::SparseTypesTrait<Scalar>::AccelSparseMatrix;
171 using SymbolicFactorization =
typename internal::SparseTypesTrait<Scalar>::SymbolicFactorization;
172 using NumericFactorization =
typename internal::SparseTypesTrait<Scalar>::NumericFactorization;
173 using SymbolicFactorizationDeleter =
typename internal::SparseTypesTrait<Scalar>::SymbolicFactorizationDeleter;
174 using NumericFactorizationDeleter =
typename internal::SparseTypesTrait<Scalar>::NumericFactorizationDeleter;
177 m_isInitialized =
false;
180 m_sparseKind = SparseSymmetric;
181 m_triType = (UpLo_ &
Lower) ? SparseLowerTriangle : SparseUpperTriangle;
183 m_sparseKind = SparseUnitTriangular;
184 m_triType = SparseLowerTriangle;
186 m_sparseKind = SparseUnitTriangular;
187 m_triType = SparseUpperTriangle;
189 m_sparseKind = SparseTriangular;
190 m_triType = SparseLowerTriangle;
192 m_sparseKind = SparseTriangular;
193 m_triType = SparseUpperTriangle;
194 }
else EIGEN_IF_CONSTEXPR ((UpLo_ &
Lower) ==
Lower) {
195 m_sparseKind = SparseTriangular;
196 m_triType = SparseLowerTriangle;
197 }
else EIGEN_IF_CONSTEXPR ((UpLo_ &
Upper) ==
Upper) {
198 m_sparseKind = SparseTriangular;
199 m_triType = SparseUpperTriangle;
201 m_sparseKind = SparseOrdinary;
202 m_triType = (UpLo_ &
Lower) ? SparseLowerTriangle : SparseUpperTriangle;
205 m_order = SparseOrderDefault;
208 explicit AccelerateImpl(
const MatrixType& matrix) : AccelerateImpl() { compute(matrix); }
210 inline Index cols()
const {
return m_nCols; }
211 inline Index rows()
const {
return m_nRows; }
214 eigen_assert(m_isInitialized &&
"Decomposition is not initialized.");
218 void analyzePattern(
const MatrixType& matrix);
220 void factorize(
const MatrixType& matrix);
222 void compute(
const MatrixType& matrix);
224 template <
typename Rhs,
typename Dest>
225 void _solve_impl(
const MatrixBase<Rhs>& b, MatrixBase<Dest>& dest)
const;
228 void setOrder(SparseOrder_t order) { m_order = order; }
231 template <
typename T>
232 void buildAccelSparseMatrix(
const SparseMatrix<T>& a, AccelSparseMatrix& A, std::vector<long>& columnStarts) {
233 const Index nColumnsStarts = a.cols() + 1;
235 columnStarts.resize(nColumnsStarts);
237 for (Index i = 0; i < nColumnsStarts; i++) columnStarts[i] = a.outerIndexPtr()[i];
239 SparseAttributes_t attributes{};
240 attributes.transpose =
false;
241 attributes.triangle = m_triType;
242 attributes.kind = m_sparseKind;
244 SparseMatrixStructure structure{};
245 structure.attributes = attributes;
246 structure.rowCount =
static_cast<int>(a.rows());
247 structure.columnCount =
static_cast<int>(a.cols());
248 structure.blockSize = 1;
249 structure.columnStarts = columnStarts.data();
250 structure.rowIndices =
const_cast<int*
>(a.innerIndexPtr());
252 A.structure = structure;
253 A.data =
const_cast<T*
>(a.valuePtr());
256 void doAnalysis(AccelSparseMatrix& A) {
257 m_numericFactorization.reset();
259 SparseSymbolicFactorOptions opts{};
260 opts.control = SparseDefaultControl;
261 opts.orderMethod = m_order;
262 opts.order =
nullptr;
263 opts.ignoreRowsAndColumns =
nullptr;
264 opts.malloc = malloc;
266 opts.reportError =
nullptr;
268 m_symbolicFactorization.reset(
new SymbolicFactorization(SparseFactor(Solver_, A.structure, opts)));
270 SparseStatus_t status = m_symbolicFactorization->status;
272 updateInfoStatus(status);
274 if (status != SparseStatusOK) m_symbolicFactorization.reset();
277 void doFactorization(AccelSparseMatrix& A) {
278 SparseStatus_t status = SparseStatusReleased;
280 if (m_symbolicFactorization) {
281 m_numericFactorization.reset(
new NumericFactorization(SparseFactor(*m_symbolicFactorization, A)));
283 status = m_numericFactorization->status;
285 if (status != SparseStatusOK) m_numericFactorization.reset();
288 updateInfoStatus(status);
292 void updateInfoStatus(SparseStatus_t status)
const {
297 case SparseFactorizationFailed:
298 case SparseMatrixIsSingular:
301 case SparseInternalError:
302 case SparseParameterError:
303 case SparseStatusReleased:
311 Index m_nRows, m_nCols;
312 std::unique_ptr<SymbolicFactorization, SymbolicFactorizationDeleter> m_symbolicFactorization;
313 std::unique_ptr<NumericFactorization, NumericFactorizationDeleter> m_numericFactorization;
314 SparseKind_t m_sparseKind;
315 SparseTriangle_t m_triType;
316 SparseOrder_t m_order;
320template <
typename MatrixType_,
int UpLo_, SparseFactorization_t Solver_,
bool EnforceSquare_>
321void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::compute(
const MatrixType& a) {
322 EIGEN_IF_CONSTEXPR (EnforceSquare_) eigen_assert(a.rows() == a.cols());
327 AccelSparseMatrix A{};
328 std::vector<long> columnStarts;
330 buildAccelSparseMatrix(a, A, columnStarts);
334 if (m_symbolicFactorization) doFactorization(A);
336 m_isInitialized =
true;
345template <
typename MatrixType_,
int UpLo_, SparseFactorization_t Solver_,
bool EnforceSquare_>
346void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::analyzePattern(
const MatrixType& a) {
347 EIGEN_IF_CONSTEXPR (EnforceSquare_) eigen_assert(a.rows() == a.cols());
352 AccelSparseMatrix A{};
353 std::vector<long> columnStarts;
355 buildAccelSparseMatrix(a, A, columnStarts);
359 m_isInitialized =
true;
369template <
typename MatrixType_,
int UpLo_, SparseFactorization_t Solver_,
bool EnforceSquare_>
370void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::factorize(
const MatrixType& a) {
371 eigen_assert(m_symbolicFactorization &&
"You must first call analyzePattern()");
372 eigen_assert(m_nRows == a.rows() && m_nCols == a.cols());
374 EIGEN_IF_CONSTEXPR (EnforceSquare_) eigen_assert(a.rows() == a.cols());
376 AccelSparseMatrix A{};
377 std::vector<long> columnStarts;
379 buildAccelSparseMatrix(a, A, columnStarts);
384template <
typename MatrixType_,
int UpLo_, SparseFactorization_t Solver_,
bool EnforceSquare_>
385template <
typename Rhs,
typename Dest>
386void AccelerateImpl<MatrixType_, UpLo_, Solver_, EnforceSquare_>::_solve_impl(
const MatrixBase<Rhs>& b,
388 if (!m_numericFactorization) {
393 eigen_assert(m_nRows == b.rows());
394 eigen_assert(((b.cols() == 1) || b.outerStride() == b.rows()));
396 SparseStatus_t status = SparseStatusOK;
398 Scalar* b_ptr =
const_cast<Scalar*
>(b.derived().data());
399 Scalar* x_ptr =
const_cast<Scalar*
>(x.derived().data());
401 AccelDenseMatrix xmat{};
402 xmat.attributes = SparseAttributes_t();
403 xmat.columnCount =
static_cast<int>(x.cols());
404 xmat.rowCount =
static_cast<int>(x.rows());
405 xmat.columnStride = xmat.rowCount;
408 AccelDenseMatrix bmat{};
409 bmat.attributes = SparseAttributes_t();
410 bmat.columnCount =
static_cast<int>(b.cols());
411 bmat.rowCount =
static_cast<int>(b.rows());
412 bmat.columnStride = bmat.rowCount;
415 SparseSolve(*m_numericFactorization, bmat, xmat);
417 updateInfoStatus(status);
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:53
AccelerateImpl< MatrixType, UpLo|Symmetric, SparseFactorizationCholesky, true > AccelerateLLT
A direct Cholesky (LLT) factorization and solver based on Accelerate.
Definition AccelerateSupport.h:28
AccelerateImpl< MatrixType, UpLo|Symmetric, SparseFactorizationLDLTUnpivoted, true > AccelerateLDLTUnpivoted
A direct Cholesky-like LDL^T factorization and solver based on Accelerate with only 1x1 pivots and no...
Definition AccelerateSupport.h:56
AccelerateImpl< MatrixType, UpLo|Symmetric, SparseFactorizationLDLT, true > AccelerateLDLT
The default Cholesky (LDLT) factorization and solver based on Accelerate.
Definition AccelerateSupport.h:42
AccelerateImpl< MatrixType, UpLo|Symmetric, SparseFactorizationLDLTTPP, true > AccelerateLDLTTPP
A direct Cholesky (LDLT) factorization and solver based on Accelerate with full threshold partial piv...
Definition AccelerateSupport.h:85
AccelerateImpl< MatrixType, 0, SparseFactorizationCholeskyAtA, false > AccelerateCholeskyAtA
A QR factorization and solver based on Accelerate without storing Q (equivalent to A^TA = R^T R)
Definition AccelerateSupport.h:111
AccelerateImpl< MatrixType, UpLo|Symmetric, SparseFactorizationLDLTSBK, true > AccelerateLDLTSBK
A direct Cholesky (LDLT) factorization and solver based on Accelerate with Supernode Bunch-Kaufman an...
Definition AccelerateSupport.h:71
AccelerateImpl< MatrixType, 0, SparseFactorizationQR, false > AccelerateQR
A QR factorization and solver based on Accelerate.
Definition AccelerateSupport.h:98
ComputationInfo
Definition Constants.h:455
@ StrictlyLower
Definition Constants.h:224
@ StrictlyUpper
Definition Constants.h:226
@ UnitLower
Definition Constants.h:220
@ Symmetric
Definition Constants.h:230
@ UnitUpper
Definition Constants.h:222
@ Lower
Definition Constants.h:212
@ Upper
Definition Constants.h:214
@ NumericalIssue
Definition Constants.h:459
@ InvalidInput
Definition Constants.h:464
@ Success
Definition Constants.h:457