Added some C++11 features to classes Z and Q
Z and Q use now smart pointers for storing their internal implementations, which were changed to use mpz_class and mpq_class. New implementation uses copy on write. Moreover, I added moving semantics for these two classes.
This commit is contained in:
parent
cddb533519
commit
66813d4a15
6
Makefile
6
Makefile
@ -5,14 +5,14 @@ BISON = bison
|
|||||||
FLEX = flex
|
FLEX = flex
|
||||||
|
|
||||||
CXX = g++ -std=c++11
|
CXX = g++ -std=c++11
|
||||||
# CXX = OMPI_CXX=clang++ mpic++ -fno-color-diagnostics --stdlib=libc++ --std=c++11 -I/u/cseed/llvm-3.1/lib/c++/v1
|
#CXX = OMPI_CXX=clang++ mpic++ -fno-color-diagnostics --stdlib=libc++ --std=c++11 -I/u/cseed/llvm-3.1/lib/c++/v1
|
||||||
#CXX = clang++ -fno-color-diagnostics --stdlib=libc++ --std=c++11
|
#CXX = clang++ -fno-color-diagnostics --stdlib=libc++ --std=c++11
|
||||||
|
|
||||||
INCLUDES = -I. -I/opt/local/include
|
INCLUDES = -I. -I/opt/local/include
|
||||||
|
|
||||||
# OPTFLAGS = -g
|
# OPTFLAGS = -g
|
||||||
OPTFLAGS = -O2 -g
|
OPTFLAGS = -O2 -g
|
||||||
# OPTFLAGS = -O2 -DNDEBUG
|
# OPTFLAGS = -O2 -g -DNDEBUG
|
||||||
|
|
||||||
LDFLAGS = -L/opt/local/lib
|
LDFLAGS = -L/opt/local/lib
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ KNOTKIT_HEADERS = knotkit.h planar_diagram.h dt_code.h knot_diagram.h \
|
|||||||
smoothing.h cobordism.h cube.h steenrod_square.h \
|
smoothing.h cobordism.h cube.h steenrod_square.h \
|
||||||
spanning_tree_complex.h cube_impl.h sseq.h simplify_chain_complex.h
|
spanning_tree_complex.h cube_impl.h sseq.h simplify_chain_complex.h
|
||||||
|
|
||||||
LIBS = -lgmp -lz
|
LIBS = -lgmpxx -lgmp -lz
|
||||||
|
|
||||||
all: kk
|
all: kk
|
||||||
|
|
||||||
|
279
algebra/Q.h
279
algebra/Q.h
@ -1,70 +1,154 @@
|
|||||||
|
#ifndef _KNOTKIT_ALGEBRA_Q_H
|
||||||
|
#define _KNOTKIT_ALGEBRA_Q_H
|
||||||
|
#include <gmpxx.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
class Q
|
class Q
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef ::linear_combination<Q> linear_combination;
|
using linear_combination = ::linear_combination<Q>;
|
||||||
typedef ::linear_combination_const_iter<Q> linear_combination_const_iter;
|
using linear_combination_const_iter = ::linear_combination_const_iter<Q>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum steal { STEAL };
|
// enum steal { STEAL };
|
||||||
|
// enum copy { COPY };
|
||||||
|
// class Q_impl : public refcounted
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// mpq_t x;
|
||||||
|
|
||||||
|
// public:
|
||||||
|
// Q_impl () { mpq_init (x); }
|
||||||
|
// Q_impl (int init)
|
||||||
|
// {
|
||||||
|
// mpq_init (x);
|
||||||
|
// mpq_set_si (x, init, 1);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Q_impl (copy, mpq_srcptr init)
|
||||||
|
// {
|
||||||
|
// mpq_init (x);
|
||||||
|
// mpq_set (x, init);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Q_impl (steal, mpq_srcptr init) { x[0] = *init; }
|
||||||
|
// Q_impl (reader &r)
|
||||||
|
// {
|
||||||
|
// mpq_init (x);
|
||||||
|
// r.read_mpz (mpq_numref (x));
|
||||||
|
// r.read_mpz (mpq_denref (x));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ~Q_impl () { mpq_clear (x); }
|
||||||
|
|
||||||
|
// void write_self (writer &w) const
|
||||||
|
// {
|
||||||
|
// w.write_mpz (mpq_numref (x));
|
||||||
|
// w.write_mpz (mpq_denref (x));
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
class Q_impl : public refcounted
|
// ptr<Q_impl> impl;
|
||||||
{
|
std::shared_ptr<mpq_class> impl;
|
||||||
public:
|
void write_state() const {
|
||||||
mpq_t x;
|
std::cout << "I store the following value " << *this << "\n";
|
||||||
|
std::cout << "Number of objects pointing to the same value " << impl.use_count() << "\n";
|
||||||
public:
|
/* std::cout << "I point to " << impl.get() << "\n"; */
|
||||||
Q_impl () { mpq_init (x); }
|
/* std::cout << "My size " << sizeof(*this) << "\n"; */
|
||||||
Q_impl (int init)
|
/* std::cout << "Size of std::shared_ptr<mpz_class> " << sizeof(impl) << "\n"; */
|
||||||
{
|
/* std::cout << "Size of mpz_class " << sizeof(*impl) << "\n"; */
|
||||||
mpq_init (x);
|
}
|
||||||
mpq_set_si (x, init, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_impl (copy, mpq_srcptr init)
|
|
||||||
{
|
|
||||||
mpq_init (x);
|
|
||||||
mpq_set (x, init);
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_impl (steal, mpq_srcptr init) { x[0] = *init; }
|
|
||||||
Q_impl (reader &r)
|
|
||||||
{
|
|
||||||
mpq_init (x);
|
|
||||||
r.read_mpz (mpq_numref (x));
|
|
||||||
r.read_mpz (mpq_denref (x));
|
|
||||||
}
|
|
||||||
|
|
||||||
~Q_impl () { mpq_clear (x); }
|
|
||||||
|
|
||||||
void write_self (writer &w) const
|
|
||||||
{
|
|
||||||
w.write_mpz (mpq_numref (x));
|
|
||||||
w.write_mpz (mpq_denref (x));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ptr<Q_impl> impl;
|
|
||||||
|
|
||||||
Q (steal, mpq_srcptr init) : impl(new Q_impl (STEAL, init)) { }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q () : impl(new Q_impl) { }
|
Q() : impl(new mpq_class()) {
|
||||||
Q (int init) : impl(new Q_impl (init)) { }
|
#ifdef DEBUG_Q
|
||||||
Q (const Q &q) : impl(q.impl) { }
|
std::cout << "Q()" << "\n";
|
||||||
Q (copy, const Q &q) : impl(new Q_impl (COPY, q.impl->x)) { }
|
write_state();
|
||||||
Q (reader &r) : impl(new Q_impl (r)) { }
|
#endif
|
||||||
~Q () { }
|
}
|
||||||
|
Q(mpq_t q) : impl(new mpq_class(q)) {
|
||||||
|
#ifdef DEBUG_Q
|
||||||
|
std::cout << "Q(mpq_t)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Q(mpq_class q) : impl(new mpq_class(q)) {
|
||||||
|
#ifdef DEBUG_Q
|
||||||
|
std::cout << "Q(mpq_class)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Q(int init) : impl(new mpq_class (init)) {
|
||||||
|
#ifdef DEBUG_Q
|
||||||
|
std::cout << "Q(int)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Q(const Q& q) : impl(q.impl) {
|
||||||
|
#ifdef DEBUG_Q
|
||||||
|
std::cout << "Q(const Q&)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Q(Q&& q) : impl(std::move (q.impl)) {
|
||||||
|
q.impl = std::make_shared<mpq_class>(0);
|
||||||
|
#ifdef DEBUG_Q
|
||||||
|
std::cout << "Q(Q&& q)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Q(copy, const Q &q) : impl(new mpq_class (*q.impl.get())) {
|
||||||
|
#ifdef DEBUG_Q
|
||||||
|
std::cout << "Q(copy, const Q&)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
//Q(reader &r) : impl(new Q_impl (r)) { }
|
||||||
|
~Q() {
|
||||||
|
#ifdef DEBUG_Q
|
||||||
|
std::cout << "~Q()" << "\n";
|
||||||
|
write_state();
|
||||||
|
if(get_count() == 1)
|
||||||
|
std::cout << "Destroying..." << "\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
Q &operator = (const Q &q) { impl = q.impl; return *this; }
|
Q &operator = (const Q &q) {
|
||||||
Q &operator = (int x) { impl = new Q_impl (x); return *this; }
|
impl = q.impl;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Q& operator = (Q&& q) {
|
||||||
|
impl = std::move(q.impl);
|
||||||
|
q.impl = std::make_shared<mpq_class>(0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Q &operator = (int x) {
|
||||||
|
impl = std::make_shared<mpq_class>(0);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator == (const Q &q) const { return mpq_cmp (impl->x,q.impl->x) == 0; }
|
bool operator == (const Q &q) const {
|
||||||
|
return *impl.get() == *q.impl.get();
|
||||||
|
}
|
||||||
|
bool operator == (const int r) const {
|
||||||
|
return *impl.get() == mpq_class(r);
|
||||||
|
}
|
||||||
|
bool operator != (const Q& q) const {
|
||||||
|
return ! operator == (q);
|
||||||
|
}
|
||||||
|
bool operator != (const int r) const {
|
||||||
|
return !operator == (r);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator == (int r) const { return mpq_cmp_si (impl->x, r, 1) == 0; }
|
bool operator < (const Q &q) const {
|
||||||
bool operator != (int r) const { return !operator == (r); }
|
return *impl.get() < *q.impl.get();
|
||||||
|
}
|
||||||
bool operator < (const Q &q) const { return mpq_cmp (impl->x, q.impl->x) < 0; }
|
// bool operator > (const Q& q) const {
|
||||||
|
// return *impl.get() > *q.impl.get();
|
||||||
|
// }
|
||||||
|
|
||||||
bool is_unit () const
|
bool is_unit () const
|
||||||
{
|
{
|
||||||
@ -73,87 +157,63 @@ class Q
|
|||||||
|
|
||||||
Q operator - () const
|
Q operator - () const
|
||||||
{
|
{
|
||||||
mpq_t x;
|
return Q(-*impl.get());
|
||||||
mpq_init (x);
|
|
||||||
mpq_neg (x, impl->x);
|
|
||||||
return Q (STEAL, x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q recip () const
|
Q recip () const
|
||||||
{
|
{
|
||||||
mpq_t x;
|
mpq_t q;
|
||||||
mpq_init (x);
|
mpq_init(q);
|
||||||
mpq_inv (x, impl->x);
|
mpq_inv(q, impl.get()->get_mpq_t());
|
||||||
return Q (STEAL, x);
|
return Q(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q operator + (const Q &q) const
|
Q operator + (const Q& q) const
|
||||||
{
|
{
|
||||||
mpq_t x;
|
return Q(*impl.get() + *q.impl.get());
|
||||||
mpq_init (x);
|
|
||||||
mpq_add (x, impl->x, q.impl->x);
|
|
||||||
return Q (STEAL, x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q operator - (const Q &q) const
|
Q operator - (const Q& q) const
|
||||||
{
|
{
|
||||||
mpq_t x;
|
return Q(*impl.get() - *q.impl.get());
|
||||||
mpq_init (x);
|
|
||||||
mpq_sub (x, impl->x, q.impl->x);
|
|
||||||
return Q (STEAL, x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q operator * (const Q &q) const
|
Q operator * (const Q& q) const
|
||||||
{
|
{
|
||||||
mpq_t x;
|
return Q(*impl.get() * (*q.impl.get()));
|
||||||
mpq_init (x);
|
|
||||||
mpq_mul (x, impl->x, q.impl->x);
|
|
||||||
return Q (STEAL, x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q operator / (const Q &q) const
|
Q operator / (const Q& q) const
|
||||||
{
|
{
|
||||||
assert (q != 0);
|
return Q(*impl.get() / *q.impl.get());
|
||||||
|
|
||||||
mpq_t x;
|
|
||||||
mpq_init (x);
|
|
||||||
mpq_div (x, impl->x, q.impl->x);
|
|
||||||
return Q (STEAL, x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q &muladdeq (const Q &q1, const Q &q2)
|
Q &muladdeq (const Q& q1, const Q& q2)
|
||||||
{
|
{
|
||||||
// ??? do inline saves refcount overhead
|
|
||||||
return operator += (q1 * q2);
|
return operator += (q1 * q2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q &operator += (const Q &q)
|
Q &operator += (const Q& q)
|
||||||
{
|
{
|
||||||
mpq_add (impl->x, impl->x, q.impl->x);
|
return *this = *this + q;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q &operator -= (const Q &q)
|
Q &operator -= (const Q& q)
|
||||||
{
|
{
|
||||||
mpq_sub (impl->x, impl->x, q.impl->x);
|
return *this = *this - q;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q &operator *= (const Q &q)
|
Q &operator *= (const Q &q)
|
||||||
{
|
{
|
||||||
mpq_mul (impl->x, impl->x, q.impl->x);
|
return *this = *this * q;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Q &operator /= (const Q &q)
|
Q &operator /= (const Q &q)
|
||||||
{
|
{
|
||||||
assert (q != 0);
|
assert (q != 0);
|
||||||
|
return *this = *this / q;
|
||||||
mpq_div (impl->x, impl->x, q.impl->x);
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// d | n, d.divides (n)
|
|
||||||
bool divides (const Q &num) const
|
bool divides (const Q &num) const
|
||||||
{
|
{
|
||||||
return *this != 0 || num == 0;
|
return *this != 0 || num == 0;
|
||||||
@ -163,12 +223,12 @@ class Q
|
|||||||
|
|
||||||
Q div (const Q &d) const { return operator / (d); }
|
Q div (const Q &d) const { return operator / (d); }
|
||||||
|
|
||||||
tuple<Q, Q, Q> extended_gcd (const Q &q) const
|
std::tuple<Q, Q, Q> extended_gcd (const Q &q) const
|
||||||
{
|
{
|
||||||
if (*this != 0)
|
if (*this != 0)
|
||||||
return tuple<Q, Q, Q> (*this, 1, 0);
|
return std::tuple<Q, Q, Q> (*this, 1, 0);
|
||||||
else
|
else
|
||||||
return tuple<Q, Q, Q> (q, 0, 1);
|
return std::tuple<Q, Q, Q> (q, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q gcd (const Q &q) const
|
Q gcd (const Q &q) const
|
||||||
@ -176,9 +236,16 @@ class Q
|
|||||||
assert (*this != 0 || q != 0);
|
assert (*this != 0 || q != 0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
friend std::ostream& operator << (std::ostream& os, const Q& q) {
|
||||||
|
return os << *q.impl.get();
|
||||||
|
}
|
||||||
static void show_ring () { printf ("Q"); }
|
static void show_ring () { printf ("Q"); }
|
||||||
void show_self () const { mpq_out_str (stdout, 10, impl->x); }
|
void show_self () const { std::cout << *this; }
|
||||||
void display_self () const { show_self (); newline (); }
|
void display_self () const { std::cout << *this << "\n"; }
|
||||||
void write_self (writer &w) const { write (w, *impl); }
|
// void write_self (writer &w) const { write (w, *impl); }
|
||||||
|
int get_count() const {
|
||||||
|
return impl.use_count();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // _KNOTKIT_ALGEBRA_Q_H
|
||||||
|
402
algebra/Z.h
402
algebra/Z.h
@ -1,209 +1,239 @@
|
|||||||
|
#ifndef _KNOTKIT_ALGEBRA_Z_H
|
||||||
|
#define _KNOTKIT_ALGEBRA_Z_H
|
||||||
|
#include<gmpxx.h>
|
||||||
|
#include<tuple>
|
||||||
|
#include<memory>
|
||||||
|
#include<iostream>
|
||||||
|
#include<cassert>
|
||||||
|
|
||||||
class Z
|
class Z
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef ::linear_combination<Z> linear_combination;
|
using linear_combination = ::linear_combination<Z>;
|
||||||
typedef ::linear_combination_const_iter<Z> linear_combination_const_iter;
|
using linear_combination_const_iter = ::linear_combination_const_iter<Z>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum steal { STEAL };
|
std::shared_ptr<mpz_class> impl;
|
||||||
|
void write_state() const {
|
||||||
class Z_impl : public refcounted
|
std::cout << "I store the following value " << *this << "\n";
|
||||||
{
|
std::cout << "Number of objects pointing to the same value " << impl.use_count() << "\n";
|
||||||
public:
|
/* std::cout << "I point to " << impl.get() << "\n"; */
|
||||||
mpz_t x;
|
/* std::cout << "My size " << sizeof(*this) << "\n"; */
|
||||||
|
/* std::cout << "Size of std::shared_ptr<mpz_class> " << sizeof(impl) << "\n"; */
|
||||||
public:
|
/* std::cout << "Size of mpz_class " << sizeof(*impl) << "\n"; */
|
||||||
Z_impl () { mpz_init (x); }
|
}
|
||||||
Z_impl (int init) { mpz_init_set_si (x, init); }
|
|
||||||
Z_impl (copy, mpz_srcptr init) { mpz_init_set (x, init); }
|
|
||||||
Z_impl (steal, mpz_srcptr init) { x[0] = *init; }
|
|
||||||
Z_impl (reader &r)
|
|
||||||
{
|
|
||||||
mpz_init (x);
|
|
||||||
r.read_mpz (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Z_impl () { mpz_clear (x); }
|
|
||||||
|
|
||||||
void write_self (writer &w) const
|
|
||||||
{
|
|
||||||
w.write_mpz (x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ptr<Z_impl> impl;
|
|
||||||
|
|
||||||
Z (steal, mpz_srcptr init) : impl(new Z_impl (STEAL, init)) { }
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Z () : impl(new Z_impl) { }
|
Z() : impl(new mpz_class) {
|
||||||
Z (int init) : impl(new Z_impl (init)) { }
|
#ifdef DEBUG_Z
|
||||||
Z (const Z &z) : impl(z.impl) { }
|
std::cout << "Z()" << "\n";
|
||||||
Z (copy, const Z &z) : impl(new Z_impl (COPY, z.impl->x)) { }
|
write_state();
|
||||||
Z (reader &r) : impl(new Z_impl (r)) { }
|
#endif
|
||||||
~Z () { }
|
}
|
||||||
|
Z(mpz_t z) : impl(new mpz_class(z)) {
|
||||||
Z &operator = (const Z &z) { impl = z.impl; return *this; }
|
#ifdef DEBUG_Z
|
||||||
Z &operator = (int x) { impl = new Z_impl (x); return *this; }
|
std::cout << "Z(mpz_t)" << "\n";
|
||||||
|
write_state();
|
||||||
bool operator == (const Z &z) const { return mpz_cmp (impl->x, z.impl->x) == 0; }
|
#endif
|
||||||
bool operator != (const Z &z) const { return !operator == (z); }
|
}
|
||||||
|
Z(mpz_class z) : impl(new mpz_class(z)) {
|
||||||
bool operator == (int y) const { return mpz_cmp_si (impl->x, y) == 0; }
|
#ifdef DEBUG_Z
|
||||||
bool operator != (int y) const { return !operator == (y); }
|
std::cout << "Z(mpz_class)" << "\n";
|
||||||
|
write_state();
|
||||||
bool operator < (const Z &z) const { return mpz_cmp (impl->x, z.impl->x) < 0; }
|
#endif
|
||||||
|
}
|
||||||
|
Z(int init) : impl(new mpz_class(init)) {
|
||||||
|
#ifdef DEBUG_Z
|
||||||
|
std::cout << "Z(int)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Z(const Z& z) : impl(z.impl) {
|
||||||
|
#ifdef DEBUG_Z
|
||||||
|
std::cout << "Z(const Z& z)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Z(Z&& z) : impl(std::move(z.impl)) {
|
||||||
|
#ifdef DEBUG_Z
|
||||||
|
std::cout << "Z(Z&& z)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
z.impl = std::make_shared<mpz_class>(mpz_class(0));
|
||||||
|
}
|
||||||
|
~Z() {
|
||||||
|
#ifdef DEBUG_Z
|
||||||
|
std::cout << "~Z()" << "\n";
|
||||||
|
write_state();
|
||||||
|
if(impl.use_count() == 1)
|
||||||
|
std::cout << "Destroying..." << "\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Z& operator = (const Z& z) {
|
||||||
|
impl = z.impl;
|
||||||
|
#ifdef DEBUG_Z
|
||||||
|
std::cout << "Z& operator = (const Z&)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z& operator = (const int x) {
|
||||||
|
impl = std::make_shared<mpz_class>(mpz_class(x));
|
||||||
|
#ifdef DEBUG_Z
|
||||||
|
std::cout << "Z& operator = (int)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Z& operator = (Z&& z) {
|
||||||
|
impl = std::move(z.impl);
|
||||||
|
z.impl = std::make_shared<mpz_class>(mpz_class(0));
|
||||||
|
#ifdef DEBUG_Z
|
||||||
|
std::cout << "Z& operator = (Z&&)" << "\n";
|
||||||
|
write_state();
|
||||||
|
#endif
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == (const Z& z) const {
|
||||||
|
return *impl.get() == *z.impl.get();
|
||||||
|
}
|
||||||
|
bool operator != (const Z& z) const {
|
||||||
|
return !operator == (z);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator == (const int y) const {
|
||||||
|
return *impl.get() == mpz_class(y);
|
||||||
|
}
|
||||||
|
bool operator != (const int y) const {
|
||||||
|
return ! operator == (y);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator < (const Z& z) const {
|
||||||
|
return *impl.get() < *z.impl.get();
|
||||||
|
}
|
||||||
|
|
||||||
bool is_unit () const
|
bool is_unit () const
|
||||||
{
|
{
|
||||||
return *this == 1 || *this == -1;
|
return *this == 1 || *this == -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Z operator + (const Z &z) const
|
|
||||||
{
|
|
||||||
mpz_t x;
|
|
||||||
mpz_init (x);
|
|
||||||
mpz_add (x, impl->x, z.impl->x);
|
|
||||||
return Z (STEAL, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Z operator - () const
|
|
||||||
{
|
|
||||||
mpz_t x;
|
|
||||||
mpz_init (x);
|
|
||||||
mpz_neg (x, impl->x);
|
|
||||||
return Z (STEAL, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Z operator - (const Z &z) const
|
|
||||||
{
|
|
||||||
mpz_t x;
|
|
||||||
mpz_init (x);
|
|
||||||
mpz_sub (x, impl->x, z.impl->x);
|
|
||||||
return Z (STEAL, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Z operator * (const Z &z) const
|
|
||||||
{
|
|
||||||
mpz_t x;
|
|
||||||
mpz_init (x);
|
|
||||||
mpz_mul (x, impl->x, z.impl->x);
|
|
||||||
return Z (STEAL, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
Z operator / (const Z &denom) const
|
|
||||||
{
|
|
||||||
if (mpz_cmp_si (denom.impl->x, 1) == 0)
|
|
||||||
return *this;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert (mpz_cmp_si (denom.impl->x, -1) == 0);
|
|
||||||
|
|
||||||
mpz_t x;
|
|
||||||
mpz_init (x);
|
|
||||||
mpz_neg (x, impl->x);
|
|
||||||
return Z (STEAL, x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Z recip () const
|
|
||||||
{
|
|
||||||
assert (is_unit ());
|
|
||||||
return Z (COPY, *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// *this += z1*z2
|
|
||||||
Z &muladdeq (const Z &z1, const Z &z2)
|
|
||||||
{
|
|
||||||
mpz_addmul (impl->x, z1.impl->x, z2.impl->x);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z &operator += (const Z &z)
|
|
||||||
{
|
|
||||||
mpz_add (impl->x, impl->x, z.impl->x);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z &operator -= (const Z &z)
|
|
||||||
{
|
|
||||||
mpz_sub (impl->x, impl->x, z.impl->x);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z &operator *= (const Z &z)
|
|
||||||
{
|
|
||||||
mpz_mul (impl->x, impl->x, z.impl->x);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Z &operator /= (const Z &z)
|
|
||||||
{
|
|
||||||
if (mpz_cmp_si (z.impl->x, 1) == 0)
|
|
||||||
;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert (mpz_cmp_si (z.impl->x, -1) == 0);
|
|
||||||
mpz_neg (impl->x, impl->x);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool divides (const Z &num) const
|
|
||||||
{
|
|
||||||
return mpz_divisible_p (num.impl->x, impl->x);
|
|
||||||
}
|
|
||||||
bool operator | (const Z &num) const { return divides (num); }
|
|
||||||
|
|
||||||
Z divide_exact (const Z &denom) const
|
Z operator + (const Z& z) const {
|
||||||
{
|
return Z(*impl.get() + *z.impl.get());
|
||||||
// num = *this
|
}
|
||||||
|
|
||||||
|
Z operator - () const {
|
||||||
|
return Z(-*impl.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
Z operator - (const Z& z) const {
|
||||||
|
return Z(*impl.get() - *z.impl.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
Z operator * (const Z& z) const {
|
||||||
|
return Z(*impl.get() * *z.impl.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
Z operator / (const Z& z) const {
|
||||||
|
if(z == 0)
|
||||||
|
return *this;
|
||||||
|
else {
|
||||||
|
assert(z != 0);
|
||||||
|
return Z(*impl.get() / *z.impl.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Z recip () const {
|
||||||
|
assert(is_unit());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z& muladdeq(const Z& z1, const Z& z2) {
|
||||||
|
return *this += z1 * z2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z& operator += (const Z& z) {
|
||||||
|
*this = *this + z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z& operator -= (const Z& z) {
|
||||||
|
*this = *this - z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z& operator *= (const Z& z) {
|
||||||
|
*this = *this * z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Z& operator /= (const Z& z) {
|
||||||
|
*this = *this / z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool divides(const Z& num) const {
|
||||||
|
return mpz_divisible_p(num.impl.get()->get_mpz_t(),impl.get()->get_mpz_t());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator | (const Z& num) const {
|
||||||
|
return divides(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z divide_exact(const Z& denom) const {
|
||||||
mpz_t q;
|
mpz_t q;
|
||||||
mpz_init (q);
|
mpz_init(q);
|
||||||
mpz_divexact (q, impl->x, denom.impl->x);
|
mpz_divexact(q,impl.get()->get_mpz_t(), denom.impl.get()->get_mpz_t());
|
||||||
return Z (STEAL, q);
|
return Z(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<Z, Z> divide_with_remainder (const Z &denom) const
|
std::tuple<Z,Z> divide_with_remainder(const Z& denom) const {
|
||||||
{
|
mpz_t q,r;
|
||||||
// *this = num
|
mpz_init(q);
|
||||||
mpz_t q, r;
|
mpz_init(r);
|
||||||
mpz_init (q);
|
mpz_tdiv_qr(q, r, impl.get()->get_mpz_t(), denom.impl.get()->get_mpz_t());
|
||||||
mpz_init (r);
|
return std::make_tuple(Z(q), Z(r));
|
||||||
mpz_tdiv_qr (q, r, impl->x, denom.impl->x);
|
|
||||||
return make_tuple (Z (STEAL, q),
|
|
||||||
Z (STEAL, r));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Z gcd (const Z &z) const
|
Z gcd (const Z& z) const {
|
||||||
{
|
|
||||||
mpz_t d;
|
mpz_t d;
|
||||||
mpz_gcd (d, impl->x, z.impl->x);
|
mpz_init(d);
|
||||||
return Z (STEAL, d);
|
mpz_gcd(d, impl.get()->get_mpz_t(), z.impl.get()->get_mpz_t());
|
||||||
|
return Z(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
Z lcm (const Z &z) const
|
Z lcm (const Z& z) const {
|
||||||
{
|
|
||||||
mpz_t m;
|
mpz_t m;
|
||||||
mpz_lcm (m, impl->x, z.impl->x);
|
mpz_init(m);
|
||||||
return Z (STEAL, m);
|
mpz_lcm(m, impl.get()->get_mpz_t(), z.impl.get()->get_mpz_t());
|
||||||
|
return Z(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<Z, Z, Z> extended_gcd (const Z &z) const
|
std::tuple<Z, Z, Z> extended_gcd(const Z& z) const {
|
||||||
{
|
mpz_t d,s,t;
|
||||||
mpz_t d, s, t;
|
mpz_init(d);
|
||||||
mpz_init (d);
|
mpz_init(s);
|
||||||
mpz_init (s);
|
mpz_init(t);
|
||||||
mpz_init (t);
|
mpz_gcdext(d, s, t, impl.get()->get_mpz_t(), z.impl.get()->get_mpz_t());
|
||||||
mpz_gcdext (d, s, t, impl->x, z.impl->x);
|
return std::make_tuple<Z, Z, Z>(Z(d), Z(s), Z(t));
|
||||||
return make_tuple (Z (STEAL, d),
|
|
||||||
Z (STEAL, s),
|
|
||||||
Z (STEAL, t));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_ring () { printf ("Z"); }
|
static void show_ring () { printf ("Z"); }
|
||||||
void show_self () const { mpz_out_str (stdout, 10, impl->x); }
|
void show_self () const {
|
||||||
void display_self () const { show_self (); newline (); }
|
std::cout << *this;
|
||||||
void write_self (writer &w) const { write (w, *impl); }
|
}
|
||||||
|
void display_self () const {
|
||||||
|
std::cout << *this << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
friend std::ostream& operator << (std::ostream& os, const Z& z) {
|
||||||
|
return os << *z.impl;
|
||||||
|
}
|
||||||
|
int get_count() const {
|
||||||
|
return impl.use_count();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // _KNOTKIT_ALGEBRA_Z_H
|
||||||
|
60
algebra/Z2.h
60
algebra/Z2.h
@ -1,9 +1,15 @@
|
|||||||
|
#ifndef KNOTKIT_ALGEBRA_Z2_H
|
||||||
|
#define KNOTKIT_ALGEBRA_Z2_H
|
||||||
|
#include <iostream>
|
||||||
|
#include <tuple>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
class Z2
|
class Z2
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef ::linear_combination<Z2> linear_combination;
|
using linear_combination = ::linear_combination<Z2>;
|
||||||
// typedef linear_combination_iter<Z2> linear_combination_iter;
|
// typedef linear_combination_iter<Z2> linear_combination_iter;
|
||||||
typedef ::linear_combination_const_iter<Z2> linear_combination_const_iter;
|
using linear_combination_const_iter = ::linear_combination_const_iter<Z2>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool v;
|
bool v;
|
||||||
@ -13,37 +19,40 @@ class Z2
|
|||||||
Z2 (int x) : v((bool)(x & 1)) { }
|
Z2 (int x) : v((bool)(x & 1)) { }
|
||||||
Z2 (unsigned x) : v((bool)(x & 1)) { }
|
Z2 (unsigned x) : v((bool)(x & 1)) { }
|
||||||
Z2 (bool v_) : v(v_) { }
|
Z2 (bool v_) : v(v_) { }
|
||||||
Z2 (const Z2 &x) : v(x.v) { }
|
Z2 (const Z2& x) : v(x.v) { }
|
||||||
Z2 (copy, const Z2 &x) : v(x.v) { }
|
Z2 (Z2&& x) : v(std::move(x.v)) {
|
||||||
|
x.v = 0;
|
||||||
|
}
|
||||||
Z2 (reader &r) { v = r.read_bool (); }
|
Z2 (reader &r) { v = r.read_bool (); }
|
||||||
~Z2 () { }
|
~Z2 () { }
|
||||||
|
|
||||||
Z2 &operator = (const Z2 &x) { v = x.v; return *this; }
|
Z2& operator = (const Z2& x) { v = x.v; return *this; }
|
||||||
Z2 &operator = (int x) { v = (bool)(x & 1); return *this; }
|
Z2& operator = (Z2&& x) { v = x.v; x.v = 0; return *this; }
|
||||||
|
Z2& operator = (int x) { v = (bool)(x & 1); return *this; }
|
||||||
|
|
||||||
bool operator == (const Z2 &x) const { return v == x.v; }
|
bool operator == (const Z2& x) const { return v == x.v; }
|
||||||
bool operator != (const Z2 &x) const { return v != x.v; }
|
bool operator != (const Z2& x) const { return v != x.v; }
|
||||||
|
|
||||||
bool operator == (int x) const { return v == (bool)(x & 1); }
|
bool operator == (int x) const { return v == (bool)(x & 1); }
|
||||||
bool operator != (int x) const { return !operator == (x); }
|
bool operator != (int x) const { return !operator == (x); }
|
||||||
|
|
||||||
bool is_unit () const { return v; }
|
bool is_unit () const { return v; }
|
||||||
|
|
||||||
Z2 operator + (const Z2 &x) const { return Z2 (v ^ x.v); }
|
Z2 operator + (const Z2& x) const { return Z2 (v ^ x.v); }
|
||||||
Z2 operator - (const Z2 &x) const { return Z2 (v ^ x.v); }
|
Z2 operator - (const Z2& x) const { return Z2 (v ^ x.v); }
|
||||||
Z2 operator - () const { return *this; }
|
Z2 operator - () const { return *this; }
|
||||||
Z2 operator * (const Z2 &x) const { return Z2 (v & x.v); }
|
Z2 operator * (const Z2& x) const { return Z2 (v & x.v); }
|
||||||
Z2 operator / (const Z2 &x) const { assert (x.v); return *this; }
|
Z2 operator / (const Z2& x) const { assert (x.v); return *this; }
|
||||||
|
|
||||||
Z2 recip () const { assert (v); return *this; }
|
Z2 recip () const { assert (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) { 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) { v &= x.v; return *this; }
|
||||||
Z2 &operator /= (const Z2 &x) { assert (x.v); return *this; }
|
Z2& operator /= (const Z2& x) { assert (x.v); return *this; }
|
||||||
|
|
||||||
// *this += z1*z2
|
// *this += z1*z2
|
||||||
Z2 &muladdeq (const Z2 &z1, const Z2 &z2)
|
Z2& muladdeq (const Z2& z1, const Z2& z2)
|
||||||
{
|
{
|
||||||
return operator += (z1 * z2);
|
return operator += (z1 * z2);
|
||||||
}
|
}
|
||||||
@ -63,16 +72,21 @@ class Z2
|
|||||||
return Z2 (1);
|
return Z2 (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<Z2, Z2, Z2> extended_gcd (Z2 x) const
|
std::tuple<Z2, Z2, Z2> extended_gcd (Z2 x) const
|
||||||
{
|
{
|
||||||
if (v)
|
if (v)
|
||||||
return make_tuple (Z2 (1), Z2 (1), Z2 (0));
|
return std::make_tuple (Z2 (1), Z2 (1), Z2 (0));
|
||||||
else
|
else
|
||||||
return make_tuple (Z2 (1), Z2 (0), Z2 (1));
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void show_ring () { printf ("Z2"); }
|
static void show_ring () { printf ("Z2"); }
|
||||||
void write_self (writer &w) const { w.write_bool (v); }
|
void write_self (writer &w) const { w.write_bool (v); }
|
||||||
void show_self () const { printf ("%d", (int)v); }
|
void show_self () const { std::cout << *this; }
|
||||||
void display_self () const { printf ("%d\n", (int)v); }
|
void display_self () const { std::cout << *this << "\n"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif //KNOTKIT_ALGEBRA_Z2_H
|
||||||
|
76
algebra/Zp.h
76
algebra/Zp.h
@ -1,10 +1,16 @@
|
|||||||
|
#ifndef KNOTKIT_ALGEBRA_ZP_H
|
||||||
|
#define KNOTKIT_ALGEBRA_ZP_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <tuple>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
template<unsigned p>
|
template<unsigned p>
|
||||||
class Zp
|
class Zp
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef ::linear_combination<Zp<p> > linear_combination;
|
using linear_combination = ::linear_combination<Zp<p>>;
|
||||||
typedef ::linear_combination_const_iter<Zp<p> > linear_combination_const_iter;
|
using linear_combination_const_iter = ::linear_combination_const_iter<Zp<p>>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned v;
|
unsigned v;
|
||||||
@ -21,84 +27,88 @@ class Zp
|
|||||||
v = i;
|
v = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zp (const Zp &x) : v(x.v) { }
|
Zp (const Zp& x) : v(x.v) { }
|
||||||
Zp (copy, const Zp &x) : v(x.v) { }
|
Zp (copy, const Zp& x) : v(x.v) {}
|
||||||
|
Zp (Zp&& x) : v(std::move(x.v)) {
|
||||||
|
x.v = 0;
|
||||||
|
}
|
||||||
~Zp () { }
|
~Zp () { }
|
||||||
|
|
||||||
Zp &operator = (const Zp &x) { v = x.v; return *this; }
|
Zp& operator = (const Zp& x) { v = x.v; return *this; }
|
||||||
Zp &operator = (int x)
|
Zp& operator = (Zp&& x) { v = x.v; x.v = 0; return *this; }
|
||||||
|
Zp& operator = (int x)
|
||||||
{
|
{
|
||||||
return operator = (Zp (x));
|
return operator = (Zp (x));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == (const Zp &x) const { return v == x.v; }
|
bool operator == (const Zp& x) const { return v == x.v; }
|
||||||
bool operator != (const Zp &x) const { return !operator == (x); }
|
bool operator != (const Zp& x) const { return !operator == (x); }
|
||||||
|
|
||||||
bool operator == (int x) const { return operator == (Zp (x)); }
|
bool operator == (int x) const { return operator == (Zp (x)); }
|
||||||
bool operator != (int x) const { return !operator == (x); }
|
bool operator != (int x) const { return !operator == (x); }
|
||||||
|
|
||||||
bool operator < (const Zp &x) const { return v < x.v; }
|
bool operator < (const Zp& x) const { return v < x.v; }
|
||||||
|
|
||||||
bool is_unit () const
|
bool is_unit () const
|
||||||
{
|
{
|
||||||
return v != 0;
|
return v != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zp operator + (const Zp &x) const { return Zp (v + x.v); }
|
Zp operator + (const Zp& x) const { return Zp (v + x.v); }
|
||||||
Zp operator - (const Zp &x) const { return Zp ((int)v - (int)x.v); }
|
Zp operator - (const Zp& x) const { return Zp ((int)v - (int)x.v); }
|
||||||
Zp operator - () const { return Zp (- (int)v); }
|
Zp operator - () const { return Zp (- (int)v); }
|
||||||
|
|
||||||
Zp operator * (const Zp &x) const { return Zp (v * x.v); }
|
Zp operator * (const Zp& x) const { return Zp (v * x.v); }
|
||||||
|
|
||||||
Zp operator / (const Zp &x) const
|
Zp operator / (const Zp& x) const
|
||||||
{
|
{
|
||||||
return operator * (x.recip ());
|
return operator * (x.recip ());
|
||||||
}
|
}
|
||||||
|
|
||||||
Zp recip () const
|
Zp recip () const
|
||||||
{
|
{
|
||||||
tuple<unsigned, int, int> t = unsigned_extended_gcd (v, p);
|
std::tuple<unsigned, int, int> t = unsigned_extended_gcd (v, p);
|
||||||
assert (get<0> (t) == 1);
|
assert (std::get<0> (t) == 1);
|
||||||
assert ((int)get<0> (t) == get<1> (t)*(int)v + get<2> (t)*(int)p);
|
assert ((int)std::get<0> (t) == std::get<1> (t)*(int)v + std::get<2> (t)*(int)p);
|
||||||
|
|
||||||
return Zp (get<1> (t));
|
return Zp (std::get<1> (t));
|
||||||
}
|
}
|
||||||
|
|
||||||
Zp &operator += (const Zp &x)
|
Zp& operator += (const Zp& x)
|
||||||
{
|
{
|
||||||
v = (v + x.v) % p;
|
v = (v + x.v) % p;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zp &operator -= (const Zp &x) { return operator = (Zp ((int)v - (int)x.v)); }
|
Zp& operator -= (const Zp& x) { return operator = (Zp ((int)v - (int)x.v)); }
|
||||||
|
|
||||||
Zp &operator *= (const Zp &x)
|
Zp& operator *= (const Zp& x)
|
||||||
{
|
{
|
||||||
v = (v * x.v) % p;
|
v = (v * x.v) % p;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zp &operator /= (const Zp &x)
|
Zp& operator /= (const Zp& x)
|
||||||
{
|
{
|
||||||
return operator *= (x.recip ());
|
return operator *= (x.recip ());
|
||||||
}
|
}
|
||||||
|
|
||||||
// d | n, d.divides (n)
|
// d | n, d.divides (n)
|
||||||
bool divides (const Zp &n) const
|
bool divides (const Zp& n) const
|
||||||
{
|
{
|
||||||
return v || !n.v;
|
return v || !n.v;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator | (const Zp &n) const { return divides (n); }
|
bool operator | (const Zp& n) const { return divides (n); }
|
||||||
|
|
||||||
Zp div (const Zp &d) const { return operator / (d); }
|
Zp div (const Zp& d) const { return operator / (d); }
|
||||||
|
|
||||||
tuple<Zp, Zp, Zp> extended_gcd (const Zp &x) const
|
std::tuple<Zp, Zp, Zp> extended_gcd (const Zp &x) const
|
||||||
{
|
{
|
||||||
if (v)
|
if (v)
|
||||||
return make_tuple (v, Zp (1), Zp (0));
|
return std::make_tuple (v, Zp (1), Zp (0));
|
||||||
else
|
else
|
||||||
return make_tuple (x, Zp (0), Zp (1));
|
return std::make_tuple (x, Zp (0), Zp (1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Zp gcd (const Zp &x) const
|
Zp gcd (const Zp &x) const
|
||||||
@ -106,8 +116,12 @@ class Zp
|
|||||||
assert (v || x.v);
|
assert (v || x.v);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
friend std::ostream& operator << (std::ostream& os, const Zp& x) {
|
||||||
static void show_ring () { printf ("Z%d", p); }
|
return os << x.v;
|
||||||
void show_self () const { printf ("%d (%d)", v, p); }
|
}
|
||||||
void display_self () const { show_self (); newline (); }
|
static void show_ring () { std::cout << "Z" << p; }
|
||||||
|
void show_self () const { std::cout << v << "(" << p << ")"; }
|
||||||
|
void display_self () const { std::cout << *this << "\n"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif //KNOTKIT_ALGEBRA_ZP_H
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
|
||||||
#include <lib/lib.h>
|
#include <lib/lib.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG_ALGEBRA
|
||||||
|
#define DEBUG_Z
|
||||||
|
#define DEBUG_Q
|
||||||
|
#endif
|
||||||
|
|
||||||
inline int recip (int x)
|
inline int recip (int x)
|
||||||
{
|
{
|
||||||
assert (x == 1 || x == -1);
|
assert (x == 1 || x == -1);
|
||||||
|
1
kk.cpp
1
kk.cpp
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
#include <knotkit.h>
|
#include <knotkit.h>
|
||||||
|
|
||||||
const char *program_name;
|
const char *program_name;
|
||||||
|
Loading…
Reference in New Issue
Block a user