source: git/libpolys/coeffs/rintegers.cc @ 560a3d

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