22    ladel_int col, index, nnz_kkt, nnz_schur, n = work->
data->
n, m = work->
data->
m;
 
   25    nnz_kkt = Q->nzmax + n + A->nzmax + m;
 
   27    for (col = 1; col <= n; col++)
 
   30      if (index >= 0 && Q->i[index] == col-1) nnz_kkt--;
 
   34    nnz_schur = nnz_kkt - A->nzmax - m; 
 
   38    c->array_int_ncol1 = work->
index_L; 
 
   40    c->array_int_ncol1 = NULL;
 
   42    ladel_int Atnz_col, Atnz_col_max = 0;
 
   43    for (col = 0; col < m; col++) Atnz_col_max = 
c_max(At->p[col+1] - At->p[col], Atnz_col_max);
 
   44    for (col = 0; col < m; col++)
 
   46      Atnz_col = At->p[col+1] - At->p[col];
 
   47      if (Atnz_col + Atnz_col_max <= n)
 
   48        nnz_schur += (Atnz_col*(Atnz_col-1))/2;
 
   50          nnz_schur += (Atnz_col*(n - Atnz_col_max) - ((n - Atnz_col_max)*(n - Atnz_col_max + 1)) / 2);
 
   52    if (2 * Atnz_col_max > n) nnz_schur += (Atnz_col_max*(Atnz_col_max - 1)) / 2 - (Atnz_col_max*(n - Atnz_col_max) - ((n - Atnz_col_max)*(n - Atnz_col_max + 1)) / 2);
 
   53    nnz_schur = 
c_max(
c_min(nnz_schur, (n*(n-1))/2), 1);
 
   56    At = ladel_sparse_free(At);
 
   59    if ((nnz_kkt*nnz_kkt)/(nnz_schur*nnz_schur)*n/(n+m) < 2) 
 
   76    ladel_int n = A->ncol;
 
   78      if (A->symmetry == UNSYMMETRIC)
 
   79        ladel_matvec(A, x, y, 
TRUE);
 
   81        ladel_symmetric_matvec(A, x, y, 
TRUE);
 
   83      ladel_double* x2 = ladel_malloc(n, 
sizeof(
c_float));
 
   84      ladel_double_vector_copy(x, n, x2);
 
   85      if (A->symmetry == UNSYMMETRIC)
 
   86        ladel_matvec(A, x2, y, 
TRUE);
 
   88        ladel_symmetric_matvec(A, x2, y, 
TRUE);
 
   96    ladel_int m = A->nrow;
 
   98      if (A->symmetry == UNSYMMETRIC)
 
   99        ladel_tpose_matvec(A, x, y, 
TRUE);
 
  101        ladel_symmetric_matvec(A, x, y, 
TRUE);  
 
  103      ladel_double* x2 = ladel_malloc(m, 
sizeof(
c_float));
 
  104      ladel_double_vector_copy(x, m, x2);
 
  105      if (A->symmetry == UNSYMMETRIC)
 
  106        ladel_tpose_matvec(A, x2, y, 
TRUE);
 
  108        ladel_symmetric_matvec(A, x2, y, 
TRUE); 
 
  117    ladel_int col, index, index_kkt, n = work->
data->
n, m = work->
data->
m, Qnz = Q->nzmax;
 
  121    for (col = 0; col < n; col++)
 
  123        kkt->p[col] = kkt_full->p[col] = Q->p[col];
 
  124        kkt->nz[col] = Q->p[col+1] - Q->p[col];
 
  126    kkt->p[col] = kkt_full->p[col] = Q->p[col];
 
  127    for (index = 0; index < Qnz; index++)
 
  129        kkt->i[index] = kkt_full->i[index] = Q->i[index];
 
  130        kkt->x[index] = kkt_full->x[index] = Q->x[index];
 
  135    for (; col < m+n; col++)
 
  137        kkt_full->i[index_kkt] = first_row_A[col-n] = At->i[At->p[col-n]];
 
  138        kkt_full->x[index_kkt] = first_elem_A[col-n] = At->x[At->p[col-n]];
 
  142            kkt->nz[col] = At->p[col-n+1] - At->p[col-n] + 1;
 
  143            kkt->i[index_kkt] = At->i[At->p[col-n]];
 
  144            kkt->x[index_kkt] = At->x[At->p[col-n]];
 
  149            kkt->i[index_kkt] = col;
 
  150            kkt->x[index_kkt] = 1;
 
  153        if (At->p[col-n+1]-At->p[col-n] != 0) index_kkt++;
 
  155        for (index = At->p[col-n]+1; index < At->p[col-n+1]; index++)
 
  157            kkt->i[index_kkt] = kkt_full->i[index_kkt] = At->i[index];
 
  158            kkt->x[index_kkt] = kkt_full->x[index_kkt] = At->x[index];
 
  162        kkt->i[index_kkt] = kkt_full->i[index_kkt] = col;
 
  163        kkt->x[index_kkt] = kkt_full->x[index_kkt] = -sigma_inv[col-n];
 
  164        if (At->p[col-n+1]-At->p[col-n] == 0) kkt->x[index_kkt] = 1;
 
  167        kkt->p[col+1] = kkt_full->p[col+1] = Qnz + At->p[col+1-n] + 1 + col - n;
 
  175    ladel_int col, n = work->
data->
n, m = work->
data->
m;
 
  179    for (col = n; col < n+m; col++)
 
  183            kkt->nz[col] = At->p[col-n+1] - At->p[col-n] + 1;
 
  184            kkt->i[kkt->p[col]] = first_row_A[col-n];
 
  185            kkt->x[kkt->p[col]] = first_elem_A[col-n];
 
  186            kkt->x[kkt->p[col+1]-1] = -sigma_inv[col-n]; 
 
  187            kkt->i[kkt->p[col+1]-1] = col;
 
  191            kkt->i[kkt->p[col]] = col;
 
  192            kkt->x[kkt->p[col]] = 1; 
 
  200    ladel_int col, index, n = work->
data->
n;
 
  207        kkt->nz[col] = At->p[col-n+1] - At->p[col-n] + 1;
 
  208        kkt->i[kkt->p[col]] = first_row_A[col-n];
 
  209        kkt->x[kkt->p[col]] = first_elem_A[col-n];
 
  210        kkt->x[kkt->p[col+1]-1] = -sigma_inv[col-n]; 
 
  211        ladel_row_add(work->
solver->
LD, work->
solver->
sym, col, kkt, col, -sigma_inv[col-n], c);
 
  217    ladel_int col, index, n = work->
data->
n;
 
  218    ladel_double *sigma_inv = work->
sigma_inv;
 
  228        kkt->i[kkt->p[col]] = col;
 
  229        kkt->x[kkt->p[col]] = -sigma_inv[col-n];
 
  248  d.diag_elem = 1.0/work->
gamma;
 
  250  else d.diag_size = 0;
 
  258    QAtA = ladel_add_matrices_pattern(work->
data->
Q, AtA, c);
 
  259    QAtA->symmetry = UPPER;
 
  262    ladel_factorize_advanced_with_diag(M, d, work->
solver->
sym, NO_ORDERING, &work->
solver->
LD, QAtA, c);
 
  264    ladel_sparse_free(AtA);
 
  265    ladel_sparse_free(QAtA);
 
  270    ladel_factorize_with_prior_basis_with_diag(M, d, work->
solver->
sym, work->
solver->
LD, c);
 
  277  size_t nb_active = 0;
 
  278  for (
size_t i = 0; i < work->
data->
m; i++) {
 
  286  AtsigmaA = ladel_mat_mat_transpose(At_sqrt_sigma, A_sqrt_sigma, c);
 
  287  QAtsigmaA = ladel_add_matrices(1.0, work->
data->
Q, 1.0, AtsigmaA, c);
 
  288  QAtsigmaA->symmetry = UPPER;
 
  291  AtsigmaA = ladel_sparse_free(AtsigmaA);
 
  292  QAtsigmaA = ladel_sparse_free(QAtsigmaA);
 
  293  At_sqrt_sigma = ladel_sparse_free(At_sqrt_sigma);
 
  294  A_sqrt_sigma = ladel_sparse_free(A_sqrt_sigma);
 
  322  for (k = 0; k < nb_sigma_changed; k++) {
 
  323    row = sigma_changed[k];
 
  324    At_scalex[row] = At_scalex[row]*At_scalex[row];
 
  326      At_scalex[row] = 
c_sqrt(1-1/At_scalex[row]); 
 
  331    ladel_sparse_matrix *W = ladel_sparse_alloc(work->
data->
n + work->
data->
m, 1, 1, UNSYMMETRIC, 
TRUE, 
FALSE);
 
  337    for (k = 0; k < nb_sigma_changed; k++)
 
  339      row = sigma_changed[k];
 
  342      factor = work->
sigma_inv[row]*(At_scalex[row] - 1.0);
 
  344      ladel_rank1_update(work->
solver->
LD, work->
solver->
sym, W, 0, factor, UPDATE, c);
 
  346    ladel_sparse_free(W);
 
  350    for (k = 0; k < nb_sigma_changed; k++)
 
  353                          sigma_changed[k], At_scalex[sigma_changed[k]], UPDATE, c);
 
#define FACTORIZE_SCHUR
factorize the Schur complement
 
#define FACTORIZE_KKT_OR_SCHUR
select automatically between kkt system and schur complement
 
#define FACTORIZE_KKT
factorize the kkt system
 
#define c_sqrt
square root
 
ladel_int c_int
type for integer numbers
 
ladel_double c_float
type for floating point numbers
 
#define c_max(a, b)
maximum of two values
 
#define c_min(a, b)
minimum of two values
 
void vec_set_scalar(c_float *a, c_float sc, size_t n)
Fill float vector with a scalar value.
 
void vec_self_mult_scalar(c_float *a, c_float sc, size_t n)
Mulitply vector with a constant scale factor.
 
void prea_vec_copy(const c_float *a, c_float *b, size_t n)
Copy vector a into preallocated vector b.
 
Linear algebra with vectors.
 
void ldlsolveLD_neg_dphi(QPALMWorkspace *work, solver_common *c)
Solve the linear system .
 
void kkt_update_leaving_constraints(QPALMWorkspace *work, solver_common *c)
Perform a factorization update for the leaving constraints.
 
void qpalm_form_kkt(QPALMWorkspace *work)
Form the KKT system .
 
void mat_vec(solver_sparse *A, solver_dense *x, solver_dense *y, solver_common *c)
Matrix-vector multiplication.
 
void qpalm_set_factorization_method(QPALMWorkspace *work, solver_common *c)
Choose the linear systems solver method based on the problem data sizes.
 
void ldldowndate_leaving_constraints(QPALMWorkspace *work, solver_common *c)
Downdate the  factorization given a set of leaving constraints.
 
void ldlupdate_sigma_changed(QPALMWorkspace *work, solver_common *c)
Update the  factorization given a set of indexes where  has been updated.
 
void kkt_update_entering_constraints(QPALMWorkspace *work, solver_common *c)
Perform a factorization update for the entering constraints.
 
void ldlcholQAtsigmaA(QPALMWorkspace *work, solver_common *c)
Calculate  factorization of , with  and  the set of active constraints.
 
void mat_tpose_vec(solver_sparse *A, solver_dense *x, solver_dense *y, solver_common *c)
Matrix-transpose-vector multiplication.
 
void ldlchol(solver_sparse *M, QPALMWorkspace *work, solver_common *c)
Calculate  factorization of a matrix .
 
void kkt_solve(QPALMWorkspace *work, solver_common *c)
Solve the KKT system .
 
void qpalm_reform_kkt(QPALMWorkspace *work)
Reform the KKT system (i.e.
 
void ldlupdate_entering_constraints(QPALMWorkspace *work, solver_common *c)
Update the  factorization given a set of entering constraints.
 
Interface and wrapper to matrix/factorization (ladel) functions.
 
size_t m
number of constraints m
 
size_t n
number of variables n
 
solver_sparse * A
sparse linear constraints matrix A (size m x n)
 
solver_sparse * Q
sparse quadratic part of the cost Q (size n x n)
 
c_int proximal
boolean, use proximal method of multipliers or not
 
c_int factorization_method
factorize KKT or Schur complement
 
solver_sparse * At_sqrt_sigma
A' * sqrt(sigma)
 
c_int * first_row_A
row index of the first element in each column of A'
 
c_int * active_constraints
index set of active constraints
 
c_int reset_newton
boolean, after sigma is updated perform a new factorization
 
c_int * leave
index set of leaving constraints
 
solver_dense * rhs_kkt
[-dphi; zeros(m,1)]
 
solver_factor * LD
LD factor (part of LDL' factorization)
 
c_int factorization_method
factorize KKT or Schur complement
 
c_int * enter
index set of entering constraints
 
c_int first_factorization
boolean, indicate we have not factorized previously
 
solver_dense * At_scale
running vector of sqrt(sigma), used to scale At_sqrt_sigma
 
solver_dense * sol_kkt
sol_kkt = kkt \ rhs_kkt
 
c_float * first_elem_A
value of the first element in each column of A'
 
c_int nb_leave
number of leaving constraints
 
solver_symbolics * sym
symbolics for kkt (only used in LADEL)
 
solver_sparse * kkt_full
KKT matrix if all constraints would be active.
 
solver_sparse * kkt
KKT matrix.
 
c_int nb_enter
number of entering constraints
 
c_int nb_sigma_changed
number of sigma-components that changed in an outer iteration (relevant for factorization update)
 
c_float * neg_dphi
-dphi, required as the rhs in SCHUR
 
QPALMSettings * settings
problem settings
 
c_float * sigma_inv
1./sigma
 
c_float gamma
proximal penalty factor
 
c_float * dphi
gradient of the Lagrangian
 
QPALMSolver * solver
linsys variables
 
QPALMData * data
problem data to work on (possibly scaled)
 
c_int * index_L
index set L (where s>0)
 
c_float * d
primal update step
 
ladel_double solver_dense
 
ladel_sparse_matrix solver_sparse