1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 /*
4  Copyright (C) 2005 Gary Kennedy
5  Copyright (C) 2006 StatPro Italia srl
6 
7  This file is part of QuantLib, a free-software/open-source library
8  for financial quantitative analysts and developers - http://quantlib.org/
9 
10  QuantLib is free software: you can redistribute it and/or modify it
11  under the terms of the QuantLib license.  You should have received a
12  copy of the license along with this program; if not, please email
13  <quantlib-dev@lists.sf.net>. The license is also available online at
14  <http://quantlib.org/license.shtml>.
15 
16  This program is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  FOR A PARTICULAR PURPOSE.  See the license for more details.
19 */
20 
21 /*! \file convergencestatistics.hpp
22     \brief statistics tool with risk measures
23 */
24 
25 #ifndef quantlib_convergence_statistics_hpp
26 #define quantlib_convergence_statistics_hpp
27 
28 #include <ql/types.hpp>
29 #include <vector>
30 
31 namespace QuantLib {
32 
33     class DoublingConvergenceSteps {
34       public:
initialSamples() const35         Size initialSamples() const { return 1; }
nextSamples(Size current)36         Size nextSamples(Size current) { return 2 * current + 1; }
37     };
38 
39     //! statistics class with convergence table
40     /*! This class decorates another statistics class adding a
41         convergence table calculation. The table tracks the
42         convergence of the mean.
43 
44         It is possible to specify the number of samples at which the
45         mean should be stored by mean of the second template
46         parameter; the default is to store \f$ 2^{n-1} \f$ samples at
47         the \f$ n \f$-th step. Any passed class must implement the
48         following interface:
49         \code
50         Size initialSamples() const;
51         Size nextSamples(Size currentSamples) const;
52         \endcode
53         as well as a copy constructor.
54 
55         \test results are tested against known good values.
56     */
57     template <class T, class U = DoublingConvergenceSteps>
58     class ConvergenceStatistics : public T {
59       public:
60         typedef typename T::value_type value_type;
61         typedef std::vector<std::pair<Size,value_type> > table_type;
62         ConvergenceStatistics(const T& stats,
63                               const U& rule = U());
64         ConvergenceStatistics(const U& rule = U());
65         void add(const value_type& value, Real weight = 1.0);
66         template <class DataIterator>
addSequence(DataIterator begin,DataIterator end)67         void addSequence(DataIterator begin, DataIterator end) {
68             for (; begin != end; ++begin)
69                 add(*begin);
70         }
71         template <class DataIterator, class WeightIterator>
addSequence(DataIterator begin,DataIterator end,WeightIterator wbegin)72         void addSequence(DataIterator begin, DataIterator end,
73                          WeightIterator wbegin) {
74             for (; begin != end; ++begin, ++wbegin)
75                 add(*begin,*wbegin);
76         }
77         void reset();
78         const std::vector<std::pair<Size,value_type> >& convergenceTable()
79                                                                         const;
80       private:
81         table_type table_;
82         U samplingRule_;
83         Size nextSampleSize_;
84     };
85 
86 
87     // inline definitions
88 
89     template <class T, class U>
ConvergenceStatistics(const T & stats,const U & rule)90     ConvergenceStatistics<T,U>::ConvergenceStatistics(const T& stats,
91                                                       const U& rule)
92     : T(stats), samplingRule_(rule) {
93         reset();
94     }
95 
96     template <class T, class U>
ConvergenceStatistics(const U & rule)97     ConvergenceStatistics<T,U>::ConvergenceStatistics(const U& rule)
98     : samplingRule_(rule) {
99         reset();
100     }
101 
102     #ifndef __DOXYGEN__
103     template <class T, class U>
add(const typename ConvergenceStatistics<T,U>::value_type & value,Real weight)104     void ConvergenceStatistics<T,U>::add(
105                  const typename ConvergenceStatistics<T,U>::value_type& value,
106                  Real weight) {
107         T::add(value,weight);
108         if (this->samples() == nextSampleSize_) {
109             table_.push_back(std::make_pair(this->samples(),this->mean()));
110             nextSampleSize_ = samplingRule_.nextSamples(nextSampleSize_);
111         }
112     }
113     #endif
114 
115     template <class T, class U>
reset()116     void ConvergenceStatistics<T,U>::reset() {
117         T::reset();
118         nextSampleSize_ = samplingRule_.initialSamples();
119         table_.clear();
120     }
121 
122     template <class T, class U>
123     const typename ConvergenceStatistics<T,U>::table_type&
convergenceTable() const124     ConvergenceStatistics<T,U>::convergenceTable() const {
125         return table_;
126     }
127 
128 }
129 
130 
131 #endif
132 
133