-
Notifications
You must be signed in to change notification settings - Fork 3
/
gaussian_field.h
76 lines (58 loc) · 1.79 KB
/
gaussian_field.h
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
#include "singleton.h"
#include <ostream>
#include <tuple>
// Fp[z] / (z^2 - alpha)
template <typename Mod> struct GaussianFieldT {
constexpr GaussianFieldT(Mod x_ = {}, Mod y_ = {}) : x{x_}, y{y_} {}
static Mod &a() { return singleton<Store>().alpha; }
static void set_alpha(Mod a_) { a() = a_; }
static constexpr GaussianFieldT mul_id() { return {Mod::mul_id(), Mod{}}; }
constexpr GaussianFieldT &operator+=(const GaussianFieldT &other) {
x += other.x;
y += other.y;
return *this;
}
constexpr GaussianFieldT &operator-=(const GaussianFieldT &other) {
x -= other.x;
y -= other.y;
return *this;
}
constexpr GaussianFieldT operator*=(const GaussianFieldT &other) {
std::tie(x, y) = std::pair<Mod, Mod>{x * other.x + a() * y * other.y,
x * other.y + y * other.x};
return *this;
}
constexpr GaussianFieldT operator+(const GaussianFieldT &other) const {
GaussianFieldT copy = *this;
return copy += other;
}
constexpr GaussianFieldT operator-() const {
GaussianFieldT copy{};
copy -= *this;
return copy;
}
constexpr GaussianFieldT operator-(const GaussianFieldT &other) const {
GaussianFieldT copy = *this;
return copy -= other;
}
constexpr GaussianFieldT operator*(const GaussianFieldT &other) const {
GaussianFieldT copy = *this;
return copy *= other;
}
constexpr GaussianFieldT inv() const {
auto d = (x * x - a() * y * y).inv();
return GaussianFieldT{d * x, -d * y};
}
Mod x, y;
private:
struct Store {
Mod alpha;
};
};
namespace std {
template <typename Mod>
std::ostream &operator<<(std::ostream &out, GaussianFieldT<Mod> e) {
return out << e.x << " + " << e.y << " sqrt{" << GaussianFieldT<Mod>::a()
<< "}";
}
} // namespace std