source: git/libpolys/coeffs/gnumpc.cc @ 2a4a23

fieker-DuValspielwiese
Last change on this file since 2a4a23 was f5f5c9, checked in by Hans Schoenemann <hannes@…>, 7 years ago
fix: include path for julia
  • Property mode set to 100644
File size: 14.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: computations with GMP complex floating-point numbers
6*
7* ngc == number gnu complex
8*/
9#include "misc/auxiliary.h"
10#include "omalloc/omalloc.h"
11
12#include "misc/mylimits.h"
13#include "reporter/reporter.h"
14
15#include "coeffs/coeffs.h"
16#include "coeffs/numbers.h"
17
18#include "coeffs/mpr_complex.h"
19
20#include "coeffs/gnumpc.h"
21#include "coeffs/longrat.h"
22#include "coeffs/gnumpfl.h"
23#include "coeffs/modulop.h"
24#include "coeffs/shortfl.h"
25
26#ifdef LDEBUG
27BOOLEAN  ngcDBTest(number a, const char *f, const int l, const coeffs r);
28#endif
29
30
31#ifdef LDEBUG
32// not yet implemented
33BOOLEAN ngcDBTest(number, const char *, const int, const coeffs r)
34{
35  assume( getCoeffType(r) == n_long_C );
36
37  return TRUE;
38}
39#endif
40
41static number ngcParameter(int i, const coeffs r)
42{
43  assume( getCoeffType(r) == n_long_C );
44  assume(i==1);
45
46  if( i == 1 )
47    return (number)(new gmp_complex( 0L, 1L ));
48
49  return NULL; // new gmp_complex( )  // 0?
50}
51
52/*2
53* n := i
54*/
55static number ngcInit (long i, const coeffs r)
56{
57  assume( getCoeffType(r) == n_long_C );
58
59  gmp_complex* n= new gmp_complex( (long)i, 0L );
60
61  return (number)n;
62}
63
64/*2
65* convert number to int
66*/
67static long ngcInt(number &i, const coeffs r)
68{
69  assume( getCoeffType(r) == n_long_C );
70
71  return ((gmp_complex*)i)->real();
72}
73
74static BOOLEAN ngcIsZero (number a, const coeffs r)
75{
76  assume( getCoeffType(r) == n_long_C );
77
78  return ( ((gmp_complex*)a)->real().isZero() && ((gmp_complex*)a)->imag().isZero());
79}
80
81static int ngcSize(number n, const coeffs R)
82{
83  int r = (int)((gmp_complex*)n)->real();
84  if (r < 0) r = -r;
85  int i = (int)((gmp_complex*)n)->imag();
86  if (i < 0) i = -i;
87  int oneNorm = r + i;
88  /* basically return the 1-norm of n;
89     only if this happens to be zero although n != 0,
90     return 1;
91     (this code ensures that zero has the size zero) */
92  if ((oneNorm == 0.0) & (ngcIsZero(n,R) == FALSE)) oneNorm = 1;
93  return oneNorm;
94}
95
96/*2
97* delete a
98*/
99static void ngcDelete (number * a, const coeffs r)
100{
101  assume( getCoeffType(r) == n_long_C );
102
103  if ( *a != NULL )
104  {
105    delete *(gmp_complex**)a;
106    *a=NULL;
107  }
108}
109
110/*2
111 * copy a to b
112*/
113static number ngcCopy(number a, const coeffs r)
114{
115  assume( getCoeffType(r) == n_long_C );
116
117  gmp_complex* b= new gmp_complex( *(gmp_complex*)a );
118  return (number)b;
119}
120
121
122/*2
123* za:= - za
124*/
125static number ngcNeg (number a, const coeffs R)
126{
127  assume( getCoeffType(R) == n_long_C );
128
129  gmp_complex* r=(gmp_complex*)a;
130  (*r).neg();
131  return (number)a;
132}
133
134/*
135* 1/a
136*/
137static number ngcInvers(number a, const coeffs R)
138{
139  assume( getCoeffType(R) == n_long_C );
140
141  gmp_complex* r = NULL;
142  if (((gmp_complex*)a)->isZero())
143  {
144    WerrorS(nDivBy0);
145  }
146  else
147  {
148    r = new gmp_complex( (gmp_complex)1 / (*(gmp_complex*)a) );
149  }
150  return (number)r;
151}
152
153/*2
154* u:= a + b
155*/
156static number ngcAdd (number a, number b, const coeffs R)
157{
158  assume( getCoeffType(R) == n_long_C );
159
160  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) + (*(gmp_complex*)b) );
161  return (number)r;
162}
163
164/*2
165* u:= a - b
166*/
167static number ngcSub (number a, number b, const coeffs R)
168{
169  assume( getCoeffType(R) == n_long_C );
170
171  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) - (*(gmp_complex*)b) );
172  return (number)r;
173}
174
175/*2
176* u := a * b
177*/
178static number ngcMult (number a, number b, const coeffs R)
179{
180  assume( getCoeffType(R) == n_long_C );
181
182  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) * (*(gmp_complex*)b) );
183  return (number)r;
184}
185
186/*2
187* u := a / b
188*/
189static number ngcDiv (number a, number b, const coeffs r)
190{
191  assume( getCoeffType(r) == n_long_C );
192
193  if (((gmp_complex*)b)->isZero())
194  {
195    // a/0 = error
196    WerrorS(nDivBy0);
197    return NULL;
198  }
199  gmp_complex* res = new gmp_complex( (*(gmp_complex*)a) / (*(gmp_complex*)b) );
200  return (number)res;
201}
202
203/*2
204* u:= x ^ exp
205*/
206static void ngcPower ( number x, int exp, number * u, const coeffs r)
207{
208  assume( getCoeffType(r) == n_long_C );
209
210  if ( exp == 0 )
211  {
212    gmp_complex* n = new gmp_complex(1);
213    *u=(number)n;
214    return;
215  }
216  else if ( exp == 1 )
217  {
218    n_New(u, r);
219    gmp_complex* n = new gmp_complex();
220    *n= *(gmp_complex*)x;
221    *u=(number)n;
222    return;
223  }
224  else if (exp == 2)
225  {
226    n_New(u, r);
227    gmp_complex* n = new gmp_complex();
228    *n= *(gmp_complex*)x;
229    *u=(number)n;
230    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
231    return;
232  }
233  if ( (exp & 1) == 1 )
234  {
235    ngcPower(x,exp-1,u, r);
236    gmp_complex *n = new gmp_complex();
237    *n=*(gmp_complex*)x;
238    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
239    delete n;
240  }
241  else
242  {
243    number w;
244    n_New(&w, r);
245    ngcPower(x,exp/2,&w, r);
246    ngcPower(w,2,u, r);
247    n_Delete(&w, r);
248  }
249}
250
251static number ngcRePart(number a, const coeffs r)
252{
253  assume( getCoeffType(r) == n_long_C );
254
255  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->real());
256  return (number)n;
257}
258
259static number ngcImPart(number a, const coeffs r)
260{
261  assume( getCoeffType(r) == n_long_C );
262
263  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->imag());
264  return (number)n;
265}
266
267/*2
268* za >= 0 ?
269*/
270static BOOLEAN ngcGreaterZero (number a, const coeffs r)
271{
272  assume( getCoeffType(r) == n_long_C );
273
274  if ( ! ((gmp_complex*)a)->imag().isZero() )
275    return ( abs( *(gmp_complex*)a).sign() >= 0 );
276  else
277    return ( ((gmp_complex*)a)->real().sign() >= 0 );
278}
279
280/*2
281* a > b ?
282*/
283static BOOLEAN ngcGreater (number a, number b, const coeffs r)
284{
285  assume( getCoeffType(r) == n_long_C );
286
287  gmp_complex *aa=(gmp_complex*)a;
288  gmp_complex *bb=(gmp_complex*)b;
289  return (*aa) > (*bb);
290}
291
292/*2
293* a = b ?
294*/
295static BOOLEAN ngcEqual (number a, number b, const coeffs r)
296{
297  assume( getCoeffType(r) == n_long_C );
298
299  gmp_complex *aa=(gmp_complex*)a;
300  gmp_complex *bb=(gmp_complex*)b;
301  return (*aa) == (*bb);
302}
303
304/*2
305* a == 1 ?
306*/
307static BOOLEAN ngcIsOne (number a, const coeffs r)
308{
309  assume( getCoeffType(r) == n_long_C );
310
311  return (((gmp_complex*)a)->real().isOne() && ((gmp_complex*)a)->imag().isZero());
312  //return (((gmp_complex*)a)->real().isOne());
313}
314
315/*2
316* a == -1 ?
317*/
318static BOOLEAN ngcIsMOne (number a, const coeffs r)
319{
320  assume( getCoeffType(r) == n_long_C );
321
322  return (((gmp_complex*)a)->real().isMOne() && ((gmp_complex*)a)->imag().isZero());
323  //return (((gmp_complex*)a)->real().isMOne());
324}
325
326/*2
327* extracts the number a from s, returns the rest
328*/
329static const char * ngcRead (const char * s, number * a, const coeffs r)
330{
331  assume( getCoeffType(r) == n_long_C );
332  const char * const complex_parameter = n_ParameterNames(r)[0];
333  assume( complex_parameter != NULL );
334  const int N = strlen(complex_parameter);
335
336  if ((*s >= '0') && (*s <= '9'))
337  {
338    gmp_float *re=NULL;
339    s=ngfRead(s,(number *)&re, r); // FIXME? TODO? // extern const char *   ngfRead (const char *s, number *a, const coeffs r);
340    gmp_complex *aa=new gmp_complex(*re);
341    *a=(number)aa;
342    delete re;
343  }
344  else if (strncmp(s, complex_parameter, N)==0)
345  {
346    s += N;
347    gmp_complex *aa=new gmp_complex(0L,1L);
348    *a=(number)aa;
349  }
350  else
351  {
352    *a=(number) new gmp_complex(1L);
353  }
354  return s;
355}
356
357
358
359/*2
360* write a floating point number
361*/
362static void ngcWrite (number a, const coeffs r)
363{
364  assume( getCoeffType(r) == n_long_C );
365
366  if (a==NULL)
367    StringAppendS("0");
368  else
369  {
370    char *out;
371    out= complexToStr(*(gmp_complex*)a, r->float_len, r);
372    StringAppendS(out);
373    //    omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
374    omFree( (void *)out );
375  }
376}
377
378static BOOLEAN ngcCoeffIsEqual (const coeffs r, n_coeffType n, void * parameter)
379{
380  if (n==n_long_C)
381  {
382    LongComplexInfo* p = (LongComplexInfo *)(parameter);
383
384    if ((p==NULL)
385      && (SHORT_REAL_LENGTH==r->float_len)
386      && (SHORT_REAL_LENGTH==r->float_len2)
387      && (strcmp("i",n_ParameterNames(r)[0]) == 0)
388      )
389        return TRUE;
390    if ((p!=NULL) &&
391        (p->float_len == r->float_len) &&
392        (p->float_len2 == r->float_len2)
393       )
394      if (strcmp(p->par_name, n_ParameterNames(r)[0]) == 0)
395        return (TRUE);
396  }
397  return (FALSE);
398}
399
400static void ngcKillChar(coeffs r)
401{
402  char** p = (char**)n_ParameterNames(r);
403
404  const int P = n_NumberOfParameters(r);
405
406  for( int i = 1; i <= P; i++ )
407    if (p[i-1] != NULL)
408      omFree( (ADDRESS)p[i-1] );
409
410  omFreeSize((ADDRESS)p, P * sizeof(char*));
411}
412
413static char* ngcCoeffString(const coeffs r)
414{
415  const char *p=n_ParameterNames(r)[0];
416  char *s=(char*)omAlloc(31+strlen(p));
417  sprintf(s,"complex,%d,%d,%s",r->float_len,r->float_len2,p);
418  return s;
419}
420
421static char* ngcCoeffName(const coeffs r)
422{
423  static char ngcCoeffName_buf[40];
424  const char *p=n_ParameterNames(r)[0];
425  if (ngcCoeffName_buf!=NULL) omFree(ngcCoeffName_buf);
426  sprintf(ngcCoeffName_buf,"complex,%d,%d,%s",r->float_len,r->float_len2,p);
427  return ngcCoeffName_buf;
428}
429
430static void ngcCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
431{
432  Print("real[%s](complex:%d digits, additional %d digits)/(%s^2+1)",n_ParameterNames(r)[0],
433        r->float_len, r->float_len2, n_ParameterNames(r)[0]);  /* long C */
434}
435
436static number ngcMapQ(number from, const coeffs aRing, const coeffs r)
437{
438  assume( getCoeffType(r) == n_long_C );
439  assume( aRing->rep == n_rep_gap_rat);
440
441  if ( from != NULL )
442  {
443    gmp_complex *res=new gmp_complex(numberFieldToFloat(from,QTOF));
444    return (number)res;
445  }
446  else
447    return NULL;
448}
449
450static number ngcMapZ(number from, const coeffs aRing, const coeffs r)
451{
452  assume( getCoeffType(r) == n_long_C );
453  assume( aRing->rep == n_rep_gap_gmp);
454
455  if ( from != NULL )
456  {
457    if (SR_HDL(from) & SR_INT)
458    {
459      gmp_float f_i= gmp_float(SR_TO_INT(from));
460      gmp_complex *res=new gmp_complex(f_i);
461      return (number)res;
462    }
463    gmp_float f_i=(mpz_ptr)from;
464    gmp_complex *res=new gmp_complex(f_i);
465    return (number)res;
466  }
467  else
468    return NULL;
469}
470
471static number ngcMapLongR(number from, const coeffs aRing, const coeffs r)
472{
473  assume( getCoeffType(r) == n_long_C );
474  assume( getCoeffType(aRing) == n_long_R );
475
476  if ( from != NULL )
477  {
478    gmp_complex *res=new gmp_complex(*((gmp_float *)from));
479    return (number)res;
480  }
481  else
482    return NULL;
483}
484
485static number ngcMapR(number from, const coeffs aRing, const coeffs r)
486{
487  assume( getCoeffType(r) == n_long_C );
488  assume( getCoeffType(aRing) == n_R );
489
490  if ( from != NULL )
491  {
492    gmp_complex *res=new gmp_complex((double)nrFloat(from));
493    return (number)res;
494  }
495  else
496    return NULL;
497}
498
499static number ngcMapP(number from, const coeffs aRing, const coeffs r)
500{
501  assume( getCoeffType(r) == n_long_C );
502  assume( getCoeffType(aRing) ==  n_Zp );
503
504  if ( from != NULL )
505    return ngcInit(npInt(from, aRing), r); // FIXME? TODO? // extern int     npInt         (number &n, const coeffs r);
506  else
507    return NULL;
508}
509
510static number ngcCopyMap(number from, const coeffs aRing, const coeffs r)
511{
512  assume( getCoeffType(r) == n_long_C );
513  assume( getCoeffType(aRing) ==  n_long_C );
514
515  gmp_complex* b = NULL;
516
517  if ( from !=  NULL )
518  {
519    b = new gmp_complex( *(gmp_complex*)from );
520  }
521  return (number)b;
522}
523
524static nMapFunc ngcSetMap(const coeffs src, const coeffs dst)
525{
526  assume( getCoeffType(dst) == n_long_C );
527
528  if (src->rep==n_rep_gap_rat) /* Q, Z*/
529  {
530    return ngcMapQ;
531  }
532  if (src->rep==n_rep_gap_gmp) /* Z */
533  {
534    return ngcMapZ;
535  }
536  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
537  {
538    return ngcMapLongR;
539  }
540  if ((src->rep==n_rep_gmp_complex) && nCoeff_is_long_C(src))
541  {
542    return ngcCopyMap;
543  }
544  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
545  {
546    return ngcMapR;
547  }
548  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
549  {
550    return ngcMapP;
551  }
552  return NULL;
553}
554
555BOOLEAN ngcInitChar(coeffs n, void* parameter)
556{
557  assume( getCoeffType(n) == n_long_C );
558  n->is_field=TRUE;
559  n->is_domain=TRUE;
560  n->rep=n_rep_gmp_complex;
561
562  n->cfKillChar = ngcKillChar;
563  n->ch = 0;
564  n->cfCoeffString=ngcCoeffString;
565  n->cfCoeffName=ngcCoeffName;
566
567  n->cfDelete  = ngcDelete;
568  //n->cfNormalize=ndNormalize;
569  n->cfInit   = ngcInit;
570  n->cfInt    = ngcInt;
571  n->cfAdd     = ngcAdd;
572  n->cfSub     = ngcSub;
573  n->cfMult    = ngcMult;
574  n->cfDiv     = ngcDiv;
575  n->cfExactDiv= ngcDiv;
576  n->cfInpNeg     = ngcNeg;
577  n->cfInvers  = ngcInvers;
578  n->cfCopy   = ngcCopy;
579  n->cfGreater = ngcGreater;
580  n->cfEqual   = ngcEqual;
581  n->cfIsZero  = ngcIsZero;
582  n->cfIsOne   = ngcIsOne;
583  n->cfIsMOne  = ngcIsMOne;
584  n->cfGreaterZero = ngcGreaterZero;
585
586  n->cfWriteLong  = ngcWrite;
587  n->cfWriteShort = ngcWrite;
588
589  n->cfRead    = ngcRead;
590  n->cfPower   = ngcPower;
591  n->cfSetMap = ngcSetMap;
592  n->cfRePart  = ngcRePart;
593  n->cfImPart  = ngcImPart;
594  n->cfCoeffWrite = ngcCoeffWrite;
595    // cfSize  = ndSize;
596#ifdef LDEBUG
597  //n->cfDBTest  = ndDBTest; // not yet implemented: ngcDBTest
598#endif
599
600  n->nCoeffIsEqual = ngcCoeffIsEqual;
601
602  n->cfSetChar=ngcSetChar;
603
604/*
605  //r->cfInitChar=nlInitChar;
606  r->cfKillChar=NULL;
607
608  r->cfMult  = nlMult;
609  r->cfSub   = nlSub;
610  r->cfAdd   = nlAdd;
611  r->cfDiv   = nlDiv;
612  r->cfIntMod= nlIntMod;
613  r->cfExactDiv= nlExactDiv;
614  r->cfInit = nlInit;
615  r->cfSize  = nlSize;
616  r->cfInt  = nlInt;
617#ifdef HAVE_RINGS
618  r->cfDivComp = NULL; // only for ring stuff
619  r->cfIsUnit = NULL; // only for ring stuff
620  r->cfGetUnit = NULL; // only for ring stuff
621  r->cfExtGcd = NULL; // only for ring stuff
622#endif
623  r->cfInpNeg   = nlNeg;
624  r->cfInvers= nlInvers;
625  r->cfCopy  = nl_Copy;
626  r->cfRePart = nl_Copy;
627  r->cfImPart = ndReturn0;
628  r->cfWriteLong = nlWrite;
629  r->cfRead = nlRead;
630  r->cfNormalize=nlNormalize;
631  r->cfGreater = nlGreater;
632#ifdef HAVE_RINGS
633  r->cfDivBy = NULL; // only for ring stuff
634#endif
635  r->cfEqual = nlEqual;
636  r->cfIsZero = nlIsZero;
637  r->cfIsOne = nlIsOne;
638  r->cfIsMOne = nlIsMOne;
639  r->cfGreaterZero = nlGreaterZero;
640  r->cfPower = nlPower;
641  r->cfGetDenom = nlGetDenom;
642  r->cfGetNumerator = nlGetNumerator;
643  r->cfGcd  = nlGcd;
644  r->cfLcm  = nlLcm;
645  r->cfDelete= nlDelete;
646  r->cfSetMap = nlSetMap;
647  r->cfName = ndName;
648  r->cfInpMult=nlInpMult;
649  r->cfInit_bigint=nlCopyMap;
650#ifdef LDEBUG
651  // debug stuff
652  r->cfDBTest=nlDBTest;
653#endif
654
655  // the variables:
656  r->type = n_Q;
657  r->ch = 0;
658  r->has_simple_Alloc=FALSE;
659  r->has_simple_Inverse=FALSE;
660*/
661
662  n->iNumberOfParameters = 1;
663  n->cfParameter = ngcParameter;
664
665  char ** pParameterNames = (char **) omAlloc0(sizeof(char *));
666
667  if( parameter != NULL)
668  {
669    LongComplexInfo* p = (LongComplexInfo*)parameter;
670    pParameterNames[0] = omStrDup(p->par_name);
671    // fix wrong parameters:
672    if (p->float_len<SHORT_REAL_LENGTH) p->float_len=SHORT_REAL_LENGTH;
673    n->float_len = p->float_len;
674    n->float_len2 = p->float_len2;
675
676  } else // default values, just for testing!
677  {
678    pParameterNames[0] = omStrDup("i");
679    n->float_len = SHORT_REAL_LENGTH;
680    n->float_len2 = SHORT_REAL_LENGTH;
681  }
682
683  assume( pParameterNames != NULL );
684  assume( pParameterNames[0] != NULL );
685
686  n->pParameterNames = (const char**)pParameterNames;
687
688  // NOTE: n->complex_parameter was replaced by n_ParameterNames(n)[0]
689  // TODO: nfKillChar MUST destroy n->pParameterNames[0] (0-term. string) && n->pParameterNames (array of size 1)
690
691  return FALSE;
692}
693
694void ngcSetChar(const coeffs r)
695{
696  setGMPFloatDigits(r->float_len, r->float_len2);
697}
698
699
700
Note: See TracBrowser for help on using the repository browser.