⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 predicates.cxx

📁 一个很有效的构建delauny的英文程序说明
💻 CXX
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************//*                                                                           *//*  Routines for Arbitrary Precision Floating-point Arithmetic               *//*  and Fast Robust Geometric Predicates                                     *//*  (predicates.c)                                                           *//*                                                                           *//*  May 18, 1996                                                             *//*                                                                           *//*  Placed in the public domain by                                           *//*  Jonathan Richard Shewchuk                                                *//*  School of Computer Science                                               *//*  Carnegie Mellon University                                               *//*  5000 Forbes Avenue                                                       *//*  Pittsburgh, Pennsylvania  15213-3891                                     *//*  jrs@cs.cmu.edu                                                           *//*                                                                           *//*  This file contains C implementation of algorithms for exact addition     *//*    and multiplication of floating-point numbers, and predicates for       *//*    robustly performing the orientation and incircle tests used in         *//*    computational geometry.  The algorithms and underlying theory are      *//*    described in Jonathan Richard Shewchuk.  "Adaptive Precision Floating- *//*    Point Arithmetic and Fast Robust Geometric Predicates."  Technical     *//*    Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon      *//*    University, Pittsburgh, Pennsylvania, May 1996.  (Submitted to         *//*    Discrete & Computational Geometry.)                                    *//*                                                                           *//*  This file, the paper listed above, and other information are available   *//*    from the Web page http://www.cs.cmu.edu/~quake/robust.html .           *//*                                                                           *//*****************************************************************************//*****************************************************************************//*                                                                           *//*  Using this code:                                                         *//*                                                                           *//*  First, read the short or long version of the paper (from the Web page    *//*    above).                                                                *//*                                                                           *//*  Be sure to call exactinit() once, before calling any of the arithmetic   *//*    functions or geometric predicates.  Also be sure to turn on the        *//*    optimizer when compiling this file.                                    *//*                                                                           *//*                                                                           *//*  Several geometric predicates are defined.  Their parameters are all      *//*    points.  Each point is an array of two or three floating-point         *//*    numbers.  The geometric predicates, described in the papers, are       *//*                                                                           *//*    orient2d(pa, pb, pc)                                                   *//*    orient2dfast(pa, pb, pc)                                               *//*    orient3d(pa, pb, pc, pd)                                               *//*    orient3dfast(pa, pb, pc, pd)                                           *//*    incircle(pa, pb, pc, pd)                                               *//*    incirclefast(pa, pb, pc, pd)                                           *//*    insphere(pa, pb, pc, pd, pe)                                           *//*    inspherefast(pa, pb, pc, pd, pe)                                       *//*                                                                           *//*  Those with suffix "fast" are approximate, non-robust versions.  Those    *//*    without the suffix are adaptive precision, robust versions.  There     *//*    are also versions with the suffices "exact" and "slow", which are      *//*    non-adaptive, exact arithmetic versions, which I use only for timings  *//*    in my arithmetic papers.                                               *//*                                                                           *//*                                                                           *//*  An expansion is represented by an array of floating-point numbers,       *//*    sorted from smallest to largest magnitude (possibly with interspersed  *//*    zeros).  The length of each expansion is stored as a separate integer, *//*    and each arithmetic function returns an integer which is the length    *//*    of the expansion it created.                                           *//*                                                                           *//*  Several arithmetic functions are defined.  Their parameters are          *//*                                                                           *//*    e, f           Input expansions                                        *//*    elen, flen     Lengths of input expansions (must be >= 1)              *//*    h              Output expansion                                        *//*    b              Input scalar                                            *//*                                                                           *//*  The arithmetic functions are                                             *//*                                                                           *//*    grow_expansion(elen, e, b, h)                                          *//*    grow_expansion_zeroelim(elen, e, b, h)                                 *//*    expansion_sum(elen, e, flen, f, h)                                     *//*    expansion_sum_zeroelim1(elen, e, flen, f, h)                           *//*    expansion_sum_zeroelim2(elen, e, flen, f, h)                           *//*    fast_expansion_sum(elen, e, flen, f, h)                                *//*    fast_expansion_sum_zeroelim(elen, e, flen, f, h)                       *//*    linear_expansion_sum(elen, e, flen, f, h)                              *//*    linear_expansion_sum_zeroelim(elen, e, flen, f, h)                     *//*    scale_expansion(elen, e, b, h)                                         *//*    scale_expansion_zeroelim(elen, e, b, h)                                *//*    compress(elen, e, h)                                                   *//*                                                                           *//*  All of these are described in the long version of the paper; some are    *//*    described in the short version.  All return an integer that is the     *//*    length of h.  Those with suffix _zeroelim perform zero elimination,    *//*    and are recommended over their counterparts.  The procedure            *//*    fast_expansion_sum_zeroelim() (or linear_expansion_sum_zeroelim() on   *//*    processors that do not use the round-to-even tiebreaking rule) is      *//*    recommended over expansion_sum_zeroelim().  Each procedure has a       *//*    little note next to it (in the code below) that tells you whether or   *//*    not the output expansion may be the same array as one of the input     *//*    expansions.                                                            *//*                                                                           *//*                                                                           *//*  If you look around below, you'll also find macros for a bunch of         *//*    simple unrolled arithmetic operations, and procedures for printing     *//*    expansions (commented out because they don't work with all C           *//*    compilers) and for generating random floating-point numbers whose      *//*    significand bits are all random.  Most of the macros have undocumented *//*    requirements that certain of their parameters should not be the same   *//*    variable; for safety, better to make sure all the parameters are       *//*    distinct variables.  Feel free to send email to jrs@cs.cmu.edu if you  *//*    have questions.                                                        *//*                                                                           *//*****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <math.h>#ifdef CPU86#include <float.h>#endif /* CPU86 */#ifdef LINUX#include <fpu_control.h>#endif /* LINUX */#include "tetgen.h"            // Defines the symbol REAL (float or double)./* On some machines, the exact arithmetic routines might be defeated by the  *//*   use of internal extended precision floating-point registers.  Sometimes *//*   this problem can be fixed by defining certain values to be volatile,    *//*   thus forcing them to be stored to memory and rounded off.  This isn't   *//*   a great solution, though, as it slows the arithmetic down.              *//*                                                                           *//* To try this out, write "#define INEXACT volatile" below.  Normally,       *//*   however, INEXACT should be defined to be nothing.  ("#define INEXACT".) */#define INEXACT                          /* Nothing *//* #define INEXACT volatile *//* #define REAL double */                      /* float or double */#define REALPRINT doubleprint#define REALRAND doublerand#define NARROWRAND narrowdoublerand#define UNIFORMRAND uniformdoublerand/* Which of the following two methods of finding the absolute values is      *//*   fastest is compiler-dependent.  A few compilers can inline and optimize *//*   the fabs() call; but most will incur the overhead of a function call,   *//*   which is disastrously slow.  A faster way on IEEE machines might be to  *//*   mask the appropriate bit, but that's difficult to do in C.              */#define Absolute(a)  ((a) >= 0.0 ? (a) : -(a))/* #define Absolute(a)  fabs(a) *//* Many of the operations are broken up into two pieces, a main part that    *//*   performs an approximate operation, and a "tail" that computes the       *//*   roundoff error of that operation.                                       *//*                                                                           *//* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(),    *//*   Split(), and Two_Product() are all implemented as described in the      *//*   reference.  Each of these macros requires certain variables to be       *//*   defined in the calling routine.  The variables `bvirt', `c', `abig',    *//*   `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because   *//*   they store the result of an operation that may incur roundoff error.    *//*   The input parameter `x' (or the highest numbered `x_' parameter) must   *//*   also be declared `INEXACT'.                                             */#define Fast_Two_Sum_Tail(a, b, x, y) \  bvirt = x - a; \  y = b - bvirt#define Fast_Two_Sum(a, b, x, y) \  x = (REAL) (a + b); \  Fast_Two_Sum_Tail(a, b, x, y)#define Fast_Two_Diff_Tail(a, b, x, y) \  bvirt = a - x; \  y = bvirt - b#define Fast_Two_Diff(a, b, x, y) \  x = (REAL) (a - b); \  Fast_Two_Diff_Tail(a, b, x, y)#define Two_Sum_Tail(a, b, x, y) \  bvirt = (REAL) (x - a); \  avirt = x - bvirt; \  bround = b - bvirt; \  around = a - avirt; \  y = around + bround#define Two_Sum(a, b, x, y) \  x = (REAL) (a + b); \  Two_Sum_Tail(a, b, x, y)#define Two_Diff_Tail(a, b, x, y) \  bvirt = (REAL) (a - x); \  avirt = x + bvirt; \  bround = bvirt - b; \  around = a - avirt; \  y = around + bround#define Two_Diff(a, b, x, y) \  x = (REAL) (a - b); \  Two_Diff_Tail(a, b, x, y)#define Split(a, ahi, alo) \  c = (REAL) (splitter * a); \  abig = (REAL) (c - a); \  ahi = c - abig; \  alo = a - ahi#define Two_Product_Tail(a, b, x, y) \  Split(a, ahi, alo); \  Split(b, bhi, blo); \  err1 = x - (ahi * bhi); \  err2 = err1 - (alo * bhi); \  err3 = err2 - (ahi * blo); \  y = (alo * blo) - err3#define Two_Product(a, b, x, y) \  x = (REAL) (a * b); \  Two_Product_Tail(a, b, x, y)/* Two_Product_Presplit() is Two_Product() where one of the inputs has       *//*   already been split.  Avoids redundant splitting.                        */#define Two_Product_Presplit(a, b, bhi, blo, x, y) \  x = (REAL) (a * b); \  Split(a, ahi, alo); \  err1 = x - (ahi * bhi); \  err2 = err1 - (alo * bhi); \  err3 = err2 - (ahi * blo); \  y = (alo * blo) - err3/* Two_Product_2Presplit() is Two_Product() where both of the inputs have    *//*   already been split.  Avoids redundant splitting.                        */#define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \  x = (REAL) (a * b); \  err1 = x - (ahi * bhi); \  err2 = err1 - (alo * bhi); \  err3 = err2 - (ahi * blo); \  y = (alo * blo) - err3/* Square() can be done more quickly than Two_Product().                     */#define Square_Tail(a, x, y) \  Split(a, ahi, alo); \  err1 = x - (ahi * ahi); \  err3 = err1 - ((ahi + ahi) * alo); \  y = (alo * alo) - err3#define Square(a, x, y) \  x = (REAL) (a * a); \  Square_Tail(a, x, y)/* Macros for summing expansions of various fixed lengths.  These are all    *//*   unrolled versions of Expansion_Sum().                                   */#define Two_One_Sum(a1, a0, b, x2, x1, x0) \  Two_Sum(a0, b , _i, x0); \  Two_Sum(a1, _i, x2, x1)#define Two_One_Diff(a1, a0, b, x2, x1, x0) \  Two_Diff(a0, b , _i, x0); \  Two_Sum( a1, _i, x2, x1)#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \  Two_One_Sum(a1, a0, b0, _j, _0, x0); \  Two_One_Sum(_j, _0, b1, x3, x2, x1)#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \  Two_One_Diff(a1, a0, b0, _j, _0, x0); \  Two_One_Diff(_j, _0, b1, x3, x2, x1)#define Four_One_Sum(a3, a2, a1, a0, b, x4, x3, x2, x1, x0) \  Two_One_Sum(a1, a0, b , _j, x1, x0); \  Two_One_Sum(a3, a2, _j, x4, x3, x2)#define Four_Two_Sum(a3, a2, a1, a0, b1, b0, x5, x4, x3, x2, x1, x0) \  Four_One_Sum(a3, a2, a1, a0, b0, _k, _2, _1, _0, x0); \  Four_One_Sum(_k, _2, _1, _0, b1, x5, x4, x3, x2, x1)#define Four_Four_Sum(a3, a2, a1, a0, b4, b3, b1, b0, x7, x6, x5, x4, x3, x2, \                      x1, x0) \  Four_Two_Sum(a3, a2, a1, a0, b1, b0, _l, _2, _1, _0, x1, x0); \  Four_Two_Sum(_l, _2, _1, _0, b4, b3, x7, x6, x5, x4, x3, x2)#define Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b, x8, x7, x6, x5, x4, \                      x3, x2, x1, x0) \  Four_One_Sum(a3, a2, a1, a0, b , _j, x3, x2, x1, x0); \  Four_One_Sum(a7, a6, a5, a4, _j, x8, x7, x6, x5, x4)#define Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, x9, x8, x7, \                      x6, x5, x4, x3, x2, x1, x0) \  Eight_One_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b0, _k, _6, _5, _4, _3, _2, \                _1, _0, x0); \  Eight_One_Sum(_k, _6, _5, _4, _3, _2, _1, _0, b1, x9, x8, x7, x6, x5, x4, \                x3, x2, x1)#define Eight_Four_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b4, b3, b1, b0, x11, \                       x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0) \  Eight_Two_Sum(a7, a6, a5, a4, a3, a2, a1, a0, b1, b0, _l, _6, _5, _4, _3, \                _2, _1, _0, x1, x0); \  Eight_Two_Sum(_l, _6, _5, _4, _3, _2, _1, _0, b4, b3, x11, x10, x9, x8, \                x7, x6, x5, x4, x3, x2)/* Macros for multiplying expansions of various fixed lengths.               */#define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \  Split(b, bhi, blo); \  Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \  Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \  Two_Sum(_i, _0, _k, x1); \  Fast_Two_Sum(_j, _k, x3, x2)#define Four_One_Product(a3, a2, a1, a0, b, x7, x6, x5, x4, x3, x2, x1, x0) \  Split(b, bhi, blo); \  Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \  Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \  Two_Sum(_i, _0, _k, x1); \  Fast_Two_Sum(_j, _k, _i, x2); \  Two_Product_Presplit(a2, b, bhi, blo, _j, _0); \  Two_Sum(_i, _0, _k, x3); \  Fast_Two_Sum(_j, _k, _i, x4); \  Two_Product_Presplit(a3, b, bhi, blo, _j, _0); \  Two_Sum(_i, _0, _k, x5); \  Fast_Two_Sum(_j, _k, x7, x6)#define Two_Two_Product(a1, a0, b1, b0, x7, x6, x5, x4, x3, x2, x1, x0) \  Split(a0, a0hi, a0lo); \  Split(b0, bhi, blo); \  Two_Product_2Presplit(a0, a0hi, a0lo, b0, bhi, blo, _i, x0); \  Split(a1, a1hi, a1lo); \  Two_Product_2Presplit(a1, a1hi, a1lo, b0, bhi, blo, _j, _0); \  Two_Sum(_i, _0, _k, _1); \  Fast_Two_Sum(_j, _k, _l, _2); \  Split(b1, bhi, blo); \  Two_Product_2Presplit(a0, a0hi, a0lo, b1, bhi, blo, _i, _0); \  Two_Sum(_1, _0, _k, x1); \  Two_Sum(_2, _k, _j, _1); \  Two_Sum(_l, _j, _m, _2); \  Two_Product_2Presplit(a1, a1hi, a1lo, b1, bhi, blo, _j, _0); \  Two_Sum(_i, _0, _n, _0); \  Two_Sum(_1, _0, _i, x2); \  Two_Sum(_2, _i, _k, _1); \  Two_Sum(_m, _k, _l, _2); \  Two_Sum(_j, _n, _k, _0); \  Two_Sum(_1, _0, _j, x3); \  Two_Sum(_2, _j, _i, _1); \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -