Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/modular/arithgroup/farey.hpp
8820 views
1
//
2
// farey.hpp
3
// FareySymbol
4
//
5
//*************************************************************************
6
// Copyright (C) 2011 Hartmut Monien <[email protected]>
7
//
8
// Distributed under the terms of the GNU General Public License (GPL)
9
//
10
// This code is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// General Public License for more details.
14
//
15
// The full text of the GPL is available at:
16
//
17
// http://www.gnu.org/licenses/
18
//*************************************************************************
19
20
21
#ifndef FAREY_SYMBOL_HPP_
22
#define FAREY_SYMBOL_HPP_
23
24
#include <iostream>
25
#include <vector>
26
#include <string>
27
28
#include <Python.h>
29
#include <gmpxx.h>
30
#include "sl2z.hpp"
31
32
//--- pure virtual base class for helper class for membership test --------
33
34
class is_element_group {
35
public:
36
virtual bool is_member(const SL2Z&) const = 0;
37
};
38
39
class is_element_Gamma0 : public is_element_group {
40
const int p;
41
public:
42
is_element_Gamma0(int p_) : p(p_) {
43
}
44
bool is_member(const SL2Z& V) const {
45
return (V.c() % p == 0);
46
}
47
};
48
49
class is_element_Gamma1 : public is_element_group {
50
const int p;
51
public:
52
is_element_Gamma1(int p_) : p(p_) {
53
}
54
bool is_member(const SL2Z& V) const {
55
return ((V.a()-1) % p == 0 &&
56
V.c() % p == 0 &&
57
(V.d()-1) % p == 0);
58
}
59
};
60
61
class is_element_Gamma : public is_element_group {
62
const int p;
63
public:
64
is_element_Gamma(int p_) : p(p_) {
65
}
66
bool is_member(const SL2Z& V) const {
67
return ((V.a()-1) % p == 0 &&
68
V.b() % p == 0 &&
69
V.c() % p == 0 &&
70
(V.d()-1) % p == 0);
71
}
72
};
73
74
class is_element_GammaH : public is_element_group {
75
const int p;
76
std::vector<long> H;
77
public:
78
is_element_GammaH(int p_, PyObject*);
79
~is_element_GammaH();
80
bool is_member(const SL2Z&) const;
81
};
82
83
class is_element_general : public is_element_group {
84
protected:
85
PyObject* group;
86
PyObject* method;
87
public:
88
is_element_general(PyObject*);
89
virtual ~is_element_general();
90
bool is_member(const SL2Z&) const;
91
};
92
93
class FareySymbol {
94
protected:
95
enum PAIRING { EVEN=-2, ODD=-3, NO=0, FREE=1 };
96
size_t pairing_max;
97
std::vector<int> pairing;
98
std::vector<int> cusp_classes;
99
std::vector<mpz_class> a, b;
100
std::vector<mpq_class> x;
101
std::vector<SL2Z> coset;
102
std::vector<SL2Z> generators;
103
std::vector<mpq_class> cusps;
104
std::vector<mpq_class> cusp_widths;
105
std::vector<SL2Z> reductions;
106
bool even;
107
std::vector<bool> pairing_in_group; // For membership test:
108
//Is the i-th pairing matrix in the group?
109
size_t rank_pi() const;
110
long side_index(const mpz_class& a0, const mpz_class& b0,
111
const mpz_class& a1, const mpz_class& b1) const;
112
void LLT_algorithm(const SL2Z& M, std::vector<int>& p, SL2Z& beta) const;
113
void dump(std::ostream& os) const;
114
std::vector<SL2Z> init_reductions() const;
115
private:
116
void add_term(const int, const mpq_class&);
117
void check_pair(const is_element_group*, const int);
118
size_t paired_side(const std::vector<int>& p, const size_t i) const;
119
SL2Z pairing_matrix(const std::vector<int>&, const size_t i) const;
120
void init_pairing(const is_element_group*);
121
std::vector<SL2Z> init_generators(const is_element_group*) const;
122
std::vector<SL2Z> init_coset_reps() const;
123
std::vector<int> init_cusp_classes() const;
124
std::vector<mpq_class> init_cusps() const;
125
std::vector<mpq_class> init_cusp_widths() const;
126
SL2Z pairing_matrix(const size_t) const;
127
SL2Z pairing_matrix_in_group(const size_t) const;
128
std::vector<bool> init_sl2z_lift(const is_element_group*) const;
129
public:
130
FareySymbol();
131
FareySymbol(std::istream& is);
132
FareySymbol(PyObject*);
133
FareySymbol(PyObject*, const is_element_group*);
134
~FareySymbol();
135
const size_t size() const;
136
size_t nu2() const;
137
size_t nu3() const;
138
size_t index() const;
139
size_t number_of_cusps() const;
140
size_t level() const;
141
size_t genus() const;
142
SL2Z reduce_to_fraction(const mpq_class& q) const;
143
SL2Z reduce_to_elementary_cusp(const mpq_class& q) const;
144
size_t cusp_class(const mpq_class& q) const;
145
bool is_element(const SL2Z& M) const;
146
friend std::ostream& operator<<(std::ostream&, const FareySymbol&);
147
friend std::istream& operator>>(std::istream&, FareySymbol&);
148
//--- communication with sage -------------------------------------------
149
PyObject* is_element(const mpz_t, const mpz_t, const mpz_t, const mpz_t) const;
150
PyObject* get_transformation_to_cusp(const mpz_t, const mpz_t) const;
151
PyObject* get_cusps() const;
152
PyObject* get_cusp_widths() const;
153
size_t get_cusp_class(const mpz_t, const mpz_t) const;
154
PyObject* get_fractions() const;
155
PyObject* get_coset() const;
156
PyObject* get_generators() const;
157
PyObject* get_pairings() const;
158
PyObject* get_paired_sides() const;
159
PyObject* get_pairing_matrices() const;
160
PyObject* dumps() const;
161
};
162
163
#endif // FAREY_SYMBOL_HPP_
164
165