39 # include <vcl_msvc_warnings.h> 41 #include "vnl/vnl_export.h" 71 inline operator int()
const {
return val_; }
72 inline operator int() {
return val_; }
73 inline operator long()
const {
return val_; }
74 inline operator long() {
return val_; }
75 inline operator short()
const {
short r = (short)
val_; assert(r ==
val_);
return r; }
76 inline operator short() {
short r = (short)
val_; assert(r ==
val_);
return r; }
104 r %=N;
if (r<0) r=N+r;
106 if (N<=0x7fff || (
val_<=0x7fff && r<=0x7fff)) {
val_ *= r;
val_ %= N;
return *
this; }
114 unsigned int s=int(r);
115 if (N<=0x7fff || (
val_<=0x7fff && s<=0x7fff)) {
val_ *= s;
val_ %= N;
return *
this; }
123 static unsigned int t_ = 0;
124 if (t_ != 0)
return t_;
125 std::vector<unsigned int> d =
decompose();
126 t_ = 1;
unsigned int p = 1;
127 for (
unsigned int i : d)
129 if (p != i) t_ *= i-1;
140 if (
val_==1)
return *
this;
143 for (
unsigned int r=1; r<=N/2; ++r) {
144 unsigned int t=int(*
this*
int(r));
145 if (t==1)
return r;
else if (t==N-1)
return N-r;
167 static std::vector<unsigned int> decomposition_ = std::vector<unsigned int>();
168 if (decomposition_.size() > 0)
return decomposition_;
170 for (
unsigned int d=2; d*d<=r; ++d)
171 while (r%d == 0) { decomposition_.push_back(d); r /= d; }
172 if (r > 1) decomposition_.push_back(r);
173 return decomposition_;
179 return d.size() == 1;
198 for (
int r=1; r<N; ++r) {
if (y==1)
return mo_=r; y *=
val_; }
207 static Base gen_ = 0;
208 if (gen_ != 0)
return gen_;
209 if (N==2)
return gen_=1;
211 for (gen_=2; gen_!=0; ++gen_) {
213 unsigned int g=h;
Base y = 1, z = gen_;
while (g>0) {
if (g%2) y *= z; g/=2; z*=z; }
215 if (y == 1)
continue;
226 if (r==0)
return 1;
if (r==1)
return *
this;
227 Base y = 1, z = *
this;
int s=r;
while (s!=0) {
if (s%2) y*=z; s/=2; z*=z; }
233 unsigned int log()
const {
240 if (y == *
this)
return lp1_-1;
254 static inline unsigned int gcd(
unsigned int l,
unsigned int n) {
256 while (l!=0) {
unsigned int t = l; l = l1 % l; l1 = t; }
259 static inline unsigned int gcd(
unsigned int l) {
return gcd(l, N); }
282 int n; s >> n; r=n;
return s;
430 template <
int N,
int M>
456 inline std::size_t
deg()
const {
return val_.size() - 1; }
459 int degree()
const {
for (
int i=
deg(); i>=0; --i)
if (
val_[i]!=0)
return i;
return -1; }
470 for (
unsigned int i=0; i<=
deg(); ++i)
471 if (
val_[i] != x[i])
return false;
472 for (
unsigned int i=
deg()+1; i<=x.
deg(); ++i)
473 if (x[i] != 0)
return false;
478 if (x!=
val_[0])
return false;
479 for (
unsigned int i=1; i<=
deg(); ++i)
if (
val_[i] != 0)
return false;
485 Base operator-()
const { std::vector<Scalar> p =
val_;
for (
unsigned int i=0; i<p.size(); ++i) p[i]=-p[i];
return p; }
489 bool operator!()
const {
for (
unsigned int i=0; i<=
deg(); ++i)
if (
val_[i] != 0)
return false;
return true; }
493 for (
unsigned int i=0; i<=r.
deg(); ++i)
495 else val_.push_back(r[i]);
500 for (
unsigned int i=0; i<=r.
deg(); ++i)
502 else val_.push_back(-r[i]);
512 for (
unsigned int i=0; i<=
deg(); ++i)
522 static std::vector<Scalar> poly_(M+1,
Scalar(0));
524 assert(poly_[M] != 0);
528 assert(p.size() == M+1 && p[M].is_unit());
531 for (
int m=0;
m<=M; ++
m) poly_[
m] = f*p[
m];
538 Base x = *
this; *
this = r; *
this *= x[0];
539 while (
val_.size() < M)
val_.push_back(0);
540 for (
int i=1; i<=x.
degree(); ++i)
541 for (
unsigned int j=0; j<=r.
deg(); ++j)
549 unsigned int order = 0;
550 do t *= *
this, ++order;
while (t !=
Scalar(1) && t !=
Scalar(0));
551 return t==
Scalar(1) ? order : -1;
590 template <
int N,
int M>
598 template <
int N,
int M>
607 template <
int N,
int M>
616 template <
int N,
int M>
626 template <
int N,
int M>
634 template <
int N,
int M>
638 for (
unsigned int i=0; i<=r.
deg(); ++i) {
639 if (r[i] == 0)
continue;
642 if (r[i] != 1 || i==0) s << r[i];
644 if (i>1) s <<
'^' << i;
650 #endif // vnl_finite_h_ bool operator==(Base const &x) const
Comparison of finite int numbers.
vnl_bignum operator+(vnl_bignum const &r1, long r2)
Returns the sum of two bignum numbers.
vnl_finite_int(Base const &x)
~vnl_finite_int_poly()=default
int val_
value of this number (smallest nonnegative representation)
Scalar operator[](unsigned int i) const
Access to individual coefficients.
Base & operator-=(Base const &r)
Minus&assign: replace lhs by lhs - rhs.
bool operator!=(Base const &x) const
Base operator-() const
Unary minus - returns the additive inverse.
finite modulo-N arithmetic.
unsigned int lp1_
cached value for 1+log()
static Base smallest_generator()
Return the smallest multiplicative generator of the units in this ring.
unsigned int mo_
cached value for multiplicative order
Base operator-() const
Unary minus - returns the additive inverse.
vnl_finite_int_poly< N, M > Base
Base operator--(int)
Post-decrement (r–).
vnl_finite_int(int x=0)
Creates a finite int element.
vnl_finite_int_poly()
Default constructor. Creates a degree 0 finite_int_poly equal to 0.
real numerical constants.
static unsigned int gcd(unsigned int l)
Base & operator *=(Scalar const &n)
Scalar multiple of this.
static unsigned int gcd(unsigned int l, unsigned int n)
Calculate the greatest common divisor of l and N.
static Base smallest_generator()
Return the smallest multiplicative generator of the units in this ring.
bool is_unit() const
Return true only when x is a unit in this ring.
bool operator!=(int x) const
vnl_bignum squared_magnitude(vnl_bignum const &x)
finite modulo-N arithmetic with polynomials of degree < M.
vnl_finite_int_poly(Scalar const &n)
Creates a degree 0 finite_int_poly.
std::ostream & operator<<(std::ostream &s, vnl_decnum const &r)
decimal output.
Base & operator=(Base const &x)
Assignment.
Base operator+() const
Unary plus - returns the current polynomial.
Base & operator+=(Base const &r)
Plus&assign: replace lhs by lhs + rhs.
Base & operator+=(Base const &r)
Plus&assign: replace lhs by lhs + rhs.
unsigned int additive_order() const
The additive order of x is the smallest positive r such that r*x == 0.
vnl_finite_int_poly(Base const &x)
bool isnan(vnl_bignum const &)
bool operator!=(Base const &x) const
~vnl_finite_int()=default
unsigned int multiplicative_order() const
The multiplicative order of x is the smallest r (>0) such that x^r == 1.
static std::vector< unsigned int > decompose()
Write N as the unique product of prime factors.
bool operator==(int r1, vnl_finite_int< N > const &r2)
Base operator++(int)
Post-increment (r++).
void add_modulo_poly(unsigned int m, Scalar const &x)
Add x to the i-th degree coefficient of val_, possibly reducing modulo the "modulo" poly.
bool operator!() const
Unary not - returns true if finite int poly is equal to zero.
Base & operator=(Scalar const &n)
static Base exp(int r)
Return the inverse of log(), i.e., return g^r where g is the smallest generator.
std::vector< Scalar > val_
M-tuple (or degree M-1 polynomial) representing this.
bool isfinite(vnl_bignum const &x)
Base & operator--()
Pre-decrement (–r).
static bool is_field()
Return true when this ring is a field.
Base operator+() const
Unary plus - returns the current number.
static bool is_field()
Return true when N is a prime number, i.e., when this ring is a field.
unsigned int log() const
Return the smallest nonnegative exponent r for which x=g^r, where g is the smallest generator.
vnl_finite_int< N > Scalar
Base & operator-=(Base const &r)
Minus&assign: replace lhs by lhs - rhs.
int degree() const
Effective degree of this polynomial; equals -1 when this polynomial is 0.
static unsigned int Ntothe(unsigned int m)
bool operator==(Base const &x) const
Comparison of finite int polys.
static std::vector< Scalar > & modulo_polynomial(std::vector< Scalar > p=std::vector< Scalar >())
get/set the (irreducible) modulo polynomial of degree M.
Base & operator=(Base const &x)
Assignment.
static unsigned int cardinality()
The number of different finite_int numbers of this type.
Base reciproc() const
Multiplicative inverse.
VNL_EXPORT std::istream & operator>>(std::istream &s, vnl_decnum &r)
decimal input.
vnl_bignum operator-(vnl_bignum const &r1, vnl_bignum const &r2)
Returns the difference of two bignum numbers.
bool operator!=(int r1, vnl_finite_int< N > const &r2)
unsigned int multiplicative_order() const
Return the multiplicative order of this polynomial.
void set_log(unsigned int r) const
private function to set cached value of lp1_ when available.
unsigned int additive_order() const
The additive order of x is the smallest nonnegative r such that r*x == 0.
bool operator!=(Scalar const &x) const
Base & operator++()
Pre-increment (++r).
Base pow(int r)
Return the r-th power of this number.
bool is_zero_divisor() const
Return true only when x is a zero divisor, i.e., is not a unit.
Base & operator/=(Base const &r)
Divide&assign. Uses r.reciproc() for efficient computation.
vnl_bignum operator/(vnl_bignum const &r1, vnl_bignum const &r2)
Returns the division of two bignum numbers.
static unsigned int totient()
Return the Euler totient function, i.e., the number of units of this ring.
bool operator==(int x) const
vnl_bignum operator *(vnl_bignum const &r1, vnl_bignum const &r2)
Returns the product of two bignum numbers.
std::size_t deg() const
Formal degree of this polynomial.
vnl_finite_int_poly(std::vector< Scalar > const &p)
Creates a general finite_int_poly.
vnl_bignum sqr(vnl_bignum const &x)
bool operator!() const
Unary not - returns true if finite int number is equal to zero.
static unsigned int cardinality()
The number of different finite_int polynomials of this type.
Base & operator *=(int r)
Multiply&assign: replace lhs by lhs * rhs.
bool operator==(Scalar const &x) const