40#ifndef GEO_INTERVAL_NT
41#define GEO_INTERVAL_NT
77 static void set_FPU_round_to_nearest() {
79 _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST);
81 fesetround(FE_TONEAREST);
85 static void set_FPU_round_to_upper() {
87 _MM_SET_ROUNDING_MODE(_MM_ROUND_UP);
89 fesetround(FE_UPWARD);
103 static bool sign_is_determined(Sign2 s) {
110 static bool sign_is_non_zero(Sign2 s) {
116 static Sign convert_sign(Sign2 s) {
145 control_ = x.control_;
147 void control_set(
double x) {
150 void control_negate() {
151 control_.rep().negate();
154 control_ += x.control_;
157 control_ -= x.control_;
160 control_ *= x.control_;
162 void control_check(
double inf,
double sup) {
163 typedef std::numeric_limits< double > dbl;
165 std::cerr.precision(dbl::max_digits10);
166 std::cerr <<
"inf() > sup() !!" << std::endl;
167 std::cerr <<
"inf()=" << inf << std::endl;
168 std::cerr <<
"sup()=" << sup << std::endl;
171 if(control_ < inf || control_ > sup) {
172 std::cerr.precision(dbl::max_digits10);
173 std::cerr <<
"[" << inf <<
"," << sup <<
"]"
174 <<
" " << control_.estimate() <<
":"
175 << control_.rep().length()
182 void control_set(
double x) {
191 void control_negate() {
202 void control_check(
double inf,
double sup) {
232 set_FPU_round_to_upper();
235 set_FPU_round_to_nearest();
255 intervalRU(
double l,
double u) : ln_(-l), u_(u) {
259 intervalRU(
const intervalRU& rhs) =
default;
261 intervalRU(
const expansion_nt& rhs) {
265 intervalRU& operator=(
const intervalRU& rhs) =
default;
267 intervalRU& operator=(
double rhs) {
275 intervalRU& operator=(
const expansion_nt& rhs) {
284 ln_ = -rhs.component(l-1);
285 u_ = rhs.component(l-1);
287 for(
int comp_idx=
int(l)-2; comp_idx>=0; --comp_idx) {
288 double comp = rhs.component(
index_t(comp_idx));
292 double new_u = u_ + comp;
295 u_, std::numeric_limits<double>::infinity()
309 double new_ln = ln_ - comp;
311 ln_ = std::nextafter(
312 ln_, std::numeric_limits<double>::infinity()
334 double estimate()
const {
336 return 0.5*(-ln_+u_);
339 bool is_nan()
const {
340 return !(ln_==ln_) || !(u_==u_);
345 int lz = int(ln_ == 0);
346 int ln = int(ln_ > 0);
347 int lp = int(ln_ < 0);
348 int uz = int(u_ == 0);
349 int un = int(u_ < 0);
350 int up = int(u_ > 0);
351 Sign2 result = Sign2(
360 int(result==SIGN2_ZERO && !(lz&&uz)) * SIGN2_ERROR
365 intervalRU& negate() {
372 intervalRU& operator+=(
const intervalRU &x) {
381 intervalRU& operator-=(
const intervalRU &x) {
391 intervalRU& operator*=(
const intervalRU &b) {
400 double lln = (-aln)*bln;
403 double uun = (-au)*bu;
407 double lu = (-aln)*bu;
408 double ul = au*(-bln);
411 ln_ = std::max(std::max(lln,lun),std::max(uln,uun));
412 u_ = std::max(std::max(ll,lu),std::max(ul,uu));
422 void control_check() {
425 set_FPU_round_to_nearest();
426 intervalBase::control_check(inf(),sup());
427 set_FPU_round_to_upper();
430 void control_check() {
438 inline intervalRU
operator+(
const intervalRU& a,
const intervalRU& b) {
439 intervalRU result = a;
443 inline intervalRU
operator-(
const intervalRU& a,
const intervalRU& b) {
444 intervalRU result = a;
448 inline intervalRU
operator*(
const intervalRU& a,
const intervalRU& b) {
449 intervalRU result = a;
490 intervalRN(
double l,
double u) : lb_(l), ub_(u) {
495 intervalRN(
const intervalRN& rhs) =
default;
497 intervalRN(
const expansion_nt& rhs) {
501 intervalRN& operator=(
const intervalRN& rhs) =
default;
503 intervalRN& operator=(
double rhs) {
511 intervalRN& operator=(
const expansion_nt& rhs) {
520 lb_ = rhs.component(l-1);
521 ub_ = rhs.component(l-1);
523 for(
int comp_idx=
int(l)-2; comp_idx>=0; --comp_idx) {
524 double comp = rhs.component(
index_t(comp_idx));
526 double nub = ub_ + comp;
528 ub_ = std::nextafter(
529 ub_, std::numeric_limits<double>::infinity()
537 double nlb = lb_ + comp;
539 lb_ = std::nextafter(
540 lb_, -std::numeric_limits<double>::infinity()
562 double estimate()
const {
563 return 0.5*(lb_ + ub_);
566 bool is_nan()
const {
567 return !(lb_==lb_) || !(ub_==ub_);
575 int lz = int(lb_ == 0);
576 int ln = int(lb_ < 0);
577 int lp = int(lb_ > 0);
578 int uz = int(ub_ == 0);
579 int un = int(ub_ < 0);
580 int up = int(ub_ > 0);
581 Sign2 result = Sign2(
590 int(result==SIGN2_ZERO && !(lz&&uz)) * SIGN2_ERROR
595 intervalRN& negate() {
604 intervalRN& operator+=(
const intervalRN &x) {
613 intervalRN& operator-=(
const intervalRN &x) {
622 intervalRN& operator*=(
const intervalRN &x) {
623 if(!is_nan() && !x.is_nan()) {
624 double ll = lb_*x.lb_;
625 double lu = lb_*x.ub_;
626 double ul = ub_*x.lb_;
627 double uu = ub_*x.ub_;
629 if(!(ll==ll)) ll = 0.0;
630 if(!(lu==lu)) lu = 0.0;
631 if(!(ul==ul)) ul = 0.0;
632 if(!(uu==uu)) uu = 0.0;
634 if(lu<ll) std::swap(lu, ll);
635 if(ul<ll) std::swap(ul, ll);
636 if(uu<ll) std::swap(uu, ll);
646 lb_ = std::numeric_limits<double>::quiet_NaN();
647 ub_ = std::numeric_limits<double>::quiet_NaN();
657 static constexpr double i = std::numeric_limits<double>::infinity();
658 static constexpr double e = std::numeric_limits<double>::epsilon();
660 static constexpr double m = std::numeric_limits<double>::min();
662 static constexpr double l = 1.0-e;
663 static constexpr double u = 1.0+e;
664 static constexpr double em = e*m;
666 if(lb_==lb_ && ub_==ub_ && (lb_!=ub_ || (lb_!=i && lb_!=-i))) {
688 lb_ = std::numeric_limits<double>::quiet_NaN();
689 ub_ = std::numeric_limits<double>::quiet_NaN();
694 void control_check() {
695 intervalBase::control_check(inf(),sup());
698 void control_check() {
707 inline intervalRN
operator+(
const intervalRN& a,
const intervalRN& b) {
708 intervalRN result = a;
712 inline intervalRN
operator-(
const intervalRN& a,
const intervalRN& b) {
713 intervalRN result = a;
717 inline intervalRN
operator*(
const intervalRN& a,
const intervalRN& b) {
718 intervalRN result = a;
744 intervalDummy(
double l,
double u) {
749 intervalDummy(
const intervalDummy& rhs) =
default;
751 intervalDummy(
const expansion_nt& rhs) {
755 intervalDummy& operator=(
const intervalDummy& rhs) =
default;
757 intervalDummy& operator=(
double rhs) {
762 intervalDummy& operator=(
const expansion_nt& rhs) {
768 return -std::numeric_limits<double>::infinity();
772 return std::numeric_limits<double>::infinity();
775 double estimate()
const {
776 return std::numeric_limits<double>::quiet_NaN();
779 bool is_nan()
const {
787 intervalDummy& negate() {
791 intervalDummy& operator+=(
const intervalDummy &x) {
796 intervalDummy& operator-=(
const intervalDummy &x) {
801 intervalDummy& operator*=(
const intervalDummy &x) {
808 const intervalDummy& a,
const intervalDummy& b
810 intervalDummy result = a;
815 const intervalDummy& a,
const intervalDummy& b
817 intervalDummy result = a;
822 const intervalDummy& a,
const intervalDummy& b
824 intervalDummy result = a;
830#ifdef GEO_NO_INTERVALS
831 typedef intervalDummy interval_nt;
833 typedef intervalRN interval_nt;
841 static constexpr bool value =
true;
855 det2x2(p1.x,p1.w,p2.x,p2.w),
856 det2x2(p1.y,p1.w,p2.y,p2.w),
873 det2x2(p1.x,p1.w,p2.x,p2.w),
874 det2x2(p1.y,p1.w,p2.y,p2.w),
875 det2x2(p1.z,p1.w,p2.z,p2.w),
#define geo_assert_not_reached
Sets a non reachable point in the program.
#define geo_assert(x)
Verifies that a condition is met.
Expansion_nt (expansion Number Type) is used to compute the sign of polynoms exactly.
Base class for interval arithmetics.
Dummy interval class, that does not compute anything and that always says that sign is undetermined.
Number type for interval arithmetics.
Interval arithmetics in round to upper (RU) mode.
2d vector with homogeneous coordinates
3d vector with homogeneous coordinates
High-level interface to multi-precision arithmetics.
Global Vorpaline namespace.
Quaternion operator-(const Quaternion &a, const Quaternion &b)
Computes the difference between two Quaternion.
void geo_argused(const T &)
Suppresses compiler warnings about unused parameters.
geo_index_t index_t
The type for storing and manipulating indices.
Sign
Integer constants that represent the sign of a value.
T det2x2(const T &a11, const T &a12, const T &a21, const T &a22)
Computes a two-by-two determinant.
Quaternion operator+(const Quaternion &a, const Quaternion &b)
Computes the sum of two Quaternion.
vecng< DIM, FT > operator*(const Matrix< DIM, FT > &M, const vecng< DIM, FT > &x)
Computes a matrix vector product.
Sets FPU rounding mode for using this type of interval.
Generic implementation of geometric vectors in homogeneous coordinates.