00001
00002
00003
00004
00005 #include <stdio.h>
00006 #include "sparse_int.h"
00007
00008
00009
00010
00011
00012 sm_row *
00013 sm_row_alloc(void)
00014 {
00015 register sm_row *prow;
00016
00017 #ifdef FAST_AND_LOOSE
00018 if (sm_row_freelist == NIL(sm_row)) {
00019 prow = ALLOC(sm_row, 1);
00020 } else {
00021 prow = sm_row_freelist;
00022 sm_row_freelist = prow->next_row;
00023 }
00024 #else
00025 prow = ALLOC(sm_row, 1);
00026 #endif
00027
00028 prow->row_num = 0;
00029 prow->length = 0;
00030 prow->first_col = prow->last_col = NIL(sm_element);
00031 prow->next_row = prow->prev_row = NIL(sm_row);
00032 prow->flag = 0;
00033 prow->user_word = NIL(char);
00034 return prow;
00035 }
00036
00037
00038
00039
00040
00041
00042
00043
00044 void
00045 sm_row_free(sm_row *prow)
00046 {
00047 #if defined(FAST_AND_LOOSE) && ! defined(COLS)
00048 if (prow->first_col != NIL(sm_element)) {
00049
00050 prow->last_col->next_col = sm_element_freelist;
00051 sm_element_freelist = prow->first_col;
00052 }
00053
00054
00055 prow->next_row = sm_row_freelist;
00056 sm_row_freelist = prow;
00057 #else
00058 register sm_element *p, *pnext;
00059
00060 for(p = prow->first_col; p != 0; p = pnext) {
00061 pnext = p->next_col;
00062 sm_element_free(p);
00063 }
00064 FREE(prow);
00065 #endif
00066 }
00067
00068
00069
00070
00071
00072 sm_row *
00073 sm_row_dup(sm_row *prow)
00074 {
00075 register sm_row *pnew;
00076 register sm_element *p;
00077
00078 pnew = sm_row_alloc();
00079 for(p = prow->first_col; p != 0; p = p->next_col) {
00080 (void) sm_row_insert(pnew, p->col_num);
00081 }
00082 return pnew;
00083 }
00084
00085
00086
00087
00088
00089 sm_element *
00090 sm_row_insert(sm_row *prow, int col)
00091 {
00092 register sm_element *test, *element;
00093
00094
00095 sm_element_alloc(element);
00096 test = element;
00097 sorted_insert(sm_element, prow->first_col, prow->last_col, prow->length,
00098 next_col, prev_col, col_num, col, test);
00099
00100
00101 if (element != test) {
00102 sm_element_free(element);
00103 }
00104
00105
00106 return test;
00107 }
00108
00109
00110
00111
00112
00113 void
00114 sm_row_remove(sm_row *prow, int col)
00115 {
00116 register sm_element *p;
00117
00118 for(p = prow->first_col; p != 0 && p->col_num < col; p = p->next_col)
00119 ;
00120 if (p != 0 && p->col_num == col) {
00121 dll_unlink(p, prow->first_col, prow->last_col,
00122 next_col, prev_col, prow->length);
00123 sm_element_free(p);
00124 }
00125 }
00126
00127
00128
00129
00130
00131 sm_element *
00132 sm_row_find(sm_row *prow, int col)
00133 {
00134 register sm_element *p;
00135
00136 for(p = prow->first_col; p != 0 && p->col_num < col; p = p->next_col)
00137 ;
00138 if (p != 0 && p->col_num == col) {
00139 return p;
00140 } else {
00141 return NIL(sm_element);
00142 }
00143 }
00144
00145
00146
00147
00148 int
00149 sm_row_contains(sm_row *p1, sm_row *p2)
00150 {
00151 register sm_element *q1, *q2;
00152
00153 q1 = p1->first_col;
00154 q2 = p2->first_col;
00155 while (q1 != 0) {
00156 if (q2 == 0 || q1->col_num < q2->col_num) {
00157 return 0;
00158 } else if (q1->col_num == q2->col_num) {
00159 q1 = q1->next_col;
00160 q2 = q2->next_col;
00161 } else {
00162 q2 = q2->next_col;
00163 }
00164 }
00165 return 1;
00166 }
00167
00168
00169
00170
00171
00172 int
00173 sm_row_intersects(sm_row *p1, sm_row *p2)
00174 {
00175 register sm_element *q1, *q2;
00176
00177 q1 = p1->first_col;
00178 q2 = p2->first_col;
00179 if (q1 == 0 || q2 == 0) return 0;
00180 for(;;) {
00181 if (q1->col_num < q2->col_num) {
00182 if ((q1 = q1->next_col) == 0) {
00183 return 0;
00184 }
00185 } else if (q1->col_num > q2->col_num) {
00186 if ((q2 = q2->next_col) == 0) {
00187 return 0;
00188 }
00189 } else {
00190 return 1;
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199 int
00200 sm_row_compare(sm_row *p1, sm_row *p2)
00201 {
00202 register sm_element *q1, *q2;
00203
00204 q1 = p1->first_col;
00205 q2 = p2->first_col;
00206 while(q1 != 0 && q2 != 0) {
00207 if (q1->col_num != q2->col_num) {
00208 return q1->col_num - q2->col_num;
00209 }
00210 q1 = q1->next_col;
00211 q2 = q2->next_col;
00212 }
00213
00214 if (q1 != 0) {
00215 return 1;
00216 } else if (q2 != 0) {
00217 return -1;
00218 } else {
00219 return 0;
00220 }
00221 }
00222
00223
00224
00225
00226
00227 sm_row *
00228 sm_row_and(sm_row *p1, sm_row *p2)
00229 {
00230 register sm_element *q1, *q2;
00231 register sm_row *result;
00232
00233 result = sm_row_alloc();
00234 q1 = p1->first_col;
00235 q2 = p2->first_col;
00236 if (q1 == 0 || q2 == 0) return result;
00237 for(;;) {
00238 if (q1->col_num < q2->col_num) {
00239 if ((q1 = q1->next_col) == 0) {
00240 return result;
00241 }
00242 } else if (q1->col_num > q2->col_num) {
00243 if ((q2 = q2->next_col) == 0) {
00244 return result;
00245 }
00246 } else {
00247 (void) sm_row_insert(result, q1->col_num);
00248 if ((q1 = q1->next_col) == 0) {
00249 return result;
00250 }
00251 if ((q2 = q2->next_col) == 0) {
00252 return result;
00253 }
00254 }
00255 }
00256 }
00257
00258 int
00259 sm_row_hash(sm_row *prow, int modulus)
00260 {
00261 register int sum;
00262 register sm_element *p;
00263
00264 sum = 0;
00265 for(p = prow->first_col; p != 0; p = p->next_col) {
00266 sum = (sum*17 + p->col_num) % modulus;
00267 }
00268 return sum;
00269 }
00270
00271
00272
00273
00274 void
00275 sm_row_remove_element(sm_row *prow, sm_element *p)
00276 {
00277 dll_unlink(p, prow->first_col, prow->last_col,
00278 next_col, prev_col, prow->length);
00279 sm_element_free(p);
00280 }
00281
00282
00283 void
00284 sm_row_print(FILE *fp, sm_row *prow)
00285 {
00286 sm_element *p;
00287
00288 for(p = prow->first_col; p != 0; p = p->next_col) {
00289 (void) fprintf(fp, " %d", p->col_num);
00290 }
00291 }