QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
fastfouriertransform.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2006 Joseph Wang
5 Copyright (C) 2009 Liquidnet Holdings, Inc.
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 fastfouriertransform.hpp
22 \brief Fast Fourier Transform
23*/
24
25// Based on public domain code by Christopher Diggins
26
27#ifndef quantlib_fast_fourier_transform_hpp
28#define quantlib_fast_fourier_transform_hpp
29
30#include <ql/errors.hpp>
31#include <ql/types.hpp>
32#include <vector>
33#include <iterator>
34
35namespace QuantLib {
36
37 //! FFT implementation
39 public:
40
41 //! the minimum order required for the given input size
42 static std::size_t min_order(std::size_t inputSize) {
43 return static_cast<std::size_t>(
44 std::ceil(std::log(static_cast<Real>(inputSize)) / M_LN2));
45 }
46
47 FastFourierTransform(std::size_t order)
48 : cs_(order), sn_(order) {
49 std::size_t m = static_cast<std::size_t>(1) << order;
50 cs_[order - 1] = std::cos (2 * M_PI / m);
51 sn_[order - 1] = std::sin (2 * M_PI / m);
52 for (std::size_t i = order - 1; i > 0; --i) {
53 cs_ [i - 1] = cs_[i]*cs_[i] - sn_[i]*sn_[i];
54 sn_ [i - 1] = 2*sn_[i]*cs_[i];
55 }
56 }
57
58 //! The required size for the output vector
59 std::size_t output_size() const {
60 return (static_cast<std::size_t>(1) << cs_.size());
61 }
62
63 //! FFT transform.
64 /*! The output sequence must be allocated by the user */
65 template<typename InputIterator, typename RandomAccessIterator>
66 void transform(InputIterator inBegin, InputIterator inEnd,
67 RandomAccessIterator out) const {
68 transform_impl(inBegin, inEnd, out, false);
69 }
70
71 //! Inverse FFT transform.
72 /*! The output sequence must be allocated by the user. */
73 template<typename InputIterator, typename RandomAccessIterator>
74 void inverse_transform(InputIterator inBegin, InputIterator inEnd,
75 RandomAccessIterator out) const {
76 transform_impl(inBegin, inEnd, out, true);
77 }
78
79 private:
80 std::vector<double> cs_, sn_;
81
82 template<typename InputIterator, typename RandomAccessIterator>
83 void transform_impl(InputIterator inBegin, InputIterator inEnd,
84 RandomAccessIterator out,
85 bool inverse) const {
86 typedef
87 typename std::iterator_traits<RandomAccessIterator>::value_type
88 complex;
89 const std::size_t order = cs_.size();
90 const auto N = std::size_t(static_cast<std::size_t>(1) << order);
91 std::size_t i = 0;
92 for (; inBegin != inEnd; ++i, ++inBegin) {
93 *(out + bit_reverse(i, order)) = *inBegin;
94 }
95 QL_REQUIRE (i <= N, "FFT order is too small");
96 for (std::size_t s = 1; s <= order; ++s) {
97 std::size_t m = static_cast<std::size_t>(1) << s;
98 complex w(1.0);
99 complex wm(cs_[s-1], inverse ? sn_[s-1] : -sn_[s-1]);
100 for (std::size_t j = 0; j < m/2; ++j) {
101 for (std::size_t k = j; k < N; k += m) {
102 complex t = w * (*(out + k + m/2));
103 complex u = *(out + k);
104 *(out + k) = u + t;
105 *(out + k + m/2) = u - t;
106 }
107 w *= wm;
108 }
109 }
110 }
111
112 static std::size_t bit_reverse(std::size_t x, std::size_t order) {
113 std::size_t n = 0;
114 for (std::size_t i = 0; i < order; ++i) {
115 n <<= 1;
116 n |= (x & 1);
117 x >>= 1;
118 }
119 return n;
120 }
121 };
122
123}
124
125#endif
static std::size_t min_order(std::size_t inputSize)
the minimum order required for the given input size
void transform(InputIterator inBegin, InputIterator inEnd, RandomAccessIterator out) const
FFT transform.
std::size_t output_size() const
The required size for the output vector.
static std::size_t bit_reverse(std::size_t x, std::size_t order)
void inverse_transform(InputIterator inBegin, InputIterator inEnd, RandomAccessIterator out) const
Inverse FFT transform.
void transform_impl(InputIterator inBegin, InputIterator inEnd, RandomAccessIterator out, bool inverse) const
const DefaultType & t
Classes and functions for error handling.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
QL_REAL Real
real number
Definition: types.hpp:50
#define M_LN2
#define M_PI
Definition: any.hpp:35
Matrix inverse(const Matrix &m)
Definition: matrix.cpp:44
Custom types.