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.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +12 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +98 -0
  5. data/ext/scs/extconf.rb +29 -0
  6. data/lib/scs.rb +17 -0
  7. data/lib/scs/ffi.rb +117 -0
  8. data/lib/scs/solver.rb +173 -0
  9. data/lib/scs/version.rb +3 -0
  10. data/vendor/scs/LICENSE.txt +21 -0
  11. data/vendor/scs/Makefile +164 -0
  12. data/vendor/scs/README.md +222 -0
  13. data/vendor/scs/include/aa.h +56 -0
  14. data/vendor/scs/include/cones.h +46 -0
  15. data/vendor/scs/include/ctrlc.h +33 -0
  16. data/vendor/scs/include/glbopts.h +177 -0
  17. data/vendor/scs/include/linalg.h +26 -0
  18. data/vendor/scs/include/linsys.h +64 -0
  19. data/vendor/scs/include/normalize.h +18 -0
  20. data/vendor/scs/include/rw.h +17 -0
  21. data/vendor/scs/include/scs.h +161 -0
  22. data/vendor/scs/include/scs_blas.h +51 -0
  23. data/vendor/scs/include/util.h +65 -0
  24. data/vendor/scs/linsys/amatrix.c +305 -0
  25. data/vendor/scs/linsys/amatrix.h +36 -0
  26. data/vendor/scs/linsys/amatrix.o +0 -0
  27. data/vendor/scs/linsys/cpu/direct/private.c +366 -0
  28. data/vendor/scs/linsys/cpu/direct/private.h +26 -0
  29. data/vendor/scs/linsys/cpu/direct/private.o +0 -0
  30. data/vendor/scs/linsys/cpu/indirect/private.c +256 -0
  31. data/vendor/scs/linsys/cpu/indirect/private.h +31 -0
  32. data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
  33. data/vendor/scs/linsys/external/amd/LICENSE.txt +934 -0
  34. data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +469 -0
  35. data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +254 -0
  36. data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
  37. data/vendor/scs/linsys/external/amd/amd.h +400 -0
  38. data/vendor/scs/linsys/external/amd/amd_1.c +180 -0
  39. data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
  40. data/vendor/scs/linsys/external/amd/amd_2.c +1842 -0
  41. data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
  42. data/vendor/scs/linsys/external/amd/amd_aat.c +184 -0
  43. data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
  44. data/vendor/scs/linsys/external/amd/amd_control.c +64 -0
  45. data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
  46. data/vendor/scs/linsys/external/amd/amd_defaults.c +37 -0
  47. data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
  48. data/vendor/scs/linsys/external/amd/amd_dump.c +179 -0
  49. data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
  50. data/vendor/scs/linsys/external/amd/amd_global.c +16 -0
  51. data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
  52. data/vendor/scs/linsys/external/amd/amd_info.c +119 -0
  53. data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
  54. data/vendor/scs/linsys/external/amd/amd_internal.h +304 -0
  55. data/vendor/scs/linsys/external/amd/amd_order.c +199 -0
  56. data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
  57. data/vendor/scs/linsys/external/amd/amd_post_tree.c +120 -0
  58. data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
  59. data/vendor/scs/linsys/external/amd/amd_postorder.c +206 -0
  60. data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
  61. data/vendor/scs/linsys/external/amd/amd_preprocess.c +118 -0
  62. data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
  63. data/vendor/scs/linsys/external/amd/amd_valid.c +92 -0
  64. data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
  65. data/vendor/scs/linsys/external/amd/changes +11 -0
  66. data/vendor/scs/linsys/external/qdldl/LICENSE +201 -0
  67. data/vendor/scs/linsys/external/qdldl/README.md +120 -0
  68. data/vendor/scs/linsys/external/qdldl/changes +4 -0
  69. data/vendor/scs/linsys/external/qdldl/qdldl.c +298 -0
  70. data/vendor/scs/linsys/external/qdldl/qdldl.h +177 -0
  71. data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
  72. data/vendor/scs/linsys/external/qdldl/qdldl_types.h +21 -0
  73. data/vendor/scs/linsys/gpu/gpu.c +41 -0
  74. data/vendor/scs/linsys/gpu/gpu.h +85 -0
  75. data/vendor/scs/linsys/gpu/indirect/private.c +304 -0
  76. data/vendor/scs/linsys/gpu/indirect/private.h +36 -0
  77. data/vendor/scs/scs.mk +181 -0
  78. data/vendor/scs/src/aa.c +224 -0
  79. data/vendor/scs/src/aa.o +0 -0
  80. data/vendor/scs/src/cones.c +802 -0
  81. data/vendor/scs/src/cones.o +0 -0
  82. data/vendor/scs/src/ctrlc.c +77 -0
  83. data/vendor/scs/src/ctrlc.o +0 -0
  84. data/vendor/scs/src/linalg.c +84 -0
  85. data/vendor/scs/src/linalg.o +0 -0
  86. data/vendor/scs/src/normalize.c +93 -0
  87. data/vendor/scs/src/normalize.o +0 -0
  88. data/vendor/scs/src/rw.c +167 -0
  89. data/vendor/scs/src/rw.o +0 -0
  90. data/vendor/scs/src/scs.c +978 -0
  91. data/vendor/scs/src/scs.o +0 -0
  92. data/vendor/scs/src/scs_version.c +5 -0
  93. data/vendor/scs/src/scs_version.o +0 -0
  94. data/vendor/scs/src/util.c +196 -0
  95. data/vendor/scs/src/util.o +0 -0
  96. data/vendor/scs/test/data/small_random_socp +0 -0
  97. data/vendor/scs/test/minunit.h +13 -0
  98. data/vendor/scs/test/problem_utils.h +93 -0
  99. data/vendor/scs/test/problems/rob_gauss_cov_est.h +85 -0
  100. data/vendor/scs/test/problems/small_lp.h +50 -0
  101. data/vendor/scs/test/problems/small_random_socp.h +33 -0
  102. data/vendor/scs/test/random_socp_prob.c +171 -0
  103. data/vendor/scs/test/run_from_file.c +69 -0
  104. data/vendor/scs/test/run_tests +2 -0
  105. data/vendor/scs/test/run_tests.c +32 -0
  106. metadata +203 -0
@@ -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
+ }
@@ -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
+ }
@@ -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
+ }