2016-11-19 20:55:11 +01:00
|
|
|
#ifndef KNOTKIT_ALGEBRA_Z2_H
|
|
|
|
#define KNOTKIT_ALGEBRA_Z2_H
|
2016-11-19 21:01:10 +01:00
|
|
|
#include <algebra/Z.h>
|
2016-11-19 20:55:11 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <tuple>
|
|
|
|
#include <cassert>
|
|
|
|
|
2011-12-09 21:50:25 +01:00
|
|
|
class Z2
|
|
|
|
{
|
|
|
|
public:
|
2016-11-19 20:55:11 +01:00
|
|
|
using linear_combination = ::linear_combination<Z2>;
|
|
|
|
using linear_combination_const_iter = ::linear_combination_const_iter<Z2>;
|
2011-12-09 21:50:25 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool v;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Z2 () : v(0) { }
|
|
|
|
Z2 (int x) : v((bool)(x & 1)) { }
|
2012-04-11 07:06:04 +02:00
|
|
|
Z2 (unsigned x) : v((bool)(x & 1)) { }
|
2011-12-09 21:50:25 +01:00
|
|
|
Z2 (bool v_) : v(v_) { }
|
2016-11-19 20:55:11 +01:00
|
|
|
Z2 (const Z2& x) : v(x.v) { }
|
|
|
|
Z2 (Z2&& x) : v(std::move(x.v)) {
|
|
|
|
x.v = 0;
|
|
|
|
}
|
2012-05-03 21:27:05 +02:00
|
|
|
Z2 (reader &r) { v = r.read_bool (); }
|
2016-11-19 21:01:10 +01:00
|
|
|
Z2 (const Z& z) : v((z % 2).get_ui()) {}
|
2011-12-09 21:50:25 +01:00
|
|
|
~Z2 () { }
|
|
|
|
|
2016-11-19 20:55:11 +01:00
|
|
|
Z2& operator = (const Z2& x) { v = x.v; return *this; }
|
|
|
|
Z2& operator = (Z2&& x) { v = x.v; x.v = 0; return *this; }
|
|
|
|
Z2& operator = (int x) { v = (bool)(x & 1); return *this; }
|
2011-12-09 21:50:25 +01:00
|
|
|
|
2016-11-19 20:55:11 +01:00
|
|
|
bool operator == (const Z2& x) const { return v == x.v; }
|
|
|
|
bool operator != (const Z2& x) const { return v != x.v; }
|
2011-12-09 21:50:25 +01:00
|
|
|
|
|
|
|
bool operator == (int x) const { return v == (bool)(x & 1); }
|
|
|
|
bool operator != (int x) const { return !operator == (x); }
|
|
|
|
|
|
|
|
bool is_unit () const { return v; }
|
|
|
|
|
2016-11-19 20:55:11 +01:00
|
|
|
Z2 operator + (const Z2& x) const { return Z2 (v ^ x.v); }
|
|
|
|
Z2 operator - (const Z2& x) const { return Z2 (v ^ x.v); }
|
2011-12-14 19:07:53 +01:00
|
|
|
Z2 operator - () const { return *this; }
|
2016-11-19 20:55:11 +01:00
|
|
|
Z2 operator * (const Z2& x) const { return Z2 (v & x.v); }
|
|
|
|
Z2 operator / (const Z2& x) const { assert (x.v); return *this; }
|
2011-12-09 21:50:25 +01:00
|
|
|
|
|
|
|
Z2 recip () const { assert (v); return *this; }
|
|
|
|
|
2016-11-19 20:55:11 +01:00
|
|
|
Z2& operator += (const Z2& x) { v ^= x.v; return *this; }
|
|
|
|
Z2& operator -= (const Z2& x) { v ^= x.v; return *this; }
|
|
|
|
Z2& operator *= (const Z2& x) { v &= x.v; return *this; }
|
|
|
|
Z2& operator /= (const Z2& x) { assert (x.v); return *this; }
|
2011-12-09 21:50:25 +01:00
|
|
|
|
2012-10-22 19:43:45 +02:00
|
|
|
// *this += z1*z2
|
2016-11-19 20:55:11 +01:00
|
|
|
Z2& muladdeq (const Z2& z1, const Z2& z2)
|
2012-10-22 19:43:45 +02:00
|
|
|
{
|
|
|
|
return operator += (z1 * z2);
|
|
|
|
}
|
|
|
|
|
2011-12-09 21:50:25 +01:00
|
|
|
bool divides (Z2 x) const { return v || !x.v; }
|
|
|
|
bool operator | (const Z2 x) const { return divides (x); }
|
|
|
|
|
|
|
|
Z2 div (Z2 x) const
|
|
|
|
{
|
|
|
|
assert (x.divides (*this));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
Z2 gcd (Z2 x) const
|
|
|
|
{
|
|
|
|
assert (v && x.v);
|
|
|
|
return Z2 (1);
|
|
|
|
}
|
|
|
|
|
2016-11-19 20:55:11 +01:00
|
|
|
std::tuple<Z2, Z2, Z2> extended_gcd (Z2 x) const
|
2011-12-09 21:50:25 +01:00
|
|
|
{
|
|
|
|
if (v)
|
2016-11-19 20:55:11 +01:00
|
|
|
return std::make_tuple (Z2 (1), Z2 (1), Z2 (0));
|
2011-12-09 21:50:25 +01:00
|
|
|
else
|
2016-11-19 20:55:11 +01:00
|
|
|
return std::make_tuple (Z2 (1), Z2 (0), Z2 (1));
|
|
|
|
}
|
|
|
|
|
|
|
|
friend std::ostream& operator << (std::ostream& os, const Z2& x) {
|
|
|
|
return os << (int)x.v;
|
2011-12-09 21:50:25 +01:00
|
|
|
}
|
|
|
|
static void show_ring () { printf ("Z2"); }
|
2012-05-03 21:27:05 +02:00
|
|
|
void write_self (writer &w) const { w.write_bool (v); }
|
2016-11-19 20:55:11 +01:00
|
|
|
void show_self () const { std::cout << *this; }
|
|
|
|
void display_self () const { std::cout << *this << "\n"; }
|
2011-12-09 21:50:25 +01:00
|
|
|
};
|
2016-11-19 20:55:11 +01:00
|
|
|
#endif //KNOTKIT_ALGEBRA_Z2_H
|