PSCF v1.1
Rational.h
1#ifndef UTIL_RATIONAL_H
2#define UTIL_RATIONAL_H
3
4/*
5* Util Package - C++ Utilities for Scientific Computation
6*
7* Copyright 2010 - 2017, The Regents of the University of Minnesota
8* Distributed under the terms of the GNU General Public License.
9*/
10
11#include "gcd.h"
12#include <util/global.h>
13
14#ifdef UTIL_MPI
15#include <util/mpi/MpiTraits.h>
16#endif
17
18#include <iostream>
19
20namespace Util
21{
22
34 {
35
36 public:
37
39
40
44 Rational();
45
54 Rational(int num, int den);
55
63 Rational(int number);
64
70 Rational(Rational const & v);
71
76 {}
77
79
80
86 Rational & operator = (Rational const & other);
87
95 Rational & operator = (int other);
96
98
100
108 Rational & operator += (Rational const & a);
109
117 Rational & operator += (int a);
118
126 Rational & operator -= (Rational const & a);
127
135 Rational & operator -= (int);
136
144 Rational & operator *= (Rational const & a);
145
153 Rational & operator *= (int a);
154
162 Rational & operator /= (Rational const & a);
163
171 Rational & operator /= (int a);
172
174
176
180 int num() const;
181
185 int den() const;
186
192 operator double () const;
193
195
202 template <class Archive>
203 void serialize(Archive & ar, const unsigned int version);
204
205 #ifdef UTIL_MPI
209 static void commitMpiType();
210 #endif
211
213
214 private:
215
219 int num_;
220
224 int den_;
225
229 void reduce();
230
231 //friends:
232
233 friend Rational operator + (Rational const & a, Rational const & b);
234 friend Rational operator + (Rational const & a, int b);
235
236 friend Rational operator - (Rational const & a, Rational const & b);
237 friend Rational operator - (Rational const & a, int b);
238 friend Rational operator - (int b, Rational const & a);
239
240 friend Rational operator * (Rational const & a, Rational const & b);
241 friend Rational operator * (Rational const & a, int b);
242
243 friend Rational operator / (Rational const & a, Rational const & b);
244 friend Rational operator / (Rational const & a, int b);
245 friend Rational operator / (int b, Rational const & a);
246
247 friend bool operator == (Rational const & a, Rational const & b);
248 friend bool operator == (Rational const & a, int b);
249
250 // Unary negation operation
251 friend Rational operator - (Rational const & a);
252
253 friend
254 std::ostream & operator << (std::ostream& out, Rational const & rational);
255
256 #ifdef UTIL_CXX11
257 friend
258 std::istream & operator >> (std::istream & in, Rational & rational);
259 #endif
260
261 };
262
263
264
265 // Inline methods
266
267 /*
268 * Default constructor
269 */
270 inline
272 : num_(0),
273 den_(1)
274 { reduce(); }
275
276 /*
277 * Constructor from numerator and denominator.
278 */
279 inline
280 Rational::Rational(int num, int den)
281 : num_(num),
282 den_(den)
283 { reduce(); }
284
285 /*
286 * Constructor from integer.
287 */
288 inline
290 : num_(number),
291 den_(1)
292 {}
293
294 /*
295 * Copy constructor
296 */
297 inline
299 : num_(other.num_),
300 den_(other.den_)
301 {}
302
303 /*
304 * Assignment from another rational.
305 */
306 inline
308 {
309 num_ = other.num_;
310 den_ = other.den_;
311 return *this;
312 }
313
314 /*
315 * Assignment from integer.
316 */
317 inline
319 {
320 num_ = other;
321 den_ = 1;
322 return *this;
323 }
324
325 // Inline arithmetic assignment operators
326
327 /*
328 * Addition assignment operator : add b to this.
329 */
330 inline
332 {
333 num_ = num_*a.den_ + a.num_*den_;
334 den_ = den_*a.den_;
335 reduce();
336 return *this;
337 }
338
339 /*
340 * Addition assignment operator : add integer to this.
341 */
342 inline
344 {
345 num_ += a*den_;
346 reduce();
347 return *this;
348 }
349
350 /*
351 * Subtraction assignment operator : subtract a from this.
352 */
353 inline
355 {
356 num_ = num_*a.den_ - a.num_*den_;
357 den_ = den_*a.den_;
358 reduce();
359 return *this;
360 }
361
362 /*
363 * Subtraction assignment operator : subtract integer from this.
364 */
365 inline
367 {
368 num_ -= a*den_;
369 reduce();
370 return *this;
371 }
372
373 /*
374 * Multipication assignment operator : multiply this by a.
375 */
376 inline
378 {
379 num_ *= a.num_;
380 den_ *= a.den_;
381 reduce();
382 return *this;
383 }
384
385 /*
386 * Multipication assignment operator : multiply this by a.
387 */
388 inline
390 {
391 num_ *= a;
392 reduce();
393 return *this;
394 }
395
396 /*
397 * Division assignment operator : divide this by rational.
398 */
399 inline
401 {
402 if (a.num_ == 0) {
403 UTIL_THROW("Attempt to divide by zero Rational");
404 }
405 num_ = num_*a.den_;
406 den_ = den_*a.num_;
407 reduce();
408 return *this;
409 }
410
411 /*
412 * Division assignment operator : divide this by rational.
413 */
414 inline
416 {
417 if (a == 0) {
418 UTIL_THROW("Attempt to divide Rational by zero integer");
419 }
420 den_ *= a;
421 reduce();
422 return *this;
423 }
424
425 // Accessors
426
427 /*
428 * Return numerator.
429 */
430 inline
431 int Rational::num() const
432 { return num_; }
433
434 /*
435 * Return denominator.
436 */
437 inline
438 int Rational::den() const
439 { return den_; }
440
441 /*
442 * Cast to double operator.
443 */
444 inline
445 Rational::operator double () const
446 { return double(num_)/double(den_); }
447
448 // Miscellaneous member functions
449
450 /*
451 * Serialize to/from an archive.
452 */
453 template <class Archive>
454 inline void Rational::serialize(Archive & ar, const unsigned int version)
455 {
456 ar & den_;
457 ar & num_;
458 }
459
460 /*
461 * Reduce rational number to standard reduced form (private).
462 */
463 inline
464 void Rational::reduce ()
465 {
466 UTIL_CHECK(den_ != 0);
467 if (num_ == 0) {
468 den_ = 1;
469 } else {
470 if (den_ < 0) {
471 den_ *= -1;
472 num_ *= -1;
473 }
474 int c = gcd(num_, den_);
475 num_ /= c;
476 den_ /= c;
477 }
478 }
479
480 // Friend functions for binary arithmetic operations
481
489 inline
490 Rational operator + (Rational const & a, Rational const & b)
491 {
492 int num = a.num_*b.den_ + b.num_*a.den_;
493 int den = a.den_*b.den_;
494 return Rational(num, den);
495 }
496
504 inline
505 Rational operator + (Rational const & a, int b)
506 {
507 int num = a.num_ + b*a.den_;
508 return Rational(num, a.den_);
509 }
510
518 inline
519 Rational operator + (int b, Rational const & a)
520 { return (a + b); }
521
529 inline
530 Rational operator - (Rational const & a, Rational const & b)
531 {
532 int num = a.num_*b.den_ - b.num_*a.den_;
533 int den = a.den_*b.den_;
534 return Rational(num, den);
535 }
536
544 inline
545 Rational operator - (Rational const & a, int b)
546 {
547 int num = a.num_ - b*a.den_;
548 return Rational(num, a.den_);
549 }
550
558 inline
559 Rational operator - (int b, Rational const & a)
560 {
561 int num = b*a.den_ - a.num_;
562 return Rational(num, a.den_);
563 }
564
572 inline
573 Rational operator * (Rational const & a, Rational const & b)
574 {
575 int num = a.num_*b.num_;
576 int den = a.den_*b.den_;
577 return Rational(num, den);
578 }
579
587 inline
588 Rational operator * (Rational const & a, int b)
589 { return Rational(b*a.num_, a.den_); }
590
598 inline
599 Rational operator * (int b, Rational const & a)
600 { return a*b; }
601
609 inline
610 Rational operator / (Rational const & a, Rational const & b)
611 {
612 if (b.num_ == 0) {
613 UTIL_THROW("Attempt to divide by zero Rational");
614 }
615 int num = a.num_*b.den_;
616 int den = a.den_*b.num_;
617 return Rational(num, den);
618 }
619
627 inline
628 Rational operator / (Rational const & a, int b)
629 {
630 if (b == 0) {
631 UTIL_THROW("Attempt to divide Rational by zero integer");
632 }
633 return Rational(a.num_, a.den_*b);
634 }
635
643 inline
644 Rational operator / (int b, Rational const & a)
645 {
646 if (a.num_ == 0) {
647 UTIL_THROW("Attempt to divide integer by zero Rational");
648 }
649 return Rational(b*a.den_, a.num_);
650 }
651
652 // Unary arithmetic operators
653
660 inline
662 { return Rational(-a.num_, a.den_); }
663
665
673 inline
674 bool operator == (Rational const & a, Rational const & b)
675 { return ((a.num_ == b.num_) && (a.den_ == b.den_)); }
676
684 inline bool operator == (Rational const & a, int b)
685 { return ((a.num_ == b) && (a.den_ == 1)); }
686
694 inline bool operator == (int b, Rational const & a)
695 { return (a == b); }
696
698
706 inline bool operator != (Rational const & a, Rational const & b)
707 { return !(a == b); }
708
716 inline bool operator != (Rational const & a, int b)
717 { return !(a == b); }
718
726 inline bool operator != (int b, Rational const & a)
727 { return !(a == b); }
728
729 // Miscellaneous global functions.
730
739 std::ostream& operator << (std::ostream& out, Rational const & rational);
740
741 #ifdef UTIL_CXX11
751 std::istream& operator >> (std::istream& in, Rational & rational);
752 #endif
753
754 #ifdef UTIL_MPI
758 template <>
760 {
761 public:
762 static MPI::Datatype type;
763 static bool hasType;
764 };
765 #endif
766
767}
768#endif
static MPI::Datatype type
MPI Datatype.
Definition: Rational.h:762
static bool hasType
Is the MPI type initialized?
Definition: Rational.h:763
Default MpiTraits class.
Definition: MpiTraits.h:40
A Rational number (a ratio of integers).
Definition: Rational.h:34
int num() const
Return numerator.
Definition: Rational.h:431
friend std::ostream & operator<<(std::ostream &out, Rational const &rational)
Output stream inserter for a Rational.
Definition: Rational.cpp:16
Rational & operator/=(Rational const &a)
Divide this rational by another.
Definition: Rational.h:400
Rational()
Default constructor.
Definition: Rational.h:271
Rational & operator*=(Rational const &a)
Multiply this rational by another.
Definition: Rational.h:377
friend bool operator==(Rational const &a, Rational const &b)
Equality operators.
Definition: Rational.h:674
friend Rational operator*(Rational const &a, Rational const &b)
Compute product of rationals.
Definition: Rational.h:573
Rational & operator+=(Rational const &a)
Add another rational to this one.
Definition: Rational.h:331
static void commitMpiType()
Commit MPI datatype MpiTraits<Rational>::type.
Rational & operator=(Rational const &other)
Copy assignment from another Rational.
Definition: Rational.h:307
Rational & operator-=(Rational const &a)
Subtract another rational from this one.
Definition: Rational.h:354
int den() const
Return denominator.
Definition: Rational.h:438
friend Rational operator-(Rational const &a, Rational const &b)
Compute difference of rationals.
Definition: Rational.h:530
~Rational()
Destructor.
Definition: Rational.h:75
friend Rational operator+(Rational const &a, Rational const &b)
Compute sum of two rationals.
Definition: Rational.h:490
void serialize(Archive &ar, const unsigned int version)
Serialize to/from an archive.
Definition: Rational.h:454
friend Rational operator/(Rational const &a, Rational const &b)
Compute quotient of two rationals.
Definition: Rational.h:610
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
#define UTIL_THROW(msg)
Macro for throwing an Exception, reporting function, file and line number.
Definition: global.h:51
int gcd(int a, int b)
Compute greatest common divisor (gcd) of two integers.
Definition: gcd.h:30
Utility classes for scientific computation.
Definition: accumulators.mod:1
Rational operator*(Rational const &a, Rational const &b)
Compute product of rationals.
Definition: Rational.h:573
Rational operator+(Rational const &a, Rational const &b)
Compute sum of two rationals.
Definition: Rational.h:490
Rational operator/(Rational const &a, Rational const &b)
Compute quotient of two rationals.
Definition: Rational.h:610
bool operator==(Polynomial< T > const &a, Polynomial< T > const &b)
Equality operator for polynomials.
Definition: Polynomial.h:675
Polynomial< T > operator-(Polynomial< T > const &a)
Unary negation of polynomial.
Definition: Polynomial.h:705
std::istream & operator>>(std::istream &in, Pair< Data > &pair)
Input a Pair from an istream.
Definition: Pair.h:44
std::ostream & operator<<(std::ostream &out, const Pair< Data > &pair)
Output a Pair to an ostream, without line breaks.
Definition: Pair.h:57
bool operator!=(Polynomial< T > const &a, Polynomial< T > const &b)
Inequality operator for polynomials.
Definition: Polynomial.h:694