Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FindPtFuncs.h
Go to the documentation of this file.
1 #ifndef FINDPTFUNCS_H 2 #define FINDPTFUNCS_H 3  4 #include "float.h" 5 #include "math.h" 6  7 /*====================================================== 8 / from types.h 9 /====================================================== 10 */ 11  12 #define MOAB_POLY_EPS ( 128 * DBL_EPSILON ) 13 #define MOAB_POLY_PI 3.1415926535897932384626433832795028841971693993751058209749445923 14  15 #define mbsqrt sqrt 16 #define mbabs fabs 17 #define mbcos cos 18 #define mbsin sin 19 #define mbfloor floor 20 #define mbceil ceil 21  22 #ifdef INTEGER 23 #undef INTEGER 24 #endif 25  26 #ifdef real 27 #undef real 28 #endif 29  30 /* integer type to use for everything */ 31 #if defined( USE_LONG ) 32 #define INTEGER long 33 #elif defined( USE_LONG_LONG ) 34 #define INTEGER long long 35 #elif defined( USE_SHORT ) 36 #define INTEGER short 37 #else 38 #define INTEGER int 39 #endif 40  41 /* when defined, use the given type for global indices instead of INTEGER */ 42 #if defined( USE_GLOBAL_LONG_LONG ) 43 #define GLOBAL_INT long long 44 #elif defined( USE_GLOBAL_LONG ) 45 #define GLOBAL_INT long 46 #else 47 #define GLOBAL_INT long 48 #endif 49  50 /* floating point type to use for everything */ 51 #if defined( USE_FLOAT ) 52 typedef float realType; 53 #elif defined( USE_LONG_DOUBLE ) 54 typedef long double realType; 55 #else 56 typedef double realType; 57 #endif 58  59 /* apparently uint and ulong can be defined already in standard headers */ 60 #ifndef uint 61 typedef signed INTEGER sint; 62 #endif 63  64 #ifndef uint 65 typedef unsigned INTEGER uint; 66 #endif 67 #undef INTEGER 68  69 #ifndef slong 70 #ifdef GLOBAL_INT 71 typedef signed GLOBAL_INT slong; 72 #else 73 typedef sint slong; 74 #endif 75 #endif 76  77 #ifndef ulong 78 #ifdef GLOBAL_INT 79 typedef unsigned GLOBAL_INT ulong; 80 #else 81 typedef uint ulong; 82 #endif 83 #endif 84  85 /*====================================================== 86 / from poly.h 87 /====================================================== 88 */ 89  90 /* 91  For brevity's sake, some names have been shortened 92  Quadrature rules 93  Gauss -> Gauss-Legendre quadrature (open) 94  Lobatto -> Gauss-Lobatto-Legendre quadrature (closed at both ends) 95  Polynomial bases 96  Legendre -> Legendre basis 97  Gauss -> Lagrangian basis using Gauss quadrature nodes 98  Lobatto -> Lagrangian basis using Lobatto quadrature nodes 99 */ 100  101 /*-------------------------------------------------------------------------- 102  Legendre Polynomial Matrix Computation 103  (compute P_i(x_j) for i = 0, ..., n and a given set of x) 104  --------------------------------------------------------------------------*/ 105  106 /* precondition: n >= 1 107  inner index is x index (0 ... m-1); 108  outer index is Legendre polynomial number (0 ... n) 109  */ 110 void legendre_matrix( const realType* x, int m, realType* P, int n ); 111  112 /* precondition: n >= 1 113  inner index is Legendre polynomial number (0 ... n) 114  outer index is x index (0 ... m-1); 115  */ 116 void legendre_matrix_t( const realType* x, int m, realType* P, int n ); 117  118 /* precondition: n >= 1 119  compute P_i(x) with i = 0 ... n 120  */ 121 void legendre_row( realType x, realType* P, int n ); 122  123 /*-------------------------------------------------------------------------- 124  Quadrature Nodes and Weights Calculation 125  126  call the _nodes function before calling the _weights function 127  --------------------------------------------------------------------------*/ 128  129 void gauss_nodes( realType* z, int n ); /* n nodes (order = 2n-1) */ 130 void lobatto_nodes( realType* z, int n ); /* n nodes (order = 2n-3) */ 131  132 void gauss_weights( const realType* z, realType* w, int n ); 133 void lobatto_weights( const realType* z, realType* w, int n ); 134  135 /*-------------------------------------------------------------------------- 136  Lagrangian to Legendre Change-of-basis Matrix 137  --------------------------------------------------------------------------*/ 138  139 /* precondition: n >= 2 140  given the Gauss quadrature rule (z,w,n), compute the square matrix J 141  for transforming from the Gauss basis to the Legendre basis: 142  143  u_legendre(i) = sum_j J(i,j) u_gauss(j) 144  145  computes J = .5 (2i+1) w P (z ) 146  ij j i j 147  148  in column major format (inner index is i, the Legendre index) 149  */ 150 void gauss_to_legendre( const realType* z, const realType* w, int n, realType* J ); 151  152 /* precondition: n >= 2 153  same as above, but 154  in row major format (inner index is j, the Gauss index) 155  */ 156 void gauss_to_legendre_t( const realType* z, const realType* w, int n, realType* J ); 157  158 /* precondition: n >= 3 159  given the Lobatto quadrature rule (z,w,n), compute the square matrix J 160  for transforming from the Lobatto basis to the Legendre basis: 161  162  u_legendre(i) = sum_j J(i,j) u_lobatto(j) 163  164  in column major format (inner index is i, the Legendre index) 165  */ 166 void lobatto_to_legendre( const realType* z, const realType* w, int n, realType* J ); 167  168 /*-------------------------------------------------------------------------- 169  Lagrangian basis function evaluation 170  --------------------------------------------------------------------------*/ 171  172 /* given the Lagrangian nodes (z,n) and evaluation points (x,m) 173  evaluate all Lagrangian basis functions at all points x 174  175  inner index of output J is the basis function index (row-major format) 176  provide work array with space for 4*n doubles 177  */ 178 void lagrange_weights( const realType* z, unsigned n, const realType* x, unsigned m, realType* J, realType* work ); 179  180 /* given the Lagrangian nodes (z,n) and evaluation points (x,m) 181  evaluate all Lagrangian basis functions and their derivatives 182  183  inner index of outputs J,D is the basis function index (row-major format) 184  provide work array with space for 6*n doubles 185  */ 186 void lagrange_weights_deriv( const realType* z, 187  unsigned n, 188  const realType* x, 189  unsigned m, 190  realType* J, 191  realType* D, 192  realType* work ); 193  194 /*-------------------------------------------------------------------------- 195  Speedy Lagrangian Interpolation 196  197  Usage: 198  199  lagrange_data p; 200  lagrange_setup(&p,z,n); * setup for nodes z[0 ... n-1] * 201  202  the weights 203  p->J [0 ... n-1] interpolation weights 204  p->D [0 ... n-1] 1st derivative weights 205  p->D2[0 ... n-1] 2nd derivative weights 206  are computed for a given x with: 207  lagrange_0(p,x); * compute p->J * 208  lagrange_1(p,x); * compute p->J, p->D * 209  lagrange_2(p,x); * compute p->J, p->D, p->D2 * 210  lagrange_2u(p); * compute p->D2 after call of lagrange_1(p,x); * 211  These functions use the z array supplied to setup 212  (that pointer should not be freed between calls) 213  Weights for x=z[0] and x=z[n-1] are computed during setup; access as: 214  p->J_z0, etc. and p->J_zn, etc. 215  216  lagrange_free(&p); * deallocate memory allocated by setup * 217  --------------------------------------------------------------------------*/ 218  219 typedef struct 220 { 221  unsigned n; /* number of Lagrange nodes */ 222  const realType* z; /* Lagrange nodes (user-supplied) */ 223  realType *J, *D, *D2; /* weights for 0th,1st,2nd derivatives */ 224  realType *J_z0, *D_z0, *D2_z0; /* ditto at z[0] (computed at setup) */ 225  realType *J_zn, *D_zn, *D2_zn; /* ditto at z[n-1] (computed at setup) */ 226  realType *w, *d, *u0, *v0, *u1, *v1, *u2, *v2; /* work data */ 227 } lagrange_data; 228  229 void lagrange_setup( lagrange_data* p, const realType* z, unsigned n ); 230 void lagrange_free( lagrange_data* p ); 231  232 void lagrange_0( lagrange_data* p, realType x ); 233 void lagrange_1( lagrange_data* p, realType x ); 234 void lagrange_2( lagrange_data* p, realType x ); 235 void lagrange_2u( lagrange_data* p ); 236  237 /*====================================================== 238 / from tensor.h 239 /====================================================== 240 */ 241  242 /*-------------------------------------------------------------------------- 243  1-,2-,3-d Tensor Application 244  245  the 3d case: 246  tensor_f3(R,mr,nr, S,ms,ns, T,mt,nt, u,v, work1,work2) 247  gives v = [ R (x) S (x) T ] u 248  where R is mr x nr, S is ms x ns, T is mt x nt, 249  each in row- or column-major format according to f := r | c 250  u is nr x ns x nt in column-major format (inner index is r) 251  v is mr x ms x mt in column-major format (inner index is r) 252  --------------------------------------------------------------------------*/ 253  254 void tensor_c1( const realType* R, unsigned mr, unsigned nr, const realType* u, realType* v ); 255 void tensor_r1( const realType* R, unsigned mr, unsigned nr, const realType* u, realType* v ); 256  257 /* work holds mr*ns realTypes */ 258 void tensor_c2( const realType* R, 259  unsigned mr, 260  unsigned nr, 261  const realType* S, 262  unsigned ms, 263  unsigned ns, 264  const realType* u, 265  realType* v, 266  realType* work ); 267 void tensor_r2( const realType* R, 268  unsigned mr, 269  unsigned nr, 270  const realType* S, 271  unsigned ms, 272  unsigned ns, 273  const realType* u, 274  realType* v, 275  realType* work ); 276  277 /* work1 holds mr*ns*nt realTypes, 278  work2 holds mr*ms*nt realTypes */ 279 void tensor_c3( const realType* R, 280  unsigned mr, 281  unsigned nr, 282  const realType* S, 283  unsigned ms, 284  unsigned ns, 285  const realType* T, 286  unsigned mt, 287  unsigned nt, 288  const realType* u, 289  realType* v, 290  realType* work1, 291  realType* work2 ); 292 void tensor_r3( const realType* R, 293  unsigned mr, 294  unsigned nr, 295  const realType* S, 296  unsigned ms, 297  unsigned ns, 298  const realType* T, 299  unsigned mt, 300  unsigned nt, 301  const realType* u, 302  realType* v, 303  realType* work1, 304  realType* work2 ); 305  306 /*-------------------------------------------------------------------------- 307  1-,2-,3-d Tensor Application of Row Vectors (for Interpolation) 308  309  the 3d case: 310  v = tensor_i3(Jr,nr, Js,ns, Jt,nt, u, work) 311  same effect as tensor_r3(Jr,1,nr, Js,1,ns, Jt,1,nt, u,&v, work1,work2): 312  gives v = [ Jr (x) Js (x) Jt ] u 313  where Jr, Js, Jt are row vectors (interpolation weights) 314  u is nr x ns x nt in column-major format (inner index is r) 315  v is a scalar 316  --------------------------------------------------------------------------*/ 317  318 realType tensor_i1( const realType* Jr, unsigned nr, const realType* u ); 319  320 /* work holds ns realTypes */ 321 realType tensor_i2( const realType* Jr, 322  unsigned nr, 323  const realType* Js, 324  unsigned ns, 325  const realType* u, 326  realType* work ); 327  328 /* work holds ns*nt + nt realTypes */ 329 realType tensor_i3( const realType* Jr, 330  unsigned nr, 331  const realType* Js, 332  unsigned ns, 333  const realType* Jt, 334  unsigned nt, 335  const realType* u, 336  realType* work ); 337  338 /*-------------------------------------------------------------------------- 339  1-,2-,3-d Tensor Application of Row Vectors 340  for simultaneous Interpolation and Gradient computation 341  342  the 3d case: 343  v = tensor_ig3(Jr,Dr,nr, Js,Ds,ns, Jt,Dt,nt, u,g, work) 344  gives v = [ Jr (x) Js (x) Jt ] u 345  g_0 = [ Dr (x) Js (x) Jt ] u 346  g_1 = [ Jr (x) Ds (x) Jt ] u 347  g_2 = [ Jr (x) Js (x) Dt ] u 348  where Jr,Dr,Js,Ds,Jt,Dt are row vectors 349  (interpolation & derivative weights) 350  u is nr x ns x nt in column-major format (inner index is r) 351  v is a scalar, g is an array of 3 realTypes 352  --------------------------------------------------------------------------*/ 353  354 realType tensor_ig1( const realType* Jr, const realType* Dr, unsigned nr, const realType* u, realType* g ); 355  356 /* work holds 2*ns realTypes */ 357 realType tensor_ig2( const realType* Jr, 358  const realType* Dr, 359  unsigned nr, 360  const realType* Js, 361  const realType* Ds, 362  unsigned ns, 363  const realType* u, 364  realType* g, 365  realType* work ); 366  367 /* work holds 2*ns*nt + 3*ns realTypes */ 368 realType tensor_ig3( const realType* Jr, 369  const realType* Dr, 370  unsigned nr, 371  const realType* Js, 372  const realType* Ds, 373  unsigned ns, 374  const realType* Jt, 375  const realType* Dt, 376  unsigned nt, 377  const realType* u, 378  realType* g, 379  realType* work ); 380  381 /*====================================================== 382 / from findpt.h 383 /====================================================== 384 */ 385  386 typedef struct 387 { 388  realType x[2], A[4], axis_bnd[4]; 389 } obbox_2; 390  391 typedef struct 392 { 393  realType x[3], A[9], axis_bnd[6]; 394 } obbox_3; 395  396 typedef struct 397 { 398  unsigned hash_n; 399  realType bnd[4]; /* bounds for all elements */ 400  realType fac[2]; /* fac[i] = hash_n / (bnd[2*i+1]-bnd[2*i]) */ 401  obbox_2* obb; /* obb[nel] -- bounding box info for each element */ 402  uint* offset; /* hash table -- for cell i,j: 403  uint index = j*hash_n+i, 404  b = offset[index ], 405  e = offset[index+1]; 406  elements in cell are 407  offset[b], offset[b+1], ..., offset[e-1] */ 408  unsigned max; /* maximum # of elements in any cell */ 409 } hash_data_2; 410  411 typedef struct 412 { 413  unsigned hash_n; 414  realType bnd[6]; /* bounds for all elements */ 415  realType fac[3]; /* fac[i] = hash_n / (bnd[2*i+1]-bnd[2*i]) */ 416  obbox_3* obb; /* obb[nel] -- bounding box info for each element */ 417  uint* offset; /* hash table -- for cell i,j,k: 418  uint index = (k*hash_n+j)*hash_n+i, 419  b = offset[index ], 420  e = offset[index+1]; 421  elements in cell are 422  offset[b], offset[b+1], ..., offset[e-1] */ 423  unsigned max; /* maximum # of elements in any cell */ 424 } hash_data_3; 425  426 typedef struct 427 { 428  uint el; 429  realType r[3]; 430  realType dist; 431 } findpt_listel; 432  433 typedef struct 434 { 435  unsigned constraints; 436  unsigned de, d1; 437  realType *x[2], *fd1[2]; 438 } opt_edge_data_2; 439  440 typedef struct 441 { 442  unsigned constraints; 443  realType x[2], jac[4]; 444 } opt_point_data_2; 445  446 typedef struct 447 { 448  lagrange_data* ld; 449  unsigned size[3]; 450  const realType* elx[2]; 451  opt_edge_data_2 ed; 452  opt_point_data_2 pd; 453  realType* work; 454  realType x[2], jac[4]; 455 } opt_data_2; 456  457 typedef struct 458 { 459  const realType* xw[2]; /* geometry data */ 460  realType* z[2]; /* lobatto nodes */ 461  lagrange_data ld[2]; /* interpolation, derivative weights & data */ 462  unsigned nptel; /* nodes per element */ 463  hash_data_2* hash; /* geometric hashing data */ 464  findpt_listel *list, **sorted, **end; 465  /* pre-allocated list of elements to 466  check (found by hashing), and 467  pre-allocated list of pointers into 468  the first list for sorting */ 469  opt_data_2* od; /* data for the optimization algorithm */ 470  realType* od_work; 471 } findpt_data_2; 472  473 typedef struct 474 { 475  unsigned constraints; 476  unsigned dn, d1, d2; 477  realType *x[3], *fdn[3]; 478 } opt_face_data_3; 479  480 typedef struct 481 { 482  unsigned constraints; 483  unsigned de, d1, d2; 484  realType *x[3], *fd1[3], *fd2[3]; 485 } opt_edge_data_3; 486  487 typedef struct 488 { 489  unsigned constraints; 490  realType x[3], jac[9]; 491 } opt_point_data_3; 492  493 typedef struct 494 { 495  lagrange_data* ld; 496  unsigned size[4]; 497  const realType* elx[3]; 498  opt_face_data_3 fd; 499  opt_edge_data_3 ed; 500  opt_point_data_3 pd; 501  realType* work; 502  realType x[3], jac[9]; 503 } opt_data_3; 504  505 typedef struct 506 { 507  const realType* xw[3]; /* geometry data */ 508  realType* z[3]; /* lobatto nodes */ 509  lagrange_data ld[3]; /* interpolation, derivative weights & data */ 510  unsigned nptel; /* nodes per element */ 511  hash_data_3* hash; /* geometric hashing data */ 512  findpt_listel *list, **sorted, **end; 513  /* pre-allocated list of elements to 514  check (found by hashing), and 515  pre-allocated list of pointers into 516  the first list for sorting */ 517  opt_data_3* od; /* data for the optimization algorithm */ 518  realType* od_work; 519 } findpt_data_3; 520  521 findpt_data_2* findpt_setup_2( const realType* const xw[2], 522  const unsigned n[2], 523  uint nel, 524  uint max_hash_size, 525  realType bbox_tol ); 526 findpt_data_3* findpt_setup_3( const realType* const xw[3], 527  const unsigned n[3], 528  uint nel, 529  uint max_hash_size, 530  realType bbox_tol ); 531  532 void findpt_free_2( findpt_data_2* p ); 533 void findpt_free_3( findpt_data_3* p ); 534  535 const realType* findpt_allbnd_2( const findpt_data_2* p ); 536 const realType* findpt_allbnd_3( const findpt_data_3* p ); 537  538 typedef int ( *findpt_func )( void*, const realType*, int, uint*, realType*, realType* ); 539 int findpt_2( findpt_data_2* p, const realType x[2], int guess, uint* el, realType r[2], realType* dist ); 540 int findpt_3( findpt_data_3* p, const realType x[3], int guess, uint* el, realType r[3], realType* dist ); 541  542 void findpt_weights_2( findpt_data_2* p, const realType r[2] ); 543  544 void findpt_weights_3( findpt_data_3* p, const realType r[3] ); 545  546 double findpt_eval_2( findpt_data_2* p, const realType* u ); 547  548 double findpt_eval_3( findpt_data_3* p, const realType* u ); 549  550 /*====================================================== 551 / from extrafindpt.h 552 /====================================================== 553 */ 554  555 void opt_alloc_3( opt_data_3* p, lagrange_data* ld ); 556 void opt_free_3( opt_data_3* p ); 557 double opt_findpt_3( opt_data_3* p, 558  const realType* const elx[3], 559  const realType xstar[3], 560  realType r[3], 561  unsigned* constr ); 562 void opt_vol_set_intp_3( opt_data_3* p, const realType r[3] ); 563  564 /* for 2d spectralQuad */ 565 /*-------------------------------------------------------------------------- 566  567  2 - D 568  569  --------------------------------------------------------------------------*/ 570  571 void opt_alloc_2( opt_data_2* p, lagrange_data* ld ); 572 void opt_free_2( opt_data_2* p ); 573 double opt_findpt_2( opt_data_2* p, 574  const realType* const elx[2], 575  const realType xstar[2], 576  realType r[2], 577  unsigned* constr ); 578  579 extern const unsigned opt_no_constraints_2; 580 extern const unsigned opt_no_constraints_3; 581  582 /*====================================================== 583 / from errmem.h 584 /====================================================== 585 */ 586  587 /* requires: 588  <stdlib.h> for malloc, calloc, realloc, free 589 */ 590  591 /*-------------------------------------------------------------------------- 592  Error Reporting 593  Memory Allocation Wrappers to Catch Out-of-memory 594  --------------------------------------------------------------------------*/ 595  596 /* #include "malloc.h" */ 597 #include <stdlib.h> 598  599 #ifdef __GNUC__ 600 void fail( const char* fmt, ... ) __attribute__( ( noreturn ) ); 601 #define MAYBE_UNUSED __attribute__( ( unused ) ) 602 #else 603 void fail( const char* fmt, ... ); 604 #define MAYBE_UNUSED 605 #endif 606  607 #if 0 608 {} 609 #endif 610  611 static void* smalloc( size_t size, const char* file ) MAYBE_UNUSED; 612 static void* smalloc( size_t size, const char* file ) 613 { 614  void* res = malloc( size ); 615  if( !res && size ) fail( "%s: allocation of %d bytes failed\n", file, (int)size ); 616  return res; 617 } 618  619 static void* scalloc( size_t nmemb, size_t size, const char* file ) MAYBE_UNUSED; 620 static void* scalloc( size_t nmemb, size_t size, const char* file ) 621 { 622  void* res = calloc( nmemb, size ); 623  if( !res && nmemb ) fail( "%s: allocation of %d bytes failed\n", file, (int)size * nmemb ); 624  return res; 625 } 626  627 static void* srealloc( void* ptr, size_t size, const char* file ) MAYBE_UNUSED; 628 static void* srealloc( void* ptr, size_t size, const char* file ) 629 { 630  void* res = realloc( ptr, size ); 631  if( !res && size ) fail( "%s: allocation of %d bytes failed\n", file, (int)size ); 632  return res; 633 } 634  635 #define tmalloc( type, count ) ( (type*)smalloc( ( count ) * sizeof( type ), __FILE__ ) ) 636 #define tcalloc( type, count ) ( (type*)scalloc( ( count ), sizeof( type ), __FILE__ ) ) 637 #define trealloc( type, ptr, count ) ( (type*)srealloc( ( ptr ), ( count ) * sizeof( type ), __FILE__ ) ) 638 /* 639 typedef struct { size_t size; void *ptr; } buffer; 640  641 static void buffer_init_(buffer *b, size_t size, const char *file) MAYBE_UNUSED; 642 static void buffer_init_(buffer *b, size_t size, const char *file) 643 { 644  b->size=size, b->ptr=smalloc(size,file); 645 } 646 static void buffer_reserve_(buffer *b, size_t min, const char *file) 647  MAYBE_UNUSED; 648 static void buffer_reserve_(buffer *b, size_t min, const char *file) 649 { 650  size_t size = b->size; 651  if(size<min) { 652  size+=size/2+1; 653  if(size<min) size=min; 654  b->ptr=srealloc(b->ptr,size,file); 655  } 656 } 657 static void buffer_free(buffer *b) MAYBE_UNUSED; 658 static void buffer_free(buffer *b) { free(b->ptr); } 659  660 #define buffer_init(b,size) buffer_init_(b,size,__FILE__) 661 #define buffer_reserve(b,min) buffer_reserve_(b,min,__FILE__) 662 */ 663  664 /*====================================================== 665 / from minmax.h 666 /====================================================== 667 */ 668  669 /*-------------------------------------------------------------------------- 670  Min, Max, Norm 671  --------------------------------------------------------------------------*/ 672  673 #ifdef __GNUC__ 674 #define MAYBE_UNUSED __attribute__( ( unused ) ) 675 #else 676 #define MAYBE_UNUSED 677 #endif 678  679 #define DECLMINMAX( type, prefix ) \ 680  static type prefix##min_2( type a, type b ) MAYBE_UNUSED; \ 681  static type prefix##min_2( type a, type b ) \ 682  { \ 683  return b < a ? b : a; \ 684  } \ 685  static type prefix##max_2( type a, type b ) MAYBE_UNUSED; \ 686  static type prefix##max_2( type a, type b ) \ 687  { \ 688  return a > b ? a : b; \ 689  } \ 690  static void prefix##minmax_2( type* min, type* max, type a, type b ) MAYBE_UNUSED; \ 691  static void prefix##minmax_2( type* min, type* max, type a, type b ) \ 692  { \ 693  if( b < a ) \ 694  *min = b, *max = a; \ 695  else \ 696  *min = a, *max = b; \ 697  } \ 698  static type prefix##min_3( type a, type b, type c ) MAYBE_UNUSED; \ 699  static type prefix##min_3( type a, type b, type c ) \ 700  { \ 701  return b < a ? ( c < b ? c : b ) : ( c < a ? c : a ); \ 702  } \ 703  static type prefix##max_3( type a, type b, type c ) MAYBE_UNUSED; \ 704  static type prefix##max_3( type a, type b, type c ) \ 705  { \ 706  return a > b ? ( a > c ? a : c ) : ( b > c ? b : c ); \ 707  } \ 708  static void prefix##minmax_3( type* min, type* max, type a, type b, type c ) MAYBE_UNUSED; \ 709  static void prefix##minmax_3( type* min, type* max, type a, type b, type c ) \ 710  { \ 711  if( b < a ) \ 712  *min = prefix##min_2( b, c ), *max = prefix##max_2( a, c ); \ 713  else \ 714  *min = prefix##min_2( a, c ), *max = prefix##max_2( b, c ); \ 715  } 716  717 DECLMINMAX( int, i ) 718 DECLMINMAX( unsigned, u ) 719 DECLMINMAX( realType, r ) 720 #undef DECLMINMAX 721  722 static realType r1norm_1( realType a ) MAYBE_UNUSED; 723 static realType r1norm_1( realType a ) 724 { 725  return mbabs( a ); 726 } 727 static realType r1norm_2( realType a, realType b ) MAYBE_UNUSED; 728 static realType r1norm_2( realType a, realType b ) 729 { 730  return mbabs( a ) + mbabs( b ); 731 } 732 static realType r1norm_3( realType a, realType b, realType c ) MAYBE_UNUSED; 733 static realType r1norm_3( realType a, realType b, realType c ) 734 { 735  return mbabs( a ) + mbabs( b ) + mbabs( c ); 736 } 737 static realType r2norm_1( realType a ) MAYBE_UNUSED; 738 static realType r2norm_1( realType a ) 739 { 740  return mbsqrt( a * a ); 741 } 742 static realType r2norm_2( realType a, realType b ) MAYBE_UNUSED; 743 static realType r2norm_2( realType a, realType b ) 744 { 745  return mbsqrt( a * a + b * b ); 746 } 747 static realType r2norm_3( realType a, realType b, realType c ) MAYBE_UNUSED; 748 static realType r2norm_3( realType a, realType b, realType c ) 749 { 750  return mbsqrt( a * a + b * b + c * c ); 751 } 752  753 #endif