ALPSCore reference
vector_functions.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 /* $Id: nobinning.h 3520 2009-12-11 16:49:53Z gamperl $ */
8 
9 #ifndef ALPS_NUMERIC_VECTOR_FUNCTIONS_HEADER
10 #define ALPS_NUMERIC_VECTOR_FUNCTIONS_HEADER
11 
12 
14 
15 #include <alps/numeric/inf.hpp>
17 
18 #include <boost/accumulators/numeric/functional/vector.hpp>
19 #include <boost/accumulators/numeric/functional.hpp>
20 
21 #include <boost/bind.hpp>
22 #include <boost/lambda/bind.hpp>
23 #include <boost/lambda/lambda.hpp>
24 #include <boost/throw_exception.hpp>
25 
26 
27 #include <vector>
28 #include <algorithm>
29 #include <cmath>
30 #include <stdexcept>
31 
32 namespace alps {
33  namespace numeric {
34 
35  // fix for old xlc compilers
36  #define IMPLEMENT_ALPS_VECTOR_FUNCTION(LIB_HEADER, FUNCTION_NAME) \
37  namespace detail { \
38  template<typename T> struct FUNCTION_NAME ## _VECTOR_OP_HELPER { \
39  T operator() (T arg) { \
40  using LIB_HEADER :: FUNCTION_NAME; \
41  return FUNCTION_NAME (arg); \
42  } \
43  }; \
44  } \
45  template<typename T> std::vector<T> FUNCTION_NAME(std::vector<T> vec) { \
46  std::transform(vec.begin(), vec.end(), vec.begin(), detail:: FUNCTION_NAME ## _VECTOR_OP_HELPER<T>()); \
47  return vec; \
48  }
49 
50  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,abs)
52  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,sqrt)
55  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,exp)
56  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,log)
57  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,sin)
58  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,cos)
59  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,tan)
60  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,asin)
61  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,acos)
62  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,atan)
63  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,sinh)
64  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,cosh)
65  // IMPLEMENT_ALPS_VECTOR_FUNCTION(std,tanh)
69 
70  #undef IMPLEMENT_ALPS_VECTOR_FUNCTION
71 
72  //------------------- infinity -------------------
74  template<typename T>
75  class inf< std::vector<T> > {
76  typedef std::vector<T> value_type;
77  value_type inf_;
78  public:
80  inf(const value_type& vec) {
81  if (vec.empty()) return;
82  inf_.resize(vec.size(), inf<T>(vec.front()));
83  }
84 
86  operator value_type const() { return inf_; }
87  };
88 
89  //------------------- unary operator - -------------------
91  template<typename T>
92  std::vector<T> operator - (std::vector<T> lhs) {
93  std::transform(lhs.begin(), lhs.end(), lhs.begin(), std::negate<T>());
94  return lhs;
95  }
96 
97  //------------------- operator + -------------------
99  template<typename T, typename U>
100  std::vector<T> operator + (std::vector<T> const & lhs, std::vector<U> const & rhs) {
101  using boost::numeric::operators::operator+;
102  if (lhs.empty()) return rhs;
103  if (rhs.empty()) return lhs;
104  return lhs + rhs;
105  }
106 
107  //------------------- operator - -------------------
109  template<typename T, typename U>
110  std::vector<T> operator - (std::vector<T> const & lhs, std::vector<U> const & rhs) {
111  using boost::numeric::operators::operator-;
112  if (rhs.empty()) return lhs;
113  if (lhs.empty()) return -rhs;
114  return lhs - rhs;
115  }
116 
117  //------------------- operator * vector-vector-------------------
119  template<typename T, typename U>
120  std::vector<T> operator * (std::vector<T> const & lhs, std::vector<U> const & rhs) {
121  using boost::numeric::operators::operator*;
122  if (lhs.empty()) return lhs;
123  if (rhs.empty()) return rhs;
124  return lhs * rhs;
125  }
126  //------------------- operator / vector-vector-------------------
128  template<typename T, typename U>
129  std::vector<T> operator / (std::vector<T> const & lhs, std::vector<U> const & rhs) {
130  using boost::numeric::operators::operator/;
131  if (lhs.empty()) return lhs;
132  if (rhs.empty()) throw std::runtime_error("Division by default-initialized vector");
133  return lhs / rhs;
134  }
135 
136  //------------------- operator + with scalar -------------------
138  template<typename T>
139  std::vector<T> operator + (T const & scalar, std::vector<T> rhs) {
140  std::transform(rhs.begin(), rhs.end(), rhs.begin(), bind1st(std::plus<T>(), scalar));
141  return rhs;
142  }
144  template<typename T>
145  std::vector<T> operator + (std::vector<T> lhs, T const & scalar) {
146  std::transform(lhs.begin(), lhs.end(), lhs.begin(), bind2nd(std::plus<T>(), scalar));
147  return lhs;
148  }
149 
150  //------------------- operator - with scalar -------------------
152  template<typename T>
153  std::vector<T> operator - (T const & scalar, std::vector<T> const & rhs) {
154  return scalar + -rhs;
155  }
157  template<typename T>
158  std::vector<T> operator - (std::vector<T> const & lhs, T const & scalar) {
159  return lhs + -scalar;
160  }
161 
162  //------------------- operator * with scalar -------------------
164  template<typename T>
165  std::vector<T> operator * (std::vector<T> const & lhs, T const & scalar) {
166  using boost::numeric::operators::operator*;
167  return lhs * scalar;
168  }
170  template<typename T>
171  std::vector<T> operator * (T const & scalar, std::vector<T> const & rhs) {
172  using boost::numeric::operators::operator*;
173  return scalar * rhs;
174  }
175  //------------------- operator / with scalar -------------------
177  template<typename T>
178  std::vector<T> operator / (std::vector<T> const & lhs, T const & scalar) {
179  using boost::numeric::operators::operator/;
180  return lhs / scalar;
181  }
183  template<typename T>
184  std::vector<T> operator / (T const & scalar, std::vector<T> rhs) {
185  std::transform(rhs.begin(), rhs.end(), rhs.begin(), scalar / boost::lambda::_1);
186  return rhs;
187  }
188 
189  //------------------- numeric functions -------------------
190  #define ALPS_NUMERIC_IMPLEMENT_FUNCTION(FUNCTION_NAME) \
191  template<typename T> std::vector<T> FUNCTION_NAME (std::vector<T> arg) { \
192  using std:: FUNCTION_NAME ; \
193  std::transform(arg.begin(), arg.end(), arg.begin(), static_cast<T (*)(T)>(& FUNCTION_NAME )); \
194  return arg; \
195  }
196 
210 
211  #undef ALPS_NUMERIC_IMPLEMENT_FUNCTION
212 
213  template<typename T, typename U> std::vector<T> pow(std::vector<T> vec, U index) {
214  using std::pow;
215  std::transform(vec.begin(), vec.end(), vec.begin(), boost::lambda::bind<T>(static_cast<T (*)(T, T)>(&pow), boost::lambda::_1, index));
216  return vec;
217  }
218 
220  template <typename T> struct negate: public std::negate<T> {};
221 
223  template <typename T>
224  struct negate< std::vector<T> > {
225  typedef std::vector<T> VT;
226  VT operator()(VT v)
227  {
228  transform(v.begin(),v.end(),v.begin(),negate<T>());
229  return v;
230  }
231  };
232 
234  template <typename T>
235  struct invert {
236  T operator()(T x) { return 1.0/x; }
237  };
238 
240  template <typename T>
241  struct invert< std::vector<T> > {
242  typedef std::vector<T> VT;
243  VT operator()(VT v)
244  {
245  transform(v.begin(),v.end(),v.begin(),invert<T>());
246  return v;
247  }
248  };
249 
250 
251  /* Functors */
252 
253  template <typename T> struct unary_minus : public std::unary_function<T, T> {
254  T operator()(T const & x) const {
255  // using boost::numeric::operators::operator-;
256  using alps::numeric::operator-;
257  return -x;
258  }
259  };
260 
261  template <typename T, typename U, typename R> struct plus : public std::binary_function<T, U, R> {
262  R operator()(T const & x, U const & y) const {
263  // using boost::numeric::operators::operator+;
264  using alps::numeric::operator+;
265  return x + y;
266  }
267  };
268  template <typename T> struct plus<T, T, T> : public std::binary_function<T, T, T> {
269  T operator()(T const & x, T const & y) const {
270  // using boost::numeric::operators::operator+;
271  using alps::numeric::operator+;
272  return x + y;
273  }
274  };
275 
276  template <typename T, typename U, typename R> struct minus : public std::binary_function<T, U, R> {
277  R operator()(T const & x, U const & y) const {
278  // using boost::numeric::operators::operator-;
279  using alps::numeric::operator-;
280  return x - y;
281  }
282  };
283  template <typename T> struct minus<T, T, T> : public std::binary_function<T, T, T> {
284  T operator()(T const & x, T const & y) const {
285  // using boost::numeric::operators::operator-;
286  using alps::numeric::operator-;
287  return x - y;
288  }
289  };
290 
291  template <typename T, typename U, typename R> struct multiplies : public std::binary_function<T, U, R> {
292  R operator()(T const & x, U const & y) const {
293  // using boost::numeric::operators::operator*;
294  using alps::numeric::operator*;
295  return x * y;
296  }
297  };
298  template <typename T> struct multiplies<T, T, T> : public std::binary_function<T, T, T> {
299  T operator()(T const & x, T const & y) const {
300  // using boost::numeric::operators::operator*;
301  using alps::numeric::operator*;
302  return x * y;
303  }
304  };
305 
306  template <typename T, typename U, typename R> struct divides : public std::binary_function<T, U, R> {
307  R operator()(T const & x, U const & y) const {
308  // using boost::numeric::operators::operator/;
309  using alps::numeric::operator/;
310  return x / y;
311  }
312  };
313  template <typename T> struct divides<T, T, T> : public std::binary_function<T, T, T> {
314  T operator()(T const & x, T const & y) const {
315  // using boost::numeric::operators::operator/;
316  using alps::numeric::operator/;
317  return x / y;
318  }
319  };
320 
321 
322  //------------------- operator equal -------------------
323  #define ALPS_NUMERIC_OPERATOR_EQ(OP_NAME, OPERATOR) \
324  template<typename T> \
325  std::vector<T> & OP_NAME (std::vector<T> & lhs, std::vector<T> const & rhs) { \
326  if(lhs.size() != rhs.size()) { \
327  std::string lsz=std::to_string(lhs.size()); \
328  std::string rsz=std::to_string(rhs.size()); \
329  boost::throw_exception(std::runtime_error("std::vectors have different sizes:" \
330  " left="+lsz+ \
331  " right="+rsz + "\n" + \
332  ALPS_STACKTRACE)); \
333  } \
334  else \
335  std::transform(lhs.begin(), lhs.end(), rhs.begin(), lhs.begin(), OPERATOR <T,T,T>() ); \
336  return lhs; \
337  }
338 
343 
344  #undef ALPS_NUMERIC_OPERATOR_EQ
345 
346 
348 
354  template <typename T>
355  std::vector<T>& merge(std::vector<T>& left, const std::vector<T>& right) {
356  std::size_t lsz=left.size();
357  std::size_t rsz=right.size();
358  if (lsz<rsz) left.resize(rsz); // now left is at least as big as right
359  std::transform(right.begin(), right.end(),
360  left.begin(),
361  left.begin(),
362  plus<T,T,T>());
363  return left;
364  }
365  }
366 }
367 
368 #endif // ALPS_NUMERIC_VECTOR_FUNCTIONS_HEADER
boost::array< T, N > sinh(boost::array< T, N > arg)
index_mesh::index_type index
Definition: mesh.hpp:1247
boost::array< T, N > tanh(boost::array< T, N > arg)
boost::array< T, N > cbrt(boost::array< T, N > arg)
boost::array< T, N > atan(boost::array< T, N > arg)
boost::array< T, N > log(boost::array< T, N > arg)
boost::array< T, N > sqrt(boost::array< T, N > arg)
#define ALPS_NUMERIC_IMPLEMENT_FUNCTION(FUNCTION_NAME)
boost::array< T, N > abs(boost::array< T, N > arg)
boost::array< T, N > operator*(boost::array< T, N > lhs, boost::array< U, N > const &rhs)
boost::array< T, N > cos(boost::array< T, N > arg)
#define IMPLEMENT_ALPS_VECTOR_FUNCTION(LIB_HEADER, FUNCTION_NAME)
T operator()(T const &x, T const &y) const
STL namespace.
boost::array< T, N > operator/(boost::array< T, N > lhs, boost::array< U, N > const &rhs)
T operator()(T const &x, T const &y) const
mean_result< T > transform(no_prop, const transformer< T > &tf, const InResult &in)
Definition: transform.hpp:27
R operator()(T const &x, U const &y) const
T operator()(T const &x, T const &y) const
std::vector< T > acosh(std::vector< T > vec)
Metafunction returning "mathematical scalar" type for type T.
Definition: scalar.hpp:28
R operator()(T const &x, U const &y) const
boost::array< T, N > cosh(boost::array< T, N > arg)
R operator()(T const &x, U const &y) const
inf(const value_type &vec)
Construct infinity object of the same size as its argument, recursively.
"Imported" negation functor class (needed to define template specializations in this namespace) ...
boost::array< T, N > exp(boost::array< T, N > arg)
#define ALPS_NUMERIC_OPERATOR_EQ(OP_NAME, OPERATOR)
boost::array< T, N > operator+(boost::array< T, N > lhs, boost::array< U, N > const &rhs)
R operator()(T const &x, U const &y) const
boost::array< T, N > asin(boost::array< T, N > arg)
boost::array< T, N > sin(boost::array< T, N > arg)
std::vector< T > asinh(std::vector< T > vec)
std::vector< T > pow(std::vector< T > vec, U index)
boost::array< T, N > acos(boost::array< T, N > arg)
boost::array< T, N > cb(boost::array< T, N > arg)
std::vector< T > atanh(std::vector< T > vec)
boost::array< T, N > tan(boost::array< T, N > arg)
T operator()(T const &x) const
std::vector< T > & merge(std::vector< T > &left, const std::vector< T > &right)
Vector merge.
boost::array< T, N > sq(boost::array< T, N > arg)
A service functor class for numerical inversion, to be used in transform()
boost::array< T, N > operator-(boost::array< T, N > lhs)
T operator()(T const &x, T const &y) const