accelerate_sparse.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // Ceres Solver - A fast non-linear least squares minimizer
  2. // Copyright 2023 Google Inc. All rights reserved.
  3. // http://ceres-solver.org/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of Google Inc. nor the names of its contributors may be
  14. // used to endorse or promote products derived from this software without
  15. // specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  21. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. // POSSIBILITY OF SUCH DAMAGE.
  28. //
  29. // Author: alexs.mac@gmail.com (Alex Stewart)
  30. #ifndef CERES_INTERNAL_ACCELERATE_SPARSE_H_
  31. #define CERES_INTERNAL_ACCELERATE_SPARSE_H_
  32. // This include must come before any #ifndef check on Ceres compile options.
  33. #include "ceres/internal/config.h"
  34. #ifndef CERES_NO_ACCELERATE_SPARSE
  35. #include <memory>
  36. #include <string>
  37. #include <vector>
  38. #include "Accelerate.h"
  39. #include "ceres/linear_solver.h"
  40. #include "ceres/sparse_cholesky.h"
  41. namespace ceres {
  42. namespace internal {
  43. class CompressedRowSparseMatrix;
  44. class TripletSparseMatrix;
  45. template <typename Scalar>
  46. struct SparseTypesTrait {};
  47. template <>
  48. struct SparseTypesTrait<double> {
  49. using DenseVector = DenseVector_Double;
  50. using SparseMatrix = SparseMatrix_Double;
  51. using SymbolicFactorization = SparseOpaqueSymbolicFactorization;
  52. using NumericFactorization = SparseOpaqueFactorization_Double;
  53. };
  54. template <>
  55. struct SparseTypesTrait<float> {
  56. using DenseVector = DenseVector_Float;
  57. using SparseMatrix = SparseMatrix_Float;
  58. using SymbolicFactorization = SparseOpaqueSymbolicFactorization;
  59. using NumericFactorization = SparseOpaqueFactorization_Float;
  60. };
  61. template <typename Scalar>
  62. class AccelerateSparse {
  63. public:
  64. using DenseVector = typename SparseTypesTrait<Scalar>::DenseVector;
  65. // Use ASSparseMatrix to avoid collision with ceres::internal::SparseMatrix.
  66. using ASSparseMatrix = typename SparseTypesTrait<Scalar>::SparseMatrix;
  67. using SymbolicFactorization =
  68. typename SparseTypesTrait<Scalar>::SymbolicFactorization;
  69. using NumericFactorization =
  70. typename SparseTypesTrait<Scalar>::NumericFactorization;
  71. // Solves a linear system given its symbolic (reference counted within
  72. // NumericFactorization) and numeric factorization.
  73. void Solve(NumericFactorization* numeric_factor,
  74. DenseVector* rhs_and_solution);
  75. // Note: Accelerate's API passes/returns its objects by value, but as the
  76. // objects contain pointers to the underlying data these copies are
  77. // all shallow (in some cases Accelerate also reference counts the
  78. // objects internally).
  79. ASSparseMatrix CreateSparseMatrixTransposeView(CompressedRowSparseMatrix* A);
  80. // Computes a symbolic factorisation of A that can be used in Solve().
  81. SymbolicFactorization AnalyzeCholesky(OrderingType ordering_type,
  82. ASSparseMatrix* A);
  83. // Compute the numeric Cholesky factorization of A, given its
  84. // symbolic factorization.
  85. NumericFactorization Cholesky(ASSparseMatrix* A,
  86. SymbolicFactorization* symbolic_factor);
  87. // Reuse the NumericFactorization from a previous matrix with the same
  88. // symbolic factorization to represent a new numeric factorization.
  89. void Cholesky(ASSparseMatrix* A, NumericFactorization* numeric_factor);
  90. private:
  91. std::vector<long> column_starts_;
  92. std::vector<uint8_t> solve_workspace_;
  93. std::vector<uint8_t> factorization_workspace_;
  94. // Storage for the values of A if Scalar != double (necessitating a copy).
  95. Eigen::Matrix<Scalar, Eigen::Dynamic, 1> values_;
  96. };
  97. // An implementation of SparseCholesky interface using Apple's Accelerate
  98. // framework.
  99. template <typename Scalar>
  100. class AppleAccelerateCholesky final : public SparseCholesky {
  101. public:
  102. // Factory
  103. static std::unique_ptr<SparseCholesky> Create(OrderingType ordering_type);
  104. // SparseCholesky interface.
  105. virtual ~AppleAccelerateCholesky();
  106. CompressedRowSparseMatrix::StorageType StorageType() const;
  107. LinearSolverTerminationType Factorize(CompressedRowSparseMatrix* lhs,
  108. std::string* message) final;
  109. LinearSolverTerminationType Solve(const double* rhs,
  110. double* solution,
  111. std::string* message) final;
  112. private:
  113. AppleAccelerateCholesky(const OrderingType ordering_type);
  114. void FreeSymbolicFactorization();
  115. void FreeNumericFactorization();
  116. const OrderingType ordering_type_;
  117. AccelerateSparse<Scalar> as_;
  118. std::unique_ptr<typename AccelerateSparse<Scalar>::SymbolicFactorization>
  119. symbolic_factor_;
  120. std::unique_ptr<typename AccelerateSparse<Scalar>::NumericFactorization>
  121. numeric_factor_;
  122. // Copy of rhs/solution if Scalar != double (necessitating a copy).
  123. Eigen::Matrix<Scalar, Eigen::Dynamic, 1> scalar_rhs_and_solution_;
  124. };
  125. } // namespace internal
  126. } // namespace ceres
  127. #endif // CERES_NO_ACCELERATE_SPARSE
  128. #endif // CERES_INTERNAL_ACCELERATE_SPARSE_H_