File: polynomial.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 (396 lines) | stat: -rw-r--r-- 14,208 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
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
/*
 * 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:
 *   Dario Andrea Bini <bini@dm.unipi.it>
 *   Giuseppe Fiorentino <fiorent@dm.unipi.it>
 *   Leonardo Robol <leonardo.robol@unipi.it>
 */

#ifndef MPS_POLYNOMIAL_H_
#define MPS_POLYNOMIAL_H_


#ifdef __cplusplus
extern "C" {
#endif

#include <mps/mps.h>

/* Macro that can be used to enforce a sort of type-safe casting between
 * mps_polynomial "subclasses". Please note that this does not guarantee
 * type-safeness at all if you cast other types. */
#define MPS_POLYNOMIAL_CAST(typename, t) ((typename*)(mps_polynomial_cast (# typename, (mps_polynomial*)t)))

/* Macro to ease casting of polynomials subclasses */
#define MPS_POLYNOMIAL(t) (MPS_POLYNOMIAL_CAST (mps_polynomial, t))

/* A polynomial is completely determined by the functions that allow to operate on it.
 * The types of these functions is defined in the following. */

/**
 * @brief The type of a function that evaluates the poynomial (Standard floating point version).
 */
typedef mps_boolean (*mps_polynomial_feval_t)(mps_context  * ctx, mps_polynomial * p, cplx_t x, cplx_t value, double * error);

/**
 * @brief The type of a function that evaluates the polynomial (CDPE version).
 */
typedef mps_boolean (*mps_polynomial_deval_t)(mps_context * ctx, mps_polynomial * p, cdpe_t x, cdpe_t value, rdpe_t error);

/**
 * @brief The type of a function that evaluates the polynomial (MP version).
 * The computation must be carried out with the precision of the value \f$x\f$.
 */
typedef mps_boolean (*mps_polynomial_meval_t)(mps_context * ctx, mps_polynomial * p, mpc_t x, mpc_t value, rdpe_t error);

/**
 * @brief Function that will be used to deallocate the polynomial on context destruction.
 */
typedef void (*mps_polynomial_free_t)(mps_context * ctx, mps_polynomial *p);

/**
 * @brief Function that will be used to raise the precision of the coefficients representing
 * the polynomial to the working precision wp.
 */
typedef long int (*mps_polynomial_raise_data_t)(mps_context * ctx, mps_polynomial * p, long int wp);

/**
 * @brief Function used to determine useful starting approximation.
 *
 * This is the floating point implementation.
 */
typedef void (*mps_polynomial_fstart_t)(mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

/**
 * @brief Function used to determine useful starting approximation.
 *
 * This is the CDPE implementation.
 */
typedef void (*mps_polynomial_dstart_t)(mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

/**
 * @brief Function used to determine useful starting approximation.
 *
 * This is the MP implementation.
 */
typedef void (*mps_polynomial_mstart_t)(mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

/**
 * @brief Function that computes \f$\frac{p}{p'}\f$ (floating point version)
 */
typedef void (*mps_polynomial_fnewton_t)(mps_context * ctx, mps_polynomial * p,
                                         mps_approximation * root, cplx_t x);
/**
 * @brief Function that computes \f$\frac{p}{p'}\f$ (dpe version)
 */
typedef void (*mps_polynomial_dnewton_t)(mps_context * ctx, mps_polynomial * p,
                                         mps_approximation * root, cdpe_t corr);

/**
 * @brief Function that computes \f$\frac{p}{p'}\f$ (multiprecision version)
 */
typedef void (*mps_polynomial_mnewton_t)(mps_context * ctx, mps_polynomial * p,
                                         mps_approximation * root, mpc_t corr, long int wp);

/**
 * @brief Function that returns the leading coefficient of the polynomial.
 * This defaults to the function that returns one (i.e. the default polynomial
 * is monic).
 */
typedef void (*mps_polynomial_get_leading_coefficient_t)(mps_context * ctx, mps_polynomial * p, mpc_t lc);

/**
 * @brief Struct that represents an abstract polynomial. All the other
 * real polynomial implementations (such as mps_monomial_poly, mps_secular_equation, ...)
 * inherits from this.
 */
struct mps_polynomial {
  /**
   * @brief Name of the type. This must be a global static string that
   * can be used to check if a mps_polynomial is of a specific type.
   * It can be NULL to leave the type vague.
   */
  const char * type_name;

  /**
   * @brief The degree of the polynomial.
   */
  int degree;

  /**
   * @brief Bits of precision of the coefficients.
   *
   * The precision used in computation can be adjusted with a call to mps_polynomial_raise_data()
   * but can never be higher than the input precision.
   */
  long int prec;

  /**
   * @brief Structure of the polynomial, i.e., the algebraic
   * (or non-algebraic) structure where the coefficients
   * are found.
   */
  mps_structure structure;

  /**
   * @brief Density of the coefficients, or MPS_DENSITY_USER
   * if the coefficients (or the newton fraction) is provided
   * via a user routine
   */
  mps_density density;

  /**
   * @brief This is true if the polynomial has thread-safe methods. Note that
   * this is the default assumption set by mps_polynomial_init(). You should
   * overwrite after calling it if that's not the case.
   */
  mps_boolean thread_safe;

  /**
   * @brief Method that evaluates the polynomial.
   */
  mps_polynomial_feval_t feval;

  /**
   * @brief Method that evaluates the polynomial.
   */
  mps_polynomial_deval_t deval;

  /**
   * @brief Method that evaluates the polynomial.
   */
  mps_polynomial_meval_t meval;

  /**
   * @brief Method that collocate initial starting points.
   */
  mps_polynomial_fstart_t fstart;

  /**
   * @brief Method that collocate initial starting points.
   */
  mps_polynomial_dstart_t dstart;

  /**
   * @brief Method that collocate initial starting points.
   */
  mps_polynomial_mstart_t mstart;

  /**
   * @brief Function used to release polynomial resources.
   */
  mps_polynomial_free_t free;

  /**
   * @brief Function used to raise precision of the coefficients
   * of the representation of the polynomial.
   */
  mps_polynomial_raise_data_t raise_data;

  /**
   * @brief Function used to compute the Newton correction in a point.
   */
  mps_polynomial_fnewton_t fnewton;

  /**
   * @brief Function used to compute the Newton correction in a point.
   */
  mps_polynomial_dnewton_t dnewton;

  /**
   * @brief Function used to compute the Newton correction in a point.
   */
  mps_polynomial_mnewton_t mnewton;

  /**
   * @brief Function used to retrieve the leading coefficient of the
   * polynomial.
   */
  mps_polynomial_get_leading_coefficient_t get_leading_coefficient;
};

void mps_polynomial_init (mps_context * ctx, mps_polynomial * p);

mps_polynomial * mps_polynomial_new (mps_context * ctx);

mps_boolean mps_polynomial_check_type (mps_polynomial * p, const char * type_name);

mps_polynomial * mps_polynomial_cast (const char *type_name, mps_polynomial *p);

mps_boolean mps_polynomial_feval (mps_context * ctx, mps_polynomial * p, cplx_t x, cplx_t value, double * error);

mps_boolean mps_polynomial_deval (mps_context * ctx, mps_polynomial * p, cdpe_t x, cdpe_t value, rdpe_t error);

mps_boolean mps_polynomial_meval (mps_context * ctx, mps_polynomial * p, mpc_t x, mpc_t value, rdpe_t error);

void mps_polynomial_fstart (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

void mps_polynomial_dstart (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

void mps_polynomial_mstart (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

void mps_polynomial_free (mps_context * ctx, mps_polynomial * p);

void mps_polynomial_fnewton (mps_context * ctx, mps_polynomial *p,
                             mps_approximation * root, cplx_t corr);

void mps_polynomial_dnewton (mps_context * ctx, mps_polynomial *p,
                             mps_approximation * root, cdpe_t corr);

void mps_polynomial_mnewton (mps_context * ctx, mps_polynomial *p,
                             mps_approximation * root, mpc_t corr, long int wp);

void mps_polynomial_get_leading_coefficient (mps_context * ctx, mps_polynomial * p, mpc_t lc);

long int mps_polynomial_raise_data (mps_context * ctx, mps_polynomial * p, long int wp);

void mps_polynomial_set_input_prec (mps_context * ctx, mps_polynomial * p, long int prec);

/* functions in general-starting.c */
void mps_general_fstart (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);
void mps_general_dstart (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);
void mps_general_mstart (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

#ifdef _MPS_PRIVATE
/* Private implementation details */
#endif

#ifdef __cplusplus
}
#endif


/*
 * C++ wrapper around mps_polynomial.
 */

#ifdef __cplusplus

namespace mps {
  class Polynomial : public mps_polynomial {
public:
    /**
     * @brief This constructor has the main role of adjusting the fake vtable in the C
     * struct to reflect the actual content of the C++ implementation that may have been
     * provided in extension to this class.
     */
    explicit Polynomial (mps_context * ctx, const char * type_name = "mps_polynomial");

    /**
     * @brief Parse a polynomial from a C-style string. 
     */
    static Polynomial * fromString (mps_context * ctx, const char * inputString);

    virtual ~Polynomial ();

    /**
     * @brief Public accessor to the degree of the Polynomial.
     */
    int get_degree ()
    {
      return degree;
    }

    /**
     * @brief Evaluate the polynomial at a point.
     *
     * This method should be overloaded by subclasses of {@link Polynomial} in order
     * to provide the necessary methods to MPSolve.
     *
     * @param x The point where the {@link Polynomial} should be evaluted.
     * @param value The storage where the result of the evaluation will be stored.
     * @param error An upper bound to the error that has been computed in this operation.
     *
     * @return true if the operation was successful, false in case an exception has been
     * encountered.
     */
    virtual bool eval (mps_context * ctx, cplx_t x, cplx_t value, double * error) = 0;

    /**
     * @brief Evaluate the polynomial at a point.
     *
     * This method should be overloaded by subclasses of {@link Polynomial} in order
     * to provide the necessary methods to MPSolve.
     *
     * @param x The point where the {@link Polynomial} should be evaluted.
     * @param value The storage where the result of the evaluation will be stored.
     * @param error An upper bound to the error that has been computed in this operation.
     *
     * @return true if the operation was successful, false in case an exception has been
     * encountered.
     */
    virtual bool eval (mps_context * ctx, cdpe_t x, cdpe_t value, rdpe_t error) = 0;

    /**
     * @brief Evaluate the polynomial at a point.
     *
     * This method should be overloaded by subclasses of {@link Polynomial} in order
     * to provide the necessary methods to MPSolve.
     *
     * @param x The point where the {@link Polynomial} should be evaluted.
     * @param value The storage where the result of the evaluation will be stored.
     * @param error An upper bound to the error that has been computed in this operation.
     *
     * @return true if the operation was successful, false in case an exception has been
     * encountered.
     */
    virtual bool eval (mps_context * ctx, mpc_t x, mpc_t value, rdpe_t error) = 0;

    /**
     * @brief Raise the working precision of this polynomial to the specified
     * value.
     *
     * Note that this might be a no-op on polynomials that are defined implicitly or
     * without the need for explicit coefficients.
     */
    virtual long int raise_data_wp (mps_context * ctx, long int wp);

    virtual void start_fp (mps_context * ctx, mps_approximation ** approximations);
    virtual void start_dpe (mps_context * ctx, mps_approximation ** approximations);
    virtual void start_mp (mps_context * ctx, mps_approximation ** approximations);

    virtual void get_leading_coefficient (mps_context * ctx, mpc_t lc);

    virtual void newton (mps_context * ctx, mps_approximation * a, cplx_t x) = 0;
    virtual void newton (mps_context * ctx, mps_approximation * a, cdpe_t x) = 0;
    virtual void newton (mps_context * ctx, mps_approximation * a, mpc_t x, long int wp) = 0;

public:
    static mps_boolean feval_wrapper (mps_context * ctx, mps_polynomial *p,
                                      cplx_t x, cplx_t value, double * error);

    static mps_boolean deval_wrapper (mps_context * ctx, mps_polynomial *p,
                                      cdpe_t x, cdpe_t value, rdpe_t error);

    static mps_boolean meval_wrapper (mps_context * ctx, mps_polynomial *p,
                                      mpc_t x, mpc_t value, rdpe_t error);

    static void free_wrapper (mps_context * ctx, mps_polynomial * p);

    static long int raise_data_wrapper (mps_context * ctx, mps_polynomial * p,
                                        long int wp);

    static void fstart_wrapper (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);
    static void dstart_wrapper (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);
    static void mstart_wrapper (mps_context * ctx, mps_polynomial * p, mps_approximation ** approximations);

    static void fnewton_wrapper (mps_context * ctx, mps_polynomial * p,
                                 mps_approximation * a, cplx_t x);
    static void dnewton_wrapper (mps_context * ctx, mps_polynomial * p,
                                 mps_approximation * a, cdpe_t x);
    static void mnewton_wrapper (mps_context * ctx, mps_polynomial * p,
                                 mps_approximation * a, mpc_t x,
                                 long int wp);

    static void get_leading_coefficient_wrapper (mps_context * ctx, mps_polynomial * p,
                                                 mpc_t leading_coefficient);
  };
}

#endif /* __cplusplus */

#endif