1 | #include "sparse_dok.h" |
---|
2 | |
---|
3 | |
---|
4 | // **************** UTILITIES *********************** |
---|
5 | |
---|
6 | static void *emalloc(size_t amt,char * location) |
---|
7 | { |
---|
8 | void *v = malloc(amt); |
---|
9 | if(!v){ |
---|
10 | fprintf(stderr, "out of mem in quad_tree: %s\n",location); |
---|
11 | exit(EXIT_FAILURE); |
---|
12 | } |
---|
13 | return v; |
---|
14 | }; |
---|
15 | |
---|
16 | // *************************************************** |
---|
17 | |
---|
18 | // 'Constructor' |
---|
19 | |
---|
20 | sparse_dok * make_dok(){ |
---|
21 | |
---|
22 | sparse_dok * ret = emalloc(sizeof(sparse_dok),"make_dok"); |
---|
23 | ret->edgetable=NULL; |
---|
24 | ret->num_entries=0; |
---|
25 | ret->num_rows=0; |
---|
26 | return ret; |
---|
27 | } |
---|
28 | |
---|
29 | //----------------------------------------------- |
---|
30 | // DOK HASH FUNCTIONS |
---|
31 | //----------------------------------------------- |
---|
32 | |
---|
33 | edge_t *find_dok_entry(sparse_dok * hashtable,edge_key_t key) { |
---|
34 | edge_t *s; |
---|
35 | HASH_FIND(hh, hashtable->edgetable, &key, sizeof(edge_key_t), s); /* s: output pointer */ |
---|
36 | return s; |
---|
37 | } |
---|
38 | |
---|
39 | void add_dok_entry(sparse_dok * hashtable, edge_key_t key, double value) { |
---|
40 | |
---|
41 | // Checking here now if there is an existing value |
---|
42 | // not sure if this code will work. |
---|
43 | |
---|
44 | edge_t *s; |
---|
45 | s = find_dok_entry(hashtable,key); |
---|
46 | if (s) { |
---|
47 | s->entry+=value; |
---|
48 | } else { |
---|
49 | hashtable->num_entries+=1; |
---|
50 | if(hashtable->num_rows<key.i){ |
---|
51 | hashtable->num_rows = key.i; |
---|
52 | } |
---|
53 | s = (edge_t*) emalloc(sizeof(edge_t),"add_dok_entry"); |
---|
54 | memset(s, 0, sizeof(edge_t)); |
---|
55 | s->key.i = key.i; |
---|
56 | s->key.j = key.j; |
---|
57 | s->entry = value; |
---|
58 | HASH_ADD(hh, hashtable->edgetable, key, sizeof(edge_key_t), s); /* key: name of key field */ |
---|
59 | } |
---|
60 | if(s->entry <= 1e-10 && s->entry >= -1e-10){ |
---|
61 | HASH_DEL(hashtable->edgetable,s); |
---|
62 | free(s); |
---|
63 | hashtable->num_entries-=1; |
---|
64 | } |
---|
65 | |
---|
66 | |
---|
67 | } |
---|
68 | |
---|
69 | void delete_dok_entry(sparse_dok * hashtable,edge_t *edge) { |
---|
70 | HASH_DEL( hashtable->edgetable, edge); /* user: pointer to deletee */ |
---|
71 | free(edge); |
---|
72 | } |
---|
73 | |
---|
74 | void delete_dok_all(sparse_dok * hashtable) { |
---|
75 | edge_t *current_edge, *tmp; |
---|
76 | |
---|
77 | HASH_ITER(hh, hashtable->edgetable, current_edge, tmp) { |
---|
78 | HASH_DEL(hashtable->edgetable, current_edge); /* delete it (hashtable advances to next) */ |
---|
79 | free(current_edge); /* free it */ |
---|
80 | } |
---|
81 | } |
---|
82 | |
---|
83 | void delete_dok_matrix(sparse_dok * mat) { |
---|
84 | |
---|
85 | delete_dok_all(mat); |
---|
86 | free(mat->edgetable); |
---|
87 | free(mat); |
---|
88 | mat=NULL; |
---|
89 | |
---|
90 | } |
---|
91 | |
---|
92 | void print_dok_entries(sparse_dok * hashtable) { |
---|
93 | edge_t *s; |
---|
94 | |
---|
95 | for(s=hashtable->edgetable; s != NULL; s=(edge_t*)(s->hh.next)) { |
---|
96 | printf("edge key i %d i %d entry %f\n", |
---|
97 | s->key.i, s->key.j, s->entry); |
---|
98 | } |
---|
99 | } |
---|
100 | |
---|
101 | int key_sort(edge_t *a, edge_t *b) { |
---|
102 | return (a->key.i - b->key.i); |
---|
103 | } |
---|
104 | |
---|
105 | int key_sort_2(edge_t *a, edge_t *b){ |
---|
106 | if(a->key.i - b->key.i==0){ |
---|
107 | return (a->key.j-b->key.j); |
---|
108 | } else{ |
---|
109 | return (a->key.i-b->key.i); |
---|
110 | } |
---|
111 | } |
---|
112 | |
---|
113 | void sort_by_key(sparse_dok * hashtable) { |
---|
114 | HASH_SORT(hashtable->edgetable, key_sort_2); |
---|
115 | } |
---|
116 | |
---|
117 | //----------------END-------------------- |
---|
118 | |
---|
119 | //----------------------------------------------- |
---|
120 | // DOK MATRIX FUNCTIONS |
---|
121 | //----------------------------------------------- |
---|
122 | |
---|
123 | |
---|
124 | void convert_to_csr_ptr(sparse_csr * new_csr, sparse_dok * hashtable){ |
---|
125 | |
---|
126 | |
---|
127 | sparse_csr * ret_csr = new_csr; |
---|
128 | |
---|
129 | //entrires stores in edgetable -> end |
---|
130 | |
---|
131 | //sort and get number of entries |
---|
132 | sort_by_key(hashtable); |
---|
133 | int num_entries = hashtable->num_entries; |
---|
134 | int num_rows = hashtable->num_rows+1; |
---|
135 | |
---|
136 | //build storage matricies |
---|
137 | ret_csr->data=emalloc(num_entries*sizeof(double),"convert_to_csr_ptr"); |
---|
138 | ret_csr->colind=emalloc(num_entries*sizeof(int),"convert_to_csr_ptr"); |
---|
139 | ret_csr->row_ptr=emalloc((num_rows+1)*sizeof(int),"convert_to_csr_ptr"); |
---|
140 | |
---|
141 | edge_t * edge = hashtable->edgetable; |
---|
142 | |
---|
143 | //now convert |
---|
144 | int current_row = -1; |
---|
145 | int k; |
---|
146 | for(k=0;k<num_entries;k++){ |
---|
147 | int i = edge->key.i; |
---|
148 | int j = edge->key.j; |
---|
149 | double value = edge->entry; |
---|
150 | |
---|
151 | if (i!=current_row){ |
---|
152 | current_row=i; |
---|
153 | ret_csr->row_ptr[i]=k; |
---|
154 | } |
---|
155 | |
---|
156 | ret_csr->data[k] = value; |
---|
157 | ret_csr->colind[k] = j; |
---|
158 | edge = edge->hh.next; |
---|
159 | } |
---|
160 | |
---|
161 | for(k=current_row+1;k<num_rows+1;k++){ |
---|
162 | ret_csr->row_ptr[k]=num_entries; |
---|
163 | } |
---|
164 | |
---|
165 | ret_csr -> num_rows = num_rows+1; |
---|
166 | ret_csr -> num_entries = num_entries; |
---|
167 | |
---|
168 | } |
---|
169 | |
---|
170 | void add_sparse_dok(sparse_dok * dok1,double mult1,sparse_dok * dok2,double mult2){ |
---|
171 | |
---|
172 | // add both into dok1 - then leave both alone (free outside) |
---|
173 | int num_entries = dok1->num_entries; |
---|
174 | edge_t * edge = dok1->edgetable; |
---|
175 | edge_t * edge2; |
---|
176 | |
---|
177 | int k; |
---|
178 | for(k=0;k<num_entries;k++){ |
---|
179 | int i = edge->key.i; |
---|
180 | int j = edge->key.j; |
---|
181 | double value = edge->entry; |
---|
182 | edge->entry=value*mult1; |
---|
183 | edge2=find_dok_entry(dok2,edge->key); |
---|
184 | if(edge2!=NULL){ |
---|
185 | edge->entry+=edge2->entry*mult2; |
---|
186 | edge2->entry=0; |
---|
187 | //delete_dok_entry(dok2,edge2); |
---|
188 | } |
---|
189 | edge = edge->hh.next; |
---|
190 | } |
---|
191 | |
---|
192 | num_entries = dok2->num_entries; |
---|
193 | edge = dok2->edgetable; |
---|
194 | for(k=0;k<num_entries;k++){ |
---|
195 | add_dok_entry(dok1,edge->key,edge->entry*mult2); |
---|
196 | edge = edge->hh.next; |
---|
197 | } |
---|
198 | |
---|
199 | } |
---|
200 | |
---|
201 | int get_dok_rows(sparse_dok * dok){ |
---|
202 | |
---|
203 | int rows = 0; |
---|
204 | |
---|
205 | edge_t *current_edge, *tmp; |
---|
206 | |
---|
207 | HASH_ITER(hh, dok->edgetable, current_edge, tmp) { |
---|
208 | if (current_edge->key.i>rows) rows = current_edge->key.i; |
---|
209 | } |
---|
210 | |
---|
211 | |
---|
212 | return rows; |
---|
213 | } |
---|
214 | |
---|