comparison src/DLD-FUNCTIONS/colamd.cc @ 7924:4976f66d469b

miscellaneous cleanup
author John W. Eaton <jwe@octave.org>
date Fri, 11 Jul 2008 17:59:28 -0400
parents b166043585a8
children 25bc2d31e1bf
comparison
equal deleted inserted replaced
7923:c3d21b9b94b6 7924:4976f66d469b
51 #define SYMAMD_NAME(name) symamd ## name 51 #define SYMAMD_NAME(name) symamd ## name
52 #endif 52 #endif
53 53
54 // The symmetric column elimination tree code take from the Davis LDL code. 54 // The symmetric column elimination tree code take from the Davis LDL code.
55 // Copyright given elsewhere in this file. 55 // Copyright given elsewhere in this file.
56 static 56 static void
57 void symetree (const octave_idx_type *ridx, const octave_idx_type *cidx, 57 symetree (const octave_idx_type *ridx, const octave_idx_type *cidx,
58 octave_idx_type *Parent, octave_idx_type *P, octave_idx_type n) 58 octave_idx_type *Parent, octave_idx_type *P, octave_idx_type n)
59 { 59 {
60 OCTAVE_LOCAL_BUFFER (octave_idx_type, Flag, n); 60 OCTAVE_LOCAL_BUFFER (octave_idx_type, Flag, n);
61 OCTAVE_LOCAL_BUFFER (octave_idx_type, Pinv, (P ? n : 0)); 61 OCTAVE_LOCAL_BUFFER (octave_idx_type, Pinv, (P ? n : 0));
62 if (P) 62 if (P)
63 // If P is present then compute Pinv, the inverse of P 63 // If P is present then compute Pinv, the inverse of P
89 } 89 }
90 } 90 }
91 } 91 }
92 92
93 // The elimination tree post-ordering code below is taken from SuperLU 93 // The elimination tree post-ordering code below is taken from SuperLU
94 static inline 94 static inline octave_idx_type
95 octave_idx_type make_set (octave_idx_type i, octave_idx_type *pp) 95 make_set (octave_idx_type i, octave_idx_type *pp)
96 { 96 {
97 pp[i] = i; 97 pp[i] = i;
98 return i; 98 return i;
99 } 99 }
100 100
101 static inline 101 static inline octave_idx_type
102 octave_idx_type link (octave_idx_type s, octave_idx_type t, octave_idx_type *pp) 102 link (octave_idx_type s, octave_idx_type t, octave_idx_type *pp)
103 { 103 {
104 pp[s] = t; 104 pp[s] = t;
105 return t; 105 return t;
106 } 106 }
107 107
108 static inline 108 static inline octave_idx_type
109 octave_idx_type find (octave_idx_type i, octave_idx_type *pp) 109 find (octave_idx_type i, octave_idx_type *pp)
110 { 110 {
111 register octave_idx_type p, gp; 111 register octave_idx_type p, gp;
112 112
113 p = pp[i]; 113 p = pp[i];
114 gp = pp[p]; 114 gp = pp[p];
115 while (gp != p) { 115
116 pp[i] = gp; 116 while (gp != p)
117 i = gp; 117 {
118 p = pp[i]; 118 pp[i] = gp;
119 gp = pp[p]; 119 i = gp;
120 } 120 p = pp[i];
121 return (p); 121 gp = pp[p];
122 } 122 }
123 123
124 static 124 return p;
125 octave_idx_type etdfs (octave_idx_type v, octave_idx_type *first_kid, 125 }
126 octave_idx_type *next_kid, octave_idx_type *post, 126
127 octave_idx_type postnum) 127 static octave_idx_type
128 { 128 etdfs (octave_idx_type v, octave_idx_type *first_kid,
129 for (octave_idx_type w = first_kid[v]; w != -1; w = next_kid[w]) { 129 octave_idx_type *next_kid, octave_idx_type *post,
130 octave_idx_type postnum)
131 {
132 for (octave_idx_type w = first_kid[v]; w != -1; w = next_kid[w])
130 postnum = etdfs (w, first_kid, next_kid, post, postnum); 133 postnum = etdfs (w, first_kid, next_kid, post, postnum);
131 } 134
132 post[postnum++] = v; 135 post[postnum++] = v;
133 136
134 return postnum; 137 return postnum;
135 } 138 }
136 139
137 static 140 static void
138 void TreePostorder(octave_idx_type n, octave_idx_type *parent, octave_idx_type *post) 141 tree_postorder (octave_idx_type n, octave_idx_type *parent,
142 octave_idx_type *post)
139 { 143 {
140 // Allocate storage for working arrays and results 144 // Allocate storage for working arrays and results
141 OCTAVE_LOCAL_BUFFER (octave_idx_type, first_kid, n+1); 145 OCTAVE_LOCAL_BUFFER (octave_idx_type, first_kid, n+1);
142 OCTAVE_LOCAL_BUFFER (octave_idx_type, next_kid, n+1); 146 OCTAVE_LOCAL_BUFFER (octave_idx_type, next_kid, n+1);
143 147
144 // Set up structure describing children 148 // Set up structure describing children
145 for (octave_idx_type v = 0; v <= n; first_kid[v++] = -1); 149 for (octave_idx_type v = 0; v <= n; first_kid[v++] = -1)
150 /* do nothing */;
151
146 for (octave_idx_type v = n-1; v >= 0; v--) 152 for (octave_idx_type v = n-1; v >= 0; v--)
147 { 153 {
148 octave_idx_type dad = parent[v]; 154 octave_idx_type dad = parent[v];
149 next_kid[v] = first_kid[dad]; 155 next_kid[v] = first_kid[dad];
150 first_kid[dad] = v; 156 first_kid[dad] = v;
152 158
153 // Depth-first search from dummy root vertex #n 159 // Depth-first search from dummy root vertex #n
154 etdfs (n, first_kid, next_kid, post, 0); 160 etdfs (n, first_kid, next_kid, post, 0);
155 } 161 }
156 162
157 static 163 static void
158 void coletree (const octave_idx_type *ridx, const octave_idx_type *colbeg, 164 coletree (const octave_idx_type *ridx, const octave_idx_type *colbeg,
159 octave_idx_type *colend, octave_idx_type *parent, 165 octave_idx_type *colend, octave_idx_type *parent,
160 octave_idx_type nr, octave_idx_type nc) 166 octave_idx_type nr, octave_idx_type nc)
161 { 167 {
162 OCTAVE_LOCAL_BUFFER (octave_idx_type, root, nc); 168 OCTAVE_LOCAL_BUFFER (octave_idx_type, root, nc);
163 OCTAVE_LOCAL_BUFFER (octave_idx_type, pp, nc); 169 OCTAVE_LOCAL_BUFFER (octave_idx_type, pp, nc);
164 OCTAVE_LOCAL_BUFFER (octave_idx_type, firstcol, nr); 170 OCTAVE_LOCAL_BUFFER (octave_idx_type, firstcol, nr);
165 171
166 // Compute firstcol[row] = first nonzero column in row 172 // Compute firstcol[row] = first nonzero column in row
167 for (octave_idx_type row = 0; row < nr; firstcol[row++] = nc); 173 for (octave_idx_type row = 0; row < nr; firstcol[row++] = nc)
174 /* do nothing */;
175
168 for (octave_idx_type col = 0; col < nc; col++) 176 for (octave_idx_type col = 0; col < nc; col++)
169 for (octave_idx_type p = colbeg[col]; p < colend[col]; p++) 177 for (octave_idx_type p = colbeg[col]; p < colend[col]; p++)
170 { 178 {
171 octave_idx_type row = ridx[p]; 179 octave_idx_type row = ridx[p];
172 if (firstcol[row] > col) 180 if (firstcol[row] > col)
398 } 406 }
399 407
400 coletree (ridx, colbeg, colend, etree, n_row, n_col); 408 coletree (ridx, colbeg, colend, etree, n_row, n_col);
401 409
402 // Calculate the tree post-ordering 410 // Calculate the tree post-ordering
403 TreePostorder (n_col, etree, colbeg); 411 tree_postorder (n_col, etree, colbeg);
404 412
405 // return the permutation vector 413 // return the permutation vector
406 NDArray out_perm (dim_vector (1, n_col)); 414 NDArray out_perm (dim_vector (1, n_col));
407 for (octave_idx_type i = 0; i < n_col; i++) 415 for (octave_idx_type i = 0; i < n_col; i++)
408 out_perm(i) = p [colbeg [i]] + 1; 416 out_perm(i) = p [colbeg [i]] + 1;
409 417
410 retval (0) = out_perm; 418 retval(0) = out_perm;
411 419
412 // print stats if spumoni > 0 420 // print stats if spumoni > 0
413 if (spumoni > 0) 421 if (spumoni > 0)
414 COLAMD_NAME (_report) (stats) ; 422 COLAMD_NAME (_report) (stats) ;
415 423
595 OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1); 603 OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
596 symetree (ridx, cidx, etree, perm, n_col); 604 symetree (ridx, cidx, etree, perm, n_col);
597 605
598 // Calculate the tree post-ordering 606 // Calculate the tree post-ordering
599 OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1); 607 OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
600 TreePostorder (n_col, etree, post); 608 tree_postorder (n_col, etree, post);
601 609
602 // return the permutation vector 610 // return the permutation vector
603 NDArray out_perm (dim_vector (1, n_col)); 611 NDArray out_perm (dim_vector (1, n_col));
604 for (octave_idx_type i = 0; i < n_col; i++) 612 for (octave_idx_type i = 0; i < n_col; i++)
605 out_perm(i) = perm [post [i]] + 1; 613 out_perm(i) = perm [post [i]] + 1;
606 614
607 retval (0) = out_perm; 615 retval(0) = out_perm;
608 616
609 // print stats if spumoni > 0 617 // print stats if spumoni > 0
610 if (spumoni > 0) 618 if (spumoni > 0)
611 SYMAMD_NAME (_report) (stats) ; 619 SYMAMD_NAME (_report) (stats) ;
612 620
705 { 713 {
706 error ("etree: second argument must be a string"); 714 error ("etree: second argument must be a string");
707 return retval; 715 return retval;
708 } 716 }
709 } 717 }
718
710 // column elimination tree post-ordering (reuse variables) 719 // column elimination tree post-ordering (reuse variables)
711 OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1); 720 OCTAVE_LOCAL_BUFFER (octave_idx_type, etree, n_col + 1);
712
713 721
714 if (is_sym) 722 if (is_sym)
715 { 723 {
716 if (n_row != n_col) 724 if (n_row != n_col)
717 { 725 {
718 error ("etree: matrix is marked as symmetric, but not square"); 726 error ("etree: matrix is marked as symmetric, but not square");
719 return retval; 727 return retval;
720 } 728 }
729
721 symetree (ridx, cidx, etree, 0, n_col); 730 symetree (ridx, cidx, etree, 0, n_col);
722 } 731 }
723 else 732 else
724 { 733 {
725 OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col); 734 OCTAVE_LOCAL_BUFFER (octave_idx_type, colbeg, n_col);
737 NDArray tree (dim_vector (1, n_col)); 746 NDArray tree (dim_vector (1, n_col));
738 for (octave_idx_type i = 0; i < n_col; i++) 747 for (octave_idx_type i = 0; i < n_col; i++)
739 // We flag a root with n_col while Matlab does it with zero 748 // We flag a root with n_col while Matlab does it with zero
740 // Convert for matlab compatiable output 749 // Convert for matlab compatiable output
741 if (etree[i] == n_col) 750 if (etree[i] == n_col)
742 tree (i) = 0; 751 tree(i) = 0;
743 else 752 else
744 tree (i) = etree[i] + 1; 753 tree(i) = etree[i] + 1;
745 754
746 retval (0) = tree; 755 retval(0) = tree;
747 756
748 if (nargout == 2) 757 if (nargout == 2)
749 { 758 {
750 // Calculate the tree post-ordering 759 // Calculate the tree post-ordering
751 OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1); 760 OCTAVE_LOCAL_BUFFER (octave_idx_type, post, n_col + 1);
752 TreePostorder (n_col, etree, post); 761 tree_postorder (n_col, etree, post);
753 762
754 NDArray postorder (dim_vector (1, n_col)); 763 NDArray postorder (dim_vector (1, n_col));
755 for (octave_idx_type i = 0; i < n_col; i++) 764 for (octave_idx_type i = 0; i < n_col; i++)
756 postorder (i) = post[i] + 1; 765 postorder(i) = post[i] + 1;
757 766
758 retval (1) = postorder; 767 retval(1) = postorder;
759 } 768 }
760 } 769 }
761 770
762 return retval; 771 return retval;
763 } 772 }