File: get_fexpr.c

package info (click to toggle)
calcium 0.4.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 4,756 kB
  • sloc: ansic: 62,836; python: 2,827; sh: 518; makefile: 163
file content (95 lines) | stat: -rw-r--r-- 2,552 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
/*
    Copyright (C) 2021 Fredrik Johansson

    This file is part of Calcium.

    Calcium is free software: you can redistribute it and/or modify it under
    the terms of the GNU Lesser General Public License (LGPL) as published
    by the Free Software Foundation; either version 2.1 of the License, or
    (at your option) any later version.  See <http://www.gnu.org/licenses/>.
*/

#include "fexpr.h"
#include "fexpr_builtin.h"
#include "ca.h"
#include "ca_ext.h"
#include "ca_poly.h"

void _ca_default_variables(fexpr_ptr ext_vars, slong num_ext);

void _ca_get_fexpr_given_ext(fexpr_t res, const ca_t x, ulong flags,
        ca_ext_ptr * ext, slong num_ext, const fexpr_struct * ext_vars, ca_ctx_t ctx);

void _ca_all_extensions(ca_ext_ptr ** extensions, slong * length, const ca_t x, ca_ctx_t ctx);

void
_ca_ext_get_fexpr_given_ext(fexpr_t res, const ca_ext_t x, ulong flags,
        ca_ext_ptr * ext, slong num_ext, const fexpr_struct * ext_vars, ca_ctx_t ctx);

void
ca_poly_get_fexpr(fexpr_t res, const ca_poly_t A, ulong flags, ca_ctx_t ctx)
{
    ca_ext_ptr * ext;
    slong n, i, num_ext;
    fexpr_struct * ext_vars;
    fexpr_struct * where_args;
    fexpr_struct * coeffs;
    fexpr_t t, u;

    ext = NULL;
    num_ext = 0;

    n = A->length;

    if (n == 0)
    {
        fexpr_zero(res);
        return;
    }

    for (i = 0; i < n; i++)
        _ca_all_extensions(&ext, &num_ext, A->coeffs + i, ctx);

    ext_vars = _fexpr_vec_init(num_ext);
    fexpr_init(t);
    fexpr_init(u);

    _ca_default_variables(ext_vars, num_ext);

    coeffs = _fexpr_vec_init(n);

    for (i = 0; i < n; i++)
        _ca_get_fexpr_given_ext(coeffs + i, A->coeffs + i, flags, ext, num_ext, ext_vars, ctx);

    fexpr_set_symbol_builtin(t, FEXPR_List);
    fexpr_call_vec(u, t, coeffs, n);

    if (num_ext == 0)
    {
        fexpr_call_builtin1(res, FEXPR_Polynomial, u);
    }
    else
    {
        where_args = _fexpr_vec_init(num_ext + 1);

        fexpr_call_builtin1(where_args + 0, FEXPR_Polynomial, u);

        for (i = 0; i < num_ext; i++)
        {
            _ca_ext_get_fexpr_given_ext(t, ext[i], flags, ext, num_ext, ext_vars, ctx);
            fexpr_call_builtin2(where_args + i + 1, FEXPR_Def, ext_vars + i, t);
        }

        fexpr_set_symbol_builtin(t, FEXPR_Where);
        fexpr_call_vec(res, t, where_args, num_ext + 1);

        _fexpr_vec_clear(where_args, num_ext + 1);
    }

    _fexpr_vec_clear(coeffs, n);

    flint_free(ext);
    fexpr_clear(t);
    fexpr_clear(u);
    _fexpr_vec_clear(ext_vars, num_ext);
}