KASKADE 7 development version
geometric_sequence.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2012-2015 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef GEOMETRIC_SEQUENCE_HH_
14#define GEOMETRIC_SEQUENCE_HH_
15
16#include <cmath>
17#include <numeric>
18#include <iterator>
19#include <utility>
20
21#include "utilities/power.hh"
22
32template <class Iterator>
33std::pair<typename std::iterator_traits<Iterator>::value_type,typename std::iterator_traits<Iterator>::value_type>
34estimateGeometricSequence(Iterator first, Iterator last) {
35
36 typedef typename std::iterator_traits<Iterator>::value_type Scalar;
37
38 // Form the normal equations A^T A x = A^T b. As A = [ ones(n,1) (0:n-1)^T ], we have
39 // /n n(n-1)/2 \ / ln(a_0)+...+ln(a_{n-1}) \ .
40 // A^T A = | | and b = | |
41 // \ n(n-1)/2 n(n-1)(2n-1)/6 / \ ln(a_1)+2ln(a_2)+...+(n-1)ln(a_{n-1}) / such that
42 //
43 // 2 / 2n-1 -3 \ .
44 // (A^T A)^{-1} = ------ | |
45 // n(n+1) \ -3 6/(n-1) / .
46
47 // compute right hand side
48 Scalar b[2] = {0.0, 0.0};
49 int n = 0;
50 for ( ; first!=last; ++first) {
51 Scalar lna = std::log(*first);
52 b[0] += lna;
53 b[1] += n*lna;
54 ++n;
55 }
56 assert(n>=2);
57
58 // solve system by multiplication with (A^T A)^{-1}
59 return std::make_pair(std::exp(2*((2*n-1)*b[0]-3*b[1])/n/(n+1)),
60 std::exp( 2*(-3*b[0]+6*b[1]/(n-1))/n/(n+1)));
61}
62
74template <class Iterator>
75typename std::iterator_traits<Iterator>::value_type estimateGeometricTruncationError(Iterator first, Iterator last, int k) {
76 typedef typename std::iterator_traits<Iterator>::value_type Scalar;
77
78 int const n = std::distance(first,last);
79 assert(0<=k && k<=n);
80
81 std::pair<Scalar,Scalar> cq = estimateGeometricSequence(first,last);
82 if (cq.second<1) {
83 std::advance(first,k);
84 return std::accumulate(first,last,0.0) + cq.first*power(cq.second,n)/(1-cq.second);
85 } else
86 return std::numeric_limits<Scalar>::max(); // TODO: throw an exception?
87}
88
89
90#endif /* GEOMETRIC_SEQUENCE_HH_ */
std::iterator_traits< Iterator >::value_type estimateGeometricTruncationError(Iterator first, Iterator last, int k)
Estimates errors of truncating geometrically convergent sequences.
std::pair< typename std::iterator_traits< Iterator >::value_type, typename std::iterator_traits< Iterator >::value_type > estimateGeometricSequence(Iterator first, Iterator last)
Estimates parameters of geometric sequence.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
R power(R base, int exp)
Computes integral powers of values in a multiplicative half-group.
Definition: power.hh:30
Scalar distance(Point< Scalar, dim > const &first, Point< Scalar, dim > const &second)