ARTS 2.5.0 (git: 9ee3ac6c)
rational.h
Go to the documentation of this file.
1/* Copyright (C) 2012
2Richard Larsson <ric.larsson@gmail.com>
3
4This program is free software; you can redistribute it and/or modify it
5under the terms of the GNU General Public License as published by the
6Free Software Foundation; either version 2, or (at your option) any
7later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17USA. */
18
27#ifndef rational_h
28#define rational_h
29
30#include "array.h"
31#include "bifstream.h"
32#include "bofstream.h"
33#include "math_funcs.h"
34#include "matpack.h"
35#include <ostream>
36
37
44constexpr Index gcd(Index a, Index b) noexcept {
45 if (b == 0)
46 return a;
47 return gcd(b, a%b);
48}
49
50
52class Rational {
53 public:
59 constexpr Rational(const Index nom = 0, const Index denom = 1) noexcept
60 : mnom(denom ? nom : 0), mdenom(denom) {
61 const auto div = gcd(nom, denom);
62 if (div) {
63 mnom /= div;
64 mdenom /= div;
65 }
66 }
67
80 explicit Rational(const String& s);
81
83 [[nodiscard]] constexpr Index Nom() const noexcept { return mnom; }
84
86 [[nodiscard]] constexpr Index Denom() const noexcept { return mdenom; }
87
89 constexpr Index& Nom() noexcept { return mnom; }
90
92 constexpr Index& Denom() noexcept { return mdenom; }
93
95 constexpr void Nom(Index x) noexcept { mnom = x; }
96
98 constexpr void Denom(Index x) noexcept { mdenom = x; }
99
101 void simplify_in_place() noexcept;
102
108 [[nodiscard]] constexpr bool isUndefined() const noexcept { return (mdenom == 0); }
109
115 [[nodiscard]] constexpr bool isDefined() const noexcept { return not isUndefined(); }
116
123 [[nodiscard]] constexpr bool isIndex(int n=1) const noexcept {
124 return isDefined() and not bool((n*mnom) % mdenom);
125 }
126
134 [[nodiscard]] constexpr Index toIndex(int n=1) const noexcept {
135 return (n*mnom) / mdenom;;
136 }
137
142 [[nodiscard]] constexpr Numeric toNumeric() const noexcept {
143 return Numeric(mnom) / Numeric(mdenom);
144 }
145
153 [[nodiscard]] constexpr int toInt(int n=1) const noexcept { return int(toIndex(n)); }
154
160 constexpr Rational& operator+=(const Rational& a) noexcept {
161 mnom = mnom * a.Denom() + a.Nom() * mdenom;
162 mdenom *= a.Denom();
163 return *this;
164 }
165
171 constexpr Rational& operator+=(const Index& a) noexcept {
172 mnom += mdenom * a;
173 return *this;
174 }
175
181 constexpr Rational& operator+=(const int& a) noexcept {
182 mnom += mdenom * a;
183 return *this;
184 }
185
191 constexpr Rational& operator-=(const Rational& a) noexcept {
192 mnom = mnom * a.Denom() - a.Nom() * mdenom;
193 mdenom *= a.Denom();
194 return *this;
195 }
196
202 constexpr Rational& operator-=(const Index& a) noexcept {
203 mnom -= mdenom * a;
204 return *this;
205 }
206
212 constexpr Rational& operator-=(const int& a) noexcept {
213 mnom -= mdenom * a;
214 return *this;
215 }
216
222 constexpr Rational& operator/=(const Rational& a) noexcept {
223 mnom *= a.Denom();
224 mdenom *= a.Nom();
225 return *this;
226 }
227
233 constexpr Rational& operator/=(const Index& a) noexcept {
234 mdenom *= a;
235 return *this;
236 }
237
243 constexpr Rational& operator/=(const int& a) noexcept {
244 mdenom *= a;
245 return *this;
246 }
247
253 constexpr Rational& operator*=(const Rational& a) noexcept {
254 mnom *= a.Nom();
255 mdenom *= a.Denom();
256 return *this;
257 }
258
264 constexpr Rational& operator*=(const Index& a) noexcept {
265 mnom *= a;
266 return *this;
267 }
268
274 constexpr Rational& operator*=(const int& a) noexcept {
275 mnom *= a;
276 return *this;
277 }
278
280 constexpr Rational operator++(int) const noexcept{
281 return Rational(mnom + mdenom, mdenom);
282 }
283
285 constexpr Rational operator--(int) const noexcept {
286 return Rational(mnom - mdenom, mdenom);
287 }
288
290 constexpr Rational& operator++() noexcept {
291 mnom += mdenom;
292 return *this;
293 }
294
296 constexpr Rational& operator--() noexcept {
297 mnom -= mdenom;
298 return *this;
299 }
300
302 explicit constexpr operator bool() const noexcept {
303 return isDefined() and bool(mnom);
304 }
305
307 explicit constexpr operator Numeric() const noexcept { return toNumeric(); }
308
310 explicit constexpr operator Index() const noexcept { return toIndex(); }
311
313 explicit constexpr operator int() const noexcept { return toInt(); }
314
317 bif >> mnom >> mdenom;
318 return bif;
319 }
320
322 bofstream& write(bofstream& bof) const {
323 bof << mnom << mdenom;
324 return bof;
325 }
326
328 constexpr Rational& fixSign() noexcept {
329 if (mdenom < 0) {
330 mnom = -mnom;
331 mdenom = -mdenom;
332 }
333 return *this;
334 }
335
336 private:
337 // Rational is supposed to be used rationally ( mnom / mdenom )
340}; // Rational;
341
347constexpr Rational reduce_by_gcd(const Rational a) noexcept {
348 const Index div = gcd(a.Nom(), a.Denom());
349 if (div)
350 return Rational(a.Nom() / div, a.Denom() / div);
351 return a;
352}
353
361constexpr Rational numeric2rational(Numeric x, size_t maxdec=4) noexcept {
362 Index nom=0, denom=1;
363
364 // Keep track of sign independently
365 const bool signchange = x < 0;
366 x = signchange ? -x : x;
367
368 // Add numbers by keeping the floor
369 size_t i=0;
370 do {
371 const auto xi=Index(x);
372 nom += xi;
373 x = 10 * (x - Numeric(xi));
374 nom *= 10;
375 denom *= 10;
376 i++;
377 } while (i<=maxdec);
378
379 // Fix possible rounding error
380 if (x >= 5)
381 nom += 10;
382
383 // Change sign or not
384 if (signchange)
385 return Rational(-nom, denom);
386 return Rational(nom, denom);
387}
388
389
390// An undefined rational to be used everywhere for a undefined rationals
391#define RATIONAL_UNDEFINED Rational(0, 0)
392
398constexpr Rational operator-(const Rational a) noexcept {
399 return Rational(-a.Nom(), a.Denom());
400}
401
407constexpr Rational operator+(const Rational a) noexcept { return a; }
408
415constexpr Rational operator+(const Rational a, const Rational b) noexcept {
416 return (a.Denom() == b.Denom())
417 ? Rational(a.Nom() + b.Nom(), a.Denom())
418 : Rational(a.Nom() * b.Denom() + b.Nom() * a.Denom(),
419 a.Denom() * b.Denom());
420}
421
428constexpr Rational operator+(const Rational a, Index b) noexcept {
429 return Rational(a.Nom() + b * a.Denom(), a.Denom());
430}
431
438constexpr Rational operator+(const Rational a, int b) noexcept {
439 return Rational(a.Nom() + b * a.Denom(), a.Denom());
440}
441
448constexpr Rational operator+(Index b, const Rational a) noexcept { return operator+(a, b); }
449
456constexpr Rational operator+(int b, const Rational a) noexcept { return operator+(a, b); }
457
464constexpr Rational operator-(const Rational a, const Rational b) noexcept {
465 return (a.Denom() == b.Denom())
466 ? Rational(a.Nom() - b.Nom(), a.Denom())
467 : Rational(a.Nom() * b.Denom() - b.Nom() * a.Denom(),
468 a.Denom() * b.Denom());
469}
470
477constexpr Rational operator-(const Rational a, Index b) noexcept {
478 return Rational(a.Nom() - b * a.Denom(), a.Denom());
479}
480
487constexpr Rational operator-(const Rational a, int b) noexcept {
488 return Rational(a.Nom() - b * a.Denom(), a.Denom());
489}
490
497constexpr Rational operator-(Index b, const Rational a) noexcept {
498 return Rational(-a.Nom() + b * a.Denom(), a.Denom());
499}
500
507constexpr Rational operator-(int b, const Rational a) noexcept {
508 return Rational(-a.Nom() + b * a.Denom(), a.Denom());
509}
510
517constexpr Rational operator/(const Rational a, const Rational b) noexcept {
518 return Rational(a.Nom() * b.Denom(), a.Denom() * b.Nom());
519}
520
527constexpr Rational operator/(const Rational a, Index b) noexcept {
528 return Rational(a.Nom(), a.Denom() * b);
529}
530
537constexpr Rational operator/(const Rational a, int b) noexcept {
538 return Rational(a.Nom(), a.Denom() * b);
539}
540
547constexpr Rational operator/(Index b, const Rational a) noexcept {
548 return Rational(a.Denom() * b, a.Nom());
549}
550
557constexpr Rational operator/(int b, const Rational a) noexcept {
558 return Rational(a.Denom() * b, a.Nom());
559}
560
567constexpr Rational operator*(const Rational a, const Rational b) noexcept {
568 return Rational(a.Nom() * b.Nom(), a.Denom() * b.Denom());
569}
570
577constexpr Rational operator*(const Rational a, Index b) noexcept {
578 return Rational(a.Nom() * b, a.Denom());
579}
580
587constexpr Rational operator*(const Rational a, int b) noexcept {
588 return Rational(a.Nom() * b, a.Denom());
589}
590
597constexpr Rational operator*(Index b, const Rational a) noexcept { return operator*(a, b); }
598
605constexpr Rational operator*(int b, const Rational a) noexcept { return operator*(a, b); }
606
613constexpr Rational operator%(const Rational a, const Rational b) noexcept {
614 return (a.Denom() == b.Denom())
615 ? Rational(a.Nom() % b.Nom(), a.Denom())
616 : Rational((a.Nom() * b.Denom()) % (a.Denom() * b.Nom()),
617 a.Denom() * b.Denom());
618}
619
626constexpr Rational operator%(const Rational a, Index b) noexcept {
627 return Rational(a.Nom() % (a.Denom() * b), a.Denom());
628}
629
636constexpr Rational operator%(const Rational a, int b) noexcept {
637 return Rational(a.Nom() % (a.Denom() * b), a.Denom());
638}
639
646constexpr Rational operator%(Index b, const Rational a) noexcept {
647 return Rational((b * a.Denom()) % a.Nom(), a.Denom());
648}
649
656constexpr Rational operator%(int b, const Rational a) noexcept {
657 return Rational((b * a.Denom()) % a.Nom(), a.Denom());
658}
659
667constexpr bool operator==(const Rational a, const Rational b) noexcept {
668 return a.isDefined() and b.isDefined() and
669 a.Nom() * b.Denom() == a.Denom() * b.Nom();
670}
671
679constexpr bool operator!=(const Rational a, const Rational b) noexcept {
680 return not (a.isDefined() and b.isDefined() and operator==(a, b));
681}
682
690constexpr bool operator<(const Rational a, const Rational b) noexcept {
691 return a.isDefined() and b.isDefined() and
692 a.Nom() * b.Denom() < a.Denom() * b.Nom();
693}
694
702constexpr bool operator>(const Rational a, const Rational b) noexcept { return operator<(b, a) and a.isDefined() and b.isDefined(); }
703
711constexpr bool operator<=(const Rational a, const Rational b) noexcept {
712 return not operator>(a, b) and a.isDefined() and b.isDefined();
713}
714
722constexpr bool operator>=(const Rational a, const Rational b) noexcept {
723 return not operator<(a, b) and a.isDefined() and b.isDefined();
724}
725
732constexpr bool operator!(const Rational a) noexcept { return a.Nom() and a.isDefined(); }
733
739inline Numeric sqrt(const Rational r) { return std::sqrt(r.toNumeric()); }
740
747inline Numeric pow(const Rational base, Numeric exp) {
748 return std::pow(base.toNumeric(), exp);
749}
750
757inline Numeric pow(Numeric base, const Rational exp) {
758 return std::pow(base, exp.toNumeric());
759}
760
767inline Numeric pow(const Rational base, const Rational exp) {
768 return pow(base, exp.toNumeric());
769}
770
772std::ostream& operator<<(std::ostream& os, const Rational& a);
773
775std::istream& operator>>(std::istream& is, Rational& a);
776
783constexpr bool operator<(const Index a, const Rational b) noexcept {
784 return Rational(a, 1) < b and b.isDefined();
785}
786
793constexpr bool operator<(const int a, const Rational b) noexcept {
794 return Rational(a, 1) < b and b.isDefined();
795}
796
803constexpr bool operator<(const Rational a, const Index b) noexcept {
804 return a < Rational(b, 1) and a.isDefined();
805}
806
813constexpr bool operator<(const Rational a, const int b) noexcept {
814 return a < Rational(b, 1) and a.isDefined();
815}
816
823constexpr bool operator>(const Index a, const Rational b) noexcept {
824 return Rational(a, 1) > b and b.isDefined();
825}
826
833constexpr bool operator>(const int a, const Rational b) noexcept {
834 return Rational(a, 1) > b and b.isDefined();
835}
836
843constexpr bool operator>(const Rational a, const Index b) noexcept {
844 return a > Rational(b, 1) and a.isDefined();
845}
846
853constexpr bool operator>(const Rational a, const int b) noexcept {
854 return a > Rational(b, 1) and a.isDefined();
855}
856
863constexpr bool operator==(const Rational a, const Index b) noexcept {
864 return a == Rational(b, 1) and a.isDefined();
865}
866
873constexpr bool operator==(const Rational a, const int b) noexcept {
874 return a == Rational(b, 1) and a.isDefined();
875}
876
883constexpr bool operator!=(const Rational a, const Index b) noexcept {
884 return not(a == b) and a.isDefined();
885}
886
893constexpr bool operator!=(const Rational a, const int b) noexcept {
894 return not(a == b) and a.isDefined();
895}
896
902constexpr Rational abs(const Rational a) noexcept {
903 return a < 0 ? -a : a;
904}
905
912constexpr Rational max(const Rational a, const Rational b) noexcept {
913 return a < b ? b : a;
914} // Let other operators find out if this is allowed instead
915
922constexpr Rational min(const Rational a, const Rational b) noexcept {
923 return a < b ? a : b;
924} // Let other operators find out if this is allowed instead
925
927
933constexpr Rational operator ""_2(unsigned long long int n) noexcept {
934 return Rational(n, 2);
935};
936
942constexpr bool iseven(const Rational r) noexcept {
943 return 0 == (r % 2);
944}
945
946#endif // rational_h
947
This file contains the definition of Array.
This file contains the class declaration of bifstream.
This file contains the class declaration of bofstream.
This can be used to make arrays out of anything.
Definition: array.h:107
Implements rational numbers to work with other ARTS types.
Definition: rational.h:52
Index mnom
Definition: rational.h:338
constexpr Rational(const Index nom=0, const Index denom=1) noexcept
Initialization call.
Definition: rational.h:59
constexpr Rational & operator++() noexcept
Add one if possible.
Definition: rational.h:290
constexpr bool isUndefined() const noexcept
Is the object not defined.
Definition: rational.h:108
constexpr Index Denom() const noexcept
Denominator.
Definition: rational.h:86
constexpr Rational & operator-=(const int &a) noexcept
Remove from this.
Definition: rational.h:212
constexpr Index & Denom() noexcept
Denominator.
Definition: rational.h:92
constexpr Index & Nom() noexcept
Nominator.
Definition: rational.h:89
constexpr bool isDefined() const noexcept
Is the object defined.
Definition: rational.h:115
constexpr Rational & operator*=(const int &a) noexcept
Multiply by this.
Definition: rational.h:274
constexpr Numeric toNumeric() const noexcept
Converts this to a Numeric.
Definition: rational.h:142
constexpr Rational & operator--() noexcept
Remove one if possible.
Definition: rational.h:296
constexpr Rational & operator-=(const Index &a) noexcept
Remove from this.
Definition: rational.h:202
constexpr Rational & operator+=(const Rational &a) noexcept
Add to this.
Definition: rational.h:160
constexpr Rational & operator/=(const Index &a) noexcept
Divide by this.
Definition: rational.h:233
constexpr Index toIndex(int n=1) const noexcept
Converts the value to index by n-scaled division.
Definition: rational.h:134
constexpr Rational & operator+=(const Index &a) noexcept
Add to this.
Definition: rational.h:171
bifstream & read(bifstream &bif)
Binary read for Rational.
Definition: rational.h:316
void simplify_in_place() noexcept
Simplify by reducing the values locally.
Definition: rational.cc:104
constexpr Rational & operator*=(const Rational &a) noexcept
Multiply by this.
Definition: rational.h:253
constexpr Rational & operator/=(const Rational &a) noexcept
Divide by this.
Definition: rational.h:222
constexpr Rational & operator+=(const int &a) noexcept
Add to this.
Definition: rational.h:181
constexpr Index Nom() const noexcept
Nominator.
Definition: rational.h:83
bofstream & write(bofstream &bof) const
Binary write for Rational.
Definition: rational.h:322
constexpr Rational operator--(int) const noexcept
Remove one if possible.
Definition: rational.h:285
constexpr Rational & fixSign() noexcept
Makes the sign of mdenom positive.
Definition: rational.h:328
constexpr Rational operator++(int) const noexcept
Add one if possible.
Definition: rational.h:280
constexpr bool isIndex(int n=1) const noexcept
Is the object a n-scaled Index.
Definition: rational.h:123
constexpr Rational & operator/=(const int &a) noexcept
Divide by this.
Definition: rational.h:243
constexpr int toInt(int n=1) const noexcept
Converts the value to int by n-scaled division in Index form.
Definition: rational.h:153
constexpr void Nom(Index x) noexcept
Nominator.
Definition: rational.h:95
Index mdenom
Definition: rational.h:339
constexpr void Denom(Index x) noexcept
Denominator.
Definition: rational.h:98
constexpr Rational & operator-=(const Rational &a) noexcept
Remove from this.
Definition: rational.h:191
constexpr Rational & operator*=(const Index &a) noexcept
Multiply by this.
Definition: rational.h:264
Binary output file stream class.
Definition: bifstream.h:42
Binary output file stream class.
Definition: bofstream.h:42
INDEX Index
The type to use for all integer numbers and indices.
Definition: matpack.h:39
NUMERIC Numeric
The type to use for all floating point numbers.
Definition: matpack.h:33
#define a
#define b
constexpr bool operator>(const Rational a, const Rational b) noexcept
More than.
Definition: rational.h:702
constexpr Rational operator+(const Rational a) noexcept
Positive.
Definition: rational.h:407
constexpr bool operator>=(const Rational a, const Rational b) noexcept
More than or equal to.
Definition: rational.h:722
Numeric pow(const Rational base, Numeric exp)
Power of.
Definition: rational.h:747
constexpr Index gcd(Index a, Index b) noexcept
Returns the greatest common denominator of two numbers.
Definition: rational.h:44
constexpr Rational max(const Rational a, const Rational b) noexcept
Maximum.
Definition: rational.h:912
constexpr bool operator!(const Rational a) noexcept
Not.
Definition: rational.h:732
constexpr Rational operator-(const Rational a) noexcept
Negative.
Definition: rational.h:398
constexpr bool operator!=(const Rational a, const Rational b) noexcept
Inequality.
Definition: rational.h:679
constexpr bool operator<(const Rational a, const Rational b) noexcept
Less than.
Definition: rational.h:690
Numeric sqrt(const Rational r)
Square root.
Definition: rational.h:739
constexpr bool iseven(const Rational r) noexcept
Returns true if even integer.
Definition: rational.h:942
std::ostream & operator<<(std::ostream &os, const Rational &a)
Output operator.
Definition: rational.cc:33
std::istream & operator>>(std::istream &is, Rational &a)
Input operator.
Definition: rational.cc:44
constexpr Rational min(const Rational a, const Rational b) noexcept
Minimum.
Definition: rational.h:922
constexpr bool operator==(const Rational a, const Rational b) noexcept
Equality.
Definition: rational.h:667
constexpr Rational numeric2rational(Numeric x, size_t maxdec=4) noexcept
Rational from Numeric.
Definition: rational.h:361
constexpr Rational operator%(const Rational a, const Rational b) noexcept
Remainder.
Definition: rational.h:613
constexpr bool operator<=(const Rational a, const Rational b) noexcept
Less than or equal to.
Definition: rational.h:711
constexpr Rational abs(const Rational a) noexcept
Absolute.
Definition: rational.h:902
constexpr Rational reduce_by_gcd(const Rational a) noexcept
Returns the rational reduced by the greates.
Definition: rational.h:347
constexpr Rational operator*(const Rational a, const Rational b) noexcept
Multiplication.
Definition: rational.h:567
constexpr Rational operator/(const Rational a, const Rational b) noexcept
Division.
Definition: rational.h:517