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
|
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
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/* ========================================================================= */
|
|
2
|
+
/* === AMD_postorder ======================================================= */
|
|
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
|
+
/* Perform a postordering (via depth-first search) of an assembly tree. */
|
|
12
|
+
|
|
13
|
+
#include "amd_internal.h"
|
|
14
|
+
|
|
15
|
+
GLOBAL void AMD_postorder
|
|
16
|
+
(
|
|
17
|
+
/* inputs, not modified on output: */
|
|
18
|
+
Int nn, /* nodes are in the range 0..nn-1 */
|
|
19
|
+
Int Parent [ ], /* Parent [j] is the parent of j, or EMPTY if root */
|
|
20
|
+
Int Nv [ ], /* Nv [j] > 0 number of pivots represented by node j,
|
|
21
|
+
* or zero if j is not a node. */
|
|
22
|
+
Int Fsize [ ], /* Fsize [j]: size of node j */
|
|
23
|
+
|
|
24
|
+
/* output, not defined on input: */
|
|
25
|
+
Int Order [ ], /* output post-order */
|
|
26
|
+
|
|
27
|
+
/* workspaces of size nn: */
|
|
28
|
+
Int Child [ ],
|
|
29
|
+
Int Sibling [ ],
|
|
30
|
+
Int Stack [ ]
|
|
31
|
+
)
|
|
32
|
+
{
|
|
33
|
+
Int i, j, k, parent, frsize, f, fprev, maxfrsize, bigfprev, bigf, fnext ;
|
|
34
|
+
|
|
35
|
+
for (j = 0 ; j < nn ; j++)
|
|
36
|
+
{
|
|
37
|
+
Child [j] = EMPTY ;
|
|
38
|
+
Sibling [j] = EMPTY ;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* --------------------------------------------------------------------- */
|
|
42
|
+
/* place the children in link lists - bigger elements tend to be last */
|
|
43
|
+
/* --------------------------------------------------------------------- */
|
|
44
|
+
|
|
45
|
+
for (j = nn-1 ; j >= 0 ; j--)
|
|
46
|
+
{
|
|
47
|
+
if (Nv [j] > 0)
|
|
48
|
+
{
|
|
49
|
+
/* this is an element */
|
|
50
|
+
parent = Parent [j] ;
|
|
51
|
+
if (parent != EMPTY)
|
|
52
|
+
{
|
|
53
|
+
/* place the element in link list of the children its parent */
|
|
54
|
+
/* bigger elements will tend to be at the end of the list */
|
|
55
|
+
Sibling [j] = Child [parent] ;
|
|
56
|
+
Child [parent] = j ;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
#ifndef NDEBUG
|
|
62
|
+
{
|
|
63
|
+
Int nels, ff, nchild ;
|
|
64
|
+
AMD_DEBUG1 (("\n\n================================ AMD_postorder:\n"));
|
|
65
|
+
nels = 0 ;
|
|
66
|
+
for (j = 0 ; j < nn ; j++)
|
|
67
|
+
{
|
|
68
|
+
if (Nv [j] > 0)
|
|
69
|
+
{
|
|
70
|
+
AMD_DEBUG1 (( ""ID" : nels "ID" npiv "ID" size "ID
|
|
71
|
+
" parent "ID" maxfr "ID"\n", j, nels,
|
|
72
|
+
Nv [j], Fsize [j], Parent [j], Fsize [j])) ;
|
|
73
|
+
/* this is an element */
|
|
74
|
+
/* dump the link list of children */
|
|
75
|
+
nchild = 0 ;
|
|
76
|
+
AMD_DEBUG1 ((" Children: ")) ;
|
|
77
|
+
for (ff = Child [j] ; ff != EMPTY ; ff = Sibling [ff])
|
|
78
|
+
{
|
|
79
|
+
AMD_DEBUG1 ((ID" ", ff)) ;
|
|
80
|
+
ASSERT (Parent [ff] == j) ;
|
|
81
|
+
nchild++ ;
|
|
82
|
+
ASSERT (nchild < nn) ;
|
|
83
|
+
}
|
|
84
|
+
AMD_DEBUG1 (("\n")) ;
|
|
85
|
+
parent = Parent [j] ;
|
|
86
|
+
if (parent != EMPTY)
|
|
87
|
+
{
|
|
88
|
+
ASSERT (Nv [parent] > 0) ;
|
|
89
|
+
}
|
|
90
|
+
nels++ ;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
AMD_DEBUG1 (("\n\nGo through the children of each node, and put\n"
|
|
95
|
+
"the biggest child last in each list:\n")) ;
|
|
96
|
+
#endif
|
|
97
|
+
|
|
98
|
+
/* --------------------------------------------------------------------- */
|
|
99
|
+
/* place the largest child last in the list of children for each node */
|
|
100
|
+
/* --------------------------------------------------------------------- */
|
|
101
|
+
|
|
102
|
+
for (i = 0 ; i < nn ; i++)
|
|
103
|
+
{
|
|
104
|
+
if (Nv [i] > 0 && Child [i] != EMPTY)
|
|
105
|
+
{
|
|
106
|
+
|
|
107
|
+
#ifndef NDEBUG
|
|
108
|
+
Int nchild ;
|
|
109
|
+
AMD_DEBUG1 (("Before partial sort, element "ID"\n", i)) ;
|
|
110
|
+
nchild = 0 ;
|
|
111
|
+
for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
|
|
112
|
+
{
|
|
113
|
+
ASSERT (f >= 0 && f < nn) ;
|
|
114
|
+
AMD_DEBUG1 ((" f: "ID" size: "ID"\n", f, Fsize [f])) ;
|
|
115
|
+
nchild++ ;
|
|
116
|
+
ASSERT (nchild <= nn) ;
|
|
117
|
+
}
|
|
118
|
+
#endif
|
|
119
|
+
|
|
120
|
+
/* find the biggest element in the child list */
|
|
121
|
+
fprev = EMPTY ;
|
|
122
|
+
maxfrsize = EMPTY ;
|
|
123
|
+
bigfprev = EMPTY ;
|
|
124
|
+
bigf = EMPTY ;
|
|
125
|
+
for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
|
|
126
|
+
{
|
|
127
|
+
ASSERT (f >= 0 && f < nn) ;
|
|
128
|
+
frsize = Fsize [f] ;
|
|
129
|
+
if (frsize >= maxfrsize)
|
|
130
|
+
{
|
|
131
|
+
/* this is the biggest seen so far */
|
|
132
|
+
maxfrsize = frsize ;
|
|
133
|
+
bigfprev = fprev ;
|
|
134
|
+
bigf = f ;
|
|
135
|
+
}
|
|
136
|
+
fprev = f ;
|
|
137
|
+
}
|
|
138
|
+
ASSERT (bigf != EMPTY) ;
|
|
139
|
+
|
|
140
|
+
fnext = Sibling [bigf] ;
|
|
141
|
+
|
|
142
|
+
AMD_DEBUG1 (("bigf "ID" maxfrsize "ID" bigfprev "ID" fnext "ID
|
|
143
|
+
" fprev " ID"\n", bigf, maxfrsize, bigfprev, fnext, fprev)) ;
|
|
144
|
+
|
|
145
|
+
if (fnext != EMPTY)
|
|
146
|
+
{
|
|
147
|
+
/* if fnext is EMPTY then bigf is already at the end of list */
|
|
148
|
+
|
|
149
|
+
if (bigfprev == EMPTY)
|
|
150
|
+
{
|
|
151
|
+
/* delete bigf from the element of the list */
|
|
152
|
+
Child [i] = fnext ;
|
|
153
|
+
}
|
|
154
|
+
else
|
|
155
|
+
{
|
|
156
|
+
/* delete bigf from the middle of the list */
|
|
157
|
+
Sibling [bigfprev] = fnext ;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* put bigf at the end of the list */
|
|
161
|
+
Sibling [bigf] = EMPTY ;
|
|
162
|
+
ASSERT (Child [i] != EMPTY) ;
|
|
163
|
+
ASSERT (fprev != bigf) ;
|
|
164
|
+
ASSERT (fprev != EMPTY) ;
|
|
165
|
+
Sibling [fprev] = bigf ;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#ifndef NDEBUG
|
|
169
|
+
AMD_DEBUG1 (("After partial sort, element "ID"\n", i)) ;
|
|
170
|
+
for (f = Child [i] ; f != EMPTY ; f = Sibling [f])
|
|
171
|
+
{
|
|
172
|
+
ASSERT (f >= 0 && f < nn) ;
|
|
173
|
+
AMD_DEBUG1 ((" "ID" "ID"\n", f, Fsize [f])) ;
|
|
174
|
+
ASSERT (Nv [f] > 0) ;
|
|
175
|
+
nchild-- ;
|
|
176
|
+
}
|
|
177
|
+
ASSERT (nchild == 0) ;
|
|
178
|
+
#endif
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* --------------------------------------------------------------------- */
|
|
184
|
+
/* postorder the assembly tree */
|
|
185
|
+
/* --------------------------------------------------------------------- */
|
|
186
|
+
|
|
187
|
+
for (i = 0 ; i < nn ; i++)
|
|
188
|
+
{
|
|
189
|
+
Order [i] = EMPTY ;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
k = 0 ;
|
|
193
|
+
|
|
194
|
+
for (i = 0 ; i < nn ; i++)
|
|
195
|
+
{
|
|
196
|
+
if (Parent [i] == EMPTY && Nv [i] > 0)
|
|
197
|
+
{
|
|
198
|
+
AMD_DEBUG1 (("Root of assembly tree "ID"\n", i)) ;
|
|
199
|
+
k = AMD_post_tree (i, k, Child, Sibling, Order, Stack
|
|
200
|
+
#ifndef NDEBUG
|
|
201
|
+
, nn
|
|
202
|
+
#endif
|
|
203
|
+
) ;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* ========================================================================= */
|
|
2
|
+
/* === AMD_preprocess ====================================================== */
|
|
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
|
+
/* Sorts, removes duplicate entries, and transposes from the nonzero pattern of
|
|
12
|
+
* a column-form matrix A, to obtain the matrix R. The input matrix can have
|
|
13
|
+
* duplicate entries and/or unsorted columns (AMD_valid (n,Ap,Ai) must not be
|
|
14
|
+
* AMD_INVALID).
|
|
15
|
+
*
|
|
16
|
+
* This input condition is NOT checked. This routine is not user-callable.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include "amd_internal.h"
|
|
20
|
+
|
|
21
|
+
/* ========================================================================= */
|
|
22
|
+
/* === AMD_preprocess ====================================================== */
|
|
23
|
+
/* ========================================================================= */
|
|
24
|
+
|
|
25
|
+
/* AMD_preprocess does not check its input for errors or allocate workspace.
|
|
26
|
+
* On input, the condition (AMD_valid (n,n,Ap,Ai) != AMD_INVALID) must hold.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
GLOBAL void AMD_preprocess
|
|
30
|
+
(
|
|
31
|
+
Int n, /* input matrix: A is n-by-n */
|
|
32
|
+
const Int Ap [ ], /* size n+1 */
|
|
33
|
+
const Int Ai [ ], /* size nz = Ap [n] */
|
|
34
|
+
|
|
35
|
+
/* output matrix R: */
|
|
36
|
+
Int Rp [ ], /* size n+1 */
|
|
37
|
+
Int Ri [ ], /* size nz (or less, if duplicates present) */
|
|
38
|
+
|
|
39
|
+
Int W [ ], /* workspace of size n */
|
|
40
|
+
Int Flag [ ] /* workspace of size n */
|
|
41
|
+
)
|
|
42
|
+
{
|
|
43
|
+
|
|
44
|
+
/* --------------------------------------------------------------------- */
|
|
45
|
+
/* local variables */
|
|
46
|
+
/* --------------------------------------------------------------------- */
|
|
47
|
+
|
|
48
|
+
Int i, j, p, p2 ;
|
|
49
|
+
|
|
50
|
+
ASSERT (AMD_valid (n, n, Ap, Ai) != AMD_INVALID) ;
|
|
51
|
+
|
|
52
|
+
/* --------------------------------------------------------------------- */
|
|
53
|
+
/* count the entries in each row of A (excluding duplicates) */
|
|
54
|
+
/* --------------------------------------------------------------------- */
|
|
55
|
+
|
|
56
|
+
for (i = 0 ; i < n ; i++)
|
|
57
|
+
{
|
|
58
|
+
W [i] = 0 ; /* # of nonzeros in row i (excl duplicates) */
|
|
59
|
+
Flag [i] = EMPTY ; /* Flag [i] = j if i appears in column j */
|
|
60
|
+
}
|
|
61
|
+
for (j = 0 ; j < n ; j++)
|
|
62
|
+
{
|
|
63
|
+
p2 = Ap [j+1] ;
|
|
64
|
+
for (p = Ap [j] ; p < p2 ; p++)
|
|
65
|
+
{
|
|
66
|
+
i = Ai [p] ;
|
|
67
|
+
if (Flag [i] != j)
|
|
68
|
+
{
|
|
69
|
+
/* row index i has not yet appeared in column j */
|
|
70
|
+
W [i]++ ; /* one more entry in row i */
|
|
71
|
+
Flag [i] = j ; /* flag row index i as appearing in col j*/
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* --------------------------------------------------------------------- */
|
|
77
|
+
/* compute the row pointers for R */
|
|
78
|
+
/* --------------------------------------------------------------------- */
|
|
79
|
+
|
|
80
|
+
Rp [0] = 0 ;
|
|
81
|
+
for (i = 0 ; i < n ; i++)
|
|
82
|
+
{
|
|
83
|
+
Rp [i+1] = Rp [i] + W [i] ;
|
|
84
|
+
}
|
|
85
|
+
for (i = 0 ; i < n ; i++)
|
|
86
|
+
{
|
|
87
|
+
W [i] = Rp [i] ;
|
|
88
|
+
Flag [i] = EMPTY ;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* --------------------------------------------------------------------- */
|
|
92
|
+
/* construct the row form matrix R */
|
|
93
|
+
/* --------------------------------------------------------------------- */
|
|
94
|
+
|
|
95
|
+
/* R = row form of pattern of A */
|
|
96
|
+
for (j = 0 ; j < n ; j++)
|
|
97
|
+
{
|
|
98
|
+
p2 = Ap [j+1] ;
|
|
99
|
+
for (p = Ap [j] ; p < p2 ; p++)
|
|
100
|
+
{
|
|
101
|
+
i = Ai [p] ;
|
|
102
|
+
if (Flag [i] != j)
|
|
103
|
+
{
|
|
104
|
+
/* row index i has not yet appeared in column j */
|
|
105
|
+
Ri [W [i]++] = j ; /* put col j in row i */
|
|
106
|
+
Flag [i] = j ; /* flag row index i as appearing in col j*/
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
#ifndef NDEBUG
|
|
112
|
+
ASSERT (AMD_valid (n, n, Rp, Ri) == AMD_OK) ;
|
|
113
|
+
for (j = 0 ; j < n ; j++)
|
|
114
|
+
{
|
|
115
|
+
ASSERT (W [j] == Rp [j+1]) ;
|
|
116
|
+
}
|
|
117
|
+
#endif
|
|
118
|
+
}
|