0.95.0-final
Finite Element Embedded Library and Language in C++
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
stdmathfunctors.hpp
1
/* -*- mode: c++; coding: utf-8; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; show-trailing-whitespace: t -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4
2
3
This file is part of the Feel library
4
5
Author(s): Christophe Prud'homme <christophe.prudhomme@feelpp.org>
6
Date: 2005-06-07
7
8
Copyright (C) 2005,2006 EPFL
9
Copyright (C) 2006-2012 Universite Joseph Fourier (Grenoble I)
10
11
This library is free software; you can redistribute it and/or
12
modify it under the terms of the GNU Lesser General Public
13
License as published by the Free Software Foundation; either
14
version 3.0 of the License, or (at your option) any later version.
15
16
This library is distributed in the hope that it will be useful,
17
but WITHOUT ANY WARRANTY; without even the implied warranty of
18
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
Lesser General Public License for more details.
20
21
You should have received a copy of the GNU Lesser General Public
22
License along with this library; if not, write to the Free Software
23
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
*/
30
#if !defined( STD_MATH_UNARY_FUNCTORS_HPP )
31
#define STD_MATH_UNARY_FUNCTORS_HPP 1
32
33
# include <boost/preprocessor/comparison/less.hpp>
34
# include <boost/preprocessor/logical/and.hpp>
35
# include <boost/preprocessor/control/if.hpp>
36
# include <boost/preprocessor/list/at.hpp>
37
# include <boost/preprocessor/list/cat.hpp>
38
# include <boost/preprocessor/list/for_each_product.hpp>
39
# include <boost/preprocessor/logical/or.hpp>
40
# include <boost/preprocessor/tuple/to_list.hpp>
41
# include <boost/preprocessor/tuple/eat.hpp>
42
# include <boost/preprocessor/facilities/empty.hpp>
43
# include <boost/preprocessor/punctuation/comma.hpp>
44
# include <boost/preprocessor/facilities/identity.hpp>
45
46
#include <boost/utility/enable_if.hpp>
47
49
#include <feel/feelcore/traits.hpp>
50
#include <
feel/feelvf/unaryfunctor.hpp
>
51
52
namespace
Feel
53
{
54
namespace
vf
55
{
56
namespace
details
57
{
61
template
<
typename
T>
62
T
63
sign( T
const
& x )
64
{
65
return
( x > T( 0.0 ) )?T( 1.0 ):( ( x < T( 0.0 ) )?T( -1.0 ):0.0 );
66
}
67
68
}
// details
69
70
}
71
}
72
73
#
/* Information about functions */
74
#
75
#
/* Accessors for the operator datatype. */
76
# define VF_FUNC_SYMBOL(O) BOOST_PP_TUPLE_ELEM(8, 0, O)
77
# define VF_FUNC_NAME(O) BOOST_PP_TUPLE_ELEM(8, 1, O)
78
# define VF_FUNC_IMPL(O) BOOST_PP_TUPLE_ELEM(8, 2, O)
79
# define VF_FUNC_NAME_STRING(O) BOOST_PP_TUPLE_ELEM(8, 3, O)
80
# define VF_FUNC_DOMAIN(O) BOOST_PP_TUPLE_ELEM(8, 4, O)
81
# define VF_FUNC_IS_FLOATING(O ) BOOST_PP_TUPLE_ELEM(8, 5, O)
82
# define VF_FUNC_IS_LOGICAL(O) BOOST_PP_TUPLE_ELEM(8, 6, O)
83
# define VF_FUNC_IS_POLYNOMIAL(O) BOOST_PP_TUPLE_ELEM(8, 7, O)
84
#
85
#
/* List of applicative unary functions. */
86
# define VF_APPLICATIVE_UNARY_FUNCS \
87
BOOST_PP_TUPLE_TO_LIST( \
88
15, \
89
( \
90
( abs , __Abs__ , Feel::math::abs ,"absolute value" , UnboundedDomain<value_type>() , 1, 0, 2), \
91
( cos , __Cos__ , Feel::math::cos ,"cosine" , UnboundedDomain<value_type>() , 1, 0, 2), \
92
( sin , __Sin__ , Feel::math::sin ,"sine" , UnboundedDomain<value_type>() , 1, 0, 2), \
93
( tan , __Tan__ , Feel::math::tan ,"tangent" , UnboundedDomain<value_type>() , 1, 0, 2), \
94
( acos , __ACos__, Feel::math::acos ,"inverse cosine" , BoundedDomain<value_type>(-1.0,1.0), 1, 0, 2), \
95
( asin , __ASin__, Feel::math::asin ,"inverse sine" , BoundedDomain<value_type>(-1.0,1.0), 1, 0, 2), \
96
( atan , __ATan__, Feel::math::atan ,"inverse tangent" , UnboundedDomain<value_type>() , 1, 0, 2), \
97
( cosh , __Cosh__, Feel::math::cosh ,"hyperbolic cosine" , UnboundedDomain<value_type>() , 1, 0, 2), \
98
( sinh , __Sinh__, Feel::math::sinh ,"hyperbolic sine" , UnboundedDomain<value_type>() , 1, 0, 2), \
99
( tanh , __Tanh__, Feel::math::tanh ,"hyperbolic tangent" , UnboundedDomain<value_type>() , 1, 0, 2), \
100
( exp , __Exp__ , Feel::math::exp ,"exponential" , UnboundedDomain<value_type>() , 1, 0, 2), \
101
( log , __Log__ , Feel::math::log ,"logarithm" , PositiveDomain<value_type>() , 1, 0, 2), \
102
( sqrt , __Sqrt__, Feel::math::sqrt ,"square root" , PositiveDomain<value_type>() , 1, 0, 2), \
103
( sign , __Sign__, details::sign ,"sign" , UnboundedDomain<value_type>() , 1, 0, 0), \
104
( chi , __Chi__ , ,"chi" , UnboundedDomain<value_type>() , 0, 1, 0) \
105
) \
106
) \
107
108
#
109
#
110
#
/* Generates code for all binary operators and integral type pairs. */
111
# define VF_UNARY_FUNCTIONS(_, O) \
112
VF_UNARY_FUNCTIONS_CODE O \
113
114
115
#if defined( FEELPP_HAS_QD_H ) && defined(FEELPP_HAS_MPFR)
116
# define VF_CHECK_ARITHMETIC_TYPE() \
117
BOOST_STATIC_ASSERT( (::boost::is_arithmetic<value_1_type>::value || \
118
::boost::is_same<value_1_type, std::complex<float> >::value || \
119
::boost::is_same<value_1_type, std::complex<double> >::value || \
120
::boost::is_same<value_1_type,mp_type>::value || \
121
::boost::is_same<value_1_type,dd_real>::value || \
122
::boost::is_same<value_1_type,qd_real>::value) ); \
123
124
#elif defined( FEELPP_HAS_QD_H )
125
# define VF_CHECK_ARITHMETIC_TYPE() \
126
BOOST_STATIC_ASSERT( (::boost::is_arithmetic<value_1_type>::value || \
127
::boost::is_same<value_1_type, std::complex<float> >::value || \
128
::boost::is_same<value_1_type, std::complex<double> >::value || \
129
::boost::is_same<value_1_type,dd_real>::value || \
130
::boost::is_same<value_1_type,qd_real>::value) ); \
131
132
#elif defined( FEELPP_HAS_MPFR )
133
# define VF_CHECK_ARITHMETIC_TYPE() \
134
BOOST_STATIC_ASSERT( (::boost::is_arithmetic<value_1_type>::value || \
135
::boost::is_same<value_1_type, std::complex<float> >::value || \
136
::boost::is_same<value_1_type, std::complex<double> >::value || \
137
::boost::is_same<value_1_type,mp_type>::value) ); \
138
139
#else
140
# define VF_CHECK_ARITHMETIC_TYPE() \
141
BOOST_STATIC_ASSERT( ( ::boost::is_arithmetic<value_1_type>::value || \
142
::boost::is_same<value_1_type, std::complex<float> >::value || \
143
::boost::is_same<value_1_type, std::complex<double> >::value ) \
144
); \
145
146
#endif
147
148
# define VF_IM_IS_POLY(O) \
149
BOOST_PP_IF( BOOST_PP_EQUAL( VF_FUNC_IS_POLYNOMIAL(O) , 0) , \
150
0 , \
151
1 ) \
152
153
154
155
156
157
#define VF_UNARY_FUNCTIONS_CODE(O) \
158
template < typename ExprT1 > \
159
class VF_FUNC_NAME( O ) : public UnaryFunctor<typename ExprT1::value_type> \
160
{ \
161
public: \
162
\
163
static const size_type context = ExprT1::context; \
164
static const bool is_terminal = false; \
165
\
166
static const uint16_type imorder = VF_FUNC_IS_POLYNOMIAL(O)*ExprT1::imorder; \
167
static const bool imIsPoly = (VF_IM_IS_POLY(O) || (ExprT1::imorder==0)); \
168
\
169
template<typename Func> \
170
struct HasTestFunction \
171
{ \
172
static const bool result = false; \
173
}; \
174
\
175
template<typename Func> \
176
struct HasTrialFunction \
177
{ \
178
static const bool result = false; \
179
}; \
180
\
181
typedef UnaryFunctor<typename ExprT1::value_type> super; \
182
typedef typename super::functordomain_type functordomain_type; \
183
typedef typename super::functordomain_ptrtype functordomain_ptrtype; \
184
typedef ExprT1 expression_1_type; \
185
typedef VF_FUNC_NAME(O)<ExprT1> this_type; \
186
typedef typename expression_1_type::value_type value_1_type; \
187
typedef value_1_type value_type; \
188
\
189
VF_CHECK_ARITHMETIC_TYPE() \
190
\
191
explicit VF_FUNC_NAME(O)( expression_1_type const& __expr1 ) \
192
: \
193
super( VF_FUNC_NAME_STRING(O), functordomain_ptrtype(new VF_FUNC_DOMAIN(O) )), \
194
M_expr_1( __expr1 ) \
195
{ \
196
DVLOG(2) << "VF_FUNC_NAME(O)::VF_FUNC_NAME(O) default constructor\n"; \
197
} \
198
\
199
VF_FUNC_NAME(O)( VF_FUNC_NAME(O) const& __vfp ) \
200
: \
201
super( VF_FUNC_NAME_STRING(O), functordomain_ptrtype(new VF_FUNC_DOMAIN(O) )), \
202
M_expr_1( __vfp.M_expr_1 ) \
203
{ \
204
DVLOG(2) << "VF_FUNC_NAME(O)::VF_FUNC_NAME(O) copy constructor\n"; \
205
} \
206
\
207
bool isSymetric() const { return false; } \
208
\
209
void eval( int nx, value_type const* x, value_type* f ) const \
210
{ \
211
for( int i = 0; i < nx; ++i ) \
212
f[i] = VF_FUNC_IMPL(O)( x[i] ); \
213
} \
214
template<typename TheExpr> \
215
struct Lambda \
216
{ \
217
typedef VF_FUNC_NAME( O )<TheExpr> type; \
218
}; \
219
\
220
template<typename TheExpr> \
221
typename Lambda<TheExpr>::type \
222
operator()( TheExpr const& e ) { return VF_FUNC_NAME(O)<TheExpr>( e ); } \
223
\
224
\
225
expression_1_type const& expression() const { return M_expr_1; } \
226
\
227
template<typename Geo_t, typename Basis_i_t, typename Basis_j_t = Basis_i_t> \
228
struct tensor \
229
{ \
230
typedef this_type expression_type; \
231
typedef typename expression_1_type::template tensor<Geo_t, Basis_i_t,Basis_j_t> tensor2_expr_type; \
232
typedef typename tensor2_expr_type::value_type value_type; \
233
typedef typename vf::detail::ExtractGm<Geo_t>::gmc_ptrtype gmc_ptrtype; \
234
typedef typename vf::detail::ExtractGm<Geo_t>::gmc_type gmc_type; \
235
typedef typename tensor2_expr_type::shape shape; \
236
\
237
struct is_zero { static const bool value = tensor2_expr_type::is_zero::value; }; \
238
\
239
tensor( this_type const& expr, Geo_t const& geom, Basis_i_t const&
/*fev*/
, Basis_j_t const&
/*feu*/
) \
240
: \
241
M_expr( expr.expression(), geom ), \
242
M_gmc(vf::detail::ExtractGm<Geo_t>::get( geom ) ) \
243
{ \
244
update( geom ); \
245
} \
246
tensor( this_type const& expr,Geo_t const& geom, Basis_i_t const&
/*fev*/
) \
247
: \
248
M_expr( expr.expression(), geom ), \
249
M_gmc(vf::detail::ExtractGm<Geo_t>::get( geom ) ) \
250
{ \
251
update( geom ); \
252
} \
253
tensor( this_type const& expr, Geo_t const& geom ) \
254
: \
255
M_expr( expr.expression(), geom ), \
256
M_gmc(vf::detail::ExtractGm<Geo_t>::get( geom ) ) \
257
{ \
258
update( geom ); \
259
} \
260
template<typename IM> \
261
void init( IM const& im ) \
262
{ \
263
M_expr.init( im ); \
264
} \
265
void update( Geo_t const& geom, Basis_i_t const&
/*fev*/
, Basis_j_t const&
/*feu*/
) \
266
{ \
267
update( geom ); \
268
} \
269
void update( Geo_t const& geom, Basis_i_t const&
/*fev*/
) \
270
{ \
271
update( geom ); \
272
} \
273
void update( Geo_t const& geom ) \
274
{ \
275
M_expr.update( geom ); \
276
} \
277
void update( Geo_t const& geom, uint16_type face ) \
278
{ \
279
M_expr.update( geom, face ); \
280
} \
281
\
282
value_type \
283
evalijq( uint16_type
/*i*/
, uint16_type
/*j*/
, uint16_type c1, uint16_type c2, uint16_type q ) const \
284
{ \
285
return evalq( c1, c2, q ); \
286
} \
287
template<int PatternContext> \
288
value_type \
289
evalijq( uint16_type
/*i*/
, uint16_type
/*j*/
, uint16_type c1, uint16_type c2, uint16_type q, \
290
mpl::int_<PatternContext> ) const \
291
{ \
292
return evalq( c1, c2, q ); \
293
} \
294
\
295
value_type \
296
evaliq( uint16_type
/*i*/
, uint16_type c1, uint16_type c2, uint16_type q ) const \
297
{ \
298
return evalq( c1, c2, q ); \
299
} \
300
value_type \
301
evalq( uint16_type c1, uint16_type c2, uint16_type q ) const \
302
{ \
303
return VF_FUNC_IMPL(O)( M_expr.evalq( c1, c2, q ) ); \
304
} \
305
private: \
306
tensor2_expr_type M_expr; \
307
gmc_ptrtype M_gmc; \
308
}; \
309
\
310
protected: \
311
VF_FUNC_NAME(O)() {} \
312
\
313
expression_1_type M_expr_1; \
314
}; \
315
\
316
template<typename ExprT1> \
317
inline \
318
Expr< VF_FUNC_NAME( O )<typename mpl::if_<boost::is_arithmetic<ExprT1>, \
319
mpl::identity<Cst<ExprT1> >, \
320
mpl::identity<Expr<ExprT1> > >::type::type > > \
321
VF_FUNC_SYMBOL( O )( Expr<ExprT1> const& __e1 ) \
322
{ \
323
typedef typename mpl::if_<boost::is_arithmetic<ExprT1>, \
324
mpl::identity<Cst<ExprT1> >, \
325
mpl::identity<Expr<ExprT1> > >::type::type t1; \
326
typedef VF_FUNC_NAME(O)<t1> expr_t; \
327
return Expr< expr_t >( expr_t( t1( __e1 ) ) ); \
328
} \
329
template<typename ExprT1> \
330
inline \
331
Expr< VF_FUNC_NAME( O )<Cst<ExprT1> > > \
332
VF_FUNC_SYMBOL( O )( ExprT1 const& __e1, typename boost::enable_if<boost::is_arithmetic<ExprT1> >::type* dummy = 0 ) \
333
{ \
334
typedef Cst<ExprT1> t1; \
335
typedef VF_FUNC_NAME(O)<t1> expr_t; \
336
return Expr< expr_t >( expr_t( t1( __e1 ) ) ); \
337
} \
338
339
#
340
341
namespace
Feel
342
{
343
namespace
vf
344
{
345
346
BOOST_PP_LIST_FOR_EACH_PRODUCT( VF_UNARY_FUNCTIONS, 1, ( VF_APPLICATIVE_UNARY_FUNCS ) )
347
}
348
}
350
#endif
/* STD_MATH_UNARY_FUNCTORS_HPP */
unaryfunctor.hpp
Generated on Sun Dec 22 2013 13:11:13 for Feel++ by
1.8.5