libpnicore
inplace_arithmetics.hpp
1 //
2 // (c) Copyright 2012 DESY, Eugen Wintersberger <eugen.wintersberger@desy.de>
3 //
4 // This file is part of libpnicore.
5 //
6 // libpnicore is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // libpnicore is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libpnicore. If not, see <http://www.gnu.org/licenses/>.
18 //
19 // ============================================================================
20 //
21 // Created on: Jul 24, 2012
22 // Author: Eugen Wintersberger <eugen.wintersberger@desy.de>
23 //
24 
25 #pragma once
26 
27 #include <limits>
28 #include <functional>
29 
30 #include "../../error/exception_utils.hpp"
31 #include "../../types.hpp"
32 #include "../../utilities/sfinae_macros.hpp"
33 
34 namespace pni{
35 namespace core{
36 
37 #define CHECK_ARITHMETIC_SINGLE(type)\
38  static_assert(std::is_arithmetic<typename type::value_type>::value || \
39  is_complex_type<typename type::value_type>::value,\
40  "Arithemtic operations can only be used with arithmetic types!")
41 
42 #define CHECK_ARITHMETIC_DOUBLE(type1,type2)\
43  static_assert(\
44  (std::is_arithmetic<typename type1::value_type>::value || \
45  is_complex_type<typename type1::value_type>::value) && \
46  (std::is_arithmetic<typename type2::value_type>::value || \
47  is_complex_type<typename type2::value_type>::value), \
48  "Arithemtic operations can only be used with arithmetic types!")
49 
59  {
60 
61  //==================inplace addition===================================
66 
75  template<
81  typename LTYPE,
82  typename T,
83  typename = enable_if<or_t<
85  >>
86  >
87  static void add(LTYPE &a,T b)
88  {
89  CHECK_ARITHMETIC_SINGLE(LTYPE);
90 
91  size_t n = a.size();
92  for(size_t i = 0;i<n;++i) a[i] += b;
93  }
94 
95  //-----------------------------------------------------------------
100 
109  template<
116  typename LTYPE,
117  typename RTYPE,
118  typename = enable_if<not_t<
120  >>
121  >
122  static void add(LTYPE &a,const RTYPE &b)
123  {
124  CHECK_ARITHMETIC_DOUBLE(LTYPE,RTYPE);
125  size_t n = a.size();
126  for(size_t i=0;i<n;++i) a[i] += b[i];
127  }
128 
129  //==================inplace subtraction===============================
134 
143  template<
148  typename LTYPE,
149  typename T,
150  typename = enable_if<or_t<
151  is_pod<T>,is_cmplx<T>
152  >>
153  >
154  static void sub(LTYPE &a,T b)
155  {
156  CHECK_ARITHMETIC_SINGLE(LTYPE);
157  size_t n = a.size();
158  for(size_t i=0;i<n;++i) a[i] -= b;
159  }
160 
161  //-----------------------------------------------------------------
166 
175  template<
181  typename LTYPE,
182  typename RTYPE,
183  typename = enable_if<not_t<
184  or_t<is_pod<RTYPE>,is_cmplx<RTYPE>>
185  >>
186  >
187  static void sub(LTYPE &a,const RTYPE &b)
188  {
189  CHECK_ARITHMETIC_DOUBLE(LTYPE,RTYPE);
190  size_t n = a.size();
191  for(size_t i=0;i<n;++i) a[i] -= b[i];
192  }
193 
194 
195  //=====================inplace multiplication======================
200 
209  template<
214  typename LTYPE,
215  typename T,
216  typename = enable_if<or_t<
217  is_pod<T>,is_cmplx<T>
218  >>
219  >
220  static void mult(LTYPE &a,T b)
221  {
222  CHECK_ARITHMETIC_SINGLE(LTYPE);
223  size_t n=a.size();
224  for(size_t i=0;i<n;++i) a[i] *= b;
225  }
226 
227  //-----------------------------------------------------------------
232 
241  template<
247  typename LTYPE,
248  typename RTYPE,
249  typename = enable_if<not_t<
250  or_t<is_pod<RTYPE>,is_cmplx<RTYPE>>
251  >>
252  >
253  static void mult(LTYPE &a,const RTYPE &b)
254  {
255  CHECK_ARITHMETIC_DOUBLE(LTYPE,RTYPE);
256  size_t n=a.size();
257  for(size_t i=0;i<n;++i) a[i] *= b[i];
258  }
259 
260  //=====================inplace division============================
265 
274  template<
279  typename LTYPE,
280  typename T,
281  typename = enable_if<or_t<
282  is_pod<T>,is_cmplx<T>
283  >>
284  >
285  static void div(LTYPE &a,T b)
286  {
287  CHECK_ARITHMETIC_SINGLE(LTYPE);
288  size_t n = a.size();
289  for(size_t i=0;i<n;++i) a[i] /= b;
290  }
291 
292  //-----------------------------------------------------------------
297 
306  template<
312  typename LTYPE,
313  typename RTYPE,
314  typename = enable_if<not_t<
315  or_t<is_pod<RTYPE>,is_cmplx<RTYPE>>
316  >>
317  >
318  static void div(LTYPE &a,const RTYPE &b)
319  {
320  CHECK_ARITHMETIC_DOUBLE(LTYPE,RTYPE);
321  size_t n = a.size();
322  for(size_t i=0;i<n;++i) a[i] /= b[i];
323  }
324  };
325 
326 //end namespace
327 }
328 }
static void add(LTYPE &a, const RTYPE &b)
add array to array
Definition: inplace_arithmetics.hpp:122
static void sub(LTYPE &a, const RTYPE &b)
subtract array from array
Definition: inplace_arithmetics.hpp:187
check complex type
Definition: traits.hpp:74
logical not
Definition: sfinae_macros.hpp:97
static void div(LTYPE &a, T b)
divide array with scalar
Definition: inplace_arithmetics.hpp:285
static void mult(LTYPE &a, T b)
multiply array with scalar
Definition: inplace_arithmetics.hpp:220
static void add(LTYPE &a, T b)
add scalar to array
Definition: inplace_arithmetics.hpp:87
Definition: add_op.hpp:29
static void div(LTYPE &a, const RTYPE &b)
divide array by array
Definition: inplace_arithmetics.hpp:318
invoke< std::enable_if< C::value >> enable_if
shortcut for std::enable_if
Definition: sfinae_macros.hpp:108
static void mult(LTYPE &a, const RTYPE &b)
multiply array by array
Definition: inplace_arithmetics.hpp:253
std::is_pod< T > is_pod
shortcut for std::is_pod
Definition: sfinae_macros.hpp:115
static void sub(LTYPE &a, T b)
subtract scalar from array
Definition: inplace_arithmetics.hpp:154
or type
Definition: sfinae_macros.hpp:60
single threaded inplace arithmetics
Definition: inplace_arithmetics.hpp:58