2
/***************************************************************************
3
* blitz/funcs.h Function objects for math functions
5
* $Id: funcs.h,v 1.5 2004/10/06 23:36:43 julianc Exp $
7
* Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org>
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License
11
* as published by the Free Software Foundation; either version 2
12
* of the License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* Suggestions: blitz-dev@oonumerics.org
20
* Bugs: blitz-bugs@oonumerics.org
22
* For more information, please see the Blitz++ Home Page:
23
* http://oonumerics.org/blitz/
25
*************************************************************************/
30
#include <blitz/blitz.h>
31
#include <blitz/promote.h>
32
#include <blitz/prettyprint.h>
36
/* Helper functions */
39
inline T blitz_sqr(T x)
43
inline T blitz_cube(T x)
47
inline T blitz_pow4(T x)
51
inline T blitz_pow5(T x)
55
inline T blitz_pow6(T x)
56
{ return x*x*x*x*x*x; }
59
inline T blitz_pow7(T x)
60
{ return x*x*x*x*x*x*x; }
63
inline T blitz_pow8(T x)
64
{ return x*x*x*x*x*x*x*x; }
67
/* Unary functions that return same type as argument */
69
#define BZ_DEFINE_UNARY_FUNC(name,fun) \
70
template<typename T_numtype1> \
72
typedef T_numtype1 T_numtype; \
74
static inline T_numtype \
78
template<typename T1> \
79
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
80
prettyPrintFormat& format, const T1& t1) \
84
t1.prettyPrint(str, format); \
89
BZ_DEFINE_UNARY_FUNC(Fn_acos,BZ_MATHFN_SCOPE(acos))
90
BZ_DEFINE_UNARY_FUNC(Fn_asin,BZ_MATHFN_SCOPE(asin))
91
BZ_DEFINE_UNARY_FUNC(Fn_atan,BZ_MATHFN_SCOPE(atan))
92
BZ_DEFINE_UNARY_FUNC(Fn_ceil,BZ_MATHFN_SCOPE(ceil))
93
BZ_DEFINE_UNARY_FUNC(Fn_cos,BZ_MATHFN_SCOPE(cos))
94
BZ_DEFINE_UNARY_FUNC(Fn_cosh,BZ_MATHFN_SCOPE(cosh))
95
BZ_DEFINE_UNARY_FUNC(Fn_exp,BZ_MATHFN_SCOPE(exp))
96
BZ_DEFINE_UNARY_FUNC(Fn_fabs,BZ_MATHFN_SCOPE(fabs))
97
BZ_DEFINE_UNARY_FUNC(Fn_floor,BZ_MATHFN_SCOPE(floor))
98
BZ_DEFINE_UNARY_FUNC(Fn_log,BZ_MATHFN_SCOPE(log))
99
BZ_DEFINE_UNARY_FUNC(Fn_log10,BZ_MATHFN_SCOPE(log10))
100
BZ_DEFINE_UNARY_FUNC(Fn_sin,BZ_MATHFN_SCOPE(sin))
101
BZ_DEFINE_UNARY_FUNC(Fn_sinh,BZ_MATHFN_SCOPE(sinh))
102
BZ_DEFINE_UNARY_FUNC(Fn_sqrt,BZ_MATHFN_SCOPE(sqrt))
103
BZ_DEFINE_UNARY_FUNC(Fn_tan,BZ_MATHFN_SCOPE(tan))
104
BZ_DEFINE_UNARY_FUNC(Fn_tanh,BZ_MATHFN_SCOPE(tanh))
106
#ifdef BZ_HAVE_IEEE_MATH
107
BZ_DEFINE_UNARY_FUNC(Fn_acosh,BZ_IEEEMATHFN_SCOPE(acosh))
108
BZ_DEFINE_UNARY_FUNC(Fn_asinh,BZ_IEEEMATHFN_SCOPE(asinh))
109
BZ_DEFINE_UNARY_FUNC(Fn_atanh,BZ_IEEEMATHFN_SCOPE(atanh))
110
BZ_DEFINE_UNARY_FUNC(Fn_cbrt,BZ_IEEEMATHFN_SCOPE(cbrt))
111
BZ_DEFINE_UNARY_FUNC(Fn_erf,BZ_IEEEMATHFN_SCOPE(erf))
112
BZ_DEFINE_UNARY_FUNC(Fn_erfc,BZ_IEEEMATHFN_SCOPE(erfc))
113
BZ_DEFINE_UNARY_FUNC(Fn_expm1,BZ_IEEEMATHFN_SCOPE(expm1))
114
BZ_DEFINE_UNARY_FUNC(Fn_j0,BZ_IEEEMATHFN_SCOPE(j0))
115
BZ_DEFINE_UNARY_FUNC(Fn_j1,BZ_IEEEMATHFN_SCOPE(j1))
116
BZ_DEFINE_UNARY_FUNC(Fn_lgamma,BZ_IEEEMATHFN_SCOPE(lgamma))
117
BZ_DEFINE_UNARY_FUNC(Fn_logb,BZ_IEEEMATHFN_SCOPE(logb))
118
BZ_DEFINE_UNARY_FUNC(Fn_log1p,BZ_IEEEMATHFN_SCOPE(log1p))
119
BZ_DEFINE_UNARY_FUNC(Fn_rint,BZ_IEEEMATHFN_SCOPE(rint))
120
BZ_DEFINE_UNARY_FUNC(Fn_y0,BZ_IEEEMATHFN_SCOPE(y0))
121
BZ_DEFINE_UNARY_FUNC(Fn_y1,BZ_IEEEMATHFN_SCOPE(y1))
124
#ifdef BZ_HAVE_SYSTEM_V_MATH
125
BZ_DEFINE_UNARY_FUNC(Fn__class,BZ_IEEEMATHFN_SCOPE(_class))
126
BZ_DEFINE_UNARY_FUNC(Fn_nearest,BZ_IEEEMATHFN_SCOPE(nearest))
127
BZ_DEFINE_UNARY_FUNC(Fn_rsqrt,BZ_IEEEMATHFN_SCOPE(rsqrt))
130
BZ_DEFINE_UNARY_FUNC(Fn_sqr,BZ_BLITZ_SCOPE(blitz_sqr))
131
BZ_DEFINE_UNARY_FUNC(Fn_cube,BZ_BLITZ_SCOPE(blitz_cube))
132
BZ_DEFINE_UNARY_FUNC(Fn_pow4,BZ_BLITZ_SCOPE(blitz_pow4))
133
BZ_DEFINE_UNARY_FUNC(Fn_pow5,BZ_BLITZ_SCOPE(blitz_pow5))
134
BZ_DEFINE_UNARY_FUNC(Fn_pow6,BZ_BLITZ_SCOPE(blitz_pow6))
135
BZ_DEFINE_UNARY_FUNC(Fn_pow7,BZ_BLITZ_SCOPE(blitz_pow7))
136
BZ_DEFINE_UNARY_FUNC(Fn_pow8,BZ_BLITZ_SCOPE(blitz_pow8))
138
#ifdef BZ_HAVE_COMPLEX_FCNS
139
BZ_DEFINE_UNARY_FUNC(Fn_conj,BZ_CMATHFN_SCOPE(conj))
142
#ifdef BZ_HAVE_COMPLEX
143
/* Specialization of unary functor for complex type */
145
#define BZ_DEFINE_UNARY_CFUNC(name,fun) \
146
template<typename T> \
147
struct name< complex<T> > { \
148
typedef complex<T> T_numtype1; \
149
typedef complex<T> T_numtype; \
151
static inline T_numtype \
152
apply(T_numtype1 a) \
155
template<typename T1> \
156
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
157
prettyPrintFormat& format, const T1& t1) \
161
t1.prettyPrint(str, format); \
166
#ifdef BZ_HAVE_COMPLEX_MATH1
167
BZ_DEFINE_UNARY_CFUNC(Fn_cos,BZ_CMATHFN_SCOPE(cos))
168
BZ_DEFINE_UNARY_CFUNC(Fn_cosh,BZ_CMATHFN_SCOPE(cosh))
169
BZ_DEFINE_UNARY_CFUNC(Fn_exp,BZ_CMATHFN_SCOPE(exp))
170
BZ_DEFINE_UNARY_CFUNC(Fn_log,BZ_CMATHFN_SCOPE(log))
171
BZ_DEFINE_UNARY_CFUNC(Fn_log10,BZ_CMATHFN_SCOPE(log10))
172
BZ_DEFINE_UNARY_CFUNC(Fn_sin,BZ_CMATHFN_SCOPE(sin))
173
BZ_DEFINE_UNARY_CFUNC(Fn_sinh,BZ_CMATHFN_SCOPE(sinh))
174
BZ_DEFINE_UNARY_CFUNC(Fn_sqrt,BZ_CMATHFN_SCOPE(sqrt))
175
BZ_DEFINE_UNARY_CFUNC(Fn_tan,BZ_CMATHFN_SCOPE(tan))
176
BZ_DEFINE_UNARY_CFUNC(Fn_tanh,BZ_CMATHFN_SCOPE(tanh))
177
#endif // BZ_HAVE_COMPLEX_MATH1
179
BZ_DEFINE_UNARY_CFUNC(Fn_sqr,BZ_BLITZ_SCOPE(blitz_sqr))
180
BZ_DEFINE_UNARY_CFUNC(Fn_cube,BZ_BLITZ_SCOPE(blitz_cube))
181
BZ_DEFINE_UNARY_CFUNC(Fn_pow4,BZ_BLITZ_SCOPE(blitz_pow4))
182
BZ_DEFINE_UNARY_CFUNC(Fn_pow5,BZ_BLITZ_SCOPE(blitz_pow5))
183
BZ_DEFINE_UNARY_CFUNC(Fn_pow6,BZ_BLITZ_SCOPE(blitz_pow6))
184
BZ_DEFINE_UNARY_CFUNC(Fn_pow7,BZ_BLITZ_SCOPE(blitz_pow7))
185
BZ_DEFINE_UNARY_CFUNC(Fn_pow8,BZ_BLITZ_SCOPE(blitz_pow8))
187
/* Unary functions that apply only to complex<T> and return T */
189
#define BZ_DEFINE_UNARY_CFUNC2(name,fun) \
190
template<typename T_numtype1> \
193
template<typename T> \
194
struct name< complex<T> > { \
195
typedef complex<T> T_numtype1; \
196
typedef T T_numtype; \
198
static inline T_numtype \
199
apply(T_numtype1 a) \
202
template<typename T1> \
203
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
204
prettyPrintFormat& format, const T1& t1) \
208
t1.prettyPrint(str, format); \
213
#ifdef BZ_HAVE_COMPLEX_FCNS
214
BZ_DEFINE_UNARY_CFUNC2(Fn_arg,BZ_CMATHFN_SCOPE(arg))
215
BZ_DEFINE_UNARY_CFUNC2(Fn_imag,BZ_CMATHFN_SCOPE(imag))
216
BZ_DEFINE_UNARY_CFUNC2(Fn_norm,BZ_CMATHFN_SCOPE(norm))
217
BZ_DEFINE_UNARY_CFUNC2(Fn_real,BZ_CMATHFN_SCOPE(real))
218
#endif // BZ_HAVE_COMPLEX_FCNS
220
#endif // BZ_HAVE_COMPLEX
222
/* Unary functions that return a specified type */
224
#define BZ_DEFINE_UNARY_FUNC_RET(name,fun,ret) \
225
template<typename T_numtype1> \
227
typedef ret T_numtype; \
229
static inline T_numtype \
230
apply(T_numtype1 a) \
233
template<typename T1> \
234
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
235
prettyPrintFormat& format, const T1& t1) \
239
t1.prettyPrint(str, format); \
244
#ifdef BZ_HAVE_IEEE_MATH
245
BZ_DEFINE_UNARY_FUNC_RET(Fn_ilogb,BZ_IEEEMATHFN_SCOPE(ilogb),int)
248
#ifdef BZ_HAVE_SYSTEM_V_MATH
249
BZ_DEFINE_UNARY_FUNC_RET(Fn_itrunc,BZ_IEEEMATHFN_SCOPE(itrunc),int)
250
BZ_DEFINE_UNARY_FUNC_RET(Fn_uitrunc,BZ_IEEEMATHFN_SCOPE(uitrunc),unsigned int)
254
/* Binary functions that return type based on type promotion */
256
#define BZ_DEFINE_BINARY_FUNC(name,fun) \
257
template<typename T_numtype1, typename T_numtype2> \
259
typedef BZ_PROMOTE(T_numtype1, T_numtype2) T_numtype; \
261
static inline T_numtype \
262
apply(T_numtype1 a, T_numtype2 b) \
263
{ return fun(a,b); } \
265
template<typename T1, typename T2> \
266
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
267
prettyPrintFormat& format, const T1& t1, \
272
t1.prettyPrint(str, format); \
274
t2.prettyPrint(str, format); \
279
BZ_DEFINE_BINARY_FUNC(Fn_atan2,BZ_MATHFN_SCOPE(atan2))
280
BZ_DEFINE_BINARY_FUNC(Fn_fmod,BZ_MATHFN_SCOPE(fmod))
281
BZ_DEFINE_BINARY_FUNC(Fn_pow,BZ_MATHFN_SCOPE(pow))
283
#ifdef BZ_HAVE_SYSTEM_V_MATH
284
BZ_DEFINE_BINARY_FUNC(Fn_copysign,BZ_IEEEMATHFN_SCOPE(copysign))
285
BZ_DEFINE_BINARY_FUNC(Fn_drem,BZ_IEEEMATHFN_SCOPE(drem))
286
BZ_DEFINE_BINARY_FUNC(Fn_hypot,BZ_IEEEMATHFN_SCOPE(hypot))
287
BZ_DEFINE_BINARY_FUNC(Fn_nextafter,BZ_IEEEMATHFN_SCOPE(nextafter))
288
BZ_DEFINE_BINARY_FUNC(Fn_remainder,BZ_IEEEMATHFN_SCOPE(remainder))
289
BZ_DEFINE_BINARY_FUNC(Fn_scalb,BZ_IEEEMATHFN_SCOPE(scalb))
292
#ifdef BZ_HAVE_COMPLEX
293
/* Specialization of binary functor for complex type */
295
#define BZ_DEFINE_BINARY_CFUNC(name,fun) \
296
template<typename T> \
297
struct name< complex<T>, complex<T> > { \
298
typedef complex<T> T_numtype1; \
299
typedef complex<T> T_numtype2; \
300
typedef complex<T> T_numtype; \
302
static inline T_numtype \
303
apply(T_numtype1 a, T_numtype2 b) \
304
{ return fun(a,b); } \
306
template<typename T1, typename T2> \
307
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
308
prettyPrintFormat& format, const T1& t1, \
313
t1.prettyPrint(str, format); \
315
t2.prettyPrint(str, format); \
320
template<typename T> \
321
struct name< complex<T>, T > { \
322
typedef complex<T> T_numtype1; \
323
typedef T T_numtype2; \
324
typedef complex<T> T_numtype; \
326
static inline T_numtype \
327
apply(T_numtype1 a, T_numtype2 b) \
328
{ return fun(a,b); } \
330
template<typename T1, typename T2> \
331
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
332
prettyPrintFormat& format, const T1& t1, \
337
t1.prettyPrint(str, format); \
339
t2.prettyPrint(str, format); \
344
template<typename T> \
345
struct name< T, complex<T> > { \
346
typedef T T_numtype1; \
347
typedef complex<T> T_numtype2; \
348
typedef complex<T> T_numtype; \
350
static inline T_numtype \
351
apply(T_numtype1 a, T_numtype2 b) \
352
{ return fun(a,b); } \
354
template<typename T1, typename T2> \
355
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
356
prettyPrintFormat& format, const T1& t1, \
361
t1.prettyPrint(str, format); \
363
t2.prettyPrint(str, format); \
368
#ifdef BZ_HAVE_COMPLEX_MATH1
369
BZ_DEFINE_BINARY_CFUNC(Fn_pow,BZ_CMATHFN_SCOPE(pow))
372
/* Binary functions that apply only to T and return complex<T> */
374
#define BZ_DEFINE_BINARY_CFUNC2(name,fun) \
375
template<typename T_numtype1, typename T_numtype2> \
378
template<typename T> \
379
struct name<T, T> { \
380
typedef T T_numtype1; \
381
typedef T T_numtype2; \
382
typedef complex<T> T_numtype; \
384
static inline T_numtype \
385
apply(T_numtype1 a, T_numtype2 b) \
386
{ return fun(a,b); } \
388
template<typename T1, typename T2> \
389
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
390
prettyPrintFormat& format, const T1& t1, \
395
t1.prettyPrint(str, format); \
397
t2.prettyPrint(str, format); \
402
#ifdef BZ_HAVE_COMPLEX_FCNS
403
BZ_DEFINE_BINARY_CFUNC2(Fn_polar,BZ_CMATHFN_SCOPE(polar))
406
#endif // BZ_HAVE_COMPLEX
408
/* Binary functions that return a specified type */
410
#define BZ_DEFINE_BINARY_FUNC_RET(name,fun,ret) \
411
template<typename T_numtype1, typename T_numtype2> \
413
typedef ret T_numtype; \
415
static inline T_numtype \
416
apply(T_numtype1 a, T_numtype2 b) \
417
{ return fun(a,b); } \
419
template<typename T1, typename T2> \
420
static inline void prettyPrint(BZ_STD_SCOPE(string) &str, \
421
prettyPrintFormat& format, const T1& t1, \
426
t1.prettyPrint(str, format); \
428
t2.prettyPrint(str, format); \
433
#ifdef BZ_HAVE_SYSTEM_V_MATH
434
BZ_DEFINE_BINARY_FUNC_RET(Fn_unordered,BZ_IEEEMATHFN_SCOPE(unordered),int)
438
/* These functions don't quite fit the usual patterns */
440
// abs() Absolute value
441
template<typename T_numtype1>
446
struct Fn_abs< int > {
447
typedef int T_numtype1;
448
typedef int T_numtype;
450
static inline T_numtype
452
{ return BZ_MATHFN_SCOPE(abs)(a); }
454
template<typename T1>
455
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
456
prettyPrintFormat& format, const T1& t1)
460
t1.prettyPrint(str, format);
467
struct Fn_abs< long int > {
468
typedef long int T_numtype1;
469
typedef long int T_numtype;
471
static inline T_numtype
473
{ return BZ_MATHFN_SCOPE(labs)(a); }
475
template<typename T1>
476
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
477
prettyPrintFormat& format, const T1& t1)
481
t1.prettyPrint(str, format);
488
struct Fn_abs< float > {
489
typedef float T_numtype1;
490
typedef float T_numtype;
492
static inline T_numtype
494
{ return BZ_MATHFN_SCOPE(fabs)(a); }
496
template<typename T1>
497
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
498
prettyPrintFormat& format, const T1& t1)
502
t1.prettyPrint(str, format);
509
struct Fn_abs< double > {
510
typedef double T_numtype1;
511
typedef double T_numtype;
513
static inline T_numtype
515
{ return BZ_MATHFN_SCOPE(fabs)(a); }
517
template<typename T1>
518
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
519
prettyPrintFormat& format, const T1& t1)
523
t1.prettyPrint(str, format);
530
struct Fn_abs< long double > {
531
typedef long double T_numtype1;
532
typedef long double T_numtype;
534
static inline T_numtype
536
{ return BZ_MATHFN_SCOPE(fabs)(a); }
538
template<typename T1>
539
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
540
prettyPrintFormat& format, const T1& t1)
544
t1.prettyPrint(str, format);
549
#ifdef BZ_HAVE_COMPLEX_FCNS
552
struct Fn_abs< complex<T> > {
553
typedef complex<T> T_numtype1;
556
static inline T_numtype
558
{ return BZ_CMATHFN_SCOPE(abs)(a); }
560
template<typename T1>
561
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
562
prettyPrintFormat& format, const T1& t1)
566
t1.prettyPrint(str, format);
570
#endif // BZ_HAVE_COMPLEX_FCNS
573
#ifdef BZ_HAVE_IEEE_MATH
574
// isnan() Nonzero if NaNS or NaNQ
575
template<typename T_numtype1>
577
typedef int T_numtype;
579
static inline T_numtype
583
// Some platforms define isnan as a macro, which causes the
584
// BZ_IEEEMATHFN_SCOPE macro to break.
587
return BZ_IEEEMATHFN_SCOPE(isnan)(a);
591
template<typename T1>
592
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
593
prettyPrintFormat& format, const T1& t1)
597
t1.prettyPrint(str, format);
601
#endif // BZ_HAVE_IEEE_MATH
604
// Blitz cast() function
605
template<typename T_numtype1, typename T_cast>
607
typedef T_cast T_numtype;
609
static inline T_numtype
611
{ return T_numtype(a); }
613
template<typename T1>
614
static inline void prettyPrint(BZ_STD_SCOPE(string) &str,
615
prettyPrintFormat& format, const T1& t1)
617
str += BZ_DEBUG_TEMPLATE_AS_STRING_LITERAL(T_cast);
619
t1.prettyPrint(str, format);