Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
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 {
429  realType r[3];
431 } findpt_listel;
432 
433 typedef struct
434 {
435  unsigned constraints;
436  unsigned de, d1;
437  realType *x[2], *fd1[2];
439 
440 typedef struct
441 {
442  unsigned constraints;
443  realType x[2], jac[4];
445 
446 typedef struct
447 {
449  unsigned size[3];
450  const realType* elx[2];
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 */
471 } findpt_data_2;
472 
473 typedef struct
474 {
475  unsigned constraints;
476  unsigned dn, d1, d2;
477  realType *x[3], *fdn[3];
479 
480 typedef struct
481 {
482  unsigned constraints;
483  unsigned de, d1, d2;
484  realType *x[3], *fd1[3], *fd2[3];
486 
487 typedef struct
488 {
489  unsigned constraints;
490  realType x[3], jac[9];
492 
493 typedef struct
494 {
496  unsigned size[4];
497  const realType* elx[3];
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 */
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 
724 {
725  return mbabs( a );
726 }
729 {
730  return mbabs( a ) + mbabs( b );
731 }
734 {
735  return mbabs( a ) + mbabs( b ) + mbabs( c );
736 }
739 {
740  return mbsqrt( a * a );
741 }
744 {
745  return mbsqrt( a * a + b * b );
746 }
749 {
750  return mbsqrt( a * a + b * b + c * c );
751 }
752 
753 #endif