1 #include "cado.h" // IWYU pragma: keep
2 #include <cstdio> // FILE // IWYU pragma: keep
3 #include <cstdlib>
4 #include "facul.hpp"
5 #include "tab_fm.h"
6 #include "macros.h"
7
8 static const double EPSILON_DBL = 0.000001;
9
tabular_fm_create(void)10 tabular_fm_t *tabular_fm_create(void)
11 {
12 tabular_fm_t *t = (tabular_fm_t*) malloc(sizeof(tabular_fm_t));
13 ASSERT_ALWAYS(t != NULL);
14
15 t->index = 0;
16 t->size = 2;
17
18 t->tab = (fm_t **) malloc(t->size * sizeof(fm_t *));
19 ASSERT_ALWAYS(t->tab != NULL);
20
21 return t;
22 }
23
tabular_fm_free(tabular_fm_t * t)24 void tabular_fm_free(tabular_fm_t * t)
25 {
26 if (t != NULL)
27 {
28 for (int i = 0; i < t->index; i++) //size
29 fm_free(t->tab[i]);
30 free(t->tab);
31 free(t);
32 }
33 }
34
tabular_fm_realloc(tabular_fm_t * t)35 void tabular_fm_realloc(tabular_fm_t * t)
36 {
37 t->tab = (fm_t **) realloc(t->tab, t->size * 2 * (sizeof(fm_t *)));
38 ASSERT(t->tab != NULL);
39 t->size *= 2;
40 }
41
tabular_fm_get_index(tabular_fm_t * t)42 int tabular_fm_get_index(tabular_fm_t * t)
43 {
44 return t->index;
45 }
46
tabular_fm_add_fm(tabular_fm_t * t,fm_t * fm)47 void tabular_fm_add_fm(tabular_fm_t * t, fm_t * fm)
48 {
49 tabular_fm_set_fm_index(t, fm, t->index);
50 }
51
52 void
tabular_fm_add(tabular_fm_t * t,unsigned long * method,int len_method,double * proba,int len_proba,double * time,int len_time,int len_p_min)53 tabular_fm_add(tabular_fm_t * t, unsigned long *method, int len_method,
54 double *proba, int len_proba, double *time, int len_time,
55 int len_p_min)
56 {
57 tabular_fm_set_index(t, method, len_method, proba, len_proba, time,
58 len_time, len_p_min, t->index);
59 }
60
tabular_fm_set_fm_index(tabular_fm_t * t,fm_t * fm,int ind)61 void tabular_fm_set_fm_index(tabular_fm_t * t, fm_t * fm, int ind)
62 {
63 tabular_fm_set_index(t, fm->method, fm->len_method, fm->proba,
64 fm->len_proba, fm->time, fm->len_time, fm->len_p_min,
65 ind);
66 }
67
68 void
tabular_fm_set_index(tabular_fm_t * t,unsigned long * method,int len_method,double * proba,int len_proba,double * time,int len_time,int len_p_min,int ind)69 tabular_fm_set_index(tabular_fm_t * t, unsigned long *method, int len_method,
70 double *proba, int len_proba, double *time, int len_time,
71 int len_p_min, int ind)
72 {
73 if (ind >= t->size)
74 tabular_fm_realloc(t);
75
76 if (ind >= t->index) {
77 t->tab[ind] = fm_create();
78 ASSERT(t->tab[ind] != NULL);
79 }
80
81 fm_set_method(t->tab[ind], method, len_method);
82 fm_set_proba(t->tab[ind], proba, len_proba, len_p_min);
83 fm_set_time(t->tab[ind], time, len_time);
84 if (ind >= t->index)
85 t->index++;
86 }
87
tabular_fm_get_fm(tabular_fm_t * t,int index)88 fm_t *tabular_fm_get_fm(tabular_fm_t * t, int index)
89 {
90 if (index >= t->index)
91 return NULL;
92 return t->tab[index];
93 }
94
tabular_fm_concat(tabular_fm_t * t1,tabular_fm_t * t2)95 void tabular_fm_concat(tabular_fm_t * t1, tabular_fm_t * t2)
96 {
97 int len = t2->index;
98 for (int i = 0; i < len; i++)
99 tabular_fm_add_fm(t1, t2->tab[i]);
100 }
101
tabular_fm_put_zero(tabular_fm_t * t,int index)102 void tabular_fm_put_zero(tabular_fm_t * t, int index)
103 {
104 if (index < t->index)
105 fm_put_zero(t->tab[index]);
106 }
107
tabular_fm_is_zero(tabular_fm_t * t,int index)108 bool tabular_fm_is_zero(tabular_fm_t * t, int index)
109 {
110 if(index >= t->index)
111 return 0;
112 return fm_is_zero(t->tab[index]);
113 }
114
extract_fm_method(tabular_fm_t * t,int method,int curve)115 tabular_fm_t *extract_fm_method(tabular_fm_t * t, int method, int curve)
116 {
117 tabular_fm_t *res = tabular_fm_create();
118 int len = t->index;
119 for (int i = 0; i < len; i++) {
120 fm_t *el = t->tab[i];
121 if ((int)el->method[0] == method) {
122 if (method == EC_METHOD) {
123 if ((int)el->method[1] == curve)
124 tabular_fm_add_fm(res, el);
125 } else
126 tabular_fm_add_fm(res, el);
127 }
128 }
129 return res;
130 }
131
132 /************************************************************************/
133 /* PRINT AND SCAN OUR FILES OF FACTORING METHODS */
134 /************************************************************************/
135
tabular_fm_print(tabular_fm_t * t)136 int tabular_fm_print(tabular_fm_t * t)
137 {
138 return tabular_fm_fprint(stdout, t);
139 }
140
tabular_fm_fprint(FILE * file,tabular_fm_t * t)141 int tabular_fm_fprint(FILE * file, tabular_fm_t * t)
142 {
143 int len = t->index;
144 for (int i = 0; i < len; i++) {
145 fm_t *elem = tabular_fm_get_fm(t, i);
146 if (fm_fprint(file, elem) < 0)
147 return -1;
148 }
149 return 0;
150 }
151
is_elem(const char c)152 static int is_elem(const char c)
153 {
154 return (c >= 48 && c <= 57) || c == '|';
155 }
156
next_elem(FILE * file,int * current_char)157 static void next_elem(FILE * file, int *current_char)
158 {
159 //end the current element
160 while (*current_char != EOF && is_elem(*current_char))
161 *current_char = fgetc(file);
162
163 //find the next element
164 while (*current_char != EOF && !is_elem(*current_char)) {
165 *current_char = fgetc(file);
166 }
167 ungetc(*current_char, file);
168 }
169
sub_routine_fm_fscanf(FILE * file,int * current_char)170 static fm_t *sub_routine_fm_fscanf(FILE * file, int *current_char)
171 {
172 fm_t *fm = fm_create();
173
174 int len_method = 100;
175 int len_proba = 100;
176 int len_time = 100;
177
178 unsigned long method[len_method];
179 double proba[len_proba];
180 double time[len_time];
181
182 int ind = 0;
183 int rc;
184 while (ind < len_method && *current_char != '|') {
185 rc = fscanf(file, "%lu", &method[ind++]);
186 ASSERT_ALWAYS(rc == 1);
187 next_elem(file, current_char);
188 }
189 next_elem(file, current_char);
190
191 fm_set_method(fm, method, ind);
192
193 rc = fscanf(file, "%d", &fm->len_p_min);
194 ASSERT_ALWAYS(rc == 1);
195 next_elem(file, current_char);
196 ind = 0;
197 while (ind < len_proba && *current_char != '|') {
198 rc = fscanf(file, "%lf", &proba[ind++]);
199 ASSERT_ALWAYS(rc == 1);
200 next_elem(file, current_char);
201 }
202 next_elem(file, current_char);
203
204 fm_set_proba(fm, proba, ind, fm->len_p_min);
205
206 ind = 0;
207 while (ind < len_time && *current_char != '|') {
208 rc = fscanf(file, "%lf", &time[ind++]);
209 ASSERT_ALWAYS(rc == 1);
210 next_elem(file, current_char);
211 }
212 next_elem(file, current_char);
213
214 fm_set_time(fm, time, ind);
215
216 return fm;
217 }
218
tabular_fm_fscan(FILE * file)219 tabular_fm_t* tabular_fm_fscan(FILE * file)
220 {
221 if (file == NULL)
222 return NULL;
223 tabular_fm_t * res = tabular_fm_create ();
224 int current_char = fgetc(file);
225 int rc = ungetc(current_char, file);
226 ASSERT_ALWAYS(rc != EOF);
227 while (current_char != EOF) {
228 fm_t *fm = sub_routine_fm_fscanf(file, ¤t_char);
229 tabular_fm_add_fm(res, fm);
230 fm_free(fm);
231 }
232
233 return res;
234 }
235
236 /************************************************************************/
237 /* SORT_TAB_FM */
238 /************************************************************************/
239
240 //return a positive value if el1 is greater than el2 and a negative
241 //value otherwise.
fm_cmp(fm_t * el1,fm_t * el2)242 int fm_cmp(fm_t * el1, fm_t * el2)
243 {
244 if (fm_is_zero(el1))
245 return -1;
246 else if (fm_is_zero(el2))
247 return 1;
248 /*assume that the variable len_p_min is the same for the both
249 fm_t.*/
250 //compare the probabilities!
251 int len1 = el1->len_proba;
252 int len2 = el2->len_proba;
253
254 int len = (len1 < len2) ? len1 : len2;
255 double diff_proba = 0;
256 for (int i = 0; i < len; i++)
257 if (el1->proba[i] > EPSILON_DBL && el2->proba[i] > EPSILON_DBL)
258 diff_proba += el1->proba[i] - el2->proba[i];
259
260 return (diff_proba>EPSILON_DBL)? 1: -1;
261 }
262
fm_swap(tabular_fm_t * t,int index1,int index2)263 void fm_swap(tabular_fm_t * t, int index1, int index2)
264 {
265 fm_t *c = t->tab[index1];
266 t->tab[index1] = t->tab[index2];
267 t->tab[index2] = c;
268 }
269
tabular_fm_sort_rec(tabular_fm_t * t,int begin,int end)270 static void tabular_fm_sort_rec(tabular_fm_t * t, int begin, int end)
271 {
272 int index_max = begin;
273 for (int i = begin; i < end; i++) {
274 if (fm_cmp(t->tab[i], t->tab[index_max]) > 0) {
275 index_max = i;
276 }
277 }
278 fm_swap(t, end - 1, index_max);
279 }
280
tabular_fm_sort(tabular_fm_t * t)281 void tabular_fm_sort(tabular_fm_t * t)
282 {
283 int max = t->index;
284 while (max > 0) {
285 tabular_fm_sort_rec(t, 0, max);
286 max--;
287 }
288 }
289
290