1 /*
2  * This file is part of MPSolve 3.2.1
3  *
4  * Copyright (C) 2001-2020, Dipartimento di Matematica "L. Tonelli", Pisa.
5  * License: http://www.gnu.org/licenses/gpl.html GPL version 3 or higher
6  *
7  * Authors:
8  *   Leonardo Robol <leonardo.robol@unipi.it>
9  */
10 
11 #ifndef MPS_MONOMIAL_MATRIX_POLY_H_
12 #define MPS_MONOMIAL_MATRIX_POLY_H_
13 
14 /**
15  * @file
16  * @brief Implementation of the monomial version of the matrix
17  * polynomial.
18  */
19 
20 #include <mps/polynomial.h>
21 
22 #define MPS_MONOMIAL_MATRIX_POLY(t) (MPS_POLYNOMIAL_CAST (mps_monomial_matrix_poly, t))
23 #define MPS_IS_MONOMIAL_MATRIX_POLY(t) \
24   (mps_polynomial_check_type (t, "mps_monomial_matrix_poly"))
25 
26 #ifdef  __cplusplus
27 extern "C"
28 {
29 #endif
30 
31 #define MPS_MONOMIAL_MATRIX_POLY_HESSENBERG 0x0001
32 
33 #ifdef _MPS_PRIVATE
34 
35 /**
36  * @brief This is the struct that holds all the data of the matrix
37  * polynomial.
38  */
39 struct mps_monomial_matrix_poly {
40   /**
41    * @brief Implementation of the overloaded methods for the
42    * matrix polynomial.
43    */
44   mps_polynomial methods;
45 
46   /**
47    * @brief If this flag is set to true then the
48    * higher degree term of the polynomial is the identity
49    * matrix and so doesn't need to be allocated and/or
50    * accessed in any way.
51    *
52    * In particular, it's not guaranteed to be available for
53    * the computations, so you should always check if this flag
54    * is set before trying to operate on P[n].
55    */
56   mps_boolean monic;
57 
58   /**
59    * @brief The size of the matrices that compose the matrix
60    * polynomial.
61    */
62   int m;
63 
64   /**
65    * @brief Degree of the matrix polynomial. Please note that this values if different
66    * from the degree value in the polynomial structure, since that is the degree of the
67    * scalar polynomial, and this is the degree of the matrix one.
68    */
69   int degree;
70 
71   /**
72    * @brief The double version of the polynomial coefficients.
73    *
74    * NOTE: At this stage, this is the only type of data that is kept
75    * for the matrix polynomial.
76    */
77   cplx_t * P;
78 
79   /**
80    * @brief The multiprecision version of the polynomial coefficients.
81    */
82   mpc_t * mP;
83 
84   /**
85    * @brief The rational version of the polynomial coefficients.
86    * This is used only if the structure of the monomial matrix poly
87    * is MPS_STRUCTURE_*_INTEGER OR MPS_STRUCTURE_*_RATIONAL.
88    *
89    * This array holds the real part of the coefficients.
90    */
91   mpq_t * mpqPr;
92 
93   /**
94    * @brief The rational version of the polynomial coefficients.
95    * This is used only if the structure of the monomial matrix poly
96    * is MPS_STRUCTURE_*_INTEGER OR MPS_STRUCTURE_*_RATIONAL.
97    *
98    * This array holds the real part of the coefficients.
99    */
100   mpq_t * mpqPi;
101 
102   /**
103    * @brief Additional properties of this polynomial. Examples are:
104    * MPS_MONOMIAL_MATRIX_POLY_HESSENBERG, ...
105    *
106    * @seealso mps_monomial_matrix_poly_add_flag(),
107    * @seealso mps_monomial_matrix_poly_clear_flags().
108    */
109   int flags;
110 };
111 
112 
113 #endif /* _MPS_PRIVATE */
114 
115 /* From here on you will find declaration of the public method
116    available for the matrix polynomials */
117 
118 /**
119  * @brief Create a new matrix polynomial of the given degree.
120  *
121  * @param ctx The current mps_context.
122  * @param degree The degree of the matrix polynomial.
123  * @param m The size of the matrices that compose the matrix polynomial.
124  * @param monic A boolean value that, if set to true, specify that the leading
125  *              coefficient of the polynomial is the identity matrix, and so
126  *              should not specified explicitely.
127  * @return A pointer to a newly allocated mps_monomial_matrix_poly that should
128  * be subsequently free with a call to mps_monomial_matrix_poly_free().
129  */
130 mps_monomial_matrix_poly* mps_monomial_matrix_poly_new (mps_context * ctx,
131                                                         int degree,
132                                                         int m,
133                                                         mps_boolean monic);
134 /**
135  * @brief Free a matrix polynomial.
136  *
137  * @param ctx The current mps_context.
138  * @param poly The mps_monomial_matrix_poly that should be freed, casted to
139  *             a mps_polynomial* pointer.
140  */
141 void mps_monomial_matrix_poly_free (mps_context * ctx,
142                                     mps_polynomial * poly);
143 
144 /**
145  * @brief Add some flags (some properties) to this matrix polynomial.
146  *
147  * @param ctx The current mps_context
148  * @param mpoly The matrix polynomial.
149  * @param flag The flags to add.
150  */
151 void mps_monomial_matrix_poly_add_flags (mps_context * ctx,
152                                          mps_monomial_matrix_poly * mpoly,
153                                          int flag);
154 
155 /**
156  * @brief Clear some flags (properties) of this matrix polynomial.
157  *
158  * @param ctx The current mps_context
159  * @param mpoly The matrix polynomial.
160  * @param flag The flags to clear.
161  */
162 void mps_monomial_matrix_poly_clear_flags (mps_context * ctx,
163                                            mps_monomial_matrix_poly * mpoly,
164                                            int flag);
165 
166 /**
167  * @brief Set the coefficient of degree i of the matrix polynomial.
168  *
169  * @param ctx The current mps_context
170  * @param mpoly The mps_monomial_matrix_poly where the coefficients should be
171  * set.
172  * @param i The degree of the coeffient to set.
173  * @param matrix A pointer to the first element of the matrix stored in row-major order.
174  */
175 void mps_monomial_matrix_poly_set_coefficient_d (mps_context * ctx,
176                                                  mps_monomial_matrix_poly *mpoly,
177                                                  int i,
178                                                  cplx_t * matrix);
179 
180 /**
181  * @brief Set the coefficient of degree i of the matrix polynomial.
182  *
183  * @param ctx The current mps_context
184  * @param mpoly The mps_monomial_matrix_poly where the coefficients should be
185  * set.
186  * @param i The degree of the coeffient to set.
187  * @param matrix_r A pointer to the first element of the matrix of the real parts
188  * of the coefficients, stored in row-major order
189  * @param matrix_i A pointer to the first element of the matrix of the imaginary parts
190  * of the coefficients, stored in row-major order
191  */
192 void mps_monomial_matrix_poly_set_coefficient_q (mps_context * ctx,
193                                                  mps_monomial_matrix_poly *mpoly,
194                                                  int i,
195                                                  mpq_t * matrix_r,
196                                                  mpq_t * matrix_i);
197 
198 /**
199  * @brief Evaluate a matrix polynomial at a point, in the sense of
200  * evaluating \f$det(P(x))\f$.
201  *
202  * @param ctx The current mps_context
203  * @param poly The matrix polynomial to evaluate
204  * @param x The point in which the evaluation is requested
205  * @param value The value of \f$det(P(x))\f$
206  * @param error An upper bound to the absolute error that affects the result.
207  * @return true if the evaluation was successful.
208  */
209 mps_boolean mps_monomial_matrix_poly_meval (mps_context * ctx,
210                                             mps_polynomial * poly,
211                                             mpc_t x,
212                                             mpc_t value,
213                                             rdpe_t error);
214 
215 /**
216  * @brief Raise the working precision of this monomial matrix polynomal
217  * to the required numnber of bits.
218  *
219  * @param ctx The current mps_context.
220  * @param p The polynomial whose working precision should be set.
221  * @param wp The bits of desired working precision.
222  * @return The precision set in the polynomial. Note that this value
223  * may be higher than wp due to the fact that, in general, not all
224  * the precisions are available on the system and the first higher precision
225  * of the value required will be used.
226  */
227 long int
228 mps_monomial_matrix_poly_raise_data (mps_context * ctx,
229                                      mps_polynomial * p,
230                                      long int wp);
231 
232 #ifdef  __cplusplus
233 }
234 #endif
235 
236 
237 #endif /* __MPS_MONOMIAL_MATRIX_POLY_H */
238