File: nmz_polynomial.h

package info (click to toggle)
normaliz 3.11.1%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 41,376 kB
  • sloc: cpp: 48,779; makefile: 2,266; sh: 1
file content (219 lines) | stat: -rw-r--r-- 7,151 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
/*
 * Copyright (C) 2007-2025  W. Bruns, B. Ichim, Ch. Soeger, U. v. d. Ohe
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 * As an exception, when this program is distributed through (i) the App Store
 * by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or (iii) Google Play
 * by Google Inc., then that store may impose any digital rights management,
 * device limits and/or redistribution restrictions that are required by its
 * terms of service.
 */

#ifndef LIBNORMALIZ_NMZ_POLYNOMIAL_H
#define LIBNORMALIZ_NMZ_POLYNOMIAL_H

#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <gmpxx.h>

#include "libnormaliz/dynamic_bitset.h"
#include "libnormaliz/general.h"
#include "libnormaliz/matrix.h"

#ifdef NMZ_COCOA
#include "CoCoA/library.H"
#endif

namespace libnormaliz {

using namespace std;

//-------------------------------------------------------------------
//       OurTerm
//-------------------------------------------------------------------

template <typename Number>
class OurPolynomial;

template<typename Number>
class OurTerm {

template <typename>
friend class OurPolynomial;

public:

    Number coeff;
    map<key_t, long> monomial; // key_t is variable, long is exponent
    vector<key_t> vars; // each variable repeated repetitions if expo > 1 --- sometimes better
    dynamic_bitset support;

    Number evaluate(const vector<Number>& argument) const;
    OurTerm();
    OurTerm(const Number& c, const map<key_t, long>& mon, const dynamic_bitset& supp);
    OurTerm(const pair<vector<key_t>, Number>& t, size_t dim);
    void shift_coordinates(const int& shift);
    void swap_coordinates(const key_t& first, const key_t& second);
    void cyclic_shift_right(const key_t& col);
    void multiply_by_constant(const Number& factor);
    // bool check_restriction(const dynamic_bitset& set_of_var) const;
    bool is_restrictable_inequ(const dynamic_bitset& set_of_var)  const;
    void permute_variables(const vector<key_t>& perm);
    void mon2vars_expos();

#ifdef NMZ_COCOA
    CoCoA::RingElem ToCoCoA(CoCoA::SparsePolyRing R) const;
#endif
};

template<typename Number>
class OurPolynomial : public std::vector<OurTerm<Number> > {

public:

    long highest_indet;  // -1 if support is empty
    dynamic_bitset support;

    // for linearization of degree 2 polynomials with +- 1 coeff
    vector<key_t> expo_1_pos, expo_2_pos;
    vector<key_t> expo_1_neg, expo_2_neg;
    vector<Number> coeffs;
    Number const_term;
    bool vectorized;

    Number evaluate(const vector<Number>& argument) const;
    Number evaluate_vectorized(const vector<Number>& argument) const;
    Number evaluate_restricted(const vector<Number>& argument, const dynamic_bitset& set_of_var) const;
    OurPolynomial();
    OurPolynomial(const string& poly_string, const size_t dim, const bool);
    OurPolynomial(const map<vector<key_t>, Number>& poly, size_t dim);
    OurPolynomial(const vector<Number>& linear_form);
    key_t get_highest_indet() const;
    void shift_coordinates(const int& shift);
    void swap_coordinates(const key_t& first, const key_t& second);
    void cyclic_shift_right(const key_t& col);
    void multiply_by_constant(const Number& factor);
    // bool check_restriction(const dynamic_bitset& set_of_var) const;
    bool is_restrictable_inequ(const dynamic_bitset& set_of_var)  const;
    void permute_variables(const vector<key_t>& perm);
    OurPolynomial<Number> restrict_to(const dynamic_bitset& variables) const;
    pair<OurPolynomial<Number>, OurPolynomial<Number> > split(const dynamic_bitset& support_variables) const;
    bool check_linearity(const dynamic_bitset& critical_variables, dynamic_bitset& support_linear) const;

    void vectorize_deg_2();

#ifdef NMZ_COCOA
    CoCoA::RingElem ToCoCoA(CoCoA::SparsePolyRing R) const;
#endif

};

template<typename Number>
class OurPolynomialCong{

public:

    OurPolynomial<Number> poly;
    Number modulus;

    OurPolynomialCong();
    OurPolynomialCong(const OurPolynomial<Number>& pol, const Number& mod);
    OurPolynomialCong(vector<Number> cong);

    bool check(const vector<Number>& v) const;
};

template<typename Number>
class OurPolynomialSystem : public std::vector<OurPolynomial<Number> > {

public:

    OurPolynomialSystem();
    OurPolynomialSystem(const vector<string>& poly_strings, const size_t dim, const bool verb);
    OurPolynomialSystem(const set<map<vector<key_t>, Number> >& Polys, size_t dim);
    void shift_coordinates(const int& shift);
    void swap_coordinates(const key_t& first, const key_t& second);
    void cyclic_shift_right(const key_t& col);
    void multiply_by_constant(const Number& factor);
    void permute_variables(const vector<key_t>& perm);

    bool check(const vector<Number>& argument, const bool is_quations, const bool exact_length) const;

    bool verbose;

#ifdef NMZ_COCOA
    vector<CoCoA::RingElem> ToCoCoA(CoCoA::SparsePolyRing R) const;
#endif

    OurPolynomialSystem<Number> minimize_equations(const Matrix<Number>& LinEqus) const;

};

template <typename To, typename From>
void convert(OurPolynomial<To>& ret, const OurPolynomial<From>& arg){
    for(auto& T: arg){
        To c = convertTo<To>(T.coeff);
        ret.push_back(OurTerm<To>(c, T.monomial, T.support));
    }
    ret.highest_indet = arg.highest_indet;
    ret.support = arg.support;
}

template <typename To, typename From>
void convert(OurPolynomialSystem<To>& ret, const OurPolynomialSystem<From>& arg){
    for(auto& P: arg){;
        OurPolynomial<To> P_ret;
        convert(P_ret, P);
        ret.push_back(P_ret);
    }
    ret.verbose = arg.verbose;
}

template <typename Number>
ostream& operator<<(ostream& out, const OurPolynomialSystem<Number> & S) {
    out << "*****************************" << endl;
    out << "system" << endl;
    for(auto& P: S){
        cout << "************" << endl;
        out << P;
    }
    out << "*****************************" << endl;
    return out;
}

template <typename Number>
ostream& operator<<(ostream& out, const OurPolynomial<Number> & P) {
    out << "terms" << endl;
    for(auto& T: P)
        out << T;
    out << "highest indet " << P.highest_indet << " support " << P.support << endl;
    return out;
}

template <typename Number>
ostream& operator<<(ostream& out, const OurTerm<Number> & T) {
    out << "coeff " << T.coeff << " --- " << T.support << " ---";
    for(auto& F: T.monomial)
        out << F.first << ":" << F.second << "  ";
    out << endl;
    return out;
}

} // name space

#endif