72 ((((
unsigned long) a) * ((
unsigned long) b)) & ((
unsigned long)r->mod2mMask));
78 ((((
unsigned long) a) + ((
unsigned long) b)) & ((
unsigned long)r->mod2mMask));
83 return (number)((
unsigned long)a < (
unsigned long)b ?
84 r->mod2mMask - (
unsigned long)b + (
unsigned long)a + 1:
85 (
unsigned long)a - (
unsigned long)
b);
88 #define nr2mNegM(A,r) (number)((r->mod2mMask - (unsigned long)(A) + 1) & r->mod2mMask)
89 #define nr2mEqualM(A,B) ((A)==(B))
95 PrintS(
"// coeff. ring is : ");
96 Print(
"Z/2^%lu\n", r->modExponent);
103 int m=(int)(
long)(
p);
104 unsigned long mm=r->mod2mMask;
105 if (((mm+1)>>
m)==1L)
return TRUE;
113 sprintf(s,
"integer,2,%lu",r->modExponent);
120 long ch = r->cfInt(c, r);
122 mpz_init_set(a, r->modNumber);
123 mpz_init_set_ui(b, ch);
125 gcd = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
128 if(mpz_cmp_ui(gcd, 1) == 0)
130 WerrorS(
"constant in q-ideal is coprime to modulus in ground ring");
131 WerrorS(
"Unable to create qring!");
134 if(mpz_cmp_ui(gcd, 2) == 0)
141 info.
base = r->modBase;
144 mpz_init(baseTokNew);
145 mpz_set(baseTokNew, r->modBase);
146 while(mpz_cmp(gcd, baseTokNew) > 0)
149 mpz_mul(baseTokNew, baseTokNew, r->modBase);
152 mpz_clear(baseTokNew);
174 mpz_init_set_si (r->modBase, 2L);
176 mpz_init (r->modNumber);
177 mpz_pow_ui (r->modNumber, r->modBase, r->modExponent);
180 r->ch = (int)r->mod2mMask + 1;
217 r->has_simple_Alloc=
TRUE;
226 if (((
unsigned long)a == 0) || ((
unsigned long)b == 0))
237 unsigned long res = 0;
238 if ((
unsigned long)a == 0) a = (number) 1;
239 if ((
unsigned long)b == 0) b = (number) 1;
240 while ((
unsigned long)a % 2 == 0)
242 a = (number)((
unsigned long)a / 2);
243 if ((
unsigned long)b % 2 == 0) b = (number)((
unsigned long)b / 2);
246 while ((
unsigned long)b % 2 == 0)
248 b = (number)((
unsigned long)b / 2);
251 return (number)(1L <<
res);
260 unsigned long res = 0;
261 if ((
unsigned long)a == 0 && (
unsigned long)b == 0)
return (number)1;
262 while ((
unsigned long)a % 2 == 0 && (
unsigned long)b % 2 == 0)
264 a = (number)((
unsigned long)a / 2);
265 b = (number)((
unsigned long)b / 2);
274 return (number)((1L <<
res));
284 unsigned long res = 0;
285 if ((
unsigned long)a == 0 && (
unsigned long)b == 0)
return (number)1;
286 while ((
unsigned long)a % 2 == 0 && (
unsigned long)b % 2 == 0)
288 a = (number)((
unsigned long)a / 2);
289 b = (number)((
unsigned long)b / 2);
292 if ((
unsigned long)b % 2 == 0)
296 return (number)((1L <<
res));
302 return (number)((1L <<
res));
310 *(
unsigned long *)result = 1;
328 if (i == 0)
return (number)(
unsigned long)i;
331 unsigned long j = (
unsigned long)1;
332 if (ii < 0) { j = r->mod2mMask; ii = -ii; }
333 unsigned long k = (
unsigned long)ii;
334 k = k & r->mod2mMask;
336 return (number)
nr2mMult((number)j, (number)k, r);
345 unsigned long nn = (
unsigned long)(
unsigned long)n & r->mod2mMask;
346 unsigned long l = r->mod2mMask >> 1; l++;
347 if ((
unsigned long)nn >
l)
348 return (
long)((
unsigned long)nn - r->mod2mMask - 1);
350 return (
long)((
unsigned long)nn);
365 return ((
unsigned long)a % 2 == 1);
370 if (k ==
NULL)
return (number)1;
371 unsigned long erg = (
unsigned long)k;
372 while (erg % 2 == 0) erg = erg / 2;
378 return 0 == (
unsigned long)a;
383 return 1 == (
unsigned long)a;
388 return (r->mod2mMask == (
unsigned long)a);
408 unsigned long c = r->mod2mMask + 1;
410 return (c % (
unsigned long)b) == 0;
415 c = (
unsigned long)b;
418 if ((c % 2) != 0)
return FALSE;
434 unsigned long a = (
unsigned long)as;
435 unsigned long b = (
unsigned long)bs;
437 while (a % 2 == 0 && b % 2 == 0)
462 if ((
unsigned long)k == 0)
return FALSE;
463 if ((
unsigned long)k > ((r->mod2mMask >> 1) + 1))
return FALSE;
473 mpz_ptr u = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
474 mpz_init_set_ui(u, a);
475 mpz_ptr u0 = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
477 mpz_ptr u1 = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
478 mpz_init_set_ui(u1, 1);
479 mpz_ptr u2 = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
481 mpz_ptr
v = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
482 mpz_init_set_ui(v, r->mod2mMask);
484 mpz_ptr v0 = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
486 mpz_ptr v1 = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
488 mpz_ptr v2 = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
489 mpz_init_set_ui(v2, 1);
490 mpz_ptr q = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
492 mpz_ptr rr = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
495 while (mpz_cmp_ui(v, 0) != 0)
503 mpz_mul(u2, u2, q); mpz_sub(u2, u1, u2);
504 mpz_mul(v2, v2, q); mpz_sub(v2, v1, v2);
509 while (mpz_cmp_ui(u1, 0) < 0)
512 mpz_add_ui(u1, u1, r->mod2mMask);
513 mpz_add_ui(u1, u1, 1);
531 assume((
unsigned long)a % 2 != 0);
540 assume((
unsigned long)c % 2 != 0);
543 inv =
InvMod((
unsigned long)c,r);
549 if ((
unsigned long)a == 0)
return (number)0;
550 else if ((
unsigned long)b % 2 == 0)
552 if ((
unsigned long)b != 0)
554 while (((
unsigned long)b % 2 == 0) && ((
unsigned long)a % 2 == 0))
556 a = (number)((
unsigned long)a / 2);
557 b = (number)((
unsigned long)b / 2);
560 if ((
unsigned long)b % 2 == 0)
562 WerrorS(
"Division not possible, even by cancelling zero divisors.");
563 WerrorS(
"Result is integer division without remainder.");
564 return (number) ((
unsigned long) a / (
unsigned long)
b);
593 assume((
unsigned long) b != 0);
595 unsigned long b_div = (
unsigned long) b;
603 unsigned long rr = 0;
604 while ((g < r->mod2mMask ) && (b_div > 0) && (b_div % 2 == 0))
610 if (g != 1) rr = (
unsigned long)a % g;
616 if ((
unsigned long)a == 0)
618 if ((
unsigned long)b == 0)
620 if ((
unsigned long)b == 1)
622 unsigned long c = r->mod2mMask + 1;
624 return (number)(c / (
unsigned long)b);
628 mpz_ptr cc = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
629 mpz_init_set_ui(cc, r->mod2mMask); mpz_add_ui(cc, cc, 1);
630 mpz_div_ui(cc, cc, (
unsigned long)(
unsigned long)b);
631 unsigned long s = mpz_get_ui(cc);
633 return (number)(
unsigned long)s;
638 if ((
unsigned long)b == 0)
640 return (number)((
unsigned long) a / (
unsigned long)
b);
646 if ((
unsigned long)b == 0)
648 if ((
unsigned long)b == 1)
650 unsigned long c = r->mod2mMask + 1;
652 return (number)(c / (
unsigned long)b);
656 mpz_ptr cc = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
657 mpz_init_set_ui(cc, r->mod2mMask); mpz_add_ui(cc, cc, 1);
658 mpz_div_ui(cc, cc, (
unsigned long)(
unsigned long)b);
659 unsigned long s = mpz_get_ui(cc);
661 return (number)(
unsigned long)s;
667 if ((
unsigned long)c % 2 == 0)
669 WerrorS(
"division by zero divisor");
677 if ((
unsigned long)c == 0)
return c;
683 unsigned long i = ((
unsigned long)from) % dst->mod2mMask ;
689 unsigned long i = ((
unsigned long)from) % (dst->mod2mMask + 1);
695 unsigned long j = (
unsigned long)1;
696 long ii = (long)from;
697 if (ii < 0) { j = dst->mod2mMask; ii = -ii; }
698 unsigned long i = (
unsigned long)ii;
699 i = i & dst->mod2mMask;
701 return (number)
nr2mMult((number)i, (number)j, dst);
708 mpz_ptr
k = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
709 mpz_init_set_ui(k, dst->mod2mMask);
711 nlGMP(from, (number)erg, src);
712 mpz_and(erg, erg, k);
713 number
res = (number)mpz_get_ui(erg);
725 mpz_ptr
k = (mpz_ptr)
omAlloc(
sizeof(mpz_t));
726 mpz_init_set_ui(k, dst->mod2mMask);
728 mpz_and(erg, (mpz_ptr)from, k);
729 number
res = (number) mpz_get_ui(erg);
750 && (src->mod2mMask == dst->mod2mMask))
755 && (src->mod2mMask < dst->mod2mMask))
760 && (src->mod2mMask > dst->mod2mMask))
784 if (mpz_divisible_2exp_p(src->modNumber,dst->modExponent))
802 for (
int i = 1;
i <
m;
i++) r->mod2mMask = (r->mod2mMask << 1) + 1;
816 WarnS(
"nr2mInitExp unexpectedly called with m = 1 (we continue with Z/2^2");
823 if (((
unsigned long)a & r->mod2mMask) != (
unsigned long)a)
return FALSE;
837 if (((*s) >=
'0') && ((*s) <=
'9'))
844 if ((*i) >= (
MAX_INT_VAL / 10)) (*i) = (*i) & r->mod2mMask;
846 while (((*s) >=
'0') && ((*s) <=
'9'));
847 (*i) = (*i) & r->mod2mMask;
865 *a = (number)(
long)
z;
867 *a =
nr2mDiv((number)(
long)z,(number)(
long)n,r);
void nr2mInitExp(int c, const coeffs r)
number nr2mGcd(number a, number b, const coeffs r)
long nr2mInt(number &n, const coeffs r)
number nr2mCopy(number a, const coeffs r)
number nr2mLcm(number a, number b, const coeffs r)
static number nr2mMultM(number a, number b, const coeffs r)
const CanonicalForm int s
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_ModN(const coeffs r)
nMapFunc nr2mSetMap(const coeffs src, const coeffs dst)
number nr2mMapZ(number from, const coeffs src, const coeffs dst)
number nr2mInit(long i, const coeffs r)
number nr2mAdd(number a, number b, const coeffs r)
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
number nr2mSub(number a, number b, const coeffs r)
static number nr2mAnn(number b, const coeffs r)
number nr2mMult(number a, number b, const coeffs r)
const char * nr2mRead(const char *s, number *a, const coeffs r)
only used if HAVE_RINGS is defined: ?
number ndCopyMap(number a, const coeffs aRing, const coeffs r)
BOOLEAN nr2mGreaterZero(number k, const coeffs r)
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_Z(const coeffs r)
const CanonicalForm CFMap CFMap int &both_non_zero int n
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
(), see rinteger.h, new impl.
number nr2mGetUnit(number a, const coeffs r)
number nr2mMod(number a, number b, const coeffs r)
number nr2mMapZp(number from, const coeffs, const coeffs dst)
void WerrorS(const char *s)
BOOLEAN nr2mIsMOne(number a, const coeffs r)
BOOLEAN nr2mInitChar(coeffs r, void *p)
number nr2mDiv(number a, number b, const coeffs r)
void nlGMP(number &i, number n, const coeffs r)
BOOLEAN nr2mGreater(number a, number b, const coeffs r)
static const n_coeffType ID
Our Type!
static FORCE_INLINE BOOLEAN nCoeff_is_Q(const coeffs r)
number nr2mMapMachineInt(number from, const coeffs, const coeffs dst)
void nr2mWrite(number a, const coeffs r)
coeffs nr2mQuot1(number c, const coeffs r)
number nr2mInvers(number c, const coeffs r)
number nr2mNeg(number c, const coeffs r)
number nr2mIntDiv(number a, number b, const coeffs r)
Coefficient rings, fields and other domains suitable for Singular polynomials.
int nr2mDivComp(number a, number b, const coeffs r)
The main handler for Singular numbers which are suitable for Singular polynomials.
BOOLEAN nr2mDBTest(number a, const char *f, const int l, const coeffs r)
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
static char * nr2mCoeffString(const coeffs r)
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_PtoM(const coeffs r)
void PrintS(const char *s)
number nr2mMapProject(number from, const coeffs, const coeffs dst)
(mpz_ptr), see rmodulon,h
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
static const char * nr2mEati(const char *s, int *i, const coeffs r)
char * nr2mName(number n, const coeffs r)
void nr2mSetExp(int c, const coeffs r)
const Variable & v
< [in] a sqrfree bivariate poly
number nr2mInversM(number c, const coeffs r)
BOOLEAN nr2mDivBy(number a, number b, const coeffs r)
unsigned long InvMod(unsigned long a, const coeffs r)
BOOLEAN nr2mIsUnit(number a, const coeffs r)
BOOLEAN nr2mIsZero(number a, const coeffs r)
static number nr2mAddM(number a, number b, const coeffs r)
number nr2mExtGcd(number a, number b, number *s, number *t, const coeffs r)
number nr2mMapGMP(number from, const coeffs, const coeffs dst)
number nr2mMapQ(number from, const coeffs src, const coeffs dst)
static number nr2mSubM(number a, number b, const coeffs r)
void nr2mCoeffWrite(const coeffs r, BOOLEAN details)
void specialXGCD(unsigned long &s, unsigned long a, const coeffs r)
BOOLEAN nr2mEqual(number a, number b, const coeffs r)
BOOLEAN nr2mIsOne(number a, const coeffs r)
void nr2mPower(number a, int i, number *result, const coeffs r)
BOOLEAN nr2mCoeffIsEqual(const coeffs r, n_coeffType n, void *p)
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL