scs 0.2.2
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 +7 -0
- data/CHANGELOG.md +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +98 -0
- data/ext/scs/extconf.rb +29 -0
- data/lib/scs.rb +17 -0
- data/lib/scs/ffi.rb +117 -0
- data/lib/scs/solver.rb +173 -0
- data/lib/scs/version.rb +3 -0
- data/vendor/scs/LICENSE.txt +21 -0
- data/vendor/scs/Makefile +164 -0
- data/vendor/scs/README.md +222 -0
- data/vendor/scs/include/aa.h +56 -0
- data/vendor/scs/include/cones.h +46 -0
- data/vendor/scs/include/ctrlc.h +33 -0
- data/vendor/scs/include/glbopts.h +177 -0
- data/vendor/scs/include/linalg.h +26 -0
- data/vendor/scs/include/linsys.h +64 -0
- data/vendor/scs/include/normalize.h +18 -0
- data/vendor/scs/include/rw.h +17 -0
- data/vendor/scs/include/scs.h +161 -0
- data/vendor/scs/include/scs_blas.h +51 -0
- data/vendor/scs/include/util.h +65 -0
- data/vendor/scs/linsys/amatrix.c +305 -0
- data/vendor/scs/linsys/amatrix.h +36 -0
- data/vendor/scs/linsys/amatrix.o +0 -0
- data/vendor/scs/linsys/cpu/direct/private.c +366 -0
- data/vendor/scs/linsys/cpu/direct/private.h +26 -0
- data/vendor/scs/linsys/cpu/direct/private.o +0 -0
- data/vendor/scs/linsys/cpu/indirect/private.c +256 -0
- data/vendor/scs/linsys/cpu/indirect/private.h +31 -0
- data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
- data/vendor/scs/linsys/external/amd/LICENSE.txt +934 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +469 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +254 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
- data/vendor/scs/linsys/external/amd/amd.h +400 -0
- data/vendor/scs/linsys/external/amd/amd_1.c +180 -0
- data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_2.c +1842 -0
- data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_aat.c +184 -0
- data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_control.c +64 -0
- data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_defaults.c +37 -0
- data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_dump.c +179 -0
- data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_global.c +16 -0
- data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_info.c +119 -0
- data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_internal.h +304 -0
- data/vendor/scs/linsys/external/amd/amd_order.c +199 -0
- data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_post_tree.c +120 -0
- data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_postorder.c +206 -0
- data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_preprocess.c +118 -0
- data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_valid.c +92 -0
- data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
- data/vendor/scs/linsys/external/amd/changes +11 -0
- data/vendor/scs/linsys/external/qdldl/LICENSE +201 -0
- data/vendor/scs/linsys/external/qdldl/README.md +120 -0
- data/vendor/scs/linsys/external/qdldl/changes +4 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.c +298 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.h +177 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
- data/vendor/scs/linsys/external/qdldl/qdldl_types.h +21 -0
- data/vendor/scs/linsys/gpu/gpu.c +41 -0
- data/vendor/scs/linsys/gpu/gpu.h +85 -0
- data/vendor/scs/linsys/gpu/indirect/private.c +304 -0
- data/vendor/scs/linsys/gpu/indirect/private.h +36 -0
- data/vendor/scs/scs.mk +181 -0
- data/vendor/scs/src/aa.c +224 -0
- data/vendor/scs/src/aa.o +0 -0
- data/vendor/scs/src/cones.c +802 -0
- data/vendor/scs/src/cones.o +0 -0
- data/vendor/scs/src/ctrlc.c +77 -0
- data/vendor/scs/src/ctrlc.o +0 -0
- data/vendor/scs/src/linalg.c +84 -0
- data/vendor/scs/src/linalg.o +0 -0
- data/vendor/scs/src/normalize.c +93 -0
- data/vendor/scs/src/normalize.o +0 -0
- data/vendor/scs/src/rw.c +167 -0
- data/vendor/scs/src/rw.o +0 -0
- data/vendor/scs/src/scs.c +978 -0
- data/vendor/scs/src/scs.o +0 -0
- data/vendor/scs/src/scs_version.c +5 -0
- data/vendor/scs/src/scs_version.o +0 -0
- data/vendor/scs/src/util.c +196 -0
- data/vendor/scs/src/util.o +0 -0
- data/vendor/scs/test/data/small_random_socp +0 -0
- data/vendor/scs/test/minunit.h +13 -0
- data/vendor/scs/test/problem_utils.h +93 -0
- data/vendor/scs/test/problems/rob_gauss_cov_est.h +85 -0
- data/vendor/scs/test/problems/small_lp.h +50 -0
- data/vendor/scs/test/problems/small_random_socp.h +33 -0
- data/vendor/scs/test/random_socp_prob.c +171 -0
- data/vendor/scs/test/run_from_file.c +69 -0
- data/vendor/scs/test/run_tests +2 -0
- data/vendor/scs/test/run_tests.c +32 -0
- metadata +203 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#ifndef SCS_BLAS_H_GUARD
|
|
2
|
+
#define SCS_BLAS_H_GUARD
|
|
3
|
+
|
|
4
|
+
#ifdef USE_LAPACK
|
|
5
|
+
|
|
6
|
+
#ifdef __cplusplus
|
|
7
|
+
extern "C" {
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
/* Default to underscore for blas / lapack */
|
|
11
|
+
#ifndef BLASSUFFIX
|
|
12
|
+
#define BLASSUFFIX _
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
/* annoying hack because some preprocessors can't handle empty macros */
|
|
16
|
+
#if defined(NOBLASSUFFIX) && NOBLASSUFFIX > 0
|
|
17
|
+
/* single or double precision */
|
|
18
|
+
#ifndef SFLOAT
|
|
19
|
+
#define BLAS(x) d##x
|
|
20
|
+
#else
|
|
21
|
+
#define BLAS(x) s##x
|
|
22
|
+
#endif
|
|
23
|
+
#else
|
|
24
|
+
/* this extra indirection is needed for BLASSUFFIX to work correctly as a
|
|
25
|
+
* variable */
|
|
26
|
+
#define stitch_(pre, x, post) pre##x##post
|
|
27
|
+
#define stitch__(pre, x, post) stitch_(pre, x, post)
|
|
28
|
+
/* single or double precision */
|
|
29
|
+
#ifndef SFLOAT
|
|
30
|
+
#define BLAS(x) stitch__(d, x, BLASSUFFIX)
|
|
31
|
+
#else
|
|
32
|
+
#define BLAS(x) stitch__(s, x, BLASSUFFIX)
|
|
33
|
+
#endif
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
#ifdef MATLAB_MEX_FILE
|
|
37
|
+
typedef ptrdiff_t blas_int;
|
|
38
|
+
#elif defined BLAS64
|
|
39
|
+
#include <stdint.h>
|
|
40
|
+
typedef int64_t blas_int;
|
|
41
|
+
#else
|
|
42
|
+
typedef int blas_int;
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
#ifdef __cplusplus
|
|
46
|
+
}
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
#endif /* USE_LAPACK */
|
|
50
|
+
|
|
51
|
+
#endif /* SCS_BLAS_H_GUARD */
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#ifndef UTIL_H_GUARD
|
|
2
|
+
#define UTIL_H_GUARD
|
|
3
|
+
|
|
4
|
+
#ifdef __cplusplus
|
|
5
|
+
extern "C" {
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
#include <stdio.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include "cones.h"
|
|
11
|
+
#include "scs.h"
|
|
12
|
+
|
|
13
|
+
/* timing code courtesy of A. Domahidi */
|
|
14
|
+
#if (defined NOTIMER)
|
|
15
|
+
typedef void *SCS(timer);
|
|
16
|
+
#elif (defined _WIN32 || defined _WIN64 || defined _WINDLL)
|
|
17
|
+
/* Use Windows QueryPerformanceCounter for timing */
|
|
18
|
+
#include <windows.h>
|
|
19
|
+
typedef struct SCS(timer) {
|
|
20
|
+
LARGE_INTEGER tic;
|
|
21
|
+
LARGE_INTEGER toc;
|
|
22
|
+
LARGE_INTEGER freq;
|
|
23
|
+
} SCS(timer);
|
|
24
|
+
|
|
25
|
+
#elif (defined __APPLE__)
|
|
26
|
+
/* Use MAC OSX mach_time for timing */
|
|
27
|
+
#include <mach/mach_time.h>
|
|
28
|
+
typedef struct SCS(timer) {
|
|
29
|
+
uint64_t tic;
|
|
30
|
+
uint64_t toc;
|
|
31
|
+
mach_timebase_info_data_t tinfo;
|
|
32
|
+
} SCS(timer);
|
|
33
|
+
|
|
34
|
+
#else
|
|
35
|
+
/* Use POSIX clock_gettime() for timing on other machines */
|
|
36
|
+
#include <time.h>
|
|
37
|
+
typedef struct SCS(timer) {
|
|
38
|
+
struct timespec tic;
|
|
39
|
+
struct timespec toc;
|
|
40
|
+
} SCS(timer);
|
|
41
|
+
|
|
42
|
+
#endif
|
|
43
|
+
|
|
44
|
+
#if EXTRA_VERBOSE > 1
|
|
45
|
+
extern SCS(timer) global_timer;
|
|
46
|
+
#endif
|
|
47
|
+
|
|
48
|
+
/* these all return milli-seconds */
|
|
49
|
+
void SCS(tic)(SCS(timer) * t);
|
|
50
|
+
scs_float SCS(toc)(SCS(timer) * t);
|
|
51
|
+
scs_float SCS(str_toc)(char *str, SCS(timer) * t);
|
|
52
|
+
scs_float SCS(tocq)(SCS(timer) * t);
|
|
53
|
+
|
|
54
|
+
void SCS(print_cone_data)(const ScsCone *k);
|
|
55
|
+
void SCS(print_data)(const ScsData *d);
|
|
56
|
+
void SCS(print_work)(const ScsWork *w);
|
|
57
|
+
void SCS(print_array)(const scs_float *arr, scs_int n, const char *name);
|
|
58
|
+
void SCS(set_default_settings)(ScsData *d);
|
|
59
|
+
void SCS(free_sol)(ScsSolution *sol);
|
|
60
|
+
void SCS(free_data)(ScsData *d, ScsCone *k);
|
|
61
|
+
|
|
62
|
+
#ifdef __cplusplus
|
|
63
|
+
}
|
|
64
|
+
#endif
|
|
65
|
+
#endif
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/* contains routines common to direct and indirect sparse solvers */
|
|
2
|
+
#include "amatrix.h"
|
|
3
|
+
|
|
4
|
+
#include "linsys.h"
|
|
5
|
+
|
|
6
|
+
#define MIN_SCALE (1e-4)
|
|
7
|
+
#define MAX_SCALE (1e4)
|
|
8
|
+
#define NUM_SCALE_PASSES 10 /* additional passes don't help much */
|
|
9
|
+
|
|
10
|
+
scs_int SCS(copy_a_matrix)(ScsMatrix **dstp, const ScsMatrix *src) {
|
|
11
|
+
scs_int Anz = src->p[src->n];
|
|
12
|
+
ScsMatrix *A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
|
|
13
|
+
if (!A) {
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
A->n = src->n;
|
|
17
|
+
A->m = src->m;
|
|
18
|
+
A->x = (scs_float *)scs_malloc(sizeof(scs_float) *
|
|
19
|
+
Anz); /* A values, size: NNZ A */
|
|
20
|
+
A->i = (scs_int *)scs_malloc(sizeof(scs_int) *
|
|
21
|
+
Anz); /* A row index, size: NNZ A */
|
|
22
|
+
A->p = (scs_int *)scs_malloc(sizeof(scs_int) *
|
|
23
|
+
(src->n + 1)); /* A column pointer, size: n+1 */
|
|
24
|
+
if (!A->x || !A->i || !A->p) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
memcpy(A->x, src->x, sizeof(scs_float) * Anz);
|
|
28
|
+
memcpy(A->i, src->i, sizeof(scs_int) * Anz);
|
|
29
|
+
memcpy(A->p, src->p, sizeof(scs_int) * (src->n + 1));
|
|
30
|
+
*dstp = A;
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
scs_int SCS(validate_lin_sys)(const ScsMatrix *A) {
|
|
35
|
+
scs_int i, r_max, Anz;
|
|
36
|
+
if (!A->x || !A->i || !A->p) {
|
|
37
|
+
scs_printf("data incompletely specified\n");
|
|
38
|
+
return -1;
|
|
39
|
+
}
|
|
40
|
+
/* detects some errors in A col ptrs: */
|
|
41
|
+
Anz = A->p[A->n];
|
|
42
|
+
if (Anz > 0) {
|
|
43
|
+
for (i = 0; i < A->n; ++i) {
|
|
44
|
+
if (A->p[i] == A->p[i + 1]) {
|
|
45
|
+
scs_printf(
|
|
46
|
+
"WARN: A->p (column pointers) not strictly increasing, "
|
|
47
|
+
"column %li empty\n",
|
|
48
|
+
(long)i);
|
|
49
|
+
} else if (A->p[i] > A->p[i + 1]) {
|
|
50
|
+
scs_printf("ERROR: A->p (column pointers) decreasing\n");
|
|
51
|
+
return -1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (((scs_float)Anz / A->m > A->n) || (Anz < 0)) {
|
|
56
|
+
scs_printf("Anz (nonzeros in A) = %li, outside of valid range\n",
|
|
57
|
+
(long)Anz);
|
|
58
|
+
return -1;
|
|
59
|
+
}
|
|
60
|
+
r_max = 0;
|
|
61
|
+
for (i = 0; i < Anz; ++i) {
|
|
62
|
+
if (A->i[i] > r_max) {
|
|
63
|
+
r_max = A->i[i];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (r_max > A->m - 1) {
|
|
67
|
+
scs_printf("number of rows in A inconsistent with input dimension\n");
|
|
68
|
+
return -1;
|
|
69
|
+
}
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void SCS(free_a_matrix)(ScsMatrix *A) {
|
|
74
|
+
if (A) {
|
|
75
|
+
scs_free(A->x);
|
|
76
|
+
scs_free(A->i);
|
|
77
|
+
scs_free(A->p);
|
|
78
|
+
scs_free(A);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
#if EXTRA_VERBOSE > 0
|
|
83
|
+
static void print_a_matrix(const ScsMatrix *A) {
|
|
84
|
+
scs_int i, j;
|
|
85
|
+
/* TODO: this is to prevent clogging stdout */
|
|
86
|
+
if (A->p[A->n] < 2500) {
|
|
87
|
+
scs_printf("\n");
|
|
88
|
+
for (i = 0; i < A->n; ++i) {
|
|
89
|
+
scs_printf("Col %li: ", (long)i);
|
|
90
|
+
for (j = A->p[i]; j < A->p[i + 1]; j++) {
|
|
91
|
+
scs_printf("A[%li,%li] = %4f, ", (long)A->i[j], (long)i, A->x[j]);
|
|
92
|
+
}
|
|
93
|
+
scs_printf("norm col = %4f\n",
|
|
94
|
+
SCS(norm)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]));
|
|
95
|
+
}
|
|
96
|
+
scs_printf("norm A = %4f\n", SCS(norm)(A->x, A->p[A->n]));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
#endif
|
|
100
|
+
|
|
101
|
+
void SCS(_normalize_a)(ScsMatrix *A, const ScsSettings *stgs, const ScsCone *k,
|
|
102
|
+
ScsScaling *scal) {
|
|
103
|
+
scs_float *D = (scs_float *)scs_malloc(A->m * sizeof(scs_float));
|
|
104
|
+
scs_float *E = (scs_float *)scs_malloc(A->n * sizeof(scs_float));
|
|
105
|
+
scs_float *Dt = (scs_float *)scs_malloc(A->m * sizeof(scs_float));
|
|
106
|
+
scs_float *Et = (scs_float *)scs_malloc(A->n * sizeof(scs_float));
|
|
107
|
+
scs_float *nms = (scs_float *)scs_calloc(A->m, sizeof(scs_float));
|
|
108
|
+
scs_int i, j, l, count, delta, *boundaries;
|
|
109
|
+
scs_int num_boundaries = SCS(get_cone_boundaries)(k, &boundaries);
|
|
110
|
+
scs_float wrk;
|
|
111
|
+
|
|
112
|
+
#if EXTRA_VERBOSE > 0
|
|
113
|
+
SCS(timer) normalize_timer;
|
|
114
|
+
SCS(tic)(&normalize_timer);
|
|
115
|
+
scs_printf("normalizing A\n");
|
|
116
|
+
print_a_matrix(A);
|
|
117
|
+
#endif
|
|
118
|
+
|
|
119
|
+
for (l = 0; l < NUM_SCALE_PASSES; ++l) {
|
|
120
|
+
memset(D, 0, A->m * sizeof(scs_float));
|
|
121
|
+
memset(E, 0, A->n * sizeof(scs_float));
|
|
122
|
+
/* calculate row norms */
|
|
123
|
+
for (i = 0; i < A->n; ++i) {
|
|
124
|
+
for (j = A->p[i]; j < A->p[i + 1]; ++j) {
|
|
125
|
+
D[A->i[j]] = MAX(D[A->i[j]], ABS(A->x[j]));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
for (i = 0; i < A->m; ++i) {
|
|
129
|
+
D[i] = SQRTF(D[i]);
|
|
130
|
+
D[i] = D[i] < MIN_SCALE ? 1.0 : D[i];
|
|
131
|
+
D[i] = D[i] > MAX_SCALE ? MAX_SCALE : D[i];
|
|
132
|
+
}
|
|
133
|
+
/* calculate col norms, E */
|
|
134
|
+
for (i = 0; i < A->n; ++i) {
|
|
135
|
+
E[i] = SCS(norm_inf)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]);
|
|
136
|
+
E[i] = SQRTF(E[i]);
|
|
137
|
+
E[i] = E[i] < MIN_SCALE ? 1.0 : E[i];
|
|
138
|
+
E[i] = E[i] > MAX_SCALE ? MAX_SCALE : E[i];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* mean of D across each cone */
|
|
142
|
+
count = boundaries[0];
|
|
143
|
+
for (i = 1; i < num_boundaries; ++i) {
|
|
144
|
+
wrk = 0;
|
|
145
|
+
delta = boundaries[i];
|
|
146
|
+
for (j = count; j < count + delta; ++j) {
|
|
147
|
+
wrk += D[j];
|
|
148
|
+
}
|
|
149
|
+
wrk /= delta;
|
|
150
|
+
for (j = count; j < count + delta; ++j) {
|
|
151
|
+
D[j] = wrk;
|
|
152
|
+
}
|
|
153
|
+
count += delta;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* scale the rows with D */
|
|
157
|
+
for (i = 0; i < A->n; ++i) {
|
|
158
|
+
for (j = A->p[i]; j < A->p[i + 1]; ++j) {
|
|
159
|
+
A->x[j] /= D[A->i[j]];
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* scale the cols with E */
|
|
164
|
+
for (i = 0; i < A->n; ++i) {
|
|
165
|
+
SCS(scale_array)(&(A->x[A->p[i]]), 1.0 / E[i], A->p[i + 1] - A->p[i]);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Accumulate scaling */
|
|
169
|
+
for (i = 0; i < A->m; ++i) {
|
|
170
|
+
Dt[i] = (l == 0) ? D[i] : Dt[i] * D[i];
|
|
171
|
+
}
|
|
172
|
+
for (i = 0; i < A->n; ++i) {
|
|
173
|
+
Et[i] = (l == 0) ? E[i] : Et[i] * E[i];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
scs_free(boundaries);
|
|
177
|
+
scs_free(D);
|
|
178
|
+
scs_free(E);
|
|
179
|
+
|
|
180
|
+
/* calculate mean of row norms of A */
|
|
181
|
+
for (i = 0; i < A->n; ++i) {
|
|
182
|
+
for (j = A->p[i]; j < A->p[i + 1]; ++j) {
|
|
183
|
+
wrk = A->x[j];
|
|
184
|
+
nms[A->i[j]] += wrk * wrk;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
scal->mean_norm_row_a = 0.0;
|
|
188
|
+
for (i = 0; i < A->m; ++i) {
|
|
189
|
+
scal->mean_norm_row_a += SQRTF(nms[i]) / A->m;
|
|
190
|
+
}
|
|
191
|
+
scs_free(nms);
|
|
192
|
+
|
|
193
|
+
/* calculate mean of col norms of A */
|
|
194
|
+
scal->mean_norm_col_a = 0.0;
|
|
195
|
+
for (i = 0; i < A->n; ++i) {
|
|
196
|
+
scal->mean_norm_col_a +=
|
|
197
|
+
SCS(norm)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]) / A->n;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* scale up by d->SCALE if not equal to 1 */
|
|
201
|
+
if (stgs->scale != 1) {
|
|
202
|
+
SCS(scale_array)(A->x, stgs->scale, A->p[A->n]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
scal->D = Dt;
|
|
206
|
+
scal->E = Et;
|
|
207
|
+
|
|
208
|
+
#if EXTRA_VERBOSE > 0
|
|
209
|
+
scs_printf("finished normalizing A, time: %1.2es\n",
|
|
210
|
+
SCS(tocq)(&normalize_timer) / 1e3);
|
|
211
|
+
print_a_matrix(A);
|
|
212
|
+
#endif
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
void SCS(_un_normalize_a)(ScsMatrix *A, const ScsSettings *stgs,
|
|
216
|
+
const ScsScaling *scal) {
|
|
217
|
+
scs_int i, j;
|
|
218
|
+
scs_float *D = scal->D;
|
|
219
|
+
scs_float *E = scal->E;
|
|
220
|
+
for (i = 0; i < A->n; ++i) {
|
|
221
|
+
SCS(scale_array)
|
|
222
|
+
(&(A->x[A->p[i]]), E[i] / stgs->scale, A->p[i + 1] - A->p[i]);
|
|
223
|
+
}
|
|
224
|
+
for (i = 0; i < A->n; ++i) {
|
|
225
|
+
for (j = A->p[i]; j < A->p[i + 1]; ++j) {
|
|
226
|
+
A->x[j] *= D[A->i[j]];
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
void SCS(_accum_by_atrans)(scs_int n, scs_float *Ax, scs_int *Ai, scs_int *Ap,
|
|
232
|
+
const scs_float *x, scs_float *y) {
|
|
233
|
+
/* y += A'*x
|
|
234
|
+
A in column compressed format
|
|
235
|
+
parallelizes over columns (rows of A')
|
|
236
|
+
*/
|
|
237
|
+
scs_int p, j;
|
|
238
|
+
scs_int c1, c2;
|
|
239
|
+
scs_float yj;
|
|
240
|
+
#if EXTRA_VERBOSE > 0
|
|
241
|
+
SCS(timer) mult_by_atrans_timer;
|
|
242
|
+
SCS(tic)(&mult_by_atrans_timer);
|
|
243
|
+
#endif
|
|
244
|
+
#ifdef _OPENMP
|
|
245
|
+
#pragma omp parallel for private(p, c1, c2, yj)
|
|
246
|
+
#endif
|
|
247
|
+
for (j = 0; j < n; j++) {
|
|
248
|
+
yj = y[j];
|
|
249
|
+
c1 = Ap[j];
|
|
250
|
+
c2 = Ap[j + 1];
|
|
251
|
+
for (p = c1; p < c2; p++) {
|
|
252
|
+
yj += Ax[p] * x[Ai[p]];
|
|
253
|
+
}
|
|
254
|
+
y[j] = yj;
|
|
255
|
+
}
|
|
256
|
+
#if EXTRA_VERBOSE > 0
|
|
257
|
+
scs_printf("mult By A trans time: %1.2es\n",
|
|
258
|
+
SCS(tocq)(&mult_by_atrans_timer) / 1e3);
|
|
259
|
+
#endif
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
scs_float SCS(cumsum)(scs_int *p, scs_int *c, scs_int n) {
|
|
263
|
+
scs_int i, nz = 0;
|
|
264
|
+
scs_float nz2 = 0;
|
|
265
|
+
if (!p || !c) {
|
|
266
|
+
return (-1);
|
|
267
|
+
} /* check inputs */
|
|
268
|
+
for (i = 0; i < n; i++) {
|
|
269
|
+
p[i] = nz;
|
|
270
|
+
nz += c[i];
|
|
271
|
+
nz2 += c[i]; /* also in scs_float to avoid scs_int overflow */
|
|
272
|
+
c[i] = p[i]; /* also copy p[0..n-1] back into c[0..n-1]*/
|
|
273
|
+
}
|
|
274
|
+
p[n] = nz;
|
|
275
|
+
return nz2; /* return sum (c [0..n-1]) */
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
void SCS(_accum_by_a)(scs_int n, scs_float *Ax, scs_int *Ai, scs_int *Ap,
|
|
279
|
+
const scs_float *x, scs_float *y) {
|
|
280
|
+
/*y += A*x
|
|
281
|
+
A in column compressed format
|
|
282
|
+
this parallelizes over columns and uses
|
|
283
|
+
pragma atomic to prevent concurrent writes to y
|
|
284
|
+
*/
|
|
285
|
+
scs_int p, j;
|
|
286
|
+
scs_int c1, c2;
|
|
287
|
+
scs_float xj;
|
|
288
|
+
#if EXTRA_VERBOSE > 0
|
|
289
|
+
SCS(timer) mult_by_a_timer;
|
|
290
|
+
SCS(tic)(&mult_by_a_timer);
|
|
291
|
+
#endif
|
|
292
|
+
/*#pragma omp parallel for private(p,c1,c2,xj) */
|
|
293
|
+
for (j = 0; j < n; j++) {
|
|
294
|
+
xj = x[j];
|
|
295
|
+
c1 = Ap[j];
|
|
296
|
+
c2 = Ap[j + 1];
|
|
297
|
+
for (p = c1; p < c2; p++) {
|
|
298
|
+
/*#pragma omp atomic */
|
|
299
|
+
y[Ai[p]] += Ax[p] * xj;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
#if EXTRA_VERBOSE > 0
|
|
303
|
+
scs_printf("mult By A time: %1.2es\n", SCS(tocq)(&mult_by_a_timer) / 1e3);
|
|
304
|
+
#endif
|
|
305
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#ifndef AMATRIX_H_GUARD
|
|
2
|
+
#define AMATRIX_H_GUARD
|
|
3
|
+
|
|
4
|
+
#ifdef __cplusplus
|
|
5
|
+
extern "C" {
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
#include "glbopts.h"
|
|
9
|
+
#include "linalg.h"
|
|
10
|
+
#include "linsys.h"
|
|
11
|
+
#include "scs.h"
|
|
12
|
+
#include "util.h"
|
|
13
|
+
|
|
14
|
+
/* this struct defines the data matrix A */
|
|
15
|
+
struct SCS_A_DATA_MATRIX {
|
|
16
|
+
/* A is supplied in column compressed format */
|
|
17
|
+
scs_float *x; /* A values, size: NNZ A */
|
|
18
|
+
scs_int *i; /* A row index, size: NNZ A */
|
|
19
|
+
scs_int *p; /* A column pointer, size: n+1 */
|
|
20
|
+
scs_int m, n; /* m rows, n cols */
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
void SCS(_accum_by_atrans)(scs_int n, scs_float *Ax, scs_int *Ai, scs_int *Ap,
|
|
24
|
+
const scs_float *x, scs_float *y);
|
|
25
|
+
void SCS(_accum_by_a)(scs_int n, scs_float *Ax, scs_int *Ai, scs_int *Ap,
|
|
26
|
+
const scs_float *x, scs_float *y);
|
|
27
|
+
void SCS(_normalize_a)(ScsMatrix *A, const ScsSettings *stgs, const ScsCone *k,
|
|
28
|
+
ScsScaling *scal);
|
|
29
|
+
void SCS(_un_normalize_a)(ScsMatrix *A, const ScsSettings *stgs,
|
|
30
|
+
const ScsScaling *scal);
|
|
31
|
+
scs_float SCS(cumsum)(scs_int *p, scs_int *c, scs_int n);
|
|
32
|
+
|
|
33
|
+
#ifdef __cplusplus
|
|
34
|
+
}
|
|
35
|
+
#endif
|
|
36
|
+
#endif
|