scs 0.2.0
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 +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +84 -0
- data/ext/scs/Rakefile +11 -0
- data/lib/scs/ffi.rb +117 -0
- data/lib/scs/solver.rb +178 -0
- data/lib/scs/version.rb +3 -0
- data/lib/scs.rb +17 -0
- data/vendor/scs/LICENSE.txt +21 -0
- data/vendor/scs/Makefile +164 -0
- data/vendor/scs/README.md +220 -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 +975 -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,304 @@
|
|
|
1
|
+
/* ========================================================================= */
|
|
2
|
+
/* === amd_internal.h ====================================================== */
|
|
3
|
+
/* ========================================================================= */
|
|
4
|
+
|
|
5
|
+
/* ------------------------------------------------------------------------- */
|
|
6
|
+
/* AMD, Copyright (c) Timothy A. Davis, */
|
|
7
|
+
/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
|
|
8
|
+
/* email: DrTimothyAldenDavis@gmail.com */
|
|
9
|
+
/* ------------------------------------------------------------------------- */
|
|
10
|
+
|
|
11
|
+
/* This file is for internal use in AMD itself, and does not normally need to
|
|
12
|
+
* be included in user code (it is included in UMFPACK, however). All others
|
|
13
|
+
* should use amd.h instead.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/* ========================================================================= */
|
|
17
|
+
/* === NDEBUG ============================================================== */
|
|
18
|
+
/* ========================================================================= */
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
* Turning on debugging takes some work (see below). If you do not edit this
|
|
22
|
+
* file, then debugging is always turned off, regardless of whether or not
|
|
23
|
+
* -DNDEBUG is specified in your compiler options.
|
|
24
|
+
*
|
|
25
|
+
* If AMD is being compiled as a mexFunction, then MATLAB_MEX_FILE is defined,
|
|
26
|
+
* and mxAssert is used instead of assert. If debugging is not enabled, no
|
|
27
|
+
* MATLAB include files or functions are used. Thus, the AMD library libamd.a
|
|
28
|
+
* can be safely used in either a stand-alone C program or in another
|
|
29
|
+
* mexFunction, without any change.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
AMD will be exceedingly slow when running in debug mode. The next three
|
|
34
|
+
lines ensure that debugging is turned off.
|
|
35
|
+
*/
|
|
36
|
+
#ifndef NDEBUG
|
|
37
|
+
#define NDEBUG
|
|
38
|
+
#endif
|
|
39
|
+
|
|
40
|
+
/*
|
|
41
|
+
To enable debugging, uncomment the following line:
|
|
42
|
+
#undef NDEBUG
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/* ------------------------------------------------------------------------- */
|
|
46
|
+
/* ANSI include files */
|
|
47
|
+
/* ------------------------------------------------------------------------- */
|
|
48
|
+
|
|
49
|
+
/* from stdlib.h: size_t, malloc, free, realloc, and calloc */
|
|
50
|
+
#include <stdlib.h>
|
|
51
|
+
|
|
52
|
+
#if !defined(NPRINT) || !defined(NDEBUG)
|
|
53
|
+
/* from stdio.h: printf. Not included if NPRINT is defined at compile time.
|
|
54
|
+
* fopen and fscanf are used when debugging. */
|
|
55
|
+
#include <stdio.h>
|
|
56
|
+
#endif
|
|
57
|
+
|
|
58
|
+
/* from limits.h: INT_MAX and LONG_MAX */
|
|
59
|
+
#include <limits.h>
|
|
60
|
+
|
|
61
|
+
/* from math.h: sqrt */
|
|
62
|
+
#include <math.h>
|
|
63
|
+
|
|
64
|
+
/* ------------------------------------------------------------------------- */
|
|
65
|
+
/* MATLAB include files (only if being used in or via MATLAB) */
|
|
66
|
+
/* ------------------------------------------------------------------------- */
|
|
67
|
+
|
|
68
|
+
#ifdef MATLAB_MEX_FILE
|
|
69
|
+
#include "matrix.h"
|
|
70
|
+
#include "mex.h"
|
|
71
|
+
#endif
|
|
72
|
+
|
|
73
|
+
/* ------------------------------------------------------------------------- */
|
|
74
|
+
/* basic definitions */
|
|
75
|
+
/* ------------------------------------------------------------------------- */
|
|
76
|
+
|
|
77
|
+
#ifdef FLIP
|
|
78
|
+
#undef FLIP
|
|
79
|
+
#endif
|
|
80
|
+
|
|
81
|
+
#ifdef MAX
|
|
82
|
+
#undef MAX
|
|
83
|
+
#endif
|
|
84
|
+
|
|
85
|
+
#ifdef MIN
|
|
86
|
+
#undef MIN
|
|
87
|
+
#endif
|
|
88
|
+
|
|
89
|
+
#ifdef EMPTY
|
|
90
|
+
#undef EMPTY
|
|
91
|
+
#endif
|
|
92
|
+
|
|
93
|
+
#ifdef GLOBAL
|
|
94
|
+
#undef GLOBAL
|
|
95
|
+
#endif
|
|
96
|
+
|
|
97
|
+
#ifdef PRIVATE
|
|
98
|
+
#undef PRIVATE
|
|
99
|
+
#endif
|
|
100
|
+
|
|
101
|
+
/* FLIP is a "negation about -1", and is used to mark an integer i that is
|
|
102
|
+
* normally non-negative. FLIP (EMPTY) is EMPTY. FLIP of a number > EMPTY
|
|
103
|
+
* is negative, and FLIP of a number < EMTPY is positive. FLIP (FLIP (i)) = i
|
|
104
|
+
* for all integers i. UNFLIP (i) is >= EMPTY. */
|
|
105
|
+
#define EMPTY (-1)
|
|
106
|
+
#define FLIP(i) (-(i)-2)
|
|
107
|
+
#define UNFLIP(i) ((i < EMPTY) ? FLIP (i) : (i))
|
|
108
|
+
|
|
109
|
+
/* for integer MAX/MIN, or for scs_floats when we don't care how NaN's behave: */
|
|
110
|
+
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
|
111
|
+
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
112
|
+
|
|
113
|
+
/* logical expression of p implies q: */
|
|
114
|
+
#define IMPLIES(p,q) (!(p) || (q))
|
|
115
|
+
|
|
116
|
+
/* Note that the IBM RS 6000 xlc predefines TRUE and FALSE in <types.h>. */
|
|
117
|
+
/* The Compaq Alpha also predefines TRUE and FALSE. */
|
|
118
|
+
#ifdef TRUE
|
|
119
|
+
#undef TRUE
|
|
120
|
+
#endif
|
|
121
|
+
#ifdef FALSE
|
|
122
|
+
#undef FALSE
|
|
123
|
+
#endif
|
|
124
|
+
|
|
125
|
+
#define TRUE (1)
|
|
126
|
+
#define FALSE (0)
|
|
127
|
+
#define PRIVATE static
|
|
128
|
+
#define GLOBAL
|
|
129
|
+
#define EMPTY (-1)
|
|
130
|
+
|
|
131
|
+
/* Note that Linux's gcc 2.96 defines NULL as ((void *) 0), but other */
|
|
132
|
+
/* compilers (even gcc 2.95.2 on Solaris) define NULL as 0 or (0). We */
|
|
133
|
+
/* need to use the ANSI standard value of 0. */
|
|
134
|
+
#ifdef NULL
|
|
135
|
+
#undef NULL
|
|
136
|
+
#endif
|
|
137
|
+
|
|
138
|
+
#define NULL 0
|
|
139
|
+
|
|
140
|
+
/* largest value of size_t */
|
|
141
|
+
#ifndef SIZE_T_MAX
|
|
142
|
+
#ifdef SIZE_MAX
|
|
143
|
+
/* C99 only */
|
|
144
|
+
#define SIZE_T_MAX SIZE_MAX
|
|
145
|
+
#else
|
|
146
|
+
#define SIZE_T_MAX ((size_t) (-1))
|
|
147
|
+
#endif
|
|
148
|
+
#endif
|
|
149
|
+
|
|
150
|
+
/* ------------------------------------------------------------------------- */
|
|
151
|
+
/* integer type for AMD: int or SuiteSparse_long */
|
|
152
|
+
/* ------------------------------------------------------------------------- */
|
|
153
|
+
|
|
154
|
+
#include "amd.h"
|
|
155
|
+
|
|
156
|
+
#include <stdint.h>
|
|
157
|
+
|
|
158
|
+
#define Int scs_int
|
|
159
|
+
#define uInt uint64_t
|
|
160
|
+
#define ID "%d"
|
|
161
|
+
#define Int_MAX INT_MAX
|
|
162
|
+
|
|
163
|
+
#define AMD_order amd_order
|
|
164
|
+
#define AMD_defaults amd_defaults
|
|
165
|
+
#define AMD_control amd_control
|
|
166
|
+
#define AMD_info amd_info
|
|
167
|
+
#define AMD_1 amd_1
|
|
168
|
+
#define AMD_2 amd_2
|
|
169
|
+
#define AMD_valid amd_valid
|
|
170
|
+
#define AMD_aat amd_aat
|
|
171
|
+
#define AMD_postorder amd_postorder
|
|
172
|
+
#define AMD_post_tree amd_post_tree
|
|
173
|
+
#define AMD_dump amd_dump
|
|
174
|
+
#define AMD_debug amd_debug
|
|
175
|
+
#define AMD_debug_init amd_debug_init
|
|
176
|
+
#define AMD_preprocess amd_preprocess
|
|
177
|
+
|
|
178
|
+
/* ------------------------------------------------------------------------- */
|
|
179
|
+
/* AMD routine definitions (not user-callable) */
|
|
180
|
+
/* ------------------------------------------------------------------------- */
|
|
181
|
+
|
|
182
|
+
GLOBAL size_t AMD_aat
|
|
183
|
+
(
|
|
184
|
+
Int n,
|
|
185
|
+
const Int Ap [ ],
|
|
186
|
+
const Int Ai [ ],
|
|
187
|
+
Int Len [ ],
|
|
188
|
+
Int Tp [ ],
|
|
189
|
+
scs_float Info [ ]
|
|
190
|
+
) ;
|
|
191
|
+
|
|
192
|
+
GLOBAL void AMD_1
|
|
193
|
+
(
|
|
194
|
+
Int n,
|
|
195
|
+
const Int Ap [ ],
|
|
196
|
+
const Int Ai [ ],
|
|
197
|
+
Int P [ ],
|
|
198
|
+
Int Pinv [ ],
|
|
199
|
+
Int Len [ ],
|
|
200
|
+
Int slen,
|
|
201
|
+
Int S [ ],
|
|
202
|
+
scs_float Control [ ],
|
|
203
|
+
scs_float Info [ ]
|
|
204
|
+
) ;
|
|
205
|
+
|
|
206
|
+
GLOBAL void AMD_postorder
|
|
207
|
+
(
|
|
208
|
+
Int nn,
|
|
209
|
+
Int Parent [ ],
|
|
210
|
+
Int Npiv [ ],
|
|
211
|
+
Int Fsize [ ],
|
|
212
|
+
Int Order [ ],
|
|
213
|
+
Int Child [ ],
|
|
214
|
+
Int Sibling [ ],
|
|
215
|
+
Int Stack [ ]
|
|
216
|
+
) ;
|
|
217
|
+
|
|
218
|
+
GLOBAL Int AMD_post_tree
|
|
219
|
+
(
|
|
220
|
+
Int root,
|
|
221
|
+
Int k,
|
|
222
|
+
Int Child [ ],
|
|
223
|
+
const Int Sibling [ ],
|
|
224
|
+
Int Order [ ],
|
|
225
|
+
Int Stack [ ]
|
|
226
|
+
#ifndef NDEBUG
|
|
227
|
+
, Int nn
|
|
228
|
+
#endif
|
|
229
|
+
) ;
|
|
230
|
+
|
|
231
|
+
GLOBAL void AMD_preprocess
|
|
232
|
+
(
|
|
233
|
+
Int n,
|
|
234
|
+
const Int Ap [ ],
|
|
235
|
+
const Int Ai [ ],
|
|
236
|
+
Int Rp [ ],
|
|
237
|
+
Int Ri [ ],
|
|
238
|
+
Int W [ ],
|
|
239
|
+
Int Flag [ ]
|
|
240
|
+
) ;
|
|
241
|
+
|
|
242
|
+
/* ------------------------------------------------------------------------- */
|
|
243
|
+
/* debugging definitions */
|
|
244
|
+
/* ------------------------------------------------------------------------- */
|
|
245
|
+
|
|
246
|
+
#ifndef NDEBUG
|
|
247
|
+
|
|
248
|
+
/* from assert.h: assert macro */
|
|
249
|
+
#include <assert.h>
|
|
250
|
+
|
|
251
|
+
#ifndef EXTERN
|
|
252
|
+
#define EXTERN extern
|
|
253
|
+
#endif
|
|
254
|
+
|
|
255
|
+
EXTERN Int AMD_debug ;
|
|
256
|
+
|
|
257
|
+
GLOBAL void AMD_debug_init ( char *s ) ;
|
|
258
|
+
|
|
259
|
+
GLOBAL void AMD_dump
|
|
260
|
+
(
|
|
261
|
+
Int n,
|
|
262
|
+
Int Pe [ ],
|
|
263
|
+
Int Iw [ ],
|
|
264
|
+
Int Len [ ],
|
|
265
|
+
Int iwlen,
|
|
266
|
+
Int pfree,
|
|
267
|
+
Int Nv [ ],
|
|
268
|
+
Int Next [ ],
|
|
269
|
+
Int Last [ ],
|
|
270
|
+
Int Head [ ],
|
|
271
|
+
Int Elen [ ],
|
|
272
|
+
Int Degree [ ],
|
|
273
|
+
Int W [ ],
|
|
274
|
+
Int nel
|
|
275
|
+
) ;
|
|
276
|
+
|
|
277
|
+
#ifdef ASSERT
|
|
278
|
+
#undef ASSERT
|
|
279
|
+
#endif
|
|
280
|
+
|
|
281
|
+
/* Use mxAssert if AMD is compiled into a mexFunction */
|
|
282
|
+
#ifdef MATLAB_MEX_FILE
|
|
283
|
+
#define ASSERT(expression) (mxAssert ((expression), ""))
|
|
284
|
+
#else
|
|
285
|
+
#define ASSERT(expression) (assert (expression))
|
|
286
|
+
#endif
|
|
287
|
+
|
|
288
|
+
#define AMD_DEBUG0(params) { SUITESPARSE_PRINTF (params) ; }
|
|
289
|
+
#define AMD_DEBUG1(params) { if (AMD_debug >= 1) SUITESPARSE_PRINTF (params) ; }
|
|
290
|
+
#define AMD_DEBUG2(params) { if (AMD_debug >= 2) SUITESPARSE_PRINTF (params) ; }
|
|
291
|
+
#define AMD_DEBUG3(params) { if (AMD_debug >= 3) SUITESPARSE_PRINTF (params) ; }
|
|
292
|
+
#define AMD_DEBUG4(params) { if (AMD_debug >= 4) SUITESPARSE_PRINTF (params) ; }
|
|
293
|
+
|
|
294
|
+
#else
|
|
295
|
+
|
|
296
|
+
/* no debugging */
|
|
297
|
+
#define ASSERT(expression)
|
|
298
|
+
#define AMD_DEBUG0(params)
|
|
299
|
+
#define AMD_DEBUG1(params)
|
|
300
|
+
#define AMD_DEBUG2(params)
|
|
301
|
+
#define AMD_DEBUG3(params)
|
|
302
|
+
#define AMD_DEBUG4(params)
|
|
303
|
+
|
|
304
|
+
#endif
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/* ========================================================================= */
|
|
2
|
+
/* === AMD_order =========================================================== */
|
|
3
|
+
/* ========================================================================= */
|
|
4
|
+
|
|
5
|
+
/* ------------------------------------------------------------------------- */
|
|
6
|
+
/* AMD, Copyright (c) Timothy A. Davis, */
|
|
7
|
+
/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
|
|
8
|
+
/* email: DrTimothyAldenDavis@gmail.com */
|
|
9
|
+
/* ------------------------------------------------------------------------- */
|
|
10
|
+
|
|
11
|
+
/* User-callable AMD minimum degree ordering routine. See amd.h for
|
|
12
|
+
* documentation.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
#include "amd_internal.h"
|
|
16
|
+
|
|
17
|
+
/* ========================================================================= */
|
|
18
|
+
/* === AMD_order =========================================================== */
|
|
19
|
+
/* ========================================================================= */
|
|
20
|
+
|
|
21
|
+
GLOBAL Int AMD_order
|
|
22
|
+
(
|
|
23
|
+
Int n,
|
|
24
|
+
const Int Ap [ ],
|
|
25
|
+
const Int Ai [ ],
|
|
26
|
+
Int P [ ],
|
|
27
|
+
scs_float Control [ ],
|
|
28
|
+
scs_float Info [ ]
|
|
29
|
+
)
|
|
30
|
+
{
|
|
31
|
+
Int *Len, *S, nz, i, *Pinv, info, status, *Rp, *Ri, *Cp, *Ci, ok ;
|
|
32
|
+
size_t nzaat, slen ;
|
|
33
|
+
scs_float mem = 0 ;
|
|
34
|
+
|
|
35
|
+
#ifndef NDEBUG
|
|
36
|
+
AMD_debug_init ("amd") ;
|
|
37
|
+
#endif
|
|
38
|
+
|
|
39
|
+
/* clear the Info array, if it exists */
|
|
40
|
+
info = Info != (scs_float *) NULL ;
|
|
41
|
+
if (info)
|
|
42
|
+
{
|
|
43
|
+
for (i = 0 ; i < AMD_INFO ; i++)
|
|
44
|
+
{
|
|
45
|
+
Info [i] = EMPTY ;
|
|
46
|
+
}
|
|
47
|
+
Info [AMD_N] = n ;
|
|
48
|
+
Info [AMD_STATUS] = AMD_OK ;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* make sure inputs exist and n is >= 0 */
|
|
52
|
+
if (Ai == (Int *) NULL || Ap == (Int *) NULL || P == (Int *) NULL || n < 0)
|
|
53
|
+
{
|
|
54
|
+
if (info) Info [AMD_STATUS] = AMD_INVALID ;
|
|
55
|
+
return (AMD_INVALID) ; /* arguments are invalid */
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (n == 0)
|
|
59
|
+
{
|
|
60
|
+
return (AMD_OK) ; /* n is 0 so there's nothing to do */
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
nz = Ap [n] ;
|
|
64
|
+
if (info)
|
|
65
|
+
{
|
|
66
|
+
Info [AMD_NZ] = nz ;
|
|
67
|
+
}
|
|
68
|
+
if (nz < 0)
|
|
69
|
+
{
|
|
70
|
+
if (info) Info [AMD_STATUS] = AMD_INVALID ;
|
|
71
|
+
return (AMD_INVALID) ;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* check if n or nz will cause size_t overflow */
|
|
75
|
+
if (((size_t) n) >= SIZE_T_MAX / sizeof (Int)
|
|
76
|
+
|| ((size_t) nz) >= SIZE_T_MAX / sizeof (Int))
|
|
77
|
+
{
|
|
78
|
+
if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ;
|
|
79
|
+
return (AMD_OUT_OF_MEMORY) ; /* problem too large */
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* check the input matrix: AMD_OK, AMD_INVALID, or AMD_OK_BUT_JUMBLED */
|
|
83
|
+
status = AMD_valid (n, n, Ap, Ai) ;
|
|
84
|
+
|
|
85
|
+
if (status == AMD_INVALID)
|
|
86
|
+
{
|
|
87
|
+
if (info) Info [AMD_STATUS] = AMD_INVALID ;
|
|
88
|
+
return (AMD_INVALID) ; /* matrix is invalid */
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* allocate two size-n integer workspaces */
|
|
92
|
+
Len = SuiteSparse_malloc (n, sizeof (Int)) ;
|
|
93
|
+
Pinv = SuiteSparse_malloc (n, sizeof (Int)) ;
|
|
94
|
+
mem += n ;
|
|
95
|
+
mem += n ;
|
|
96
|
+
if (!Len || !Pinv)
|
|
97
|
+
{
|
|
98
|
+
/* :: out of memory :: */
|
|
99
|
+
SuiteSparse_free (Len) ;
|
|
100
|
+
SuiteSparse_free (Pinv) ;
|
|
101
|
+
if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ;
|
|
102
|
+
return (AMD_OUT_OF_MEMORY) ;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (status == AMD_OK_BUT_JUMBLED)
|
|
106
|
+
{
|
|
107
|
+
/* sort the input matrix and remove duplicate entries */
|
|
108
|
+
AMD_DEBUG1 (("Matrix is jumbled\n")) ;
|
|
109
|
+
Rp = SuiteSparse_malloc (n+1, sizeof (Int)) ;
|
|
110
|
+
Ri = SuiteSparse_malloc (nz, sizeof (Int)) ;
|
|
111
|
+
mem += (n+1) ;
|
|
112
|
+
mem += MAX (nz,1) ;
|
|
113
|
+
if (!Rp || !Ri)
|
|
114
|
+
{
|
|
115
|
+
/* :: out of memory :: */
|
|
116
|
+
SuiteSparse_free (Rp) ;
|
|
117
|
+
SuiteSparse_free (Ri) ;
|
|
118
|
+
SuiteSparse_free (Len) ;
|
|
119
|
+
SuiteSparse_free (Pinv) ;
|
|
120
|
+
if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ;
|
|
121
|
+
return (AMD_OUT_OF_MEMORY) ;
|
|
122
|
+
}
|
|
123
|
+
/* use Len and Pinv as workspace to create R = A' */
|
|
124
|
+
AMD_preprocess (n, Ap, Ai, Rp, Ri, Len, Pinv) ;
|
|
125
|
+
Cp = Rp ;
|
|
126
|
+
Ci = Ri ;
|
|
127
|
+
}
|
|
128
|
+
else
|
|
129
|
+
{
|
|
130
|
+
/* order the input matrix as-is. No need to compute R = A' first */
|
|
131
|
+
Rp = NULL ;
|
|
132
|
+
Ri = NULL ;
|
|
133
|
+
Cp = (Int *) Ap ;
|
|
134
|
+
Ci = (Int *) Ai ;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/* --------------------------------------------------------------------- */
|
|
138
|
+
/* determine the symmetry and count off-diagonal nonzeros in A+A' */
|
|
139
|
+
/* --------------------------------------------------------------------- */
|
|
140
|
+
|
|
141
|
+
nzaat = AMD_aat (n, Cp, Ci, Len, P, Info) ;
|
|
142
|
+
AMD_DEBUG1 (("nzaat: %g\n", (scs_float) nzaat)) ;
|
|
143
|
+
ASSERT ((MAX (nz-n, 0) <= nzaat) && (nzaat <= 2 * (size_t) nz)) ;
|
|
144
|
+
|
|
145
|
+
/* --------------------------------------------------------------------- */
|
|
146
|
+
/* allocate workspace for matrix, elbow room, and 6 size-n vectors */
|
|
147
|
+
/* --------------------------------------------------------------------- */
|
|
148
|
+
|
|
149
|
+
S = NULL ;
|
|
150
|
+
slen = nzaat ; /* space for matrix */
|
|
151
|
+
ok = ((slen + nzaat/5) >= slen) ; /* check for size_t overflow */
|
|
152
|
+
slen += nzaat/5 ; /* add elbow room */
|
|
153
|
+
for (i = 0 ; ok && i < 7 ; i++)
|
|
154
|
+
{
|
|
155
|
+
ok = ((slen + n) > slen) ; /* check for size_t overflow */
|
|
156
|
+
slen += n ; /* size-n elbow room, 6 size-n work */
|
|
157
|
+
}
|
|
158
|
+
mem += slen ;
|
|
159
|
+
ok = ok && (slen < SIZE_T_MAX / sizeof (Int)) ; /* check for overflow */
|
|
160
|
+
ok = ok && (slen < Int_MAX) ; /* S[i] for Int i must be OK */
|
|
161
|
+
if (ok)
|
|
162
|
+
{
|
|
163
|
+
S = SuiteSparse_malloc (slen, sizeof (Int)) ;
|
|
164
|
+
}
|
|
165
|
+
AMD_DEBUG1 (("slen %g\n", (scs_float) slen)) ;
|
|
166
|
+
if (!S)
|
|
167
|
+
{
|
|
168
|
+
/* :: out of memory :: (or problem too large) */
|
|
169
|
+
SuiteSparse_free (Rp) ;
|
|
170
|
+
SuiteSparse_free (Ri) ;
|
|
171
|
+
SuiteSparse_free (Len) ;
|
|
172
|
+
SuiteSparse_free (Pinv) ;
|
|
173
|
+
if (info) Info [AMD_STATUS] = AMD_OUT_OF_MEMORY ;
|
|
174
|
+
return (AMD_OUT_OF_MEMORY) ;
|
|
175
|
+
}
|
|
176
|
+
if (info)
|
|
177
|
+
{
|
|
178
|
+
/* memory usage, in bytes. */
|
|
179
|
+
Info [AMD_MEMORY] = mem * sizeof (Int) ;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* --------------------------------------------------------------------- */
|
|
183
|
+
/* order the matrix */
|
|
184
|
+
/* --------------------------------------------------------------------- */
|
|
185
|
+
|
|
186
|
+
AMD_1 (n, Cp, Ci, P, Pinv, Len, slen, S, Control, Info) ;
|
|
187
|
+
|
|
188
|
+
/* --------------------------------------------------------------------- */
|
|
189
|
+
/* free the workspace */
|
|
190
|
+
/* --------------------------------------------------------------------- */
|
|
191
|
+
|
|
192
|
+
SuiteSparse_free (Rp) ;
|
|
193
|
+
SuiteSparse_free (Ri) ;
|
|
194
|
+
SuiteSparse_free (Len) ;
|
|
195
|
+
SuiteSparse_free (Pinv) ;
|
|
196
|
+
SuiteSparse_free (S) ;
|
|
197
|
+
if (info) Info [AMD_STATUS] = status ;
|
|
198
|
+
return (status) ; /* successful ordering */
|
|
199
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/* ========================================================================= */
|
|
2
|
+
/* === AMD_post_tree ======================================================= */
|
|
3
|
+
/* ========================================================================= */
|
|
4
|
+
|
|
5
|
+
/* ------------------------------------------------------------------------- */
|
|
6
|
+
/* AMD, Copyright (c) Timothy A. Davis, */
|
|
7
|
+
/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */
|
|
8
|
+
/* email: DrTimothyAldenDavis@gmail.com */
|
|
9
|
+
/* ------------------------------------------------------------------------- */
|
|
10
|
+
|
|
11
|
+
/* Post-ordering of a supernodal elimination tree. */
|
|
12
|
+
|
|
13
|
+
#include "amd_internal.h"
|
|
14
|
+
|
|
15
|
+
GLOBAL Int AMD_post_tree
|
|
16
|
+
(
|
|
17
|
+
Int root, /* root of the tree */
|
|
18
|
+
Int k, /* start numbering at k */
|
|
19
|
+
Int Child [ ], /* input argument of size nn, undefined on
|
|
20
|
+
* output. Child [i] is the head of a link
|
|
21
|
+
* list of all nodes that are children of node
|
|
22
|
+
* i in the tree. */
|
|
23
|
+
const Int Sibling [ ], /* input argument of size nn, not modified.
|
|
24
|
+
* If f is a node in the link list of the
|
|
25
|
+
* children of node i, then Sibling [f] is the
|
|
26
|
+
* next child of node i.
|
|
27
|
+
*/
|
|
28
|
+
Int Order [ ], /* output order, of size nn. Order [i] = k
|
|
29
|
+
* if node i is the kth node of the reordered
|
|
30
|
+
* tree. */
|
|
31
|
+
Int Stack [ ] /* workspace of size nn */
|
|
32
|
+
#ifndef NDEBUG
|
|
33
|
+
, Int nn /* nodes are in the range 0..nn-1. */
|
|
34
|
+
#endif
|
|
35
|
+
)
|
|
36
|
+
{
|
|
37
|
+
Int f, head, h, i ;
|
|
38
|
+
|
|
39
|
+
#if 0
|
|
40
|
+
/* --------------------------------------------------------------------- */
|
|
41
|
+
/* recursive version (Stack [ ] is not used): */
|
|
42
|
+
/* --------------------------------------------------------------------- */
|
|
43
|
+
|
|
44
|
+
/* this is simple, but can caouse stack overflow if nn is large */
|
|
45
|
+
i = root ;
|
|
46
|
+
for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
|
|
47
|
+
{
|
|
48
|
+
k = AMD_post_tree (f, k, Child, Sibling, Order, Stack, nn) ;
|
|
49
|
+
}
|
|
50
|
+
Order [i] = k++ ;
|
|
51
|
+
return (k) ;
|
|
52
|
+
#endif
|
|
53
|
+
|
|
54
|
+
/* --------------------------------------------------------------------- */
|
|
55
|
+
/* non-recursive version, using an explicit stack */
|
|
56
|
+
/* --------------------------------------------------------------------- */
|
|
57
|
+
|
|
58
|
+
/* push root on the stack */
|
|
59
|
+
head = 0 ;
|
|
60
|
+
Stack [0] = root ;
|
|
61
|
+
|
|
62
|
+
while (head >= 0)
|
|
63
|
+
{
|
|
64
|
+
/* get head of stack */
|
|
65
|
+
ASSERT (head < nn) ;
|
|
66
|
+
i = Stack [head] ;
|
|
67
|
+
AMD_DEBUG1 (("head of stack "ID" \n", i)) ;
|
|
68
|
+
ASSERT (i >= 0 && i < nn) ;
|
|
69
|
+
|
|
70
|
+
if (Child [i] != EMPTY)
|
|
71
|
+
{
|
|
72
|
+
/* the children of i are not yet ordered */
|
|
73
|
+
/* push each child onto the stack in reverse order */
|
|
74
|
+
/* so that small ones at the head of the list get popped first */
|
|
75
|
+
/* and the biggest one at the end of the list gets popped last */
|
|
76
|
+
for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
|
|
77
|
+
{
|
|
78
|
+
head++ ;
|
|
79
|
+
ASSERT (head < nn) ;
|
|
80
|
+
ASSERT (f >= 0 && f < nn) ;
|
|
81
|
+
}
|
|
82
|
+
h = head ;
|
|
83
|
+
ASSERT (head < nn) ;
|
|
84
|
+
for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
|
|
85
|
+
{
|
|
86
|
+
ASSERT (h > 0) ;
|
|
87
|
+
Stack [h--] = f ;
|
|
88
|
+
AMD_DEBUG1 (("push "ID" on stack\n", f)) ;
|
|
89
|
+
ASSERT (f >= 0 && f < nn) ;
|
|
90
|
+
}
|
|
91
|
+
ASSERT (Stack [h] == i) ;
|
|
92
|
+
|
|
93
|
+
/* delete child list so that i gets ordered next time we see it */
|
|
94
|
+
Child [i] = EMPTY ;
|
|
95
|
+
}
|
|
96
|
+
else
|
|
97
|
+
{
|
|
98
|
+
/* the children of i (if there were any) are already ordered */
|
|
99
|
+
/* remove i from the stack and order it. Front i is kth front */
|
|
100
|
+
head-- ;
|
|
101
|
+
AMD_DEBUG1 (("pop "ID" order "ID"\n", i, k)) ;
|
|
102
|
+
Order [i] = k++ ;
|
|
103
|
+
ASSERT (k <= nn) ;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#ifndef NDEBUG
|
|
107
|
+
AMD_DEBUG1 (("\nStack:")) ;
|
|
108
|
+
for (h = head ; h >= 0 ; h--)
|
|
109
|
+
{
|
|
110
|
+
Int j = Stack [h] ;
|
|
111
|
+
AMD_DEBUG1 ((" "ID, j)) ;
|
|
112
|
+
ASSERT (j >= 0 && j < nn) ;
|
|
113
|
+
}
|
|
114
|
+
AMD_DEBUG1 (("\n\n")) ;
|
|
115
|
+
ASSERT (head < nn) ;
|
|
116
|
+
#endif
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
return (k) ;
|
|
120
|
+
}
|
|
Binary file
|