Geogram Version 1.9.2
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
44
50namespace GEO {
51
59 template <class T> class rationalg {
60 public:
61 typedef T value_type;
62
63 rationalg() = default;
64
69 explicit rationalg(double x) : num_(x), denom_(1.0) {
70 }
71
76 explicit rationalg(const T& x) : num_(x), denom_(1.0) {
77 }
78
84 explicit rationalg(T&& x) : num_(x), denom_(1.0) {
85 }
86
92 explicit rationalg(double num, double denom)
93 : num_(num), denom_(denom) {
94 }
95
101 explicit rationalg(const T& num, const T& denom)
102 : num_(num), denom_(denom) {
103 }
104
111 explicit rationalg(
112 T&& num, T&& denom
113 ) : num_(num), denom_(denom) {
114 }
115
120 rationalg(const rationalg<T>& rhs) = default;
121
126 rationalg(rationalg<T>&& rhs) = default;
127
133 rationalg<T>& operator= (const rationalg<T>& rhs) = default;
134
141
146 const T& num() const {
147 return num_;
148 }
149
154 const T& denom() const {
155 return denom_;
156 }
157
162 T& num() {
163 return num_;
164 }
165
170 T& denom() {
171 return denom_;
172 }
173
182
183 /********************************************************************/
184
191 if(has_same_denom(rhs)) {
192 num_ += rhs.num_;
193 } else {
194 num_ = num_ * rhs.denom_ + rhs.num_ * denom_;
195 denom_ *= rhs.denom_;
196 }
197 return *this;
198 }
199
206 if(has_same_denom(rhs)) {
207 num_ -= rhs.num_;
208 } else {
209 num_ = num_ * rhs.denom_ - rhs.num_ * denom_;
210 denom_ *= rhs.denom_;
211 }
212 return *this;
213 }
214
221 num_ *= rhs.num_;
222 denom_ *= rhs.denom_;
223 return *this;
224 }
225
232 num_ *= rhs.denom_;
233 denom_ *= rhs.num_;
234 return *this;
235 }
236
243 num_ += denom_ * T(rhs);
244 return *this;
245 }
246
253 num_ -= denom_ * T(rhs);
254 return *this;
255 }
256
266 num_ *= T(rhs);
267 return *this;
268 }
269
279 denom_ *= T(rhs);
280 return *this;
281 }
282
283 /********************************************************************/
284
291 if(has_same_denom(rhs)) {
292 return rationalg(
293 num_ + rhs.num_,
294 denom_
295 );
296 }
297 return rationalg(
298 num_ * rhs.denom_ + rhs.num_ * denom_,
299 denom_ * rhs.denom_
300 );
301 }
302
310 if(has_same_denom(rhs)) {
311 return rationalg(
312 num_ - rhs.num_,
313 denom_
314 );
315 }
316 return rationalg(
317 num_ * rhs.denom_ - rhs.num_ * denom_,
318 denom_ * rhs.denom_
319 );
320 }
321
329 return rationalg(
330 num_ * rhs.num_,
331 denom_ * rhs.denom_
332 );
333 }
334
342 return rationalg(
343 num_ * rhs.denom_,
344 denom_ * rhs.num_
345 );
346 }
347
348
354 rationalg<T> operator+ (double rhs) const {
355 return rationalg(
356 num_ + T(rhs) * denom_,
357 denom_
358 );
359 }
360
366 rationalg<T> operator- (double rhs) const {
367 return rationalg(
368 num_ - T(rhs) * denom_,
369 denom_
370 );
371 }
372
378 rationalg<T> operator* (double rhs) const {
379 return rationalg(
380 num_ * T(rhs),
381 denom_
382 );
383 }
384
390 rationalg<T> operator/ (double rhs) const {
391 return rationalg(
392 num_,
393 denom_* T(rhs)
394 );
395 }
396
397 /********************************************************************/
398
404 return rationalg(
405 -num_,
406 denom_
407 );
408 }
409
410 /********************************************************************/
411
416 Sign sign() const {
417 geo_debug_assert(denom_.sign() != ZERO);
418 return Sign(num_.sign() * denom_.sign());
419 }
420
421 /********************************************************************/
422
427 Sign compare(const rationalg<T>& rhs) const {
428 if(sign() != rhs.sign()){
429 return Sign(sign()-rhs.sign());
430 }
431 if(has_same_denom(rhs)) {
432 return Sign(num_.compare(rhs.num_) * denom_.sign());
433 }
434 return Sign(
435 (num_ * rhs.denom_).compare(rhs.num_ * denom_) *
436 denom_.sign() * rhs.denom_.sign()
437 );
438 }
439
444 Sign compare(double rhs) const {
445 return Sign(
446 num_.compare(T(rhs)*denom_) * denom_.sign()
447 );
448 }
449
457 bool operator> (const rationalg<T>& rhs) const {
458 return (int(compare(rhs))>0);
459 }
460
468 bool operator>= (const rationalg<T>& rhs) const {
469 return (int(compare(rhs))>=0);
470 }
471
479 bool operator< (const rationalg<T>& rhs) const {
480 return (int(compare(rhs))<0);
481 }
482
490 bool operator<= (const rationalg<T>& rhs) const {
491 return (int(compare(rhs))<=0);
492 }
493
501 bool operator> (double rhs) const {
502 return (int(compare(rhs))>0);
503 }
504
512 bool operator>= (double rhs) const {
513 return (int(compare(rhs))>=0);
514 }
515
523 bool operator< (double rhs) const {
524 return (int(compare(rhs))<0);
525 }
526
534 bool operator<= (double rhs) const {
535 return (int(compare(rhs))<=0);
536 }
537
538 /********************************************************************/
539
545 double estimate() const {
546 return num_.estimate() / denom_.estimate();
547 }
548
549 protected:
554 void copy(const rationalg<T>& rhs) {
555 num_ = rhs.num_;
556 denom_ = rhs.denom_;
557 }
558
569 bool has_same_denom(const rationalg<T>& rhs) const {
570 return denom_ == rhs.denom_;
571 }
572
573 private:
574 T num_;
575 T denom_;
576 };
577
578 /**************************************************************************/
579
587 template <class T>
588 inline rationalg<T> operator+ (double a, const rationalg<T>& b) {
589 return b + a;
590 }
591
599 template <class T>
600 inline rationalg<T> operator- (double a, const rationalg<T>& b) {
601 rationalg<T> result = b - a;
602 result.num().negate();
603 return result;
604 }
605
613 template <class T>
614 inline rationalg<T> operator* (double a, const rationalg<T>& b) {
615 return b * a;
616 }
617
625 template <class T>
626 inline rationalg<T> operator/ (double a, const rationalg<T>& b) {
627 return rationalg<T>(
628 T(a)*b.denom(),
629 b.num()
630 );
631 }
632
641 template <class T>
642 inline bool operator== (const rationalg<T>& a, const rationalg<T>& b) {
643 return (a.compare(b) == ZERO);
644 }
645
654 template <class T>
655 inline bool operator== (const rationalg<T>& a, double b) {
656 return (a.compare(b) == ZERO);
657 }
658
667 template <class T>
668 inline bool operator== (double a, const rationalg<T>& b) {
669 return (b.compare(a) == ZERO);
670 }
671
680 template <class T>
681 inline bool operator!= (const rationalg<T>& a, const rationalg<T>& b) {
682 return (a.compare(b) != ZERO);
683 }
684
693 template <class T>
694 inline bool operator!= (const rationalg<T>& a, double b) {
695 return (a.compare(b) != ZERO);
696 }
697
706 template <class T>
707 inline bool operator!= (double a, const rationalg<T>& b) {
708 return (b.compare(a) != ZERO);
709 }
710
711 /**************************************************************************/
712
718 template <class T> inline Sign geo_sgn(const rationalg<T>& x) {
719 return x.sign();
720 }
721
729 template <class T> inline Sign geo_cmp(
730 const rationalg<T>& a, const rationalg<T>& b
731 ) {
732 return a.compare(b);
733 }
734
735 namespace Numeric {
736
737 template <class T> inline void optimize_number_representation(
738 rationalg<T>& x
739 ) {
740 x.optimize();
741 }
742
743 }
744
745 /**************************************************************************/
746
747}
748
749#endif
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition assert.h:196
Common include file, providing basic definitions. Should be included before anything else by all head...
rationalg (generic rational) is used to compute the sign of rational fractions exactly.
Definition rationalg.h:59
rationalg< T > operator-() const
Computes the opposite of this rationalg.
Definition rationalg.h:403
rationalg(const T &x)
Constructs a new rationalg from an T.
Definition rationalg.h:76
Sign sign() const
Gets the sign of a rationalg.
Definition rationalg.h:416
rationalg(const T &num, const T &denom)
Constructs a new rationalg from two T.
Definition rationalg.h:101
bool operator<=(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:490
bool operator>=(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:468
rationalg< T > operator*(const rationalg< T > &rhs) const
Computes the product between two rationalgs.
Definition rationalg.h:328
T & num()
gets the numerator.
Definition rationalg.h:162
rationalg< T > & operator/=(const rationalg< T > &rhs)
Divides this rationalg by a rationalg.
Definition rationalg.h:231
rationalg< T > & operator+=(const rationalg< T > &rhs)
Adds a rationalg to this rationalg.
Definition rationalg.h:190
rationalg< T > & operator*=(const rationalg< T > &rhs)
Multiplies this rationalg by a rationalg.
Definition rationalg.h:220
rationalg< T > operator/(const rationalg< T > &rhs) const
Computes the ratio between two rationalgs.
Definition rationalg.h:341
rationalg(T &&x)
Constructs a new rationalg from an T with move semantics.
Definition rationalg.h:84
const T & num() const
gets the numerator.
Definition rationalg.h:146
Sign compare(double rhs) const
Compares a rationalg with a double.
Definition rationalg.h:444
T & denom()
gets the denominator.
Definition rationalg.h:170
void copy(const rationalg< T > &rhs)
Copies a rational into this one.
Definition rationalg.h:554
rationalg< T > operator+(const rationalg< T > &rhs) const
Computes the sum of two rationalgs.
Definition rationalg.h:290
rationalg(double x)
Constructs a new rationalg from a double.
Definition rationalg.h:69
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:111
bool has_same_denom(const rationalg< T > &rhs) const
Tests whether a rationalg has trivially the same denominator this rationalg.
Definition rationalg.h:569
rationalg< T > & operator-=(const rationalg< T > &rhs)
Subtracts a rationalg to this rationalg.
Definition rationalg.h:205
Sign compare(const rationalg< T > &rhs) const
Compares two rationalg.
Definition rationalg.h:427
double estimate() const
Computes an approximation of the stored value in this rational.
Definition rationalg.h:545
rationalg(rationalg< T > &&rhs)=default
Move-constructor.
rationalg(double num, double denom)
Constructs a new rationalg from two doubles.
Definition rationalg.h:92
bool operator>(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:457
const T & denom() const
gets the denominator.
Definition rationalg.h:154
rationalg(const rationalg< T > &rhs)=default
Copy-constructor.
void optimize()
Optimizes the internal representation without changing the represented value.
Definition rationalg.h:178
bool operator<(const rationalg< T > &rhs) const
Compares this rationalg with another one.
Definition rationalg.h:479
void optimize_number_representation(T &x)
place holder for optimizing internal number representation
Definition numeric.h:267
Global Vorpaline namespace.
Definition algorithm.h:65
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:90
Sign
Integer constants that represent the sign of a value.
Definition numeric.h:68
@ ZERO
Definition numeric.h:72
Sign geo_cmp(const T &a, const T &b)
Compares two values.
Definition numeric.h:106
Quaternion operator+(const Quaternion &a, const Quaternion &b)
Computes the sum of two Quaternion.
Definition quaternion.h:239
vecng< DIM, FT > operator*(const Matrix< DIM, FT > &M, const vecng< DIM, FT > &x)
Computes a matrix vector product.
Definition matrix.h:536