source: git/libpolys/coeffs/gnumpc.cc @ 96ce32

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