Geogram Version 1.9.9
A programming library of geometric algorithms
Loading...
Searching...
No Matches
rationalg.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2023 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40#ifndef GEOGRAM_BASIC_RATIONALG
41#define GEOGRAM_BASIC_RATIONALG
42
45
51namespace GEO {
52
60 template <class T> class rationalg {
61 public:
62 typedef T value_type;
63
64 rationalg() = default;
65
70 explicit rationalg(double x) : num_(x), denom_(1.0) {
71 }
72
77 explicit rationalg(const T& x) : num_(x), denom_(1.0) {
78 }
79
85 explicit rationalg(T&& x) : num_(x), denom_(1.0) {
86 }
87
93 explicit rationalg(double num, double denom)
94 : num_(num), denom_(denom) {
95 }
96
102 explicit rationalg(const T& num, const T& denom)
103 : num_(num), denom_(denom) {
104 }
105
112 explicit rationalg(
113 T&& num, T&& denom
114 ) : num_(num), denom_(denom) {
115 }
116
121 rationalg(const rationalg<T>& rhs) = default;
122
127 rationalg(rationalg<T>&& rhs) = default;
128
134 rationalg<T>& operator= (const rationalg<T>& rhs) = default;
135
142
147 const T& num() const {
148 return num_;
149 }
150
155 const T& denom() const {
156 return denom_;
157 }
158
163 T& num() {
164 return num_;
165 }
166
171 T& denom() {
172 return denom_;
173 }
174
183
184 /********************************************************************/
185
192 if(has_same_denom(rhs)) {
193 num_ += rhs.num_;
194 } else {
195 num_ = num_ * rhs.denom_ + rhs.num_ * denom_;
196 denom_ *= rhs.denom_;
197 }
198 return *this;
199 }
200
207 if(has_same_denom(rhs)) {
208 num_ -= rhs.num_;
209 } else {
210 num_ = num_ * rhs.denom_ - rhs.num_ * denom_;
211 denom_ *= rhs.denom_;
212 }
213 return *this;
214 }
215
222 num_ *= rhs.num_;
223 denom_ *= rhs.denom_;
224 return *this;
225 }
226
233 num_ *= rhs.denom_;
234 denom_ *= rhs.num_;
235 return *this;
236 }
237
244 num_ += denom_ * T(rhs);
245 return *this;
246 }
247
254 num_ -= denom_ * T(rhs);
255 return *this;
256 }
257
267 num_ *= T(rhs);
268 return *this;
269 }
270
280 denom_ *= T(rhs);
281 return *this;
282 }
283
284 /********************************************************************/
285
292 if(has_same_denom(rhs)) {
293 return rationalg(
294 num_ + rhs.num_,
295 denom_
296 );
297 }
298 return rationalg(
299 num_ * rhs.denom_ + rhs.num_ * denom_,
300 denom_ * rhs.denom_
301 );
302 }
303
311 if(has_same_denom(rhs)) {
312 return rationalg(
313 num_ - rhs.num_,
314 denom_
315 );
316 }
317 return rationalg(
318 num_ * rhs.denom_ - rhs.num_ * denom_,
319 denom_ * rhs.denom_
320 );
321 }
322
330 return rationalg(
331 num_ * rhs.num_,
332 denom_ * rhs.denom_
333 );
334 }
335
343 return rationalg(
344 num_ * rhs.denom_,
345 denom_ * rhs.num_
346 );
347 }
348
349
355 rationalg<T> operator+ (double rhs) const {
356 return rationalg(
357 num_ + T(rhs) * denom_,
358 denom_
359 );
360 }
361
367 rationalg<T> operator- (double rhs) const {
368 return rationalg(
369 num_ - T(rhs) * denom_,
370 denom_
371 );
372 }
373
379 rationalg<T> operator* (double rhs) const {
380 return rationalg(
381 num_ * T(rhs),
382 denom_
383 );
384 }
385
391 rationalg<T> operator/ (double rhs) const {
392 return rationalg(
393 num_,
394 denom_* T(rhs)
395 );
396 }
397
398 /********************************************************************/
399
405 return rationalg(
406 -num_,
407 denom_
408 );
409 }
410
411 /********************************************************************/
412
417 Sign sign() const {
418 geo_debug_assert(denom_.sign() != ZERO);
419 return Sign(num_.sign() * denom_.sign());
420 }
421
422 /********************************************************************/
423
428 Sign compare(const rationalg<T>& rhs) const {
429 if(sign() != rhs.sign()){
430 return Sign(sign()-rhs.sign());
431 }
432 if(has_same_denom(rhs)) {
433 return Sign(num_.compare(rhs.num_) * denom_.sign());
434 }
435 return Sign(
436 (num_ * rhs.denom_).compare(rhs.num_ * denom_) *
437 denom_.sign() * rhs.denom_.sign()
438 );
439 }
440
445 Sign compare(double rhs) const {
446 return Sign(
447 num_.compare(T(rhs)*denom_) * denom_.sign()
448 );
449 }
450
458 bool operator> (const rationalg<T>& rhs) const {
459 return (int(compare(rhs))>0);
460 }
461
469 bool operator>= (const rationalg<T>& rhs) const {
470 return (int(compare(rhs))>=0);
471 }
472
480 bool operator< (const rationalg<T>& rhs) const {
481 return (int(compare(rhs))<0);
482 }
483
491 bool operator<= (const rationalg<T>& rhs) const {
492 return (int(compare(rhs))<=0);
493 }
494
502 bool operator> (double rhs) const {
503 return (int(compare(rhs))>0);
504 }
505
513 bool operator>= (double rhs) const {
514 return (int(compare(rhs))>=0);
515 }
516
524 bool operator< (double rhs) const {
525 return (int(compare(rhs))<0);
526 }
527
535 bool operator<= (double rhs) const {
536 return (int(compare(rhs))<=0);
537 }
538
539 /********************************************************************/
540
546 double estimate() const {
547 return num_.estimate() / denom_.estimate();
548 }
549
550 protected:
555 void copy(const rationalg<T>& rhs) {
556 num_ = rhs.num_;
557 denom_ = rhs.denom_;
558 }
559
570 bool has_same_denom(const rationalg<T>& rhs) const {
571 return denom_ == rhs.denom_;
572 }
573
574 private:
575 T num_;
576 T denom_;
577 };
578
579 /**************************************************************************/
580
588 template <class T>
589 inline rationalg<T> operator+ (double a, const rationalg<T>& b) {
590 return b + a;
591 }
592
600 template <class T>
601 inline rationalg<T> operator- (double a, const rationalg<T>& b) {
602 rationalg<T> result = b - a;
603 result.num().negate();
604 return result;
605 }
606
614 template <class T>
615 inline rationalg<T> operator* (double a, const rationalg<T>& b) {
616 return b * a;
617 }
618
626 template <class T>
627 inline rationalg<T> operator/ (double a, const rationalg<T>& b) {
628 return rationalg<T>(
629 T(a)*b.denom(),
630 b.num()
631 );
632 }
633
642 template <class T>
643 inline bool operator== (const rationalg<T>& a, const rationalg<T>& b) {
644 return (a.compare(b) == ZERO);
645 }
646
655 template <class T>
656 inline bool operator== (const rationalg<T>& a, double b) {
657 return (a.compare(b) == ZERO);
658 }
659
668 template <class T>
669 inline bool operator== (double a, const rationalg<T>& b) {
670 return (b.compare(a) == ZERO);
671 }
672
681 template <class T>
682 inline bool operator!= (const rationalg<T>& a, const rationalg<T>& b) {
683 return (a.compare(b) != ZERO);
684 }
685
694 template <class T>
695 inline bool operator!= (const rationalg<T>& a, double b) {
696 return (a.compare(b) != ZERO);
697 }
698
707 template <class T>
708 inline bool operator!= (double a, const rationalg<T>& b) {
709 return (b.compare(a) != ZERO);
710 }
711
712 /**************************************************************************/
713
719 template <class T> inline Sign geo_sgn(const rationalg<T>& x) {
720 return x.sign();
721 }
722
730 template <class T> inline Sign geo_cmp(
731 const rationalg<T>& a, const rationalg<T>& b
732 ) {
733 return a.compare(b);
734 }
735
736 namespace Numeric {
737
738 template <class T> inline void optimize_number_representation(
739 rationalg<T>& x
740 ) {
741 x.optimize();
742 }
743
744 }
745
746 /**************************************************************************/
747
749 template <class T> struct is_scalar<rationalg<T> > {
750 typedef rationalg<T> type;
751 static constexpr bool value = true;
752 };
753
754}
755
756#endif
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition assert.h:196
rationalg (generic rational) is used to compute the sign of rational fractions exactly.
Definition rationalg.h:60
rationalg< T > operator-() const
Computes the opposite of this rationalg.
Definition rationalg.h:404
rationalg(const T &x)
Constructs a new rationalg from an T.
Definition rationalg.h:77
Sign sign() const
Gets the sign of a rationalg.
Definition rationalg.h:417
rationalg(const T &num, const T &denom)
Constructs a new rationalg from two T.
Definition rationalg.h:102
bool operator<=(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:491
bool operator>=(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:469
rationalg< T > operator*(const rationalg< T > &rhs) const
Computes the product between two rationalgs.
Definition rationalg.h:329
T & num()
gets the numerator.
Definition rationalg.h:163
rationalg< T > & operator/=(const rationalg< T > &rhs)
Divides this rationalg by a rationalg.
Definition rationalg.h:232
rationalg< T > & operator+=(const rationalg< T > &rhs)
Adds a rationalg to this rationalg.
Definition rationalg.h:191
rationalg< T > & operator*=(const rationalg< T > &rhs)
Multiplies this rationalg by a rationalg.
Definition rationalg.h:221
rationalg< T > operator/(const rationalg< T > &rhs) const
Computes the ratio between two rationalgs.
Definition rationalg.h:342
rationalg(T &&x)
Constructs a new rationalg from an T with move semantics.
Definition rationalg.h:85
const T & num() const
gets the numerator.
Definition rationalg.h:147
Sign compare(double rhs) const
Compares a rationalg with a double.
Definition rationalg.h:445
T & denom()
gets the denominator.
Definition rationalg.h:171
void copy(const rationalg< T > &rhs)
Copies a rational into this one.
Definition rationalg.h:555
rationalg< T > operator+(const rationalg< T > &rhs) const
Computes the sum of two rationalgs.
Definition rationalg.h:291
rationalg(double x)
Constructs a new rationalg from a double.
Definition rationalg.h:70
rationalg< T > & operator=(const rationalg< T > &rhs)=default
Assignment operator.
rationalg(T &&num, T &&denom)
Constructs a new rationalg from two T with move semantics.
Definition rationalg.h:112
bool has_same_denom(const rationalg< T > &rhs) const
Tests whether a rationalg has trivially the same denominator this rationalg.
Definition rationalg.h:570
rationalg< T > & operator-=(const rationalg< T > &rhs)
Subtracts a rationalg to this rationalg.
Definition rationalg.h:206
Sign compare(const rationalg< T > &rhs) const
Compares two rationalg.
Definition rationalg.h:428
double estimate() const
Computes an approximation of the stored value in this rational.
Definition rationalg.h:546
rationalg(rationalg< T > &&rhs)=default
Move-constructor.
rationalg(double num, double denom)
Constructs a new rationalg from two doubles.
Definition rationalg.h:93
bool operator>(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:458
const T & denom() const
gets the denominator.
Definition rationalg.h:155
rationalg(const rationalg< T > &rhs)=default
Copy-constructor.
void optimize()
Optimizes the internal representation without changing the represented value.
Definition rationalg.h:179
bool operator<(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:480
Common include file, providing basic definitions. Should be included before anything else by all head...
void optimize_number_representation(T &x)
place holder for optimizing internal number representation
Definition numeric.h:268
Global Vorpaline namespace.
Definition basic.h:55
Quaternion operator-(const Quaternion &a, const Quaternion &b)
Computes the difference between two Quaternion.
Definition quaternion.h:252
Sign geo_sgn(const T &x)
Gets the sign of a value.
Definition numeric.h:107
Sign
Integer constants that represent the sign of a value.
Definition numeric.h:69
@ ZERO
Definition numeric.h:73
Sign geo_cmp(const T &a, const T &b)
Compares two values.
Definition numeric.h:89
Quaternion operator+(const Quaternion &a, const Quaternion &b)
Computes the sum of two Quaternion.
Definition quaternion.h:239
Types and functions for numbers manipulation.
type traits for scalars
Definition numeric.h:390