Chaste Release::3.1
|
00001 /*****************************************************************************/ 00002 /* */ 00003 /* Routines for Arbitrary Precision Floating-point Arithmetic */ 00004 /* and Fast Robust Geometric Predicates */ 00005 /* (predicates.c) */ 00006 /* */ 00007 /* May 18, 1996 */ 00008 /* */ 00009 /* Placed in the public domain by */ 00010 /* Jonathan Richard Shewchuk */ 00011 /* School of Computer Science */ 00012 /* Carnegie Mellon University */ 00013 /* 5000 Forbes Avenue */ 00014 /* Pittsburgh, Pennsylvania 15213-3891 */ 00015 /* jrs@cs.cmu.edu */ 00016 /* */ 00017 /* This file contains C implementation of algorithms for exact addition */ 00018 /* and multiplication of floating-point numbers, and predicates for */ 00019 /* robustly performing the orientation and incircle tests used in */ 00020 /* computational geometry. The algorithms and underlying theory are */ 00021 /* described in Jonathan Richard Shewchuk. "Adaptive Precision Floating- */ 00022 /* Point Arithmetic and Fast Robust Geometric Predicates." Technical */ 00023 /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */ 00024 /* University, Pittsburgh, Pennsylvania, May 1996. (Submitted to */ 00025 /* Discrete & Computational Geometry.) */ 00026 /* */ 00027 /* This file, the paper listed above, and other information are available */ 00028 /* from the Web page http://www.cs.cmu.edu/~quake/robust.html . */ 00029 /* */ 00030 /*****************************************************************************/ 00031 00032 /*****************************************************************************/ 00033 /* */ 00034 /* Using this code: */ 00035 /* */ 00036 /* First, read the short or long version of the paper (from the Web page */ 00037 /* above). */ 00038 /* */ 00039 /* Be sure to call exactinit() once, before calling any of the arithmetic */ 00040 /* functions or geometric predicates. Also be sure to turn on the */ 00041 /* optimizer when compiling this file. */ 00042 /* */ 00043 /* */ 00044 /* Several geometric predicates are defined. Their parameters are all */ 00045 /* points. Each point is an array of two or three floating-point */ 00046 /* numbers. The geometric predicates, described in the papers, are */ 00047 /* */ 00048 /* orient2d(pa, pb, pc) */ 00049 /* orient2dfast(pa, pb, pc) */ 00050 /* orient3d(pa, pb, pc, pd) */ 00051 /* orient3dfast(pa, pb, pc, pd) */ 00052 /* incircle(pa, pb, pc, pd) */ 00053 /* incirclefast(pa, pb, pc, pd) */ 00054 /* insphere(pa, pb, pc, pd, pe) */ 00055 /* inspherefast(pa, pb, pc, pd, pe) */ 00056 /* */ 00057 /* Those with suffix "fast" are approximate, non-robust versions. Those */ 00058 /* without the suffix are adaptive precision, robust versions. There */ 00059 /* are also versions with the suffices "exact" and "slow", which are */ 00060 /* non-adaptive, exact arithmetic versions, which I use only for timings */ 00061 /* in my arithmetic papers. */ 00062 /* */ 00063 /* */ 00064 /* An expansion is represented by an array of floating-point numbers, */ 00065 /* sorted from smallest to largest magnitude (possibly with interspersed */ 00066 /* zeros). The length of each expansion is stored as a separate integer, */ 00067 /* and each arithmetic function returns an integer which is the length */ 00068 /* of the expansion it created. */ 00069 /* */ 00070 /* Several arithmetic functions are defined. Their parameters are */ 00071 /* */ 00072 /* e, f Input expansions */ 00073 /* elen, flen Lengths of input expansions (must be >= 1) */ 00074 /* h Output expansion */ 00075 /* b Input scalar */ 00076 /* */ 00077 /* The arithmetic functions are */ 00078 /* */ 00079 /* grow_expansion(elen, e, b, h) */ 00080 /* grow_expansion_zeroelim(elen, e, b, h) */ 00081 /* expansion_sum(elen, e, flen, f, h) */ 00082 /* expansion_sum_zeroelim1(elen, e, flen, f, h) */ 00083 /* expansion_sum_zeroelim2(elen, e, flen, f, h) */ 00084 /* fast_expansion_sum(elen, e, flen, f, h) */ 00085 /* fast_expansion_sum_zeroelim(elen, e, flen, f, h) */ 00086 /* linear_expansion_sum(elen, e, flen, f, h) */ 00087 /* linear_expansion_sum_zeroelim(elen, e, flen, f, h) */ 00088 /* scale_expansion(elen, e, b, h) */ 00089 /* scale_expansion_zeroelim(elen, e, b, h) */ 00090 /* compress(elen, e, h) */ 00091 /* */ 00092 /* All of these are described in the long version of the paper; some are */ 00093 /* described in the short version. All return an integer that is the */ 00094 /* length of h. Those with suffix _zeroelim perform zero elimination, */ 00095 /* and are recommended over their counterparts. The procedure */ 00096 /* fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on */ 00097 /* processors that do not use the round-to-even tiebreaking rule) is */ 00098 /* recommended over expansion_sum_zeroelim(). Each procedure has a */ 00099 /* little note next to it (in the code below) that tells you whether or */ 00100 /* not the output expansion may be the same array as one of the input */ 00101 /* expansions. */ 00102 /* */ 00103 /* */ 00104 /* If you look around below, you'll also find macros for a bunch of */ 00105 /* simple unrolled arithmetic operations, and procedures for printing */ 00106 /* expansions (commented out because they don't work with all C */ 00107 /* compilers) and for generating random floating-point numbers whose */ 00108 /* significand bits are all random. Most of the macros have undocumented */ 00109 /* requirements that certain of their parameters should not be the same */ 00110 /* variable; for safety, better to make sure all the parameters are */ 00111 /* distinct variables. Feel free to send email to jrs@cs.cmu.edu if you */ 00112 /* have questions. */ 00113 /* */ 00114 /*****************************************************************************/ 00115 00116 #include <stdio.h> 00117 #include <stdlib.h> 00118 #include <math.h> 00119 #ifdef CPU86 00120 #include <float.h> 00121 #endif /* CPU86 */ 00122 #ifdef LINUX 00123 #include <fpu_control.h> 00124 #endif /* LINUX */ 00125 00126 #include "tetgen.h" // Defines the symbol REAL (float or double). 00127 00128 /* On some machines, the exact arithmetic routines might be defeated by the */ 00129 /* use of internal extended precision floating-point registers. Sometimes */ 00130 /* this problem can be fixed by defining certain values to be volatile, */ 00131 /* thus forcing them to be stored to memory and rounded off. This isn't */ 00132 /* a great solution, though, as it slows the arithmetic down. */ 00133 /* */ 00134 /* To try this out, write "#define INEXACT volatile" below. Normally, */ 00135 /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */ 00136 00137 #define INEXACT /* Nothing */ 00138 /* #define INEXACT volatile */ 00139 00140 /* #define REAL double */ /* float or double */ 00141 #define REALPRINT doubleprint 00142 #define REALRAND doublerand 00143 #define NARROWRAND narrowdoublerand 00144 #define UNIFORMRAND uniformdoublerand 00145 00146 /* Which of the following two methods of finding the absolute values is */ 00147 /* fastest is compiler-dependent. A few compilers can inline and optimize */ 00148 /* the fabs() call; but most will incur the overhead of a function call, */ 00149 /* which is disastrously slow. A faster way on IEEE machines might be to */ 00150 /* mask the appropriate bit, but that's difficult to do in C. */ 00151 00152 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a)) 00153 /* #define Absolute(a) fabs(a) */ 00154 00155 /* Many of the operations are broken up into two pieces, a main part that */ 00156 /* performs an approximate operation, and a "tail" that computes the */ 00157 /* roundoff error of that operation. */ 00158 /* */ 00159 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */ 00160 /* Split(), and Two_Product() are all implemented as described in the */ 00161 /* reference. Each of these macros requires certain variables to be */ 00162 /* defined in the calling routine. The variables `bvirt', `c', `abig', */ 00163 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */ 00164 /* they store the result of an operation that may incur roundoff error. */ 00165 /* The input parameter `x' (or the highest numbered `x_' parameter) must */ 00166 /* also be declared `INEXACT'. */ 00167 00168 #define Fast_Two_Sum_Tail(a, b, x, y) \ 00169 bvirt = x - a; \ 00170 y = b - bvirt 00171 00172 #define Fast_Two_Sum(a, b, x, y) \ 00173 x = (REAL) (a + b); \ 00174 Fast_Two_Sum_Tail(a, b, x, y) 00175 00176 #define Fast_Two_Diff_Tail(a, b, x, y) \ 00177 bvirt = a - x; \ 00178 y = bvirt - b 00179 00180 #define Fast_Two_Diff(a, b, x, y) \ 00181 x = (REAL) (a - b); \ 00182 Fast_Two_Diff_Tail(a, b, x, y) 00183 00184 #define Two_Sum_Tail(a, b, x, y) \ 00185 bvirt = (REAL) (x - a); \ 00186 avirt = x - bvirt; \ 00187 bround = b - bvirt; \ 00188 around = a - avirt; \ 00189 y = around + bround 00190 00191 #define Two_Sum(a, b, x, y) \ 00192 x = (REAL) (a + b); \ 00193 Two_Sum_Tail(a, b, x, y) 00194 00195 #define Two_Diff_Tail(a, b, x, y) \ 00196 bvirt = (REAL) (a - x); \ 00197 avirt = x + bvirt; \ 00198 bround = bvirt - b; \ 00199 around = a - avirt; \ 00200 y = around + bround 00201 00202 #define Two_Diff(a, b, x, y) \ 00203 x = (REAL) (a - b); \ 00204 Two_Diff_Tail(a, b, x, y) 00205 00206 #define Split(a, ahi, alo) \ 00207 c = (REAL) (splitter * a); \ 00208 abig = (REAL) (c - a); \ 00209 ahi = c - abig; \ 00210 alo = a - ahi 00211 00212 #define Two_Product_Tail(a, b, x, y) \ 00213 Split(a, ahi, alo); \ 00214 Split(b, bhi, blo); \ 00215 err1 = x - (ahi * bhi); \ 00216 err2 = err1 - (alo * bhi); \ 00217 err3 = err2 - (ahi * blo); \ 00218 y = (alo * blo) - err3 00219 00220 #define Two_Product(a, b, x, y) \ 00221 x = (REAL) (a * b); \ 00222 Two_Product_Tail(a, b, x, y) 00223 00224 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */ 00225 /* already been split. Avoids redundant splitting. */ 00226 00227 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \ 00228 x = (REAL) (a * b); \ 00229 Split(a, ahi, alo); \ 00230 err1 = x - (ahi * bhi); \ 00231 err2 = err1 - (alo * bhi); \ 00232 err3 = err2 - (ahi * blo); \ 00233 y = (alo * blo) - err3 00234 00235 /* Two_Product_2Presplit() is Two_Product() where both of the inputs have */ 00236 /* already been split. Avoids redundant splitting. */ 00237 00238 #define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ 00239 x = (REAL) (a * b); \ 00240 err1 = x - (ahi * bhi); \ 00241 err2 = err1 - (alo * bhi); \ 00242 err3 = err2 - (ahi * blo); \ 00243 y = (alo * blo) - err3 00244 00245 /* Square() can be done more quickly than Two_Product(). */ 00246 00247 #define Square_Tail(a, x, y) \ 00248 Split(a, ahi, alo); \ 00249 err1 = x - (ahi * ahi); \ 00250 err3 = err1 - ((ahi + ahi) * alo); \ 00251 y = (alo * alo) - err3 00252 00253 #define Square(a, x, y) \ 00254 x = (REAL) (a * a); \ 00255 Square_Tail(a, x, y) 00256 00257 /* Macros for summing expansions of various fixed lengths. These are all */ 00258 /* unrolled versions of Expansion_Sum(). */ 00259 00260 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \ 00261 Two_Sum(a0, b , _i, x0); \ 00262 Two_Sum(a1, _i, x2, x1) 00263 00264 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \ 00265 Two_Diff(a0, b , _i, x0); \ 00266 Two_Sum( a1, _i, x2, x1) 00267 00268 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \ 00269 Two_One_Sum(a1, a0, b0, _j, _0, x0); \ 00270 Two_One_Sum(_j, _0, b1, x3, x2, x1) 00271 00272 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \ 00273 Two_One_Diff(a1, a0, b0, _j, _0, x0); \ 00274 Two_One_Diff(_j, _0, b1, x3, x2, x1) 00275 00276 #define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \ 00277 Two_One_Sum(a1, a0, b , _j, x1, x0); \ 00278 Two_One_Sum(a3, a2, _j, x4, x3, x2) 00279 00280 #define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \ 00281 Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \ 00282 Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1) 00283 00284 #define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \ 00285 x1, x0) \ 00286 Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \ 00287 Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2) 00288 00289 #define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \ 00290 x3, x2, x1, x0) \ 00291 Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \ 00292 Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4) 00293 00294 #define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \ 00295 x6, x5, x4, x3, x2, x1, x0) \ 00296 Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \ 00297 _1, _0, x0); \ 00298 Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \ 00299 x3, x2, x1) 00300 00301 #define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \ 00302 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \ 00303 Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \ 00304 _2, _1, _0, x1, x0); \ 00305 Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \ 00306 x7, x6, x5, x4, x3, x2) 00307 00308 /* Macros for multiplying expansions of various fixed lengths. */ 00309 00310 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \ 00311 Split(b, bhi, blo); \ 00312 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ 00313 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ 00314 Two_Sum(_i, _0, _k, x1); \ 00315 Fast_Two_Sum(_j, _k, x3, x2) 00316 00317 #define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \ 00318 Split(b, bhi, blo); \ 00319 Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \ 00320 Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \ 00321 Two_Sum(_i, _0, _k, x1); \ 00322 Fast_Two_Sum(_j, _k, _i, x2); \ 00323 Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \ 00324 Two_Sum(_i, _0, _k, x3); \ 00325 Fast_Two_Sum(_j, _k, _i, x4); \ 00326 Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \ 00327 Two_Sum(_i, _0, _k, x5); \ 00328 Fast_Two_Sum(_j, _k, x7, x6) 00329 00330 #define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \ 00331 Split(a0, a0hi, a0lo); \ 00332 Split(b0, bhi, blo); \ 00333 Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \ 00334 Split(a1, a1hi, a1lo); \ 00335 Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \ 00336 Two_Sum(_i, _0, _k, _1); \ 00337 Fast_Two_Sum(_j, _k, _l, _2); \ 00338 Split(b1, bhi, blo); \ 00339 Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \ 00340 Two_Sum(_1, _0, _k, x1); \ 00341 Two_Sum(_2, _k, _j, _1); \ 00342 Two_Sum(_l, _j, _m, _2); \ 00343 Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \ 00344 Two_Sum(_i, _0, _n, _0); \ 00345 Two_Sum(_1, _0, _i, x2); \ 00346 Two_Sum(_2, _i, _k, _1); \ 00347 Two_Sum(_m, _k, _l, _2); \ 00348 Two_Sum(_j, _n, _k, _0); \ 00349 Two_Sum(_1, _0, _j, x3); \ 00350 Two_Sum(_2, _j, _i, _1); \ 00351 Two_Sum(_l, _i, _m, _2); \ 00352 Two_Sum(_1, _k, _i, x4); \ 00353 Two_Sum(_2, _i, _k, x5); \ 00354 Two_Sum(_m, _k, x7, x6) 00355 00356 /* An expansion of length two can be squared more quickly than finding the */ 00357 /* product of two different expansions of length two, and the result is */ 00358 /* guaranteed to have no more than six (rather than eight) components. */ 00359 00360 #define Two_Square(a1, a0, x5, x4, x3, x2, x1, x0) \ 00361 Square(a0, _j, x0); \ 00362 _0 = a0 + a0; \ 00363 Two_Product(a1, _0, _k, _1); \ 00364 Two_One_Sum(_k, _1, _j, _l, _2, x1); \ 00365 Square(a1, _j, _1); \ 00366 Two_Two_Sum(_j, _1, _l, _2, x5, x4, x3, x2) 00367 00368 /* splitter = 2^ceiling(p / 2) + 1. Used to split floats in half. */ 00369 static REAL splitter; 00370 static REAL epsilon; /* = 2^(-p). Used to estimate roundoff errors. */ 00371 /* A set of coefficients used to calculate maximum roundoff errors. */ 00372 static REAL resulterrbound; 00373 static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC; 00374 static REAL o3derrboundA, o3derrboundB, o3derrboundC; 00375 static REAL iccerrboundA, iccerrboundB, iccerrboundC; 00376 static REAL isperrboundA, isperrboundB, isperrboundC; 00377 00378 /*****************************************************************************/ 00379 /* */ 00380 /* doubleprint() Print the bit representation of a double. */ 00381 /* */ 00382 /* Useful for debugging exact arithmetic routines. */ 00383 /* */ 00384 /*****************************************************************************/ 00385 00386 /* 00387 void doubleprint(number) 00388 double number; 00389 { 00390 unsigned long long no; 00391 unsigned long long sign, expo; 00392 int exponent; 00393 int i, bottomi; 00394 00395 no = *(unsigned long long *) &number; 00396 sign = no & 0x8000000000000000ll; 00397 expo = (no >> 52) & 0x7ffll; 00398 exponent = (int) expo; 00399 exponent = exponent - 1023; 00400 if (sign) { 00401 printf("-"); 00402 } else { 00403 printf(" "); 00404 } 00405 if (exponent == -1023) { 00406 printf( 00407 "0.0000000000000000000000000000000000000000000000000000_ ( )"); 00408 } else { 00409 printf("1."); 00410 bottomi = -1; 00411 for (i = 0; i < 52; i++) { 00412 if (no & 0x0008000000000000ll) { 00413 printf("1"); 00414 bottomi = i; 00415 } else { 00416 printf("0"); 00417 } 00418 no <<= 1; 00419 } 00420 printf("_%d (%d)", exponent, exponent - 1 - bottomi); 00421 } 00422 } 00423 */ 00424 00425 /*****************************************************************************/ 00426 /* */ 00427 /* floatprint() Print the bit representation of a float. */ 00428 /* */ 00429 /* Useful for debugging exact arithmetic routines. */ 00430 /* */ 00431 /*****************************************************************************/ 00432 00433 /* 00434 void floatprint(number) 00435 float number; 00436 { 00437 unsigned no; 00438 unsigned sign, expo; 00439 int exponent; 00440 int i, bottomi; 00441 00442 no = *(unsigned *) &number; 00443 sign = no & 0x80000000; 00444 expo = (no >> 23) & 0xff; 00445 exponent = (int) expo; 00446 exponent = exponent - 127; 00447 if (sign) { 00448 printf("-"); 00449 } else { 00450 printf(" "); 00451 } 00452 if (exponent == -127) { 00453 printf("0.00000000000000000000000_ ( )"); 00454 } else { 00455 printf("1."); 00456 bottomi = -1; 00457 for (i = 0; i < 23; i++) { 00458 if (no & 0x00400000) { 00459 printf("1"); 00460 bottomi = i; 00461 } else { 00462 printf("0"); 00463 } 00464 no <<= 1; 00465 } 00466 printf("_%3d (%3d)", exponent, exponent - 1 - bottomi); 00467 } 00468 } 00469 */ 00470 00471 /*****************************************************************************/ 00472 /* */ 00473 /* expansion_print() Print the bit representation of an expansion. */ 00474 /* */ 00475 /* Useful for debugging exact arithmetic routines. */ 00476 /* */ 00477 /*****************************************************************************/ 00478 00479 /* 00480 void expansion_print(elen, e) 00481 int elen; 00482 REAL *e; 00483 { 00484 int i; 00485 00486 for (i = elen - 1; i >= 0; i--) { 00487 REALPRINT(e[i]); 00488 if (i > 0) { 00489 printf(" +\n"); 00490 } else { 00491 printf("\n"); 00492 } 00493 } 00494 } 00495 */ 00496 00497 /*****************************************************************************/ 00498 /* */ 00499 /* doublerand() Generate a double with random 53-bit significand and a */ 00500 /* random exponent in [0, 511]. */ 00501 /* */ 00502 /*****************************************************************************/ 00503 00504 /* 00505 double doublerand() 00506 { 00507 double result; 00508 double expo; 00509 long a, b, c; 00510 long i; 00511 00512 a = random(); 00513 b = random(); 00514 c = random(); 00515 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); 00516 for (i = 512, expo = 2; i <= 131072; i *= 2, expo = expo * expo) { 00517 if (c & i) { 00518 result *= expo; 00519 } 00520 } 00521 return result; 00522 } 00523 */ 00524 00525 /*****************************************************************************/ 00526 /* */ 00527 /* narrowdoublerand() Generate a double with random 53-bit significand */ 00528 /* and a random exponent in [0, 7]. */ 00529 /* */ 00530 /*****************************************************************************/ 00531 00532 /* 00533 double narrowdoublerand() 00534 { 00535 double result; 00536 double expo; 00537 long a, b, c; 00538 long i; 00539 00540 a = random(); 00541 b = random(); 00542 c = random(); 00543 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); 00544 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { 00545 if (c & i) { 00546 result *= expo; 00547 } 00548 } 00549 return result; 00550 } 00551 */ 00552 00553 /*****************************************************************************/ 00554 /* */ 00555 /* uniformdoublerand() Generate a double with random 53-bit significand. */ 00556 /* */ 00557 /*****************************************************************************/ 00558 00559 /* 00560 double uniformdoublerand() 00561 { 00562 double result; 00563 long a, b; 00564 00565 a = random(); 00566 b = random(); 00567 result = (double) (a - 1073741824) * 8388608.0 + (double) (b >> 8); 00568 return result; 00569 } 00570 */ 00571 00572 /*****************************************************************************/ 00573 /* */ 00574 /* floatrand() Generate a float with random 24-bit significand and a */ 00575 /* random exponent in [0, 63]. */ 00576 /* */ 00577 /*****************************************************************************/ 00578 00579 /* 00580 float floatrand() 00581 { 00582 float result; 00583 float expo; 00584 long a, c; 00585 long i; 00586 00587 a = random(); 00588 c = random(); 00589 result = (float) ((a - 1073741824) >> 6); 00590 for (i = 512, expo = 2; i <= 16384; i *= 2, expo = expo * expo) { 00591 if (c & i) { 00592 result *= expo; 00593 } 00594 } 00595 return result; 00596 } 00597 */ 00598 00599 /*****************************************************************************/ 00600 /* */ 00601 /* narrowfloatrand() Generate a float with random 24-bit significand and */ 00602 /* a random exponent in [0, 7]. */ 00603 /* */ 00604 /*****************************************************************************/ 00605 00606 /* 00607 float narrowfloatrand() 00608 { 00609 float result; 00610 float expo; 00611 long a, c; 00612 long i; 00613 00614 a = random(); 00615 c = random(); 00616 result = (float) ((a - 1073741824) >> 6); 00617 for (i = 512, expo = 2; i <= 2048; i *= 2, expo = expo * expo) { 00618 if (c & i) { 00619 result *= expo; 00620 } 00621 } 00622 return result; 00623 } 00624 */ 00625 00626 /*****************************************************************************/ 00627 /* */ 00628 /* uniformfloatrand() Generate a float with random 24-bit significand. */ 00629 /* */ 00630 /*****************************************************************************/ 00631 00632 /* 00633 float uniformfloatrand() 00634 { 00635 float result; 00636 long a; 00637 00638 a = random(); 00639 result = (float) ((a - 1073741824) >> 6); 00640 return result; 00641 } 00642 */ 00643 namespace tetgen 00644 { //Added namespace to avoid clash with triangle 00645 00646 /*****************************************************************************/ 00647 /* */ 00648 /* exactinit() Initialize the variables used for exact arithmetic. */ 00649 /* */ 00650 /* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */ 00651 /* floating-point arithmetic. `epsilon' bounds the relative roundoff */ 00652 /* error. It is used for floating-point error analysis. */ 00653 /* */ 00654 /* `splitter' is used to split floating-point numbers into two half- */ 00655 /* length significands for exact multiplication. */ 00656 /* */ 00657 /* I imagine that a highly optimizing compiler might be too smart for its */ 00658 /* own good, and somehow cause this routine to fail, if it pretends that */ 00659 /* floating-point arithmetic is too much like real arithmetic. */ 00660 /* */ 00661 /* Don't change this routine unless you fully understand it. */ 00662 /* */ 00663 /*****************************************************************************/ 00664 00665 REAL exactinit() 00666 { 00667 REAL half; 00668 REAL check, lastcheck; 00669 int every_other; 00670 #ifdef LINUX 00671 int cword; 00672 #endif /* LINUX */ 00673 00674 #ifdef CPU86 00675 #ifdef SINGLE 00676 _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */ 00677 #else /* not SINGLE */ 00678 _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */ 00679 #endif /* not SINGLE */ 00680 #endif /* CPU86 */ 00681 #ifdef LINUX 00682 #ifdef SINGLE 00683 /* cword = 4223; */ 00684 cword = 4210; /* set FPU control word for single precision */ 00685 #else /* not SINGLE */ 00686 /* cword = 4735; */ 00687 cword = 4722; /* set FPU control word for double precision */ 00688 #endif /* not SINGLE */ 00689 _FPU_SETCW(cword); 00690 #endif /* LINUX */ 00691 00692 every_other = 1; 00693 half = 0.5; 00694 epsilon = 1.0; 00695 splitter = 1.0; 00696 check = 1.0; 00697 /* Repeatedly divide `epsilon' by two until it is too small to add to */ 00698 /* one without causing roundoff. (Also check if the sum is equal to */ 00699 /* the previous sum, for machines that round up instead of using exact */ 00700 /* rounding. Not that this library will work on such machines anyway. */ 00701 do { 00702 lastcheck = check; 00703 epsilon *= half; 00704 if (every_other) { 00705 splitter *= 2.0; 00706 } 00707 every_other = !every_other; 00708 check = 1.0 + epsilon; 00709 } while ((check != 1.0) && (check != lastcheck)); 00710 splitter += 1.0; 00711 00712 /* Error bounds for orientation and incircle tests. */ 00713 resulterrbound = (3.0 + 8.0 * epsilon) * epsilon; 00714 ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon; 00715 ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon; 00716 ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon; 00717 o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon; 00718 o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon; 00719 o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon; 00720 iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon; 00721 iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon; 00722 iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon; 00723 isperrboundA = (16.0 + 224.0 * epsilon) * epsilon; 00724 isperrboundB = (5.0 + 72.0 * epsilon) * epsilon; 00725 isperrboundC = (71.0 + 1408.0 * epsilon) * epsilon * epsilon; 00726 00727 return epsilon; /* Added by H. Si 30 Juli, 2004. */ 00728 } 00729 00730 /*****************************************************************************/ 00731 /* */ 00732 /* grow_expansion() Add a scalar to an expansion. */ 00733 /* */ 00734 /* Sets h = e + b. See the long version of my paper for details. */ 00735 /* */ 00736 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 00737 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ 00738 /* properties as well. (That is, if e has one of these properties, so */ 00739 /* will h.) */ 00740 /* */ 00741 /*****************************************************************************/ 00742 00743 int grow_expansion(int elen, REAL *e, REAL b, REAL *h) 00744 /* e and h can be the same. */ 00745 { 00746 REAL Q; 00747 INEXACT REAL Qnew; 00748 int eindex; 00749 REAL enow; 00750 INEXACT REAL bvirt; 00751 REAL avirt, bround, around; 00752 00753 Q = b; 00754 for (eindex = 0; eindex < elen; eindex++) { 00755 enow = e[eindex]; 00756 Two_Sum(Q, enow, Qnew, h[eindex]); 00757 Q = Qnew; 00758 } 00759 h[eindex] = Q; 00760 return eindex + 1; 00761 } 00762 00763 /*****************************************************************************/ 00764 /* */ 00765 /* grow_expansion_zeroelim() Add a scalar to an expansion, eliminating */ 00766 /* zero components from the output expansion. */ 00767 /* */ 00768 /* Sets h = e + b. See the long version of my paper for details. */ 00769 /* */ 00770 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 00771 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ 00772 /* properties as well. (That is, if e has one of these properties, so */ 00773 /* will h.) */ 00774 /* */ 00775 /*****************************************************************************/ 00776 00777 int grow_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) 00778 /* e and h can be the same. */ 00779 { 00780 REAL Q, hh; 00781 INEXACT REAL Qnew; 00782 int eindex, hindex; 00783 REAL enow; 00784 INEXACT REAL bvirt; 00785 REAL avirt, bround, around; 00786 00787 hindex = 0; 00788 Q = b; 00789 for (eindex = 0; eindex < elen; eindex++) { 00790 enow = e[eindex]; 00791 Two_Sum(Q, enow, Qnew, hh); 00792 Q = Qnew; 00793 if (hh != 0.0) { 00794 h[hindex++] = hh; 00795 } 00796 } 00797 if ((Q != 0.0) || (hindex == 0)) { 00798 h[hindex++] = Q; 00799 } 00800 return hindex; 00801 } 00802 00803 /*****************************************************************************/ 00804 /* */ 00805 /* expansion_sum() Sum two expansions. */ 00806 /* */ 00807 /* Sets h = e + f. See the long version of my paper for details. */ 00808 /* */ 00809 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 00810 /* with IEEE 754), maintains the nonadjacent property as well. (That is, */ 00811 /* if e has one of these properties, so will h.) Does NOT maintain the */ 00812 /* strongly nonoverlapping property. */ 00813 /* */ 00814 /*****************************************************************************/ 00815 00816 int expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) 00817 /* e and h can be the same, but f and h cannot. */ 00818 { 00819 REAL Q; 00820 INEXACT REAL Qnew; 00821 int findex, hindex, hlast; 00822 REAL hnow; 00823 INEXACT REAL bvirt; 00824 REAL avirt, bround, around; 00825 00826 Q = f[0]; 00827 for (hindex = 0; hindex < elen; hindex++) { 00828 hnow = e[hindex]; 00829 Two_Sum(Q, hnow, Qnew, h[hindex]); 00830 Q = Qnew; 00831 } 00832 h[hindex] = Q; 00833 hlast = hindex; 00834 for (findex = 1; findex < flen; findex++) { 00835 Q = f[findex]; 00836 for (hindex = findex; hindex <= hlast; hindex++) { 00837 hnow = h[hindex]; 00838 Two_Sum(Q, hnow, Qnew, h[hindex]); 00839 Q = Qnew; 00840 } 00841 h[++hlast] = Q; 00842 } 00843 return hlast + 1; 00844 } 00845 00846 /*****************************************************************************/ 00847 /* */ 00848 /* expansion_sum_zeroelim1() Sum two expansions, eliminating zero */ 00849 /* components from the output expansion. */ 00850 /* */ 00851 /* Sets h = e + f. See the long version of my paper for details. */ 00852 /* */ 00853 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 00854 /* with IEEE 754), maintains the nonadjacent property as well. (That is, */ 00855 /* if e has one of these properties, so will h.) Does NOT maintain the */ 00856 /* strongly nonoverlapping property. */ 00857 /* */ 00858 /*****************************************************************************/ 00859 00860 int expansion_sum_zeroelim1(int elen, REAL *e, int flen, REAL *f, REAL *h) 00861 /* e and h can be the same, but f and h cannot. */ 00862 { 00863 REAL Q; 00864 INEXACT REAL Qnew; 00865 int index, findex, hindex, hlast; 00866 REAL hnow; 00867 INEXACT REAL bvirt; 00868 REAL avirt, bround, around; 00869 00870 Q = f[0]; 00871 for (hindex = 0; hindex < elen; hindex++) { 00872 hnow = e[hindex]; 00873 Two_Sum(Q, hnow, Qnew, h[hindex]); 00874 Q = Qnew; 00875 } 00876 h[hindex] = Q; 00877 hlast = hindex; 00878 for (findex = 1; findex < flen; findex++) { 00879 Q = f[findex]; 00880 for (hindex = findex; hindex <= hlast; hindex++) { 00881 hnow = h[hindex]; 00882 Two_Sum(Q, hnow, Qnew, h[hindex]); 00883 Q = Qnew; 00884 } 00885 h[++hlast] = Q; 00886 } 00887 hindex = -1; 00888 for (index = 0; index <= hlast; index++) { 00889 hnow = h[index]; 00890 if (hnow != 0.0) { 00891 h[++hindex] = hnow; 00892 } 00893 } 00894 if (hindex == -1) { 00895 return 1; 00896 } else { 00897 return hindex + 1; 00898 } 00899 } 00900 00901 /*****************************************************************************/ 00902 /* */ 00903 /* expansion_sum_zeroelim2() Sum two expansions, eliminating zero */ 00904 /* components from the output expansion. */ 00905 /* */ 00906 /* Sets h = e + f. See the long version of my paper for details. */ 00907 /* */ 00908 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 00909 /* with IEEE 754), maintains the nonadjacent property as well. (That is, */ 00910 /* if e has one of these properties, so will h.) Does NOT maintain the */ 00911 /* strongly nonoverlapping property. */ 00912 /* */ 00913 /*****************************************************************************/ 00914 00915 int expansion_sum_zeroelim2(int elen, REAL *e, int flen, REAL *f, REAL *h) 00916 /* e and h can be the same, but f and h cannot. */ 00917 { 00918 REAL Q, hh; 00919 INEXACT REAL Qnew; 00920 int eindex, findex, hindex, hlast; 00921 REAL enow; 00922 INEXACT REAL bvirt; 00923 REAL avirt, bround, around; 00924 00925 hindex = 0; 00926 Q = f[0]; 00927 for (eindex = 0; eindex < elen; eindex++) { 00928 enow = e[eindex]; 00929 Two_Sum(Q, enow, Qnew, hh); 00930 Q = Qnew; 00931 if (hh != 0.0) { 00932 h[hindex++] = hh; 00933 } 00934 } 00935 h[hindex] = Q; 00936 hlast = hindex; 00937 for (findex = 1; findex < flen; findex++) { 00938 hindex = 0; 00939 Q = f[findex]; 00940 for (eindex = 0; eindex <= hlast; eindex++) { 00941 enow = h[eindex]; 00942 Two_Sum(Q, enow, Qnew, hh); 00943 Q = Qnew; 00944 if (hh != 0) { 00945 h[hindex++] = hh; 00946 } 00947 } 00948 h[hindex] = Q; 00949 hlast = hindex; 00950 } 00951 return hlast + 1; 00952 } 00953 00954 /*****************************************************************************/ 00955 /* */ 00956 /* fast_expansion_sum() Sum two expansions. */ 00957 /* */ 00958 /* Sets h = e + f. See the long version of my paper for details. */ 00959 /* */ 00960 /* If round-to-even is used (as with IEEE 754), maintains the strongly */ 00961 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ 00962 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ 00963 /* properties. */ 00964 /* */ 00965 /*****************************************************************************/ 00966 00967 int fast_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) 00968 /* h cannot be e or f. */ 00969 { 00970 REAL Q; 00971 INEXACT REAL Qnew; 00972 INEXACT REAL bvirt; 00973 REAL avirt, bround, around; 00974 int eindex, findex, hindex; 00975 REAL enow, fnow; 00976 00977 enow = e[0]; 00978 fnow = f[0]; 00979 eindex = findex = 0; 00980 if ((fnow > enow) == (fnow > -enow)) { 00981 Q = enow; 00982 enow = e[++eindex]; 00983 } else { 00984 Q = fnow; 00985 fnow = f[++findex]; 00986 } 00987 hindex = 0; 00988 if ((eindex < elen) && (findex < flen)) { 00989 if ((fnow > enow) == (fnow > -enow)) { 00990 Fast_Two_Sum(enow, Q, Qnew, h[0]); 00991 enow = e[++eindex]; 00992 } else { 00993 Fast_Two_Sum(fnow, Q, Qnew, h[0]); 00994 fnow = f[++findex]; 00995 } 00996 Q = Qnew; 00997 hindex = 1; 00998 while ((eindex < elen) && (findex < flen)) { 00999 if ((fnow > enow) == (fnow > -enow)) { 01000 Two_Sum(Q, enow, Qnew, h[hindex]); 01001 enow = e[++eindex]; 01002 } else { 01003 Two_Sum(Q, fnow, Qnew, h[hindex]); 01004 fnow = f[++findex]; 01005 } 01006 Q = Qnew; 01007 hindex++; 01008 } 01009 } 01010 while (eindex < elen) { 01011 Two_Sum(Q, enow, Qnew, h[hindex]); 01012 enow = e[++eindex]; 01013 Q = Qnew; 01014 hindex++; 01015 } 01016 while (findex < flen) { 01017 Two_Sum(Q, fnow, Qnew, h[hindex]); 01018 fnow = f[++findex]; 01019 Q = Qnew; 01020 hindex++; 01021 } 01022 h[hindex] = Q; 01023 return hindex + 1; 01024 } 01025 01026 /*****************************************************************************/ 01027 /* */ 01028 /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ 01029 /* components from the output expansion. */ 01030 /* */ 01031 /* Sets h = e + f. See the long version of my paper for details. */ 01032 /* */ 01033 /* If round-to-even is used (as with IEEE 754), maintains the strongly */ 01034 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */ 01035 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */ 01036 /* properties. */ 01037 /* */ 01038 /*****************************************************************************/ 01039 01040 int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h) 01041 /* h cannot be e or f. */ 01042 { 01043 REAL Q; 01044 INEXACT REAL Qnew; 01045 INEXACT REAL hh; 01046 INEXACT REAL bvirt; 01047 REAL avirt, bround, around; 01048 int eindex, findex, hindex; 01049 REAL enow, fnow; 01050 01051 enow = e[0]; 01052 fnow = f[0]; 01053 eindex = findex = 0; 01054 if ((fnow > enow) == (fnow > -enow)) { 01055 Q = enow; 01056 enow = e[++eindex]; 01057 } else { 01058 Q = fnow; 01059 fnow = f[++findex]; 01060 } 01061 hindex = 0; 01062 if ((eindex < elen) && (findex < flen)) { 01063 if ((fnow > enow) == (fnow > -enow)) { 01064 Fast_Two_Sum(enow, Q, Qnew, hh); 01065 enow = e[++eindex]; 01066 } else { 01067 Fast_Two_Sum(fnow, Q, Qnew, hh); 01068 fnow = f[++findex]; 01069 } 01070 Q = Qnew; 01071 if (hh != 0.0) { 01072 h[hindex++] = hh; 01073 } 01074 while ((eindex < elen) && (findex < flen)) { 01075 if ((fnow > enow) == (fnow > -enow)) { 01076 Two_Sum(Q, enow, Qnew, hh); 01077 enow = e[++eindex]; 01078 } else { 01079 Two_Sum(Q, fnow, Qnew, hh); 01080 fnow = f[++findex]; 01081 } 01082 Q = Qnew; 01083 if (hh != 0.0) { 01084 h[hindex++] = hh; 01085 } 01086 } 01087 } 01088 while (eindex < elen) { 01089 Two_Sum(Q, enow, Qnew, hh); 01090 enow = e[++eindex]; 01091 Q = Qnew; 01092 if (hh != 0.0) { 01093 h[hindex++] = hh; 01094 } 01095 } 01096 while (findex < flen) { 01097 Two_Sum(Q, fnow, Qnew, hh); 01098 fnow = f[++findex]; 01099 Q = Qnew; 01100 if (hh != 0.0) { 01101 h[hindex++] = hh; 01102 } 01103 } 01104 if ((Q != 0.0) || (hindex == 0)) { 01105 h[hindex++] = Q; 01106 } 01107 return hindex; 01108 } 01109 01110 /*****************************************************************************/ 01111 /* */ 01112 /* linear_expansion_sum() Sum two expansions. */ 01113 /* */ 01114 /* Sets h = e + f. See either version of my paper for details. */ 01115 /* */ 01116 /* Maintains the nonoverlapping property. (That is, if e is */ 01117 /* nonoverlapping, h will be also.) */ 01118 /* */ 01119 /*****************************************************************************/ 01120 01121 int linear_expansion_sum(int elen, REAL *e, int flen, REAL *f, REAL *h) 01122 /* h cannot be e or f. */ 01123 { 01124 REAL Q, q; 01125 INEXACT REAL Qnew; 01126 INEXACT REAL R; 01127 INEXACT REAL bvirt; 01128 REAL avirt, bround, around; 01129 int eindex, findex, hindex; 01130 REAL enow, fnow; 01131 REAL g0; 01132 01133 enow = e[0]; 01134 fnow = f[0]; 01135 eindex = findex = 0; 01136 if ((fnow > enow) == (fnow > -enow)) { 01137 g0 = enow; 01138 enow = e[++eindex]; 01139 } else { 01140 g0 = fnow; 01141 fnow = f[++findex]; 01142 } 01143 if ((eindex < elen) && ((findex >= flen) 01144 || ((fnow > enow) == (fnow > -enow)))) { 01145 Fast_Two_Sum(enow, g0, Qnew, q); 01146 enow = e[++eindex]; 01147 } else { 01148 Fast_Two_Sum(fnow, g0, Qnew, q); 01149 fnow = f[++findex]; 01150 } 01151 Q = Qnew; 01152 for (hindex = 0; hindex < elen + flen - 2; hindex++) { 01153 if ((eindex < elen) && ((findex >= flen) 01154 || ((fnow > enow) == (fnow > -enow)))) { 01155 Fast_Two_Sum(enow, q, R, h[hindex]); 01156 enow = e[++eindex]; 01157 } else { 01158 Fast_Two_Sum(fnow, q, R, h[hindex]); 01159 fnow = f[++findex]; 01160 } 01161 Two_Sum(Q, R, Qnew, q); 01162 Q = Qnew; 01163 } 01164 h[hindex] = q; 01165 h[hindex + 1] = Q; 01166 return hindex + 2; 01167 } 01168 01169 /*****************************************************************************/ 01170 /* */ 01171 /* linear_expansion_sum_zeroelim() Sum two expansions, eliminating zero */ 01172 /* components from the output expansion. */ 01173 /* */ 01174 /* Sets h = e + f. See either version of my paper for details. */ 01175 /* */ 01176 /* Maintains the nonoverlapping property. (That is, if e is */ 01177 /* nonoverlapping, h will be also.) */ 01178 /* */ 01179 /*****************************************************************************/ 01180 01181 int linear_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, 01182 REAL *h) 01183 /* h cannot be e or f. */ 01184 { 01185 REAL Q, q, hh; 01186 INEXACT REAL Qnew; 01187 INEXACT REAL R; 01188 INEXACT REAL bvirt; 01189 REAL avirt, bround, around; 01190 int eindex, findex, hindex; 01191 int count; 01192 REAL enow, fnow; 01193 REAL g0; 01194 01195 enow = e[0]; 01196 fnow = f[0]; 01197 eindex = findex = 0; 01198 hindex = 0; 01199 if ((fnow > enow) == (fnow > -enow)) { 01200 g0 = enow; 01201 enow = e[++eindex]; 01202 } else { 01203 g0 = fnow; 01204 fnow = f[++findex]; 01205 } 01206 if ((eindex < elen) && ((findex >= flen) 01207 || ((fnow > enow) == (fnow > -enow)))) { 01208 Fast_Two_Sum(enow, g0, Qnew, q); 01209 enow = e[++eindex]; 01210 } else { 01211 Fast_Two_Sum(fnow, g0, Qnew, q); 01212 fnow = f[++findex]; 01213 } 01214 Q = Qnew; 01215 for (count = 2; count < elen + flen; count++) { 01216 if ((eindex < elen) && ((findex >= flen) 01217 || ((fnow > enow) == (fnow > -enow)))) { 01218 Fast_Two_Sum(enow, q, R, hh); 01219 enow = e[++eindex]; 01220 } else { 01221 Fast_Two_Sum(fnow, q, R, hh); 01222 fnow = f[++findex]; 01223 } 01224 Two_Sum(Q, R, Qnew, q); 01225 Q = Qnew; 01226 if (hh != 0) { 01227 h[hindex++] = hh; 01228 } 01229 } 01230 if (q != 0) { 01231 h[hindex++] = q; 01232 } 01233 if ((Q != 0.0) || (hindex == 0)) { 01234 h[hindex++] = Q; 01235 } 01236 return hindex; 01237 } 01238 01239 /*****************************************************************************/ 01240 /* */ 01241 /* scale_expansion() Multiply an expansion by a scalar. */ 01242 /* */ 01243 /* Sets h = be. See either version of my paper for details. */ 01244 /* */ 01245 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 01246 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ 01247 /* properties as well. (That is, if e has one of these properties, so */ 01248 /* will h.) */ 01249 /* */ 01250 /*****************************************************************************/ 01251 01252 int scale_expansion(int elen, REAL *e, REAL b, REAL *h) 01253 /* e and h cannot be the same. */ 01254 { 01255 INEXACT REAL Q; 01256 INEXACT REAL sum; 01257 INEXACT REAL product1; 01258 REAL product0; 01259 int eindex, hindex; 01260 REAL enow; 01261 INEXACT REAL bvirt; 01262 REAL avirt, bround, around; 01263 INEXACT REAL c; 01264 INEXACT REAL abig; 01265 REAL ahi, alo, bhi, blo; 01266 REAL err1, err2, err3; 01267 01268 Split(b, bhi, blo); 01269 Two_Product_Presplit(e[0], b, bhi, blo, Q, h[0]); 01270 hindex = 1; 01271 for (eindex = 1; eindex < elen; eindex++) { 01272 enow = e[eindex]; 01273 Two_Product_Presplit(enow, b, bhi, blo, product1, product0); 01274 Two_Sum(Q, product0, sum, h[hindex]); 01275 hindex++; 01276 Two_Sum(product1, sum, Q, h[hindex]); 01277 hindex++; 01278 } 01279 h[hindex] = Q; 01280 return elen + elen; 01281 } 01282 01283 /*****************************************************************************/ 01284 /* */ 01285 /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */ 01286 /* eliminating zero components from the */ 01287 /* output expansion. */ 01288 /* */ 01289 /* Sets h = be. See either version of my paper for details. */ 01290 /* */ 01291 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 01292 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */ 01293 /* properties as well. (That is, if e has one of these properties, so */ 01294 /* will h.) */ 01295 /* */ 01296 /*****************************************************************************/ 01297 01298 int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h) 01299 /* e and h cannot be the same. */ 01300 { 01301 INEXACT REAL Q, sum; 01302 REAL hh; 01303 INEXACT REAL product1; 01304 REAL product0; 01305 int eindex, hindex; 01306 REAL enow; 01307 INEXACT REAL bvirt; 01308 REAL avirt, bround, around; 01309 INEXACT REAL c; 01310 INEXACT REAL abig; 01311 REAL ahi, alo, bhi, blo; 01312 REAL err1, err2, err3; 01313 01314 Split(b, bhi, blo); 01315 Two_Product_Presplit(e[0], b, bhi, blo, Q, hh); 01316 hindex = 0; 01317 if (hh != 0) { 01318 h[hindex++] = hh; 01319 } 01320 for (eindex = 1; eindex < elen; eindex++) { 01321 enow = e[eindex]; 01322 Two_Product_Presplit(enow, b, bhi, blo, product1, product0); 01323 Two_Sum(Q, product0, sum, hh); 01324 if (hh != 0) { 01325 h[hindex++] = hh; 01326 } 01327 Fast_Two_Sum(product1, sum, Q, hh); 01328 if (hh != 0) { 01329 h[hindex++] = hh; 01330 } 01331 } 01332 if ((Q != 0.0) || (hindex == 0)) { 01333 h[hindex++] = Q; 01334 } 01335 return hindex; 01336 } 01337 01338 /*****************************************************************************/ 01339 /* */ 01340 /* compress() Compress an expansion. */ 01341 /* */ 01342 /* See the long version of my paper for details. */ 01343 /* */ 01344 /* Maintains the nonoverlapping property. If round-to-even is used (as */ 01345 /* with IEEE 754), then any nonoverlapping expansion is converted to a */ 01346 /* nonadjacent expansion. */ 01347 /* */ 01348 /*****************************************************************************/ 01349 01350 int compress(int elen, REAL *e, REAL *h) 01351 /* e and h may be the same. */ 01352 { 01353 REAL Q, q; 01354 INEXACT REAL Qnew; 01355 int eindex, hindex; 01356 INEXACT REAL bvirt; 01357 REAL enow, hnow; 01358 int top, bottom; 01359 01360 bottom = elen - 1; 01361 Q = e[bottom]; 01362 for (eindex = elen - 2; eindex >= 0; eindex--) { 01363 enow = e[eindex]; 01364 Fast_Two_Sum(Q, enow, Qnew, q); 01365 if (q != 0) { 01366 h[bottom--] = Qnew; 01367 Q = q; 01368 } else { 01369 Q = Qnew; 01370 } 01371 } 01372 top = 0; 01373 for (hindex = bottom + 1; hindex < elen; hindex++) { 01374 hnow = h[hindex]; 01375 Fast_Two_Sum(hnow, Q, Qnew, q); 01376 if (q != 0) { 01377 h[top++] = q; 01378 } 01379 Q = Qnew; 01380 } 01381 h[top] = Q; 01382 return top + 1; 01383 } 01384 01385 /*****************************************************************************/ 01386 /* */ 01387 /* estimate() Produce a one-word estimate of an expansion's value. */ 01388 /* */ 01389 /* See either version of my paper for details. */ 01390 /* */ 01391 /*****************************************************************************/ 01392 01393 REAL estimate(int elen, REAL *e) 01394 { 01395 REAL Q; 01396 int eindex; 01397 01398 Q = e[0]; 01399 for (eindex = 1; eindex < elen; eindex++) { 01400 Q += e[eindex]; 01401 } 01402 return Q; 01403 } 01404 01405 /*****************************************************************************/ 01406 /* */ 01407 /* orient2dfast() Approximate 2D orientation test. Nonrobust. */ 01408 /* orient2dexact() Exact 2D orientation test. Robust. */ 01409 /* orient2dslow() Another exact 2D orientation test. Robust. */ 01410 /* orient2d() Adaptive exact 2D orientation test. Robust. */ 01411 /* */ 01412 /* Return a positive value if the points pa, pb, and pc occur */ 01413 /* in counterclockwise order; a negative value if they occur */ 01414 /* in clockwise order; and zero if they are collinear. The */ 01415 /* result is also a rough approximation of twice the signed */ 01416 /* area of the triangle defined by the three points. */ 01417 /* */ 01418 /* Only the first and last routine should be used; the middle two are for */ 01419 /* timings. */ 01420 /* */ 01421 /* The last three use exact arithmetic to ensure a correct answer. The */ 01422 /* result returned is the determinant of a matrix. In orient2d() only, */ 01423 /* this determinant is computed adaptively, in the sense that exact */ 01424 /* arithmetic is used only to the degree it is needed to ensure that the */ 01425 /* returned value has the correct sign. Hence, orient2d() is usually quite */ 01426 /* fast, but will run more slowly when the input points are collinear or */ 01427 /* nearly so. */ 01428 /* */ 01429 /*****************************************************************************/ 01430 01431 REAL orient2dfast(REAL *pa, REAL *pb, REAL *pc) 01432 { 01433 REAL acx, bcx, acy, bcy; 01434 01435 acx = pa[0] - pc[0]; 01436 bcx = pb[0] - pc[0]; 01437 acy = pa[1] - pc[1]; 01438 bcy = pb[1] - pc[1]; 01439 return acx * bcy - acy * bcx; 01440 } 01441 01442 REAL orient2dexact(REAL *pa, REAL *pb, REAL *pc) 01443 { 01444 INEXACT REAL axby1, axcy1, bxcy1, bxay1, cxay1, cxby1; 01445 REAL axby0, axcy0, bxcy0, bxay0, cxay0, cxby0; 01446 REAL aterms[4], bterms[4], cterms[4]; 01447 INEXACT REAL aterms3, bterms3, cterms3; 01448 REAL v[8], w[12]; 01449 int vlength, wlength; 01450 01451 INEXACT REAL bvirt; 01452 REAL avirt, bround, around; 01453 INEXACT REAL c; 01454 INEXACT REAL abig; 01455 REAL ahi, alo, bhi, blo; 01456 REAL err1, err2, err3; 01457 INEXACT REAL _i, _j; 01458 REAL _0; 01459 01460 Two_Product(pa[0], pb[1], axby1, axby0); 01461 Two_Product(pa[0], pc[1], axcy1, axcy0); 01462 Two_Two_Diff(axby1, axby0, axcy1, axcy0, 01463 aterms3, aterms[2], aterms[1], aterms[0]); 01464 aterms[3] = aterms3; 01465 01466 Two_Product(pb[0], pc[1], bxcy1, bxcy0); 01467 Two_Product(pb[0], pa[1], bxay1, bxay0); 01468 Two_Two_Diff(bxcy1, bxcy0, bxay1, bxay0, 01469 bterms3, bterms[2], bterms[1], bterms[0]); 01470 bterms[3] = bterms3; 01471 01472 Two_Product(pc[0], pa[1], cxay1, cxay0); 01473 Two_Product(pc[0], pb[1], cxby1, cxby0); 01474 Two_Two_Diff(cxay1, cxay0, cxby1, cxby0, 01475 cterms3, cterms[2], cterms[1], cterms[0]); 01476 cterms[3] = cterms3; 01477 01478 vlength = fast_expansion_sum_zeroelim(4, aterms, 4, bterms, v); 01479 wlength = fast_expansion_sum_zeroelim(vlength, v, 4, cterms, w); 01480 01481 return w[wlength - 1]; 01482 } 01483 01484 REAL orient2dslow(REAL *pa, REAL *pb, REAL *pc) 01485 { 01486 INEXACT REAL acx, acy, bcx, bcy; 01487 REAL acxtail, acytail; 01488 REAL bcxtail, bcytail; 01489 REAL negate, negatetail; 01490 REAL axby[8], bxay[8]; 01491 INEXACT REAL axby7, bxay7; 01492 REAL deter[16]; 01493 int deterlen; 01494 01495 INEXACT REAL bvirt; 01496 REAL avirt, bround, around; 01497 INEXACT REAL c; 01498 INEXACT REAL abig; 01499 REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; 01500 REAL err1, err2, err3; 01501 INEXACT REAL _i, _j, _k, _l, _m, _n; 01502 REAL _0, _1, _2; 01503 01504 Two_Diff(pa[0], pc[0], acx, acxtail); 01505 Two_Diff(pa[1], pc[1], acy, acytail); 01506 Two_Diff(pb[0], pc[0], bcx, bcxtail); 01507 Two_Diff(pb[1], pc[1], bcy, bcytail); 01508 01509 Two_Two_Product(acx, acxtail, bcy, bcytail, 01510 axby7, axby[6], axby[5], axby[4], 01511 axby[3], axby[2], axby[1], axby[0]); 01512 axby[7] = axby7; 01513 negate = -acy; 01514 negatetail = -acytail; 01515 Two_Two_Product(bcx, bcxtail, negate, negatetail, 01516 bxay7, bxay[6], bxay[5], bxay[4], 01517 bxay[3], bxay[2], bxay[1], bxay[0]); 01518 bxay[7] = bxay7; 01519 01520 deterlen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, deter); 01521 01522 return deter[deterlen - 1]; 01523 } 01524 01525 REAL orient2dadapt(REAL *pa, REAL *pb, REAL *pc, REAL detsum) 01526 { 01527 INEXACT REAL acx, acy, bcx, bcy; 01528 REAL acxtail, acytail, bcxtail, bcytail; 01529 INEXACT REAL detleft, detright; 01530 REAL detlefttail, detrighttail; 01531 REAL det, errbound; 01532 REAL B[4], C1[8], C2[12], D[16]; 01533 INEXACT REAL B3; 01534 int C1length, C2length, Dlength; 01535 REAL u[4]; 01536 INEXACT REAL u3; 01537 INEXACT REAL s1, t1; 01538 REAL s0, t0; 01539 01540 INEXACT REAL bvirt; 01541 REAL avirt, bround, around; 01542 INEXACT REAL c; 01543 INEXACT REAL abig; 01544 REAL ahi, alo, bhi, blo; 01545 REAL err1, err2, err3; 01546 INEXACT REAL _i, _j; 01547 REAL _0; 01548 01549 acx = (REAL) (pa[0] - pc[0]); 01550 bcx = (REAL) (pb[0] - pc[0]); 01551 acy = (REAL) (pa[1] - pc[1]); 01552 bcy = (REAL) (pb[1] - pc[1]); 01553 01554 Two_Product(acx, bcy, detleft, detlefttail); 01555 Two_Product(acy, bcx, detright, detrighttail); 01556 01557 Two_Two_Diff(detleft, detlefttail, detright, detrighttail, 01558 B3, B[2], B[1], B[0]); 01559 B[3] = B3; 01560 01561 det = estimate(4, B); 01562 errbound = ccwerrboundB * detsum; 01563 if ((det >= errbound) || (-det >= errbound)) { 01564 return det; 01565 } 01566 01567 Two_Diff_Tail(pa[0], pc[0], acx, acxtail); 01568 Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail); 01569 Two_Diff_Tail(pa[1], pc[1], acy, acytail); 01570 Two_Diff_Tail(pb[1], pc[1], bcy, bcytail); 01571 01572 if ((acxtail == 0.0) && (acytail == 0.0) 01573 && (bcxtail == 0.0) && (bcytail == 0.0)) { 01574 return det; 01575 } 01576 01577 errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det); 01578 det += (acx * bcytail + bcy * acxtail) 01579 - (acy * bcxtail + bcx * acytail); 01580 if ((det >= errbound) || (-det >= errbound)) { 01581 return det; 01582 } 01583 01584 Two_Product(acxtail, bcy, s1, s0); 01585 Two_Product(acytail, bcx, t1, t0); 01586 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); 01587 u[3] = u3; 01588 C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1); 01589 01590 Two_Product(acx, bcytail, s1, s0); 01591 Two_Product(acy, bcxtail, t1, t0); 01592 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); 01593 u[3] = u3; 01594 C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2); 01595 01596 Two_Product(acxtail, bcytail, s1, s0); 01597 Two_Product(acytail, bcxtail, t1, t0); 01598 Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]); 01599 u[3] = u3; 01600 Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D); 01601 01602 return(D[Dlength - 1]); 01603 } 01604 01605 REAL orient2d(REAL *pa, REAL *pb, REAL *pc) 01606 { 01607 REAL detleft, detright, det; 01608 REAL detsum, errbound; 01609 01610 detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]); 01611 detright = (pa[1] - pc[1]) * (pb[0] - pc[0]); 01612 det = detleft - detright; 01613 01614 if (detleft > 0.0) { 01615 if (detright <= 0.0) { 01616 return det; 01617 } else { 01618 detsum = detleft + detright; 01619 } 01620 } else if (detleft < 0.0) { 01621 if (detright >= 0.0) { 01622 return det; 01623 } else { 01624 detsum = -detleft - detright; 01625 } 01626 } else { 01627 return det; 01628 } 01629 01630 errbound = ccwerrboundA * detsum; 01631 if ((det >= errbound) || (-det >= errbound)) { 01632 return det; 01633 } 01634 01635 return orient2dadapt(pa, pb, pc, detsum); 01636 } 01637 01638 /*****************************************************************************/ 01639 /* */ 01640 /* orient3dfast() Approximate 3D orientation test. Nonrobust. */ 01641 /* orient3dexact() Exact 3D orientation test. Robust. */ 01642 /* orient3dslow() Another exact 3D orientation test. Robust. */ 01643 /* orient3d() Adaptive exact 3D orientation test. Robust. */ 01644 /* */ 01645 /* Return a positive value if the point pd lies below the */ 01646 /* plane passing through pa, pb, and pc; "below" is defined so */ 01647 /* that pa, pb, and pc appear in counterclockwise order when */ 01648 /* viewed from above the plane. Returns a negative value if */ 01649 /* pd lies above the plane. Returns zero if the points are */ 01650 /* coplanar. The result is also a rough approximation of six */ 01651 /* times the signed volume of the tetrahedron defined by the */ 01652 /* four points. */ 01653 /* */ 01654 /* Only the first and last routine should be used; the middle two are for */ 01655 /* timings. */ 01656 /* */ 01657 /* The last three use exact arithmetic to ensure a correct answer. The */ 01658 /* result returned is the determinant of a matrix. In orient3d() only, */ 01659 /* this determinant is computed adaptively, in the sense that exact */ 01660 /* arithmetic is used only to the degree it is needed to ensure that the */ 01661 /* returned value has the correct sign. Hence, orient3d() is usually quite */ 01662 /* fast, but will run more slowly when the input points are coplanar or */ 01663 /* nearly so. */ 01664 /* */ 01665 /*****************************************************************************/ 01666 01667 REAL orient3dfast(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 01668 { 01669 REAL adx, bdx, cdx; 01670 REAL ady, bdy, cdy; 01671 REAL adz, bdz, cdz; 01672 01673 adx = pa[0] - pd[0]; 01674 bdx = pb[0] - pd[0]; 01675 cdx = pc[0] - pd[0]; 01676 ady = pa[1] - pd[1]; 01677 bdy = pb[1] - pd[1]; 01678 cdy = pc[1] - pd[1]; 01679 adz = pa[2] - pd[2]; 01680 bdz = pb[2] - pd[2]; 01681 cdz = pc[2] - pd[2]; 01682 01683 return adx * (bdy * cdz - bdz * cdy) 01684 + bdx * (cdy * adz - cdz * ady) 01685 + cdx * (ady * bdz - adz * bdy); 01686 } 01687 01688 REAL orient3dexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 01689 { 01690 INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; 01691 INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; 01692 REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; 01693 REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; 01694 REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; 01695 REAL temp8[8]; 01696 int templen; 01697 REAL abc[12], bcd[12], cda[12], dab[12]; 01698 int abclen, bcdlen, cdalen, dablen; 01699 REAL adet[24], bdet[24], cdet[24], ddet[24]; 01700 int alen, blen, clen, dlen; 01701 REAL abdet[48], cddet[48]; 01702 int ablen, cdlen; 01703 REAL deter[96]; 01704 int deterlen; 01705 int i; 01706 01707 INEXACT REAL bvirt; 01708 REAL avirt, bround, around; 01709 INEXACT REAL c; 01710 INEXACT REAL abig; 01711 REAL ahi, alo, bhi, blo; 01712 REAL err1, err2, err3; 01713 INEXACT REAL _i, _j; 01714 REAL _0; 01715 01716 Two_Product(pa[0], pb[1], axby1, axby0); 01717 Two_Product(pb[0], pa[1], bxay1, bxay0); 01718 Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); 01719 01720 Two_Product(pb[0], pc[1], bxcy1, bxcy0); 01721 Two_Product(pc[0], pb[1], cxby1, cxby0); 01722 Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); 01723 01724 Two_Product(pc[0], pd[1], cxdy1, cxdy0); 01725 Two_Product(pd[0], pc[1], dxcy1, dxcy0); 01726 Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); 01727 01728 Two_Product(pd[0], pa[1], dxay1, dxay0); 01729 Two_Product(pa[0], pd[1], axdy1, axdy0); 01730 Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); 01731 01732 Two_Product(pa[0], pc[1], axcy1, axcy0); 01733 Two_Product(pc[0], pa[1], cxay1, cxay0); 01734 Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); 01735 01736 Two_Product(pb[0], pd[1], bxdy1, bxdy0); 01737 Two_Product(pd[0], pb[1], dxby1, dxby0); 01738 Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); 01739 01740 templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); 01741 cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); 01742 templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); 01743 dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); 01744 for (i = 0; i < 4; i++) { 01745 bd[i] = -bd[i]; 01746 ac[i] = -ac[i]; 01747 } 01748 templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); 01749 abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); 01750 templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); 01751 bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); 01752 01753 alen = scale_expansion_zeroelim(bcdlen, bcd, pa[2], adet); 01754 blen = scale_expansion_zeroelim(cdalen, cda, -pb[2], bdet); 01755 clen = scale_expansion_zeroelim(dablen, dab, pc[2], cdet); 01756 dlen = scale_expansion_zeroelim(abclen, abc, -pd[2], ddet); 01757 01758 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 01759 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); 01760 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); 01761 01762 return deter[deterlen - 1]; 01763 } 01764 01765 REAL orient3dslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 01766 { 01767 INEXACT REAL adx, ady, adz, bdx, bdy, bdz, cdx, cdy, cdz; 01768 REAL adxtail, adytail, adztail; 01769 REAL bdxtail, bdytail, bdztail; 01770 REAL cdxtail, cdytail, cdztail; 01771 REAL negate, negatetail; 01772 INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; 01773 REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; 01774 REAL temp16[16], temp32[32], temp32t[32]; 01775 int temp16len, temp32len, temp32tlen; 01776 REAL adet[64], bdet[64], cdet[64]; 01777 int alen, blen, clen; 01778 REAL abdet[128]; 01779 int ablen; 01780 REAL deter[192]; 01781 int deterlen; 01782 01783 INEXACT REAL bvirt; 01784 REAL avirt, bround, around; 01785 INEXACT REAL c; 01786 INEXACT REAL abig; 01787 REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; 01788 REAL err1, err2, err3; 01789 INEXACT REAL _i, _j, _k, _l, _m, _n; 01790 REAL _0, _1, _2; 01791 01792 Two_Diff(pa[0], pd[0], adx, adxtail); 01793 Two_Diff(pa[1], pd[1], ady, adytail); 01794 Two_Diff(pa[2], pd[2], adz, adztail); 01795 Two_Diff(pb[0], pd[0], bdx, bdxtail); 01796 Two_Diff(pb[1], pd[1], bdy, bdytail); 01797 Two_Diff(pb[2], pd[2], bdz, bdztail); 01798 Two_Diff(pc[0], pd[0], cdx, cdxtail); 01799 Two_Diff(pc[1], pd[1], cdy, cdytail); 01800 Two_Diff(pc[2], pd[2], cdz, cdztail); 01801 01802 Two_Two_Product(adx, adxtail, bdy, bdytail, 01803 axby7, axby[6], axby[5], axby[4], 01804 axby[3], axby[2], axby[1], axby[0]); 01805 axby[7] = axby7; 01806 negate = -ady; 01807 negatetail = -adytail; 01808 Two_Two_Product(bdx, bdxtail, negate, negatetail, 01809 bxay7, bxay[6], bxay[5], bxay[4], 01810 bxay[3], bxay[2], bxay[1], bxay[0]); 01811 bxay[7] = bxay7; 01812 Two_Two_Product(bdx, bdxtail, cdy, cdytail, 01813 bxcy7, bxcy[6], bxcy[5], bxcy[4], 01814 bxcy[3], bxcy[2], bxcy[1], bxcy[0]); 01815 bxcy[7] = bxcy7; 01816 negate = -bdy; 01817 negatetail = -bdytail; 01818 Two_Two_Product(cdx, cdxtail, negate, negatetail, 01819 cxby7, cxby[6], cxby[5], cxby[4], 01820 cxby[3], cxby[2], cxby[1], cxby[0]); 01821 cxby[7] = cxby7; 01822 Two_Two_Product(cdx, cdxtail, ady, adytail, 01823 cxay7, cxay[6], cxay[5], cxay[4], 01824 cxay[3], cxay[2], cxay[1], cxay[0]); 01825 cxay[7] = cxay7; 01826 negate = -cdy; 01827 negatetail = -cdytail; 01828 Two_Two_Product(adx, adxtail, negate, negatetail, 01829 axcy7, axcy[6], axcy[5], axcy[4], 01830 axcy[3], axcy[2], axcy[1], axcy[0]); 01831 axcy[7] = axcy7; 01832 01833 temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); 01834 temp32len = scale_expansion_zeroelim(temp16len, temp16, adz, temp32); 01835 temp32tlen = scale_expansion_zeroelim(temp16len, temp16, adztail, temp32t); 01836 alen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, 01837 adet); 01838 01839 temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); 01840 temp32len = scale_expansion_zeroelim(temp16len, temp16, bdz, temp32); 01841 temp32tlen = scale_expansion_zeroelim(temp16len, temp16, bdztail, temp32t); 01842 blen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, 01843 bdet); 01844 01845 temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); 01846 temp32len = scale_expansion_zeroelim(temp16len, temp16, cdz, temp32); 01847 temp32tlen = scale_expansion_zeroelim(temp16len, temp16, cdztail, temp32t); 01848 clen = fast_expansion_sum_zeroelim(temp32len, temp32, temp32tlen, temp32t, 01849 cdet); 01850 01851 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 01852 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); 01853 01854 return deter[deterlen - 1]; 01855 } 01856 01857 REAL orient3dadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL permanent) 01858 { 01859 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; 01860 REAL det, errbound; 01861 01862 INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; 01863 REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; 01864 REAL bc[4], ca[4], ab[4]; 01865 INEXACT REAL bc3, ca3, ab3; 01866 REAL adet[8], bdet[8], cdet[8]; 01867 int alen, blen, clen; 01868 REAL abdet[16]; 01869 int ablen; 01870 REAL *finnow, *finother, *finswap; 01871 REAL fin1[192], fin2[192]; 01872 int finlength; 01873 01875 // To avoid uninitialized warnings reported by valgrind. 01876 int i; 01877 for (i = 0; i < 8; i++) { 01878 adet[i] = bdet[i] = cdet[i] = 0.0; 01879 } 01880 for (i = 0; i < 16; i++) { 01881 abdet[i] = 0.0; 01882 } 01884 01885 REAL adxtail, bdxtail, cdxtail; 01886 REAL adytail, bdytail, cdytail; 01887 REAL adztail, bdztail, cdztail; 01888 INEXACT REAL at_blarge, at_clarge; 01889 INEXACT REAL bt_clarge, bt_alarge; 01890 INEXACT REAL ct_alarge, ct_blarge; 01891 REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4]; 01892 int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen; 01893 INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1; 01894 INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1; 01895 REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0; 01896 REAL adxt_cdy0, adxt_bdy0, bdxt_ady0; 01897 INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1; 01898 INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1; 01899 REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0; 01900 REAL adyt_cdx0, adyt_bdx0, bdyt_adx0; 01901 REAL bct[8], cat[8], abt[8]; 01902 int bctlen, catlen, abtlen; 01903 INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1; 01904 INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1; 01905 REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0; 01906 REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0; 01907 REAL u[4], v[12], w[16]; 01908 INEXACT REAL u3; 01909 int vlength, wlength; 01910 REAL negate; 01911 01912 INEXACT REAL bvirt; 01913 REAL avirt, bround, around; 01914 INEXACT REAL c; 01915 INEXACT REAL abig; 01916 REAL ahi, alo, bhi, blo; 01917 REAL err1, err2, err3; 01918 INEXACT REAL _i, _j, _k; 01919 REAL _0; 01920 01921 adx = (REAL) (pa[0] - pd[0]); 01922 bdx = (REAL) (pb[0] - pd[0]); 01923 cdx = (REAL) (pc[0] - pd[0]); 01924 ady = (REAL) (pa[1] - pd[1]); 01925 bdy = (REAL) (pb[1] - pd[1]); 01926 cdy = (REAL) (pc[1] - pd[1]); 01927 adz = (REAL) (pa[2] - pd[2]); 01928 bdz = (REAL) (pb[2] - pd[2]); 01929 cdz = (REAL) (pc[2] - pd[2]); 01930 01931 Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); 01932 Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); 01933 Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); 01934 bc[3] = bc3; 01935 alen = scale_expansion_zeroelim(4, bc, adz, adet); 01936 01937 Two_Product(cdx, ady, cdxady1, cdxady0); 01938 Two_Product(adx, cdy, adxcdy1, adxcdy0); 01939 Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); 01940 ca[3] = ca3; 01941 blen = scale_expansion_zeroelim(4, ca, bdz, bdet); 01942 01943 Two_Product(adx, bdy, adxbdy1, adxbdy0); 01944 Two_Product(bdx, ady, bdxady1, bdxady0); 01945 Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); 01946 ab[3] = ab3; 01947 clen = scale_expansion_zeroelim(4, ab, cdz, cdet); 01948 01949 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 01950 finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); 01951 01952 det = estimate(finlength, fin1); 01953 errbound = o3derrboundB * permanent; 01954 if ((det >= errbound) || (-det >= errbound)) { 01955 return det; 01956 } 01957 01958 Two_Diff_Tail(pa[0], pd[0], adx, adxtail); 01959 Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); 01960 Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); 01961 Two_Diff_Tail(pa[1], pd[1], ady, adytail); 01962 Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); 01963 Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); 01964 Two_Diff_Tail(pa[2], pd[2], adz, adztail); 01965 Two_Diff_Tail(pb[2], pd[2], bdz, bdztail); 01966 Two_Diff_Tail(pc[2], pd[2], cdz, cdztail); 01967 01968 if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) 01969 && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) 01970 && (adztail == 0.0) && (bdztail == 0.0) && (cdztail == 0.0)) { 01971 return det; 01972 } 01973 01974 errbound = o3derrboundC * permanent + resulterrbound * Absolute(det); 01975 det += (adz * ((bdx * cdytail + cdy * bdxtail) 01976 - (bdy * cdxtail + cdx * bdytail)) 01977 + adztail * (bdx * cdy - bdy * cdx)) 01978 + (bdz * ((cdx * adytail + ady * cdxtail) 01979 - (cdy * adxtail + adx * cdytail)) 01980 + bdztail * (cdx * ady - cdy * adx)) 01981 + (cdz * ((adx * bdytail + bdy * adxtail) 01982 - (ady * bdxtail + bdx * adytail)) 01983 + cdztail * (adx * bdy - ady * bdx)); 01984 if ((det >= errbound) || (-det >= errbound)) { 01985 return det; 01986 } 01987 01988 finnow = fin1; 01989 finother = fin2; 01990 01991 if (adxtail == 0.0) { 01992 if (adytail == 0.0) { 01993 at_b[0] = 0.0; 01994 at_blen = 1; 01995 at_c[0] = 0.0; 01996 at_clen = 1; 01997 } else { 01998 negate = -adytail; 01999 Two_Product(negate, bdx, at_blarge, at_b[0]); 02000 at_b[1] = at_blarge; 02001 at_blen = 2; 02002 Two_Product(adytail, cdx, at_clarge, at_c[0]); 02003 at_c[1] = at_clarge; 02004 at_clen = 2; 02005 } 02006 } else { 02007 if (adytail == 0.0) { 02008 Two_Product(adxtail, bdy, at_blarge, at_b[0]); 02009 at_b[1] = at_blarge; 02010 at_blen = 2; 02011 negate = -adxtail; 02012 Two_Product(negate, cdy, at_clarge, at_c[0]); 02013 at_c[1] = at_clarge; 02014 at_clen = 2; 02015 } else { 02016 Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0); 02017 Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0); 02018 Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0, 02019 at_blarge, at_b[2], at_b[1], at_b[0]); 02020 at_b[3] = at_blarge; 02021 at_blen = 4; 02022 Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0); 02023 Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0); 02024 Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0, 02025 at_clarge, at_c[2], at_c[1], at_c[0]); 02026 at_c[3] = at_clarge; 02027 at_clen = 4; 02028 } 02029 } 02030 if (bdxtail == 0.0) { 02031 if (bdytail == 0.0) { 02032 bt_c[0] = 0.0; 02033 bt_clen = 1; 02034 bt_a[0] = 0.0; 02035 bt_alen = 1; 02036 } else { 02037 negate = -bdytail; 02038 Two_Product(negate, cdx, bt_clarge, bt_c[0]); 02039 bt_c[1] = bt_clarge; 02040 bt_clen = 2; 02041 Two_Product(bdytail, adx, bt_alarge, bt_a[0]); 02042 bt_a[1] = bt_alarge; 02043 bt_alen = 2; 02044 } 02045 } else { 02046 if (bdytail == 0.0) { 02047 Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]); 02048 bt_c[1] = bt_clarge; 02049 bt_clen = 2; 02050 negate = -bdxtail; 02051 Two_Product(negate, ady, bt_alarge, bt_a[0]); 02052 bt_a[1] = bt_alarge; 02053 bt_alen = 2; 02054 } else { 02055 Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0); 02056 Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0); 02057 Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0, 02058 bt_clarge, bt_c[2], bt_c[1], bt_c[0]); 02059 bt_c[3] = bt_clarge; 02060 bt_clen = 4; 02061 Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0); 02062 Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0); 02063 Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0, 02064 bt_alarge, bt_a[2], bt_a[1], bt_a[0]); 02065 bt_a[3] = bt_alarge; 02066 bt_alen = 4; 02067 } 02068 } 02069 if (cdxtail == 0.0) { 02070 if (cdytail == 0.0) { 02071 ct_a[0] = 0.0; 02072 ct_alen = 1; 02073 ct_b[0] = 0.0; 02074 ct_blen = 1; 02075 } else { 02076 negate = -cdytail; 02077 Two_Product(negate, adx, ct_alarge, ct_a[0]); 02078 ct_a[1] = ct_alarge; 02079 ct_alen = 2; 02080 Two_Product(cdytail, bdx, ct_blarge, ct_b[0]); 02081 ct_b[1] = ct_blarge; 02082 ct_blen = 2; 02083 } 02084 } else { 02085 if (cdytail == 0.0) { 02086 Two_Product(cdxtail, ady, ct_alarge, ct_a[0]); 02087 ct_a[1] = ct_alarge; 02088 ct_alen = 2; 02089 negate = -cdxtail; 02090 Two_Product(negate, bdy, ct_blarge, ct_b[0]); 02091 ct_b[1] = ct_blarge; 02092 ct_blen = 2; 02093 } else { 02094 Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0); 02095 Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0); 02096 Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0, 02097 ct_alarge, ct_a[2], ct_a[1], ct_a[0]); 02098 ct_a[3] = ct_alarge; 02099 ct_alen = 4; 02100 Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0); 02101 Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0); 02102 Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0, 02103 ct_blarge, ct_b[2], ct_b[1], ct_b[0]); 02104 ct_b[3] = ct_blarge; 02105 ct_blen = 4; 02106 } 02107 } 02108 02109 bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct); 02110 wlength = scale_expansion_zeroelim(bctlen, bct, adz, w); 02111 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 02112 finother); 02113 finswap = finnow; finnow = finother; finother = finswap; 02114 02115 catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat); 02116 wlength = scale_expansion_zeroelim(catlen, cat, bdz, w); 02117 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 02118 finother); 02119 finswap = finnow; finnow = finother; finother = finswap; 02120 02121 abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt); 02122 wlength = scale_expansion_zeroelim(abtlen, abt, cdz, w); 02123 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 02124 finother); 02125 finswap = finnow; finnow = finother; finother = finswap; 02126 02127 if (adztail != 0.0) { 02128 vlength = scale_expansion_zeroelim(4, bc, adztail, v); 02129 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, 02130 finother); 02131 finswap = finnow; finnow = finother; finother = finswap; 02132 } 02133 if (bdztail != 0.0) { 02134 vlength = scale_expansion_zeroelim(4, ca, bdztail, v); 02135 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, 02136 finother); 02137 finswap = finnow; finnow = finother; finother = finswap; 02138 } 02139 if (cdztail != 0.0) { 02140 vlength = scale_expansion_zeroelim(4, ab, cdztail, v); 02141 finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v, 02142 finother); 02143 finswap = finnow; finnow = finother; finother = finswap; 02144 } 02145 02146 if (adxtail != 0.0) { 02147 if (bdytail != 0.0) { 02148 Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0); 02149 Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdz, u3, u[2], u[1], u[0]); 02150 u[3] = u3; 02151 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02152 finother); 02153 finswap = finnow; finnow = finother; finother = finswap; 02154 if (cdztail != 0.0) { 02155 Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdztail, u3, u[2], u[1], u[0]); 02156 u[3] = u3; 02157 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02158 finother); 02159 finswap = finnow; finnow = finother; finother = finswap; 02160 } 02161 } 02162 if (cdytail != 0.0) { 02163 negate = -adxtail; 02164 Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0); 02165 Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdz, u3, u[2], u[1], u[0]); 02166 u[3] = u3; 02167 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02168 finother); 02169 finswap = finnow; finnow = finother; finother = finswap; 02170 if (bdztail != 0.0) { 02171 Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdztail, u3, u[2], u[1], u[0]); 02172 u[3] = u3; 02173 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02174 finother); 02175 finswap = finnow; finnow = finother; finother = finswap; 02176 } 02177 } 02178 } 02179 if (bdxtail != 0.0) { 02180 if (cdytail != 0.0) { 02181 Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0); 02182 Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adz, u3, u[2], u[1], u[0]); 02183 u[3] = u3; 02184 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02185 finother); 02186 finswap = finnow; finnow = finother; finother = finswap; 02187 if (adztail != 0.0) { 02188 Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adztail, u3, u[2], u[1], u[0]); 02189 u[3] = u3; 02190 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02191 finother); 02192 finswap = finnow; finnow = finother; finother = finswap; 02193 } 02194 } 02195 if (adytail != 0.0) { 02196 negate = -bdxtail; 02197 Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0); 02198 Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdz, u3, u[2], u[1], u[0]); 02199 u[3] = u3; 02200 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02201 finother); 02202 finswap = finnow; finnow = finother; finother = finswap; 02203 if (cdztail != 0.0) { 02204 Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdztail, u3, u[2], u[1], u[0]); 02205 u[3] = u3; 02206 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02207 finother); 02208 finswap = finnow; finnow = finother; finother = finswap; 02209 } 02210 } 02211 } 02212 if (cdxtail != 0.0) { 02213 if (adytail != 0.0) { 02214 Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0); 02215 Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdz, u3, u[2], u[1], u[0]); 02216 u[3] = u3; 02217 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02218 finother); 02219 finswap = finnow; finnow = finother; finother = finswap; 02220 if (bdztail != 0.0) { 02221 Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdztail, u3, u[2], u[1], u[0]); 02222 u[3] = u3; 02223 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02224 finother); 02225 finswap = finnow; finnow = finother; finother = finswap; 02226 } 02227 } 02228 if (bdytail != 0.0) { 02229 negate = -cdxtail; 02230 Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0); 02231 Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adz, u3, u[2], u[1], u[0]); 02232 u[3] = u3; 02233 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02234 finother); 02235 finswap = finnow; finnow = finother; finother = finswap; 02236 if (adztail != 0.0) { 02237 Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adztail, u3, u[2], u[1], u[0]); 02238 u[3] = u3; 02239 finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u, 02240 finother); 02241 finswap = finnow; finnow = finother; finother = finswap; 02242 } 02243 } 02244 } 02245 02246 if (adztail != 0.0) { 02247 wlength = scale_expansion_zeroelim(bctlen, bct, adztail, w); 02248 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 02249 finother); 02250 finswap = finnow; finnow = finother; finother = finswap; 02251 } 02252 if (bdztail != 0.0) { 02253 wlength = scale_expansion_zeroelim(catlen, cat, bdztail, w); 02254 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 02255 finother); 02256 finswap = finnow; finnow = finother; finother = finswap; 02257 } 02258 if (cdztail != 0.0) { 02259 wlength = scale_expansion_zeroelim(abtlen, abt, cdztail, w); 02260 finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w, 02261 finother); 02262 finswap = finnow; finnow = finother; finother = finswap; 02263 } 02264 02265 return finnow[finlength - 1]; 02266 } 02267 02268 REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 02269 { 02270 REAL adx, bdx, cdx, ady, bdy, cdy, adz, bdz, cdz; 02271 REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; 02272 REAL det; 02273 REAL permanent, errbound; 02274 02275 adx = pa[0] - pd[0]; 02276 bdx = pb[0] - pd[0]; 02277 cdx = pc[0] - pd[0]; 02278 ady = pa[1] - pd[1]; 02279 bdy = pb[1] - pd[1]; 02280 cdy = pc[1] - pd[1]; 02281 adz = pa[2] - pd[2]; 02282 bdz = pb[2] - pd[2]; 02283 cdz = pc[2] - pd[2]; 02284 02285 bdxcdy = bdx * cdy; 02286 cdxbdy = cdx * bdy; 02287 02288 cdxady = cdx * ady; 02289 adxcdy = adx * cdy; 02290 02291 adxbdy = adx * bdy; 02292 bdxady = bdx * ady; 02293 02294 det = adz * (bdxcdy - cdxbdy) 02295 + bdz * (cdxady - adxcdy) 02296 + cdz * (adxbdy - bdxady); 02297 02298 permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) 02299 + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) 02300 + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); 02301 errbound = o3derrboundA * permanent; 02302 if ((det > errbound) || (-det > errbound)) { 02303 return det; 02304 } 02305 02306 return orient3dadapt(pa, pb, pc, pd, permanent); 02307 } 02308 02309 /*****************************************************************************/ 02310 /* */ 02311 /* incirclefast() Approximate 2D incircle test. Nonrobust. */ 02312 /* incircleexact() Exact 2D incircle test. Robust. */ 02313 /* incircleslow() Another exact 2D incircle test. Robust. */ 02314 /* incircle() Adaptive exact 2D incircle test. Robust. */ 02315 /* */ 02316 /* Return a positive value if the point pd lies inside the */ 02317 /* circle passing through pa, pb, and pc; a negative value if */ 02318 /* it lies outside; and zero if the four points are cocircular.*/ 02319 /* The points pa, pb, and pc must be in counterclockwise */ 02320 /* order, or the sign of the result will be reversed. */ 02321 /* */ 02322 /* Only the first and last routine should be used; the middle two are for */ 02323 /* timings. */ 02324 /* */ 02325 /* The last three use exact arithmetic to ensure a correct answer. The */ 02326 /* result returned is the determinant of a matrix. In incircle() only, */ 02327 /* this determinant is computed adaptively, in the sense that exact */ 02328 /* arithmetic is used only to the degree it is needed to ensure that the */ 02329 /* returned value has the correct sign. Hence, incircle() is usually quite */ 02330 /* fast, but will run more slowly when the input points are cocircular or */ 02331 /* nearly so. */ 02332 /* */ 02333 /*****************************************************************************/ 02334 02335 REAL incirclefast(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 02336 { 02337 REAL adx, ady, bdx, bdy, cdx, cdy; 02338 REAL abdet, bcdet, cadet; 02339 REAL alift, blift, clift; 02340 02341 adx = pa[0] - pd[0]; 02342 ady = pa[1] - pd[1]; 02343 bdx = pb[0] - pd[0]; 02344 bdy = pb[1] - pd[1]; 02345 cdx = pc[0] - pd[0]; 02346 cdy = pc[1] - pd[1]; 02347 02348 abdet = adx * bdy - bdx * ady; 02349 bcdet = bdx * cdy - cdx * bdy; 02350 cadet = cdx * ady - adx * cdy; 02351 alift = adx * adx + ady * ady; 02352 blift = bdx * bdx + bdy * bdy; 02353 clift = cdx * cdx + cdy * cdy; 02354 02355 return alift * bcdet + blift * cadet + clift * abdet; 02356 } 02357 02358 REAL incircleexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 02359 { 02360 INEXACT REAL axby1, bxcy1, cxdy1, dxay1, axcy1, bxdy1; 02361 INEXACT REAL bxay1, cxby1, dxcy1, axdy1, cxay1, dxby1; 02362 REAL axby0, bxcy0, cxdy0, dxay0, axcy0, bxdy0; 02363 REAL bxay0, cxby0, dxcy0, axdy0, cxay0, dxby0; 02364 REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; 02365 REAL temp8[8]; 02366 int templen; 02367 REAL abc[12], bcd[12], cda[12], dab[12]; 02368 int abclen, bcdlen, cdalen, dablen; 02369 REAL det24x[24], det24y[24], det48x[48], det48y[48]; 02370 int xlen, ylen; 02371 REAL adet[96], bdet[96], cdet[96], ddet[96]; 02372 int alen, blen, clen, dlen; 02373 REAL abdet[192], cddet[192]; 02374 int ablen, cdlen; 02375 REAL deter[384]; 02376 int deterlen; 02377 int i; 02378 02379 INEXACT REAL bvirt; 02380 REAL avirt, bround, around; 02381 INEXACT REAL c; 02382 INEXACT REAL abig; 02383 REAL ahi, alo, bhi, blo; 02384 REAL err1, err2, err3; 02385 INEXACT REAL _i, _j; 02386 REAL _0; 02387 02388 Two_Product(pa[0], pb[1], axby1, axby0); 02389 Two_Product(pb[0], pa[1], bxay1, bxay0); 02390 Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); 02391 02392 Two_Product(pb[0], pc[1], bxcy1, bxcy0); 02393 Two_Product(pc[0], pb[1], cxby1, cxby0); 02394 Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); 02395 02396 Two_Product(pc[0], pd[1], cxdy1, cxdy0); 02397 Two_Product(pd[0], pc[1], dxcy1, dxcy0); 02398 Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); 02399 02400 Two_Product(pd[0], pa[1], dxay1, dxay0); 02401 Two_Product(pa[0], pd[1], axdy1, axdy0); 02402 Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); 02403 02404 Two_Product(pa[0], pc[1], axcy1, axcy0); 02405 Two_Product(pc[0], pa[1], cxay1, cxay0); 02406 Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); 02407 02408 Two_Product(pb[0], pd[1], bxdy1, bxdy0); 02409 Two_Product(pd[0], pb[1], dxby1, dxby0); 02410 Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); 02411 02412 templen = fast_expansion_sum_zeroelim(4, cd, 4, da, temp8); 02413 cdalen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, cda); 02414 templen = fast_expansion_sum_zeroelim(4, da, 4, ab, temp8); 02415 dablen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, dab); 02416 for (i = 0; i < 4; i++) { 02417 bd[i] = -bd[i]; 02418 ac[i] = -ac[i]; 02419 } 02420 templen = fast_expansion_sum_zeroelim(4, ab, 4, bc, temp8); 02421 abclen = fast_expansion_sum_zeroelim(templen, temp8, 4, ac, abc); 02422 templen = fast_expansion_sum_zeroelim(4, bc, 4, cd, temp8); 02423 bcdlen = fast_expansion_sum_zeroelim(templen, temp8, 4, bd, bcd); 02424 02425 xlen = scale_expansion_zeroelim(bcdlen, bcd, pa[0], det24x); 02426 xlen = scale_expansion_zeroelim(xlen, det24x, pa[0], det48x); 02427 ylen = scale_expansion_zeroelim(bcdlen, bcd, pa[1], det24y); 02428 ylen = scale_expansion_zeroelim(ylen, det24y, pa[1], det48y); 02429 alen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, adet); 02430 02431 xlen = scale_expansion_zeroelim(cdalen, cda, pb[0], det24x); 02432 xlen = scale_expansion_zeroelim(xlen, det24x, -pb[0], det48x); 02433 ylen = scale_expansion_zeroelim(cdalen, cda, pb[1], det24y); 02434 ylen = scale_expansion_zeroelim(ylen, det24y, -pb[1], det48y); 02435 blen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, bdet); 02436 02437 xlen = scale_expansion_zeroelim(dablen, dab, pc[0], det24x); 02438 xlen = scale_expansion_zeroelim(xlen, det24x, pc[0], det48x); 02439 ylen = scale_expansion_zeroelim(dablen, dab, pc[1], det24y); 02440 ylen = scale_expansion_zeroelim(ylen, det24y, pc[1], det48y); 02441 clen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, cdet); 02442 02443 xlen = scale_expansion_zeroelim(abclen, abc, pd[0], det24x); 02444 xlen = scale_expansion_zeroelim(xlen, det24x, -pd[0], det48x); 02445 ylen = scale_expansion_zeroelim(abclen, abc, pd[1], det24y); 02446 ylen = scale_expansion_zeroelim(ylen, det24y, -pd[1], det48y); 02447 dlen = fast_expansion_sum_zeroelim(xlen, det48x, ylen, det48y, ddet); 02448 02449 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 02450 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); 02451 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); 02452 02453 return deter[deterlen - 1]; 02454 } 02455 02456 REAL incircleslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 02457 { 02458 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; 02459 REAL adxtail, bdxtail, cdxtail; 02460 REAL adytail, bdytail, cdytail; 02461 REAL negate, negatetail; 02462 INEXACT REAL axby7, bxcy7, axcy7, bxay7, cxby7, cxay7; 02463 REAL axby[8], bxcy[8], axcy[8], bxay[8], cxby[8], cxay[8]; 02464 REAL temp16[16]; 02465 int temp16len; 02466 REAL detx[32], detxx[64], detxt[32], detxxt[64], detxtxt[64]; 02467 int xlen, xxlen, xtlen, xxtlen, xtxtlen; 02468 REAL x1[128], x2[192]; 02469 int x1len, x2len; 02470 REAL dety[32], detyy[64], detyt[32], detyyt[64], detytyt[64]; 02471 int ylen, yylen, ytlen, yytlen, ytytlen; 02472 REAL y1[128], y2[192]; 02473 int y1len, y2len; 02474 REAL adet[384], bdet[384], cdet[384], abdet[768], deter[1152]; 02475 int alen, blen, clen, ablen, deterlen; 02476 int i; 02477 02478 INEXACT REAL bvirt; 02479 REAL avirt, bround, around; 02480 INEXACT REAL c; 02481 INEXACT REAL abig; 02482 REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; 02483 REAL err1, err2, err3; 02484 INEXACT REAL _i, _j, _k, _l, _m, _n; 02485 REAL _0, _1, _2; 02486 02487 Two_Diff(pa[0], pd[0], adx, adxtail); 02488 Two_Diff(pa[1], pd[1], ady, adytail); 02489 Two_Diff(pb[0], pd[0], bdx, bdxtail); 02490 Two_Diff(pb[1], pd[1], bdy, bdytail); 02491 Two_Diff(pc[0], pd[0], cdx, cdxtail); 02492 Two_Diff(pc[1], pd[1], cdy, cdytail); 02493 02494 Two_Two_Product(adx, adxtail, bdy, bdytail, 02495 axby7, axby[6], axby[5], axby[4], 02496 axby[3], axby[2], axby[1], axby[0]); 02497 axby[7] = axby7; 02498 negate = -ady; 02499 negatetail = -adytail; 02500 Two_Two_Product(bdx, bdxtail, negate, negatetail, 02501 bxay7, bxay[6], bxay[5], bxay[4], 02502 bxay[3], bxay[2], bxay[1], bxay[0]); 02503 bxay[7] = bxay7; 02504 Two_Two_Product(bdx, bdxtail, cdy, cdytail, 02505 bxcy7, bxcy[6], bxcy[5], bxcy[4], 02506 bxcy[3], bxcy[2], bxcy[1], bxcy[0]); 02507 bxcy[7] = bxcy7; 02508 negate = -bdy; 02509 negatetail = -bdytail; 02510 Two_Two_Product(cdx, cdxtail, negate, negatetail, 02511 cxby7, cxby[6], cxby[5], cxby[4], 02512 cxby[3], cxby[2], cxby[1], cxby[0]); 02513 cxby[7] = cxby7; 02514 Two_Two_Product(cdx, cdxtail, ady, adytail, 02515 cxay7, cxay[6], cxay[5], cxay[4], 02516 cxay[3], cxay[2], cxay[1], cxay[0]); 02517 cxay[7] = cxay7; 02518 negate = -cdy; 02519 negatetail = -cdytail; 02520 Two_Two_Product(adx, adxtail, negate, negatetail, 02521 axcy7, axcy[6], axcy[5], axcy[4], 02522 axcy[3], axcy[2], axcy[1], axcy[0]); 02523 axcy[7] = axcy7; 02524 02525 02526 temp16len = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, temp16); 02527 02528 xlen = scale_expansion_zeroelim(temp16len, temp16, adx, detx); 02529 xxlen = scale_expansion_zeroelim(xlen, detx, adx, detxx); 02530 xtlen = scale_expansion_zeroelim(temp16len, temp16, adxtail, detxt); 02531 xxtlen = scale_expansion_zeroelim(xtlen, detxt, adx, detxxt); 02532 for (i = 0; i < xxtlen; i++) { 02533 detxxt[i] *= 2.0; 02534 } 02535 xtxtlen = scale_expansion_zeroelim(xtlen, detxt, adxtail, detxtxt); 02536 x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); 02537 x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); 02538 02539 ylen = scale_expansion_zeroelim(temp16len, temp16, ady, dety); 02540 yylen = scale_expansion_zeroelim(ylen, dety, ady, detyy); 02541 ytlen = scale_expansion_zeroelim(temp16len, temp16, adytail, detyt); 02542 yytlen = scale_expansion_zeroelim(ytlen, detyt, ady, detyyt); 02543 for (i = 0; i < yytlen; i++) { 02544 detyyt[i] *= 2.0; 02545 } 02546 ytytlen = scale_expansion_zeroelim(ytlen, detyt, adytail, detytyt); 02547 y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); 02548 y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); 02549 02550 alen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, adet); 02551 02552 02553 temp16len = fast_expansion_sum_zeroelim(8, cxay, 8, axcy, temp16); 02554 02555 xlen = scale_expansion_zeroelim(temp16len, temp16, bdx, detx); 02556 xxlen = scale_expansion_zeroelim(xlen, detx, bdx, detxx); 02557 xtlen = scale_expansion_zeroelim(temp16len, temp16, bdxtail, detxt); 02558 xxtlen = scale_expansion_zeroelim(xtlen, detxt, bdx, detxxt); 02559 for (i = 0; i < xxtlen; i++) { 02560 detxxt[i] *= 2.0; 02561 } 02562 xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bdxtail, detxtxt); 02563 x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); 02564 x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); 02565 02566 ylen = scale_expansion_zeroelim(temp16len, temp16, bdy, dety); 02567 yylen = scale_expansion_zeroelim(ylen, dety, bdy, detyy); 02568 ytlen = scale_expansion_zeroelim(temp16len, temp16, bdytail, detyt); 02569 yytlen = scale_expansion_zeroelim(ytlen, detyt, bdy, detyyt); 02570 for (i = 0; i < yytlen; i++) { 02571 detyyt[i] *= 2.0; 02572 } 02573 ytytlen = scale_expansion_zeroelim(ytlen, detyt, bdytail, detytyt); 02574 y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); 02575 y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); 02576 02577 blen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, bdet); 02578 02579 02580 temp16len = fast_expansion_sum_zeroelim(8, axby, 8, bxay, temp16); 02581 02582 xlen = scale_expansion_zeroelim(temp16len, temp16, cdx, detx); 02583 xxlen = scale_expansion_zeroelim(xlen, detx, cdx, detxx); 02584 xtlen = scale_expansion_zeroelim(temp16len, temp16, cdxtail, detxt); 02585 xxtlen = scale_expansion_zeroelim(xtlen, detxt, cdx, detxxt); 02586 for (i = 0; i < xxtlen; i++) { 02587 detxxt[i] *= 2.0; 02588 } 02589 xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cdxtail, detxtxt); 02590 x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); 02591 x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); 02592 02593 ylen = scale_expansion_zeroelim(temp16len, temp16, cdy, dety); 02594 yylen = scale_expansion_zeroelim(ylen, dety, cdy, detyy); 02595 ytlen = scale_expansion_zeroelim(temp16len, temp16, cdytail, detyt); 02596 yytlen = scale_expansion_zeroelim(ytlen, detyt, cdy, detyyt); 02597 for (i = 0; i < yytlen; i++) { 02598 detyyt[i] *= 2.0; 02599 } 02600 ytytlen = scale_expansion_zeroelim(ytlen, detyt, cdytail, detytyt); 02601 y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); 02602 y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); 02603 02604 clen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, cdet); 02605 02606 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 02607 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, deter); 02608 02609 return deter[deterlen - 1]; 02610 } 02611 02612 REAL incircleadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL permanent) 02613 { 02614 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy; 02615 REAL det, errbound; 02616 02617 INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1; 02618 REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0; 02619 REAL bc[4], ca[4], ab[4]; 02620 INEXACT REAL bc3, ca3, ab3; 02621 REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32]; 02622 int axbclen, axxbclen, aybclen, ayybclen, alen; 02623 REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32]; 02624 int bxcalen, bxxcalen, bycalen, byycalen, blen; 02625 REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32]; 02626 int cxablen, cxxablen, cyablen, cyyablen, clen; 02627 REAL abdet[64]; 02628 int ablen; 02629 REAL fin1[1152], fin2[1152]; 02630 REAL *finnow, *finother, *finswap; 02631 int finlength; 02632 02633 REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail; 02634 INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1; 02635 REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0; 02636 REAL aa[4], bb[4], cc[4]; 02637 INEXACT REAL aa3, bb3, cc3; 02638 INEXACT REAL ti1, tj1; 02639 REAL ti0, tj0; 02640 REAL u[4], v[4]; 02641 INEXACT REAL u3, v3; 02642 REAL temp8[8], temp16a[16], temp16b[16], temp16c[16]; 02643 REAL temp32a[32], temp32b[32], temp48[48], temp64[64]; 02644 int temp8len, temp16alen, temp16blen, temp16clen; 02645 int temp32alen, temp32blen, temp48len, temp64len; 02646 REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8]; 02647 int axtbblen, axtcclen, aytbblen, aytcclen; 02648 REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8]; 02649 int bxtaalen, bxtcclen, bytaalen, bytcclen; 02650 REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8]; 02651 int cxtaalen, cxtbblen, cytaalen, cytbblen; 02652 REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8]; 02653 int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen; 02654 REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16]; 02655 int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen; 02656 REAL axtbctt[8], aytbctt[8], bxtcatt[8]; 02657 REAL bytcatt[8], cxtabtt[8], cytabtt[8]; 02658 int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen; 02659 REAL abt[8], bct[8], cat[8]; 02660 int abtlen, bctlen, catlen; 02661 REAL abtt[4], bctt[4], catt[4]; 02662 int abttlen, bcttlen, cattlen; 02663 INEXACT REAL abtt3, bctt3, catt3; 02664 REAL negate; 02665 02666 INEXACT REAL bvirt; 02667 REAL avirt, bround, around; 02668 INEXACT REAL c; 02669 INEXACT REAL abig; 02670 REAL ahi, alo, bhi, blo; 02671 REAL err1, err2, err3; 02672 INEXACT REAL _i, _j; 02673 REAL _0; 02674 02675 axtbclen=0; 02676 aytbclen=0; 02677 bxtcalen=0; 02678 bytcalen=0; 02679 cxtablen=0; 02680 cytablen=0; 02681 adx = (REAL) (pa[0] - pd[0]); 02682 bdx = (REAL) (pb[0] - pd[0]); 02683 cdx = (REAL) (pc[0] - pd[0]); 02684 ady = (REAL) (pa[1] - pd[1]); 02685 bdy = (REAL) (pb[1] - pd[1]); 02686 cdy = (REAL) (pc[1] - pd[1]); 02687 02688 Two_Product(bdx, cdy, bdxcdy1, bdxcdy0); 02689 Two_Product(cdx, bdy, cdxbdy1, cdxbdy0); 02690 Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]); 02691 bc[3] = bc3; 02692 axbclen = scale_expansion_zeroelim(4, bc, adx, axbc); 02693 axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc); 02694 aybclen = scale_expansion_zeroelim(4, bc, ady, aybc); 02695 ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc); 02696 alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet); 02697 02698 Two_Product(cdx, ady, cdxady1, cdxady0); 02699 Two_Product(adx, cdy, adxcdy1, adxcdy0); 02700 Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]); 02701 ca[3] = ca3; 02702 bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca); 02703 bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca); 02704 bycalen = scale_expansion_zeroelim(4, ca, bdy, byca); 02705 byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca); 02706 blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet); 02707 02708 Two_Product(adx, bdy, adxbdy1, adxbdy0); 02709 Two_Product(bdx, ady, bdxady1, bdxady0); 02710 Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]); 02711 ab[3] = ab3; 02712 cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab); 02713 cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab); 02714 cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab); 02715 cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab); 02716 clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet); 02717 02718 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 02719 finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1); 02720 02721 det = estimate(finlength, fin1); 02722 errbound = iccerrboundB * permanent; 02723 if ((det >= errbound) || (-det >= errbound)) { 02724 return det; 02725 } 02726 02727 Two_Diff_Tail(pa[0], pd[0], adx, adxtail); 02728 Two_Diff_Tail(pa[1], pd[1], ady, adytail); 02729 Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail); 02730 Two_Diff_Tail(pb[1], pd[1], bdy, bdytail); 02731 Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail); 02732 Two_Diff_Tail(pc[1], pd[1], cdy, cdytail); 02733 if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) 02734 && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) { 02735 return det; 02736 } 02737 02738 errbound = iccerrboundC * permanent + resulterrbound * Absolute(det); 02739 det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) 02740 - (bdy * cdxtail + cdx * bdytail)) 02741 + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) 02742 + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) 02743 - (cdy * adxtail + adx * cdytail)) 02744 + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) 02745 + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) 02746 - (ady * bdxtail + bdx * adytail)) 02747 + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx)); 02748 if ((det >= errbound) || (-det >= errbound)) { 02749 return det; 02750 } 02751 02752 finnow = fin1; 02753 finother = fin2; 02754 02755 if ((bdxtail != 0.0) || (bdytail != 0.0) 02756 || (cdxtail != 0.0) || (cdytail != 0.0)) { 02757 Square(adx, adxadx1, adxadx0); 02758 Square(ady, adyady1, adyady0); 02759 Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]); 02760 aa[3] = aa3; 02761 } 02762 if ((cdxtail != 0.0) || (cdytail != 0.0) 02763 || (adxtail != 0.0) || (adytail != 0.0)) { 02764 Square(bdx, bdxbdx1, bdxbdx0); 02765 Square(bdy, bdybdy1, bdybdy0); 02766 Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]); 02767 bb[3] = bb3; 02768 } 02769 if ((adxtail != 0.0) || (adytail != 0.0) 02770 || (bdxtail != 0.0) || (bdytail != 0.0)) { 02771 Square(cdx, cdxcdx1, cdxcdx0); 02772 Square(cdy, cdycdy1, cdycdy0); 02773 Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]); 02774 cc[3] = cc3; 02775 } 02776 02777 if (adxtail != 0.0) { 02778 axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc); 02779 temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx, 02780 temp16a); 02781 02782 axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc); 02783 temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b); 02784 02785 axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb); 02786 temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c); 02787 02788 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02789 temp16blen, temp16b, temp32a); 02790 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 02791 temp32alen, temp32a, temp48); 02792 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02793 temp48, finother); 02794 finswap = finnow; finnow = finother; finother = finswap; 02795 } 02796 if (adytail != 0.0) { 02797 aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc); 02798 temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady, 02799 temp16a); 02800 02801 aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb); 02802 temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b); 02803 02804 aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc); 02805 temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c); 02806 02807 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02808 temp16blen, temp16b, temp32a); 02809 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 02810 temp32alen, temp32a, temp48); 02811 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02812 temp48, finother); 02813 finswap = finnow; finnow = finother; finother = finswap; 02814 } 02815 if (bdxtail != 0.0) { 02816 bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca); 02817 temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx, 02818 temp16a); 02819 02820 bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa); 02821 temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b); 02822 02823 bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc); 02824 temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c); 02825 02826 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02827 temp16blen, temp16b, temp32a); 02828 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 02829 temp32alen, temp32a, temp48); 02830 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02831 temp48, finother); 02832 finswap = finnow; finnow = finother; finother = finswap; 02833 } 02834 if (bdytail != 0.0) { 02835 bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca); 02836 temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy, 02837 temp16a); 02838 02839 bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc); 02840 temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b); 02841 02842 bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa); 02843 temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c); 02844 02845 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02846 temp16blen, temp16b, temp32a); 02847 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 02848 temp32alen, temp32a, temp48); 02849 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02850 temp48, finother); 02851 finswap = finnow; finnow = finother; finother = finswap; 02852 } 02853 if (cdxtail != 0.0) { 02854 cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab); 02855 temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx, 02856 temp16a); 02857 02858 cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb); 02859 temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b); 02860 02861 cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa); 02862 temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c); 02863 02864 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02865 temp16blen, temp16b, temp32a); 02866 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 02867 temp32alen, temp32a, temp48); 02868 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02869 temp48, finother); 02870 finswap = finnow; finnow = finother; finother = finswap; 02871 } 02872 if (cdytail != 0.0) { 02873 cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab); 02874 temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy, 02875 temp16a); 02876 02877 cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa); 02878 temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b); 02879 02880 cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb); 02881 temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c); 02882 02883 temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02884 temp16blen, temp16b, temp32a); 02885 temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c, 02886 temp32alen, temp32a, temp48); 02887 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02888 temp48, finother); 02889 finswap = finnow; finnow = finother; finother = finswap; 02890 } 02891 02892 if ((adxtail != 0.0) || (adytail != 0.0)) { 02893 if ((bdxtail != 0.0) || (bdytail != 0.0) 02894 || (cdxtail != 0.0) || (cdytail != 0.0)) { 02895 Two_Product(bdxtail, cdy, ti1, ti0); 02896 Two_Product(bdx, cdytail, tj1, tj0); 02897 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); 02898 u[3] = u3; 02899 negate = -bdy; 02900 Two_Product(cdxtail, negate, ti1, ti0); 02901 negate = -bdytail; 02902 Two_Product(cdx, negate, tj1, tj0); 02903 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); 02904 v[3] = v3; 02905 bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct); 02906 02907 Two_Product(bdxtail, cdytail, ti1, ti0); 02908 Two_Product(cdxtail, bdytail, tj1, tj0); 02909 Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]); 02910 bctt[3] = bctt3; 02911 bcttlen = 4; 02912 } else { 02913 bct[0] = 0.0; 02914 bctlen = 1; 02915 bctt[0] = 0.0; 02916 bcttlen = 1; 02917 } 02918 02919 if (adxtail != 0.0) { 02920 temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a); 02921 axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct); 02922 temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx, 02923 temp32a); 02924 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02925 temp32alen, temp32a, temp48); 02926 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02927 temp48, finother); 02928 finswap = finnow; finnow = finother; finother = finswap; 02929 if (bdytail != 0.0) { 02930 temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8); 02931 temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, 02932 temp16a); 02933 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 02934 temp16a, finother); 02935 finswap = finnow; finnow = finother; finother = finswap; 02936 } 02937 if (cdytail != 0.0) { 02938 temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8); 02939 temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, 02940 temp16a); 02941 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 02942 temp16a, finother); 02943 finswap = finnow; finnow = finother; finother = finswap; 02944 } 02945 02946 temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail, 02947 temp32a); 02948 axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt); 02949 temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx, 02950 temp16a); 02951 temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail, 02952 temp16b); 02953 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02954 temp16blen, temp16b, temp32b); 02955 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 02956 temp32blen, temp32b, temp64); 02957 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 02958 temp64, finother); 02959 finswap = finnow; finnow = finother; finother = finswap; 02960 } 02961 if (adytail != 0.0) { 02962 temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a); 02963 aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct); 02964 temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady, 02965 temp32a); 02966 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02967 temp32alen, temp32a, temp48); 02968 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 02969 temp48, finother); 02970 finswap = finnow; finnow = finother; finother = finswap; 02971 02972 02973 temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail, 02974 temp32a); 02975 aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt); 02976 temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady, 02977 temp16a); 02978 temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail, 02979 temp16b); 02980 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 02981 temp16blen, temp16b, temp32b); 02982 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 02983 temp32blen, temp32b, temp64); 02984 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 02985 temp64, finother); 02986 finswap = finnow; finnow = finother; finother = finswap; 02987 } 02988 } 02989 if ((bdxtail != 0.0) || (bdytail != 0.0)) { 02990 if ((cdxtail != 0.0) || (cdytail != 0.0) 02991 || (adxtail != 0.0) || (adytail != 0.0)) { 02992 Two_Product(cdxtail, ady, ti1, ti0); 02993 Two_Product(cdx, adytail, tj1, tj0); 02994 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); 02995 u[3] = u3; 02996 negate = -cdy; 02997 Two_Product(adxtail, negate, ti1, ti0); 02998 negate = -cdytail; 02999 Two_Product(adx, negate, tj1, tj0); 03000 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); 03001 v[3] = v3; 03002 catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat); 03003 03004 Two_Product(cdxtail, adytail, ti1, ti0); 03005 Two_Product(adxtail, cdytail, tj1, tj0); 03006 Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]); 03007 catt[3] = catt3; 03008 cattlen = 4; 03009 } else { 03010 cat[0] = 0.0; 03011 catlen = 1; 03012 catt[0] = 0.0; 03013 cattlen = 1; 03014 } 03015 03016 if (bdxtail != 0.0) { 03017 temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a); 03018 bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat); 03019 temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx, 03020 temp32a); 03021 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03022 temp32alen, temp32a, temp48); 03023 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 03024 temp48, finother); 03025 finswap = finnow; finnow = finother; finother = finswap; 03026 if (cdytail != 0.0) { 03027 temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8); 03028 temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail, 03029 temp16a); 03030 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 03031 temp16a, finother); 03032 finswap = finnow; finnow = finother; finother = finswap; 03033 } 03034 if (adytail != 0.0) { 03035 temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8); 03036 temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, 03037 temp16a); 03038 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 03039 temp16a, finother); 03040 finswap = finnow; finnow = finother; finother = finswap; 03041 } 03042 03043 temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail, 03044 temp32a); 03045 bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt); 03046 temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx, 03047 temp16a); 03048 temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail, 03049 temp16b); 03050 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03051 temp16blen, temp16b, temp32b); 03052 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03053 temp32blen, temp32b, temp64); 03054 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 03055 temp64, finother); 03056 finswap = finnow; finnow = finother; finother = finswap; 03057 } 03058 if (bdytail != 0.0) { 03059 temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a); 03060 bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat); 03061 temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy, 03062 temp32a); 03063 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03064 temp32alen, temp32a, temp48); 03065 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 03066 temp48, finother); 03067 finswap = finnow; finnow = finother; finother = finswap; 03068 03069 03070 temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail, 03071 temp32a); 03072 bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt); 03073 temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy, 03074 temp16a); 03075 temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail, 03076 temp16b); 03077 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03078 temp16blen, temp16b, temp32b); 03079 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03080 temp32blen, temp32b, temp64); 03081 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 03082 temp64, finother); 03083 finswap = finnow; finnow = finother; finother = finswap; 03084 } 03085 } 03086 if ((cdxtail != 0.0) || (cdytail != 0.0)) { 03087 if ((adxtail != 0.0) || (adytail != 0.0) 03088 || (bdxtail != 0.0) || (bdytail != 0.0)) { 03089 Two_Product(adxtail, bdy, ti1, ti0); 03090 Two_Product(adx, bdytail, tj1, tj0); 03091 Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]); 03092 u[3] = u3; 03093 negate = -ady; 03094 Two_Product(bdxtail, negate, ti1, ti0); 03095 negate = -adytail; 03096 Two_Product(bdx, negate, tj1, tj0); 03097 Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]); 03098 v[3] = v3; 03099 abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt); 03100 03101 Two_Product(adxtail, bdytail, ti1, ti0); 03102 Two_Product(bdxtail, adytail, tj1, tj0); 03103 Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]); 03104 abtt[3] = abtt3; 03105 abttlen = 4; 03106 } else { 03107 abt[0] = 0.0; 03108 abtlen = 1; 03109 abtt[0] = 0.0; 03110 abttlen = 1; 03111 } 03112 03113 if (cdxtail != 0.0) { 03114 temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a); 03115 cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt); 03116 temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx, 03117 temp32a); 03118 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03119 temp32alen, temp32a, temp48); 03120 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 03121 temp48, finother); 03122 finswap = finnow; finnow = finother; finother = finswap; 03123 if (adytail != 0.0) { 03124 temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8); 03125 temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail, 03126 temp16a); 03127 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 03128 temp16a, finother); 03129 finswap = finnow; finnow = finother; finother = finswap; 03130 } 03131 if (bdytail != 0.0) { 03132 temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8); 03133 temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail, 03134 temp16a); 03135 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen, 03136 temp16a, finother); 03137 finswap = finnow; finnow = finother; finother = finswap; 03138 } 03139 03140 temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail, 03141 temp32a); 03142 cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt); 03143 temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx, 03144 temp16a); 03145 temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail, 03146 temp16b); 03147 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03148 temp16blen, temp16b, temp32b); 03149 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03150 temp32blen, temp32b, temp64); 03151 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 03152 temp64, finother); 03153 finswap = finnow; finnow = finother; finother = finswap; 03154 } 03155 if (cdytail != 0.0) { 03156 temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a); 03157 cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt); 03158 temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy, 03159 temp32a); 03160 temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03161 temp32alen, temp32a, temp48); 03162 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len, 03163 temp48, finother); 03164 finswap = finnow; finnow = finother; finother = finswap; 03165 03166 03167 temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail, 03168 temp32a); 03169 cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt); 03170 temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy, 03171 temp16a); 03172 temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail, 03173 temp16b); 03174 temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a, 03175 temp16blen, temp16b, temp32b); 03176 temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03177 temp32blen, temp32b, temp64); 03178 finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len, 03179 temp64, finother); 03180 finswap = finnow; finnow = finother; finother = finswap; 03181 } 03182 } 03183 03184 return finnow[finlength - 1]; 03185 } 03186 03187 REAL incircle(REAL *pa, REAL *pb, REAL *pc, REAL *pd) 03188 { 03189 REAL adx, bdx, cdx, ady, bdy, cdy; 03190 REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady; 03191 REAL alift, blift, clift; 03192 REAL det; 03193 REAL permanent, errbound; 03194 03195 adx = pa[0] - pd[0]; 03196 bdx = pb[0] - pd[0]; 03197 cdx = pc[0] - pd[0]; 03198 ady = pa[1] - pd[1]; 03199 bdy = pb[1] - pd[1]; 03200 cdy = pc[1] - pd[1]; 03201 03202 bdxcdy = bdx * cdy; 03203 cdxbdy = cdx * bdy; 03204 alift = adx * adx + ady * ady; 03205 03206 cdxady = cdx * ady; 03207 adxcdy = adx * cdy; 03208 blift = bdx * bdx + bdy * bdy; 03209 03210 adxbdy = adx * bdy; 03211 bdxady = bdx * ady; 03212 clift = cdx * cdx + cdy * cdy; 03213 03214 det = alift * (bdxcdy - cdxbdy) 03215 + blift * (cdxady - adxcdy) 03216 + clift * (adxbdy - bdxady); 03217 03218 permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift 03219 + (Absolute(cdxady) + Absolute(adxcdy)) * blift 03220 + (Absolute(adxbdy) + Absolute(bdxady)) * clift; 03221 errbound = iccerrboundA * permanent; 03222 if ((det > errbound) || (-det > errbound)) { 03223 return det; 03224 } 03225 03226 return incircleadapt(pa, pb, pc, pd, permanent); 03227 } 03228 03229 /*****************************************************************************/ 03230 /* */ 03231 /* inspherefast() Approximate 3D insphere test. Nonrobust. */ 03232 /* insphereexact() Exact 3D insphere test. Robust. */ 03233 /* insphereslow() Another exact 3D insphere test. Robust. */ 03234 /* insphere() Adaptive exact 3D insphere test. Robust. */ 03235 /* */ 03236 /* Return a positive value if the point pe lies inside the */ 03237 /* sphere passing through pa, pb, pc, and pd; a negative value */ 03238 /* if it lies outside; and zero if the five points are */ 03239 /* cospherical. The points pa, pb, pc, and pd must be ordered */ 03240 /* so that they have a positive orientation (as defined by */ 03241 /* orient3d()), or the sign of the result will be reversed. */ 03242 /* */ 03243 /* Only the first and last routine should be used; the middle two are for */ 03244 /* timings. */ 03245 /* */ 03246 /* The last three use exact arithmetic to ensure a correct answer. The */ 03247 /* result returned is the determinant of a matrix. In insphere() only, */ 03248 /* this determinant is computed adaptively, in the sense that exact */ 03249 /* arithmetic is used only to the degree it is needed to ensure that the */ 03250 /* returned value has the correct sign. Hence, insphere() is usually quite */ 03251 /* fast, but will run more slowly when the input points are cospherical or */ 03252 /* nearly so. */ 03253 /* */ 03254 /*****************************************************************************/ 03255 03256 REAL inspherefast(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) 03257 { 03258 REAL aex, bex, cex, dex; 03259 REAL aey, bey, cey, dey; 03260 REAL aez, bez, cez, dez; 03261 REAL alift, blift, clift, dlift; 03262 REAL ab, bc, cd, da, ac, bd; 03263 REAL abc, bcd, cda, dab; 03264 03265 aex = pa[0] - pe[0]; 03266 bex = pb[0] - pe[0]; 03267 cex = pc[0] - pe[0]; 03268 dex = pd[0] - pe[0]; 03269 aey = pa[1] - pe[1]; 03270 bey = pb[1] - pe[1]; 03271 cey = pc[1] - pe[1]; 03272 dey = pd[1] - pe[1]; 03273 aez = pa[2] - pe[2]; 03274 bez = pb[2] - pe[2]; 03275 cez = pc[2] - pe[2]; 03276 dez = pd[2] - pe[2]; 03277 03278 ab = aex * bey - bex * aey; 03279 bc = bex * cey - cex * bey; 03280 cd = cex * dey - dex * cey; 03281 da = dex * aey - aex * dey; 03282 03283 ac = aex * cey - cex * aey; 03284 bd = bex * dey - dex * bey; 03285 03286 abc = aez * bc - bez * ac + cez * ab; 03287 bcd = bez * cd - cez * bd + dez * bc; 03288 cda = cez * da + dez * ac + aez * cd; 03289 dab = dez * ab + aez * bd + bez * da; 03290 03291 alift = aex * aex + aey * aey + aez * aez; 03292 blift = bex * bex + bey * bey + bez * bez; 03293 clift = cex * cex + cey * cey + cez * cez; 03294 dlift = dex * dex + dey * dey + dez * dez; 03295 03296 return (dlift * abc - clift * dab) + (blift * cda - alift * bcd); 03297 } 03298 03299 REAL insphereexact(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) 03300 { 03301 INEXACT REAL axby1, bxcy1, cxdy1, dxey1, exay1; 03302 INEXACT REAL bxay1, cxby1, dxcy1, exdy1, axey1; 03303 INEXACT REAL axcy1, bxdy1, cxey1, dxay1, exby1; 03304 INEXACT REAL cxay1, dxby1, excy1, axdy1, bxey1; 03305 REAL axby0, bxcy0, cxdy0, dxey0, exay0; 03306 REAL bxay0, cxby0, dxcy0, exdy0, axey0; 03307 REAL axcy0, bxdy0, cxey0, dxay0, exby0; 03308 REAL cxay0, dxby0, excy0, axdy0, bxey0; 03309 REAL ab[4], bc[4], cd[4], de[4], ea[4]; 03310 REAL ac[4], bd[4], ce[4], da[4], eb[4]; 03311 REAL temp8a[8], temp8b[8], temp16[16]; 03312 int temp8alen, temp8blen, temp16len; 03313 REAL abc[24], bcd[24], cde[24], dea[24], eab[24]; 03314 REAL abd[24], bce[24], cda[24], deb[24], eac[24]; 03315 int abclen, bcdlen, cdelen, dealen, eablen; 03316 int abdlen, bcelen, cdalen, deblen, eaclen; 03317 REAL temp48a[48], temp48b[48]; 03318 int temp48alen, temp48blen; 03319 REAL abcd[96], bcde[96], cdea[96], deab[96], eabc[96]; 03320 int abcdlen, bcdelen, cdealen, deablen, eabclen; 03321 REAL temp192[192]; 03322 REAL det384x[384], det384y[384], det384z[384]; 03323 int xlen, ylen, zlen; 03324 REAL detxy[768]; 03325 int xylen; 03326 REAL adet[1152], bdet[1152], cdet[1152], ddet[1152], edet[1152]; 03327 int alen, blen, clen, dlen, elen; 03328 REAL abdet[2304], cddet[2304], cdedet[3456]; 03329 int ablen, cdlen; 03330 REAL deter[5760]; 03331 int deterlen; 03332 int i; 03333 03334 INEXACT REAL bvirt; 03335 REAL avirt, bround, around; 03336 INEXACT REAL c; 03337 INEXACT REAL abig; 03338 REAL ahi, alo, bhi, blo; 03339 REAL err1, err2, err3; 03340 INEXACT REAL _i, _j; 03341 REAL _0; 03342 03343 Two_Product(pa[0], pb[1], axby1, axby0); 03344 Two_Product(pb[0], pa[1], bxay1, bxay0); 03345 Two_Two_Diff(axby1, axby0, bxay1, bxay0, ab[3], ab[2], ab[1], ab[0]); 03346 03347 Two_Product(pb[0], pc[1], bxcy1, bxcy0); 03348 Two_Product(pc[0], pb[1], cxby1, cxby0); 03349 Two_Two_Diff(bxcy1, bxcy0, cxby1, cxby0, bc[3], bc[2], bc[1], bc[0]); 03350 03351 Two_Product(pc[0], pd[1], cxdy1, cxdy0); 03352 Two_Product(pd[0], pc[1], dxcy1, dxcy0); 03353 Two_Two_Diff(cxdy1, cxdy0, dxcy1, dxcy0, cd[3], cd[2], cd[1], cd[0]); 03354 03355 Two_Product(pd[0], pe[1], dxey1, dxey0); 03356 Two_Product(pe[0], pd[1], exdy1, exdy0); 03357 Two_Two_Diff(dxey1, dxey0, exdy1, exdy0, de[3], de[2], de[1], de[0]); 03358 03359 Two_Product(pe[0], pa[1], exay1, exay0); 03360 Two_Product(pa[0], pe[1], axey1, axey0); 03361 Two_Two_Diff(exay1, exay0, axey1, axey0, ea[3], ea[2], ea[1], ea[0]); 03362 03363 Two_Product(pa[0], pc[1], axcy1, axcy0); 03364 Two_Product(pc[0], pa[1], cxay1, cxay0); 03365 Two_Two_Diff(axcy1, axcy0, cxay1, cxay0, ac[3], ac[2], ac[1], ac[0]); 03366 03367 Two_Product(pb[0], pd[1], bxdy1, bxdy0); 03368 Two_Product(pd[0], pb[1], dxby1, dxby0); 03369 Two_Two_Diff(bxdy1, bxdy0, dxby1, dxby0, bd[3], bd[2], bd[1], bd[0]); 03370 03371 Two_Product(pc[0], pe[1], cxey1, cxey0); 03372 Two_Product(pe[0], pc[1], excy1, excy0); 03373 Two_Two_Diff(cxey1, cxey0, excy1, excy0, ce[3], ce[2], ce[1], ce[0]); 03374 03375 Two_Product(pd[0], pa[1], dxay1, dxay0); 03376 Two_Product(pa[0], pd[1], axdy1, axdy0); 03377 Two_Two_Diff(dxay1, dxay0, axdy1, axdy0, da[3], da[2], da[1], da[0]); 03378 03379 Two_Product(pe[0], pb[1], exby1, exby0); 03380 Two_Product(pb[0], pe[1], bxey1, bxey0); 03381 Two_Two_Diff(exby1, exby0, bxey1, bxey0, eb[3], eb[2], eb[1], eb[0]); 03382 03383 temp8alen = scale_expansion_zeroelim(4, bc, pa[2], temp8a); 03384 temp8blen = scale_expansion_zeroelim(4, ac, -pb[2], temp8b); 03385 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03386 temp16); 03387 temp8alen = scale_expansion_zeroelim(4, ab, pc[2], temp8a); 03388 abclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03389 abc); 03390 03391 temp8alen = scale_expansion_zeroelim(4, cd, pb[2], temp8a); 03392 temp8blen = scale_expansion_zeroelim(4, bd, -pc[2], temp8b); 03393 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03394 temp16); 03395 temp8alen = scale_expansion_zeroelim(4, bc, pd[2], temp8a); 03396 bcdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03397 bcd); 03398 03399 temp8alen = scale_expansion_zeroelim(4, de, pc[2], temp8a); 03400 temp8blen = scale_expansion_zeroelim(4, ce, -pd[2], temp8b); 03401 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03402 temp16); 03403 temp8alen = scale_expansion_zeroelim(4, cd, pe[2], temp8a); 03404 cdelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03405 cde); 03406 03407 temp8alen = scale_expansion_zeroelim(4, ea, pd[2], temp8a); 03408 temp8blen = scale_expansion_zeroelim(4, da, -pe[2], temp8b); 03409 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03410 temp16); 03411 temp8alen = scale_expansion_zeroelim(4, de, pa[2], temp8a); 03412 dealen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03413 dea); 03414 03415 temp8alen = scale_expansion_zeroelim(4, ab, pe[2], temp8a); 03416 temp8blen = scale_expansion_zeroelim(4, eb, -pa[2], temp8b); 03417 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03418 temp16); 03419 temp8alen = scale_expansion_zeroelim(4, ea, pb[2], temp8a); 03420 eablen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03421 eab); 03422 03423 temp8alen = scale_expansion_zeroelim(4, bd, pa[2], temp8a); 03424 temp8blen = scale_expansion_zeroelim(4, da, pb[2], temp8b); 03425 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03426 temp16); 03427 temp8alen = scale_expansion_zeroelim(4, ab, pd[2], temp8a); 03428 abdlen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03429 abd); 03430 03431 temp8alen = scale_expansion_zeroelim(4, ce, pb[2], temp8a); 03432 temp8blen = scale_expansion_zeroelim(4, eb, pc[2], temp8b); 03433 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03434 temp16); 03435 temp8alen = scale_expansion_zeroelim(4, bc, pe[2], temp8a); 03436 bcelen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03437 bce); 03438 03439 temp8alen = scale_expansion_zeroelim(4, da, pc[2], temp8a); 03440 temp8blen = scale_expansion_zeroelim(4, ac, pd[2], temp8b); 03441 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03442 temp16); 03443 temp8alen = scale_expansion_zeroelim(4, cd, pa[2], temp8a); 03444 cdalen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03445 cda); 03446 03447 temp8alen = scale_expansion_zeroelim(4, eb, pd[2], temp8a); 03448 temp8blen = scale_expansion_zeroelim(4, bd, pe[2], temp8b); 03449 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03450 temp16); 03451 temp8alen = scale_expansion_zeroelim(4, de, pb[2], temp8a); 03452 deblen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03453 deb); 03454 03455 temp8alen = scale_expansion_zeroelim(4, ac, pe[2], temp8a); 03456 temp8blen = scale_expansion_zeroelim(4, ce, pa[2], temp8b); 03457 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp8blen, temp8b, 03458 temp16); 03459 temp8alen = scale_expansion_zeroelim(4, ea, pc[2], temp8a); 03460 eaclen = fast_expansion_sum_zeroelim(temp8alen, temp8a, temp16len, temp16, 03461 eac); 03462 03463 temp48alen = fast_expansion_sum_zeroelim(cdelen, cde, bcelen, bce, temp48a); 03464 temp48blen = fast_expansion_sum_zeroelim(deblen, deb, bcdlen, bcd, temp48b); 03465 for (i = 0; i < temp48blen; i++) { 03466 temp48b[i] = -temp48b[i]; 03467 } 03468 bcdelen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 03469 temp48blen, temp48b, bcde); 03470 xlen = scale_expansion_zeroelim(bcdelen, bcde, pa[0], temp192); 03471 xlen = scale_expansion_zeroelim(xlen, temp192, pa[0], det384x); 03472 ylen = scale_expansion_zeroelim(bcdelen, bcde, pa[1], temp192); 03473 ylen = scale_expansion_zeroelim(ylen, temp192, pa[1], det384y); 03474 zlen = scale_expansion_zeroelim(bcdelen, bcde, pa[2], temp192); 03475 zlen = scale_expansion_zeroelim(zlen, temp192, pa[2], det384z); 03476 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 03477 alen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, adet); 03478 03479 temp48alen = fast_expansion_sum_zeroelim(dealen, dea, cdalen, cda, temp48a); 03480 temp48blen = fast_expansion_sum_zeroelim(eaclen, eac, cdelen, cde, temp48b); 03481 for (i = 0; i < temp48blen; i++) { 03482 temp48b[i] = -temp48b[i]; 03483 } 03484 cdealen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 03485 temp48blen, temp48b, cdea); 03486 xlen = scale_expansion_zeroelim(cdealen, cdea, pb[0], temp192); 03487 xlen = scale_expansion_zeroelim(xlen, temp192, pb[0], det384x); 03488 ylen = scale_expansion_zeroelim(cdealen, cdea, pb[1], temp192); 03489 ylen = scale_expansion_zeroelim(ylen, temp192, pb[1], det384y); 03490 zlen = scale_expansion_zeroelim(cdealen, cdea, pb[2], temp192); 03491 zlen = scale_expansion_zeroelim(zlen, temp192, pb[2], det384z); 03492 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 03493 blen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, bdet); 03494 03495 temp48alen = fast_expansion_sum_zeroelim(eablen, eab, deblen, deb, temp48a); 03496 temp48blen = fast_expansion_sum_zeroelim(abdlen, abd, dealen, dea, temp48b); 03497 for (i = 0; i < temp48blen; i++) { 03498 temp48b[i] = -temp48b[i]; 03499 } 03500 deablen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 03501 temp48blen, temp48b, deab); 03502 xlen = scale_expansion_zeroelim(deablen, deab, pc[0], temp192); 03503 xlen = scale_expansion_zeroelim(xlen, temp192, pc[0], det384x); 03504 ylen = scale_expansion_zeroelim(deablen, deab, pc[1], temp192); 03505 ylen = scale_expansion_zeroelim(ylen, temp192, pc[1], det384y); 03506 zlen = scale_expansion_zeroelim(deablen, deab, pc[2], temp192); 03507 zlen = scale_expansion_zeroelim(zlen, temp192, pc[2], det384z); 03508 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 03509 clen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, cdet); 03510 03511 temp48alen = fast_expansion_sum_zeroelim(abclen, abc, eaclen, eac, temp48a); 03512 temp48blen = fast_expansion_sum_zeroelim(bcelen, bce, eablen, eab, temp48b); 03513 for (i = 0; i < temp48blen; i++) { 03514 temp48b[i] = -temp48b[i]; 03515 } 03516 eabclen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 03517 temp48blen, temp48b, eabc); 03518 xlen = scale_expansion_zeroelim(eabclen, eabc, pd[0], temp192); 03519 xlen = scale_expansion_zeroelim(xlen, temp192, pd[0], det384x); 03520 ylen = scale_expansion_zeroelim(eabclen, eabc, pd[1], temp192); 03521 ylen = scale_expansion_zeroelim(ylen, temp192, pd[1], det384y); 03522 zlen = scale_expansion_zeroelim(eabclen, eabc, pd[2], temp192); 03523 zlen = scale_expansion_zeroelim(zlen, temp192, pd[2], det384z); 03524 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 03525 dlen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, ddet); 03526 03527 temp48alen = fast_expansion_sum_zeroelim(bcdlen, bcd, abdlen, abd, temp48a); 03528 temp48blen = fast_expansion_sum_zeroelim(cdalen, cda, abclen, abc, temp48b); 03529 for (i = 0; i < temp48blen; i++) { 03530 temp48b[i] = -temp48b[i]; 03531 } 03532 abcdlen = fast_expansion_sum_zeroelim(temp48alen, temp48a, 03533 temp48blen, temp48b, abcd); 03534 xlen = scale_expansion_zeroelim(abcdlen, abcd, pe[0], temp192); 03535 xlen = scale_expansion_zeroelim(xlen, temp192, pe[0], det384x); 03536 ylen = scale_expansion_zeroelim(abcdlen, abcd, pe[1], temp192); 03537 ylen = scale_expansion_zeroelim(ylen, temp192, pe[1], det384y); 03538 zlen = scale_expansion_zeroelim(abcdlen, abcd, pe[2], temp192); 03539 zlen = scale_expansion_zeroelim(zlen, temp192, pe[2], det384z); 03540 xylen = fast_expansion_sum_zeroelim(xlen, det384x, ylen, det384y, detxy); 03541 elen = fast_expansion_sum_zeroelim(xylen, detxy, zlen, det384z, edet); 03542 03543 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 03544 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); 03545 cdelen = fast_expansion_sum_zeroelim(cdlen, cddet, elen, edet, cdedet); 03546 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdelen, cdedet, deter); 03547 03548 return deter[deterlen - 1]; 03549 } 03550 03551 REAL insphereslow(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) 03552 { 03553 INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; 03554 REAL aextail, bextail, cextail, dextail; 03555 REAL aeytail, beytail, ceytail, deytail; 03556 REAL aeztail, beztail, ceztail, deztail; 03557 REAL negate, negatetail; 03558 INEXACT REAL axby7, bxcy7, cxdy7, dxay7, axcy7, bxdy7; 03559 INEXACT REAL bxay7, cxby7, dxcy7, axdy7, cxay7, dxby7; 03560 REAL axby[8], bxcy[8], cxdy[8], dxay[8], axcy[8], bxdy[8]; 03561 REAL bxay[8], cxby[8], dxcy[8], axdy[8], cxay[8], dxby[8]; 03562 REAL ab[16], bc[16], cd[16], da[16], ac[16], bd[16]; 03563 int ablen, bclen, cdlen, dalen, aclen, bdlen; 03564 REAL temp32a[32], temp32b[32], temp64a[64], temp64b[64], temp64c[64]; 03565 int temp32alen, temp32blen, temp64alen, temp64blen, temp64clen; 03566 REAL temp128[128], temp192[192]; 03567 int temp128len, temp192len; 03568 REAL detx[384], detxx[768], detxt[384], detxxt[768], detxtxt[768]; 03569 int xlen, xxlen, xtlen, xxtlen, xtxtlen; 03570 REAL x1[1536], x2[2304]; 03571 int x1len, x2len; 03572 REAL dety[384], detyy[768], detyt[384], detyyt[768], detytyt[768]; 03573 int ylen, yylen, ytlen, yytlen, ytytlen; 03574 REAL y1[1536], y2[2304]; 03575 int y1len, y2len; 03576 REAL detz[384], detzz[768], detzt[384], detzzt[768], detztzt[768]; 03577 int zlen, zzlen, ztlen, zztlen, ztztlen; 03578 REAL z1[1536], z2[2304]; 03579 int z1len, z2len; 03580 REAL detxy[4608]; 03581 int xylen; 03582 REAL adet[6912], bdet[6912], cdet[6912], ddet[6912]; 03583 int alen, blen, clen, dlen; 03584 REAL abdet[13824], cddet[13824], deter[27648]; 03585 int deterlen; 03586 int i; 03587 03588 INEXACT REAL bvirt; 03589 REAL avirt, bround, around; 03590 INEXACT REAL c; 03591 INEXACT REAL abig; 03592 REAL a0hi, a0lo, a1hi, a1lo, bhi, blo; 03593 REAL err1, err2, err3; 03594 INEXACT REAL _i, _j, _k, _l, _m, _n; 03595 REAL _0, _1, _2; 03596 03597 Two_Diff(pa[0], pe[0], aex, aextail); 03598 Two_Diff(pa[1], pe[1], aey, aeytail); 03599 Two_Diff(pa[2], pe[2], aez, aeztail); 03600 Two_Diff(pb[0], pe[0], bex, bextail); 03601 Two_Diff(pb[1], pe[1], bey, beytail); 03602 Two_Diff(pb[2], pe[2], bez, beztail); 03603 Two_Diff(pc[0], pe[0], cex, cextail); 03604 Two_Diff(pc[1], pe[1], cey, ceytail); 03605 Two_Diff(pc[2], pe[2], cez, ceztail); 03606 Two_Diff(pd[0], pe[0], dex, dextail); 03607 Two_Diff(pd[1], pe[1], dey, deytail); 03608 Two_Diff(pd[2], pe[2], dez, deztail); 03609 03610 Two_Two_Product(aex, aextail, bey, beytail, 03611 axby7, axby[6], axby[5], axby[4], 03612 axby[3], axby[2], axby[1], axby[0]); 03613 axby[7] = axby7; 03614 negate = -aey; 03615 negatetail = -aeytail; 03616 Two_Two_Product(bex, bextail, negate, negatetail, 03617 bxay7, bxay[6], bxay[5], bxay[4], 03618 bxay[3], bxay[2], bxay[1], bxay[0]); 03619 bxay[7] = bxay7; 03620 ablen = fast_expansion_sum_zeroelim(8, axby, 8, bxay, ab); 03621 Two_Two_Product(bex, bextail, cey, ceytail, 03622 bxcy7, bxcy[6], bxcy[5], bxcy[4], 03623 bxcy[3], bxcy[2], bxcy[1], bxcy[0]); 03624 bxcy[7] = bxcy7; 03625 negate = -bey; 03626 negatetail = -beytail; 03627 Two_Two_Product(cex, cextail, negate, negatetail, 03628 cxby7, cxby[6], cxby[5], cxby[4], 03629 cxby[3], cxby[2], cxby[1], cxby[0]); 03630 cxby[7] = cxby7; 03631 bclen = fast_expansion_sum_zeroelim(8, bxcy, 8, cxby, bc); 03632 Two_Two_Product(cex, cextail, dey, deytail, 03633 cxdy7, cxdy[6], cxdy[5], cxdy[4], 03634 cxdy[3], cxdy[2], cxdy[1], cxdy[0]); 03635 cxdy[7] = cxdy7; 03636 negate = -cey; 03637 negatetail = -ceytail; 03638 Two_Two_Product(dex, dextail, negate, negatetail, 03639 dxcy7, dxcy[6], dxcy[5], dxcy[4], 03640 dxcy[3], dxcy[2], dxcy[1], dxcy[0]); 03641 dxcy[7] = dxcy7; 03642 cdlen = fast_expansion_sum_zeroelim(8, cxdy, 8, dxcy, cd); 03643 Two_Two_Product(dex, dextail, aey, aeytail, 03644 dxay7, dxay[6], dxay[5], dxay[4], 03645 dxay[3], dxay[2], dxay[1], dxay[0]); 03646 dxay[7] = dxay7; 03647 negate = -dey; 03648 negatetail = -deytail; 03649 Two_Two_Product(aex, aextail, negate, negatetail, 03650 axdy7, axdy[6], axdy[5], axdy[4], 03651 axdy[3], axdy[2], axdy[1], axdy[0]); 03652 axdy[7] = axdy7; 03653 dalen = fast_expansion_sum_zeroelim(8, dxay, 8, axdy, da); 03654 Two_Two_Product(aex, aextail, cey, ceytail, 03655 axcy7, axcy[6], axcy[5], axcy[4], 03656 axcy[3], axcy[2], axcy[1], axcy[0]); 03657 axcy[7] = axcy7; 03658 negate = -aey; 03659 negatetail = -aeytail; 03660 Two_Two_Product(cex, cextail, negate, negatetail, 03661 cxay7, cxay[6], cxay[5], cxay[4], 03662 cxay[3], cxay[2], cxay[1], cxay[0]); 03663 cxay[7] = cxay7; 03664 aclen = fast_expansion_sum_zeroelim(8, axcy, 8, cxay, ac); 03665 Two_Two_Product(bex, bextail, dey, deytail, 03666 bxdy7, bxdy[6], bxdy[5], bxdy[4], 03667 bxdy[3], bxdy[2], bxdy[1], bxdy[0]); 03668 bxdy[7] = bxdy7; 03669 negate = -bey; 03670 negatetail = -beytail; 03671 Two_Two_Product(dex, dextail, negate, negatetail, 03672 dxby7, dxby[6], dxby[5], dxby[4], 03673 dxby[3], dxby[2], dxby[1], dxby[0]); 03674 dxby[7] = dxby7; 03675 bdlen = fast_expansion_sum_zeroelim(8, bxdy, 8, dxby, bd); 03676 03677 temp32alen = scale_expansion_zeroelim(cdlen, cd, -bez, temp32a); 03678 temp32blen = scale_expansion_zeroelim(cdlen, cd, -beztail, temp32b); 03679 temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03680 temp32blen, temp32b, temp64a); 03681 temp32alen = scale_expansion_zeroelim(bdlen, bd, cez, temp32a); 03682 temp32blen = scale_expansion_zeroelim(bdlen, bd, ceztail, temp32b); 03683 temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03684 temp32blen, temp32b, temp64b); 03685 temp32alen = scale_expansion_zeroelim(bclen, bc, -dez, temp32a); 03686 temp32blen = scale_expansion_zeroelim(bclen, bc, -deztail, temp32b); 03687 temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03688 temp32blen, temp32b, temp64c); 03689 temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, 03690 temp64blen, temp64b, temp128); 03691 temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, 03692 temp128len, temp128, temp192); 03693 xlen = scale_expansion_zeroelim(temp192len, temp192, aex, detx); 03694 xxlen = scale_expansion_zeroelim(xlen, detx, aex, detxx); 03695 xtlen = scale_expansion_zeroelim(temp192len, temp192, aextail, detxt); 03696 xxtlen = scale_expansion_zeroelim(xtlen, detxt, aex, detxxt); 03697 for (i = 0; i < xxtlen; i++) { 03698 detxxt[i] *= 2.0; 03699 } 03700 xtxtlen = scale_expansion_zeroelim(xtlen, detxt, aextail, detxtxt); 03701 x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); 03702 x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); 03703 ylen = scale_expansion_zeroelim(temp192len, temp192, aey, dety); 03704 yylen = scale_expansion_zeroelim(ylen, dety, aey, detyy); 03705 ytlen = scale_expansion_zeroelim(temp192len, temp192, aeytail, detyt); 03706 yytlen = scale_expansion_zeroelim(ytlen, detyt, aey, detyyt); 03707 for (i = 0; i < yytlen; i++) { 03708 detyyt[i] *= 2.0; 03709 } 03710 ytytlen = scale_expansion_zeroelim(ytlen, detyt, aeytail, detytyt); 03711 y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); 03712 y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); 03713 zlen = scale_expansion_zeroelim(temp192len, temp192, aez, detz); 03714 zzlen = scale_expansion_zeroelim(zlen, detz, aez, detzz); 03715 ztlen = scale_expansion_zeroelim(temp192len, temp192, aeztail, detzt); 03716 zztlen = scale_expansion_zeroelim(ztlen, detzt, aez, detzzt); 03717 for (i = 0; i < zztlen; i++) { 03718 detzzt[i] *= 2.0; 03719 } 03720 ztztlen = scale_expansion_zeroelim(ztlen, detzt, aeztail, detztzt); 03721 z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); 03722 z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); 03723 xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); 03724 alen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, adet); 03725 03726 temp32alen = scale_expansion_zeroelim(dalen, da, cez, temp32a); 03727 temp32blen = scale_expansion_zeroelim(dalen, da, ceztail, temp32b); 03728 temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03729 temp32blen, temp32b, temp64a); 03730 temp32alen = scale_expansion_zeroelim(aclen, ac, dez, temp32a); 03731 temp32blen = scale_expansion_zeroelim(aclen, ac, deztail, temp32b); 03732 temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03733 temp32blen, temp32b, temp64b); 03734 temp32alen = scale_expansion_zeroelim(cdlen, cd, aez, temp32a); 03735 temp32blen = scale_expansion_zeroelim(cdlen, cd, aeztail, temp32b); 03736 temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03737 temp32blen, temp32b, temp64c); 03738 temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, 03739 temp64blen, temp64b, temp128); 03740 temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, 03741 temp128len, temp128, temp192); 03742 xlen = scale_expansion_zeroelim(temp192len, temp192, bex, detx); 03743 xxlen = scale_expansion_zeroelim(xlen, detx, bex, detxx); 03744 xtlen = scale_expansion_zeroelim(temp192len, temp192, bextail, detxt); 03745 xxtlen = scale_expansion_zeroelim(xtlen, detxt, bex, detxxt); 03746 for (i = 0; i < xxtlen; i++) { 03747 detxxt[i] *= 2.0; 03748 } 03749 xtxtlen = scale_expansion_zeroelim(xtlen, detxt, bextail, detxtxt); 03750 x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); 03751 x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); 03752 ylen = scale_expansion_zeroelim(temp192len, temp192, bey, dety); 03753 yylen = scale_expansion_zeroelim(ylen, dety, bey, detyy); 03754 ytlen = scale_expansion_zeroelim(temp192len, temp192, beytail, detyt); 03755 yytlen = scale_expansion_zeroelim(ytlen, detyt, bey, detyyt); 03756 for (i = 0; i < yytlen; i++) { 03757 detyyt[i] *= 2.0; 03758 } 03759 ytytlen = scale_expansion_zeroelim(ytlen, detyt, beytail, detytyt); 03760 y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); 03761 y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); 03762 zlen = scale_expansion_zeroelim(temp192len, temp192, bez, detz); 03763 zzlen = scale_expansion_zeroelim(zlen, detz, bez, detzz); 03764 ztlen = scale_expansion_zeroelim(temp192len, temp192, beztail, detzt); 03765 zztlen = scale_expansion_zeroelim(ztlen, detzt, bez, detzzt); 03766 for (i = 0; i < zztlen; i++) { 03767 detzzt[i] *= 2.0; 03768 } 03769 ztztlen = scale_expansion_zeroelim(ztlen, detzt, beztail, detztzt); 03770 z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); 03771 z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); 03772 xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); 03773 blen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, bdet); 03774 03775 temp32alen = scale_expansion_zeroelim(ablen, ab, -dez, temp32a); 03776 temp32blen = scale_expansion_zeroelim(ablen, ab, -deztail, temp32b); 03777 temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03778 temp32blen, temp32b, temp64a); 03779 temp32alen = scale_expansion_zeroelim(bdlen, bd, -aez, temp32a); 03780 temp32blen = scale_expansion_zeroelim(bdlen, bd, -aeztail, temp32b); 03781 temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03782 temp32blen, temp32b, temp64b); 03783 temp32alen = scale_expansion_zeroelim(dalen, da, -bez, temp32a); 03784 temp32blen = scale_expansion_zeroelim(dalen, da, -beztail, temp32b); 03785 temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03786 temp32blen, temp32b, temp64c); 03787 temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, 03788 temp64blen, temp64b, temp128); 03789 temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, 03790 temp128len, temp128, temp192); 03791 xlen = scale_expansion_zeroelim(temp192len, temp192, cex, detx); 03792 xxlen = scale_expansion_zeroelim(xlen, detx, cex, detxx); 03793 xtlen = scale_expansion_zeroelim(temp192len, temp192, cextail, detxt); 03794 xxtlen = scale_expansion_zeroelim(xtlen, detxt, cex, detxxt); 03795 for (i = 0; i < xxtlen; i++) { 03796 detxxt[i] *= 2.0; 03797 } 03798 xtxtlen = scale_expansion_zeroelim(xtlen, detxt, cextail, detxtxt); 03799 x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); 03800 x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); 03801 ylen = scale_expansion_zeroelim(temp192len, temp192, cey, dety); 03802 yylen = scale_expansion_zeroelim(ylen, dety, cey, detyy); 03803 ytlen = scale_expansion_zeroelim(temp192len, temp192, ceytail, detyt); 03804 yytlen = scale_expansion_zeroelim(ytlen, detyt, cey, detyyt); 03805 for (i = 0; i < yytlen; i++) { 03806 detyyt[i] *= 2.0; 03807 } 03808 ytytlen = scale_expansion_zeroelim(ytlen, detyt, ceytail, detytyt); 03809 y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); 03810 y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); 03811 zlen = scale_expansion_zeroelim(temp192len, temp192, cez, detz); 03812 zzlen = scale_expansion_zeroelim(zlen, detz, cez, detzz); 03813 ztlen = scale_expansion_zeroelim(temp192len, temp192, ceztail, detzt); 03814 zztlen = scale_expansion_zeroelim(ztlen, detzt, cez, detzzt); 03815 for (i = 0; i < zztlen; i++) { 03816 detzzt[i] *= 2.0; 03817 } 03818 ztztlen = scale_expansion_zeroelim(ztlen, detzt, ceztail, detztzt); 03819 z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); 03820 z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); 03821 xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); 03822 clen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, cdet); 03823 03824 temp32alen = scale_expansion_zeroelim(bclen, bc, aez, temp32a); 03825 temp32blen = scale_expansion_zeroelim(bclen, bc, aeztail, temp32b); 03826 temp64alen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03827 temp32blen, temp32b, temp64a); 03828 temp32alen = scale_expansion_zeroelim(aclen, ac, -bez, temp32a); 03829 temp32blen = scale_expansion_zeroelim(aclen, ac, -beztail, temp32b); 03830 temp64blen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03831 temp32blen, temp32b, temp64b); 03832 temp32alen = scale_expansion_zeroelim(ablen, ab, cez, temp32a); 03833 temp32blen = scale_expansion_zeroelim(ablen, ab, ceztail, temp32b); 03834 temp64clen = fast_expansion_sum_zeroelim(temp32alen, temp32a, 03835 temp32blen, temp32b, temp64c); 03836 temp128len = fast_expansion_sum_zeroelim(temp64alen, temp64a, 03837 temp64blen, temp64b, temp128); 03838 temp192len = fast_expansion_sum_zeroelim(temp64clen, temp64c, 03839 temp128len, temp128, temp192); 03840 xlen = scale_expansion_zeroelim(temp192len, temp192, dex, detx); 03841 xxlen = scale_expansion_zeroelim(xlen, detx, dex, detxx); 03842 xtlen = scale_expansion_zeroelim(temp192len, temp192, dextail, detxt); 03843 xxtlen = scale_expansion_zeroelim(xtlen, detxt, dex, detxxt); 03844 for (i = 0; i < xxtlen; i++) { 03845 detxxt[i] *= 2.0; 03846 } 03847 xtxtlen = scale_expansion_zeroelim(xtlen, detxt, dextail, detxtxt); 03848 x1len = fast_expansion_sum_zeroelim(xxlen, detxx, xxtlen, detxxt, x1); 03849 x2len = fast_expansion_sum_zeroelim(x1len, x1, xtxtlen, detxtxt, x2); 03850 ylen = scale_expansion_zeroelim(temp192len, temp192, dey, dety); 03851 yylen = scale_expansion_zeroelim(ylen, dety, dey, detyy); 03852 ytlen = scale_expansion_zeroelim(temp192len, temp192, deytail, detyt); 03853 yytlen = scale_expansion_zeroelim(ytlen, detyt, dey, detyyt); 03854 for (i = 0; i < yytlen; i++) { 03855 detyyt[i] *= 2.0; 03856 } 03857 ytytlen = scale_expansion_zeroelim(ytlen, detyt, deytail, detytyt); 03858 y1len = fast_expansion_sum_zeroelim(yylen, detyy, yytlen, detyyt, y1); 03859 y2len = fast_expansion_sum_zeroelim(y1len, y1, ytytlen, detytyt, y2); 03860 zlen = scale_expansion_zeroelim(temp192len, temp192, dez, detz); 03861 zzlen = scale_expansion_zeroelim(zlen, detz, dez, detzz); 03862 ztlen = scale_expansion_zeroelim(temp192len, temp192, deztail, detzt); 03863 zztlen = scale_expansion_zeroelim(ztlen, detzt, dez, detzzt); 03864 for (i = 0; i < zztlen; i++) { 03865 detzzt[i] *= 2.0; 03866 } 03867 ztztlen = scale_expansion_zeroelim(ztlen, detzt, deztail, detztzt); 03868 z1len = fast_expansion_sum_zeroelim(zzlen, detzz, zztlen, detzzt, z1); 03869 z2len = fast_expansion_sum_zeroelim(z1len, z1, ztztlen, detztzt, z2); 03870 xylen = fast_expansion_sum_zeroelim(x2len, x2, y2len, y2, detxy); 03871 dlen = fast_expansion_sum_zeroelim(z2len, z2, xylen, detxy, ddet); 03872 03873 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 03874 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); 03875 deterlen = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, deter); 03876 03877 return deter[deterlen - 1]; 03878 } 03879 03880 REAL insphereadapt(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe, 03881 REAL permanent) 03882 { 03883 INEXACT REAL aex, bex, cex, dex, aey, bey, cey, dey, aez, bez, cez, dez; 03884 REAL det, errbound; 03885 03886 INEXACT REAL aexbey1, bexaey1, bexcey1, cexbey1; 03887 INEXACT REAL cexdey1, dexcey1, dexaey1, aexdey1; 03888 INEXACT REAL aexcey1, cexaey1, bexdey1, dexbey1; 03889 REAL aexbey0, bexaey0, bexcey0, cexbey0; 03890 REAL cexdey0, dexcey0, dexaey0, aexdey0; 03891 REAL aexcey0, cexaey0, bexdey0, dexbey0; 03892 REAL ab[4], bc[4], cd[4], da[4], ac[4], bd[4]; 03893 INEXACT REAL ab3, bc3, cd3, da3, ac3, bd3; 03894 REAL abeps, bceps, cdeps, daeps, aceps, bdeps; 03895 REAL temp8a[8], temp8b[8], temp8c[8], temp16[16], temp24[24], temp48[48]; 03896 int temp8alen, temp8blen, temp8clen, temp16len, temp24len, temp48len; 03897 REAL xdet[96], ydet[96], zdet[96], xydet[192]; 03898 int xlen, ylen, zlen, xylen; 03899 REAL adet[288], bdet[288], cdet[288], ddet[288]; 03900 int alen, blen, clen, dlen; 03901 REAL abdet[576], cddet[576]; 03902 int ablen, cdlen; 03903 REAL fin1[1152]; 03904 int finlength; 03905 03906 REAL aextail, bextail, cextail, dextail; 03907 REAL aeytail, beytail, ceytail, deytail; 03908 REAL aeztail, beztail, ceztail, deztail; 03909 03910 INEXACT REAL bvirt; 03911 REAL avirt, bround, around; 03912 INEXACT REAL c; 03913 INEXACT REAL abig; 03914 REAL ahi, alo, bhi, blo; 03915 REAL err1, err2, err3; 03916 INEXACT REAL _i, _j; 03917 REAL _0; 03918 03919 aex = (REAL) (pa[0] - pe[0]); 03920 bex = (REAL) (pb[0] - pe[0]); 03921 cex = (REAL) (pc[0] - pe[0]); 03922 dex = (REAL) (pd[0] - pe[0]); 03923 aey = (REAL) (pa[1] - pe[1]); 03924 bey = (REAL) (pb[1] - pe[1]); 03925 cey = (REAL) (pc[1] - pe[1]); 03926 dey = (REAL) (pd[1] - pe[1]); 03927 aez = (REAL) (pa[2] - pe[2]); 03928 bez = (REAL) (pb[2] - pe[2]); 03929 cez = (REAL) (pc[2] - pe[2]); 03930 dez = (REAL) (pd[2] - pe[2]); 03931 03932 Two_Product(aex, bey, aexbey1, aexbey0); 03933 Two_Product(bex, aey, bexaey1, bexaey0); 03934 Two_Two_Diff(aexbey1, aexbey0, bexaey1, bexaey0, ab3, ab[2], ab[1], ab[0]); 03935 ab[3] = ab3; 03936 03937 Two_Product(bex, cey, bexcey1, bexcey0); 03938 Two_Product(cex, bey, cexbey1, cexbey0); 03939 Two_Two_Diff(bexcey1, bexcey0, cexbey1, cexbey0, bc3, bc[2], bc[1], bc[0]); 03940 bc[3] = bc3; 03941 03942 Two_Product(cex, dey, cexdey1, cexdey0); 03943 Two_Product(dex, cey, dexcey1, dexcey0); 03944 Two_Two_Diff(cexdey1, cexdey0, dexcey1, dexcey0, cd3, cd[2], cd[1], cd[0]); 03945 cd[3] = cd3; 03946 03947 Two_Product(dex, aey, dexaey1, dexaey0); 03948 Two_Product(aex, dey, aexdey1, aexdey0); 03949 Two_Two_Diff(dexaey1, dexaey0, aexdey1, aexdey0, da3, da[2], da[1], da[0]); 03950 da[3] = da3; 03951 03952 Two_Product(aex, cey, aexcey1, aexcey0); 03953 Two_Product(cex, aey, cexaey1, cexaey0); 03954 Two_Two_Diff(aexcey1, aexcey0, cexaey1, cexaey0, ac3, ac[2], ac[1], ac[0]); 03955 ac[3] = ac3; 03956 03957 Two_Product(bex, dey, bexdey1, bexdey0); 03958 Two_Product(dex, bey, dexbey1, dexbey0); 03959 Two_Two_Diff(bexdey1, bexdey0, dexbey1, dexbey0, bd3, bd[2], bd[1], bd[0]); 03960 bd[3] = bd3; 03961 03962 temp8alen = scale_expansion_zeroelim(4, cd, bez, temp8a); 03963 temp8blen = scale_expansion_zeroelim(4, bd, -cez, temp8b); 03964 temp8clen = scale_expansion_zeroelim(4, bc, dez, temp8c); 03965 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 03966 temp8blen, temp8b, temp16); 03967 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 03968 temp16len, temp16, temp24); 03969 temp48len = scale_expansion_zeroelim(temp24len, temp24, aex, temp48); 03970 xlen = scale_expansion_zeroelim(temp48len, temp48, -aex, xdet); 03971 temp48len = scale_expansion_zeroelim(temp24len, temp24, aey, temp48); 03972 ylen = scale_expansion_zeroelim(temp48len, temp48, -aey, ydet); 03973 temp48len = scale_expansion_zeroelim(temp24len, temp24, aez, temp48); 03974 zlen = scale_expansion_zeroelim(temp48len, temp48, -aez, zdet); 03975 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 03976 alen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, adet); 03977 03978 temp8alen = scale_expansion_zeroelim(4, da, cez, temp8a); 03979 temp8blen = scale_expansion_zeroelim(4, ac, dez, temp8b); 03980 temp8clen = scale_expansion_zeroelim(4, cd, aez, temp8c); 03981 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 03982 temp8blen, temp8b, temp16); 03983 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 03984 temp16len, temp16, temp24); 03985 temp48len = scale_expansion_zeroelim(temp24len, temp24, bex, temp48); 03986 xlen = scale_expansion_zeroelim(temp48len, temp48, bex, xdet); 03987 temp48len = scale_expansion_zeroelim(temp24len, temp24, bey, temp48); 03988 ylen = scale_expansion_zeroelim(temp48len, temp48, bey, ydet); 03989 temp48len = scale_expansion_zeroelim(temp24len, temp24, bez, temp48); 03990 zlen = scale_expansion_zeroelim(temp48len, temp48, bez, zdet); 03991 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 03992 blen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, bdet); 03993 03994 temp8alen = scale_expansion_zeroelim(4, ab, dez, temp8a); 03995 temp8blen = scale_expansion_zeroelim(4, bd, aez, temp8b); 03996 temp8clen = scale_expansion_zeroelim(4, da, bez, temp8c); 03997 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 03998 temp8blen, temp8b, temp16); 03999 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 04000 temp16len, temp16, temp24); 04001 temp48len = scale_expansion_zeroelim(temp24len, temp24, cex, temp48); 04002 xlen = scale_expansion_zeroelim(temp48len, temp48, -cex, xdet); 04003 temp48len = scale_expansion_zeroelim(temp24len, temp24, cey, temp48); 04004 ylen = scale_expansion_zeroelim(temp48len, temp48, -cey, ydet); 04005 temp48len = scale_expansion_zeroelim(temp24len, temp24, cez, temp48); 04006 zlen = scale_expansion_zeroelim(temp48len, temp48, -cez, zdet); 04007 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 04008 clen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, cdet); 04009 04010 temp8alen = scale_expansion_zeroelim(4, bc, aez, temp8a); 04011 temp8blen = scale_expansion_zeroelim(4, ac, -bez, temp8b); 04012 temp8clen = scale_expansion_zeroelim(4, ab, cez, temp8c); 04013 temp16len = fast_expansion_sum_zeroelim(temp8alen, temp8a, 04014 temp8blen, temp8b, temp16); 04015 temp24len = fast_expansion_sum_zeroelim(temp8clen, temp8c, 04016 temp16len, temp16, temp24); 04017 temp48len = scale_expansion_zeroelim(temp24len, temp24, dex, temp48); 04018 xlen = scale_expansion_zeroelim(temp48len, temp48, dex, xdet); 04019 temp48len = scale_expansion_zeroelim(temp24len, temp24, dey, temp48); 04020 ylen = scale_expansion_zeroelim(temp48len, temp48, dey, ydet); 04021 temp48len = scale_expansion_zeroelim(temp24len, temp24, dez, temp48); 04022 zlen = scale_expansion_zeroelim(temp48len, temp48, dez, zdet); 04023 xylen = fast_expansion_sum_zeroelim(xlen, xdet, ylen, ydet, xydet); 04024 dlen = fast_expansion_sum_zeroelim(xylen, xydet, zlen, zdet, ddet); 04025 04026 ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet); 04027 cdlen = fast_expansion_sum_zeroelim(clen, cdet, dlen, ddet, cddet); 04028 finlength = fast_expansion_sum_zeroelim(ablen, abdet, cdlen, cddet, fin1); 04029 04030 det = estimate(finlength, fin1); 04031 errbound = isperrboundB * permanent; 04032 if ((det >= errbound) || (-det >= errbound)) { 04033 return det; 04034 } 04035 04036 Two_Diff_Tail(pa[0], pe[0], aex, aextail); 04037 Two_Diff_Tail(pa[1], pe[1], aey, aeytail); 04038 Two_Diff_Tail(pa[2], pe[2], aez, aeztail); 04039 Two_Diff_Tail(pb[0], pe[0], bex, bextail); 04040 Two_Diff_Tail(pb[1], pe[1], bey, beytail); 04041 Two_Diff_Tail(pb[2], pe[2], bez, beztail); 04042 Two_Diff_Tail(pc[0], pe[0], cex, cextail); 04043 Two_Diff_Tail(pc[1], pe[1], cey, ceytail); 04044 Two_Diff_Tail(pc[2], pe[2], cez, ceztail); 04045 Two_Diff_Tail(pd[0], pe[0], dex, dextail); 04046 Two_Diff_Tail(pd[1], pe[1], dey, deytail); 04047 Two_Diff_Tail(pd[2], pe[2], dez, deztail); 04048 if ((aextail == 0.0) && (aeytail == 0.0) && (aeztail == 0.0) 04049 && (bextail == 0.0) && (beytail == 0.0) && (beztail == 0.0) 04050 && (cextail == 0.0) && (ceytail == 0.0) && (ceztail == 0.0) 04051 && (dextail == 0.0) && (deytail == 0.0) && (deztail == 0.0)) { 04052 return det; 04053 } 04054 04055 errbound = isperrboundC * permanent + resulterrbound * Absolute(det); 04056 abeps = (aex * beytail + bey * aextail) 04057 - (aey * bextail + bex * aeytail); 04058 bceps = (bex * ceytail + cey * bextail) 04059 - (bey * cextail + cex * beytail); 04060 cdeps = (cex * deytail + dey * cextail) 04061 - (cey * dextail + dex * ceytail); 04062 daeps = (dex * aeytail + aey * dextail) 04063 - (dey * aextail + aex * deytail); 04064 aceps = (aex * ceytail + cey * aextail) 04065 - (aey * cextail + cex * aeytail); 04066 bdeps = (bex * deytail + dey * bextail) 04067 - (bey * dextail + dex * beytail); 04068 det += (((bex * bex + bey * bey + bez * bez) 04069 * ((cez * daeps + dez * aceps + aez * cdeps) 04070 + (ceztail * da3 + deztail * ac3 + aeztail * cd3)) 04071 + (dex * dex + dey * dey + dez * dez) 04072 * ((aez * bceps - bez * aceps + cez * abeps) 04073 + (aeztail * bc3 - beztail * ac3 + ceztail * ab3))) 04074 - ((aex * aex + aey * aey + aez * aez) 04075 * ((bez * cdeps - cez * bdeps + dez * bceps) 04076 + (beztail * cd3 - ceztail * bd3 + deztail * bc3)) 04077 + (cex * cex + cey * cey + cez * cez) 04078 * ((dez * abeps + aez * bdeps + bez * daeps) 04079 + (deztail * ab3 + aeztail * bd3 + beztail * da3)))) 04080 + 2.0 * (((bex * bextail + bey * beytail + bez * beztail) 04081 * (cez * da3 + dez * ac3 + aez * cd3) 04082 + (dex * dextail + dey * deytail + dez * deztail) 04083 * (aez * bc3 - bez * ac3 + cez * ab3)) 04084 - ((aex * aextail + aey * aeytail + aez * aeztail) 04085 * (bez * cd3 - cez * bd3 + dez * bc3) 04086 + (cex * cextail + cey * ceytail + cez * ceztail) 04087 * (dez * ab3 + aez * bd3 + bez * da3))); 04088 if ((det >= errbound) || (-det >= errbound)) { 04089 return det; 04090 } 04091 04092 return insphereexact(pa, pb, pc, pd, pe); 04093 } 04094 04095 REAL insphere(REAL *pa, REAL *pb, REAL *pc, REAL *pd, REAL *pe) 04096 { 04097 REAL aex, bex, cex, dex; 04098 REAL aey, bey, cey, dey; 04099 REAL aez, bez, cez, dez; 04100 REAL aexbey, bexaey, bexcey, cexbey, cexdey, dexcey, dexaey, aexdey; 04101 REAL aexcey, cexaey, bexdey, dexbey; 04102 REAL alift, blift, clift, dlift; 04103 REAL ab, bc, cd, da, ac, bd; 04104 REAL abc, bcd, cda, dab; 04105 REAL aezplus, bezplus, cezplus, dezplus; 04106 REAL aexbeyplus, bexaeyplus, bexceyplus, cexbeyplus; 04107 REAL cexdeyplus, dexceyplus, dexaeyplus, aexdeyplus; 04108 REAL aexceyplus, cexaeyplus, bexdeyplus, dexbeyplus; 04109 REAL det; 04110 REAL permanent, errbound; 04111 04112 aex = pa[0] - pe[0]; 04113 bex = pb[0] - pe[0]; 04114 cex = pc[0] - pe[0]; 04115 dex = pd[0] - pe[0]; 04116 aey = pa[1] - pe[1]; 04117 bey = pb[1] - pe[1]; 04118 cey = pc[1] - pe[1]; 04119 dey = pd[1] - pe[1]; 04120 aez = pa[2] - pe[2]; 04121 bez = pb[2] - pe[2]; 04122 cez = pc[2] - pe[2]; 04123 dez = pd[2] - pe[2]; 04124 04125 aexbey = aex * bey; 04126 bexaey = bex * aey; 04127 ab = aexbey - bexaey; 04128 bexcey = bex * cey; 04129 cexbey = cex * bey; 04130 bc = bexcey - cexbey; 04131 cexdey = cex * dey; 04132 dexcey = dex * cey; 04133 cd = cexdey - dexcey; 04134 dexaey = dex * aey; 04135 aexdey = aex * dey; 04136 da = dexaey - aexdey; 04137 04138 aexcey = aex * cey; 04139 cexaey = cex * aey; 04140 ac = aexcey - cexaey; 04141 bexdey = bex * dey; 04142 dexbey = dex * bey; 04143 bd = bexdey - dexbey; 04144 04145 abc = aez * bc - bez * ac + cez * ab; 04146 bcd = bez * cd - cez * bd + dez * bc; 04147 cda = cez * da + dez * ac + aez * cd; 04148 dab = dez * ab + aez * bd + bez * da; 04149 04150 alift = aex * aex + aey * aey + aez * aez; 04151 blift = bex * bex + bey * bey + bez * bez; 04152 clift = cex * cex + cey * cey + cez * cez; 04153 dlift = dex * dex + dey * dey + dez * dez; 04154 04155 det = (dlift * abc - clift * dab) + (blift * cda - alift * bcd); 04156 04157 aezplus = Absolute(aez); 04158 bezplus = Absolute(bez); 04159 cezplus = Absolute(cez); 04160 dezplus = Absolute(dez); 04161 aexbeyplus = Absolute(aexbey); 04162 bexaeyplus = Absolute(bexaey); 04163 bexceyplus = Absolute(bexcey); 04164 cexbeyplus = Absolute(cexbey); 04165 cexdeyplus = Absolute(cexdey); 04166 dexceyplus = Absolute(dexcey); 04167 dexaeyplus = Absolute(dexaey); 04168 aexdeyplus = Absolute(aexdey); 04169 aexceyplus = Absolute(aexcey); 04170 cexaeyplus = Absolute(cexaey); 04171 bexdeyplus = Absolute(bexdey); 04172 dexbeyplus = Absolute(dexbey); 04173 permanent = ((cexdeyplus + dexceyplus) * bezplus 04174 + (dexbeyplus + bexdeyplus) * cezplus 04175 + (bexceyplus + cexbeyplus) * dezplus) 04176 * alift 04177 + ((dexaeyplus + aexdeyplus) * cezplus 04178 + (aexceyplus + cexaeyplus) * dezplus 04179 + (cexdeyplus + dexceyplus) * aezplus) 04180 * blift 04181 + ((aexbeyplus + bexaeyplus) * dezplus 04182 + (bexdeyplus + dexbeyplus) * aezplus 04183 + (dexaeyplus + aexdeyplus) * bezplus) 04184 * clift 04185 + ((bexceyplus + cexbeyplus) * aezplus 04186 + (cexaeyplus + aexceyplus) * bezplus 04187 + (aexbeyplus + bexaeyplus) * cezplus) 04188 * dlift; 04189 errbound = isperrboundA * permanent; 04190 if ((det > errbound) || (-det > errbound)) { 04191 return det; 04192 } 04193 04194 return insphereadapt(pa, pb, pc, pd, pe, permanent); 04195 } 04196 } //Added namespace to avoid clash with triangle