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, &current_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