moab
FindPtFuncs.h
Go to the documentation of this file.
00001 #ifndef FINDPTFUNCS_H
00002 #define FINDPTFUNCS_H
00003 
00004 #include "float.h"
00005 #include "math.h"
00006 
00007 /*======================================================
00008 / from types.h
00009 /======================================================
00010 */
00011 
00012 /* integer type to use for everything */
00013 #if   defined(USE_LONG)
00014 #  define INTEGER long
00015 #elif defined(USE_LONG_LONG)
00016 #  define INTEGER long long
00017 #elif defined(USE_SHORT)
00018 #  define INTEGER short
00019 #else
00020 #  define INTEGER int
00021 #endif
00022 
00023 /* when defined, use the given type for global indices instead of INTEGER */
00024 #if   defined(USE_GLOBAL_LONG_LONG)
00025 #  define GLOBAL_INT long long
00026 #elif defined(USE_GLOBAL_LONG)
00027 #  define GLOBAL_INT long
00028 #else
00029 #  define GLOBAL_INT long
00030 #endif
00031 
00032 /* floating point type to use for everything */
00033 #if   defined(USE_FLOAT)
00034    typedef float real;
00035 #  define floorr floorf
00036 #  define ceilr  ceilf
00037 #  define sqrtr  sqrtf
00038 #  define fabsr  fabsf
00039 #  define cosr   cosf
00040 #  define sinr   sinf
00041 #  define EPS   (128*FLT_EPSILON)
00042 #  define PI 3.1415926535897932384626433832795028841971693993751058209749445923F
00043 #elif defined(USE_LONG_DOUBLE)
00044    typedef long double real;
00045 #  define floorr floorl
00046 #  define ceilr  ceill
00047 #  define sqrtr  sqrtl
00048 #  define fabsr  fabsl
00049 #  define cosr   cosl
00050 #  define sinr   sinl
00051 #  define EPS   (128*LDBL_EPSILON)
00052 #  define PI 3.1415926535897932384626433832795028841971693993751058209749445923L
00053 #else
00054    typedef double real;
00055 #  define floorr floor
00056 #  define ceilr  ceil
00057 #  define sqrtr  sqrt
00058 #  define fabsr  fabs
00059 #  define cosr   cos
00060 #  define sinr   sin
00061 #  define EPS   (128*DBL_EPSILON)
00062 #  define PI 3.1415926535897932384626433832795028841971693993751058209749445923
00063 #endif
00064 
00065 /* apparently uint and ulong can be defined already in standard headers */
00066 #define uint uint_
00067 #define ulong ulong_
00068 #define sint sint_
00069 #define slong slong_
00070 
00071 typedef   signed INTEGER sint;
00072 typedef unsigned INTEGER uint;
00073 #undef INTEGER
00074 
00075 #ifdef GLOBAL_INT
00076   typedef   signed GLOBAL_INT slong;
00077   typedef unsigned GLOBAL_INT ulong;
00078 #else
00079   typedef sint slong;
00080   typedef uint ulong;
00081 #endif
00082 
00083 /*======================================================
00084 / from poly.h
00085 /======================================================
00086 */
00087 
00088 /* 
00089   For brevity's sake, some names have been shortened
00090   Quadrature rules
00091     Gauss   -> Gauss-Legendre quadrature (open)
00092     Lobatto -> Gauss-Lobatto-Legendre quadrature (closed at both ends)
00093   Polynomial bases
00094     Legendre -> Legendre basis
00095     Gauss    -> Lagrangian basis using Gauss   quadrature nodes
00096     Lobatto  -> Lagrangian basis using Lobatto quadrature nodes
00097 */
00098 
00099 /*--------------------------------------------------------------------------
00100    Legendre Polynomial Matrix Computation
00101    (compute P_i(x_j) for i = 0, ..., n and a given set of x)
00102   --------------------------------------------------------------------------*/
00103 
00104 /* precondition: n >= 1
00105    inner index is x index (0 ... m-1);
00106    outer index is Legendre polynomial number (0 ... n)
00107  */
00108 void legendre_matrix(const real *x, int m, real *P, int n);
00109 
00110 /* precondition: n >= 1
00111    inner index is Legendre polynomial number (0 ... n)
00112    outer index is x index (0 ... m-1);
00113  */
00114 void legendre_matrix_t(const real *x, int m, real *P, int n);
00115 
00116 /* precondition: n >= 1
00117    compute P_i(x) with i = 0 ... n
00118  */
00119 void legendre_row(real x, real *P, int n);
00120 
00121 
00122 /*--------------------------------------------------------------------------
00123    Quadrature Nodes and Weights Calculation
00124    
00125    call the _nodes function before calling the _weights function
00126   --------------------------------------------------------------------------*/
00127 
00128 void gauss_nodes(real *z, int n);   /* n nodes (order = 2n-1) */
00129 void lobatto_nodes(real *z, int n); /* n nodes (order = 2n-3) */
00130 
00131 void gauss_weights(const real *z, real *w, int n);
00132 void lobatto_weights(const real *z, real *w, int n);
00133 
00134 /*--------------------------------------------------------------------------
00135    Lagrangian to Legendre Change-of-basis Matrix
00136   --------------------------------------------------------------------------*/
00137 
00138 /* precondition: n >= 2
00139    given the Gauss quadrature rule (z,w,n), compute the square matrix J
00140    for transforming from the Gauss basis to the Legendre basis:
00141    
00142       u_legendre(i) = sum_j J(i,j) u_gauss(j)
00143 
00144    computes J   = .5 (2i+1) w  P (z )
00145              ij              j  i  j
00146              
00147    in column major format (inner index is i, the Legendre index)
00148  */
00149 void gauss_to_legendre(const real *z, const real *w, int n, real *J);
00150 
00151 /* precondition: n >= 2
00152    same as above, but
00153    in row major format (inner index is j, the Gauss index)
00154  */
00155 void gauss_to_legendre_t(const real *z, const real *w, int n, real *J);
00156 
00157 /* precondition: n >= 3
00158    given the Lobatto quadrature rule (z,w,n), compute the square matrix J
00159    for transforming from the Lobatto basis to the Legendre basis:
00160    
00161       u_legendre(i) = sum_j J(i,j) u_lobatto(j)
00162 
00163    in column major format (inner index is i, the Legendre index)
00164  */
00165 void lobatto_to_legendre(const real *z, const real *w, int n, real *J);
00166 
00167 /*--------------------------------------------------------------------------
00168    Lagrangian basis function evaluation
00169   --------------------------------------------------------------------------*/
00170 
00171 /* given the Lagrangian nodes (z,n) and evaluation points (x,m)
00172    evaluate all Lagrangian basis functions at all points x
00173    
00174    inner index of output J is the basis function index (row-major format)
00175    provide work array with space for 4*n doubles
00176  */
00177 void lagrange_weights(const real *z, unsigned n,
00178                       const real *x, unsigned m,
00179                       real *J, real *work);
00180 
00181 /* given the Lagrangian nodes (z,n) and evaluation points (x,m)
00182    evaluate all Lagrangian basis functions and their derivatives
00183    
00184    inner index of outputs J,D is the basis function index (row-major format)
00185    provide work array with space for 6*n doubles
00186  */
00187 void lagrange_weights_deriv(const real *z, unsigned n,
00188                             const real *x, unsigned m,
00189                             real *J, real *D, real *work);
00190 
00191 /*--------------------------------------------------------------------------
00192    Speedy Lagrangian Interpolation
00193    
00194    Usage:
00195    
00196      lagrange_data p;
00197      lagrange_setup(&p,z,n);    *  setup for nodes z[0 ... n-1] *
00198      
00199      the weights
00200        p->J [0 ... n-1]     interpolation weights
00201        p->D [0 ... n-1]     1st derivative weights
00202        p->D2[0 ... n-1]     2nd derivative weights
00203      are computed for a given x with:
00204        lagrange_0(p,x);  *  compute p->J *
00205        lagrange_1(p,x);  *  compute p->J, p->D *
00206        lagrange_2(p,x);  *  compute p->J, p->D, p->D2 *
00207        lagrange_2u(p);   *  compute p->D2 after call of lagrange_1(p,x); *
00208      These functions use the z array supplied to setup
00209        (that pointer should not be freed between calls)
00210      Weights for x=z[0] and x=z[n-1] are computed during setup; access as:
00211        p->J_z0, etc. and p->J_zn, etc.
00212 
00213      lagrange_free(&p);  *  deallocate memory allocated by setup *
00214   --------------------------------------------------------------------------*/
00215 
00216 typedef struct {
00217   unsigned n;                /* number of Lagrange nodes            */
00218   const real *z;             /* Lagrange nodes (user-supplied)      */
00219   real *J, *D, *D2;          /* weights for 0th,1st,2nd derivatives */
00220   real *J_z0, *D_z0, *D2_z0; /* ditto at z[0]   (computed at setup) */
00221   real *J_zn, *D_zn, *D2_zn; /* ditto at z[n-1] (computed at setup) */
00222   real *w, *d, *u0, *v0, *u1, *v1, *u2, *v2; /* work data           */
00223 } lagrange_data;
00224 
00225 void lagrange_setup(lagrange_data *p, const real *z, unsigned n);
00226 void lagrange_free(lagrange_data *p);
00227 
00228 void lagrange_0(lagrange_data *p, real x) ;
00229 void lagrange_1(lagrange_data *p, real x) ;
00230 void lagrange_2(lagrange_data *p, real x) ;
00231 void lagrange_2u(lagrange_data *p) ;
00232 
00233 /*======================================================
00234 / from tensor.h
00235 /======================================================
00236 */
00237 
00238 /*--------------------------------------------------------------------------
00239    1-,2-,3-d Tensor Application
00240    
00241    the 3d case:
00242    tensor_f3(R,mr,nr, S,ms,ns, T,mt,nt, u,v, work1,work2)
00243      gives v = [ R (x) S (x) T ] u
00244      where R is mr x nr, S is ms x ns, T is mt x nt,
00245        each in row- or column-major format according to f := r | c
00246      u is nr x ns x nt in column-major format (inner index is r)
00247      v is mr x ms x mt in column-major format (inner index is r)
00248   --------------------------------------------------------------------------*/
00249 
00250 void tensor_c1(const real *R, unsigned mr, unsigned nr, 
00251                const real *u, real *v);
00252 void tensor_r1(const real *R, unsigned mr, unsigned nr, 
00253                const real *u, real *v);
00254 
00255 /* work holds mr*ns reals */
00256 void tensor_c2(const real *R, unsigned mr, unsigned nr,
00257                const real *S, unsigned ms, unsigned ns,
00258                const real *u, real *v, real *work);
00259 void tensor_r2(const real *R, unsigned mr, unsigned nr,
00260                const real *S, unsigned ms, unsigned ns,
00261                const real *u, real *v, real *work);
00262 
00263 /* work1 holds mr*ns*nt reals,
00264    work2 holds mr*ms*nt reals */
00265 void tensor_c3(const real *R, unsigned mr, unsigned nr,
00266                const real *S, unsigned ms, unsigned ns,
00267                const real *T, unsigned mt, unsigned nt,
00268                const real *u, real *v, real *work1, real *work2);
00269 void tensor_r3(const real *R, unsigned mr, unsigned nr,
00270                const real *S, unsigned ms, unsigned ns,
00271                const real *T, unsigned mt, unsigned nt,
00272                const real *u, real *v, real *work1, real *work2);
00273 
00274 /*--------------------------------------------------------------------------
00275    1-,2-,3-d Tensor Application of Row Vectors (for Interpolation)
00276    
00277    the 3d case:
00278    v = tensor_i3(Jr,nr, Js,ns, Jt,nt, u, work)
00279    same effect as tensor_r3(Jr,1,nr, Js,1,ns, Jt,1,nt, u,&v, work1,work2):
00280      gives v = [ Jr (x) Js (x) Jt ] u
00281      where Jr, Js, Jt are row vectors (interpolation weights)
00282      u is nr x ns x nt in column-major format (inner index is r)
00283      v is a scalar
00284   --------------------------------------------------------------------------*/
00285 
00286 real tensor_i1(const real *Jr, unsigned nr, const real *u);
00287 
00288 /* work holds ns reals */
00289 real tensor_i2(const real *Jr, unsigned nr,
00290                const real *Js, unsigned ns,
00291                const real *u, real *work);
00292 
00293 /* work holds ns*nt + nt reals */
00294 real tensor_i3(const real *Jr, unsigned nr,
00295                const real *Js, unsigned ns,
00296                const real *Jt, unsigned nt,
00297                const real *u, real *work);
00298 
00299 /*--------------------------------------------------------------------------
00300    1-,2-,3-d Tensor Application of Row Vectors
00301              for simultaneous Interpolation and Gradient computation
00302    
00303    the 3d case:
00304    v = tensor_ig3(Jr,Dr,nr, Js,Ds,ns, Jt,Dt,nt, u,g, work)
00305      gives v   = [ Jr (x) Js (x) Jt ] u
00306            g_0 = [ Dr (x) Js (x) Jt ] u
00307            g_1 = [ Jr (x) Ds (x) Jt ] u
00308            g_2 = [ Jr (x) Js (x) Dt ] u
00309      where Jr,Dr,Js,Ds,Jt,Dt are row vectors
00310        (interpolation & derivative weights)
00311      u is nr x ns x nt in column-major format (inner index is r)
00312      v is a scalar, g is an array of 3 reals
00313   --------------------------------------------------------------------------*/
00314 
00315 real tensor_ig1(const real *Jr, const real *Dr, unsigned nr,
00316                 const real *u, real *g);
00317 
00318 /* work holds 2*ns reals */
00319 real tensor_ig2(const real *Jr, const real *Dr, unsigned nr,
00320                 const real *Js, const real *Ds, unsigned ns,
00321                 const real *u, real *g, real *work);
00322 
00323 /* work holds 2*ns*nt + 3*ns reals */
00324 real tensor_ig3(const real *Jr, const real *Dr, unsigned nr,
00325                 const real *Js, const real *Ds, unsigned ns,
00326                 const real *Jt, const real *Dt, unsigned nt,
00327                 const real *u, real *g, real *work);
00328 
00329 /*======================================================
00330 / from findpt.h
00331 /======================================================
00332 */
00333 
00334 typedef struct {
00335   real x[2], A[4], axis_bnd[4];
00336 } obbox_2;
00337 
00338 typedef struct {
00339   real x[3], A[9], axis_bnd[6];
00340 } obbox_3;
00341 
00342 typedef struct {
00343   unsigned hash_n;
00344   real bnd[4]; /* bounds for all elements */
00345   real fac[2]; /* fac[i] = hash_n / (bnd[2*i+1]-bnd[2*i]) */
00346   obbox_2 *obb; /* obb[nel] -- bounding box info for each element */
00347   uint *offset; /* hash table -- for cell i,j:
00348                          uint index = j*hash_n+i,
00349                                   b = offset[index  ],
00350                                   e = offset[index+1];
00351                          elements in cell are
00352                            offset[b], offset[b+1], ..., offset[e-1] */
00353   unsigned max; /* maximum # of elements in any cell */
00354 } hash_data_2;
00355 
00356 typedef struct {
00357   unsigned hash_n;
00358   real bnd[6]; /* bounds for all elements */
00359   real fac[3]; /* fac[i] = hash_n / (bnd[2*i+1]-bnd[2*i]) */
00360   obbox_3 *obb; /* obb[nel] -- bounding box info for each element */
00361   uint *offset; /* hash table -- for cell i,j,k:
00362                          uint index = (k*hash_n+j)*hash_n+i,
00363                                   b = offset[index  ],
00364                                   e = offset[index+1];
00365                          elements in cell are
00366                            offset[b], offset[b+1], ..., offset[e-1] */
00367   unsigned max; /* maximum # of elements in any cell */
00368 } hash_data_3;
00369 
00370 typedef struct {
00371   uint el;
00372   real r[3];
00373   real dist;
00374 } findpt_listel;
00375 
00376 typedef struct {
00377   unsigned constraints;
00378   unsigned de, d1;
00379   real *x[2], *fd1[2];
00380 } opt_edge_data_2;
00381 
00382 typedef struct {
00383   unsigned constraints;
00384   real x[2], jac[4];
00385 } opt_point_data_2;
00386 
00387 typedef struct {
00388   lagrange_data *ld;
00389   unsigned size[3];
00390   const real *elx[2];
00391   opt_edge_data_2 ed;
00392   opt_point_data_2 pd;
00393   real *work;
00394   real x[2], jac[4];
00395 } opt_data_2;
00396 
00397 typedef struct {
00398   const real *xw[2];   /* geometry data */
00399   real *z[2];          /* lobatto nodes */
00400   lagrange_data ld[2]; /* interpolation, derivative weights & data */
00401   unsigned nptel;      /* nodes per element */
00402   hash_data_2 *hash;   /* geometric hashing data */
00403   findpt_listel *list, **sorted, **end;
00404                                         /* pre-allocated list of elements to
00405                                            check (found by hashing), and
00406                                            pre-allocated list of pointers into
00407                                            the first list for sorting */
00408   opt_data_2 *od; /* data for the optimization algorithm */
00409   real *od_work;
00410 } findpt_data_2;
00411 
00412 typedef struct {
00413   unsigned constraints;
00414   unsigned dn, d1, d2;
00415   real *x[3], *fdn[3];
00416 } opt_face_data_3;
00417 
00418 typedef struct {
00419   unsigned constraints;
00420   unsigned de, d1, d2;
00421   real *x[3], *fd1[3], *fd2[3];
00422 } opt_edge_data_3;
00423 
00424 typedef struct {
00425   unsigned constraints;
00426   real x[3], jac[9];
00427 } opt_point_data_3;
00428 
00429 typedef struct {
00430   lagrange_data *ld;
00431   unsigned size[4];
00432   const real *elx[3];
00433   opt_face_data_3 fd;
00434   opt_edge_data_3 ed;
00435   opt_point_data_3 pd;
00436   real *work;
00437   real x[3], jac[9];
00438 } opt_data_3;
00439 
00440 typedef struct {
00441   const real *xw[3];   /* geometry data */
00442   real *z[3];          /* lobatto nodes */
00443   lagrange_data ld[3]; /* interpolation, derivative weights & data */
00444   unsigned nptel;      /* nodes per element */
00445   hash_data_3 *hash;   /* geometric hashing data */
00446   findpt_listel *list, **sorted, **end;
00447                                         /* pre-allocated list of elements to
00448                                            check (found by hashing), and
00449                                            pre-allocated list of pointers into
00450                                            the first list for sorting */
00451   opt_data_3 *od; /* data for the optimization algorithm */
00452   real *od_work;
00453 } findpt_data_3;
00454 
00455 findpt_data_2 *findpt_setup_2(
00456           const real *const xw[2], const unsigned n[2], uint nel,
00457           uint max_hash_size, real bbox_tol);
00458 findpt_data_3 *findpt_setup_3(
00459           const real *const xw[3], const unsigned n[3], uint nel,
00460           uint max_hash_size, real bbox_tol);
00461 
00462 void findpt_free_2(findpt_data_2 *p);
00463 void findpt_free_3(findpt_data_3 *p);
00464 
00465 const real *findpt_allbnd_2(const findpt_data_2 *p);
00466 const real *findpt_allbnd_3(const findpt_data_3 *p);
00467 
00468 typedef int (*findpt_func)(void *, const real *, int, uint *, real *, real *);
00469 int findpt_2(findpt_data_2 *p, const real x[2], int guess,
00470              uint *el, real r[2], real *dist);
00471 int findpt_3(findpt_data_3 *p, const real x[3], int guess,
00472              uint *el, real r[3], real *dist);
00473 
00474 void findpt_weights_2(findpt_data_2 *p, const real r[2]);
00475 
00476 void findpt_weights_3(findpt_data_3 *p, const real r[3]);
00477 
00478 double findpt_eval_2(findpt_data_2 *p, const real *u);
00479 
00480 double findpt_eval_3(findpt_data_3 *p, const real *u);
00481 
00482 /*======================================================
00483 / from extrafindpt.h
00484 /======================================================
00485 */
00486 
00487 void opt_alloc_3(opt_data_3 *p, lagrange_data *ld);
00488 void opt_free_3(opt_data_3 *p);
00489 double opt_findpt_3(opt_data_3 *p, const real *const elx[3],
00490                            const real xstar[3], real r[3], unsigned *constr);
00491 void opt_vol_set_intp_3(opt_data_3 *p, const real r[3]);
00492 
00493 /* for 2d spectralQuad */
00494 /*--------------------------------------------------------------------------
00495 
00496    2 - D
00497 
00498   --------------------------------------------------------------------------*/
00499 
00500 void opt_alloc_2(opt_data_2 *p, lagrange_data *ld);
00501 void opt_free_2(opt_data_2 *p);
00502 double opt_findpt_2(opt_data_2 *p, const real *const elx[2],
00503                            const real xstar[2], real r[2], unsigned *constr);
00504 
00505 extern const unsigned opt_no_constraints_2;
00506 extern const unsigned opt_no_constraints_3;
00507 
00508 /*======================================================
00509 / from errmem.h
00510 /======================================================
00511 */
00512 
00513 /* requires:
00514      <stdlib.h> for malloc, calloc, realloc, free
00515 */
00516 
00517 /*--------------------------------------------------------------------------
00518    Error Reporting
00519    Memory Allocation Wrappers to Catch Out-of-memory
00520   --------------------------------------------------------------------------*/
00521 
00522 /* #include "malloc.h" */
00523 #include <stdlib.h>
00524 
00525 #ifdef __GNUC__
00526 void fail(const char *fmt, ...) __attribute__ ((noreturn));
00527 #define MAYBE_UNUSED __attribute__ ((unused))
00528 #else
00529 void fail(const char *fmt, ...);
00530 #define MAYBE_UNUSED
00531 #endif
00532 
00533 #if 0
00534 {}
00535 #endif
00536 
00537 static void *smalloc(size_t size, const char *file) MAYBE_UNUSED;
00538 static void *smalloc(size_t size, const char *file)
00539 {
00540   void *res = malloc(size);
00541   if(!res && size) fail("%s: allocation of %d bytes failed\n",file,(int)size);
00542   return res;
00543 }
00544 
00545 static void *scalloc(size_t nmemb, size_t size, const char *file) MAYBE_UNUSED;
00546 static void *scalloc(size_t nmemb, size_t size, const char *file)
00547 {
00548   void *res = calloc(nmemb, size);
00549   if(!res && nmemb)
00550     fail("%s: allocation of %d bytes failed\n",file,(int)size*nmemb);
00551   return res;
00552 }
00553 
00554 static void *srealloc(void *ptr, size_t size, const char *file) MAYBE_UNUSED;
00555 static void *srealloc(void *ptr, size_t size, const char *file)
00556 {
00557   void *res = realloc(ptr, size);
00558   if(!res && size) fail("%s: allocation of %d bytes failed\n",file,(int)size);
00559   return res;
00560 }
00561 
00562 #define tmalloc(type, count) \
00563   ((type*) smalloc((count)*sizeof(type),__FILE__) )
00564 #define tcalloc(type, count) \
00565   ((type*) scalloc((count),sizeof(type),__FILE__) )
00566 #define trealloc(type, ptr, count) \
00567   ((type*) srealloc((ptr),(count)*sizeof(type),__FILE__) )
00568 /*
00569 typedef struct { size_t size; void *ptr; } buffer;
00570 
00571 static void buffer_init_(buffer *b, size_t size, const char *file) MAYBE_UNUSED;
00572 static void buffer_init_(buffer *b, size_t size, const char *file)
00573 {
00574   b->size=size, b->ptr=smalloc(size,file);
00575 }
00576 static void buffer_reserve_(buffer *b, size_t min, const char *file)
00577   MAYBE_UNUSED;
00578 static void buffer_reserve_(buffer *b, size_t min, const char *file)
00579 {
00580   size_t size = b->size;
00581   if(size<min) {
00582     size+=size/2+1;
00583     if(size<min) size=min;
00584     b->ptr=srealloc(b->ptr,size,file);
00585   }
00586 }
00587 static void buffer_free(buffer *b) MAYBE_UNUSED;
00588 static void buffer_free(buffer *b) { free(b->ptr); }
00589 
00590 #define buffer_init(b,size) buffer_init_(b,size,__FILE__)
00591 #define buffer_reserve(b,min) buffer_reserve_(b,min,__FILE__)
00592 */
00593 
00594 
00595 /*======================================================
00596 / from minmax.h
00597 /======================================================
00598 */
00599 
00600 /*--------------------------------------------------------------------------
00601    Min, Max, Norm
00602   --------------------------------------------------------------------------*/
00603 
00604 #ifdef __GNUC__
00605 #define MAYBE_UNUSED __attribute__ ((unused))
00606 #else
00607 #define MAYBE_UNUSED
00608 #endif
00609 
00610 #define DECLMINMAX(type, prefix) \
00611   static type prefix##min_2(type a, type b) MAYBE_UNUSED;               \
00612   static type prefix##min_2(type a, type b) {                           \
00613     return b<a?b:a;                                                     \
00614   }                                                                     \
00615   static type prefix##max_2(type a, type b) MAYBE_UNUSED;               \
00616   static type prefix##max_2(type a, type b) {                           \
00617     return a>b?a:b;                                                     \
00618   }                                                                     \
00619   static void prefix##minmax_2(type *min, type *max, type a,            \
00620                                type b) MAYBE_UNUSED;                    \
00621   static void prefix##minmax_2(type *min, type *max, type a, type b) {  \
00622     if(b<a) *min=b, *max=a;                                             \
00623     else *min=a, *max=b;                                                \
00624   }                                                                     \
00625   static type prefix##min_3(type a, type b, type c) MAYBE_UNUSED;       \
00626   static type prefix##min_3(type a, type b, type c) {                   \
00627     return b<a?(c<b?c:b):(c<a?c:a);                                     \
00628   }                                                                     \
00629   static type prefix##max_3(type a, type b, type c) MAYBE_UNUSED;       \
00630   static type prefix##max_3(type a, type b, type c) {                   \
00631     return a>b?(a>c?a:c):(b>c?b:c);                                     \
00632   }                                                                     \
00633   static void prefix##minmax_3(type *min, type *max, type a, type b,    \
00634                                type c) MAYBE_UNUSED;                    \
00635   static void prefix##minmax_3(type *min, type *max, type a, type b,    \
00636                                type c) {                                \
00637     if(b<a) *min=prefix##min_2(b,c), *max=prefix##max_2(a,c);           \
00638     else    *min=prefix##min_2(a,c), *max=prefix##max_2(b,c);           \
00639   }
00640 
00641 DECLMINMAX(int, i)
00642 DECLMINMAX(unsigned, u)
00643 DECLMINMAX(real, r)
00644 #undef DECLMINMAX
00645 
00646 static real r1norm_1(real a) MAYBE_UNUSED;
00647 static real r1norm_1(real a) {
00648   return fabsr(a);
00649 }
00650 static real r1norm_2(real a, real b) MAYBE_UNUSED;
00651 static real r1norm_2(real a, real b) {
00652   return fabsr(a)+fabsr(b);
00653 }
00654 static real r1norm_3(real a, real b, real c) MAYBE_UNUSED;
00655 static real r1norm_3(real a, real b, real c) {
00656   return fabsr(a)+fabsr(b)+fabsr(c);
00657 }
00658 static real r2norm_1(real a) MAYBE_UNUSED;
00659 static real r2norm_1(real a) {
00660   return sqrtr(a*a);
00661 }
00662 static real r2norm_2(real a, real b) MAYBE_UNUSED;
00663 static real r2norm_2(real a, real b) {
00664   return sqrtr(a*a+b*b);
00665 }
00666 static real r2norm_3(real a, real b, real c) MAYBE_UNUSED;
00667 static real r2norm_3(real a, real b, real c) {
00668   return sqrtr(a*a+b*b+c*c);
00669 }
00670 
00671 #endif
00672 
00673 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines