yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.0
Point.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of YODA -- Yet more Objects for Data Analysis
4// Copyright (C) 2008-2023 The YODA collaboration (see AUTHORS for details)
5//
6#ifndef YODA_POINT_H
7#define YODA_POINT_H
8
10#include "YODA/Exceptions.h"
11#include "YODA/Transformation.h"
14#include "YODA/Utils/Traits.h"
16#include "YODA/Utils/ndarray.h"
17#include <utility>
18#include <algorithm>
19#include <iostream>
20
21
22namespace YODA {
23
24
26 class Point {
27 public:
28
29 using ValuePair = std::pair<double,double>;
30
31
33 virtual ~Point() {};
34
35
38
40 virtual size_t dim() const = 0;
41
43 virtual double val(size_t i) const = 0;
44
46 virtual void setVal(const size_t i, const double val) = 0;
47
49
50
53
55 //virtual const std::pair<double,double>& errs(size_t i) const = 0;
57 virtual void setErr(const size_t i, const double e) = 0;
58
60 virtual void setErrs(const size_t i, const double eminus, const double eplus) = 0;
61
63 virtual void setErrs(const size_t i, const std::pair<double,double>& e) = 0;
64
66 //virtual double errMinus(size_t i) const = 0;
68 virtual void setErrMinus(const size_t i, const double eminus) = 0;
69
71 //virtual double errPlus(size_t i) const = 0;
73 virtual void setErrPlus(const size_t i, const double eplus) = 0;
74
76 //virtual double errAvg(size_t i) const = 0;
77
78 // /// Get value minus negative error for direction @a i
79 // double min(size_t i) const = 0;
80 // /// Get value plus positive error for direction @a i
81 // double max(size_t i) const = 0;*/
82
84
85
88
90 virtual void set(const size_t i, const double val, const double e) = 0;
91
93 virtual void set(const size_t i, const double val, const double eminus, const double eplus) = 0;
94
96 virtual void set(const size_t i, const double val, const std::pair<double,double>& e) = 0;
97
99
100
103
104 // /// Scaling of direction @a i
105 virtual void scale(const size_t i, const double scale) = 0;
106
107 //template<typename FN>
108 //void scale(size_t i, FN f) = 0;
109
111
112 };
113
114
115
116
117
119 template<size_t N>
120 class PointBase : public Point {
121 protected:
122
123 // Convenient aliases
124 using Pair = std::pair<double,double>;
125 using ValList = std::initializer_list<double>;
126 using PairList = std::initializer_list<Pair>;
127
128 // extract the content type of an array Arr
129 template<typename Arr>
130 using containedType = std::decay_t<decltype(*std::declval<Arr>().begin())>;
131
132 // check if content type of an array Arr is Pair
133 template<typename Arr>
134 using containsPair = typename std::is_same<containedType<Arr>, Pair>;
135
136 // succeeds if T is an iterable container
137 template<typename T>
138 using isIterable = std::enable_if_t<Iterable<T>::value>;
139
140 // succeeds if T is an iterable container and its content type is Pair
141 template<typename T, typename U>
143
144 public:
145
146 // Typedefs
147 using NdVal = typename Utils::ndarray<double, N>;
148 using NdValPair = typename Utils::ndarray<std::pair<double,double>, N>;
149 using DataSize = std::integral_constant<size_t, 3*N>;
150
151
154
155 // @brief Default constructor
157 clear();
158 }
159
160
162 template <typename ValRange = ValList, typename = isIterable<ValRange>>
163 PointBase(ValRange&& val) : _val(std::forward<ValRange>(val)) { }
164
165
167 template <typename ValRange = ValList,
168 typename PairRange = PairList,
169 typename = isIterableWithPair<ValRange,PairRange>>
170 PointBase(ValRange&& val, PairRange&& errs)
171 : _val(std::forward<ValRange>(val)), _errs(std::forward<PairRange>(errs)) { }
172
174 template <typename ValRange = ValList, typename = isIterable<ValRange>>
175 PointBase(ValRange&& val, ValRange&& errs)
176 : _val(std::forward<ValRange>(val)) {
177 if (val.size() != N || errs.size() != N)
178 throw RangeError("Expected " + std::to_string(N) + " dimensions.");
179 size_t i = 0;
180 auto it = std::begin(errs);
181 const auto& itEnd = std::end(errs);
182 for (; it != itEnd; ++it) {
183 _errs[i++] = std::make_pair(*it, *it);
184 }
185 }
186
187
189 template <typename ValRange = ValList, typename = isIterable<ValRange>>
190 PointBase(ValRange&& val, ValRange&& errsdn, ValRange&& errsup)
191 : _val(std::forward<ValRange>(val)) {
192 if (val.size() != N || errsdn.size() != N || errsup.size() != N)
193 throw RangeError("Expected " + std::to_string(N) + " dimensions.");
194 size_t i = 0;
195 auto itdn = std::begin(errsdn);
196 auto itup = std::begin(errsup);
197 const auto& itEnd = std::end(errsdn);
198 for (; itdn != itEnd; ) {
199 _errs[i++] = std::make_pair(*itdn++, *itup++);
200 }
201 }
202
203 PointBase(const PointBase& p) : _val(p._val), _errs(p._errs) { }
204
205 PointBase(PointBase&& p) : _val(std::move(p._val)), _errs(std::move(p._errs)) { }
206
208
210 size_t dim() const { return N; }
211
214
215 void _renderYODA(std::ostream& os, const int width = 13) const noexcept {
216
217 for (size_t i = 0; i < N; ++i) {
218 os << std::setw(width) << std::left << _val[i] << "\t"
219 << std::setw(width) << std::left << _errs[i].first << "\t"
220 << std::setw(width) << std::left << _errs[i].second << "\t";
221 }
222 os << "\n";
223
224 }
225
227
230
232 void clear() {
233 for (size_t i = 0; i < N; ++i) {
234 _val[i] = 0;
235 _errs[i] = {0.,0.};
236 }
237 }
238
241 if (this != &p) {
242 _val = p._val;
243 _errs = p._errs;
244 }
245 return *this;
246 }
247
250 if (this != &p) {
251 _val = std::move(p._val);
252 _errs = std::move(p._errs);
253 }
254 return *this;
255 }
256
258
260
261
262 public:
263
266
268 NdVal& vals() { return _val; }
269
271 const NdVal& vals() const { return _val; }
272
274 double val(size_t i) const {
275 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
276 return _val[i];
277 }
278
280 void setVal(const NdVal& val) {
281 _val = val;
282 }
283
285 void setVal(const size_t i, const double val) {
286 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
287 _val[i] = val;
288 }
289
291
292
295
298 return _errs;
299 }
300
302 const NdValPair& errs() const {
303 return _errs;
304 }
305
307 Pair errs(const size_t i) const {
308 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
309 return _errs[i];
310 }
311
313 double errMinus(const size_t i) const {
314 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
315 return _errs[i].first;
316 }
317
319 double errPlus(const size_t i) const {
320 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
321 return _errs[i].second;
322 }
323
324 // Get the average error along axis @a i
325 double errAvg(const size_t i) const {
326 return 0.5*(errMinus(i) + errPlus(i));
327 }
328
330 double min(const size_t i) const {
331 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
332 return _val[i] - _errs[i].first;
333 }
334
336 double max(const size_t i) const {
337 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
338 return _val[i] + _errs[i].second;
339 }
340
342 void setErr(const size_t i, const double e) {
343 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
344 const double err = fabs(e);
345 _errs[i] = { err, err};
346 }
347
349 void setErrs(const size_t i, const double eminus, const double eplus) {
350 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
351 _errs[i] = { eminus, eplus};
352 }
353
355 void setErrs(const size_t i, const std::pair<double,double>& e) {
356 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
357 _errs[i] = e;
358 }
359
361 void setErrMinus(const size_t i, const double eminus) {
362 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
363 _errs[i].first = eminus;
364 }
365
367 void setErrPlus(const size_t i, const double eplus) {
368 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
369 _errs[i].second = eplus;
370 }
371
373
376
377 void set(const size_t i, const double val, const double e) {
378 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
379 const double err = fabs(e);
380 _val[i] = val;
381 _errs[i] = {err,err};
382 }
383
384 void set(const size_t i, const double val, const double eminus, const double eplus) {
385 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
386 _val[i] = val;
387 _errs[i].first = eminus;
388 _errs[i].second = eplus;
389 }
390
391 void set(const size_t i, const double val, const std::pair<double,double>& e) {
392 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
393 _val[i] = val;
394 _errs[i] = e;
395 }
396
398
401
403 void scale(const size_t i, const double scale) {
404 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
405 _val[i] *= scale;
406 _errs[i].first *= scale;
407 _errs[i].second *= scale;
408 }
409
411 void scale(const NdVal& scales) {
412 for (size_t i = 0; i < N; ++i) {
413 scale(i, scales[i]);
414 }
415 }
416
418 void scale(const Trf<N>& trf) {
419 trf.transform(_val, _errs);
420 }
421
424 void scale(const size_t i, const Trf<N>& trf) {
425 if (i >= N) throw RangeError("Invalid axis int, must be in range 0..dim-1");
426 trf.transform(_val[i], _errs[i]);
427 }
428 //
429 void transform(const size_t i, const Trf<N>& trf) {
430 scale(i, trf);
431 }
432
434
436
437
438 std::vector<double> _serializeContent() const noexcept {
439 std::vector<double> rtn;
440 rtn.reserve(DataSize::value);
441 rtn.insert(rtn.end(), _val.begin(), _val.end());
442 for (auto err : _errs) {
443 rtn.push_back(std::move(err.first));
444 rtn.push_back(std::move(err.second));
445 }
446 return rtn;
447 }
448
449 void _deserializeContent(const std::vector<double>& data) {
450
451 if (data.size() != DataSize::value)
452 throw UserError("Length of serialized data should be "+std::to_string(DataSize::value)+"!");
453
454 for (size_t i = 0; i < N; ++i) {
455 _val[i] = data[i];
456 _errs[i] = { data[N+i], data[2*N+i] };
457 }
458
459 }
460
461 // @}
462
463 protected:
464
467
468 NdVal _val;
469 NdValPair _errs;
470
472
473 };
474
475
476
479
481 template <size_t N>
482 inline bool operator==(const PointBase<N>& a, const PointBase<N>& b) {
483 // Compare valitions
484 for (size_t i = 0; i < N; ++i) {
485 if ( !fuzzyEquals(a.vals()[i], b.vals()[i]) ) return false;
486 if ( !fuzzyEquals(a.errs()[i].first, b.errs()[i].first)) return false;
487 if ( !fuzzyEquals(a.errs()[i].second, b.errs()[i].second)) return false;
488 }
489 return true;
490 }
491
493 template <size_t N>
494 inline bool operator!=(const PointBase<N>& a, const PointBase<N>& b) {
495 return !(a == b);
496 }
497
498
500 template <size_t N>
501 inline bool operator<(const PointBase<N>& a, const PointBase<N>& b) {
502 #define LT_IF_NOT_EQ(a,b) { if (!fuzzyEquals(a, b)) return a < b; }
503 for (size_t i = 0; i < N; ++i) {
504 LT_IF_NOT_EQ(a.vals()[i], b.vals()[i]);
505 LT_IF_NOT_EQ(a.errs()[i].first, b.errs()[i].first);
506 LT_IF_NOT_EQ(a.errs()[i].second, b.errs()[i].second);
507 }
508 #undef LT_IF_NOT_EQ
509 return false;
510 }
511
513 template <size_t N>
514 inline bool operator<=(const PointBase<N>& a, const PointBase<N>& b) {
515 if (a == b) return true;
516 return a < b;
517 }
518
520 template <size_t N>
521 inline bool operator>(const PointBase<N>& a, const PointBase<N>& b) {
522 return !(a <= b);
523 }
524
526 template <size_t N>
527 inline bool operator>=(const PointBase<N>& a, const PointBase<N>& b) {
528 return !(a < b);
529 }
530
532
533 template <size_t N>
534 class PointND : public PointBase<N> {
535 using BaseT = PointBase<N>;
536 using BaseT::BaseT;
537 };
538
539
540
542 template <>
543 class PointND<1> : public PointBase<1>,
544 public XDirectionMixin<PointND<1>> {
545 public:
546
548 using BaseT::BaseT;
549
552
554 PointND(double x, double ex=0.0)
555 : BaseT({x}, {{ex, ex}}) { }
556
557
559 PointND(double x, double exminus, double explus)
560 : BaseT({x}, {{exminus, explus}}) { }
561
562
564 PointND(double x, const std::pair<double,double>& ex)
565 : BaseT( {x}, {ex}) { }
566
567
569 PointND(const BaseT& other) : BaseT(other) {}
570
572 PointND(BaseT&& other) : BaseT(std::move(other)) {}
573
575
576
579
581 double val(size_t i=0) const {
582 if (i >= 1) throw RangeError("Invalid axis int, must be in range 0..dim-1");
583 return _val[i];
584 }
585
587
588 };
589
590
591
593 template <>
594 class PointND<2> : public PointBase<2>,
595 public XDirectionMixin<PointND<2>>,
596 public YDirectionMixin<PointND<2>> {
597 public:
598
600 using BaseT::BaseT;
601
604
606 PointND(double x, double y, double ex=0.0, double ey=0.0)
607 : BaseT( {x,y}, {{ex,ex}, {ey,ey}}) { }
608
609
611 PointND(double x, double y,
612 double exminus, double explus,
613 double eyminus, double eyplus)
614 : BaseT({x,y}, {{exminus,explus}, {eyminus,eyplus}}) { }
615
616
618 PointND(double x, double y, const std::pair<double,double>& ex, const std::pair<double,double>& ey)
619 : BaseT({x,y}, {ex, ey}) { }
620
621
623 PointND(const BaseT& other) : BaseT(other) { }
624
626 PointND(BaseT&& other) : BaseT(std::move(other)) { }
627
629
630
631 // @name Manipulations
633
635 void scaleXY(double scalex, double scaley) {
636 scaleX(scalex);
637 scaleY(scaley);
638 }
639
641
642 };
643
644
645
647 template <>
648 class PointND<3> : public PointBase<3>,
649 public XDirectionMixin<PointND<3>>,
650 public YDirectionMixin<PointND<3>>,
651 public ZDirectionMixin<PointND<3>> {
652 public:
653
655 using BaseT::BaseT;
656
659
661 PointND(double x, double y, double z, double ex=0.0, double ey=0.0, double ez=0.0)
662 : BaseT({x,y,z}, {{ex,ex}, {ey,ey}, {ez,ez}}) { }
663
664
666 PointND(double x, double y, double z,
667 double exminus, double explus,
668 double eyminus, double eyplus,
669 double ezminus, double ezplus)
670 : BaseT({x,y,z}, {{exminus,explus}, {eyminus,eyplus}, {ezminus,ezplus}}) { }
671
673 PointND(double x, double y, double z,
674 const std::pair<double,double>& ex,
675 const std::pair<double,double>& ey,
676 const std::pair<double,double>& ez)
677 : BaseT({x,y,z}, {ex,ey,ez}) { }
678
679
681 PointND(const BaseT& other) : BaseT(other) { }
682
684 PointND(BaseT&& other) : BaseT(std::move(other)) { }
685
687
688 // @name Manipulations
690
692 void scaleXYZ(double scalex, double scaley, double scalez) {
693 scaleX(scalex);
694 scaleY(scaley);
695 scaleZ(scalez);
696 }
697
699
700 };
701
702
708
709}
710
711#endif
#define LT_IF_NOT_EQ(a, b)
The base for an N-dimensional data point to be contained in a Scatter<N>
Definition Point.h:120
PointBase(ValRange &&val, PairRange &&errs)
Constructor from values and a set of asymmetric errors.
Definition Point.h:170
double val(size_t i) const
Get the value along direction i.
Definition Point.h:274
void scale(const size_t i, const Trf< N > &trf)
Definition Point.h:424
PointBase(PointBase &&p)
Definition Point.h:205
typename std::is_same< containedType< Arr >, Pair > containsPair
Definition Point.h:134
void scale(const Trf< N > &trf)
Generalised transformations with functors.
Definition Point.h:418
std::enable_if_t<(Iterable< T >::value &&Iterable< U >::value &&containsPair< U >::value)> isIterableWithPair
Definition Point.h:142
void setErr(const size_t i, const double e)
Set a symmetric error pair along axis i.
Definition Point.h:342
void setErrs(const size_t i, const std::pair< double, double > &e)
Set a specific error pair along axis i.
Definition Point.h:355
PointBase & operator=(const PointBase &p)
Assignment operator.
Definition Point.h:240
PointBase(ValRange &&val)
Constructor from position values without errors.
Definition Point.h:163
NdValPair & errs()
Get error values.
Definition Point.h:297
double errMinus(const size_t i) const
Get the minus error along axis i.
Definition Point.h:313
size_t dim() const
Space dimension of the point.
Definition Point.h:210
std::pair< double, double > Pair
Definition Point.h:124
std::decay_t< decltype(*std::declval< Arr >().begin())> containedType
Definition Point.h:130
typename Utils::ndarray< double, N > NdVal
Definition Point.h:147
void setVal(const NdVal &val)
Set the coordinate vector.
Definition Point.h:280
void setVal(const size_t i, const double val)
Set a specific coordinate.
Definition Point.h:285
double errPlus(const size_t i) const
Get the plus error along axis i.
Definition Point.h:319
std::integral_constant< size_t, 3 *N > DataSize
Definition Point.h:149
void set(const size_t i, const double val, const std::pair< double, double > &e)
Set value and asymmetric error for direction i.
Definition Point.h:391
std::initializer_list< double > ValList
Definition Point.h:125
void set(const size_t i, const double val, const double e)
Set value and symmetric error for direction i.
Definition Point.h:377
std::initializer_list< Pair > PairList
Definition Point.h:126
PointBase(ValRange &&val, ValRange &&errs)
Constructor from values and a set of symmetric errors.
Definition Point.h:175
const NdValPair & errs() const
Get error values (const version)
Definition Point.h:302
PointBase(const PointBase &p)
Definition Point.h:203
double errAvg(const size_t i) const
Definition Point.h:325
void setErrMinus(const size_t i, const double eminus)
Set a specific minus error along axis i.
Definition Point.h:361
std::enable_if_t< Iterable< T >::value > isIterable
Definition Point.h:138
void setErrs(const size_t i, const double eminus, const double eplus)
Set an asymmetric error pair along axis i.
Definition Point.h:349
NdVal & vals()
Get the coordinate vector.
Definition Point.h:268
void set(const size_t i, const double val, const double eminus, const double eplus)
Set value and asymmetric error for direction i.
Definition Point.h:384
void transform(const size_t i, const Trf< N > &trf)
Definition Point.h:429
void scale(const NdVal &scales)
Uniform scaling.
Definition Point.h:411
void setErrPlus(const size_t i, const double eplus)
Set a specific plus error along axis i.
Definition Point.h:367
typename Utils::ndarray< std::pair< double, double >, N > NdValPair
Definition Point.h:148
Pair errs(const size_t i) const
Get error values along axis i.
Definition Point.h:307
const NdVal & vals() const
Get the coordinate vector (const version)
Definition Point.h:271
double min(const size_t i) const
Get value minus negative error along axis i.
Definition Point.h:330
void scale(const size_t i, const double scale)
Scaling along direction i.
Definition Point.h:403
PointBase(ValRange &&val, ValRange &&errsdn, ValRange &&errsup)
Constructor from values and a set of asymmetric errors.
Definition Point.h:190
double max(const size_t i) const
Get value plus positive error along axis i.
Definition Point.h:336
void clear()
Clear the point values and errors.
Definition Point.h:232
A 1D data point to be contained in a Scatter1D.
Definition Point.h:544
PointND(BaseT &&other)
Move constructor.
Definition Point.h:572
PointND(double x, double ex=0.0)
Constructor from values with optional symmetric errors.
Definition Point.h:554
PointND(double x, double exminus, double explus)
Constructor from values with explicit asymmetric errors.
Definition Point.h:559
PointND(double x, const std::pair< double, double > &ex)
Constructor from values with asymmetric errors.
Definition Point.h:564
double val(size_t i=0) const
Get the value along direction i.
Definition Point.h:581
PointND(const BaseT &other)
Copy constructor.
Definition Point.h:569
A 2D data point to be contained in a Scatter2D.
Definition Point.h:596
PointND(double x, double y, const std::pair< double, double > &ex, const std::pair< double, double > &ey)
Constructor from values with asymmetric errors on both x and y.
Definition Point.h:618
PointND(double x, double y, double exminus, double explus, double eyminus, double eyplus)
Constructor from values with explicit asymmetric errors.
Definition Point.h:611
PointND(const BaseT &other)
Copy constructor.
Definition Point.h:623
PointND(BaseT &&other)
Move constructor.
Definition Point.h:626
void scaleXY(double scalex, double scaley)
Scaling of both axes.
Definition Point.h:635
PointND(double x, double y, double ex=0.0, double ey=0.0)
Constructor from values with optional symmetric errors.
Definition Point.h:606
A 3D data point to be contained in a Scatter3D.
Definition Point.h:651
PointND(BaseT &&other)
Move constructor.
Definition Point.h:684
PointND(double x, double y, double z, double exminus, double explus, double eyminus, double eyplus, double ezminus, double ezplus)
Constructor from values with explicit asymmetric errors.
Definition Point.h:666
PointND(const BaseT &other)
Copy constructor.
Definition Point.h:681
PointND(double x, double y, double z, double ex=0.0, double ey=0.0, double ez=0.0)
Constructor from values with optional symmetric errors.
Definition Point.h:661
PointND(double x, double y, double z, const std::pair< double, double > &ex, const std::pair< double, double > &ey, const std::pair< double, double > &ez)
Constructor from asymmetric errors given as vectors.
Definition Point.h:673
void scaleXYZ(double scalex, double scaley, double scalez)
Scaling of both axes.
Definition Point.h:692
Base class for all Point*Ds, providing generic access to their numerical properties.
Definition Point.h:26
virtual void setErrMinus(const size_t i, const double eminus)=0
Get negative error value for direction i.
virtual void set(const size_t i, const double val, const double e)=0
Set value and symmetric error for direction i.
virtual void setErrs(const size_t i, const std::pair< double, double > &e)=0
Set error pair for direction i.
virtual void scale(const size_t i, const double scale)=0
virtual void setErrPlus(const size_t i, const double eplus)=0
Get positive error value for direction i.
std::pair< double, double > ValuePair
Definition Point.h:29
virtual void setVal(const size_t i, const double val)=0
Set the point value for direction i.
virtual void setErr(const size_t i, const double e)=0
Get error values for direction i.
virtual void set(const size_t i, const double val, const double eminus, const double eplus)=0
Set value and asymmetric error for direction i.
virtual void set(const size_t i, const double val, const std::pair< double, double > &e)=0
Set value and asymmetric error for direction i.
virtual void setErrs(const size_t i, const double eminus, const double eplus)=0
Set asymmetric error for direction i.
virtual ~Point()
Virtual destructor for inheritance.
Definition Point.h:33
virtual double val(size_t i) const =0
Get the point value for direction i.
virtual size_t dim() const =0
Space dimension of the point.
Error for e.g. use of invalid bin ranges.
Definition Exceptions.h:34
void transform(double &val, Args &&... args) const
Transform value val.
Anonymous namespace to limit visibility.
bool operator<=(const PointBase< N > &a, const PointBase< N > &b)
Less-than-or-equals operator used to sort points.
Definition Point.h:514
bool operator>=(const PointBase< N > &a, const PointBase< N > &b)
Greater-than-or-equals operator used to sort points.
Definition Point.h:527
bool operator<(const PointBase< N > &a, const PointBase< N > &b)
Less-than operator used to sort points.
Definition Point.h:501
std::enable_if_t< std::is_arithmetic_v< N1 > &&std::is_arithmetic_v< N2 > &&(std::is_floating_point_v< N1 >||std::is_floating_point_v< N2 >), bool > fuzzyEquals(N1 a, N2 b, double tolerance=1e-5)
Compare two numbers for equality with a degree of fuzziness.
Definition MathUtils.h:96
bool operator>(const PointBase< N > &a, const PointBase< N > &b)
Greater-than operator used to sort points.
Definition Point.h:521
bool operator==(const PointBase< N > &a, const PointBase< N > &b)
Equality test.
Definition Point.h:482
bool operator!=(const PointBase< N > &a, const PointBase< N > &b)
Inequality test.
Definition Point.h:494
CRTP mixin introducing convenience aliases along X axis.
Definition PointUtils.h:18
CRTP mixin introducing convenience aliases along Y axis.
Definition PointUtils.h:142
CRTP mixin introducing convenience aliases along Z axis.
Definition PointUtils.h:281