Dear all,
I am starting to look at Ceres and really like it so far.
One issue I am facing right now is that I am interested in using its linear solvers for a matrix-free least-squares problem but the API is a non-exposed internal one.
I have read this thread:
I understand that "Ceres is not structured as a general purpose nonlinear and linear algebra library" and that "Eigen and pretty much any other linear algebra library has a perfectly capable CG implementation."
However, three reasons would make the use of the CG in ceres useful to me:
- I am planning to already use Ceres for non-linear least squares
- There are not so many nice c++ implementation of matrix-free CG out there
- Ceres and Eigen (http://eigen.tuxfamily.org/dox/group__MatrixfreeSolverExample.html) can do it but the Ceres API is simpler and sufficient for my needs. Also, I haven't tried the Eigen matrix-free CG but I don't quite get how they get away without asking for the adjoint operator
For the record, provided I copy the internal header files from Ceres in my source tree the toy example below currently work for me and looks quite nice.
#include "ceres/ceres.h"
#include "glog/logging.h"
#include "ceres/conjugate_gradients_solver.h"
struct MyLinearOperator : public ceres::internal::LinearOperator {
virtual ~MyLinearOperator() {
};
// y = y + Ax;
virtual void RightMultiply(const double* x, double* y) const {
y[0] += x[0] + 0.1*x[1];
y[1] += 2.0*x[1];
};
// y = y + A'x;
virtual void LeftMultiply(const double* x, double* y) const{
y[0] += x[0];
y[1] += 0.1*x[0] + 2.0*x[1];
};
virtual int num_rows() const{
return 2;
};
virtual int num_cols() const{
return 2;
};
};
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
ceres::internal::LinearSolver::Options options;
options.type = ceres::CGNR;
options.preconditioner_type = ceres::IDENTITY;
options.max_num_iterations = 10;
ceres::internal::LinearSolver::PerSolveOptions per_solve_options;
per_solve_options.r_tolerance = 1e-9;
MyLinearOperator myoperator;
ceres::internal::ConjugateGradientsSolver solver(options);
double b[] = { 5.0, 4.0 };
double x[] = { -1.0, 0.0 };
ceres::internal::LinearSolver::Summary summary =
solver.Solve(&myoperator, b, per_solve_options, x);
std::cout << summary.message << "\n";
std::cout << "x : [0; 0] -> [" << x[0] << "; " << x[1] << "]\n";
return 0;
}
Are there any plans to expose the linear solvers? This would avoid having to copy a bunch of internal header files, and would ease keeping track with updates from Ceres.
As a side question, as I am fairly new to this field, are there any obvious open-source library besides Eigen that I should look into for matrix-free solvers in c++?
Best wishes,