Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The createOsqpSparseMatrix does not correctly handle empty sparse matrix. #142

Open
Levi-Armstrong opened this issue Jul 31, 2023 · 5 comments

Comments

@Levi-Armstrong
Copy link

When setting the hessian which has zero nonZero entries it creates an osqp hessian with one value initialized to garbage.

Current:

OSQP Hessian:
     nzmax:1
         m:19
         n:19
         p:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
         i:93825007825568
         x:4.64e-310

Expected:

OSQP Hessian:
     nzmax:0
         m:19
         n:19
         p:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
         i:
         x:
@traversaro
Copy link
Member

Thanks @Levi-Armstrong for reporting the problem. fyi @GiulioRomualdi @S-Dafarra

@Levi-Armstrong
Copy link
Author

I believe this line should be updated to the following.

osqpSparseMatrix = csc_spalloc(rows, cols, numberOfNonZeroCoeff, numberOfNonZeroCoeff != 0, 0);

@Levi-Armstrong
Copy link
Author

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;
}

@Levi-Armstrong
Copy link
Author

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
}

@Levi-Armstrong
Copy link
Author

Levi-Armstrong commented Jul 31, 2023

Then updated the call below.

osqpSparseMatrix = csc_spalloc_fix(rows, cols, numberOfNonZeroCoeff, 1, 0);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants