Test explicit iterative Schur solves Compare explicit ITERATIVE_SCHUR solutions with dense QR through the existing Schur test helper. Cover regularized and unregularized systems, zero retained blocks, and varying retained block sizes. Use SCHUR_JACOBI, NO_SPARSE, and a residual tolerance of 1e-12. Addresses https://github.com/ceres-solver/ceres-solver/issues/290. Codex used. Change-Id: I3b9efdf5f2d08cc4cff66b6babdabcde822966da
diff --git a/internal/ceres/schur_complement_solver_test.cc b/internal/ceres/schur_complement_solver_test.cc index de00508..db15185 100644 --- a/internal/ceres/schur_complement_solver_test.cc +++ b/internal/ceres/schur_complement_solver_test.cc
@@ -78,12 +78,15 @@ // Gold standard solutions using dense QR factorization. DenseSparseMatrix dense_A(triplet_A); - qr->Solve(&dense_A, b.get(), LinearSolver::PerSolveOptions(), sol.data()); + LinearSolver::Summary summary = qr->Solve( + &dense_A, b.get(), LinearSolver::PerSolveOptions(), sol.data()); + ASSERT_EQ(summary.termination_type, LinearSolverTerminationType::SUCCESS); // Gold standard solution with appended diagonal. LinearSolver::PerSolveOptions per_solve_options; per_solve_options.D = D.get(); - qr->Solve(&dense_A, b.get(), per_solve_options, sol_d.data()); + summary = qr->Solve(&dense_A, b.get(), per_solve_options, sol_d.data()); + ASSERT_EQ(summary.termination_type, LinearSolverTerminationType::SUCCESS); } void ComputeAndCompareSolutions( @@ -104,6 +107,9 @@ options.sparse_linear_algebra_library_type = sparse_linear_algebra_library_type; options.ordering_type = ordering_type; + options.use_explicit_schur_complement = true; + options.preconditioner_type = SCHUR_JACOBI; + options.max_num_iterations = num_cols; ContextImpl context; options.context = &context; DetectStructure(*A->block_structure(), @@ -115,6 +121,7 @@ std::unique_ptr<LinearSolver> solver(LinearSolver::Create(options)); LinearSolver::PerSolveOptions per_solve_options; + per_solve_options.r_tolerance = 1e-12; LinearSolver::Summary summary; if (regularization) { per_solve_options.D = D.get(); @@ -167,6 +174,25 @@ 4, true, DENSE_SCHUR, EIGEN, SUITE_SPARSE, OrderingType::NATURAL); } +TEST_F(SchurComplementSolverTest, ExplicitSchurSmallProblem) { + ComputeAndCompareSolutions( + 2, false, ITERATIVE_SCHUR, EIGEN, NO_SPARSE, OrderingType::NATURAL); + ComputeAndCompareSolutions( + 2, true, ITERATIVE_SCHUR, EIGEN, NO_SPARSE, OrderingType::NATURAL); +} + +TEST_F(SchurComplementSolverTest, ExplicitSchurLargeProblem) { + ComputeAndCompareSolutions( + 3, false, ITERATIVE_SCHUR, EIGEN, NO_SPARSE, OrderingType::NATURAL); + ComputeAndCompareSolutions( + 3, true, ITERATIVE_SCHUR, EIGEN, NO_SPARSE, OrderingType::NATURAL); +} + +TEST_F(SchurComplementSolverTest, ExplicitSchurVaryingFBlockSize) { + ComputeAndCompareSolutions( + 4, true, ITERATIVE_SCHUR, EIGEN, NO_SPARSE, OrderingType::NATURAL); +} + #ifndef CERES_NO_LAPACK TEST_F(SchurComplementSolverTest, DenseSchurWithLAPACKSmallProblem) { ComputeAndCompareSolutions(