Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modular/arithgroup/sl2z.hpp
4069 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;
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
return SL2Z(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
}
91
92
inline
93
SL2Z SL2Z::operator/=(const SL2Z& x) {
94
return SL2Z( M[0][0]*x.M[1][1] - M[0][1]*x.M[1][0],
95
-M[0][0]*x.M[0][1] + M[0][1]*x.M[0][0],
96
M[1][0]*x.M[1][1] - M[1][1]*x.M[1][0],
97
-M[1][0]*x.M[0][1] + M[1][1]*x.M[0][0]);
98
}
99
100
inline
101
SL2Z SL2Z::inverse() const {
102
return SL2Z(M[1][1], -M[0][1], -M[1][0], M[0][0]);
103
}
104
105
inline
106
SL2Z SL2Z::mod(const size_t n) const {
107
return SL2Z(M[0][0]%n, M[0][1]%n, M[1][0]%n, M[1][1]%n);
108
}
109
110
inline
111
SL2Z operator*(const SL2Z& x, const SL2Z& y) {
112
return SL2Z(x.M[0][0]*y.M[0][0] + x.M[0][1]*y.M[1][0],
113
x.M[0][0]*y.M[0][1] + x.M[0][1]*y.M[1][1],
114
x.M[1][0]*y.M[0][0] + x.M[1][1]*y.M[1][0],
115
x.M[1][0]*y.M[0][1] + x.M[1][1]*y.M[1][1]);
116
}
117
118
inline
119
SL2Z operator/(const SL2Z& x, const SL2Z& y) {
120
return SL2Z( x.M[0][0]*y.M[1][1] - x.M[0][1]*y.M[1][0],
121
-x.M[0][0]*y.M[0][1] + x.M[0][1]*y.M[0][0],
122
x.M[1][0]*y.M[1][1] - x.M[1][1]*y.M[1][0],
123
-x.M[1][0]*y.M[0][1] + x.M[1][1]*y.M[0][0]);
124
}
125
126
inline
127
bool operator==(const SL2Z& x, const SL2Z& y) {
128
return (x.M[0][0] == y.M[0][0] and
129
x.M[0][1] == y.M[0][1] and
130
x.M[1][0] == y.M[1][0] and
131
x.M[1][1] == y.M[1][1]);
132
}
133
134
inline
135
bool operator!=(const SL2Z& x, const SL2Z& y) {
136
return not (x == y);
137
}
138
139
inline
140
std::ostream& operator<<(std::ostream& os, const SL2Z& x) {
141
os << "["
142
<< x.M[0][0] << ", "
143
<< x.M[0][1] << "; "
144
<< x.M[1][0] << ", "
145
<< x.M[1][1]
146
<< "]";
147
return os;
148
}
149
150
inline
151
std::istream& operator>>(std::istream& is, SL2Z& x) {
152
char c;
153
is >> c;
154
if( c == '[' ) {
155
is >> x.M[0][0] >> c;
156
if( c == ',' ) {
157
is >> x.M[0][1] >> c;
158
if( c == ';' ) {
159
is >> x.M[1][0] >> c;
160
if( c == ',' ) {
161
is >> x.M[1][1] >> c;
162
if( c != ']' ) is.clear(std::ios_base::badbit);
163
} else {
164
is.clear(std::ios_base::badbit);
165
}
166
} else {
167
is.clear(std::ios_base::badbit);
168
}
169
} else {
170
is.clear(std::ios_base::badbit);
171
}
172
} else {
173
is.clear(std::ios_base::badbit);
174
}
175
return is;
176
}
177
178
#endif // SL2Z_HPP_
179
180