source: trunk/anuga_core/source/anuga/utilities/sparse_dok.c @ 8968

Last change on this file since 8968 was 8947, checked in by steve, 11 years ago

changed delete_all to different name in each c file

File size: 5.2 KB
Line 
1#include "sparse_dok.h"
2
3
4// **************** UTILITIES ***********************
5
6static 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
20sparse_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
33edge_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
39void 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
69void delete_dok_entry(sparse_dok * hashtable,edge_t *edge) {
70    HASH_DEL( hashtable->edgetable, edge);  /* user: pointer to deletee */
71    free(edge);
72}
73
74void 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
83void 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
92void 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
101int key_sort(edge_t *a, edge_t *b) {
102    return (a->key.i - b->key.i);
103}
104
105int 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
113void 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
124void 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
170void 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
201int 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
Note: See TracBrowser for help on using the repository browser.