11#include "acb_types.h"
22#include "acb_poly.h"
33#include "acb_mat.h"
4- #include "fmpq_types.h"
5- #include "fmpq_poly.h"
64#include "acb_holonomic.h"
5+ #include "gr.h"
6+ #include "gr_poly.h"
77
88
99void
@@ -43,7 +43,7 @@ ordinary(void)
4343 acb_poly_set_coeff_si (ctx -> dop + 1 , 0 , 2 );
4444 acb_poly_set_coeff_si (ctx -> dop + 0 , 4 , 7 );
4545
46- ctx -> flags |= ACB_HOLONOMIC_WANT_SERIES ;
46+ /* ctx->flags |= ACB_HOLONOMIC_WANT_SERIES; */
4747
4848 acb_holonomic_sum_ordinary (ctx );
4949 acb_holonomic_sum_canonical_basis (ctx );
@@ -142,9 +142,14 @@ void
142142whittaker_m (void ) /* non-integer exponent, no logs */
143143{
144144 acb_t kappa , mu2 , half ;
145+ acb_poly_t val ;
146+
145147 acb_init (kappa );
146148 acb_init (mu2 );
147149 acb_init (half );
150+ acb_poly_init (val );
151+
152+ acb_holonomic_sum_context_t ctx ;
148153
149154 acb_set_si (kappa , 2 );
150155 acb_set_si (mu2 , 3 );
@@ -154,8 +159,6 @@ whittaker_m(void) /* non-integer exponent, no logs */
154159 slong dop_order = 2 ;
155160 slong len = dop_order ;
156161
157- acb_holonomic_sum_context_t ctx ;
158-
159162 acb_holonomic_sum_context_init (ctx , dop_order + 1 , 1 , 1 , len );
160163
161164 acb_poly_set_coeff_si (ctx -> dop + 2 , 0 , 4 );
@@ -166,7 +169,7 @@ whittaker_m(void) /* non-integer exponent, no logs */
166169 acb_addmul_si ((ctx -> dop + 0 )-> coeffs + 0 , mu2 , -4 , prec );
167170
168171 acb_sqrt (ctx -> expo , mu2 , prec );
169- acb_add (ctx -> expo , ctx -> expo , half , prec ); /* sub for other expo */
172+ acb_add (ctx -> expo , ctx -> expo , half , prec ); /* other expo = mu2 - 1/2 */
170173
171174 ctx -> sing_shifts [0 ].n = 0 ;
172175 ctx -> sing_shifts [0 ].mult = 1 ;
@@ -180,38 +183,120 @@ whittaker_m(void) /* non-integer exponent, no logs */
180183
181184 acb_holonomic_sum_divconquer (ctx , prec );
182185
183- flint_printf ("(%{acb} + x)^(%{acb}) * (%{acb_poly})\n" ,
184- ctx -> pts , ctx -> expo ,
185- acb_holonomic_sol_sum_ptr (ctx -> sol , 0 , 0 ));
186+ acb_poly_struct * f = acb_holonomic_sol_sum_ptr (ctx -> sol , 0 , 0 );
186187
187- acb_poly_t tmp ;
188- acb_poly_init (tmp );
189- acb_poly_set_coeff_si (tmp , 1 , 1 );
190- acb_poly_set_coeff_acb (tmp , 0 , ctx -> pts );
191- acb_poly_pow_acb_series (tmp , tmp , ctx -> expo , len , prec );
192- acb_poly_mullow (tmp , tmp , acb_holonomic_sol_sum_ptr (ctx -> sol , 0 , 0 ), len , prec );
188+ flint_printf ("(%{acb} + x)^(%{acb}) * (%{acb_poly})\n" ,
189+ ctx -> pts , ctx -> expo , f );
193190
194- flint_printf ("M(%{acb} + x) = %{acb_poly} + O(x^%wd)\n" , ctx -> pts , tmp , len );
191+ _acb_holonomic_sol_value (val , ctx -> expo , f , ctx -> sol [0 ].nlogs , ctx -> pts ,
192+ ctx -> nder , 1 , ctx -> prec );
195193
196- acb_poly_clear ( tmp );
194+ flint_printf ( "M(%{acb} + x) = %{acb_poly} + O(x^%wd)\n" , ctx -> pts , val , len );
197195
198196 acb_holonomic_sum_context_clear (ctx );
199197 acb_clear (kappa );
200198 acb_clear (mu2 );
201199 acb_clear (half );
200+ acb_poly_clear (val );
202201}
203202
204203
205- /* TODO once we have more support for extracting the results: Apéry */
204+ void
205+ fundamental_matrix (const char * dop_str ,
206+ const acb_holonomic_exponents_struct * expos ,
207+ double pt_d )
208+ {
209+ gr_ctx_t CC , Pol , Dop ;
210+ gr_ptr dop ;
211+
212+ slong prec = 30 ;
213+
214+ int status = GR_SUCCESS ;
215+
216+ gr_ctx_init_complex_acb (CC , prec );
217+ gr_ctx_init_gr_poly (Pol , CC );
218+ gr_ctx_init_gr_poly (Dop , Pol ); /* should be Ore poly */
219+
220+ GR_TMP_INIT (dop , Dop );
221+
222+ status |= gr_ctx_set_gen_name (Pol , "z" );
223+ status |= gr_ctx_set_gen_name (Dop , "Tz" );
224+ status |= gr_set_str (dop , dop_str , Dop );
225+ status |= gr_println (dop , Dop );
226+ GR_MUST_SUCCEED (status );
227+
228+ slong dop_order = gr_poly_length (dop , Dop ) - 1 ;
229+
230+ acb_mat_t mat ;
231+ acb_mat_init (mat , dop_order , dop_order );
232+
233+ acb_t pt ;
234+ acb_init (pt );
235+ acb_set_d (pt , pt_d );
236+
237+ acb_holonomic_fundamental_matrix (mat , dop , Dop , expos , pt , 1 , 0 , 8 , prec );
238+
239+ flint_printf ("%{acb_mat}\n" , mat );
240+
241+ acb_mat_clear (mat );
242+ GR_TMP_CLEAR (dop , Dop );
243+ gr_ctx_clear (Dop );
244+ gr_ctx_clear (Pol );
245+ gr_ctx_clear (CC );
246+ acb_clear (pt );
247+ }
248+
249+
250+ void
251+ apery (void )
252+ {
253+ acb_holonomic_shift_struct shift [1 ] = {{ .n = 0 , .mult = 3 }};
254+ acb_holonomic_group_struct grp [1 ] = {{ .nshifts = 1 , .shifts = shift }};
255+ acb_init (grp -> expo );
256+ acb_zero (grp -> expo );
257+ acb_holonomic_exponents_struct expos [1 ] = {{ .len = 1 , .grps = grp }};
258+
259+ fundamental_matrix (
260+ "(z^2 - 34*z + 1)*Tz^3 + (3*z^2 - 51*z)*Tz^2 + (3*z^2 - 27*z)*Tz + z^2 - 5*z" ,
261+ expos ,
262+ 0.015625 );
263+
264+ acb_clear (grp -> expo );
265+ }
266+
267+
268+ void
269+ multiple_shifts (void )
270+ {
271+ /* const char * dop = "Tz^4 - 4*Tz^3 + 3*Tz^2 - z"; */
272+ const char * dop = "Tz^6 - 6*Tz^5 + 12*Tz^4 - 10*Tz^3 + 3*Tz^2 + z^2" ;
273+
274+ acb_holonomic_shift_struct shift [3 ] = {
275+ { .n = 0 , .mult = 2 },
276+ { .n = 1 , .mult = 3 },
277+ { .n = 3 , .mult = 1 },
278+ };
279+ acb_holonomic_group_struct grp [1 ] = {{ .nshifts = 3 , .shifts = shift }};
280+ acb_init (grp -> expo );
281+ acb_zero (grp -> expo );
282+ acb_holonomic_exponents_struct expos [1 ] = {{ .len = 1 , .grps = grp }};
283+
284+ fundamental_matrix (dop , expos , 2. );
285+
286+ acb_clear (grp -> expo );
287+ }
206288
207289
208290int
209291main (void )
210292{
211- ordinary ();
212- series ();
213- bessel_j0 ();
214- whittaker_m ();
293+ /* ordinary(); */
294+ /* series(); */
295+ /* bessel_j0(); */
296+ /* whittaker_m(); */
297+
298+ /* apery(); */
299+ multiple_shifts ();
215300
216301 flint_cleanup_master ();
217302}
0 commit comments