1 #ifndef MPS_TYPES_H_
2 #define MPS_TYPES_H_
3 
4 /* String type used for some hacks */
5 typedef const char * mps_string;
6 
7 /* Boolean type used in MPSolve */
8 #ifndef __MPS_NOT_DEFINE_BOOL
9 typedef enum
10 { false = 0, true = 1 } mps_boolean;
11 #else
12 /* Small workaround to make matlab module work; there is,
13  * int matlab headers, already a false keyword defined, so
14  * reusing it here make compilation fail. */
15 typedef bool mps_boolean;
16 #endif                          /* mps_boolean */
17 
18 #define mps_boolean_to_string(x) ((x) == true) ? "true" : "false"
19 
20 /* Debug level */
21 typedef int mps_debug_level;
22 
23 /* Handle systems where isnan and isinf are not available */
24 #include <math.h>
25 #ifndef isnan
26           # define isnan(x) \
27   (sizeof(x) == sizeof(long double) ? isnan_ld (x) \
28    : sizeof(x) == sizeof(double) ? isnan_d (x) \
29    : isnan_f (x))
isnan_f(float x)30 static inline int isnan_f (float x)
31 {
32   return x != x;
33 }
isnan_d(double x)34 static inline int isnan_d (double x)
35 {
36   return x != x;
37 }
isnan_ld(long double x)38 static inline int isnan_ld (long double x)
39 {
40   return x != x;
41 }
42           #endif
43 
44 #ifndef isinf
45           # define isinf(x) \
46   (sizeof(x) == sizeof(long double) ? isinf_ld (x) \
47    : sizeof(x) == sizeof(double) ? isinf_d (x) \
48    : isinf_f (x))
isinf_f(float x)49 static inline int isinf_f (float x)
50 {
51   return !isnan (x) && isnan (x - x);
52 }
isinf_d(double x)53 static inline int isinf_d (double x)
54 {
55   return !isnan (x) && isnan (x - x);
56 }
isinf_ld(long double x)57 static inline int isinf_ld (long double x)
58 {
59   return !isnan (x) && isnan (x - x);
60 }
61 #endif
62 
63 #include <mps/mt-types.h>
64 
65 #ifdef __cplusplus
66 
67 /* Forward declarations of the type used in the headers, so they can be
68  * resolved indepently by the header inclusion order. */
69 
70 /* context.h */
71 struct mps_context;
72 
73 /* cluster.h */
74 struct mps_root;
75 struct mps_cluster;
76 struct mps_cluster_item;
77 struct mps_clusterization;
78 
79 /* secular-equation.h */
80 struct mps_secular_equation;
81 struct mps_secular_iteration_data;
82 
83 /* monomial-poly.h */
84 struct mps_monomial_poly;
85 
86 /* monomial-matrix-poly.h */
87 struct mps_monomial_matrix_poly;
88 
89 /* polynomial.h */
90 struct mps_polynomial;
91 
92 /* input-buffer.h */
93 struct mps_input_buffer;
94 
95 /* approximation.h */
96 struct mps_approximation;
97 
98 /* options.h */
99 struct mps_opt;
100 struct mps_input_option;
101 struct mps_command_line_option;
102 struct mps_command_line_option_configuration;
103 
104 /* list.h */
105 struct mps_list_element;
106 struct mps_list;
107 
108 struct mps_input_configuration;
109 struct mps_output_configuration;
110 
111 /* threading.h */
112 struct mps_thread_job;
113 struct mps_thread_job_queue;
114 struct mps_thread_worker_data;
115 struct mps_thread;
116 struct mps_thread_pool;
117 struct mps_thread_pool_queue;
118 struct mps_thread_pool_queue_item;
119 
120 /* regeneration-driver.h */
121 struct mps_regeneration_driver;
122 
123 #else
124 
125 /* Forward declarations of the type used in the headers, so they can be
126  * resolved indepently by the header inclusion order. */
127 
128 /* context.h */
129 typedef struct mps_context mps_context;
130 
131 /* cluster.h */
132 typedef struct mps_root mps_root;
133 typedef struct mps_cluster mps_cluster;
134 typedef struct mps_cluster_item mps_cluster_item;
135 typedef struct mps_clusterization mps_clusterization;
136 
137 /* secular-equation.h */
138 typedef struct mps_secular_equation mps_secular_equation;
139 typedef struct mps_secular_iteration_data mps_secular_iteration_data;
140 
141 /* monomial-poly.h */
142 typedef struct mps_monomial_poly mps_monomial_poly;
143 
144 /* monomial-matrix-poly.h */
145 typedef struct mps_monomial_matrix_poly mps_monomial_matrix_poly;
146 
147 /* polynomial.h */
148 typedef struct mps_polynomial mps_polynomial;
149 
150 /* input-buffer.h */
151 typedef struct mps_input_buffer mps_input_buffer;
152 
153 /* approximation.h */
154 typedef struct mps_approximation mps_approximation;
155 
156 /* options.h */
157 typedef struct mps_opt mps_opt;
158 typedef struct mps_input_option mps_input_option;
159 typedef struct mps_command_line_option mps_command_line_option;
160 typedef struct mps_command_line_option_configuration mps_command_line_option_configuration;
161 
162 /* list.h */
163 typedef struct mps_list_element mps_list_element;
164 typedef struct mps_list mps_list;
165 
166 typedef enum mps_root_status mps_root_status;
167 typedef enum mps_root_inclusion mps_root_inclusion;
168 typedef enum mps_root_attrs mps_root_attrs;
169 
170 typedef enum mps_algorithm mps_algorithm;
171 typedef enum mps_operation mps_operation;
172 typedef enum mps_option_key mps_option_key;
173 typedef enum mps_structure mps_structure;
174 typedef enum mps_representation mps_representation;
175 typedef enum mps_density mps_density;
176 typedef enum mps_output_format mps_output_format;
177 typedef enum mps_output_goal mps_output_goal;
178 typedef enum mps_search_set mps_search_set;
179 typedef enum mps_phase mps_phase;
180 typedef enum mps_starting_strategy mps_starting_strategy;
181 
182 typedef struct mps_input_configuration mps_input_configuration;
183 typedef struct mps_output_configuration mps_output_configuration;
184 
185 /* threading.h */
186 typedef struct mps_thread_job mps_thread_job;
187 typedef struct mps_thread_job_queue mps_thread_job_queue;
188 typedef struct mps_thread_worker_data mps_thread_worker_data;
189 typedef struct mps_thread mps_thread;
190 typedef struct mps_thread_pool mps_thread_pool;
191 typedef struct mps_thread_pool_queue mps_thread_pool_queue;
192 typedef struct mps_thread_pool_queue_item mps_thread_pool_queue_item;
193 
194 /* regeneration-driver.h */
195 typedef struct mps_regeneration_driver mps_regeneration_driver;
196 
197 #endif
198 
199 /**
200  * @brief Type representing the computation phase
201  * of the algorithm we are in
202  * now. It can assume the values:
203  * - <code>no_phase</code>;
204  * - <code>float_phase</code>;
205  * - <code>dpe_phase</code>;
206  * - <code>mp_phase</code>;
207  */
208 enum mps_phase {
209   no_phase, float_phase, dpe_phase, mp_phase
210 };
211 
212 static const mps_string mps_phase_string [] = {
213   "No phase", "Float phase", "DPE phase", "MP phase"
214 };
215 #define MPS_PHASE_TO_STRING(phase) (mps_phase_string[phase])
216 
217 /**
218  * @brief Used to label different operation inside the various
219  * algorithms.
220  */
221 enum mps_operation {
222   MPS_OPERATION_CLUSTER_ANALYSIS,
223   MPS_OPERATION_ABERTH_FP_ITERATIONS,
224   MPS_OPERATION_ABERTH_DPE_ITERATIONS,
225   MPS_OPERATION_ABERTH_MP_ITERATIONS,
226   MPS_OPERATION_REGENERATION,
227   MPS_OPERATION_STARTING_POINTS_FP,
228   MPS_OPERATION_STARTING_POINTS_DPE,
229   MPS_OPERATION_STARTING_POINTS_MP,
230   MPS_OPERATION_SHIFT,
231   MPS_OPERATION_REFINEMENT
232 };
233 static const mps_string mps_operation_string [] = {
234   "Cluster Analysis", "Aberth floating point iterations", "Aberth DPE iterations",
235   "Aberth multiprecision iterations", "Regeneration", "Starting point computation in floating point",
236   "Starting point computatino in DPE", "Starting point computation in multiprecision",
237   "Shift of the polynomial", "Refinement of the approximation"
238 };
239 #define MPS_OPERATION_TO_STRING(operation) (mps_operation_string[operation])
240 
241 /**
242  * @brief Status of approximation of the root.
243  */
244 enum mps_root_status {
245   MPS_ROOT_STATUS_NEW_CLUSTERED,
246   MPS_ROOT_STATUS_CLUSTERED,
247   MPS_ROOT_STATUS_ISOLATED,
248   MPS_ROOT_STATUS_APPROXIMATED,
249   MPS_ROOT_STATUS_APPROXIMATED_IN_CLUSTER,
250   MPS_ROOT_STATUS_NOT_FLOAT,
251   MPS_ROOT_STATUS_NOT_DPE,
252   MPS_ROOT_STATUS_MULTIPLE
253 };
254 
255 /* Macros to check root status */
256 static const mps_boolean mps_table_of_approximated_roots [] = { false, false, false, true, true, false, false, false };
257 static const mps_boolean mps_table_of_computed_roots [] = { false, false, true, true, true, false, false, false };
258 static const mps_boolean mps_table_of_improvable_roots [] = { false, false, true, true, false, false, false, false };
259 #define MPS_ROOT_STATUS_IS_APPROXIMATED(status) (mps_table_of_approximated_roots[status])
260 #define MPS_ROOT_STATUS_IS_COMPUTED(status)     (mps_table_of_computed_roots[status])
261 #define MPS_ROOT_STATUS_IS_IMPROVABLE(status)   (mps_table_of_improvable_roots[status])
262 
263 /* Cast of root_status to string */
264 static const mps_string mps_root_status_string[] = {
265   "Clustered (pinned)",
266   "Clustered",
267   "Isolated",
268   "Approximated",
269   "Approximated in a cluster",
270   "Not representable as floating point",
271   "Not representable as DPE",
272   "Multiple root"
273 };
274 #define MPS_ROOT_STATUS_TO_STRING(status) (mps_root_status_string[status])
275 
276 /**
277  * @brief Attributes that can be attached to a root and
278  * are mostly aimed to detect reality or not.
279  */
280 enum mps_root_attrs {
281   MPS_ROOT_ATTRS_NONE,
282   MPS_ROOT_ATTRS_REAL,
283   MPS_ROOT_ATTRS_NOT_REAL,
284   MPS_ROOT_ATTRS_IMAG,
285   MPS_ROOT_ATTRS_NOT_IMAG,
286   MPS_ROOT_ATTRS_NOT_REAL_AND_IMAG
287 };
288 
289 /* Cast of root_attrs to string */
290 static const mps_string mps_root_attrs_string [] = {
291   "None",
292   "Real",
293   "Not real",
294   "Imaginary",
295   "Not imaginary",
296   "Not Real nor imaginary"
297 };
298 #define MPS_ROOT_ATTRS_TO_STRING(attrs) (mps_root_attrs_string[attrs])
299 
300 /**
301  * @brief Status of inclusion of the root in the target
302  * set.
303  */
304 enum mps_root_inclusion {
305   MPS_ROOT_INCLUSION_UNKNOWN,
306   MPS_ROOT_INCLUSION_IN,
307   MPS_ROOT_INCLUSION_OUT
308 };
309 
310 /* Cast of mps_root_inclusion to string */
311 static const mps_string mps_root_inclusion_string [] = {
312   "Unknown",
313   "In",
314   "Out",
315 };
316 #define MPS_ROOT_INCLUSION_TO_STRING(inclusion) (mps_root_inclusion_string[inclusion])
317 
318 /**
319  * @brief Algorithm used to find the solution of the polynomial,
320  * or of the secular equation.
321  */
322 enum  mps_algorithm {
323   /**
324    * @brief Standard MPsolve approach
325    */
326   MPS_ALGORITHM_STANDARD_MPSOLVE,
327 
328   /**
329    * @brief Gemignani's approach applied to secular equations.
330    */
331   MPS_ALGORITHM_SECULAR_GA
332 };
333 
334 /**
335  * @brief Key for options parsed from the input source file.
336  * Key that don't need values could exists (these are boolean flags,
337  * actually).
338  */
339 enum mps_option_key {
340   /* Flag for UNDEFINED Options */
341   MPS_FLAG_UNDEFINED,
342 
343   /* Key without values associated */
344   MPS_FLAG_INTEGER,
345   MPS_FLAG_REAL,
346   MPS_FLAG_COMPLEX,
347   MPS_FLAG_RATIONAL,
348   MPS_FLAG_FP,
349 
350   MPS_FLAG_SECULAR,
351   MPS_FLAG_MONOMIAL,
352 
353   MPS_FLAG_DENSE,
354   MPS_FLAG_SPARSE,
355 
356   /* Key with a value */
357   MPS_KEY_DEGREE,
358   MPS_KEY_PRECISION,
359 
360   /* Key introduced in MPSolve 3.1 */
361   MPS_FLAG_CHEBYSHEV
362 };
363 
364 /**
365  * @brief Definition of various algebraic structure that
366  * MPSolve can use as input.
367  *
368  * Precisely, integer, rational and floating point, either real or
369  * complex, can be treated in input.
370  */
371 enum mps_structure {
372   MPS_STRUCTURE_REAL_INTEGER,
373   MPS_STRUCTURE_REAL_RATIONAL,
374   MPS_STRUCTURE_REAL_FP,
375   MPS_STRUCTURE_REAL_BIGFLOAT,
376   MPS_STRUCTURE_COMPLEX_INTEGER,
377   MPS_STRUCTURE_COMPLEX_RATIONAL,
378   MPS_STRUCTURE_COMPLEX_FP,
379   MPS_STRUCTURE_COMPLEX_BIGFLOAT,
380   MPS_STRUCTURE_UNKNOWN
381 };
382 
383 /**
384  * @brief Density of the polynomial, or
385  * MPS_DENSITY_USER if density doesn't make sense
386  * since user routines are provided to compute
387  * the newton fraction.
388  */
389 enum mps_density {
390   MPS_DENSITY_DENSE,
391   MPS_DENSITY_SPARSE,
392   MPS_DENSITY_USER,
393 };
394 
395 /**
396  * @brief Desired output format for the roots.
397  */
398 enum mps_output_format {
399   MPS_OUTPUT_FORMAT_COMPACT,
400   MPS_OUTPUT_FORMAT_GNUPLOT,
401   MPS_OUTPUT_FORMAT_GNUPLOT_FULL,
402   MPS_OUTPUT_FORMAT_BARE,
403   MPS_OUTPUT_FORMAT_FULL,
404   MPS_OUTPUT_FORMAT_VERBOSE
405 };
406 
407 /**
408  * @brief Goal to reach before returning the result.
409  */
410 enum mps_output_goal {
411   MPS_OUTPUT_GOAL_ISOLATE,
412   MPS_OUTPUT_GOAL_APPROXIMATE,
413   MPS_OUTPUT_GOAL_COUNT
414 };
415 
416 /**
417  * @brief Set in which the roots are searched.
418  */
419 enum mps_search_set {
420   /**
421    * @brief The whole complex plane.
422    */
423   MPS_SEARCH_SET_COMPLEX_PLANE,
424 
425   /**
426    * @brief Complex numbers with a positive real part.
427    */
428   MPS_SEARCH_SET_POSITIVE_REAL_PART,
429 
430   /**
431    * @brief Complex numbers with a negative real part.
432    */
433   MPS_SEARCH_SET_NEGATIVE_REAL_PART,
434 
435   /**
436    * @brief Complex numbers with a positive imaginary part.
437    */
438   MPS_SEARCH_SET_POSITIVE_IMAG_PART,
439 
440   /**
441    * @brief Complex numbers with a negative real part.
442    */
443   MPS_SEARCH_SET_NEGATIVE_IMAG_PART,
444 
445   /**
446    * @brief Complex numbers in the unitary disc
447    * \f$S = \{ z \: | \: \lvert z \rvert \leq 1 \}\f$
448    */
449   MPS_SEARCH_SET_UNITARY_DISC,
450 
451   /**
452    * @brief Complex number out of the unitary disc
453    * \f$S = \{ z \: | \: \lvert z \rvert \leq 1 \}\f$
454    */
455   MPS_SEARCH_SET_UNITARY_DISC_COMPL,
456 
457   /**
458    * @brief Only real roots.
459    */
460   MPS_SEARCH_SET_REAL,
461 
462   /**
463    * @brief Only pure imaginary roots.
464    */
465   MPS_SEARCH_SET_IMAG,
466 
467   /**
468    * @brief Custom set specified by the user.
469    */
470   MPS_SEARCH_SET_CUSTOM
471 };
472 
473 /**
474  * @brief Representation chosen for the polynomial
475  */
476 enum mps_representation {
477   MPS_REPRESENTATION_SECULAR,
478   MPS_REPRESENTATION_MONOMIAL,
479   MPS_REPRESENTATION_CHEBYSHEV
480 };
481 
482 /**
483  * @brief Strategy used to select the starting approximations.
484  */
485 enum mps_starting_strategy {
486   MPS_STARTING_STRATEGY_DEFAULT,
487   MPS_STARTING_STRATEGY_RECURSIVE,
488   MPS_STARTING_STRATEGY_FILE
489 };
490 
491 #endif /* endif MPS_TYPES_H_ */
492