Logo  0.95.0-final
Finite Element Embedded Library and Language in C++
Feel++ Feel++ on Github Feel++ community
 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>
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 */

Generated on Fri Oct 25 2013 14:24:24 for Feel++ by doxygen 1.8.4