File: interface.h

package info (click to toggle)
mpsolve 3.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 13,100 kB
  • sloc: ansic: 25,748; sh: 4,925; cpp: 3,155; makefile: 914; python: 407; yacc: 158; lex: 85; xml: 41
file content (232 lines) | stat: -rw-r--r-- 9,455 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
 * This file is part of MPSolve 3.2.2
 *
 * Copyright (C) 2001-2020, Dipartimento di Matematica "L. Tonelli", Pisa.
 * License: http://www.gnu.org/licenses/gpl.html GPL version 3 or higher
 *
 * Authors:
 *   Leonardo Robol <leonardo.robol@unipi.it>
 */

#ifndef MPS_INTERFACE_H_
#define MPS_INTERFACE_H_

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <gmp.h>
#include <mps/mps.h>

#ifdef  __cplusplus
extern "C"
{
#endif

/**
 * @file
 * @brief Simple routines used to interact with MPSolve without going into the internals.
 */

/* Since this is the interface header it contains also the documentation that doxygen
 * will output in HTML form. */

/**
 * @mainpage General documentation
 *
 * @section About What is MPSolve
 * MPSolve is a C library that allow to find solution to univariate polynomial equations
 * with arbitrary precision.
 *
 * More precisely, MPSolve can handle polynomials but not necessarly in their monomial
 * form. Support is now given even for secular equation and more implicit representation
 * are scheduled to be added later.
 *
 * @section Installation Installing MPSolve system-wide
 * First, you need to get MPSolve. You can get the latest release via <code>git</code>
 * or download it via <code>http</code> grabbing it at http://www.dm.unipi.it/...
 * If you downloaded the source tarball this operation is pretty straightforward.
 * You can simply unpack it and then
 * @code
 *   ./configure
 *   make
 *   [sudo] make install
 * @endcode
 *
 * These commands will install the library <code>libmps.so</code> in your system library
 * directory. In this way you will be able compile your source file using a command similar
 * to
 * @code
 * gcc -o myprogram -lmps -lgmp -lm myprogram.c.
 * @endcode
 *
 * @section ExtendedTypes MPSolve extended arithmetic types
 * To perform its computations MPSolve uses some more types than standard C does.
 * You will need to interact with these to give and obtain data from MPSolve.
 *
 * There are three main category of types that you will be required to deal with:
 * -# Standard floating point doubles;
 * -# DPE types;
 * -# Multiprecision GMP types
 *
 * @subsection FloatingPoint Floating point simple types
 * There is clearly nothing to explain about floating point doubles, but MPSolve needs to deal
 * with complex floating point and it uses a type called <code>cplx_t</code> that is nothing
 * more than a struct with two double field, <code>r</code> and <code>i</code> that represents
 * the real and imaginary part of the given complex number.
 * You should access these fields with macro provided in this way:
 * @code
 * cplx_t my_complex_number;
 * double theta = 0.5;
 * cplx_Re (my_complex_number) = cos (theta);
 * cplx_Im (my_complex_number) = sin (theta);
 * @endcode
 *
 * Some standard complex number are provided for convenicence, such as <code>cplx_one</code>
 * and <code>cplx_zero</code>.
 *
 * To get an idea of all the routines that you can use you can read the <code>mt.h</code> header
 * file. But for a simple start, the routines that you will need are cplx_add(),
 * cplx_sub(), cplx_mul() and cplx_div(). I think that it's pretty clear what they do.
 *
 * @subsection DPE The DPE types
 * The <code>DPE</code> are have the same precision of the <code>double</code>s but allow
 * the exponent to be much larger; the exponent is stored as a <code>long</code> value so
 * the maximum reachable one is <code>LONG_MAX</code>, while the minimum is <code>LONG_MIN</code>.
 *
 * In the <code>mt</code> library that is embedded in MPSolve two version of the <code>DPE</code>
 * types are provided: the real and the complex one. They are called <code>RDPE</code> and <code>CDPE</code>,
 * respectively.
 *
 * The function used to handle these types are almost the same of the complex one case, so we will
 * not cover they extensively here.
 *
 * @subsection GMP GMP types
 * GMP types are used to represent multiprecision data that is used to get arbitrary high precision
 * approximation of the roots. See http://gmplib.org for details on the use of GMP.
 *
 * @section Interface Using the libmps interface
 *
 * The library provides some useful routine to interact with the polynomial solver. Most of
 * them are designed to handle polynomial definition and are implemented in <code>interface.c</code>
 *
 * This is a typical example of how you'll be using MPSolve.
 *
 * @code
 * // Select the degree
 * int n = 4;
 *
 * // Allocate a new mps_context that hold the status of a computation.
 * // Its field should never be accessed directly but only via appropriate
 * //functions.
 * mps_context * status = mps_context_new ();
 *
 * // Create a polynomial that will be solved
 * mps_monomial_poly * poly = mps_monomial_poly_new (status, n);
 *
 * // Set the coefficients. We will solve x^n - 1 in here
 * mps_monomial_poly_set_coefficient_int (status, poly, 0, -1, 0);
 * mps_monomial_poly_set_coefficient_int (status, poly, n,  1, 0);
 *
 * // Select some common output options, i.e. 512 bits of precision
 * // (more or less 200 digits guaranteed) and approximation goal.
 * mps_context_set_output_prec (status, 512);
 * mps_context_set_output_goal (status, MPS_OUTPUT_GOAL_APPROXIMATE);
 *
 * // Solve the polynomial
 * mps_context_set_input_poly (status, poly);
 * mps_mpsolve (status);
 *
 * // Get the roots in a <code>cplx_t</code> vector. Please note that
 * // this make completely useless to have asked 512 bits of output
 * // precision, and you should use mps_context_get_roots_m() to get
 * // multiprecision approximation of the roots.
 * cplx_t * results = cplx_valloc (n);
 * mps_context_get_roots_d (status, &results, NULL);
 *
 * // Free the data used. This will free the monomial_poly if you have
 * // not done it by yourself.
 * mps_context_free (status);
 * cplx_vfree (results);
 * @endcode
 *
 * As pointed out in the comments, this piece of code is not that smart, since it asks
 * for a lot of digits in output, but then discard all this good by copying the roots
 * in floating point <code>cplx_t</code> types.
 *
 * Please see the documentation of mps_context_get_roots_m() for a better way to get
 * the results. It was not used in example in order to keep it short and clear.
 *
 * @subsection inclusion How to include libmps
 *
 * In general libmps will be usable by including the header file <code>mps/mps.h</code>.
 * Please note that almost all structures defined in MPSolve will be available only as
 * incomplete declarations, so they should be used with pointers, and manipulated with available
 * functions.
 *
 * Remember to include always <code>mps/mps.h</code> and not the other headers in the
 * directory. This is not supported and not guaranteed to work.
 *
 * For example you can instantiate a pointer to a new <code>mps_context</code> with
 * the function <code>mps_context_new()</code>, add the input to it, solve the polynoial
 * with <code>mps_mpsolve()</code> and then free its resources with <code>mps_context_free()</code>.
 *
 * The data structures that will be mostly used are:
 * -# <code>mps_context</code>: This structure holds the state of the computation and must
 * be instanciated for every polynomial solving operation. After allocating a pointer to
 * an <code>mps_context</code> you should, generally,:
 *   -# Set the input data and output requirements (i.e. the input polynomial, the desired
 *   output digits and goal, ...)
 *   -# Ask libmps to solve the polynomial by calling <code>mps_mpsolve()</code>
 *   -# Retrieve the computed data with the appropriate accessors functions
 * <code>mps_context_get_roots_d()</code> or <code>mps_context_get_roots_m()</code>.
 * All the functions usable on an <code>mps_context</code> pointer are available in
 * status.h.
 *
 * -# <code>mps_monomial_poly</code>: A polynomial given by its coefficients. Can be allocated
 * with <code>mps_monomial_poly_new()</code> and manipulated with the functions in
 * monomial-poly.h. Once it is the desired polynomial to solve you can call
 * <code>mps_context_set_input_poly()</code> to set it as the active polynomial to solve.
 *
 * -# <code>mps_secular_equation</code>: The same as the monomial poly, but for secular equations.
 * See secular-equation.h for some functions to allocate, free and manipulate them.
 *
 * @subsection async Calling MPSolve asynchronously
 *
 * Desktop application using MPSolve to solve polynomials may want to call a
 * non-blocking version of mps_mpsolve(). This is provided inside the package
 * as mps_mpsolve_async().
 *
 * This routine will return a <code>mps_handle</code> pointer that can be used to wait
 * for the result by calling mps_mpsolve_wait() on it.
 */

/*
 *    ====== ROUTINES EXPOSED TO THE INTERFACE ======
 */

/* functions in mps_defaults.c */
void mps_set_default_values (mps_context * s);

/* Functions in mps_main.c */
void mps_mpsolve (mps_context * s);
void mps_standard_mpsolve (mps_context * s);

/* functions in mps_interface.c */
void * mps_malloc (size_t size);
void * mps_realloc (void * pointer, size_t size);

void mps_mpsolve_async (mps_context * s, mps_callback callback, void * user_data);

/* Macros to init pointer and/or vectors in a convenient way */
#define mps_new(type) ((type*)mps_malloc (sizeof(type)))
#define mps_newv(type, n) ((type*)mps_malloc (sizeof(type) * (n)))

#ifdef  __cplusplus
}
#endif

#ifdef __UNDEF_CPLUSPLUS
}
#endif

#endif                          /* MPS_INTERFACE_H */