You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

325 lines
9.7 KiB

#include <implicit_point.h>
#pragma intrinsic(fabs)
int det4_filtered(double a_,
double b_,
double c_,
double d_,
double e_,
double f_,
double g_,
double h_,
double i_,
double j_,
double k_,
double l_,
double m_,
double n_,
double o_,
double p_)
{
double af = a_ * f_;
double be = b_ * e_;
double kp = k_ * p_;
double lo = l_ * o_;
double ce = c_ * e_;
double ag = a_ * g_;
double jp = j_ * p_;
double ln = l_ * n_;
double ah = a_ * h_;
double de = d_ * e_;
double jo = j_ * o_;
double kn = k_ * n_;
double bg = b_ * g_;
double cf = c_ * f_;
double ip = i_ * p_;
double lm = l_ * m_;
double df = d_ * f_;
double bh = b_ * h_;
double io = i_ * o_;
double km = k_ * m_;
double ch = c_ * h_;
double dg = d_ * g_;
double in = i_ * n_;
double jm = j_ * m_;
double d1 = af - be;
double d2 = kp - lo;
double d3 = ce - ag;
double d4 = jp - ln;
double d5 = ah - de;
double d6 = jo - kn;
double d7 = bg - cf;
double d8 = ip - lm;
double d9 = df - bh;
double d10 = io - km;
double d11 = ch - dg;
double d12 = in - jm;
double t1 = d1 * d2;
double t2 = d3 * d4;
double t3 = d5 * d6;
double t4 = d7 * d8;
double t5 = d9 * d10;
double t6 = d11 * d12;
double r12 = t1 + t2;
double r34 = t3 + t4;
double r56 = t5 + t6;
double r1234 = r12 + r34;
double r123456 = r1234 + r56;
double _tmp_fabs;
double max_var = 0.0;
if ((_tmp_fabs = fabs(a_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(b_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(c_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(d_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(e_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(f_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(g_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(h_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(i_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(j_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(k_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(l_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(m_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(n_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(o_)) > max_var) max_var = _tmp_fabs;
if ((_tmp_fabs = fabs(p_)) > max_var) max_var = _tmp_fabs;
double epsilon = max_var;
epsilon *= epsilon;
epsilon *= epsilon;
epsilon *= 1.953992523340277e-14;
if (r123456 > epsilon) return IP_Sign::POSITIVE;
if (-r123456 > epsilon) return IP_Sign::NEGATIVE;
return Filtered_Sign::UNCERTAIN;
}
int det4_interval(interval_number a_,
interval_number b_,
interval_number c_,
interval_number d_,
interval_number e_,
interval_number f_,
interval_number g_,
interval_number h_,
interval_number i_,
interval_number j_,
interval_number k_,
interval_number l_,
interval_number m_,
interval_number n_,
interval_number o_,
interval_number p_)
{
setFPUModeToRoundUP();
interval_number af(a_ * f_);
interval_number be(b_ * e_);
interval_number kp(k_ * p_);
interval_number lo(l_ * o_);
interval_number ce(c_ * e_);
interval_number ag(a_ * g_);
interval_number jp(j_ * p_);
interval_number ln(l_ * n_);
interval_number ah(a_ * h_);
interval_number de(d_ * e_);
interval_number jo(j_ * o_);
interval_number kn(k_ * n_);
interval_number bg(b_ * g_);
interval_number cf(c_ * f_);
interval_number ip(i_ * p_);
interval_number lm(l_ * m_);
interval_number df(d_ * f_);
interval_number bh(b_ * h_);
interval_number io(i_ * o_);
interval_number km(k_ * m_);
interval_number ch(c_ * h_);
interval_number dg(d_ * g_);
interval_number in(i_ * n_);
interval_number jm(j_ * m_);
interval_number d1(af - be);
interval_number d2(kp - lo);
interval_number d3(ce - ag);
interval_number d4(jp - ln);
interval_number d5(ah - de);
interval_number d6(jo - kn);
interval_number d7(bg - cf);
interval_number d8(ip - lm);
interval_number d9(df - bh);
interval_number d10(io - km);
interval_number d11(ch - dg);
interval_number d12(in - jm);
interval_number t1(d1 * d2);
interval_number t2(d3 * d4);
interval_number t3(d5 * d6);
interval_number t4(d7 * d8);
interval_number t5(d9 * d10);
interval_number t6(d11 * d12);
interval_number r12(t1 + t2);
interval_number r34(t3 + t4);
interval_number r56(t5 + t6);
interval_number r1234(r12 + r34);
interval_number r123456(r1234 + r56);
setFPUModeToRoundNEAR();
if (!r123456.signIsReliable()) return Filtered_Sign::UNCERTAIN;
return r123456.sign();
}
int det4_exact(double a_,
double b_,
double c_,
double d_,
double e_,
double f_,
double g_,
double h_,
double i_,
double j_,
double k_,
double l_,
double m_,
double n_,
double o_,
double p_)
{
expansionObject o;
double af[2];
o.Two_Prod(a_, f_, af);
double be[2];
o.Two_Prod(b_, e_, be);
double kp[2];
o.Two_Prod(k_, p_, kp);
double lo[2];
o.Two_Prod(l_, o_, lo);
double ce[2];
o.Two_Prod(c_, e_, ce);
double ag[2];
o.Two_Prod(a_, g_, ag);
double jp[2];
o.Two_Prod(j_, p_, jp);
double ln[2];
o.Two_Prod(l_, n_, ln);
double ah[2];
o.Two_Prod(a_, h_, ah);
double de[2];
o.Two_Prod(d_, e_, de);
double jo[2];
o.Two_Prod(j_, o_, jo);
double kn[2];
o.Two_Prod(k_, n_, kn);
double bg[2];
o.Two_Prod(b_, g_, bg);
double cf[2];
o.Two_Prod(c_, f_, cf);
double ip[2];
o.Two_Prod(i_, p_, ip);
double lm[2];
o.Two_Prod(l_, m_, lm);
double df[2];
o.Two_Prod(d_, f_, df);
double bh[2];
o.Two_Prod(b_, h_, bh);
double io[2];
o.Two_Prod(i_, o_, io);
double km[2];
o.Two_Prod(k_, m_, km);
double ch[2];
o.Two_Prod(c_, h_, ch);
double dg[2];
o.Two_Prod(d_, g_, dg);
double in[2];
o.Two_Prod(i_, n_, in);
double jm[2];
o.Two_Prod(j_, m_, jm);
double d1[4];
o.Two_Two_Diff(af, be, d1);
double d2[4];
o.Two_Two_Diff(kp, lo, d2);
double d3[4];
o.Two_Two_Diff(ce, ag, d3);
double d4[4];
o.Two_Two_Diff(jp, ln, d4);
double d5[4];
o.Two_Two_Diff(ah, de, d5);
double d6[4];
o.Two_Two_Diff(jo, kn, d6);
double d7[4];
o.Two_Two_Diff(bg, cf, d7);
double d8[4];
o.Two_Two_Diff(ip, lm, d8);
double d9[4];
o.Two_Two_Diff(df, bh, d9);
double d10[4];
o.Two_Two_Diff(io, km, d10);
double d11[4];
o.Two_Two_Diff(ch, dg, d11);
double d12[4];
o.Two_Two_Diff(in, jm, d12);
double t1[32];
int t1_len = o.Gen_Product(4, d1, 4, d2, t1);
double t2[32];
int t2_len = o.Gen_Product(4, d3, 4, d4, t2);
double t3[32];
int t3_len = o.Gen_Product(4, d5, 4, d6, t3);
double t4[32];
int t4_len = o.Gen_Product(4, d7, 4, d8, t4);
double t5[32];
int t5_len = o.Gen_Product(4, d9, 4, d10, t5);
double t6[32];
int t6_len = o.Gen_Product(4, d11, 4, d12, t6);
double r12[64];
int r12_len = o.Gen_Sum(t1_len, t1, t2_len, t2, r12);
double r34[64];
int r34_len = o.Gen_Sum(t3_len, t3, t4_len, t4, r34);
double r56[64];
int r56_len = o.Gen_Sum(t5_len, t5, t6_len, t6, r56);
double r1234[128];
int r1234_len = o.Gen_Sum(r12_len, r12, r34_len, r34, r1234);
double r123456_p[128], *r123456 = r123456_p;
int r123456_len = o.Gen_Sum_With_PreAlloc(r1234_len, r1234, r56_len, r56, &r123456, 128);
double return_value = r123456[r123456_len - 1];
if (r123456_p != r123456) free(r123456);
if (return_value > 0) return IP_Sign::POSITIVE;
if (return_value < 0) return IP_Sign::NEGATIVE;
if (return_value == 0) return IP_Sign::ZERO;
return IP_Sign::UNDEFINED;
}
int det4(double a_,
double b_,
double c_,
double d_,
double e_,
double f_,
double g_,
double h_,
double i_,
double j_,
double k_,
double l_,
double m_,
double n_,
double o_,
double p_)
{
int ret;
#ifdef IMPLICIT_PREDICATES_STAGE_STATS
semi_static_filter_stage++;
#endif
ret = det4_filtered(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_, p_);
if (ret != Filtered_Sign::UNCERTAIN) return ret;
#ifdef IMPLICIT_PREDICATES_STAGE_STATS
interval_arithmetic_stage++;
#endif
ret = det4_interval(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_, p_);
if (ret != Filtered_Sign::UNCERTAIN) return ret;
#ifdef IMPLICIT_PREDICATES_STAGE_STATS
exact_computation_stage++;
#endif
return det4_exact(a_, b_, c_, d_, e_, f_, g_, h_, i_, j_, k_, l_, m_, n_, o_, p_);
}