scs 0.3.2 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +10 -0
 - data/LICENSE.txt +1 -1
 - data/README.md +35 -6
 - data/lib/scs/matrix.rb +72 -0
 - data/lib/scs/solver.rb +19 -26
 - data/lib/scs/version.rb +1 -1
 - data/lib/scs.rb +1 -0
 - data/vendor/scs/CITATION.cff +2 -2
 - data/vendor/scs/CMakeLists.txt +285 -169
 - data/vendor/scs/Makefile +43 -18
 - data/vendor/scs/README.md +3 -1
 - data/vendor/scs/include/cones.h +5 -3
 - data/vendor/scs/include/glbopts.h +35 -17
 - data/vendor/scs/include/linsys.h +8 -8
 - data/vendor/scs/include/normalize.h +1 -0
 - data/vendor/scs/include/rw.h +3 -3
 - data/vendor/scs/include/scs.h +51 -24
 - data/vendor/scs/include/scs_types.h +3 -1
 - data/vendor/scs/include/scs_work.h +13 -15
 - data/vendor/scs/include/util.h +4 -2
 - data/vendor/scs/linsys/cpu/direct/private.c +32 -153
 - data/vendor/scs/linsys/cpu/direct/private.h +6 -6
 - data/vendor/scs/linsys/cpu/indirect/private.c +9 -22
 - data/vendor/scs/linsys/cpu/indirect/private.h +4 -2
 - data/vendor/scs/linsys/csparse.c +140 -12
 - data/vendor/scs/linsys/csparse.h +10 -17
 - data/vendor/scs/linsys/external/amd/LICENSE.txt +0 -897
 - data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +4 -2
 - data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +0 -5
 - data/vendor/scs/linsys/gpu/gpu.c +4 -4
 - data/vendor/scs/linsys/gpu/gpu.h +1 -1
 - data/vendor/scs/linsys/gpu/indirect/private.c +15 -26
 - data/vendor/scs/linsys/mkl/direct/private.c +182 -0
 - data/vendor/scs/linsys/mkl/direct/private.h +38 -0
 - data/vendor/scs/linsys/scs_matrix.c +49 -72
 - data/vendor/scs/linsys/scs_matrix.h +4 -3
 - data/vendor/scs/scs.mk +39 -30
 - data/vendor/scs/src/aa.c +0 -4
 - data/vendor/scs/src/cones.c +78 -184
 - data/vendor/scs/src/exp_cone.c +399 -0
 - data/vendor/scs/src/normalize.c +51 -0
 - data/vendor/scs/src/rw.c +139 -76
 - data/vendor/scs/src/scs.c +275 -202
 - data/vendor/scs/src/util.c +36 -13
 - data/vendor/scs/test/minunit.h +2 -1
 - data/vendor/scs/test/problem_utils.h +5 -4
 - data/vendor/scs/test/problems/degenerate.h +1 -0
 - data/vendor/scs/test/problems/hs21_tiny_qp.h +2 -1
 - data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +13 -4
 - data/vendor/scs/test/problems/infeasible_tiny_qp.h +1 -0
 - data/vendor/scs/test/problems/max_ent +0 -0
 - data/vendor/scs/test/problems/max_ent.h +8 -0
 - data/vendor/scs/test/problems/qafiro_tiny_qp.h +2 -1
 - data/vendor/scs/test/problems/random_prob.h +2 -39
 - data/vendor/scs/test/problems/rob_gauss_cov_est.h +15 -3
 - data/vendor/scs/test/problems/small_lp.h +4 -1
 - data/vendor/scs/test/problems/small_qp.h +42 -7
 - data/vendor/scs/test/problems/test_exp_cone.h +84 -0
 - data/vendor/scs/test/problems/test_prob_from_data_file.h +57 -0
 - data/vendor/scs/test/problems/test_validation.h +4 -1
 - data/vendor/scs/test/problems/unbounded_tiny_qp.h +3 -3
 - data/vendor/scs/test/random_socp_prob.c +3 -1
 - data/vendor/scs/test/run_from_file.c +22 -4
 - data/vendor/scs/test/run_tests.c +22 -9
 - metadata +12 -4
 
| 
         @@ -50,7 +50,9 @@ 
     | 
|
| 
       50 
50 
     | 
    
         | 
| 
       51 
51 
     | 
    
         
             
            struct SuiteSparse_config_struct SuiteSparse_config =
         
     | 
| 
       52 
52 
     | 
    
         
             
            {
         
     | 
| 
       53 
     | 
    
         
            -
                scs_malloc, scs_calloc, scs_realloc, scs_free, 
     | 
| 
      
 53 
     | 
    
         
            +
                scs_malloc, scs_calloc, scs_realloc, scs_free,
         
     | 
| 
      
 54 
     | 
    
         
            +
                /* Disable printing */
         
     | 
| 
      
 55 
     | 
    
         
            +
                SCS_NULL,
         
     | 
| 
       54 
56 
     | 
    
         
             
                SuiteSparse_hypot,
         
     | 
| 
       55 
57 
     | 
    
         
             
                SuiteSparse_divcomplex
         
     | 
| 
       56 
58 
     | 
    
         | 
| 
         @@ -79,7 +81,7 @@ void SuiteSparse_start ( void ) 
     | 
|
| 
       79 
81 
     | 
    
         
             
                SuiteSparse_config.calloc_func  = scs_calloc ;
         
     | 
| 
       80 
82 
     | 
    
         
             
                SuiteSparse_config.realloc_func = scs_realloc ;
         
     | 
| 
       81 
83 
     | 
    
         
             
                SuiteSparse_config.free_func    = scs_free ;
         
     | 
| 
       82 
     | 
    
         
            -
                SuiteSparse_config.printf_func  =  
     | 
| 
      
 84 
     | 
    
         
            +
                SuiteSparse_config.printf_func  = SCS_NULL;
         
     | 
| 
       83 
85 
     | 
    
         
             
                /* math functions */
         
     | 
| 
       84 
86 
     | 
    
         
             
                SuiteSparse_config.hypot_func = SuiteSparse_hypot ;
         
     | 
| 
       85 
87 
     | 
    
         
             
                SuiteSparse_config.divcomplex_func = SuiteSparse_divcomplex ;
         
     | 
| 
         @@ -71,11 +71,6 @@ extern "C" { 
     | 
|
| 
       71 
71 
     | 
    
         
             
            #define SuiteSparse_long_id "%" SuiteSparse_long_idd
         
     | 
| 
       72 
72 
     | 
    
         
             
            #endif
         
     | 
| 
       73 
73 
     | 
    
         | 
| 
       74 
     | 
    
         
            -
            #ifndef _scs_printf
         
     | 
| 
       75 
     | 
    
         
            -
            #define _scs_printf scs_printf
         
     | 
| 
       76 
     | 
    
         
            -
            #endif
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
74 
     | 
    
         
             
            /* ========================================================================== */
         
     | 
| 
       80 
75 
     | 
    
         
             
            /* === SuiteSparse_config parameters and functions ========================== */
         
     | 
| 
       81 
76 
     | 
    
         
             
            /* ========================================================================== */
         
     | 
    
        data/vendor/scs/linsys/gpu/gpu.c
    CHANGED
    
    | 
         @@ -19,13 +19,13 @@ void SCS(accum_by_atrans_gpu)(const ScsGpuMatrix *Ag, 
     | 
|
| 
       19 
19 
     | 
    
         
             
                if (*buffer != SCS_NULL) {
         
     | 
| 
       20 
20 
     | 
    
         
             
                  cudaFree(*buffer);
         
     | 
| 
       21 
21 
     | 
    
         
             
                }
         
     | 
| 
       22 
     | 
    
         
            -
                cudaMalloc(buffer,  
     | 
| 
      
 22 
     | 
    
         
            +
                cudaMalloc(buffer, new_buffer_size);
         
     | 
| 
       23 
23 
     | 
    
         
             
                *buffer_size = new_buffer_size;
         
     | 
| 
       24 
24 
     | 
    
         
             
              }
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
              CUSPARSE_GEN(SpMV)
         
     | 
| 
       27 
27 
     | 
    
         
             
              (cusparse_handle, CUSPARSE_OPERATION_NON_TRANSPOSE, &onef, Ag->descr, x,
         
     | 
| 
       28 
     | 
    
         
            -
               &onef, y, SCS_CUDA_FLOAT, SCS_CSRMV_ALG, buffer);
         
     | 
| 
      
 28 
     | 
    
         
            +
               &onef, y, SCS_CUDA_FLOAT, SCS_CSRMV_ALG, *buffer);
         
     | 
| 
       29 
29 
     | 
    
         
             
            }
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
            /* this is slow, use trans routine if possible */
         
     | 
| 
         @@ -48,13 +48,13 @@ void SCS(accum_by_a_gpu)(const ScsGpuMatrix *Ag, const cusparseDnVecDescr_t x, 
     | 
|
| 
       48 
48 
     | 
    
         
             
                if (*buffer != SCS_NULL) {
         
     | 
| 
       49 
49 
     | 
    
         
             
                  cudaFree(*buffer);
         
     | 
| 
       50 
50 
     | 
    
         
             
                }
         
     | 
| 
       51 
     | 
    
         
            -
                cudaMalloc(buffer,  
     | 
| 
      
 51 
     | 
    
         
            +
                cudaMalloc(buffer, new_buffer_size);
         
     | 
| 
       52 
52 
     | 
    
         
             
                *buffer_size = new_buffer_size;
         
     | 
| 
       53 
53 
     | 
    
         
             
              }
         
     | 
| 
       54 
54 
     | 
    
         | 
| 
       55 
55 
     | 
    
         
             
              CUSPARSE_GEN(SpMV)
         
     | 
| 
       56 
56 
     | 
    
         
             
              (cusparse_handle, CUSPARSE_OPERATION_TRANSPOSE, &onef, Ag->descr, x, &onef, y,
         
     | 
| 
       57 
     | 
    
         
            -
               SCS_CUDA_FLOAT, SCS_CSRMV_ALG, buffer);
         
     | 
| 
      
 57 
     | 
    
         
            +
               SCS_CUDA_FLOAT, SCS_CSRMV_ALG, *buffer);
         
     | 
| 
       58 
58 
     | 
    
         
             
            }
         
     | 
| 
       59 
59 
     | 
    
         | 
| 
       60 
60 
     | 
    
         
             
            /* This assumes that P has been made full (ie not triangular) and uses the
         
     | 
    
        data/vendor/scs/linsys/gpu/gpu.h
    CHANGED
    
    
| 
         @@ -21,20 +21,10 @@ static scs_float cg_gpu_norm(cublasHandle_t cublas_handle, scs_float *r, 
     | 
|
| 
       21 
21 
     | 
    
         
             
              return nrm;
         
     | 
| 
       22 
22 
     | 
    
         
             
            }
         
     | 
| 
       23 
23 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
            const char * 
     | 
| 
      
 24 
     | 
    
         
            +
            const char *scs_get_lin_sys_method() {
         
     | 
| 
       25 
25 
     | 
    
         
             
              return "sparse-indirect GPU";
         
     | 
| 
       26 
26 
     | 
    
         
             
            }
         
     | 
| 
       27 
27 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
            /*
         
     | 
| 
       29 
     | 
    
         
            -
            char *SCS(get_lin_sys_summary)(ScsLinSysWork *p, const ScsInfo *info) {
         
     | 
| 
       30 
     | 
    
         
            -
              char *str = (char *)scs_malloc(sizeof(char) * 128);
         
     | 
| 
       31 
     | 
    
         
            -
              sprintf(str, "lin-sys: avg cg its: %2.2f\n",
         
     | 
| 
       32 
     | 
    
         
            -
                      (scs_float)p->tot_cg_its / (info->iter + 1));
         
     | 
| 
       33 
     | 
    
         
            -
              p->tot_cg_its = 0;
         
     | 
| 
       34 
     | 
    
         
            -
              return str;
         
     | 
| 
       35 
     | 
    
         
            -
            }
         
     | 
| 
       36 
     | 
    
         
            -
            */
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
28 
     | 
    
         
             
            /* Not possible to do this on the fly due to M_ii += a_i' (R_y)^-1 a_i */
         
     | 
| 
       39 
29 
     | 
    
         
             
            /* set M = inv ( diag ( R_x + P + A' R_y^{-1} A ) ) */
         
     | 
| 
       40 
30 
     | 
    
         
             
            static void set_preconditioner(ScsLinSysWork *p, const scs_float *diag_r) {
         
     | 
| 
         @@ -76,7 +66,7 @@ static void set_preconditioner(ScsLinSysWork *p, const scs_float *diag_r) { 
     | 
|
| 
       76 
66 
     | 
    
         
             
            }
         
     | 
| 
       77 
67 
     | 
    
         | 
| 
       78 
68 
     | 
    
         
             
            /* no need to update anything in this case */
         
     | 
| 
       79 
     | 
    
         
            -
            void  
     | 
| 
      
 69 
     | 
    
         
            +
            void scs_update_lin_sys_diag_r(ScsLinSysWork *p, const scs_float *diag_r) {
         
     | 
| 
       80 
70 
     | 
    
         
             
              scs_int i;
         
     | 
| 
       81 
71 
     | 
    
         | 
| 
       82 
72 
     | 
    
         
             
              /* R_x to gpu */
         
     | 
| 
         @@ -93,7 +83,7 @@ void SCS(update_lin_sys_diag_r)(ScsLinSysWork *p, const scs_float *diag_r) { 
     | 
|
| 
       93 
83 
     | 
    
         
             
              set_preconditioner(p, diag_r);
         
     | 
| 
       94 
84 
     | 
    
         
             
            }
         
     | 
| 
       95 
85 
     | 
    
         | 
| 
       96 
     | 
    
         
            -
            void  
     | 
| 
      
 86 
     | 
    
         
            +
            void scs_free_lin_sys_work(ScsLinSysWork *p) {
         
     | 
| 
       97 
87 
     | 
    
         
             
              if (p) {
         
     | 
| 
       98 
88 
     | 
    
         
             
                scs_free(p->M);
         
     | 
| 
       99 
89 
     | 
    
         
             
                scs_free(p->inv_r_y);
         
     | 
| 
         @@ -182,13 +172,13 @@ static void mat_vec(ScsLinSysWork *p, const scs_float *x, scs_float *y) { 
     | 
|
| 
       182 
172 
     | 
    
         
             
            }
         
     | 
| 
       183 
173 
     | 
    
         | 
| 
       184 
174 
     | 
    
         
             
            /* P comes in upper triangular, expand to full
         
     | 
| 
       185 
     | 
    
         
            -
             * First compute triplet version of full matrix, then compress to  
     | 
| 
      
 175 
     | 
    
         
            +
             * First compute triplet version of full matrix, then compress to CSC
         
     | 
| 
       186 
176 
     | 
    
         
             
             * */
         
     | 
| 
       187 
     | 
    
         
            -
            static  
     | 
| 
      
 177 
     | 
    
         
            +
            static ScsMatrix *fill_p_matrix(const ScsMatrix *P) {
         
     | 
| 
       188 
178 
     | 
    
         
             
              scs_int i, j, k, kk;
         
     | 
| 
       189 
179 
     | 
    
         
             
              scs_int Pnzmax = 2 * P->p[P->n]; /* upper bound */
         
     | 
| 
       190 
     | 
    
         
            -
               
     | 
| 
       191 
     | 
    
         
            -
               
     | 
| 
      
 180 
     | 
    
         
            +
              ScsMatrix *P_tmp = SCS(cs_spalloc)(P->n, P->n, Pnzmax, 1, 1);
         
     | 
| 
      
 181 
     | 
    
         
            +
              ScsMatrix *P_full;
         
     | 
| 
       192 
182 
     | 
    
         
             
              kk = 0;
         
     | 
| 
       193 
183 
     | 
    
         
             
              for (j = 0; j < P->n; j++) { /* cols */
         
     | 
| 
       194 
184 
     | 
    
         
             
                for (k = P->p[j]; k < P->p[j + 1]; k++) {
         
     | 
| 
         @@ -209,16 +199,15 @@ static csc *fill_p_matrix(const ScsMatrix *P) { 
     | 
|
| 
       209 
199 
     | 
    
         
             
                  kk++;
         
     | 
| 
       210 
200 
     | 
    
         
             
                }
         
     | 
| 
       211 
201 
     | 
    
         
             
              }
         
     | 
| 
       212 
     | 
    
         
            -
               
     | 
| 
       213 
     | 
    
         
            -
              P_full = SCS(cs_compress)(P_tmp, SCS_NULL);
         
     | 
| 
      
 202 
     | 
    
         
            +
              P_full = SCS(cs_compress)(P_tmp, kk, SCS_NULL);
         
     | 
| 
       214 
203 
     | 
    
         
             
              SCS(cs_spfree)(P_tmp);
         
     | 
| 
       215 
204 
     | 
    
         
             
              return P_full;
         
     | 
| 
       216 
205 
     | 
    
         
             
            }
         
     | 
| 
       217 
206 
     | 
    
         | 
| 
       218 
     | 
    
         
            -
            ScsLinSysWork * 
     | 
| 
       219 
     | 
    
         
            -
             
     | 
| 
      
 207 
     | 
    
         
            +
            ScsLinSysWork *scs_init_lin_sys_work(const ScsMatrix *A, const ScsMatrix *P,
         
     | 
| 
      
 208 
     | 
    
         
            +
                                                 const scs_float *diag_r) {
         
     | 
| 
       220 
209 
     | 
    
         
             
              cudaError_t err;
         
     | 
| 
       221 
     | 
    
         
            -
               
     | 
| 
      
 210 
     | 
    
         
            +
              ScsMatrix *P_full;
         
     | 
| 
       222 
211 
     | 
    
         
             
              ScsLinSysWork *p = SCS_NULL;
         
     | 
| 
       223 
212 
     | 
    
         
             
              ScsGpuMatrix *Ag = SCS_NULL;
         
     | 
| 
       224 
213 
     | 
    
         
             
              ScsGpuMatrix *Pg = SCS_NULL;
         
     | 
| 
         @@ -324,7 +313,7 @@ ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A, const ScsMatrix *P, 
     | 
|
| 
       324 
313 
     | 
    
         
             
              cusparseCreateDnVec(&p->dn_vec_m, Ag->m, p->tmp_m, SCS_CUDA_FLOAT);
         
     | 
| 
       325 
314 
     | 
    
         | 
| 
       326 
315 
     | 
    
         
             
              /* Form preconditioner and copy R_x, 1/R_y to gpu */
         
     | 
| 
       327 
     | 
    
         
            -
               
     | 
| 
      
 316 
     | 
    
         
            +
              scs_update_lin_sys_diag_r(p, diag_r);
         
     | 
| 
       328 
317 
     | 
    
         | 
| 
       329 
318 
     | 
    
         
             
            #if GPU_TRANSPOSE_MAT > 0
         
     | 
| 
       330 
319 
     | 
    
         
             
              p->Agt = (ScsGpuMatrix *)scs_malloc(sizeof(ScsGpuMatrix));
         
     | 
| 
         @@ -367,7 +356,7 @@ ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A, const ScsMatrix *P, 
     | 
|
| 
       367 
356 
     | 
    
         
             
              if (err != cudaSuccess) {
         
     | 
| 
       368 
357 
     | 
    
         
             
                printf("%s:%d:%s\nERROR_CUDA (*): %s\n", __FILE__, __LINE__, __func__,
         
     | 
| 
       369 
358 
     | 
    
         
             
                       cudaGetErrorString(err));
         
     | 
| 
       370 
     | 
    
         
            -
                 
     | 
| 
      
 359 
     | 
    
         
            +
                scs_free_lin_sys_work(p);
         
     | 
| 
       371 
360 
     | 
    
         
             
                return SCS_NULL;
         
     | 
| 
       372 
361 
     | 
    
         
             
              }
         
     | 
| 
       373 
362 
     | 
    
         
             
              return p;
         
     | 
| 
         @@ -466,8 +455,8 @@ static scs_int pcg(ScsLinSysWork *pr, const scs_float *s, scs_float *bg, 
     | 
|
| 
       466 
455 
     | 
    
         
             
             * y = R_y^{-1} (Ax - ry)
         
     | 
| 
       467 
456 
     | 
    
         
             
             *
         
     | 
| 
       468 
457 
     | 
    
         
             
             */
         
     | 
| 
       469 
     | 
    
         
            -
            scs_int  
     | 
| 
       470 
     | 
    
         
            -
             
     | 
| 
      
 458 
     | 
    
         
            +
            scs_int scs_solve_lin_sys(ScsLinSysWork *p, scs_float *b, const scs_float *s,
         
     | 
| 
      
 459 
     | 
    
         
            +
                                      scs_float tol) {
         
     | 
| 
       471 
460 
     | 
    
         
             
              scs_int cg_its, max_iters;
         
     | 
| 
       472 
461 
     | 
    
         
             
              scs_float neg_onef = -1.0;
         
     | 
| 
       473 
462 
     | 
    
         | 
| 
         @@ -0,0 +1,182 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #include "private.h"
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            #define PARDISO_SYMBOLIC (11)
         
     | 
| 
      
 4 
     | 
    
         
            +
            #define PARDISO_NUMERIC (22)
         
     | 
| 
      
 5 
     | 
    
         
            +
            #define PARDISO_SOLVE (33)
         
     | 
| 
      
 6 
     | 
    
         
            +
            #define PARDISO_CLEANUP (-1)
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            /* TODO: is it necessary to use pardiso_64 and MKL_Set_Interface_Layer ? */
         
     | 
| 
      
 9 
     | 
    
         
            +
            /*
         
     | 
| 
      
 10 
     | 
    
         
            +
            #define MKL_INTERFACE_LP64 0
         
     | 
| 
      
 11 
     | 
    
         
            +
            #define MKL_INTERFACE_ILP64 1
         
     | 
| 
      
 12 
     | 
    
         
            +
            */
         
     | 
| 
      
 13 
     | 
    
         
            +
            #ifdef DLONG
         
     | 
| 
      
 14 
     | 
    
         
            +
            #define _PARDISO pardiso_64
         
     | 
| 
      
 15 
     | 
    
         
            +
            #else
         
     | 
| 
      
 16 
     | 
    
         
            +
            #define _PARDISO pardiso
         
     | 
| 
      
 17 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            /* Prototypes for Pardiso functions */
         
     | 
| 
      
 20 
     | 
    
         
            +
            void _PARDISO(void **pt, const scs_int *maxfct, const scs_int *mnum,
         
     | 
| 
      
 21 
     | 
    
         
            +
                          const scs_int *mtype, const scs_int *phase, const scs_int *n,
         
     | 
| 
      
 22 
     | 
    
         
            +
                          const scs_float *a, const scs_int *ia, const scs_int *ja,
         
     | 
| 
      
 23 
     | 
    
         
            +
                          scs_int *perm, const scs_int *nrhs, scs_int *iparm,
         
     | 
| 
      
 24 
     | 
    
         
            +
                          const scs_int *msglvl, scs_float *b, scs_float *x,
         
     | 
| 
      
 25 
     | 
    
         
            +
                          scs_int *error);
         
     | 
| 
      
 26 
     | 
    
         
            +
            /* scs_int MKL_Set_Interface_Layer(scs_int); */
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            const char *scs_get_lin_sys_method() {
         
     | 
| 
      
 29 
     | 
    
         
            +
              return "sparse-direct-mkl-pardiso";
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            void scs_free_lin_sys_work(ScsLinSysWork *p) {
         
     | 
| 
      
 33 
     | 
    
         
            +
              if (p) {
         
     | 
| 
      
 34 
     | 
    
         
            +
                p->phase = PARDISO_CLEANUP;
         
     | 
| 
      
 35 
     | 
    
         
            +
                _PARDISO(p->pt, &(p->maxfct), &(p->mnum), &(p->mtype), &(p->phase),
         
     | 
| 
      
 36 
     | 
    
         
            +
                         &(p->n_plus_m), SCS_NULL, p->kkt->p, p->kkt->i, SCS_NULL,
         
     | 
| 
      
 37 
     | 
    
         
            +
                         &(p->nrhs), p->iparm, &(p->msglvl), SCS_NULL, SCS_NULL,
         
     | 
| 
      
 38 
     | 
    
         
            +
                         &(p->error));
         
     | 
| 
      
 39 
     | 
    
         
            +
                if (p->error != 0) {
         
     | 
| 
      
 40 
     | 
    
         
            +
                  scs_printf("Error during MKL Pardiso cleanup: %d", (int)p->error);
         
     | 
| 
      
 41 
     | 
    
         
            +
                }
         
     | 
| 
      
 42 
     | 
    
         
            +
                if (p->kkt)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  SCS(cs_spfree)(p->kkt);
         
     | 
| 
      
 44 
     | 
    
         
            +
                if (p->sol)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  scs_free(p->sol);
         
     | 
| 
      
 46 
     | 
    
         
            +
                if (p->diag_r_idxs)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  scs_free(p->diag_r_idxs);
         
     | 
| 
      
 48 
     | 
    
         
            +
                if (p->diag_p)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  scs_free(p->diag_p);
         
     | 
| 
      
 50 
     | 
    
         
            +
                scs_free(p);
         
     | 
| 
      
 51 
     | 
    
         
            +
              }
         
     | 
| 
      
 52 
     | 
    
         
            +
            }
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            ScsLinSysWork *scs_init_lin_sys_work(const ScsMatrix *A, const ScsMatrix *P,
         
     | 
| 
      
 55 
     | 
    
         
            +
                                                 const scs_float *diag_r) {
         
     | 
| 
      
 56 
     | 
    
         
            +
              scs_int i;
         
     | 
| 
      
 57 
     | 
    
         
            +
              ScsLinSysWork *p = scs_calloc(1, sizeof(ScsLinSysWork));
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              /* TODO: is this necessary with pardiso_64? */
         
     | 
| 
      
 60 
     | 
    
         
            +
              /* Set MKL interface layer */
         
     | 
| 
      
 61 
     | 
    
         
            +
              /*
         
     | 
| 
      
 62 
     | 
    
         
            +
            #ifdef DLONG
         
     | 
| 
      
 63 
     | 
    
         
            +
              MKL_Set_Interface_Layer(MKL_INTERFACE_ILP64);
         
     | 
| 
      
 64 
     | 
    
         
            +
            #else
         
     | 
| 
      
 65 
     | 
    
         
            +
              MKL_Set_Interface_Layer(MKL_INTERFACE_LP64);
         
     | 
| 
      
 66 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 67 
     | 
    
         
            +
              */
         
     | 
| 
      
 68 
     | 
    
         
            +
              p->n = A->n;
         
     | 
| 
      
 69 
     | 
    
         
            +
              p->m = A->m;
         
     | 
| 
      
 70 
     | 
    
         
            +
              p->n_plus_m = p->n + p->m;
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
              /* Even though we overwrite rhs with sol pardiso requires the memory */
         
     | 
| 
      
 73 
     | 
    
         
            +
              p->sol = (scs_float *)scs_malloc(sizeof(scs_float) * p->n_plus_m);
         
     | 
| 
      
 74 
     | 
    
         
            +
              p->diag_r_idxs = (scs_int *)scs_calloc(p->n_plus_m, sizeof(scs_int));
         
     | 
| 
      
 75 
     | 
    
         
            +
              p->diag_p = (scs_float *)scs_calloc(p->n, sizeof(scs_float));
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
              /* MKL pardiso requires upper triangular CSR matrices. The KKT matrix stuffed
         
     | 
| 
      
 78 
     | 
    
         
            +
               * as CSC lower triangular is equivalent. Pass upper=0. */
         
     | 
| 
      
 79 
     | 
    
         
            +
              p->kkt = SCS(form_kkt)(A, P, p->diag_p, diag_r, p->diag_r_idxs, 0);
         
     | 
| 
      
 80 
     | 
    
         
            +
              if (!(p->kkt)) {
         
     | 
| 
      
 81 
     | 
    
         
            +
                scs_printf("Error in forming KKT matrix");
         
     | 
| 
      
 82 
     | 
    
         
            +
                scs_free_lin_sys_work(p);
         
     | 
| 
      
 83 
     | 
    
         
            +
                return SCS_NULL;
         
     | 
| 
      
 84 
     | 
    
         
            +
              }
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
              for (i = 0; i < 64; i++) {
         
     | 
| 
      
 87 
     | 
    
         
            +
                p->iparm[i] = 0; /* Setup Pardiso control parameters */
         
     | 
| 
      
 88 
     | 
    
         
            +
                p->pt[i] = 0;    /* Initialize the internal solver memory pointer */
         
     | 
| 
      
 89 
     | 
    
         
            +
              }
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              /* Set Pardiso variables */
         
     | 
| 
      
 92 
     | 
    
         
            +
              p->mtype = -2;         /* Real symmetric indefinite matrix */
         
     | 
| 
      
 93 
     | 
    
         
            +
              p->nrhs = 1;           /* Number of right hand sides */
         
     | 
| 
      
 94 
     | 
    
         
            +
              p->maxfct = 1;         /* Maximum number of numerical factorizations */
         
     | 
| 
      
 95 
     | 
    
         
            +
              p->mnum = 1;           /* Which factorization to use */
         
     | 
| 
      
 96 
     | 
    
         
            +
              p->error = 0;          /* Initialize error flag */
         
     | 
| 
      
 97 
     | 
    
         
            +
              p->msglvl = VERBOSITY; /* Printing information */
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
              /* For all iparm vars see MKL documentation */
         
     | 
| 
      
 100 
     | 
    
         
            +
              p->iparm[0] = 1;          /* Parsido must inspect iparm */
         
     | 
| 
      
 101 
     | 
    
         
            +
              p->iparm[1] = 3;          /* Fill-in reordering from OpenMP */
         
     | 
| 
      
 102 
     | 
    
         
            +
              p->iparm[5] = 1;          /* Write solution into b */
         
     | 
| 
      
 103 
     | 
    
         
            +
              p->iparm[7] = 0;          /* Automatic iterative refinement calculation */
         
     | 
| 
      
 104 
     | 
    
         
            +
              p->iparm[9] = 8;          /* Perturb the pivot elements with 1E-8 */
         
     | 
| 
      
 105 
     | 
    
         
            +
              p->iparm[34] = 1;         /* Use C-style indexing for indices */
         
     | 
| 
      
 106 
     | 
    
         
            +
              /* p->iparm[36] = -80; */ /* Form block sparse matrices */
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            #ifdef SFLOAT
         
     | 
| 
      
 109 
     | 
    
         
            +
              p->iparm[27] = 1; /* 1 is single precision, 0 is double */
         
     | 
| 
      
 110 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              /* Permutation and symbolic factorization */
         
     | 
| 
      
 113 
     | 
    
         
            +
              scs_int phase = PARDISO_SYMBOLIC;
         
     | 
| 
      
 114 
     | 
    
         
            +
              _PARDISO(p->pt, &(p->maxfct), &(p->mnum), &(p->mtype), &phase, &(p->n_plus_m),
         
     | 
| 
      
 115 
     | 
    
         
            +
                       p->kkt->x, p->kkt->p, p->kkt->i, SCS_NULL, &(p->nrhs), p->iparm,
         
     | 
| 
      
 116 
     | 
    
         
            +
                       &(p->msglvl), SCS_NULL, SCS_NULL, &(p->error));
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
              if (p->error != 0) {
         
     | 
| 
      
 119 
     | 
    
         
            +
                scs_printf("Error during symbolic factorization: %d", (int)p->error);
         
     | 
| 
      
 120 
     | 
    
         
            +
                scs_free_lin_sys_work(p);
         
     | 
| 
      
 121 
     | 
    
         
            +
                return SCS_NULL;
         
     | 
| 
      
 122 
     | 
    
         
            +
              }
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              /* Numerical factorization */
         
     | 
| 
      
 125 
     | 
    
         
            +
              p->phase = PARDISO_NUMERIC;
         
     | 
| 
      
 126 
     | 
    
         
            +
              _PARDISO(p->pt, &(p->maxfct), &(p->mnum), &(p->mtype), &(p->phase),
         
     | 
| 
      
 127 
     | 
    
         
            +
                       &(p->n_plus_m), p->kkt->x, p->kkt->p, p->kkt->i, SCS_NULL,
         
     | 
| 
      
 128 
     | 
    
         
            +
                       &(p->nrhs), p->iparm, &(p->msglvl), SCS_NULL, SCS_NULL, &(p->error));
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
              if (p->error) {
         
     | 
| 
      
 131 
     | 
    
         
            +
                scs_printf("Error during numerical factorization: %d", (int)p->error);
         
     | 
| 
      
 132 
     | 
    
         
            +
                scs_free_lin_sys_work(p);
         
     | 
| 
      
 133 
     | 
    
         
            +
                return SCS_NULL;
         
     | 
| 
      
 134 
     | 
    
         
            +
              }
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
              if (p->iparm[21] < p->n) {
         
     | 
| 
      
 137 
     | 
    
         
            +
                scs_printf("KKT matrix has < n positive eigenvalues. P not PSD.");
         
     | 
| 
      
 138 
     | 
    
         
            +
                return SCS_NULL;
         
     | 
| 
      
 139 
     | 
    
         
            +
              }
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              return p;
         
     | 
| 
      
 142 
     | 
    
         
            +
            }
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
            /* Returns solution to linear system Ax = b with solution stored in b */
         
     | 
| 
      
 145 
     | 
    
         
            +
            scs_int scs_solve_lin_sys(ScsLinSysWork *p, scs_float *b, const scs_float *ws,
         
     | 
| 
      
 146 
     | 
    
         
            +
                                      scs_float tol) {
         
     | 
| 
      
 147 
     | 
    
         
            +
              /* Back substitution and iterative refinement */
         
     | 
| 
      
 148 
     | 
    
         
            +
              p->phase = PARDISO_SOLVE;
         
     | 
| 
      
 149 
     | 
    
         
            +
              _PARDISO(p->pt, &(p->maxfct), &(p->mnum), &(p->mtype), &(p->phase),
         
     | 
| 
      
 150 
     | 
    
         
            +
                       &(p->n_plus_m), p->kkt->x, p->kkt->p, p->kkt->i, SCS_NULL,
         
     | 
| 
      
 151 
     | 
    
         
            +
                       &(p->nrhs), p->iparm, &(p->msglvl), b, p->sol, &(p->error));
         
     | 
| 
      
 152 
     | 
    
         
            +
              if (p->error != 0) {
         
     | 
| 
      
 153 
     | 
    
         
            +
                scs_printf("Error during linear system solution: %d", (int)p->error);
         
     | 
| 
      
 154 
     | 
    
         
            +
              }
         
     | 
| 
      
 155 
     | 
    
         
            +
              return p->error;
         
     | 
| 
      
 156 
     | 
    
         
            +
            }
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            /* Update factorization when R changes */
         
     | 
| 
      
 159 
     | 
    
         
            +
            void scs_update_lin_sys_diag_r(ScsLinSysWork *p, const scs_float *diag_r) {
         
     | 
| 
      
 160 
     | 
    
         
            +
              scs_int i;
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
              for (i = 0; i < p->n; ++i) {
         
     | 
| 
      
 163 
     | 
    
         
            +
                /* top left is R_x + P, bottom right is -R_y */
         
     | 
| 
      
 164 
     | 
    
         
            +
                p->kkt->x[p->diag_r_idxs[i]] = p->diag_p[i] + diag_r[i];
         
     | 
| 
      
 165 
     | 
    
         
            +
              }
         
     | 
| 
      
 166 
     | 
    
         
            +
              for (i = p->n; i < p->n + p->m; ++i) {
         
     | 
| 
      
 167 
     | 
    
         
            +
                /* top left is R_x + P, bottom right is -R_y */
         
     | 
| 
      
 168 
     | 
    
         
            +
                p->kkt->x[p->diag_r_idxs[i]] = -diag_r[i];
         
     | 
| 
      
 169 
     | 
    
         
            +
              }
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
              /* Perform numerical factorization */
         
     | 
| 
      
 172 
     | 
    
         
            +
              p->phase = PARDISO_NUMERIC;
         
     | 
| 
      
 173 
     | 
    
         
            +
              _PARDISO(p->pt, &(p->maxfct), &(p->mnum), &(p->mtype), &(p->phase),
         
     | 
| 
      
 174 
     | 
    
         
            +
                       &(p->n_plus_m), p->kkt->x, p->kkt->p, p->kkt->i, SCS_NULL,
         
     | 
| 
      
 175 
     | 
    
         
            +
                       &(p->nrhs), p->iparm, &(p->msglvl), SCS_NULL, SCS_NULL, &(p->error));
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
              if (p->error != 0) {
         
     | 
| 
      
 178 
     | 
    
         
            +
                scs_printf("Error in PARDISO factorization when updating: %d.\n",
         
     | 
| 
      
 179 
     | 
    
         
            +
                           (int)p->error);
         
     | 
| 
      
 180 
     | 
    
         
            +
                scs_free_lin_sys_work(p);
         
     | 
| 
      
 181 
     | 
    
         
            +
              }
         
     | 
| 
      
 182 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #ifndef PRIV_H_GUARD
         
     | 
| 
      
 2 
     | 
    
         
            +
            #define PRIV_H_GUARD
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            #ifdef __cplusplus
         
     | 
| 
      
 5 
     | 
    
         
            +
            extern "C" {
         
     | 
| 
      
 6 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            #include "csparse.h"
         
     | 
| 
      
 9 
     | 
    
         
            +
            #include "linsys.h"
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            struct SCS_LIN_SYS_WORK {
         
     | 
| 
      
 12 
     | 
    
         
            +
              ScsMatrix *kkt; /* Upper triangular KKT matrix (in CSR format) */
         
     | 
| 
      
 13 
     | 
    
         
            +
              scs_float *sol; /* solution to the KKT system */
         
     | 
| 
      
 14 
     | 
    
         
            +
              scs_int n;      /* number of QP variables */
         
     | 
| 
      
 15 
     | 
    
         
            +
              scs_int m;      /* number of QP constraints */
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              /* Pardiso variables */
         
     | 
| 
      
 18 
     | 
    
         
            +
              void *pt[64];      /* internal solver memory pointer pt */
         
     | 
| 
      
 19 
     | 
    
         
            +
              scs_int iparm[64]; /* Pardiso control parameters */
         
     | 
| 
      
 20 
     | 
    
         
            +
              scs_int n_plus_m;  /* dimension of the linear system */
         
     | 
| 
      
 21 
     | 
    
         
            +
              scs_int mtype;     /* matrix type (-2 for real and symmetric indefinite) */
         
     | 
| 
      
 22 
     | 
    
         
            +
              scs_int nrhs;      /* number of right-hand sides (1) */
         
     | 
| 
      
 23 
     | 
    
         
            +
              scs_int maxfct;    /* maximum number of factors (1) */
         
     | 
| 
      
 24 
     | 
    
         
            +
              scs_int mnum;      /* indicates matrix for the solution phase (1) */
         
     | 
| 
      
 25 
     | 
    
         
            +
              scs_int phase;     /* control the execution phases of the solver */
         
     | 
| 
      
 26 
     | 
    
         
            +
              scs_int error;     /* the error indicator (0 for no error) */
         
     | 
| 
      
 27 
     | 
    
         
            +
              scs_int msglvl;    /* Message level information (0 for no output) */
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              /* These are required for matrix updates */
         
     | 
| 
      
 30 
     | 
    
         
            +
              scs_int *diag_r_idxs; /* indices where R appears */
         
     | 
| 
      
 31 
     | 
    
         
            +
              scs_float *diag_p;    /* Diagonal values of P */
         
     | 
| 
      
 32 
     | 
    
         
            +
            };
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            #ifdef __cplusplus
         
     | 
| 
      
 35 
     | 
    
         
            +
            }
         
     | 
| 
      
 36 
     | 
    
         
            +
            #endif
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            #endif
         
     | 
| 
         @@ -10,6 +10,10 @@ 
     | 
|
| 
       10 
10 
     | 
    
         
             
            #define NUM_L2_PASSES (1)    /* do one or zero, not more since not stable */
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
            scs_int SCS(copy_matrix)(ScsMatrix **dstp, const ScsMatrix *src) {
         
     | 
| 
      
 13 
     | 
    
         
            +
              if (!src) {
         
     | 
| 
      
 14 
     | 
    
         
            +
                *dstp = SCS_NULL;
         
     | 
| 
      
 15 
     | 
    
         
            +
                return 1;
         
     | 
| 
      
 16 
     | 
    
         
            +
              }
         
     | 
| 
       13 
17 
     | 
    
         
             
              scs_int Anz = src->p[src->n];
         
     | 
| 
       14 
18 
     | 
    
         
             
              ScsMatrix *A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
         
     | 
| 
       15 
19 
     | 
    
         
             
              if (!A) {
         
     | 
| 
         @@ -41,6 +45,8 @@ scs_int SCS(validate_lin_sys)(const ScsMatrix *A, const ScsMatrix *P) { 
     | 
|
| 
       41 
45 
     | 
    
         
             
              }
         
     | 
| 
       42 
46 
     | 
    
         
             
              /* detects some errors in A col ptrs: */
         
     | 
| 
       43 
47 
     | 
    
         
             
              Anz = A->p[A->n];
         
     | 
| 
      
 48 
     | 
    
         
            +
              /* Disable this check which is slowish and typically just produces noise. */
         
     | 
| 
      
 49 
     | 
    
         
            +
              /*
         
     | 
| 
       44 
50 
     | 
    
         
             
              if (Anz > 0) {
         
     | 
| 
       45 
51 
     | 
    
         
             
                for (i = 0; i < A->n; ++i) {
         
     | 
| 
       46 
52 
     | 
    
         
             
                  if (A->p[i] == A->p[i + 1]) {
         
     | 
| 
         @@ -53,6 +59,7 @@ scs_int SCS(validate_lin_sys)(const ScsMatrix *A, const ScsMatrix *P) { 
     | 
|
| 
       53 
59 
     | 
    
         
             
                  }
         
     | 
| 
       54 
60 
     | 
    
         
             
                }
         
     | 
| 
       55 
61 
     | 
    
         
             
              }
         
     | 
| 
      
 62 
     | 
    
         
            +
              */
         
     | 
| 
       56 
63 
     | 
    
         
             
              if (((scs_float)Anz / A->m > A->n) || (Anz < 0)) {
         
     | 
| 
       57 
64 
     | 
    
         
             
                scs_printf("Anz (nonzeros in A) = %li, outside of valid range\n",
         
     | 
| 
       58 
65 
     | 
    
         
             
                           (long)Anz);
         
     | 
| 
         @@ -106,18 +113,18 @@ static inline scs_float apply_limit(scs_float x) { 
     | 
|
| 
       106 
113 
     | 
    
         
             
              return x;
         
     | 
| 
       107 
114 
     | 
    
         
             
            }
         
     | 
| 
       108 
115 
     | 
    
         | 
| 
       109 
     | 
    
         
            -
            static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float * 
     | 
| 
       110 
     | 
    
         
            -
                                          scs_float * 
     | 
| 
       111 
     | 
    
         
            -
                                          scs_float *s, ScsConeWork *cone) {
         
     | 
| 
      
 116 
     | 
    
         
            +
            static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *Dt,
         
     | 
| 
      
 117 
     | 
    
         
            +
                                          scs_float *Et, ScsConeWork *cone) {
         
     | 
| 
       112 
118 
     | 
    
         
             
              scs_int i, j, kk;
         
     | 
| 
       113 
119 
     | 
    
         
             
              scs_float wrk;
         
     | 
| 
      
 120 
     | 
    
         
            +
              scs_float nm_a_col;
         
     | 
| 
       114 
121 
     | 
    
         | 
| 
       115 
122 
     | 
    
         
             
              /****************************  D  ****************************/
         
     | 
| 
       116 
123 
     | 
    
         | 
| 
       117 
124 
     | 
    
         
             
              /* initialize D */
         
     | 
| 
       118 
125 
     | 
    
         
             
              for (i = 0; i < A->m; ++i) {
         
     | 
| 
       119 
     | 
    
         
            -
                 
     | 
| 
       120 
     | 
    
         
            -
                Dt[i] = ABS(b[i]);
         
     | 
| 
      
 126 
     | 
    
         
            +
                Dt[i] = 0.;
         
     | 
| 
      
 127 
     | 
    
         
            +
                /* Dt[i] = ABS(b[i]); */
         
     | 
| 
       121 
128 
     | 
    
         
             
              }
         
     | 
| 
       122 
129 
     | 
    
         | 
| 
       123 
130 
     | 
    
         
             
              /* calculate row norms */
         
     | 
| 
         @@ -132,15 +139,16 @@ static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b, 
     | 
|
| 
       132 
139 
     | 
    
         | 
| 
       133 
140 
     | 
    
         
             
              /* invert temporary vec to form D */
         
     | 
| 
       134 
141 
     | 
    
         
             
              for (i = 0; i < A->m; ++i) {
         
     | 
| 
       135 
     | 
    
         
            -
                Dt[i] =  
     | 
| 
      
 142 
     | 
    
         
            +
                Dt[i] = SQRTF(apply_limit(Dt[i]));
         
     | 
| 
      
 143 
     | 
    
         
            +
                Dt[i] = SAFEDIV_POS(1.0, Dt[i]);
         
     | 
| 
       136 
144 
     | 
    
         
             
              }
         
     | 
| 
       137 
145 
     | 
    
         | 
| 
       138 
146 
     | 
    
         
             
              /****************************  E  ****************************/
         
     | 
| 
       139 
147 
     | 
    
         | 
| 
       140 
148 
     | 
    
         
             
              /* initialize E */
         
     | 
| 
       141 
149 
     | 
    
         
             
              for (i = 0; i < A->n; ++i) {
         
     | 
| 
       142 
     | 
    
         
            -
                 
     | 
| 
       143 
     | 
    
         
            -
                Et[i] = ABS(c[i]);
         
     | 
| 
      
 150 
     | 
    
         
            +
                Et[i] = 0.;
         
     | 
| 
      
 151 
     | 
    
         
            +
                /* Et[i] = ABS(c[i]); */
         
     | 
| 
       144 
152 
     | 
    
         
             
              }
         
     | 
| 
       145 
153 
     | 
    
         | 
| 
       146 
154 
     | 
    
         
             
              /* TODO: test not using P to determine scaling  */
         
     | 
| 
         @@ -163,27 +171,24 @@ static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b, 
     | 
|
| 
       163 
171 
     | 
    
         | 
| 
       164 
172 
     | 
    
         
             
              /* calculate col norms, E */
         
     | 
| 
       165 
173 
     | 
    
         
             
              for (i = 0; i < A->n; ++i) {
         
     | 
| 
       166 
     | 
    
         
            -
                 
     | 
| 
       167 
     | 
    
         
            -
                Et[i] =  
     | 
| 
      
 174 
     | 
    
         
            +
                nm_a_col = SCS(norm_inf)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]);
         
     | 
| 
      
 175 
     | 
    
         
            +
                Et[i] = MAX(Et[i], nm_a_col);
         
     | 
| 
      
 176 
     | 
    
         
            +
                Et[i] = SQRTF(apply_limit(Et[i]));
         
     | 
| 
      
 177 
     | 
    
         
            +
                Et[i] = SAFEDIV_POS(1.0, Et[i]);
         
     | 
| 
       168 
178 
     | 
    
         
             
              }
         
     | 
| 
       169 
     | 
    
         
            -
             
     | 
| 
       170 
     | 
    
         
            -
              /* calculate s value */
         
     | 
| 
       171 
     | 
    
         
            -
              *s = MAX(SCS(norm_inf)(c, A->n), SCS(norm_inf)(b, A->m));
         
     | 
| 
       172 
     | 
    
         
            -
              *s = SAFEDIV_POS(1.0, SQRTF(apply_limit(*s)));
         
     | 
| 
       173 
179 
     | 
    
         
             
            }
         
     | 
| 
       174 
180 
     | 
    
         | 
| 
       175 
     | 
    
         
            -
            static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float * 
     | 
| 
       176 
     | 
    
         
            -
                                        scs_float * 
     | 
| 
       177 
     | 
    
         
            -
                                        scs_float *s, ScsConeWork *cone) {
         
     | 
| 
      
 181 
     | 
    
         
            +
            static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float *Dt,
         
     | 
| 
      
 182 
     | 
    
         
            +
                                        scs_float *Et, ScsConeWork *cone) {
         
     | 
| 
       178 
183 
     | 
    
         
             
              scs_int i, j, kk;
         
     | 
| 
       179 
     | 
    
         
            -
              scs_float wrk 
     | 
| 
      
 184 
     | 
    
         
            +
              scs_float wrk;
         
     | 
| 
       180 
185 
     | 
    
         | 
| 
       181 
186 
     | 
    
         
             
              /****************************  D  ****************************/
         
     | 
| 
       182 
187 
     | 
    
         | 
| 
       183 
188 
     | 
    
         
             
              /* initialize D */
         
     | 
| 
       184 
189 
     | 
    
         
             
              for (i = 0; i < A->m; ++i) {
         
     | 
| 
       185 
     | 
    
         
            -
                 
     | 
| 
       186 
     | 
    
         
            -
                Dt[i] = b[i] * b[i];
         
     | 
| 
      
 190 
     | 
    
         
            +
                Dt[i] = 0.;
         
     | 
| 
      
 191 
     | 
    
         
            +
                /* Dt[i] = b[i] * b[i]; */
         
     | 
| 
       187 
192 
     | 
    
         
             
              }
         
     | 
| 
       188 
193 
     | 
    
         | 
| 
       189 
194 
     | 
    
         
             
              /* calculate row norms */
         
     | 
| 
         @@ -200,15 +205,16 @@ static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b, 
     | 
|
| 
       200 
205 
     | 
    
         
             
              SCS(enforce_cone_boundaries)(cone, Dt, &SCS(mean));
         
     | 
| 
       201 
206 
     | 
    
         | 
| 
       202 
207 
     | 
    
         
             
              for (i = 0; i < A->m; ++i) {
         
     | 
| 
       203 
     | 
    
         
            -
                Dt[i] =  
     | 
| 
      
 208 
     | 
    
         
            +
                Dt[i] = SQRTF(apply_limit(Dt[i]));
         
     | 
| 
      
 209 
     | 
    
         
            +
                Dt[i] = SAFEDIV_POS(1.0, Dt[i]);
         
     | 
| 
       204 
210 
     | 
    
         
             
              }
         
     | 
| 
       205 
211 
     | 
    
         | 
| 
       206 
212 
     | 
    
         
             
              /****************************  E  ****************************/
         
     | 
| 
       207 
213 
     | 
    
         | 
| 
       208 
214 
     | 
    
         
             
              /* initialize E */
         
     | 
| 
       209 
215 
     | 
    
         
             
              for (i = 0; i < A->n; ++i) {
         
     | 
| 
       210 
     | 
    
         
            -
                 
     | 
| 
       211 
     | 
    
         
            -
                Et[i] = c[i] * c[i];
         
     | 
| 
      
 216 
     | 
    
         
            +
                Et[i] = 0.;
         
     | 
| 
      
 217 
     | 
    
         
            +
                /* Et[i] = c[i] * c[i]; */
         
     | 
| 
       212 
218 
     | 
    
         
             
              }
         
     | 
| 
       213 
219 
     | 
    
         | 
| 
       214 
220 
     | 
    
         
             
              /* TODO: test not using P to determine scaling  */
         
     | 
| 
         @@ -232,19 +238,13 @@ static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b, 
     | 
|
| 
       232 
238 
     | 
    
         
             
              /* calculate col norms, E */
         
     | 
| 
       233 
239 
     | 
    
         
             
              for (i = 0; i < A->n; ++i) {
         
     | 
| 
       234 
240 
     | 
    
         
             
                Et[i] += SCS(norm_sq)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]);
         
     | 
| 
       235 
     | 
    
         
            -
                Et[i] =  
     | 
| 
      
 241 
     | 
    
         
            +
                Et[i] = SQRTF(apply_limit(SQRTF(Et[i])));
         
     | 
| 
      
 242 
     | 
    
         
            +
                Et[i] = SAFEDIV_POS(1.0, Et[i]);
         
     | 
| 
       236 
243 
     | 
    
         
             
              }
         
     | 
| 
       237 
     | 
    
         
            -
             
     | 
| 
       238 
     | 
    
         
            -
              /* calculate s value */
         
     | 
| 
       239 
     | 
    
         
            -
              norm_c = SCS(norm_2)(c, A->n);
         
     | 
| 
       240 
     | 
    
         
            -
              norm_b = SCS(norm_2)(b, A->m);
         
     | 
| 
       241 
     | 
    
         
            -
              *s = SQRTF(norm_c * norm_c + norm_b * norm_b);
         
     | 
| 
       242 
     | 
    
         
            -
              *s = SAFEDIV_POS(1.0, SQRTF(apply_limit(*s)));
         
     | 
| 
       243 
244 
     | 
    
         
             
            }
         
     | 
| 
       244 
245 
     | 
    
         | 
| 
       245 
     | 
    
         
            -
            static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float * 
     | 
| 
       246 
     | 
    
         
            -
                                 
     | 
| 
       247 
     | 
    
         
            -
                                ScsConeWork *cone) {
         
     | 
| 
      
 246 
     | 
    
         
            +
            static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float *Dt, scs_float *Et,
         
     | 
| 
      
 247 
     | 
    
         
            +
                                ScsScaling *scal, ScsConeWork *cone) {
         
     | 
| 
       248 
248 
     | 
    
         
             
              scs_int i, j;
         
     | 
| 
       249 
249 
     | 
    
         
             
              /* scale the rows of A with D */
         
     | 
| 
       250 
250 
     | 
    
         
             
              for (i = 0; i < A->n; ++i) {
         
     | 
| 
         @@ -271,15 +271,6 @@ static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float *b, scs_float *c, 
     | 
|
| 
       271 
271 
     | 
    
         
             
                }
         
     | 
| 
       272 
272 
     | 
    
         
             
              }
         
     | 
| 
       273 
273 
     | 
    
         | 
| 
       274 
     | 
    
         
            -
              /* scale c */
         
     | 
| 
       275 
     | 
    
         
            -
              for (i = 0; i < A->n; ++i) {
         
     | 
| 
       276 
     | 
    
         
            -
                c[i] *= Et[i];
         
     | 
| 
       277 
     | 
    
         
            -
              }
         
     | 
| 
       278 
     | 
    
         
            -
              /* scale b */
         
     | 
| 
       279 
     | 
    
         
            -
              for (i = 0; i < A->m; ++i) {
         
     | 
| 
       280 
     | 
    
         
            -
                b[i] *= Dt[i];
         
     | 
| 
       281 
     | 
    
         
            -
              }
         
     | 
| 
       282 
     | 
    
         
            -
             
     | 
| 
       283 
274 
     | 
    
         
             
              /* Accumulate scaling */
         
     | 
| 
       284 
275 
     | 
    
         
             
              for (i = 0; i < A->m; ++i) {
         
     | 
| 
       285 
276 
     | 
    
         
             
                scal->D[i] *= Dt[i];
         
     | 
| 
         @@ -288,53 +279,39 @@ static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float *b, scs_float *c, 
     | 
|
| 
       288 
279 
     | 
    
         
             
                scal->E[i] *= Et[i];
         
     | 
| 
       289 
280 
     | 
    
         
             
              }
         
     | 
| 
       290 
281 
     | 
    
         | 
| 
       291 
     | 
    
         
            -
              /*  
     | 
| 
       292 
     | 
    
         
            -
              SCS(scale_array)(c, s, A->n);
         
     | 
| 
       293 
     | 
    
         
            -
              SCS(scale_array)(b, s, A->m);
         
     | 
| 
       294 
     | 
    
         
            -
              /* no need to scale P since primal_scale = dual_scale */
         
     | 
| 
      
 282 
     | 
    
         
            +
              /* no need to scale P since later primal_scale = dual_scale */
         
     | 
| 
       295 
283 
     | 
    
         
             
              /*
         
     | 
| 
       296 
284 
     | 
    
         
             
              if (P) {
         
     | 
| 
       297 
285 
     | 
    
         
             
                SCS(scale_array)(P->x, primal_scale, P->p[P->n]);
         
     | 
| 
       298 
286 
     | 
    
         
             
                SCS(scale_array)(P->x, 1.0 / dual_scale, P->p[P->n]);
         
     | 
| 
       299 
287 
     | 
    
         
             
              }
         
     | 
| 
       300 
288 
     | 
    
         
             
              */
         
     | 
| 
       301 
     | 
    
         
            -
             
     | 
| 
       302 
     | 
    
         
            -
              /* Accumulate scaling */
         
     | 
| 
       303 
     | 
    
         
            -
              scal->primal_scale *= s;
         
     | 
| 
       304 
     | 
    
         
            -
              scal->dual_scale *= s;
         
     | 
| 
       305 
289 
     | 
    
         
             
            }
         
     | 
| 
       306 
290 
     | 
    
         | 
| 
       307 
     | 
    
         
            -
            /* Will rescale as P -> EPE, A -> DAE 
     | 
| 
      
 291 
     | 
    
         
            +
            /* Will rescale as P -> EPE, A -> DAE in-place.
         
     | 
| 
       308 
292 
     | 
    
         
             
             * Essentially trying to rescale this matrix:
         
     | 
| 
       309 
293 
     | 
    
         
             
             *
         
     | 
| 
       310 
     | 
    
         
            -
             * [P  A' 
     | 
| 
       311 
     | 
    
         
            -
             * [A  0 
     | 
| 
       312 
     | 
    
         
            -
             * [c' b' 0]          [0  0  s]
         
     | 
| 
      
 294 
     | 
    
         
            +
             * [P  A']   with   [E  0 ] on both sides (D, E diagonal)
         
     | 
| 
      
 295 
     | 
    
         
            +
             * [A  0 ]          [0  D ]
         
     | 
| 
       313 
296 
     | 
    
         
             
             *
         
     | 
| 
       314 
297 
     | 
    
         
             
             * which results in:
         
     | 
| 
       315 
298 
     | 
    
         
             
             *
         
     | 
| 
       316 
     | 
    
         
            -
             * [ EPE   EA'D 
     | 
| 
       317 
     | 
    
         
            -
             * [ DAE    0 
     | 
| 
       318 
     | 
    
         
            -
             * [ sc'E  sb'D   0  ]
         
     | 
| 
      
 299 
     | 
    
         
            +
             * [ EPE   EA'D ]
         
     | 
| 
      
 300 
     | 
    
         
            +
             * [ DAE    0   ]
         
     | 
| 
       319 
301 
     | 
    
         
             
             *
         
     | 
| 
       320 
     | 
    
         
            -
             * In other words D rescales the rows of A 
     | 
| 
       321 
     | 
    
         
            -
             *                E rescales the cols of A and rows/cols of P 
     | 
| 
      
 302 
     | 
    
         
            +
             * In other words D rescales the rows of A
         
     | 
| 
      
 303 
     | 
    
         
            +
             *                E rescales the cols of A and rows/cols of P
         
     | 
| 
       322 
304 
     | 
    
         
             
             *
         
     | 
| 
       323 
     | 
    
         
            -
             * will repeatedly set: D^-1 ~ norm of rows of [ A 
     | 
| 
      
 305 
     | 
    
         
            +
             * will repeatedly set: D^-1 ~ norm of rows of [ A ]
         
     | 
| 
       324 
306 
     | 
    
         
             
             *
         
     | 
| 
       325 
307 
     | 
    
         
             
             *                      E^-1 ~ norm of cols of [ P ]
         
     | 
| 
       326 
308 
     | 
    
         
             
             *                                             [ A ]
         
     | 
| 
       327 
     | 
    
         
            -
             *                                             [ c']
         
     | 
| 
       328 
     | 
    
         
            -
             *
         
     | 
| 
       329 
     | 
    
         
            -
             * `s` is incorporated into dual_scale and primal_scale
         
     | 
| 
       330 
309 
     | 
    
         
             
             *
         
     | 
| 
       331 
310 
     | 
    
         
             
             * The main complication is that D has to respect cone boundaries.
         
     | 
| 
       332 
311 
     | 
    
         
             
             *
         
     | 
| 
       333 
312 
     | 
    
         
             
             */
         
     | 
| 
       334 
     | 
    
         
            -
            ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A,  
     | 
| 
       335 
     | 
    
         
            -
                                           scs_float *c, ScsConeWork *cone) {
         
     | 
| 
      
 313 
     | 
    
         
            +
            ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, ScsConeWork *cone) {
         
     | 
| 
       336 
314 
     | 
    
         
             
              scs_int i;
         
     | 
| 
       337 
     | 
    
         
            -
              scs_float s;
         
     | 
| 
       338 
315 
     | 
    
         
             
              ScsScaling *scal = (ScsScaling *)scs_calloc(1, sizeof(ScsScaling));
         
     | 
| 
       339 
316 
     | 
    
         
             
              scs_float *Dt = (scs_float *)scs_calloc(A->m, sizeof(scs_float));
         
     | 
| 
       340 
317 
     | 
    
         
             
              scs_float *Et = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
         
     | 
| 
         @@ -359,12 +336,12 @@ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b, 
     | 
|
| 
       359 
336 
     | 
    
         
             
              scal->primal_scale = 1.;
         
     | 
| 
       360 
337 
     | 
    
         
             
              scal->dual_scale = 1.;
         
     | 
| 
       361 
338 
     | 
    
         
             
              for (i = 0; i < NUM_RUIZ_PASSES; ++i) {
         
     | 
| 
       362 
     | 
    
         
            -
                compute_ruiz_mats(P, A,  
     | 
| 
       363 
     | 
    
         
            -
                rescale(P, A,  
     | 
| 
      
 339 
     | 
    
         
            +
                compute_ruiz_mats(P, A, Dt, Et, cone);
         
     | 
| 
      
 340 
     | 
    
         
            +
                rescale(P, A, Dt, Et, scal, cone);
         
     | 
| 
       364 
341 
     | 
    
         
             
              }
         
     | 
| 
       365 
342 
     | 
    
         
             
              for (i = 0; i < NUM_L2_PASSES; ++i) {
         
     | 
| 
       366 
     | 
    
         
            -
                compute_l2_mats(P, A,  
     | 
| 
       367 
     | 
    
         
            -
                rescale(P, A,  
     | 
| 
      
 343 
     | 
    
         
            +
                compute_l2_mats(P, A, Dt, Et, cone);
         
     | 
| 
      
 344 
     | 
    
         
            +
                rescale(P, A, Dt, Et, scal, cone);
         
     | 
| 
       368 
345 
     | 
    
         
             
              }
         
     | 
| 
       369 
346 
     | 
    
         
             
              scs_free(Dt);
         
     | 
| 
       370 
347 
     | 
    
         
             
              scs_free(Et);
         
     | 
| 
         @@ -378,14 +355,13 @@ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b, 
     | 
|
| 
       378 
355 
     | 
    
         
             
              }
         
     | 
| 
       379 
356 
     | 
    
         
             
              scs_printf("primal_scale %g\n", scal->primal_scale);
         
     | 
| 
       380 
357 
     | 
    
         
             
              scs_printf("dual_scale %g\n", scal->dual_scale);
         
     | 
| 
       381 
     | 
    
         
            -
              scs_printf("norm_b %g\n", SCS(norm_inf)(b, A->m));
         
     | 
| 
       382 
     | 
    
         
            -
              scs_printf("norm_c %g\n", SCS(norm_inf)(c, A->n));
         
     | 
| 
       383 
358 
     | 
    
         
             
              scs_printf("norm D %g\n", SCS(norm_inf)(scal->D, A->m));
         
     | 
| 
       384 
359 
     | 
    
         
             
              scs_printf("norm E %g\n", SCS(norm_inf)(scal->E, A->n));
         
     | 
| 
       385 
360 
     | 
    
         
             
            #endif
         
     | 
| 
       386 
361 
     | 
    
         
             
              return scal;
         
     | 
| 
       387 
362 
     | 
    
         
             
            }
         
     | 
| 
       388 
363 
     | 
    
         | 
| 
      
 364 
     | 
    
         
            +
            /*
         
     | 
| 
       389 
365 
     | 
    
         
             
            void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling *scal) {
         
     | 
| 
       390 
366 
     | 
    
         
             
              scs_int i, j;
         
     | 
| 
       391 
367 
     | 
    
         
             
              scs_float *D = scal->D;
         
     | 
| 
         @@ -411,6 +387,7 @@ void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling *scal) { 
     | 
|
| 
       411 
387 
     | 
    
         
             
                }
         
     | 
| 
       412 
388 
     | 
    
         
             
              }
         
     | 
| 
       413 
389 
     | 
    
         
             
            }
         
     | 
| 
      
 390 
     | 
    
         
            +
            */
         
     | 
| 
       414 
391 
     | 
    
         | 
| 
       415 
392 
     | 
    
         
             
            void SCS(accum_by_atrans)(const ScsMatrix *A, const scs_float *x,
         
     | 
| 
       416 
393 
     | 
    
         
             
                                      scs_float *y) {
         
     |