source: vis_dev/glu-2.3/src/sparse/cols.c @ 64

Last change on this file since 64 was 13, checked in by cecile, 13 years ago

library glu 2.3

File size: 5.5 KB
Line 
1/*
2 * $Id: cols.c,v 1.3 2002/09/10 00:00:12 fabio Exp $
3 *
4 */
5#include <stdio.h>
6#include "sparse_int.h"
7
8
9/*
10 *  allocate a new col vector
11 */
12sm_col *
13sm_col_alloc(void)
14{
15    register sm_col *pcol;
16
17#ifdef FAST_AND_LOOSE
18    if (sm_col_freelist == NIL(sm_col)) {
19        pcol = ALLOC(sm_col, 1);
20    } else {
21        pcol = sm_col_freelist;
22        sm_col_freelist = pcol->next_col;
23    }
24#else
25    pcol = ALLOC(sm_col, 1);
26#endif
27
28    pcol->col_num = 0;
29    pcol->length = 0;
30    pcol->first_row = pcol->last_row = NIL(sm_element);
31    pcol->next_col = pcol->prev_col = NIL(sm_col);
32    pcol->flag = 0;
33    pcol->user_word = NIL(char);                /* for our user ... */
34    return pcol;
35}
36
37
38/*
39 *  free a col vector -- for FAST_AND_LOOSE, this is real cheap for cols;
40 *  however, freeing a rowumn must still walk down the rowumn discarding
41 *  the elements one-by-one; that is the only use for the extra '-DCOLS'
42 *  compile flag ...
43 */
44void
45sm_col_free(sm_col *pcol)
46{
47#if defined(FAST_AND_LOOSE) && ! defined(COLS)
48    if (pcol->first_row != NIL(sm_element)) {
49        /* Add the linked list of col items to the free list */
50        pcol->last_row->next_row = sm_element_freelist;
51        sm_element_freelist = pcol->first_row;
52    }
53
54    /* Add the col to the free list of cols */
55    pcol->next_col = sm_col_freelist;
56    sm_col_freelist = pcol;
57#else
58    register sm_element *p, *pnext;
59
60    for(p = pcol->first_row; p != 0; p = pnext) {
61        pnext = p->next_row;
62        sm_element_free(p);
63    }
64    FREE(pcol);
65#endif
66}
67
68
69/*
70 *  duplicate an existing col
71 */
72sm_col *
73sm_col_dup(sm_col *pcol)
74{
75    register sm_col *pnew;
76    register sm_element *p;
77
78    pnew = sm_col_alloc();
79    for(p = pcol->first_row; p != 0; p = p->next_row) {
80        (void) sm_col_insert(pnew, p->row_num);
81    }
82    return pnew;
83}
84
85
86/*
87 *  insert an element into a col vector
88 */
89sm_element *
90sm_col_insert(sm_col *pcol, int row)
91{
92    register sm_element *test, *element;
93
94    /* get a new item, save its address */
95    sm_element_alloc(element);
96    test = element;
97    sorted_insert(sm_element, pcol->first_row, pcol->last_row, pcol->length, 
98                    next_row, prev_row, row_num, row, test);
99
100    /* if item was not used, free it */
101    if (element != test) {
102        sm_element_free(element);
103    }
104
105    /* either way, return the current new value */
106    return test;
107}
108
109
110/*
111 *  remove an element from a col vector
112 */
113void
114sm_col_remove(sm_col *pcol, int row)
115{
116    register sm_element *p;
117
118    for(p = pcol->first_row; p != 0 && p->row_num < row; p = p->next_row)
119        ;
120    if (p != 0 && p->row_num == row) {
121        dll_unlink(p, pcol->first_row, pcol->last_row, 
122                            next_row, prev_row, pcol->length);
123        sm_element_free(p);
124    }
125}
126
127
128/*
129 *  find an element (if it is in the col vector)
130 */
131sm_element *
132sm_col_find(sm_col *pcol, int row)
133{
134    register sm_element *p;
135
136    for(p = pcol->first_row; p != 0 && p->row_num < row; p = p->next_row)
137        ;
138    if (p != 0 && p->row_num == row) {
139        return p;
140    } else {
141        return NIL(sm_element);
142    }
143}
144
145/*
146 *  return 1 if col p2 contains col p1; 0 otherwise
147 */
148int 
149sm_col_contains(sm_col *p1, sm_col *p2)
150{
151    register sm_element *q1, *q2;
152
153    q1 = p1->first_row;
154    q2 = p2->first_row;
155    while (q1 != 0) {
156        if (q2 == 0 || q1->row_num < q2->row_num) {
157            return 0;
158        } else if (q1->row_num == q2->row_num) {
159            q1 = q1->next_row;
160            q2 = q2->next_row;
161        } else {
162            q2 = q2->next_row;
163        }
164    }
165    return 1;
166}
167
168
169/*
170 *  return 1 if col p1 and col p2 share an element in common
171 */
172int 
173sm_col_intersects(sm_col *p1, sm_col *p2)
174{
175    register sm_element *q1, *q2;
176
177    q1 = p1->first_row;
178    q2 = p2->first_row;
179    if (q1 == 0 || q2 == 0) return 0;
180    for(;;) {
181        if (q1->row_num < q2->row_num) {
182            if ((q1 = q1->next_row) == 0) {
183                return 0;
184            }
185        } else if (q1->row_num > q2->row_num) {
186            if ((q2 = q2->next_row) == 0) {
187                return 0;
188            }
189        } else {
190            return 1;
191        }
192    }
193}
194
195
196/*
197 *  compare two cols, lexical ordering
198 */
199int 
200sm_col_compare(sm_col *p1, sm_col *p2)
201{
202    register sm_element *q1, *q2;
203
204    q1 = p1->first_row;
205    q2 = p2->first_row;
206    while(q1 != 0 && q2 != 0) {
207        if (q1->row_num != q2->row_num) {
208            return q1->row_num - q2->row_num;
209        }
210        q1 = q1->next_row;
211        q2 = q2->next_row;
212    }
213
214    if (q1 != 0) {
215        return 1;
216    } else if (q2 != 0) {
217        return -1;
218    } else {
219        return 0;
220    }
221}
222
223
224/*
225 *  return the intersection
226 */
227sm_col *
228sm_col_and(sm_col *p1, sm_col *p2)
229{
230    register sm_element *q1, *q2;
231    register sm_col *result;
232
233    result = sm_col_alloc();
234    q1 = p1->first_row;
235    q2 = p2->first_row;
236    if (q1 == 0 || q2 == 0) return result;
237    for(;;) {
238        if (q1->row_num < q2->row_num) {
239            if ((q1 = q1->next_row) == 0) {
240                return result;
241            }
242        } else if (q1->row_num > q2->row_num) {
243            if ((q2 = q2->next_row) == 0) {
244                return result;
245            }
246        } else {
247            (void) sm_col_insert(result, q1->row_num);
248            if ((q1 = q1->next_row) == 0) {
249                return result;
250            }
251            if ((q2 = q2->next_row) == 0) {
252                return result;
253            }
254        }
255    }
256}
257
258int 
259sm_col_hash(sm_col *pcol, int modulus)
260{
261    register int sum;
262    register sm_element *p;
263
264    sum = 0;
265    for(p = pcol->first_row; p != 0; p = p->next_row) {
266        sum = (sum*17 + p->row_num) % modulus;
267    }
268    return sum;
269}
270
271/*
272 *  remove an element from a col vector (given a pointer to the element)
273 */
274void
275sm_col_remove_element(sm_col *pcol, sm_element *p)
276{
277    dll_unlink(p, pcol->first_row, pcol->last_row, 
278                        next_row, prev_row, pcol->length);
279    sm_element_free(p);
280}
281
282
283void
284sm_col_print(FILE *fp, sm_col *pcol)
285{
286    sm_element *p;
287
288    for(p = pcol->first_row; p != 0; p = p->next_row) {
289        (void) fprintf(fp, " %d", p->row_num);
290    }
291}
Note: See TracBrowser for help on using the repository browser.