File: padic_poly.rst

package info (click to toggle)
flint 3.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 68,996 kB
  • sloc: ansic: 915,350; asm: 14,605; python: 5,340; sh: 4,512; lisp: 2,621; makefile: 787; cpp: 341
file content (545 lines) | stat: -rw-r--r-- 21,487 bytes parent folder | download | duplicates (2)
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
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
.. _padic-poly:

**padic_poly.h** -- polynomials over p-adic numbers
===============================================================================

Module documentation
--------------------------------------------------------------------------------

We represent a polynomial in `\mathbf{Q}_p[x]` as a 
product `p^v f(x)`, where `p` is a prime number, 
`v \in \mathbf{Z}` and `f(x) \in \mathbf{Z}[x]`.
As a data structure, we call this polynomial *normalised* 
if the polynomial `f(x)` is *normalised*, that is, if the top 
coefficient is non-zero.
We say this polynomial is in *canonical form* if one of the 
coefficients of `f(x)` is a `p`-adic unit.  If `f(x)` is the zero 
polynomial, we require that `v = 0`.
We say this polynomial is *reduced* modulo `p^N` if it is 
canonical form and if all coefficients lie in the range `[0, p^N)`.


Memory management
--------------------------------------------------------------------------------


.. function:: void padic_poly_init(padic_poly_t poly)

    Initialises ``poly`` for use, setting its length to zero.  
    The precision of the polynomial is set to ``PADIC_DEFAULT_PREC``. 
    A corresponding call to :func:`padic_poly_clear` must be made 
    after finishing with the :type:`padic_poly_t` to free the memory 
    used by the polynomial.

.. function:: void padic_poly_init2(padic_poly_t poly, slong alloc, slong prec)

    Initialises ``poly`` with space for at least ``alloc`` coefficients 
    and sets the length to zero.  The allocated coefficients are all set to 
    zero.  The precision is set to ``prec``.

.. function:: void padic_poly_realloc(padic_poly_t poly, slong alloc, const fmpz_t p)

    Reallocates the given polynomial to have space for ``alloc`` 
    coefficients.  If ``alloc`` is zero the polynomial is cleared 
    and then reinitialised.  If the current length is greater than 
    ``alloc`` the polynomial is first truncated to length ``alloc``.

.. function:: void padic_poly_fit_length(padic_poly_t poly, slong len)

    If ``len`` is greater than the number of coefficients currently 
    allocated, then the polynomial is reallocated to have space for at 
    least ``len`` coefficients.  No data is lost when calling this 
    function.

    The function efficiently deals with the case where ``fit_length`` is 
    called many times in small increments by at least doubling the number 
    of allocated coefficients when length is larger than the number of 
    coefficients currently allocated.

.. function:: void _padic_poly_set_length(padic_poly_t poly, slong len)

    Demotes the coefficients of ``poly`` beyond ``len`` and sets 
    the length of ``poly`` to ``len``.

    Note that if the current length is greater than ``len`` the 
    polynomial may no slonger be in canonical form.

.. function:: void padic_poly_clear(padic_poly_t poly)

    Clears the given polynomial, releasing any memory used.  It must 
    be reinitialised in order to be used again.

.. function:: void _padic_poly_normalise(padic_poly_t poly)

    Sets the length of ``poly`` so that the top coefficient is non-zero. 
    If all coefficients are zero, the length is set to zero.  This function 
    is mainly used internally, as all functions guarantee normalisation.

.. function:: void _padic_poly_canonicalise(fmpz * poly, slong * v, slong len, const fmpz_t p)
              void padic_poly_canonicalise(padic_poly_t poly, const fmpz_t p)

    Brings the polynomial ``poly`` into canonical form, 
    assuming that it is normalised already.  Does *not* 
    carry out any reduction.

.. function:: void padic_poly_reduce(padic_poly_t poly, const padic_ctx_t ctx)

    Reduces the polynomial ``poly`` modulo `p^N`, assuming 
    that it is in canonical form already.

.. function:: void padic_poly_truncate(padic_poly_t poly, slong n, const fmpz_t p)

    Truncates the polynomial to length at most~`n`.


Polynomial parameters
--------------------------------------------------------------------------------


.. function:: slong padic_poly_degree(const padic_poly_t poly)

    Returns the degree of the polynomial ``poly``.

.. function:: slong padic_poly_length(const padic_poly_t poly)

    Returns the length of the polynomial ``poly``.

.. function:: slong padic_poly_val(const padic_poly_t poly)

    Returns the valuation of the polynomial ``poly``, 
    which is defined to be the minimum valuation of all 
    its coefficients.

    The valuation of the zero polynomial is~`0`.

    Note that this is implemented as a macro and can be 
    used as either a ``lvalue`` or a ``rvalue``.

.. function:: slong padic_poly_prec(padic_poly_t poly)

    Returns the precision of the polynomial ``poly``. 

    Note that this is implemented as a macro and can be 
    used as either a ``lvalue`` or a ``rvalue``.

    Note that increasing the precision might require 
    a call to :func:`padic_poly_reduce`.


Randomisation
--------------------------------------------------------------------------------


.. function:: void padic_poly_randtest(padic_poly_t f, flint_rand_t state, slong len, const padic_ctx_t ctx)

    Sets `f` to a random polynomial of length at most ``len`` 
    with entries reduced modulo `p^N`.

.. function:: void padic_poly_randtest_not_zero(padic_poly_t f, flint_rand_t state, slong len, const padic_ctx_t ctx)

    Sets `f` to a non-zero random polynomial of length at most ``len`` 
    with entries reduced modulo `p^N`.

.. function:: void padic_poly_randtest_val(padic_poly_t f, flint_rand_t state, slong val, slong len, const padic_ctx_t ctx)

    Sets `f` to a random polynomial of length at most ``len`` 
    with at most the prescribed valuation ``val`` and entries 
    reduced modulo `p^N`.

    Specifically, we aim to set the valuation to be exactly equal 
    to ``val``, but do not check for additional cancellation 
    when creating the coefficients.


Assignment and basic manipulation
--------------------------------------------------------------------------------


.. function:: void padic_poly_set_padic(padic_poly_t poly, const padic_t x, const padic_ctx_t ctx)

    Sets the polynomial ``poly`` to the `p`-adic number `x`, 
    reduced to the precision of the polynomial.

.. function:: void padic_poly_set(padic_poly_t poly1, const padic_poly_t poly2, const padic_ctx_t ctx)

    Sets the polynomial ``poly1`` to the polynomial ``poly2``, 
    reduced to the precision of ``poly1``.

.. function:: void padic_poly_set_si(padic_poly_t poly, slong x, const padic_ctx_t ctx)

    Sets the polynomial ``poly`` to the ``signed slong`` 
    integer `x` reduced to the precision of the polynomial.

.. function:: void padic_poly_set_ui(padic_poly_t poly, ulong x, const padic_ctx_t ctx)

    Sets the polynomial ``poly`` to the ``unsigned slong`` 
    integer `x` reduced to the precision of the polynomial.

.. function:: void padic_poly_set_fmpz(padic_poly_t poly, const fmpz_t x, const padic_ctx_t ctx)

    Sets the polynomial ``poly`` to the integer `x` 
    reduced to the precision of the polynomial.

.. function:: void padic_poly_set_fmpq(padic_poly_t poly, const fmpq_t x, const padic_ctx_t ctx)

    Sets the polynomial ``poly`` to the value of the rational `x`, 
    reduced to the precision of the polynomial.

.. function:: void padic_poly_set_fmpz_poly(padic_poly_t rop, const fmpz_poly_t op, const padic_ctx_t ctx)

    Sets the polynomial ``rop`` to the integer polynomial ``op``
    reduced to the precision of the polynomial.

.. function:: void padic_poly_set_fmpq_poly(padic_poly_t rop, const fmpq_poly_t op, const padic_ctx_t ctx)

    Sets the polynomial ``rop`` to the value of the rational 
    polynomial ``op``, reduced to the precision of the polynomial.

.. function:: int padic_poly_get_fmpz_poly(fmpz_poly_t rop, const padic_poly_t op, const padic_ctx_t ctx)

    Sets the integer polynomial ``rop`` to the value of the `p`-adic 
    polynomial ``op`` and returns `1` if the polynomial is `p`-adically 
    integral.  Otherwise, returns `0`.

.. function:: void padic_poly_get_fmpq_poly(fmpq_poly_t rop, const padic_poly_t op, const padic_ctx_t ctx)

    Sets ``rop`` to the rational polynomial corresponding to 
    the `p`-adic polynomial ``op``.

.. function:: void padic_poly_zero(padic_poly_t poly)

    Sets ``poly`` to the zero polynomial.

.. function:: void padic_poly_one(padic_poly_t poly)

    Sets ``poly`` to the constant polynomial `1`, 
    reduced to the precision of the polynomial.

.. function:: void padic_poly_swap(padic_poly_t poly1, padic_poly_t poly2)

    Swaps the two polynomials ``poly1`` and ``poly2``, 
    including their precisions.

    This is done efficiently by swapping pointers.


Getting and setting coefficients
--------------------------------------------------------------------------------


.. function:: void padic_poly_get_coeff_padic(padic_t c, const padic_poly_t poly, slong n, const padic_ctx_t ctx)

    Sets `c` to the coefficient of `x^n` in the polynomial, 
    reduced modulo the precision of `c`.

.. function:: void padic_poly_set_coeff_padic(padic_poly_t f, slong n, const padic_t c, const padic_ctx_t ctx)

    Sets the coefficient of `x^n` in the polynomial `f` to `c`, 
    reduced to the precision of the polynomial `f`.

    Note that this operation can take linear time in the length 
    of the polynomial.


Comparison
--------------------------------------------------------------------------------


.. function:: int padic_poly_equal(const padic_poly_t poly1, const padic_poly_t poly2)

    Returns whether the two polynomials ``poly1`` and ``poly2`` 
    are equal.

.. function:: int padic_poly_is_zero(const padic_poly_t poly)

    Returns whether the polynomial ``poly`` is the zero polynomial.

.. function:: int padic_poly_is_one(const padic_poly_t poly)

    Returns whether the polynomial ``poly`` is equal 
    to the constant polynomial~`1`, taking the precision 
    of the polynomial into account.


Addition and subtraction
--------------------------------------------------------------------------------


.. function:: void _padic_poly_add(fmpz * rop, slong * rval, slong N, const fmpz * op1, slong val1, slong len1, slong N1, const fmpz * op2, slong val2, slong len2, slong N2, const padic_ctx_t ctx)

    Sets ``(rop, *val, FLINT_MAX(len1, len2)`` to the sum of 
    ``(op1, val1, len1)`` and ``(op2, val2, len2)``.

    Assumes that the input is reduced and guarantees that this is 
    also the case for the output.

    Assumes that `\min\{v_1, v_2\} < N`.

    Supports aliasing between the output and input arguments.

.. function:: void padic_poly_add(padic_poly_t f, const padic_poly_t g, const padic_poly_t h, const padic_ctx_t ctx)

    Sets `f` to the sum `g + h`.

.. function:: void _padic_poly_sub(fmpz * rop, slong * rval, slong N, const fmpz * op1, slong val1, slong len1, slong N1, const fmpz * op2, slong val2, slong len2, slong N2, const padic_ctx_t ctx)

    Sets ``(rop, *val, FLINT_MAX(len1, len2)`` to the difference of 
    ``(op1, val1, len1)`` and ``(op2, val2, len2)``.

    Assumes that the input is reduced and guarantees that this is 
    also the case for the output.

    Assumes that `\min\{v_1, v_2\} < N`.

    Support aliasing between the output and input arguments.

.. function:: void padic_poly_sub(padic_poly_t f, const padic_poly_t g, const padic_poly_t h, const padic_ctx_t ctx)

    Sets `f` to the difference `g - h`.

.. function:: void padic_poly_neg(padic_poly_t f, const padic_poly_t g, const padic_ctx_t ctx)

    Sets `f` to `-g`.


Scalar multiplication
--------------------------------------------------------------------------------


.. function:: void _padic_poly_scalar_mul_padic(fmpz * rop, slong * rval, slong N, const fmpz * op, slong val, slong len, const padic_t c, const padic_ctx_t ctx)

    Sets ``(rop, *rval, len)`` to ``(op, val, len)`` multiplied 
    by the scalar `c`.

    The result will only be correctly reduced if the polynomial 
    is non-zero.  Otherwise, the array ``(rop, len)`` will be 
    set to zero but the valuation ``*rval`` might be wrong.

.. function:: void padic_poly_scalar_mul_padic(padic_poly_t rop, const padic_poly_t op, const padic_t c, const padic_ctx_t ctx)

    Sets the polynomial ``rop`` to the product of the 
    polynomial ``op`` and the `p`-adic number `c`, 
    reducing the result modulo `p^N`.


Multiplication
--------------------------------------------------------------------------------


.. function:: void _padic_poly_mul(fmpz * rop, slong * rval, slong N, const fmpz * op1, slong val1, slong len1, const fmpz * op2, slong val2, slong len2, const padic_ctx_t ctx)

    Sets ``(rop, *rval, len1 + len2 - 1)`` to the product of 
    ``(op1, val1, len1)`` and ``(op2, val2, len2)``.

    Assumes that the resulting valuation ``*rval``, which is 
    the sum of the valuations ``val1`` and ``val2``, is less 
    than the precision~`N` of the context.

    Assumes that ``len1 >= len2 > 0``.

.. function:: void padic_poly_mul(padic_poly_t res, const padic_poly_t poly1, const padic_poly_t poly2, const padic_ctx_t ctx)

    Sets the polynomial ``res`` to the product of the two polynomials 
    ``poly1`` and ``poly2``, reduced modulo `p^N`.


Powering
--------------------------------------------------------------------------------


.. function:: void _padic_poly_pow(fmpz * rop, slong * rval, slong N, const fmpz * op, slong val, slong len, ulong e, const padic_ctx_t ctx)

    Sets the polynomial ``(rop, *rval, e (len - 1) + 1)`` to the 
    polynomial ``(op, val, len)`` raised to the power~`e`.

    Assumes that `e > 1` and ``len > 0``.

    Does not support aliasing between the input and output arguments.

.. function:: void padic_poly_pow(padic_poly_t rop, const padic_poly_t op, ulong e, const padic_ctx_t ctx)

    Sets the polynomial ``rop`` to the polynomial ``op`` raised 
    to the power~`e`, reduced to the precision in ``rop``.

    In the special case `e = 0`, sets ``rop`` to the constant 
    polynomial one reduced to the precision of ``rop``.  
    Also note that when `e = 1`, this operation sets ``rop`` to 
    ``op`` and then reduces ``rop``.

    When the valuation of the input polynomial is negative, 
    this results in a loss of `p`-adic precision.  Suppose 
    that the input polynomial is given to precision~`N` and 
    has valuation~`v < 0`.  The result then has valuation 
    `e v < 0` but is only correct to precision `N + (e - 1) v`.


Series inversion
--------------------------------------------------------------------------------


.. function:: void padic_poly_inv_series(padic_poly_t g, const padic_poly_t f, slong n, const padic_ctx_t ctx)

    Computes the power series inverse `g` of `f` modulo `X^n`, 
    where `n \geq 1`.

    Given the polynomial `f \in \mathbf{Q}[X] \subset \mathbf{Q}_p[X]`, 
    there exists a unique polynomial `f^{-1} \in \mathbf{Q}[X]` such that 
    `f f^{-1} = 1` modulo `X^n`.  This function sets `g` to `f^{-1}` 
    reduced modulo `p^N`.

    Assumes that the constant coefficient of `f` is non-zero.

    Moreover, assumes that the valuation of the constant coefficient 
    of `f` is minimal among the coefficients of `f`.

    Note that the result `g` is zero if and only if  `- \operatorname{ord}_p(f) \geq N`.


Derivative
--------------------------------------------------------------------------------


.. function:: void _padic_poly_derivative(fmpz * rop, slong * rval, slong N, const fmpz * op, slong val, slong len, const padic_ctx_t ctx)

    Sets ``(rop, rval)`` to the derivative of ``(op, val)`` reduced 
    modulo `p^N`.

    Supports aliasing of the input and the output parameters.

.. function:: void padic_poly_derivative(padic_poly_t rop, const padic_poly_t op, const padic_ctx_t ctx)

    Sets ``rop`` to the derivative of ``op``, reducing the 
    result modulo the precision of ``rop``.


Shifting
--------------------------------------------------------------------------------


.. function:: void padic_poly_shift_left(padic_poly_t rop, const padic_poly_t op, slong n, const padic_ctx_t ctx)

    Notationally, sets the polynomial ``rop`` to the polynomial ``op`` 
    multiplied by `x^n`, where `n \geq 0`, and reduces the result.

.. function:: void padic_poly_shift_right(padic_poly_t rop, const padic_poly_t op, slong n, const padic_ctx_t ctx)

    Notationally, sets the polynomial ``rop`` to the polynomial 
    ``op`` after floor division by `x^n`, where `n \geq 0`, ensuring 
    the result is reduced.


Evaluation
--------------------------------------------------------------------------------


.. function:: void _padic_poly_evaluate_padic(fmpz_t u, slong * v, slong N, const fmpz * poly, slong val, slong len, const fmpz_t a, slong b, const padic_ctx_t ctx)
              void padic_poly_evaluate_padic(padic_t y, const padic_poly_t poly, const padic_t a, const padic_ctx_t ctx)

    Sets the `p`-adic number ``y`` to ``poly`` evaluated at `a`, 
    reduced in the given context.

    Suppose that the polynomial can be written as `F(X) = p^w f(X)` 
    with `\operatorname{ord}_p(f) = 1`, that `\operatorname{ord}_p(a) = b` and that both are 
    defined to precision~`N`.  Then `f` is defined to precision 
    `N-w` and so `f(a)` is defined to precision `N-w` when `a` is 
    integral and `N-w+(n-1)b` when `b < 0`, where `n = \deg(f)`.  Thus, 
    `y = F(a)` is defined to precision `N` when `a` is integral and 
    `N+(n-1)b` when `b < 0`.


Composition
--------------------------------------------------------------------------------


.. function:: void _padic_poly_compose(fmpz * rop, slong * rval, slong N, const fmpz * op1, slong val1, slong len1, const fmpz * op2, slong val2, slong len2, const padic_ctx_t ctx)

    Sets ``(rop, *rval, (len1-1)*(len2-1)+1)`` to the composition 
    of the two input polynomials, reducing the result modulo `p^N`.

    Assumes that ``len1`` is non-zero.

    Does not support aliasing.

.. function:: void padic_poly_compose(padic_poly_t rop, const padic_poly_t op1, const padic_poly_t op2, const padic_ctx_t ctx)

    Sets ``rop`` to the composition of ``op1`` and ``op2``, 
    reducing the result in the given context.

    To be clear about the order of composition, let `f(X)` and `g(X)` 
    denote the polynomials ``op1`` and ``op2``, respectively. 
    Then ``rop`` is set to `f(g(X))`.

.. function:: void _padic_poly_compose_pow(fmpz * rop, slong * rval, slong N, const fmpz * op, slong val, slong len, slong k, const padic_ctx_t ctx)

    Sets ``(rop, *rval, (len - 1)*k + 1)`` to the composition of 
    ``(op, val, len)`` and the monomial `x^k`, where `k \geq 1`.

    Assumes that ``len`` is positive.

    Supports aliasing between the input and output polynomials.

.. function:: void padic_poly_compose_pow(padic_poly_t rop, const padic_poly_t op, slong k, const padic_ctx_t ctx)

    Sets ``rop`` to the composition of ``op`` and the monomial `x^k`, 
    where `k \geq 1`.

    Note that no reduction takes place.


Input and output
--------------------------------------------------------------------------------


.. function:: int padic_poly_debug(const padic_poly_t poly)

    Prints the data defining the `p`-adic polynomial ``poly`` 
    in a simple format useful for debugging purposes.

    In the current implementation, always returns `1`.

.. function:: int _padic_poly_fprint(FILE * file, const fmpz * poly, slong val, slong len, const padic_ctx_t ctx)
              int padic_poly_fprint(FILE * file, const padic_poly_t poly, const padic_ctx_t ctx)

    Prints a simple representation of the polynomial ``poly`` 
    to the stream ``file``.

    A non-zero polynomial is represented by the number of coefficients, 
    two spaces, followed by a list of the coefficients, which are printed 
    in a way depending on the print mode,

    In the ``PADIC_TERSE`` mode, the coefficients are printed as 
    rational numbers.

    The ``PADIC_SERIES`` mode is currently not supported and will 
    raise an abort signal.

    In the ``PADIC_VAL_UNIT`` mode, the coefficients are printed 
    in the form `p^v u`.

    The zero polynomial is represented by ``"0"``.

    In the current implementation, always returns `1`.

.. function:: int _padic_poly_print(const fmpz * poly, slong val, slong len, const padic_ctx_t ctx)
              int padic_poly_print(const padic_poly_t poly, const padic_ctx_t ctx)

    Prints a simple representation of the polynomial ``poly`` 
    to ``stdout``.

    In the current implementation, always returns `1`.

.. function:: int _padic_poly_fprint_pretty(FILE * file, const fmpz * poly, slong val, slong len, const char * var, const padic_ctx_t ctx)
              int padic_poly_fprint_pretty(FILE * file, const padic_poly_t poly, const char * var, const padic_ctx_t ctx)
              int _padic_poly_print_pretty(const fmpz * poly, slong val, slong len, const char * var, const padic_ctx_t ctx)
              int padic_poly_print_pretty(const padic_poly_t poly, const char * var, const padic_ctx_t ctx)


Testing
--------------------------------------------------------------------------------


.. function:: int _padic_poly_is_canonical(const fmpz * op, slong val, slong len, const padic_ctx_t ctx)
              int padic_poly_is_canonical(const padic_poly_t op, const padic_ctx_t ctx)
              int _padic_poly_is_reduced(const fmpz * op, slong val, slong len, slong N, const padic_ctx_t ctx)
              int padic_poly_is_reduced(const padic_poly_t op, const padic_ctx_t ctx)