Open Levi-Armstrong opened 1 year ago
Thanks @Levi-Armstrong for reporting the problem. fyi @GiulioRomualdi @S-Dafarra
I believe this line should be updated to the following.
osqpSparseMatrix = csc_spalloc(rows, cols, numberOfNonZeroCoeff, numberOfNonZeroCoeff != 0, 0);
It looks like it may be a bug in 0.6.X
csc* csc_spalloc(c_int m, c_int n, c_int nzmax, c_int values, c_int triplet) {
csc *A = csc_calloc(1, sizeof(csc)); /* allocate the csc struct */
if (!A) return OSQP_NULL; /* out of memory */
A->m = m; /* define dimensions and nzmax */
A->n = n;
A->nzmax = nzmax = c_max(nzmax, 1);
A->nz = triplet ? 0 : -1; /* allocate triplet or comp.col */
A->p = csc_malloc(triplet ? nzmax : n + 1, sizeof(c_int));
A->i = csc_malloc(nzmax, sizeof(c_int));
A->x = values ? csc_malloc(nzmax, sizeof(c_float)) : OSQP_NULL;
if (!A->p || !A->i || (values && !A->x)){
csc_spfree(A);
return OSQP_NULL;
} else return A;
}
Master:
OSQPCscMatrix* csc_spalloc(OSQPInt m,
OSQPInt n,
OSQPInt nzmax,
OSQPInt values,
OSQPInt triplet) {
OSQPCscMatrix* A = c_calloc(1, sizeof(OSQPCscMatrix)); /* allocate the OSQPCscMatrix struct */
if (!A) return OSQP_NULL; /* out of memory */
A->m = m; /* define dimensions and nzmax */
A->n = n;
A->nzmax = nzmax = c_max(nzmax, 0);
A->nz = triplet ? 0 : -1; /* allocate triplet or comp.col */
A->p = csc_malloc(triplet ? nzmax : n + 1, sizeof(OSQPInt));
A->i = values ? csc_malloc(nzmax, sizeof(OSQPInt)) : OSQP_NULL;
A->x = values ? csc_malloc(nzmax, sizeof(OSQPFloat)) : OSQP_NULL;
if (!A->p || (values && !A->i ) || (values && !A->x)){
csc_spfree(A);
return OSQP_NULL;
} else return A;
}
I created this method and used it within osqp_eigen to solve the issue.
static void* csc_malloc(c_int n, c_int size) {
return c_malloc(n * size); // NOLINT
}
static void* csc_calloc(c_int n, c_int size) {
return c_calloc(n, size); // NOLINT
}
csc* csc_spalloc_fix(c_int m, c_int n, c_int nzmax, c_int values, c_int triplet) {
csc *A = (csc*)(csc_calloc(1, sizeof(csc))); /* allocate the csc struct */ // NOLINT
if (!A) return OSQP_NULL; /* out of memory */ // NOLINT
A->m = m; /* define dimensions and nzmax */
A->n = n;
A->nzmax = nzmax = c_max(nzmax, 0);
A->nz = triplet ? 0 : -1; /* allocate triplet or comp.col */ // NOLINT
A->p = (c_int*)(csc_malloc(triplet ? nzmax : n + 1, sizeof(c_int))); // NOLINT
A->i = values ? (c_int*)(csc_malloc(nzmax, sizeof(c_int))) : OSQP_NULL; // NOLINT
A->x = values ? (c_float*)(csc_malloc(nzmax, sizeof(c_float))) : OSQP_NULL; // NOLINT
if (!A->p || (values && !A->i) || (values && !A->x)){ // NOLINT
csc_spfree(A);
return OSQP_NULL;
} else return A; // NOLINT
}
Then updated the call below.
osqpSparseMatrix = csc_spalloc_fix(rows, cols, numberOfNonZeroCoeff, 1, 0);
When setting the hessian which has zero nonZero entries it creates an osqp hessian with one value initialized to garbage.
Current:
Expected: