Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/modular/arithgroup/sl2z.hpp
8820 views
1
//****************************************************************************
2
// Copyright (C) 2011 Hartmut Monien <[email protected]>
3
//
4
// Distributed under the terms of the GNU General Public License (GPL)
5
//
6
// This code is distributed in the hope that it will be useful,
7
// but WITHOUT ANY WARRANTY; without even the implied warranty of
8
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9
// General Public License for more details.
10
//
11
// The full text of the GPL is available at:
12
//
13
// http://www.gnu.org/licenses/
14
//****************************************************************************
15
16
#ifndef SL2Z_HPP_
17
#define SL2Z_HPP_
18
19
#include <iostream>
20
#include <iomanip>
21
#include <cassert>
22
#include <gmpxx.h>
23
24
class SL2Z {
25
public:
26
typedef mpz_class ElementType;
27
protected:
28
ElementType M[2][2];
29
public:
30
const static SL2Z E, R, T, S, U, I;
31
SL2Z(int a_, int b_, int c_, int d_);
32
SL2Z(const ElementType& a_, const ElementType& b_,
33
const ElementType& c_, const ElementType& d_);
34
SL2Z(const SL2Z&);
35
ElementType a() const { return M[0][0]; };
36
ElementType b() const { return M[0][1]; };
37
ElementType c() const { return M[1][0]; };
38
ElementType d() const { return M[1][1]; };
39
SL2Z inverse() const;
40
SL2Z operator-() const;
41
SL2Z operator*=(const SL2Z& x);
42
SL2Z operator/=(const SL2Z& x);
43
SL2Z mod(const size_t) const;
44
friend bool operator==(const SL2Z&, const SL2Z&);
45
friend bool operator!=(const SL2Z&, const SL2Z&);
46
friend SL2Z operator*(const SL2Z&, const SL2Z&);
47
friend SL2Z operator/(const SL2Z&, const SL2Z&);
48
friend std::ostream& operator<<(std::ostream&, const SL2Z&);
49
friend std::istream& operator>>(std::istream&, SL2Z&);
50
};
51
52
inline
53
SL2Z::SL2Z(const SL2Z::ElementType& a_, const SL2Z::ElementType& b_,
54
const SL2Z::ElementType& c_, const SL2Z::ElementType& d_) {
55
M[0][0] = a_;
56
M[0][1] = b_;
57
M[1][0] = c_;
58
M[1][1] = d_;
59
assert(M[0][0]*M[1][1] - M[0][1]*M[1][0] == 1);
60
}
61
62
inline
63
SL2Z::SL2Z(int a_, int b_, int c_, int d_) {
64
M[0][0] = a_;
65
M[0][1] = b_;
66
M[1][0] = c_;
67
M[1][1] = d_;
68
assert(M[0][0]*M[1][1] - M[0][1]*M[1][0] == 1);
69
}
70
71
inline
72
SL2Z::SL2Z(const SL2Z& x) {
73
M[0][0] = x.M[0][0];
74
M[0][1] = x.M[0][1];
75
M[1][0] = x.M[1][0];
76
M[1][1] = x.M[1][1];
77
}
78
79
inline
80
SL2Z SL2Z::operator-() const {
81
return SL2Z(-M[0][0],-M[0][1],-M[1][0],-M[1][1]);
82
}
83
84
inline
85
SL2Z SL2Z::operator*=(const SL2Z& x) {
86
SL2Z result(M[0][0]*x.M[0][0] + M[0][1]*x.M[1][0],
87
M[0][0]*x.M[0][1] + M[0][1]*x.M[1][1],
88
M[1][0]*x.M[0][0] + M[1][1]*x.M[1][0],
89
M[1][0]*x.M[0][1] + M[1][1]*x.M[1][1]);
90
M[0][0] = result.M[0][0];
91
M[0][1] = result.M[0][1];
92
M[1][0] = result.M[1][0];
93
M[1][1] = result.M[1][1];
94
return *this;
95
}
96
97
inline
98
SL2Z SL2Z::operator/=(const SL2Z& x) {
99
SL2Z result( M[0][0]*x.M[1][1] - M[0][1]*x.M[1][0],
100
-M[0][0]*x.M[0][1] + M[0][1]*x.M[0][0],
101
M[1][0]*x.M[1][1] - M[1][1]*x.M[1][0],
102
-M[1][0]*x.M[0][1] + M[1][1]*x.M[0][0]);
103
M[0][0] = result.M[0][0];
104
M[0][1] = result.M[0][1];
105
M[1][0] = result.M[1][0];
106
M[1][1] = result.M[1][1];
107
return *this;
108
}
109
110
inline
111
SL2Z SL2Z::inverse() const {
112
return SL2Z(M[1][1], -M[0][1], -M[1][0], M[0][0]);
113
}
114
115
inline
116
SL2Z SL2Z::mod(const size_t n) const {
117
return SL2Z(M[0][0]%n, M[0][1]%n, M[1][0]%n, M[1][1]%n);
118
}
119
120
inline
121
SL2Z operator*(const SL2Z& x, const SL2Z& y) {
122
return SL2Z(x.M[0][0]*y.M[0][0] + x.M[0][1]*y.M[1][0],
123
x.M[0][0]*y.M[0][1] + x.M[0][1]*y.M[1][1],
124
x.M[1][0]*y.M[0][0] + x.M[1][1]*y.M[1][0],
125
x.M[1][0]*y.M[0][1] + x.M[1][1]*y.M[1][1]);
126
}
127
128
inline
129
SL2Z operator/(const SL2Z& x, const SL2Z& y) {
130
return SL2Z( x.M[0][0]*y.M[1][1] - x.M[0][1]*y.M[1][0],
131
-x.M[0][0]*y.M[0][1] + x.M[0][1]*y.M[0][0],
132
x.M[1][0]*y.M[1][1] - x.M[1][1]*y.M[1][0],
133
-x.M[1][0]*y.M[0][1] + x.M[1][1]*y.M[0][0]);
134
}
135
136
inline
137
bool operator==(const SL2Z& x, const SL2Z& y) {
138
return (x.M[0][0] == y.M[0][0] and
139
x.M[0][1] == y.M[0][1] and
140
x.M[1][0] == y.M[1][0] and
141
x.M[1][1] == y.M[1][1]);
142
}
143
144
inline
145
bool operator!=(const SL2Z& x, const SL2Z& y) {
146
return not (x == y);
147
}
148
149
inline
150
std::ostream& operator<<(std::ostream& os, const SL2Z& x) {
151
os << "["
152
<< x.M[0][0] << ", "
153
<< x.M[0][1] << "; "
154
<< x.M[1][0] << ", "
155
<< x.M[1][1]
156
<< "]";
157
return os;
158
}
159
160
inline
161
std::istream& operator>>(std::istream& is, SL2Z& x) {
162
char c;
163
is >> c;
164
if( c == '[' ) {
165
is >> x.M[0][0] >> c;
166
if( c == ',' ) {
167
is >> x.M[0][1] >> c;
168
if( c == ';' ) {
169
is >> x.M[1][0] >> c;
170
if( c == ',' ) {
171
is >> x.M[1][1] >> c;
172
if( c != ']' ) is.clear(std::ios_base::badbit);
173
} else {
174
is.clear(std::ios_base::badbit);
175
}
176
} else {
177
is.clear(std::ios_base::badbit);
178
}
179
} else {
180
is.clear(std::ios_base::badbit);
181
}
182
} else {
183
is.clear(std::ios_base::badbit);
184
}
185
return is;
186
}
187
188
#endif // SL2Z_HPP_
189
190