source: git/libpolys/coeffs/rintegers.cc @ 0acf3e

spielwiese
Last change on this file since 0acf3e was 45cc512, checked in by Hans Schoenemann <hannes@…>, 10 years ago
chg: rCharstr is now a wrapper for r->cf->cfCoeffString fixes also: charstr for integer,2,3
  • Property mode set to 100644
File size: 9.3 KB
RevLine 
[255eaa]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: numbers modulo n
6*/
[16f511]7#ifdef HAVE_CONFIG_H
[ba5e9e]8#include "libpolysconfig.h"
[16f511]9#endif /* HAVE_CONFIG_H */
[18cb65]10#include <misc/auxiliary.h>
[f1c465f]11
12#ifdef HAVE_RINGS
[255eaa]13
14#include <string.h>
[18cb65]15#include <misc/mylimits.h>
[2d805a]16#include <coeffs/coeffs.h>
[18cb65]17#include <reporter/reporter.h>
18#include <omalloc/omalloc.h>
[2d805a]19#include <coeffs/numbers.h>
20#include <coeffs/longrat.h>
21#include <coeffs/mpr_complex.h>
22#include <coeffs/rintegers.h>
[e3b233]23#include "si_gmp.h"
[255eaa]24
[73a9ffb]25/// Our Type!
26static const n_coeffType ID = n_Z;
[255eaa]27
[a604c3]28omBin gmp_nrz_bin = omGetSpecBin(sizeof(mpz_t));
[1e579c6]29
[255eaa]30/*
31 * Multiply two numbers
32 */
[9bb5457]33number nrzMult (number a, number b, const coeffs)
[255eaa]34{
[1d03c4e]35  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]36  mpz_init(erg);
[1e579c6]37  mpz_mul(erg, (int_number) a, (int_number) b);
[255eaa]38  return (number) erg;
39}
40
41/*
42 * Give the smallest non unit k, such that a * x = k = b * y has a solution
43 */
[9bb5457]44number nrzLcm (number a,number b,const coeffs)
[255eaa]45{
[1d03c4e]46  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]47  mpz_init(erg);
[1e579c6]48  mpz_lcm(erg, (int_number) a, (int_number) b);
49  return (number) erg;
[255eaa]50}
51
52/*
53 * Give the largest non unit k, such that a = x * k, b = y * k has
54 * a solution.
55 */
[9bb5457]56number nrzGcd (number a,number b,const coeffs)
[255eaa]57{
[1d03c4e]58  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[1e579c6]59  mpz_init(erg);
60  mpz_gcd(erg, (int_number) a, (int_number) b);
61  return (number) erg;
62}
63
64/*
65 * Give the largest non unit k, such that a = x * k, b = y * k has
66 * a solution and r, s, s.t. k = s*a + t*b
67 */
[9bb5457]68number  nrzExtGcd (number a, number b, number *s, number *t, const coeffs)
[1e579c6]69{
[1d03c4e]70  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
71  int_number bs = (int_number) omAllocBin(gmp_nrz_bin);
72  int_number bt = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]73  mpz_init(erg);
[1e579c6]74  mpz_init(bs);
75  mpz_init(bt);
76  mpz_gcdext(erg, bs, bt, (int_number) a, (int_number) b);
77  *s = (number) bs;
78  *t = (number) bt;
79  return (number) erg;
[255eaa]80}
81
[9bb5457]82void nrzPower (number a, int i, number * result, const coeffs)
[255eaa]83{
[1d03c4e]84  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]85  mpz_init(erg);
[1e579c6]86  mpz_pow_ui(erg, (int_number) a, i);
87  *result = (number) erg;
[255eaa]88}
89
90/*
91 * create a number from int
92 */
[2f3764]93number nrzInit (long i, const coeffs)
[255eaa]94{
[1d03c4e]95  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]96  mpz_init_set_si(erg, i);
97  return (number) erg;
98}
99
[9bb5457]100void nrzDelete(number *a, const coeffs)
[1e579c6]101{
[befecbc]102  if (*a == NULL) return;
[1e579c6]103  mpz_clear((int_number) *a);
[bac8611]104  omFreeBin((ADDRESS) *a, gmp_nrz_bin);
[befecbc]105  *a = NULL;
[bac8611]106}
107
[9bb5457]108number nrzCopy(number a, const coeffs)
[bac8611]109{
[1d03c4e]110  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[bac8611]111  mpz_init_set(erg, (int_number) a);
112  return (number) erg;
113}
114
[c14846c]115#if 0
[9bb5457]116number nrzCopyMap(number a, const coeffs /*src*/, const coeffs dst)
[bac8611]117{
[85d8bee]118  return nrzCopy(a,dst);
[bac8611]119}
[c14846c]120#endif
[bac8611]121
[9bb5457]122int nrzSize(number a, const coeffs)
[bac8611]123{
124  if (a == NULL) return 0;
[a604c3]125  return sizeof(mpz_t);
[1e579c6]126}
127
[255eaa]128/*
[9600b0]129 * convert a number to int
[255eaa]130 */
[9bb5457]131int nrzInt(number &n, const coeffs)
[255eaa]132{
[25d15e]133  return (int) mpz_get_si( (int_number)n);
[255eaa]134}
135
[9bb5457]136number nrzAdd (number a, number b, const coeffs)
[255eaa]137{
[1d03c4e]138  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]139  mpz_init(erg);
[1e579c6]140  mpz_add(erg, (int_number) a, (int_number) b);
[255eaa]141  return (number) erg;
142}
143
[9bb5457]144number nrzSub (number a, number b, const coeffs)
[255eaa]145{
[1d03c4e]146  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]147  mpz_init(erg);
[1e579c6]148  mpz_sub(erg, (int_number) a, (int_number) b);
149  return (number) erg;
150}
151
[9bb5457]152number  nrzGetUnit (number, const coeffs r)
[1e579c6]153{
[85d8bee]154  return nrzInit(1, r);
[255eaa]155}
156
[9bb5457]157BOOLEAN nrzIsUnit (number a, const coeffs)
[1e579c6]158{
159  return 0 == mpz_cmpabs_ui((int_number) a, 1);
160}
161
[9bb5457]162BOOLEAN nrzIsZero (number  a, const coeffs)
[255eaa]163{
[1e579c6]164  return 0 == mpz_cmpabs_ui((int_number) a, 0);
[255eaa]165}
166
[9bb5457]167BOOLEAN nrzIsOne (number a, const coeffs)
[255eaa]168{
[a0d9be]169  return (a!=NULL) && (0 == mpz_cmp_si((int_number) a, 1));
[b18621]170}
171
[9bb5457]172BOOLEAN nrzIsMOne (number a, const coeffs)
[b18621]173{
[a0d9be]174  return (a!=NULL) && (0 == mpz_cmp_si((int_number) a, -1));
[255eaa]175}
176
[9bb5457]177BOOLEAN nrzEqual (number a,number b, const coeffs)
[255eaa]178{
[1e579c6]179  return 0 == mpz_cmp((int_number) a, (int_number) b);
[255eaa]180}
181
[9bb5457]182BOOLEAN nrzGreater (number a,number b, const coeffs)
[255eaa]183{
[1e579c6]184  return 0 < mpz_cmp((int_number) a, (int_number) b);
[255eaa]185}
186
[9bb5457]187BOOLEAN nrzGreaterZero (number k, const coeffs)
[b18621]188{
[675ce47]189  return 0 < mpz_cmp_si((int_number) k, 0);
[b18621]190}
191
[bec902b]192int nrzDivComp(number a, number b, const coeffs r)
[255eaa]193{
[bec902b]194  if (nrzDivBy(a, b, r))
[91d286]195  {
[bec902b]196    if (nrzDivBy(b, a, r)) return 2;
[91d286]197    return -1;
[04f365]198  }
[bec902b]199  if (nrzDivBy(b, a, r)) return 1;
[91d286]200  return 0;
[255eaa]201}
202
[9bb5457]203BOOLEAN nrzDivBy (number a,number b, const coeffs)
[255eaa]204{
[8e56ad]205  return mpz_divisible_p((int_number) a, (int_number) b) != 0;
[255eaa]206}
207
[bec902b]208number nrzDiv (number a,number b, const coeffs R)
[255eaa]209{
[1d03c4e]210  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[1e579c6]211  mpz_init(erg);
[1d03c4e]212  int_number r = (int_number) omAllocBin(gmp_nrz_bin);
213  mpz_init(r);
[1e579c6]214  mpz_tdiv_qr(erg, r, (int_number) a, (int_number) b);
[bec902b]215  if (!nrzIsZero((number) r, R))
[1e579c6]216  {
[bca575c]217    WerrorS("Division by non divisible element.");
218    WerrorS("Result is without remainder.");
[1e579c6]219  }
220  mpz_clear(r);
[bac8611]221  omFreeBin(r, gmp_nrz_bin);
[1e579c6]222  return (number) erg;
[255eaa]223}
224
[9bb5457]225number nrzIntDiv (number a,number b, const coeffs)
[255eaa]226{
[1d03c4e]227  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[1e579c6]228  mpz_init(erg);
229  mpz_tdiv_q(erg, (int_number) a, (int_number) b);
230  return (number) erg;
[255eaa]231}
232
[9bb5457]233number nrzIntMod (number a,number b, const coeffs)
[3231f3]234{
235  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
236  mpz_init(erg);
237  int_number r = (int_number) omAllocBin(gmp_nrz_bin);
238  mpz_init(r);
239  mpz_tdiv_qr(erg, r, (int_number) a, (int_number) b);
240  mpz_clear(erg);
241  return (number) r;
242}
243
[4d1ae5]244number  nrzInvers (number c, const coeffs r)
[255eaa]245{
[bec902b]246  if (!nrzIsUnit((number) c, r))
[1e579c6]247  {
[bca575c]248    WerrorS("Non invertible element.");
[1e579c6]249    return (number)0; //TODO
250  }
[4d1ae5]251  return nrzCopy(c,r);
[255eaa]252}
253
[9bb5457]254number nrzNeg (number c, const coeffs)
[255eaa]255{
[1d03c4e]256// nNeg inplace !!!
[a539ad]257  mpz_mul_si((int_number) c, (int_number) c, -1);
258  return c;
[255eaa]259}
260
[9bb5457]261number nrzMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
[d9301a]262{
[1d03c4e]263  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[d9301a]264  mpz_init_set_ui(erg, (NATNUMBER) from);
265  return (number) erg;
266}
267
[9bb5457]268number nrzMapZp(number from, const coeffs /*src*/, const coeffs /*dst*/)
[894f5b1]269{
[1d03c4e]270  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[894f5b1]271  mpz_init_set_si(erg, (long) from);
272  return (number) erg;
273}
274
[9bb5457]275number nrzMapQ(number from, const coeffs src, const coeffs /*dst*/)
[894f5b1]276{
[1d03c4e]277  int_number erg = (int_number) omAllocBin(gmp_nrz_bin);
[894f5b1]278  mpz_init(erg);
[4d1ae5]279  nlGMP(from, (number) erg, src);
[894f5b1]280  return (number) erg;
281}
282
[2e4ec14]283nMapFunc nrzSetMap(const coeffs src, const coeffs /*dst*/)
[255eaa]284{
[d9301a]285  /* dst = currRing */
[1cce47]286  if (nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_ModN(src) || nCoeff_is_Ring_PtoM(src))
[d9301a]287  {
[c14846c]288    return ndCopyMap; //nrzCopyMap;
[d9301a]289  }
[1cce47]290  if (nCoeff_is_Ring_2toM(src))
[d9301a]291  {
292    return nrzMapMachineInt;
293  }
[1cce47]294  if (nCoeff_is_Zp(src))
[894f5b1]295  {
296    return nrzMapZp;
297  }
[1cce47]298  if (nCoeff_is_Q(src))
[894f5b1]299  {
300    return nrzMapQ;
301  }
[d9301a]302  return NULL;      // default
[255eaa]303}
304
305
306/*
307 * set the exponent (allocate and init tables) (TODO)
308 */
309
[9bb5457]310void nrzSetExp(int, coeffs)
[255eaa]311{
312}
313
[9bb5457]314void nrzInitExp(int, coeffs)
[255eaa]315{
316}
317
318#ifdef LDEBUG
[9bb5457]319BOOLEAN nrzDBTest (number, const char *, const int, const coeffs)
[ec997eb]320{
321  return TRUE;//TODO
322}
[255eaa]323#endif
324
[9bb5457]325void nrzWrite (number &a, const coeffs)
[255eaa]326{
[1e579c6]327  char *s,*z;
328  if (a==NULL)
329  {
330    StringAppendS("o");
331  }
332  else
333  {
[c81a40]334    int l=mpz_sizeinbase((int_number) a, 10) + 2;
[1e579c6]335    s=(char*)omAlloc(l);
336    z=mpz_get_str(s,10,(int_number) a);
337    StringAppendS(z);
338    omFreeSize((ADDRESS)s,l);
339  }
[255eaa]340}
341
[1e579c6]342/*2
343* extracts a long integer from s, returns the rest    (COPY FROM longrat0.cc)
344*/
[a604c3]345static const char * nlEatLongC(char *s, mpz_ptr i)
[255eaa]346{
[3ad53dd]347  const char * start=s;
348
[0959dc]349  if (*s<'0' || *s>'9')
350  {
351    mpz_set_si(i,1);
352    return s;
353  }
[1e579c6]354  while (*s >= '0' && *s <= '9') s++;
355  if (*s=='\0')
[255eaa]356  {
[1e579c6]357    mpz_set_str(i,start,10);
358  }
359  else
360  {
361    char c=*s;
362    *s='\0';
363    mpz_set_str(i,start,10);
364    *s=c;
[255eaa]365  }
366  return s;
367}
368
[9bb5457]369const char * nrzRead (const char *s, number *a, const coeffs)
[255eaa]370{
[1d03c4e]371  int_number z = (int_number) omAllocBin(gmp_nrz_bin);
[255eaa]372  {
[1e579c6]373    mpz_init(z);
[3ad53dd]374    s = nlEatLongC((char *) s, z);
[255eaa]375  }
[1e579c6]376  *a = (number) z;
[255eaa]377  return s;
378}
[ec997eb]379
[03f7b5]380void    nrzCoeffWrite  (const coeffs, BOOLEAN /*details*/)
[7a8011]381{
[5a0b78]382  PrintS("//   coeff. ring is : Integers\n");
[7a8011]383}
384
[45cc512]385static char* nrzCoeffString(const coeffs r)
386{
387  return omStrDup("integer");
388}
[7a8011]389
[9bb5457]390BOOLEAN nrzInitChar(coeffs r,  void *)
[ec997eb]391{
[73a9ffb]392  assume( getCoeffType(r) == ID );
[613794]393  r->nCoeffIsEqual = ndCoeffIsEqual;
[45cc512]394  r->cfCoeffString = nrzCoeffString;
[613794]395  r->cfKillChar = ndKillChar;
[ec997eb]396  r->cfMult  = nrzMult;
397  r->cfSub   = nrzSub;
398  r->cfAdd   = nrzAdd;
399  r->cfDiv   = nrzDiv;
400  r->cfIntDiv= nrzDiv;
401  r->cfIntMod= nrzIntMod;
402  r->cfExactDiv= nrzDiv;
403  r->cfInit = nrzInit;
404  r->cfSize  = nrzSize;
405  r->cfInt  = nrzInt;
[7a8011]406  //#ifdef HAVE_RINGS
407  r->cfDivComp = nrzDivComp; // only for ring stuff
408  r->cfIsUnit = nrzIsUnit; // only for ring stuff
409  r->cfGetUnit = nrzGetUnit; // only for ring stuff
410  r->cfExtGcd = nrzExtGcd; // only for ring stuff
411  r->cfDivBy = nrzDivBy; // only for ring stuff
[8c6bd4d]412  r->cfInit_bigint = nrzMapQ;
[7a8011]413  //#endif
[ec997eb]414  r->cfNeg   = nrzNeg;
415  r->cfInvers= nrzInvers;
416  r->cfCopy  = nrzCopy;
[ce1f78]417  r->cfWriteLong = nrzWrite;
[ec997eb]418  r->cfRead = nrzRead;
419  r->cfGreater = nrzGreater;
420  r->cfEqual = nrzEqual;
421  r->cfIsZero = nrzIsZero;
422  r->cfIsOne = nrzIsOne;
423  r->cfIsMOne = nrzIsMOne;
424  r->cfGreaterZero = nrzGreaterZero;
425  r->cfPower = nrzPower;
426  r->cfGcd  = nrzGcd;
[b39b313]427  r->cfLcm  = nrzLcm;
[ec997eb]428  r->cfDelete= nrzDelete;
429  r->cfSetMap = nrzSetMap;
[7a8011]430  r->cfCoeffWrite = nrzCoeffWrite;
[ec997eb]431  // debug stuff
432
433#ifdef LDEBUG
434  r->cfDBTest=nrzDBTest;
435#endif
[9bb5457]436
[9306a01]437  r->nNULL = 0;
[73a9ffb]438  r->ch = 0;
[9306a01]439  r->has_simple_Alloc=FALSE;
[9bb5457]440  r->has_simple_Inverse=FALSE;
[5d594a9]441  return FALSE;
[ec997eb]442}
443
[1e579c6]444#endif
Note: See TracBrowser for help on using the repository browser.