compressed_col_sparse_matrix_utils.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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: sameeragarwal@google.com (Sameer Agarwal)
  30. #ifndef CERES_INTERNAL_COMPRESSED_COL_SPARSE_MATRIX_UTILS_H_
  31. #define CERES_INTERNAL_COMPRESSED_COL_SPARSE_MATRIX_UTILS_H_
  32. #include <algorithm>
  33. #include <vector>
  34. #include "ceres/block_structure.h"
  35. #include "ceres/internal/disable_warnings.h"
  36. #include "ceres/internal/export.h"
  37. namespace ceres::internal {
  38. // Extract the block sparsity pattern of the scalar compressed columns
  39. // matrix and return it in compressed column form. The compressed
  40. // column form is stored in two vectors block_rows, and block_cols,
  41. // which correspond to the row and column arrays in a compressed
  42. // column sparse matrix.
  43. //
  44. // If c_ij is the block in the matrix A corresponding to row block i
  45. // and column block j, then it is expected that A contains at least
  46. // one non-zero entry corresponding to the top left entry of c_ij,
  47. // as that entry is used to detect the presence of a non-zero c_ij.
  48. CERES_NO_EXPORT void CompressedColumnScalarMatrixToBlockMatrix(
  49. const int* scalar_rows,
  50. const int* scalar_cols,
  51. const std::vector<Block>& row_blocks,
  52. const std::vector<Block>& col_blocks,
  53. std::vector<int>* block_rows,
  54. std::vector<int>* block_cols);
  55. // Given a set of blocks and a permutation of these blocks, compute
  56. // the corresponding "scalar" ordering, where the scalar ordering of
  57. // size sum(blocks).
  58. CERES_NO_EXPORT void BlockOrderingToScalarOrdering(
  59. const std::vector<Block>& blocks,
  60. const std::vector<int>& block_ordering,
  61. std::vector<int>* scalar_ordering);
  62. // Solve the linear system
  63. //
  64. // R * solution = rhs
  65. //
  66. // Where R is an upper triangular compressed column sparse matrix.
  67. template <typename IntegerType>
  68. void SolveUpperTriangularInPlace(IntegerType num_cols,
  69. const IntegerType* rows,
  70. const IntegerType* cols,
  71. const double* values,
  72. double* rhs_and_solution) {
  73. for (IntegerType c = num_cols - 1; c >= 0; --c) {
  74. rhs_and_solution[c] /= values[cols[c + 1] - 1];
  75. for (IntegerType idx = cols[c]; idx < cols[c + 1] - 1; ++idx) {
  76. const IntegerType r = rows[idx];
  77. const double v = values[idx];
  78. rhs_and_solution[r] -= v * rhs_and_solution[c];
  79. }
  80. }
  81. }
  82. // Solve the linear system
  83. //
  84. // R' * solution = rhs
  85. //
  86. // Where R is an upper triangular compressed column sparse matrix.
  87. template <typename IntegerType>
  88. void SolveUpperTriangularTransposeInPlace(IntegerType num_cols,
  89. const IntegerType* rows,
  90. const IntegerType* cols,
  91. const double* values,
  92. double* rhs_and_solution) {
  93. for (IntegerType c = 0; c < num_cols; ++c) {
  94. for (IntegerType idx = cols[c]; idx < cols[c + 1] - 1; ++idx) {
  95. const IntegerType r = rows[idx];
  96. const double v = values[idx];
  97. rhs_and_solution[c] -= v * rhs_and_solution[r];
  98. }
  99. rhs_and_solution[c] = rhs_and_solution[c] / values[cols[c + 1] - 1];
  100. }
  101. }
  102. // Given a upper triangular matrix R in compressed column form, solve
  103. // the linear system,
  104. //
  105. // R'R x = b
  106. //
  107. // Where b is all zeros except for rhs_nonzero_index, where it is
  108. // equal to one.
  109. //
  110. // The function exploits this knowledge to reduce the number of
  111. // floating point operations.
  112. template <typename IntegerType>
  113. void SolveRTRWithSparseRHS(IntegerType num_cols,
  114. const IntegerType* rows,
  115. const IntegerType* cols,
  116. const double* values,
  117. const int rhs_nonzero_index,
  118. double* solution) {
  119. std::fill(solution, solution + num_cols, 0.0);
  120. solution[rhs_nonzero_index] = 1.0 / values[cols[rhs_nonzero_index + 1] - 1];
  121. for (IntegerType c = rhs_nonzero_index + 1; c < num_cols; ++c) {
  122. for (IntegerType idx = cols[c]; idx < cols[c + 1] - 1; ++idx) {
  123. const IntegerType r = rows[idx];
  124. if (r < rhs_nonzero_index) continue;
  125. const double v = values[idx];
  126. solution[c] -= v * solution[r];
  127. }
  128. solution[c] = solution[c] / values[cols[c + 1] - 1];
  129. }
  130. SolveUpperTriangularInPlace(num_cols, rows, cols, values, solution);
  131. }
  132. } // namespace ceres::internal
  133. #include "ceres/internal/reenable_warnings.h"
  134. #endif // CERES_INTERNAL_COMPRESSED_COL_SPARSE_MATRIX_UTILS_H_