Loading...
Searching...
No Matches
int_int.cc
Go to the documentation of this file.
/* emacs edit mode for this file is -*- C++ -*- */
#include "config.h"
#include "canonicalform.h"
#include "imm.h"
#include "int_int.h"
#include "int_rat.h"
#include "factory/cf_gmp.h"
#include "gmpext.h"
#ifdef HAVE_OMALLOC
const omBin InternalInteger::InternalInteger_bin = omGetSpecBin(sizeof(InternalInteger));
#endif
InternalCF* InternalInteger::deepCopyObject() const
{
mpz_t dummy;
mpz_init_set( dummy, thempi );
return new InternalInteger( dummy );
}
#ifndef NOSTREAMIO
void InternalInteger::print( OSTREAM & os, char * c )
{
if ( *c == '*' && mpz_cmp_si( thempi, 1 ) == 0 )
os << c+1;
else if ( *c == '*' && mpz_cmp_si( thempi, -1 ) == 0 )
os << '-' << c+1;
else {
char * str = new char[mpz_sizeinbase( thempi, 10 ) + 2];
str = mpz_get_str( str, 10, thempi );
os << str << c;
delete [] str;
}
}
#endif /* NOSTREAMIO */
bool InternalInteger::is_imm() const
{
return mpz_is_imm( thempi );
}
InternalCF* InternalInteger::genZero()
{
if ( isZero() )
return copyObject();
else
return new InternalInteger();
}
InternalCF* InternalInteger::genOne()
{
if ( isOne() )
return copyObject();
else
return new InternalInteger( 1 );
}
/** InternalCF * InternalInteger::neg ()
* @sa CanonicalForm::operator -()
**/
InternalCF *
InternalInteger::neg ()
{
if ( getRefCount() > 1 )
{
decRefCount();
mpz_t dummy;
mpz_init_set( dummy, thempi );
mpz_neg( dummy, dummy );
return new InternalInteger( dummy );
}
else
{
mpz_neg( thempi, thempi );
return this;
}
}
InternalCF* InternalInteger::addsame( InternalCF * c )
{
if ( getRefCount() > 1 )
{
decRefCount();
mpz_t dummy;
mpz_init( dummy );
mpz_add( dummy, thempi, MPI( c ) );
if ( mpz_is_imm( dummy ) )
{
InternalCF * res = int2imm( mpz_get_si( dummy ) );
mpz_clear( dummy );
return res;
}
else
return new InternalInteger( dummy );
}
else
{
mpz_add( thempi, thempi, MPI( c ) );
if ( mpz_is_imm( thempi ) )
{
InternalCF * res = int2imm( mpz_get_si( thempi ) );
delete this;
return res;
}
else
return this;
}
}
InternalCF* InternalInteger::subsame( InternalCF * c )
{
if ( getRefCount() > 1 )
{
decRefCount();
mpz_t dummy;
mpz_init( dummy );
mpz_sub( dummy, thempi, MPI( c ) );
if ( mpz_is_imm( dummy ) )
{
InternalCF * res = int2imm( mpz_get_si( dummy ) );
mpz_clear( dummy );
return res;
}
else
return new InternalInteger( dummy );
}
else
{
mpz_sub( thempi, thempi, MPI( c ) );
if ( mpz_is_imm( thempi ) )
{
InternalCF * res = int2imm( mpz_get_si( thempi ) );
delete this;
return res;
}
else
return this;
}
}
InternalCF* InternalInteger::mulsame( InternalCF * c )
{
if ( getRefCount() > 1 )
{
decRefCount();
mpz_t dummy;
mpz_init( dummy );
mpz_mul( dummy, thempi, MPI( c ) );
#if 0
if ( mpz_is_imm( dummy ) )
{
// can this happen ???
InternalCF * res = int2imm( mpz_get_si( dummy ) );
mpz_clear( dummy );
return res;
}
else
#endif
return new InternalInteger( dummy );
}
else
{
mpz_mul( thempi, thempi, MPI( c ) );
#if 0
if ( mpz_is_imm( &thempi ) )
{
// can this happen ???
InternalCF * res = int2imm( mpz_get_si( &thempi ) );
delete this;
return res;
}
else
#endif
return this;
}
}
/**
* @sa CanonicalForm::operator <(), CanonicalForm::operator ==(), InternalInteger::comparecoeff()
**/
int
InternalInteger::comparesame ( InternalCF * c )
{
ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
return mpz_cmp( thempi, MPI( c ) );
}
/**
* @sa CanonicalForm::operator <(), CanonicalForm::operator ==(), InternalInteger::comparesame()
**/
int
InternalInteger::comparecoeff ( InternalCF * c )
{
ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
return mpz_cmp_si( thempi, imm2int( c ) );
}
InternalCF* InternalInteger::addcoeff( InternalCF* c )
{
ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
long cc = imm2int( c );
if ( getRefCount() > 1 )
{
decRefCount();
mpz_t dummy;
mpz_init( dummy );
if ( cc < 0 )
mpz_sub_ui( dummy, thempi, -cc );
else
mpz_add_ui( dummy, thempi, cc );
if ( mpz_is_imm( dummy ) )
{
InternalCF * res = int2imm( mpz_get_si( dummy ) );
mpz_clear( dummy );
return res;
}
else
return new InternalInteger( dummy );
}
else
{
if ( cc < 0 )
mpz_sub_ui( thempi, thempi, -cc );
else
mpz_add_ui( thempi, thempi, cc );
if ( mpz_is_imm( thempi ) )
{
InternalCF * res = int2imm( mpz_get_si( thempi ) );
delete this;
return res;
}
else
return this;
}
}
InternalCF* InternalInteger::subcoeff( InternalCF* c, bool negate )
{
ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
long cc = imm2int( c );
if ( getRefCount() > 1 )
{
decRefCount();
mpz_t dummy;
if ( negate )
{
mpz_init_set_si( dummy, cc );
mpz_sub( dummy, dummy, thempi );
}
else
{
mpz_init( dummy );
if ( cc < 0 )
mpz_add_ui( dummy, thempi, -cc );
else
mpz_sub_ui( dummy, thempi, cc );
}
if ( mpz_is_imm( dummy ) )
{
InternalCF * res = int2imm( mpz_get_si( dummy ) );
mpz_clear( dummy );
return res;
}
else
return new InternalInteger( dummy );
}
else
{
if ( negate )
{
mpz_t dummy;
mpz_init_set_si( dummy, cc );
mpz_sub( thempi, dummy, thempi );
mpz_clear( dummy );
}
else
if ( cc < 0 )
mpz_add_ui( thempi, thempi, -cc );
else
mpz_sub_ui( thempi, thempi, cc );
if ( mpz_is_imm( thempi ) )
{
InternalCF * res = int2imm( mpz_get_si( thempi ) );
delete this;
return res;
}
else
return this;
}
}
InternalCF* InternalInteger::mulcoeff( InternalCF* c )
{
ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
long cc = imm2int( c );
if ( getRefCount() > 1 )
{
decRefCount();
mpz_t dummy;
mpz_init( dummy );
if ( cc < 0 )
{
mpz_mul_ui( dummy, thempi, -cc );
mpz_neg( dummy, dummy );
}
else
mpz_mul_ui( dummy, thempi, cc );
if ( mpz_is_imm( dummy ) )
{
InternalCF * res = int2imm( mpz_get_si( dummy ) );
mpz_clear( dummy );
return res;
}
else
return new InternalInteger( dummy );
}
else
{
if ( cc < 0 )
{
mpz_mul_ui( thempi, thempi, -cc );
mpz_neg( thempi, thempi );
}
else
mpz_mul_ui( thempi, thempi, cc );
if ( mpz_is_imm( thempi ) )
{
InternalCF * res = int2imm( mpz_get_si( thempi ) );
delete this;
return res;
}
else
return this;
}
}
/**
* @sa CanonicalForm::bgcd(), InternalInteger::bgcdcoeff()
**/
InternalCF *
InternalInteger::bgcdsame ( const InternalCF * const c ) const
{
ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
// simply return 1 if we are calculating over the rationals
if ( cf_glob_switches.isOn( SW_RATIONAL ) )
return int2imm( 1 );
// calculate gcd
mpz_t result;
mpz_init( result );
mpz_gcd( result, thempi, MPI( c ) );
mpz_abs( result, result );
// check for immediate result
if ( mpz_is_imm( result ) )
{
InternalCF * res = int2imm( mpz_get_si( result ) );
mpz_clear( result );
return res;
}
else
return new InternalInteger( result );
}
/**
* @sa CanonicalForm::bgcd(), InternalInteger::bgcdsame()
**/
InternalCF *
InternalInteger::bgcdcoeff ( const InternalCF * const c )
{
ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
// simply return 1 if we are calculating over the rationals
if ( cf_glob_switches.isOn( SW_RATIONAL ) )
return int2imm( 1 );
long cInt = imm2int( c );
// trivial cases
if ( cInt == 1 || cInt == -1 )
return int2imm( 1 );
else if ( cInt == 0 )
return copyObject();
// calculate gcd. We need a positive operand since
// `mpz_gcd_ui()' operates an unsigned int's only.
if ( cInt < 0 ) cInt = -cInt;
mpz_t dummy;
mpz_init( dummy );
// we do not need dummy since we know that cInt != 0
cInt = mpz_gcd_ui( dummy, thempi, cInt );
mpz_clear( dummy );
if ( cInt < 0 ) cInt = -cInt;
return int2imm( cInt );
}
/**
* @sa CanonicalForm::bextgcd(), InternalInteger::bextgcdcoeff()
**/
InternalCF *
InternalInteger::bextgcdsame( InternalCF * c, CanonicalForm & a, CanonicalForm & b )
{
ASSERT( ! ::is_imm( c ) && c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
// simply return 1 if we are calculating over the rationals
if ( cf_glob_switches.isOn( SW_RATIONAL ) )
{
a = 1/CanonicalForm( copyObject() ); b = 0;
return int2imm( 1 );
}
// calculate extended gcd
mpz_t result, aMPI, bMPI;
mpz_init( result );
mpz_init( aMPI );
mpz_init( bMPI );
mpz_gcdext( result, aMPI, bMPI, thempi, MPI( c ) );
// check and modify signs
if ( mpz_sgn( result ) < 0 )
{
mpz_neg( result, result );
mpz_neg( aMPI, aMPI );
mpz_neg( bMPI, bMPI );
}
// postconditioning of result
if ( mpz_is_imm( aMPI ) )
{
a = CanonicalForm( int2imm( mpz_get_si( aMPI ) ) );
mpz_clear( aMPI );
}
else
a = CanonicalForm( new InternalInteger( aMPI ) );
if ( mpz_is_imm( bMPI ) )
{
b = CanonicalForm( int2imm( mpz_get_si( bMPI ) ) );
mpz_clear( bMPI );
}
else
b = CanonicalForm( new InternalInteger( bMPI ) );
if ( mpz_is_imm( result ) )
{
InternalCF * res = int2imm( mpz_get_si( result ) );
mpz_clear( result );
return res;
}
else
return new InternalInteger( result );
}
/**
* @sa CanonicalForm::bextgcd(), InternalInteger::bextgcdsame()
**/
InternalCF *
InternalInteger::bextgcdcoeff( InternalCF * c, CanonicalForm & a, CanonicalForm & b )
{
ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
// simply return 1 if we are calculating over the rationals
if ( cf_glob_switches.isOn( SW_RATIONAL ) )
{
a = 1/CanonicalForm( copyObject() ); b = 0;
return int2imm( 1 );
}
long cInt = imm2int( c );
// trivial cases
if ( cInt == 1 || cInt == -1 )
{
a = 0; b = cInt;
return int2imm( 1 );
}
else if ( cInt == 0 )
{
a = 1; b = 0;
return copyObject();
}
// calculate q and r such that CO = q*cInt + r
InternalCF * q = 0, * r = 0;
divremcoeff( c, q, r, false );
// we do not repeat all the code to calculate the gcd of two
// immediates. Note that r is an immediate since c != 0, so
// we do not have to destroy it. q is destroyed by the
// CanonicalForm destructor, hence we do not need to worry
// about it, either.
CanonicalForm aPrime, bPrime;
CanonicalForm result = bextgcd( c, r, aPrime, bPrime );
a = bPrime;
b = aPrime - CanonicalForm( q ) * bPrime;
return result.getval();
}
long InternalInteger::intval() const
{
return mpz_get_si( thempi );
}
int InternalInteger::intmod( int p ) const
{
return (int)mpz_fdiv_ui( thempi, (unsigned long)p );
}
/** int InternalInteger::sign () const
* @sa CanonicalForm::sign()
**/
int
InternalInteger::sign () const
{
return mpz_sgn( thempi );
}
/** InternalCF * InternalInteger::sqrt ()
* @sa CanonicalForm::sqrt()
**/
InternalCF *
InternalInteger::sqrt ()
{
ASSERT( mpz_cmp_si( thempi, 0 ) >= 0, "sqrt() argument < 0" );
mpz_t result;
mpz_init( result );
mpz_sqrt( result, thempi );
if ( mpz_is_imm( result ) )
{
InternalCF * res = int2imm( mpz_get_si( result ) );
mpz_clear( result );
return res;
}
else
return new InternalInteger( result );
}
/** int InternalInteger::ilog2 ()
* @sa CanonicalForm::ilog2()
**/
int
InternalInteger::ilog2 ()
{
ASSERT( mpz_cmp_si( thempi, 0 ) > 0, "log() argument <= 0" );
return mpz_sizeinbase( thempi, 2 ) - 1;
}
bextgcd
CanonicalForm bextgcd(const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &a, CanonicalForm &b)
CanonicalForm bextgcd ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & a,...
Definition canonicalform.cc:1722
canonicalform.h
Header for factory's main class CanonicalForm.
p
int p
Definition cfModGcd.cc:4086
b
CanonicalForm b
Definition cfModGcd.cc:4111
ASSERT
#define ASSERT(expression, message)
Definition cf_assert.h:99
SW_RATIONAL
static const int SW_RATIONAL
set to 1 for computations over Q
Definition cf_defs.h:31
IntegerDomain
#define IntegerDomain
Definition cf_defs.h:21
cf_gmp.h
cf_glob_switches
INST_VAR CFSwitches cf_glob_switches
Definition cf_switches.cc:54
CanonicalForm
factory's main class
Definition canonicalform.h:86
InternalCF
virtual class for internal CanonicalForm's
Definition int_cf.h:47
InternalCF::copyObject
InternalCF * copyObject()
Definition int_cf.h:62
InternalCF::InternalCF
InternalCF()
Definition int_cf.h:55
InternalCF::isZero
virtual bool isZero() const
Definition int_cf.cc:24
InternalCF::getRefCount
int getRefCount()
Definition int_cf.h:51
InternalCF::levelcoeff
virtual int levelcoeff() const
Definition int_cf.h:68
InternalCF::decRefCount
int decRefCount()
Definition int_cf.h:53
InternalCF::isOne
virtual bool isOne() const
bool InternalCF::isOne, isZero () const
Definition int_cf.cc:18
InternalInteger
factory's class for integers
Definition int_int.h:56
InternalInteger::deepCopyObject
InternalCF * deepCopyObject() const
Definition int_int.cc:18
InternalInteger::sqrt
InternalCF * sqrt()
InternalCF * InternalInteger::sqrt ().
Definition int_int.cc:529
InternalInteger::thempi
mpz_t thempi
Definition int_int.h:58
InternalInteger::InternalInteger_bin
static const omBin InternalInteger_bin
Definition int_int.h:69
InternalInteger::divremcoeff
void divremcoeff(InternalCF *, InternalCF *&, InternalCF *&, bool)
Definition int_intdiv.cc:308
InternalInteger::InternalInteger
InternalInteger()
Definition int_int.h:85
InternalInteger::intval
long intval() const
Definition int_int.cc:506
InternalInteger::mulsame
InternalCF * mulsame(InternalCF *)
Definition int_int.cc:147
InternalInteger::ilog2
int ilog2()
int InternalInteger::ilog2 ()
Definition int_int.cc:549
InternalInteger::bgcdcoeff
InternalCF * bgcdcoeff(const InternalCF *const)
Definition int_int.cc:377
InternalInteger::genOne
InternalCF * genOne()
Definition int_int.cc:54
InternalInteger::genZero
InternalCF * genZero()
Definition int_int.cc:46
InternalInteger::sign
int sign() const
int InternalInteger::sign () const
Definition int_int.cc:520
InternalInteger::addcoeff
InternalCF * addcoeff(InternalCF *)
Definition int_int.cc:205
InternalInteger::subcoeff
InternalCF * subcoeff(InternalCF *, bool)
Definition int_int.cc:244
InternalInteger::bgcdsame
InternalCF * bgcdsame(const InternalCF *const) const
Definition int_int.cc:348
InternalInteger::bextgcdsame
InternalCF * bextgcdsame(InternalCF *, CanonicalForm &, CanonicalForm &)
Definition int_int.cc:409
InternalInteger::is_imm
bool is_imm() const
Definition int_int.cc:41
InternalInteger::subsame
InternalCF * subsame(InternalCF *)
Definition int_int.cc:116
InternalInteger::bextgcdcoeff
InternalCF * bextgcdcoeff(InternalCF *, CanonicalForm &, CanonicalForm &)
Definition int_int.cc:464
InternalInteger::mulcoeff
InternalCF * mulcoeff(InternalCF *)
Definition int_int.cc:299
InternalInteger::neg
InternalCF * neg()
InternalCF * InternalInteger::neg ().
Definition int_int.cc:66
InternalInteger::print
void print(OSTREAM &, char *)
Definition int_int.cc:26
InternalInteger::comparesame
int comparesame(InternalCF *)
Definition int_int.cc:188
InternalInteger::comparecoeff
int comparecoeff(InternalCF *)
Definition int_int.cc:198
InternalInteger::MPI
static mpz_ptr MPI(const InternalCF *const c)
uiNormalizeMPI()' is the same as normalizeMPI()' except that aMpi' is expected to be non-begative.
Definition int_int.h:252
InternalInteger::addsame
InternalCF * addsame(InternalCF *)
Definition int_int.cc:85
InternalInteger::intmod
int intmod(int p) const
Definition int_int.cc:511
result
return result
Definition facAbsBiFact.cc:76
res
CanonicalForm res
Definition facAbsFact.cc:60
gmpext.h
utility functions for gmp
mpz_is_imm
bool mpz_is_imm(const mpz_t mpi)
Definition gmpext.h:19
imm.h
operations on immediates, that is elements of F_p, GF, Z, Q that fit into intrinsic int,...
imm2int
static long imm2int(const InternalCF *const imm)
Definition imm.h:70
INTMARK
const long INTMARK
Definition imm.h:37
int2imm
static InternalCF * int2imm(long i)
Definition imm.h:75
int_int.h
Factory's internal integers.
OSTREAM
#define OSTREAM
Definition int_int.h:17
int_rat.h
Factory's internal rationals.
omGetSpecBin
#define omGetSpecBin(size)
Definition omBin.h:11
omBin
omBin_t * omBin
Definition omStructs.h:12