Loading...
Searching...
No Matches
imm.h
Go to the documentation of this file.
/* emacs edit mode for this file is -*- C++ -*- */
/**
* @file imm.h
*
* operations on immediates, that is elements of F_p, GF, Z, Q
* that fit into intrinsic int, long
**/
#ifndef INCL_IMM_H
#define INCL_IMM_H
#include <stdint.h>
// #include "config.h"
#ifndef NOSTREAMIO
#ifdef HAVE_IOSTREAM
#include <iostream>
#define OSTREAM std::ostream
#elif defined(HAVE_IOSTREAM_H)
#include <iostream.h>
#define OSTREAM ostream
#endif
#endif /* NOSTREAMIO */
#include "cf_assert.h"
#include "cf_defs.h"
#include "cf_globals.h"
#include "ffops.h"
#include "gfops.h"
#include "cf_factory.h"
#include "canonicalform.h"
#include "int_cf.h"
const long INTMARK = 1;
const long FFMARK = 2;
const long GFMARK = 3;
/* define type of your compilers 64 bit integer type */
#ifndef FACTORY_INT64
#if SIZEOF_LONG == 8
#define FACTORY_INT64 long int
#else
#define FACTORY_INT64 long long int
#endif
#endif
#if SIZEOF_LONG == 4
const long MINIMMEDIATE = -268435454; // -2^28+2
const long MAXIMMEDIATE = 268435454; // 2^28-2
#else
const long MINIMMEDIATE = -(1L<<60)+2L; // -2^60+2
const long MAXIMMEDIATE = (1L<<60)-2L; // 2^60-2
#endif
#if defined(WINNT) && ! defined(__GNUC__)
const FACTORY_INT64 MINIMMEDIATELL = -268435454i64;
const FACTORY_INT64 MAXIMMEDIATELL = 268435454i64;
#else
const FACTORY_INT64 MINIMMEDIATELL = -268435454LL;
const FACTORY_INT64 MAXIMMEDIATELL = 268435454LL;
#endif
//{{{ conversion functions
//#ifdef HAS_ARITHMETIC_SHIFT
#if 1
static inline long imm2int ( const InternalCF * const imm )
{
return ((intptr_t)imm) >> 2;
}
static inline InternalCF * int2imm ( long i )
{
return (InternalCF*)((i << 2) | INTMARK );
}
#else
static inline long imm2int ( const InternalCF * const imm )
{
// this could be better done by masking the sign bit
if ( ((long)(intptr_t)imm)) < 0 )
return -((-(long)(intptr_t)imm) >> 2);
else
return (long)(intptr_t)imm >> 2;
}
static inline InternalCF * int2imm ( long i )
{
if ( i < 0 )
return (InternalCF*)(-(((-i) << 2) | INTMARK));
else
return (InternalCF*)((i << 2) | INTMARK );
}
#endif
inline InternalCF * int2imm_p ( long i )
{
return (InternalCF*)((i << 2) | FFMARK );
}
inline InternalCF * int2imm_gf ( long i )
{
return (InternalCF*)((i << 2) | GFMARK );
}
//}}}
// predicates
#if 0
inline int is_imm ( const InternalCF * const ptr )
{
// returns 0 if ptr is not immediate
return ( (intptr_t)ptr & 3 );
}
#endif
//{{{ inline int imm_isone, imm_isone_p, imm_isone_gf ( const InternalCF * const ptr )
// docu: see CanonicalForm::isOne()
inline int
imm_isone ( const InternalCF * const ptr )
{
return imm2int( ptr ) == 1;
}
inline int
imm_isone_p ( const InternalCF * const ptr )
{
return imm2int( ptr ) == 1;
}
inline int
imm_isone_gf ( const InternalCF * const ptr )
{
return gf_isone( imm2int( ptr ) );
}
//}}}
//{{{ inline int imm_iszero, imm_iszero_p, imm_iszero_gf ( const InternalCF * const ptr )
// docu: see CanonicalForm::isZero()
inline int
imm_iszero ( const InternalCF * const ptr )
{
return imm2int( ptr ) == 0;
}
inline int
imm_iszero_p ( const InternalCF * const ptr )
{
return imm2int( ptr ) == 0;
}
inline int
imm_iszero_gf ( const InternalCF * const ptr )
{
return gf_iszero( imm2int( ptr ) );
}
//}}}
//{{{ conversion functions
inline long imm_intval ( const InternalCF* const op )
{
if ( is_imm( op ) == FFMARK )
{
if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
return ff_symmetric( imm2int( op ) );
else
return imm2int( op );
}
else if ( is_imm( op ) == GFMARK )
{
ASSERT( gf_isff( imm2int( op ) ), "invalid conversion" );
if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
return ff_symmetric( gf_gf2ff( imm2int( op ) ) );
else
return gf_gf2ff( imm2int( op ) );
}
/*else*/
return imm2int( op );
}
//}}}
/**
*
* imm_sign() - return sign of immediate object.
*
* If CO is an immediate integer, the sign is defined as usual.
* If CO is an element of FF(p) and SW_SYMMETRIC_FF is on the
* sign of CO is the sign of the symmetric representation of CO.
* If CO is in GF(q) or in FF(p) and SW_SYMMETRIC_FF is off, the
* sign of CO is zero iff CO is zero, otherwise the sign is one.
*
* @sa CanonicalForm::sign(), gf_sign()
*
**/
inline int
imm_sign ( const InternalCF * const op )
{
if ( is_imm( op ) == FFMARK )
if ( imm2int( op ) == 0 )
return 0;
else if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
if ( ff_symmetric( imm2int( op ) ) > 0 )
return 1;
else
return -1;
else
return 1;
else if ( is_imm( op ) == GFMARK )
return gf_sign( imm2int( op ) );
else if ( imm2int( op ) == 0 )
return 0;
else if ( imm2int( op ) > 0 )
return 1;
else
return -1;
}
/**
*
* imm_cmp(), imm_cmp_p(), imm_cmp_gf() - compare immediate objects.
*
* For immediate integers, it is clear how this should be done.
* For objects from finite fields, it is not clear since they
* are not ordered fields. However, since we want to have a
* total well order on polynomials we have to define a total well
* order on all coefficients, too. We decided to use simply the
* order on the representation as `int's of such objects.
*
* @sa CanonicalForm::operator <(), CanonicalForm::operator ==()
*
**/
inline int
imm_cmp ( const InternalCF * const lhs, const InternalCF * const rhs )
{
if ( imm2int( lhs ) == imm2int( rhs ) )
return 0;
else if ( imm2int( lhs ) > imm2int( rhs ) )
return 1;
else
return -1;
}
inline int
imm_cmp_p ( const InternalCF * const lhs, const InternalCF * const rhs )
{
if ( imm2int( lhs ) == imm2int( rhs ) )
return 0;
else if ( imm2int( lhs ) > imm2int( rhs ) )
return 1;
else
return -1;
}
inline int
imm_cmp_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
{
if ( imm2int( lhs ) == imm2int( rhs ) )
return 0;
// check is done in this way because zero should be minimal
else if ( imm2int( lhs ) > imm2int( rhs ) )
return -1;
else
return 1;
}
//}}}
//{{{ arithmetic operators
inline InternalCF * imm_add ( const InternalCF * const lhs, const InternalCF * const rhs )
{
long result = imm2int( lhs ) + imm2int( rhs );
if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
return CFFactory::basic( result );
else
return int2imm( result );
}
inline InternalCF * imm_add_p ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_p( ff_add( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF * imm_add_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_gf( gf_add( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF * imm_sub ( const InternalCF * const lhs, const InternalCF * const rhs )
{
long result = imm2int( lhs ) - imm2int( rhs );
if ( ( result > MAXIMMEDIATE ) || ( result < MINIMMEDIATE ) )
return CFFactory::basic( result );
else
return int2imm( result );
}
inline InternalCF * imm_sub_p ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_p( ff_sub( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF * imm_sub_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_gf( gf_sub( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF *
imm_mul ( InternalCF * lhs, InternalCF * rhs )
{
long a = imm2int( lhs );
if (a == 0L)
return int2imm(0);
long b = imm2int( rhs );
int sa= 1;
unsigned FACTORY_INT64 aa, bb;
if (a < 0)
{
sa= -1;
aa= (unsigned FACTORY_INT64) (-a);
}
else
aa= (unsigned FACTORY_INT64) a;
if (b < 0)
{
sa= -sa;
bb= (unsigned FACTORY_INT64) (-b);
}
else
bb= (unsigned FACTORY_INT64) b;
unsigned FACTORY_INT64 result = aa*bb;
#if SIZEOF_LONG == 4
if (result>(unsigned FACTORY_INT64)MAXIMMEDIATE)
{
InternalCF * res = CFFactory::basic( IntegerDomain, a, true );
return res->mulcoeff( rhs );
}
#else
if ( ((result/aa!=bb) || (result>(unsigned FACTORY_INT64) MAXIMMEDIATE) ))
{
InternalCF * res = CFFactory::basic( IntegerDomain, a, true );
return res->mulcoeff( rhs );
}
#endif
else
return int2imm( sa*result );
}
inline InternalCF * imm_mul_p ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_p( ff_mul( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF * imm_mul_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_gf( gf_mul( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF * imm_div ( const InternalCF * const lhs, const InternalCF * const rhs )
{
long a = imm2int( lhs );
long b = imm2int( rhs );
if ( a > 0 )
return int2imm( a / b );
else if ( b > 0 )
return int2imm( -((b-a-1)/b) );
else
return int2imm( (-a-b-1)/(-b) );
}
inline InternalCF * imm_divrat ( const InternalCF * const lhs, const InternalCF * const rhs )
{
if ( cf_glob_switches.isOn( SW_RATIONAL ) )
return CFFactory::rational( imm2int( lhs ), imm2int( rhs ) );
else {
long a = imm2int( lhs );
long b = imm2int( rhs );
if ( a > 0 )
return int2imm( a / b );
else if ( b > 0 )
return int2imm( -((b-a-1)/b) );
else
return int2imm( (-a-b-1)/(-b) );
}
}
inline InternalCF * imm_div_p ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF * imm_div_gf ( const InternalCF * const lhs, const InternalCF * const rhs )
{
return int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
}
inline InternalCF * imm_mod ( const InternalCF * const lhs, const InternalCF * const rhs )
{
if ( cf_glob_switches.isOn( SW_RATIONAL ) )
return int2imm( 0 );
else {
long a = imm2int( lhs );
long b = imm2int( rhs );
if ( a > 0 )
if ( b > 0 )
return int2imm( a % b );
else
return int2imm( a % (-b) );
else
if ( b > 0 ) {
long r = (-a) % b;
return int2imm( (r==0) ? r : b-r );
}
else {
long r = (-a) % (-b);
return int2imm( (r==0) ? r : -b-r );
}
}
}
inline InternalCF * imm_mod_p ( const InternalCF * const, const InternalCF * const )
{
return int2imm_p( 0 );
}
inline InternalCF * imm_mod_gf ( const InternalCF * const, const InternalCF * const )
{
return int2imm_gf( gf_q );
}
inline void imm_divrem ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
{
if ( cf_glob_switches.isOn( SW_RATIONAL ) ) {
q = imm_divrat( lhs, rhs );
r = CFFactory::basic( 0L );
}
else {
q = imm_div( lhs, rhs );
r = imm_mod( lhs, rhs );
}
}
inline void imm_divrem_p ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
{
q = int2imm_p( ff_div( imm2int( lhs ), imm2int( rhs ) ) );
r = int2imm_p( 0 );
}
inline void imm_divrem_gf ( const InternalCF * const lhs, const InternalCF * const rhs, InternalCF * & q, InternalCF * & r )
{
q = int2imm_gf( gf_div( imm2int( lhs ), imm2int( rhs ) ) );
r = int2imm_gf( gf_q );
}
//{{{ inline InternalCF * imm_neg, imm_neg_p, imm_neg_gf ( const InternalCF * const op )
// docu: see CanonicalForm::operator -()
inline InternalCF *
imm_neg ( const InternalCF * const op )
{
return int2imm( -imm2int( op ) );
}
inline InternalCF *
imm_neg_p ( const InternalCF * const op )
{
return int2imm_p( ff_neg( imm2int( op ) ) );
}
inline InternalCF *
imm_neg_gf ( const InternalCF * const op )
{
return int2imm_gf( gf_neg( imm2int( op ) ) );
}
//}}}
//}}}
//{{{ input/output
#ifndef NOSTREAMIO
inline void imm_print ( OSTREAM & os, const InternalCF * const op, const char * const str )
{
if ( is_imm( op ) == FFMARK )
if ( cf_glob_switches.isOn( SW_SYMMETRIC_FF ) )
os << ff_symmetric( imm2int( op ) ) << str;
else
os << imm2int( op ) << str;
else if ( is_imm( op ) == GFMARK ) {
gf_print( os, imm2int( op ) );
os << str;
}
else
os << imm2int( op ) << str;
}
#endif /* NOSTREAMIO */
//}}}
#endif /* ! INCL_IMM_H */
canonicalform.h
Header for factory's main class CanonicalForm.
OSTREAM
#define OSTREAM
Definition canonicalform.h:16
is_imm
int is_imm(const InternalCF *const ptr)
Definition canonicalform.h:65
i
int i
Definition cfEzgcd.cc:132
b
CanonicalForm b
Definition cfModGcd.cc:4111
cf_assert.h
assertions for Factory
ASSERT
#define ASSERT(expression, message)
Definition cf_assert.h:99
cf_defs.h
factory switches.
SW_RATIONAL
static const int SW_RATIONAL
set to 1 for computations over Q
Definition cf_defs.h:31
SW_SYMMETRIC_FF
static const int SW_SYMMETRIC_FF
set to 1 for symmetric representation over F_q
Definition cf_defs.h:33
IntegerDomain
#define IntegerDomain
Definition cf_defs.h:21
cf_factory.h
Interface to generate InternalCF's over various domains from intrinsic types or mpz_t's.
cf_globals.h
cf_glob_switches
INST_VAR CFSwitches cf_glob_switches
Definition cf_switches.cc:54
CFFactory::basic
static InternalCF * basic(int value)
Definition cf_factory.cc:61
CFFactory::rational
static InternalCF * rational(long num, long den)
Definition cf_factory.cc:268
InternalCF
virtual class for internal CanonicalForm's
Definition int_cf.h:47
result
return result
Definition facAbsBiFact.cc:76
res
CanonicalForm res
Definition facAbsFact.cc:60
gf_gf2ff
long gf_gf2ff(long a)
Definition gfops.cc:209
gf_isff
bool gf_isff(long a)
Definition gfops.cc:253
ffops.h
operations in a finite prime field F_p.
FACTORY_INT64
#define FACTORY_INT64
Definition ffops.h:24
ff_symmetric
int ff_symmetric(const int a)
Definition ffops.h:67
ff_add
int ff_add(const int a, const int b)
Definition ffops.h:97
ff_div
int ff_div(const int a, const int b)
Definition ffops.h:163
ff_mul
int ff_mul(const int a, const int b)
Definition ffops.h:139
ff_neg
int ff_neg(const int a)
Definition ffops.h:126
ff_sub
int ff_sub(const int a, const int b)
Definition ffops.h:112
gf_q
VAR int gf_q
Definition gfops.cc:47
gfops.h
Operations in GF, where GF is a finite field of size less than 2^16 represented by a root of Conway p...
gf_sub
int gf_sub(int a, int b)
Definition gfops.h:158
gf_print
void gf_print(OSTREAM &os, int a)
Definition gfops.h:207
gf_neg
int gf_neg(int a)
Definition gfops.h:123
gf_isone
bool gf_isone(int a)
Definition gfops.h:53
gf_iszero
bool gf_iszero(int a)
Definition gfops.h:43
gf_mul
int gf_mul(int a, int b)
Definition gfops.h:163
gf_div
int gf_div(int a, int b)
Definition gfops.h:185
gf_sign
int gf_sign(int a)
Definition gfops.h:113
gf_add
int gf_add(int a, int b)
Definition gfops.h:133
imm_isone_p
int imm_isone_p(const InternalCF *const ptr)
Definition imm.h:130
imm2int
static long imm2int(const InternalCF *const imm)
Definition imm.h:70
MAXIMMEDIATE
const long MAXIMMEDIATE
Definition imm.h:55
imm_isone
int imm_isone(const InternalCF *const ptr)
Definition imm.h:124
MAXIMMEDIATELL
const FACTORY_INT64 MAXIMMEDIATELL
Definition imm.h:63
int2imm_p
InternalCF * int2imm_p(long i)
Definition imm.h:101
imm_sign
int imm_sign(const InternalCF *const op)
imm_sign() - return sign of immediate object.
Definition imm.h:200
imm_iszero
int imm_iszero(const InternalCF *const ptr)
Definition imm.h:145
imm_iszero_gf
int imm_iszero_gf(const InternalCF *const ptr)
Definition imm.h:157
imm_intval
long imm_intval(const InternalCF *const op)
Definition imm.h:164
MINIMMEDIATELL
const FACTORY_INT64 MINIMMEDIATELL
Definition imm.h:62
FFMARK
const long FFMARK
Definition imm.h:38
MINIMMEDIATE
const long MINIMMEDIATE
Definition imm.h:54
imm_iszero_p
int imm_iszero_p(const InternalCF *const ptr)
Definition imm.h:151
INTMARK
const long INTMARK
Definition imm.h:37
int2imm_gf
InternalCF * int2imm_gf(long i)
Definition imm.h:106
imm_isone_gf
int imm_isone_gf(const InternalCF *const ptr)
Definition imm.h:136
int2imm
static InternalCF * int2imm(long i)
Definition imm.h:75
GFMARK
const long GFMARK
Definition imm.h:39
int_cf.h
Factory's internal CanonicalForm's.
LibThread::str
char * str(leftv arg)
Definition shared.cc:699