oxfordcontrol / Clarabel.cpp

Clarabel.cpp: C/C++ interface to the Clarabel Interior-point solver for convex conic optimisation problems.
Apache License 2.0
32 stars 10 forks source link

Unable to update P and A with different sparsity structures and must disable presolve to do partial update #37

Closed min-dai closed 2 months ago

min-dai commented 2 months ago

Hello,

I'm running Clarabel with c++. I found that I cannot update P and A matrices with different sparsity structures using the functions that claim to do a full rewrite. Any suggestions on this?

inline void DefaultSolver<double>::update_P(const Eigen::SparseMatrix<double, Eigen::ColMajor> &P){
    ConvertedCscMatrix matrix_P = DefaultSolver<double>::eigen_sparse_to_clarabel(P);
    CscMatrix<double> mat(matrix_P.m, matrix_P.n, matrix_P.colptr.data(), matrix_P.rowval.data(), matrix_P.nzval);
     clarabel_DefaultSolver_f64_update_P_csc(this->handle,&mat);
}
// DefaultSolver::update_P (full rewrite of sparse matrix data using CSC formatted source)
ClarabelDefaultInfo_f64 clarabel_DefaultSolver_f64_update_P_csc(ClarabelDefaultSolver_f64 *solver, const ClarabelCscMatrix_f64 *P);

Also, I have to disable presolve to avoid the following error when updating without changing the sparsity structure. It seems like this might be standard as data_updating.cpp used the same setting, but it felt concerning.

thread '<unnamed>' panicked at src/solver/implementations/default/data_updating.rs:35:54:
called `Result::unwrap()` on an `Err` value: PresolveEnabled
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5
goulart-paul commented 2 months ago

Yes, the 'full rewrite' versions still expect that "P" and "A" maintain their same sparsity structure. The function is just letting you update the entries of those matrices in one shot.

The reason for this restriction is that if you update the values only, but don't change the sparsity structure, then the solver doesn't need to reallocate memory for its internal matrix factorisation because its sparsity pattern likewise won't change. If you do change the sparsity pattern of your data then internal reallocations would be required. At that point you might as well just make a new solver object.

It's also correct that you can't update the problem data with presolve or chordal decomposition enabled. The reason is that changing the entries of the problem data could invalidate the presolve steps we applied. For example, an infinite bound in a constraint causes the solver to eliminate that constraint before solving. If you then change that bound to a finite one, we can't restore it internally without reallocating.

I agree that that could be better documented though and should fail more gracefully.