source: git/kernel/GMPrat.cc @ fbc7cb

spielwiese
Last change on this file since fbc7cb was ba5e9e, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Changed configure-scripts to generate individual public config files for each package: resources, libpolys, singular (main) fix: sources should include correct corresponding config headers.
  • Property mode set to 100644
File size: 10.7 KB
Line 
1// ----------------------------------------------------------------------------
2//  GMPrat.cc
3//  begin of file
4//  originally written by Gerd Sussner, sussner@mi.uni-erlangen.de
5//  copied by Stephan Endrass, endrass@mathematik.uni-mainz.de
6//  23.7.99
7// ----------------------------------------------------------------------------
8
9#define  GMPRAT_CC
10
11#ifdef HAVE_CONFIG_H
12#include "singularconfig.h"
13#endif /* HAVE_CONFIG_H */
14#include <kernel/mod2.h>
15
16#ifdef HAVE_SPECTRUM
17
18#ifdef   GMPRAT_PRINT
19#include <iostream.h>
20#ifndef  GMPRAT_IOSTREAM
21#include <stdio.h>
22#endif
23#endif
24
25#include <stdlib.h>
26#include <math.h>
27#include <ctype.h>
28#include <string.h>
29
30#include <kernel/GMPrat.h>
31
32// ----------------------------------------------------------------------------
33//  Miscellaneous
34// ----------------------------------------------------------------------------
35
36Rational Rational::save;    // dummy variable
37
38// ----------------------------------------------------------------------------
39//  disconnect a rational from its reference
40// ----------------------------------------------------------------------------
41
42void    Rational::disconnect( )
43{
44    if( p->n>1)
45    {
46        p->n--;
47        p = new rep;
48    }
49    else
50    {
51        mpq_clear(p->rat);
52    }
53    mpq_init(p->rat);
54}
55
56// ----------------------------------------------------------------------------
57//  Constructors
58// ----------------------------------------------------------------------------
59
60Rational::Rational( )
61{
62    p = new rep;
63    mpq_init( p->rat );
64}
65
66Rational::Rational( int a )
67{
68    p = new rep;
69    mpq_init( p->rat );
70    mpq_set_si( p->rat,(long)a,1 );
71}
72
73Rational::Rational( const Rational& a )
74{
75    a.p->n++;
76    p=a.p;
77}
78
79// ----------------------------------------------------------------------------
80//  Constructors with two arguments: numerator and denominator
81// ----------------------------------------------------------------------------
82
83Rational::Rational(const Rational& a, const Rational& b)
84{
85    p=new rep;
86    mpq_init(p->rat);
87    mpq_div(p->rat, a.p->rat, b.p->rat);
88}
89
90Rational::Rational(int a, int b)
91{
92    if (b<0) a=-a;
93    p=new rep;
94    mpq_init(p->rat);
95    mpq_set_si(p->rat,(long) a,(unsigned long) abs(b));
96    mpq_canonicalize(p->rat);
97}
98
99// ----------------------------------------------------------------------------
100//  Destructor
101// ----------------------------------------------------------------------------
102
103Rational::~Rational()
104{
105  if (--(p->n)==0)
106  {
107    mpq_clear(p->rat);
108    delete p;
109  }
110}
111
112// ----------------------------------------------------------------------------
113//  Assignment operators
114// ----------------------------------------------------------------------------
115
116Rational& Rational::operator=(int a)
117{
118  disconnect();
119  mpq_set_si(p->rat,(long) a,1);
120  return *this;
121}
122
123Rational& Rational::operator=(const Rational& a)
124{
125  a.p->n++;
126  if (--(p->n)==0)
127  {
128    mpq_clear(p->rat);
129    delete p;
130  }
131  p=a.p;
132  return *this;
133}
134
135// ----------------------------------------------------------------------------
136//  Numerator and denominator
137// ----------------------------------------------------------------------------
138
139Rational Rational::get_num( )
140{
141    Rational erg;
142
143    mpq_set_num( erg.p->rat,mpq_numref( p->rat ) );
144
145    return  erg;
146}
147
148int Rational::get_num_si( )
149{
150    return  mpz_get_si( mpq_numref( p->rat ) );
151}
152
153Rational Rational::get_den( )
154{
155    Rational erg;
156
157    mpq_set_num( erg.p->rat,mpq_denref( p->rat ) );
158
159    return  erg;
160}
161
162int Rational::get_den_si( )
163{
164    return  mpz_get_si( mpq_denref( p->rat ) );
165}
166
167// ----------------------------------------------------------------------------
168//  Casting
169// ----------------------------------------------------------------------------
170
171Rational::operator int()
172{
173  mpz_t h;
174  long ret_val;
175
176  mpz_init(h);
177  mpz_tdiv_q(h,mpq_numref(p->rat),mpq_denref(p->rat));
178  ret_val=mpz_get_si(h);
179  mpz_clear(h);
180
181  return ret_val;
182}
183
184// ----------------------------------------------------------------------------
185//  Unary minus
186// ----------------------------------------------------------------------------
187
188Rational
189Rational::operator-()
190{
191  Rational erg;
192
193  mpq_neg(erg.p->rat,p->rat);
194  return erg;
195}
196
197Rational operator - ( const Rational &r )
198{
199  Rational erg;
200
201  mpq_neg(erg.p->rat,r.p->rat);
202  return erg;
203}
204
205// ----------------------------------------------------------------------------
206//  Inverse
207// ----------------------------------------------------------------------------
208
209Rational
210Rational::operator~()
211{
212  Rational erg;
213
214  mpq_inv(erg.p->rat,p->rat);
215  return erg;
216}
217
218// ----------------------------------------------------------------------------
219//  +=, -= ...
220// ----------------------------------------------------------------------------
221
222Rational&
223Rational::operator+=(const Rational &a)
224{
225  mpq_set(save.p->rat,p->rat);
226  disconnect();
227  mpq_add(p->rat,save.p->rat,a.p->rat);
228  return *this;
229}
230
231Rational&
232Rational::operator-=(const Rational &a)
233{
234  mpq_set(save.p->rat,p->rat);
235  disconnect();
236  mpq_sub(p->rat,save.p->rat,a.p->rat);
237  return *this;
238}
239
240Rational&
241Rational::operator*=(const Rational &a)
242{
243  mpq_set(save.p->rat,p->rat);
244  disconnect();
245  mpq_mul(p->rat,save.p->rat,a.p->rat);
246  return *this;
247}
248
249Rational&
250Rational::operator/=(const Rational &a)
251{
252  mpq_set(save.p->rat,p->rat);
253  disconnect();
254  mpq_div(p->rat,save.p->rat,a.p->rat);
255  return *this;
256}
257
258// ----------------------------------------------------------------------------
259//  Increment and decrement
260// ----------------------------------------------------------------------------
261
262Rational&
263Rational::operator++()
264{
265  mpq_set(save.p->rat,p->rat);
266  *this=1;
267  mpq_add(p->rat,p->rat,save.p->rat);
268  return *this;
269}
270
271Rational
272Rational::operator++(int)
273{
274  Rational erg(*this);
275
276  mpq_set(save.p->rat,p->rat);
277  *this=1;
278  mpq_add(p->rat,p->rat,save.p->rat);
279  return erg;
280}
281
282Rational&
283Rational::operator--()
284{
285  mpq_set(save.p->rat,p->rat);
286  *this=1;
287  mpq_sub(p->rat,save.p->rat,p->rat);
288  return *this;
289}
290
291Rational
292Rational::operator--(int)
293{
294  Rational erg(*this);
295
296  mpq_set(save.p->rat,p->rat);
297  *this=1;
298  mpq_sub(p->rat,save.p->rat,p->rat);
299  return erg;
300}
301
302// ----------------------------------------------------------------------------
303//  Relational operators
304// ----------------------------------------------------------------------------
305
306bool operator<(const Rational& a,const Rational& b)
307{
308  if (mpq_cmp(a.p->rat,b.p->rat)<0) return true;
309  return false;
310}
311
312bool operator<=(const Rational& a,const Rational& b)
313{
314  if (mpq_cmp(a.p->rat,b.p->rat)>0) return false;
315  return true;
316}
317
318bool operator>(const Rational& a,const Rational& b)
319{
320  if (mpq_cmp(a.p->rat,b.p->rat)>0) return true;
321  return false;
322}
323
324bool operator>=(const Rational& a,const Rational& b)
325{
326  if (mpq_cmp(a.p->rat,b.p->rat)<0) return false;
327  return true;
328}
329
330bool operator==(const Rational& a,const Rational& b)
331{
332  if (mpq_equal(a.p->rat,b.p->rat)) return true;
333  return false;
334}
335
336bool operator!=(const Rational& a,const Rational& b)
337{
338  if (mpq_equal(a.p->rat,b.p->rat)) return false;
339  return true;
340}
341
342// ----------------------------------------------------------------------------
343//  Ostream
344// ----------------------------------------------------------------------------
345
346#ifdef GMPRAT_PRINT
347ostream& operator<< (ostream& s,const Rational& a)
348{
349    char *snum,*sdenom;
350
351    snum   = mpz_get_str( NULL,10,mpq_numref(a.p->rat) );
352    sdenom = mpz_get_str( NULL,10,mpq_denref(a.p->rat) );
353
354    if( sdenom[0] == '1' && sdenom[1] == '\0' )
355    {
356        #ifdef GMPRAT_IOSTREAM
357            s << snum;
358        #else
359            fprintf( stdout,snum );
360        #endif
361    }
362    else
363    {
364        #ifdef GMPRAT_IOSTREAM
365            s << snum << "/" << sdenom;
366        #else
367            fprintf( stdout,snum );
368            fprintf( stdout,"/" );
369            fprintf( stdout,sdenom );
370        #endif
371    }
372
373    //free( snum );
374    //free( sdenom );
375
376    return s;
377}
378#endif
379
380unsigned int Rational::length( ) const
381{
382    char *snum = (char*)NULL;
383    char *sden = (char*)NULL;
384
385    snum = mpz_get_str( snum,10,mpq_numref( p->rat ) );
386    sden = mpz_get_str( sden,10,mpq_denref( p->rat ) );
387
388    int length = strlen( snum );
389
390    if( sden[0] != '1' || sden[1] != '\0' ) length += strlen( sden ) + 1;
391
392    free( snum );
393    free( sden );
394
395    return  length;
396}
397
398// ----------------------------------------------------------------------------
399//  Operators
400// ----------------------------------------------------------------------------
401
402Rational
403operator+(const Rational& a,const Rational &b)
404{
405  Rational
406    erg(a);
407
408  return erg+=b;
409}
410
411Rational
412operator-(const Rational& a,const Rational &b)
413{
414  Rational
415    erg(a);
416
417  return erg-=b;
418}
419
420Rational
421operator*(const Rational& a,const Rational &b)
422{
423  Rational
424    erg(a);
425
426  return erg*=b;
427}
428
429Rational pow( const Rational& a,int e )
430{
431    Rational erg(1);
432
433    for( int i=0; i<e; i++ )
434    {
435        erg *= a;
436    }
437    return erg;
438}
439
440Rational operator/(const Rational& a,const Rational &b)
441{
442  Rational
443    erg(a);
444
445  return erg/=b;
446}
447
448int sgn(const Rational& a)
449{
450  return mpq_sgn(a.p->rat);
451}
452
453Rational
454abs(const Rational& a)
455{
456  Rational
457    erg;
458
459  if (mpq_sgn(a.p->rat)<0)
460    mpq_neg(erg.p->rat,a.p->rat);
461  else
462    mpq_set(erg.p->rat,a.p->rat);
463  return erg;
464}
465
466Rational gcd( const Rational &a,const Rational &b )
467{
468    if( a == 0 )
469    {
470        if( b == 0 )
471        {
472            return  (Rational)1;
473        }
474        else
475        {
476            return  abs( b );
477        }
478    }
479    else if( b == 0 )
480    {
481        return  abs( a );
482    }
483
484    Rational erg;
485
486    mpz_gcd( mpq_numref( erg.p->rat ),
487            mpq_numref( a.p->rat ),mpq_numref( b.p->rat ) );
488    mpz_gcd( mpq_denref( erg.p->rat ),
489            mpq_denref( a.p->rat ),mpq_denref( b.p->rat ) );
490
491    //mpq_canonicalize( erg.p->rat );
492
493    return  abs( erg );
494}
495
496Rational gcd( Rational *a,int n )
497{
498    if( n == 1 )
499    {
500        return  a[0];
501    }
502
503    Rational g = gcd( a[0],a[1] );
504
505    for( int i=2; i<n; i++ )
506    {
507        g = gcd( g,a[i] );
508    }
509
510    return  g;
511}
512
513Rational lcm( const Rational &a,const Rational &b )
514{
515    if( a == 0 )
516    {
517        return b;
518    }
519    else if( b == 0 )
520    {
521        return a;
522    }
523
524    return a*b/gcd(a,b);
525}
526
527Rational lcm( Rational *a,int n )
528{
529    if( n == 1 )
530    {
531        return  a[0];
532    }
533
534    Rational g = lcm( a[0],a[1] );
535
536    for( int i=2; i<n; i++ )
537    {
538        g = lcm( g,a[i] );
539    }
540
541    return  g;
542}
543
544double  Rational::complexity( ) const
545{
546    double num = mpz_get_d( mpq_numref( p->rat ) );
547    double den = mpz_get_d( mpq_denref( p->rat ) );
548
549    if( num < 0 ) num = -num;
550    if( den < 0 ) den = -den;
551
552    return  ( num > den ? num : den );
553}
554
555#endif /* HAVE_SPECTRUM */
556// ----------------------------------------------------------------------------
557//  GMPrat.cc
558//  end of file
559// ----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.