source: git/Singular/number2.cc @ 206e202

fieker-DuValspielwiese
Last change on this file since 206e202 was a4b31c, checked in by Hans Schoenemann <hannes@…>, 7 years ago
use include ".." for singular related .h, p4
  • Property mode set to 100644
File size: 13.0 KB
Line 
1#include "kernel/mod2.h" // general settings/macros
2#include "reporter/reporter.h"  // for Print, WerrorS
3#include "coeffs/numbers.h" // nRegister, coeffs.h
4#include "coeffs/rmodulon.h" // ZnmInfo
5#include "coeffs/bigintmat.h" // bigintmat
6#include "coeffs/longrat.h" // BIGINTs: nlGMP
7#include "polys/ext_fields/algext.h" // AlgExtInfo
8#include "misc/prime.h" // IsPrime
9#include "Singular/blackbox.h" // blackbox type
10#include "Singular/ipshell.h" // IsPrime
11#include "Singular/ipconv.h" // iiConvert etc.
12
13#include "Singular/ipid.h" // for SModulFunctions, leftv
14
15#include "Singular/number2.h"
16
17char *crString(coeffs c)
18{
19  if (c==NULL)
20  {
21    return omStrDup("oo");
22  }
23  return omStrDup(nCoeffName(c));
24}
25void crPrint(coeffs c)
26{
27  char *s=crString(c);
28  PrintS(s);
29  omFree(s);
30}
31
32// -----------------------------------------------------------
33// interpreter stuff for cring/coeffs
34// -----------------------------------------------------------
35BOOLEAN jjCRING_Zp(leftv res, leftv a, leftv b)
36{
37  coeffs c1=(coeffs)a->Data();
38  int    i2=(int)(long)b->Data();
39  if (c1->type==n_Z)
40  {
41    if (i2==IsPrime(i2))
42    {
43      res->data=(void *)nInitChar(n_Zp,(void*)(long)i2);
44    }
45    else
46    {
47      ZnmInfo info;
48      mpz_t modBase;
49      mpz_init_set_ui(modBase,i2);
50      info.base= modBase;
51      info.exp= 1;
52      if (mpz_popcount((mpz_ptr)modBase)==1) // is a power of 2
53      {
54        // is exponent <=2^(8*sizeof(unsigned long))
55        if (i2<(8*sizeof(unsigned long)))
56        {
57          mpz_clear(modBase);
58          res->data=(void *) nInitChar(n_Z2m,(void*)(long)i2);
59          return FALSE;
60        }
61        else
62        {
63          mpz_set_ui(modBase,2);
64          info.exp=i2;
65          res->data=(void *) nInitChar(n_Znm,&info);
66          mpz_clear(modBase);
67          return FALSE;
68        }
69      }
70      res->data=(void *)nInitChar(n_Zn,&info);
71      mpz_clear(modBase);
72    }
73    return FALSE;
74  }
75  return TRUE;
76}
77BOOLEAN jjCRING_Zm(leftv res, leftv a, leftv b)
78{
79  coeffs c1=(coeffs)a->Data();
80  number i2=(number)b->Data();
81  if (c1->type==n_Z)
82  {
83    ZnmInfo info;
84    mpz_t modBase;
85    mpz_init(modBase);
86    nlGMP(i2,modBase,coeffs_BIGINT); // FIXME? TODO? // extern void   nlGMP(number &i, mpz_t n, const coeffs r); // to be replaced with n_MPZ(modBase,i2,coeffs_BIGINT); // ?
87    info.base= (mpz_ptr)modBase;
88    info.exp= 1;
89    if (mpz_popcount(modBase)==1) // is a power of 2
90    {
91      // is exponent <=2^(8*sizeof(unsigned long))
92      mp_bitcnt_t l=mpz_scan1 (modBase,0);
93      if ((l>0) && (l<=8*sizeof(unsigned long)))
94      {
95        res->data=(void *) nInitChar(n_Z2m,(void*)(long)l);
96      }
97      else
98      {
99        mpz_set_ui(modBase,2);
100        info.exp= l;
101        res->data=(void *) nInitChar(n_Znm,&info);
102      }
103      mpz_clear(modBase);
104      return FALSE;
105    }
106    res->data=(void *)nInitChar(n_Zn,&info);
107    mpz_clear(modBase);
108    return FALSE;
109  }
110  return TRUE;
111}
112
113BOOLEAN jjEQUAL_CR(leftv res, leftv a, leftv b)
114{
115  coeffs a2=(coeffs)a->Data();
116  coeffs b2=(coeffs)b->Data();
117  res->data=(void*)(long)(a2==b2);
118  return FALSE;
119}
120
121BOOLEAN jjR2_CR(leftv res, leftv a)              // ring ->cring
122{
123  ring r=(ring)a->Data();
124  AlgExtInfo extParam;
125  extParam.r = r;
126  coeffs cf=nInitChar(n_transExt,&extParam);
127  res->data=(void*)cf;
128  return FALSE;
129}
130
131#ifdef SINGULAR_4_2
132// -----------------------------------------------------------
133// interpreter stuff for Number/number2
134// -----------------------------------------------------------
135BOOLEAN jjNUMBER2_POW(leftv res, leftv a, leftv b)
136{
137  number2 a2=(number2)a->Data();
138  if (a2->cf==NULL) return TRUE;
139  number2 r=(number2)omAlloc0(sizeof(*r));
140  r->cf=a2->cf;
141  n_Power(a2->n,(int)(long)b->Data(),&(r->n),r->cf);
142  return FALSE;
143}
144BOOLEAN jjNUMBER2_OP2(leftv res, leftv a, leftv b)
145{
146  int op=iiOp;
147  // binary operations for number2
148  number2 a2=NULL;
149  number aa=NULL;
150  number2 b2=NULL;
151  number bb=NULL;
152  leftv an = (leftv)omAlloc0Bin(sleftv_bin);
153  leftv bn = (leftv)omAlloc0Bin(sleftv_bin);
154  int ai,bi;
155  int at=a->Typ();
156  int bt=b->Typ();
157  if ((ai=iiTestConvert(at,CNUMBER_CMD,dConvertTypes))!=0)
158  {
159    if ((bi=iiTestConvert(bt,CNUMBER_CMD,dConvertTypes))!=0)
160    {
161      iiConvert(at,CNUMBER_CMD,ai,a,an);
162      iiConvert(bt,CNUMBER_CMD,bi,b,bn);
163      a2=(number2)an->Data();
164      b2=(number2)bn->Data();
165      if (((a2!=NULL) && (b2!=NULL) && (a2->cf!=b2->cf))
166      || (a2==NULL)
167      || (b2==NULL))
168      {
169        an->CleanUp();
170        bn->CleanUp();
171        omFreeBin((ADDRESS)an, sleftv_bin);
172        omFreeBin((ADDRESS)bn, sleftv_bin);
173        WerrorS("Number not compatible");
174        return TRUE;
175      }
176      aa=a2->n;
177      bb=b2->n;
178      number2 r=(number2)omAlloc0(sizeof(*r));
179      r->cf=a2->cf;
180      if (r->cf==NULL) op=0; // force error
181      switch(op)
182      {
183        case '+': r->n=n_Add(aa,bb,r->cf);break;
184        case '-': r->n=n_Sub(aa,bb,r->cf);break;
185        case '*': r->n=n_Mult(aa,bb,r->cf);break;
186        case '/': r->n=n_Div(aa,bb,r->cf);break;
187        case '%': r->n=n_IntMod(aa,bb,r->cf);break;
188        default: Werror("unknown binary operation %s(%d)",Tok2Cmdname(op),op);
189             omFree(r);
190             an->CleanUp();
191             bn->CleanUp();
192             omFreeBin((ADDRESS)an, sleftv_bin);
193             omFreeBin((ADDRESS)bn, sleftv_bin);
194             return TRUE;
195      }
196      res->data=(void*)r;
197      r->cf->ref++;
198      return FALSE;
199    }
200    else
201    {
202      an->CleanUp();
203      omFreeBin((ADDRESS)an, sleftv_bin);
204      Werror("cannot convert second operand (%s) to Number",b->Name());
205      return TRUE;
206    }
207  }
208  else
209  {
210    Werror("cannot convert first operand (%s) to Number",a->Name());
211    return TRUE;
212  }
213}
214BOOLEAN jjNUMBER2_OP1(leftv res, leftv a)
215{
216  int op=iiOp;
217  // unary operations for number2
218  number2 a2=(number2)a->Data();
219  number2 r=(number2)omAlloc(sizeof(*r));
220  r->cf=a2->cf;
221  if (a2->cf==NULL) op=0; // force error
222  switch(op)
223  {
224    case '-': r->n=n_Copy(a2->n,a2->cf);r->n=n_InpNeg(r->n,a2->cf);break;
225    default: Werror("unknown unary operation %s(%d)",Tok2Cmdname(op),op);
226             omFree(r);
227             return TRUE;
228  }
229  res->data=(void*)r;
230  r->cf->ref++;
231  return FALSE;
232}
233
234BOOLEAN jjPOLY2_POW(leftv res, leftv a, leftv b)
235{
236  poly2 a2=(poly2)a->Data();
237  if (a2->cf==NULL) return TRUE;
238  poly2 r=(poly2)omAlloc0(sizeof(*r));
239  r->cf=a2->cf;
240  r->n=p_Power(p_Copy(a2->n,r->cf),(int)(long)b->Data(),r->cf);
241  return FALSE;
242}
243BOOLEAN jjPOLY2_OP2(leftv res, leftv a, leftv b)
244{
245  int op=iiOp;
246  // binary operations for poly2
247  poly2 a2=NULL;
248  poly aa=NULL;
249  poly2 b2=NULL;
250  poly bb=NULL;
251  leftv an = (leftv)omAlloc0Bin(sleftv_bin);
252  leftv bn = (leftv)omAlloc0Bin(sleftv_bin);
253  int ai,bi;
254  int at=a->Typ();
255  int bt=b->Typ();
256  if ((ai=iiTestConvert(at,CPOLY_CMD,dConvertTypes))!=0)
257  {
258    if ((bi=iiTestConvert(bt,CPOLY_CMD,dConvertTypes))!=0)
259    {
260      iiConvert(at,CPOLY_CMD,ai,a,an);
261      iiConvert(bt,CPOLY_CMD,bi,b,bn);
262      a2=(poly2)an->Data();
263      b2=(poly2)bn->Data();
264      if (((a2!=NULL) && (b2!=NULL) && (a2->cf!=b2->cf))
265      || (a2==NULL)
266      || (b2==NULL))
267      {
268        an->CleanUp();
269        bn->CleanUp();
270        omFreeBin((ADDRESS)an, sleftv_bin);
271        omFreeBin((ADDRESS)bn, sleftv_bin);
272        WerrorS("Poly not compatible");
273        return TRUE;
274      }
275      aa=a2->n;
276      bb=b2->n;
277      poly2 r=(poly2)omAlloc0(sizeof(*r));
278      r->cf=a2->cf;
279      if (r->cf==NULL) op=0; // force error
280      switch(op)
281      {
282        case '+': r->n=p_Add_q(p_Copy(aa,r->cf),p_Copy(bb,r->cf),r->cf);break;
283        case '-': r->n=p_Sub(p_Copy(aa,r->cf),p_Copy(bb,r->cf),r->cf);break;
284        case '*': r->n=pp_Mult_qq(aa,bb,r->cf);break;
285        //case '/': r->n=n_Div(aa,bb,r->cf);break;
286        //case '%': r->n=n_IntMod(aa,bb,r->cf);break;
287        default: Werror("unknown binary operation %s(%d)",Tok2Cmdname(op),op);
288             omFree(r);
289             an->CleanUp();
290             bn->CleanUp();
291             omFreeBin((ADDRESS)an, sleftv_bin);
292             omFreeBin((ADDRESS)bn, sleftv_bin);
293             return TRUE;
294      }
295      res->data=(void*)r;
296      r->cf->ref++;
297      return FALSE;
298    }
299    else
300    {
301      an->CleanUp();
302      omFreeBin((ADDRESS)an, sleftv_bin);
303      Werror("cannot convert second operand (%s) to Poly",b->Name());
304      return TRUE;
305    }
306  }
307  else
308  {
309    Werror("cannot convert first operand (%s) to Poly",a->Name());
310    return TRUE;
311  }
312}
313BOOLEAN jjPOLY2_OP1(leftv res, leftv a)
314{
315  int op=iiOp;
316  // unary operations for poly2
317  poly2 a2=(poly2)a->Data();
318  poly2 r=(poly2)omAlloc(sizeof(*r));
319  r->cf=a2->cf;
320  if (a2->cf==NULL) op=0; // force error
321  switch(op)
322  {
323    case '-': r->n=p_Copy(a2->n,a2->cf);r->n=p_Neg(r->n,a2->cf);break;
324    default: Werror("unknown unary operation %s(%d)",Tok2Cmdname(op),op);
325             omFree(r);
326             return TRUE;
327  }
328  res->data=(void*)r;
329  r->cf->ref++;
330  return FALSE;
331}
332
333BOOLEAN jjNUMBER2CR(leftv res, leftv a, leftv b)
334{
335  number2 r=(number2)omAlloc(sizeof(*r));
336  r->cf=(coeffs)b->CopyD();
337  BOOLEAN bo=FALSE;
338  switch(a->Typ())
339  {
340    case INT_CMD:
341      r->n=n_Init((long)a->Data(),r->cf); break;
342    case BIGINT_CMD:
343    {
344      nMapFunc nMap=n_SetMap(coeffs_BIGINT,r->cf);
345      r->n=nMap((number)a->Data(),coeffs_BIGINT,r->cf); break;
346    }
347    case NUMBER_CMD:
348    {
349      nMapFunc nMap=n_SetMap(currRing->cf,r->cf);
350      if (nMap!=NULL)
351        r->n=nMap((number)a->Data(),currRing->cf,r->cf);
352      else
353        bo=TRUE;
354      break;
355    }
356    case CNUMBER_CMD:
357    {
358      number2 a2=(number2)a->Data();
359      if (a2->cf==NULL) bo=TRUE;
360      else
361      {
362        nMapFunc nMap=n_SetMap(a2->cf,r->cf);
363        if (nMap!=NULL)
364          r->n=nMap(a2->n,a2->cf,r->cf);
365        else
366          bo=TRUE;
367      }
368      break;
369    }
370    default: bo=TRUE; break;
371  }
372  if (bo)
373  {
374    Werror("no conversion to Number from %s",Tok2Cmdname(a->Typ()));
375    omFreeSize(r,sizeof(*r));
376  }
377  else
378    res->data=(void*)r;
379  return bo;
380}
381
382BOOLEAN jjN2_CR(leftv res, leftv a)              // number2 ->cring
383{
384  number2 n=(number2)a->Data();
385  n->cf->ref++;
386  res->data=(void*)n->cf;
387  return FALSE;
388}
389
390BOOLEAN jjP2_R(leftv res, leftv a)              // poly2 ->ring
391{
392  poly2 n=(poly2)a->Data();
393  n->cf->ref++;
394  res->data=(void*)n->cf;
395  return FALSE;
396}
397
398BOOLEAN jjCM_CR(leftv res, leftv a)              // cmatrix ->cring
399{
400  bigintmat *b=(bigintmat*)a->Data();
401  coeffs cf=b->basecoeffs();
402  if (cf!=NULL)
403  {
404    cf->ref++;
405  }
406  res->data=(void*)cf;
407  return FALSE;
408}
409
410BOOLEAN jjCMATRIX_3(leftv res, leftv r, leftv c,leftv cf)
411{
412  bigintmat *b=new bigintmat((int)(long)r->Data(),
413                             (int)(long)c->Data(),
414                             (coeffs)cf->Data());
415  res->data=(char*)b;
416  return FALSE;
417}
418
419BOOLEAN jjN2_N(leftv res, leftv a)              // number2 ->number
420{
421  number2 n2=(number2)a->Data();
422  BOOLEAN bo=TRUE;
423  if (currRing!=NULL)
424  {
425    nMapFunc nMap=n_SetMap(n2->cf,currRing->cf);
426    if (nMap!=NULL)
427    {
428      res->data=(void*)nMap(n2->n,n2->cf,currRing->cf);
429      bo=FALSE;
430    }
431  }
432  return bo;
433}
434
435// -----------------------------------------------------------
436// operations with Number/number2
437// -----------------------------------------------------------
438number2 n2Copy(const number2 d)
439{
440  number2 r=NULL;
441  if ((d!=NULL)&&(d->cf!=NULL))
442  {
443    r=(number2)omAlloc(sizeof(*r));
444    d->cf->ref++;
445    r->cf=d->cf;
446    if (d->cf!=NULL)
447      r->n=n_Copy(d->n,d->cf);
448    else
449      r->n=NULL;
450  }
451  return r;
452}
453void n2Delete(number2 &d)
454{
455  if (d!=NULL)
456  {
457    if (d->cf!=NULL)
458    {
459      n_Delete(&d->n,d->cf);
460      nKillChar(d->cf);
461    }
462    omFreeSize(d,sizeof(*d));
463    d=NULL;
464  }
465}
466char *n2String(number2 d, BOOLEAN typed)
467{
468  StringSetS("");
469  if ((d!=NULL) && (d->cf!=NULL))
470  {
471    if (typed) StringAppendS("Number(");
472    n_Write(d->n,d->cf);
473    if (typed) StringAppendS(")");
474  }
475  else StringAppendS("oo");
476  return StringEndS();
477}
478
479void n2Print(number2 d)
480{
481  char *s=n2String(d,FALSE);
482  PrintS(s);
483  omFree(s);
484}
485
486// -----------------------------------------------------------
487// operations with Poly/poly2
488// -----------------------------------------------------------
489
490poly2 p2Copy(const poly2 d)
491{
492  poly2 r=NULL;
493  if ((d!=NULL)&&(d->cf!=NULL))
494  {
495    r=(poly2)omAlloc(sizeof(*r));
496    d->cf->ref++;
497    r->cf=d->cf;
498    if (d->cf!=NULL)
499      r->n=p_Copy(d->n,d->cf);
500    else
501      r->n=NULL;
502  }
503  return r;
504}
505void p2Delete(poly2 &d)
506{
507  if (d!=NULL)
508  {
509    if (d->cf!=NULL)
510    {
511      p_Delete(&d->n,d->cf);
512      rKill(d->cf);
513    }
514    omFreeSize(d,sizeof(*d));
515    d=NULL;
516  }
517}
518char *p2String(poly2 d, BOOLEAN typed)
519{
520  StringSetS("");
521  if ((d!=NULL) && (d->cf!=NULL))
522  {
523    if (typed) StringAppendS("Poly(");
524    p_Write0(d->n,d->cf);
525    if (typed) StringAppendS(")");
526  }
527  else StringAppendS("oo");
528  return StringEndS();
529}
530
531void p2Print(poly2 d)
532{
533  char *s=p2String(d,FALSE);
534  PrintS(s);
535  omFree(s);
536}
537
538// ---------------------------------------------------------------------
539BOOLEAN jjBIM2_CR(leftv res, leftv a)              // bigintmat ->cring
540{
541  bigintmat *b=(bigintmat*)a->Data();
542  coeffs cf=b->basecoeffs();
543  if (cf==NULL) return TRUE;
544  cf->ref++;
545  res->data=(void*)cf;
546  return FALSE;
547}
548
549#endif
Note: See TracBrowser for help on using the repository browser.