ALPSCore reference
transform.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 #pragma once
7 
8 #include <alps/alea/core.hpp>
9 #include <alps/alea/computed.hpp>
10 
11 #include <alps/alea/mean.hpp>
12 #include <alps/alea/variance.hpp>
13 #include <alps/alea/covariance.hpp>
14 #include <alps/alea/batch.hpp>
15 
17 #include <alps/alea/convert.hpp>
18 #include <alps/alea/transformer.hpp> //FIXME
19 
20 #include <random>
21 #include <type_traits>
22 
23 
24 namespace alps { namespace alea {
25 
26 template <typename T, typename InResult>
27 mean_result<T> transform(no_prop, const transformer<T> &tf, const InResult &in)
28 {
29  static_assert(traits<InResult>::HAVE_MEAN, "result does not have mean");
30  static_assert(std::is_same<typename traits<InResult>::value_type, T>::value,
31  "Result and transform types are mismatched");
32 
33  if (tf.in_size() != in.size())
34  throw size_mismatch();
35 
37  res.store().data() = tf(in.mean());
38  res.store().count() = in.count();
39  return res;
40 }
41 
42 // template mean_result<double> transform(no_prop, const transformer<double>&, const mean_result<double>&);
43 
44 template <typename T, typename InResult>
45 typename std::enable_if<traits<InResult>::HAVE_COV, cov_result<T> >::type transform(linear_prop p, const transformer<T> &tf, const InResult &in)
46 {
47  static_assert(traits<InResult>::HAVE_MEAN, "result does not have mean");
48  static_assert(traits<InResult>::HAVE_COV, "result does not have covariance");
49  static_assert(std::is_same<typename traits<InResult>::value_type, T>::value,
50  "Result and transform types are mismatched");
51 
52  if (tf.in_size() != in.size())
53  throw size_mismatch();
54 
55  double dx = p.dx();
56  if (dx == 0)
57  dx = 0.125 * std::abs(in.stderror().mean());
58  typename eigen<T>::matrix jac = jacobian(tf, in.mean(), dx);
59 
60  // TODO: this batch_size thing works but is conceptually hairy.
61  double batch_size = in.count2() / in.count();
63  res.store().data() = tf(in.mean());
64  res.store().data2() = jac * in.cov()/batch_size * jac.adjoint();
65  res.store().count() = in.count();
66  res.store().count2() = in.count2();
67  return res;
68 }
69 
70 // template cov_result<double> transform(linear_prop, const transformer<double>&, const cov_result<double>&);
71 
72 template <typename T, typename InResult>
73 typename std::enable_if<!traits<InResult>::HAVE_COV, cov_result<T>>::type transform(linear_prop p, const transformer<T> &tf, const InResult &in)
74 {
75  static_assert(traits<InResult>::HAVE_MEAN, "result does not have mean");
76  static_assert(traits<InResult>::HAVE_VAR, "result does not have variance");
77  static_assert(std::is_same<typename traits<InResult>::value_type, T>::value,
78  "Result and transform types are mismatched");
79 
80  if (tf.in_size() != in.size())
81  throw size_mismatch();
82 
83  double dx = p.dx();
84  if (dx == 0)
85  dx = 0.125 * std::abs(in.stderror().mean());
86  typename eigen<T>::matrix jac = jacobian(tf, in.mean(), dx);
87 
88  // TODO: this batch_size() thing is conceptually hairy.
89  double batch_size = in.count2() / in.count();
91  res.store().data() = tf(in.mean());
92  res.store().data2() = jac * in.var().asDiagonal()/batch_size * jac.adjoint();
93  res.store().count() = in.count();
94  res.store().count2() = in.count2();
95  return res;
96 }
97 
98 // template cov_result<double> transform(linear_prop, const transformer<double>&, const var_result<double>&);
99 
100 template <typename T>
102 {
103  if (tf.in_size() != in.size())
104  throw size_mismatch();
105 
106  batch_result<T> res(jackknife(in.store(), tf));
107  return res;
108 }
109 
111 
112 }}
double dx() const
Definition: propagation.hpp:49
eigen< T >::matrix jacobian(const transformer< T > &f, column< T > x, double dx)
Definition: propagation.cpp:13
batch_data< T > jackknife(const batch_data< T > &in, const transformer< T > &tf)
Definition: propagation.cpp:37
boost::array< T, N > abs(boost::array< T, N > arg)
size_t size() const
Definition: batch.hpp:190
const mean_data< T > & store() const
Definition: mean.hpp:190
mean_result< T > transform(no_prop, const transformer< T > &tf, const InResult &in)
Definition: transform.hpp:27
virtual size_t in_size() const =0
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > matrix
Definition: util.hpp:49
virtual size_t out_size() const =0
const batch_data< T > & store() const
Definition: batch.hpp:216
const cov_data< T, Strategy > & store() const
Definition: covariance.hpp:259