|
||||
File indexing completed on 2025-01-30 10:04:22
0001 //========================================================================== 0002 // AIDA Detector description implementation 0003 //-------------------------------------------------------------------------- 0004 // 0005 // This code is originally written by Sampo Niskanen in java. 0006 // Translated to C++ by M.Frank 0007 // 0008 // See original copyright notice below 0009 //========================================================================== 0010 // 0011 // PinkNoise.java - a pink noise generator 0012 // 0013 // Copyright (c) 2008, Sampo Niskanen <sampo.niskanen@iki.fi> 0014 // All rights reserved. 0015 // Source: http://www.iki.fi/sampo.niskanen/PinkNoise/ 0016 // 0017 // Distrubuted under the BSD license: 0018 // 0019 // Redistribution and use in source and binary forms, with or without 0020 // modification, are permitted provided that the following conditions 0021 // are met: 0022 // 0023 // - Redistributions of source code must retain the above copyright 0024 // notice, this list of conditions and the following disclaimer. 0025 // 0026 // - Redistributions in binary form must reproduce the above 0027 // copyright notice, this list of conditions and the following 0028 // disclaimer in the documentation and/or other materials provided 0029 // with the distribution. 0030 // 0031 // - Neither the name of the copyright owners nor contributors may be 0032 // used to endorse or promote products derived from this software 0033 // without specific prior written permission. 0034 // 0035 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0036 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0037 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 0038 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 0039 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 0040 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 0041 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 0042 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 0043 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 0044 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 0045 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0046 // POSSIBILITY OF SUCH DAMAGE. 0047 // 0048 //========================================================================== 0049 0050 #ifndef DDDIGI_NOISE_FALPHANOISE_H 0051 #define DDDIGI_NOISE_FALPHANOISE_H 0052 0053 /// C/C++ include files 0054 #include <vector> 0055 #include <random> 0056 0057 /// Namespace for the AIDA detector description toolkit 0058 namespace dd4hep { 0059 0060 /// Namespace for the Digitization part of the AIDA detector description toolkit 0061 namespace detail { 0062 0063 /// Source of pink noise with a power spectrum proportional to 1/f^alpha. 0064 /** 0065 * A class that provides a source of pink noise with a power spectrum 0066 * density (PSD) proportional to 1/f^alpha. "Regular" pink noise has a 0067 * PSD proportional to 1/f, i.e. alpha=1. However, many natural 0068 * systems may require a different PSD proportionality. The value of 0069 * alpha may be from 0 to 2, inclusive. The special case alpha=0 0070 * results in white noise (directly generated random numbers) and 0071 * alpha=2 results in brown noise (integrated white noise). 0072 * <p> 0073 * The values are computed by applying an IIR filter to generated 0074 * Gaussian random numbers. The number of poles used in the filter 0075 * may be specified. For each number of poles there is a limiting 0076 * frequency below which the PSD becomes constant. Values as low as 0077 * 1-3 poles produce relatively good results, however these values 0078 * will be concentrated near zero. Using a larger number of poles 0079 * will allow more low frequency components to be included, leading to 0080 * more variation from zero. However, the sequence is stationary, 0081 * that is, it will always return to zero even with a large number of 0082 * poles. 0083 * <p> 0084 * The distribution of values is very close to Gaussian with mean 0085 * zero, but the variance depends on the number of poles used. 0086 * The resulting distribution is almost Gaussian, but has a relatively 0087 * larger amount of large values. To re-normalize the variance a 0088 * calibration method normalize() is provided. 0089 * <p> 0090 * The IIR filter used by this class is presented by N. Jeremy Kasdin, 0091 * Proceedings of the IEEE, Vol. 83, No. 5, May 1995, p. 822. 0092 * 0093 * \author Sampo Niskanen <sampo.niskanen@iki.fi> 0094 * \author M.Frank 0095 * \version 1.0 0096 * \ingroup DD4HEP_DIGITIZATION 0097 */ 0098 class FalphaNoise { 0099 public: 0100 /// Minimal class to mimic a std::random_engine 0101 struct random_engine_wrapper { 0102 typedef unsigned int result_type; 0103 static constexpr result_type min() { return std::default_random_engine::min(); } 0104 static constexpr result_type max() { return std::default_random_engine::max(); } 0105 static constexpr double range() { return double(max()) - double(min()); } 0106 virtual result_type operator()() const = 0; 0107 }; 0108 /// Concrete wrapper of a user defined random engine 0109 template <typename ENGINE> struct random_engine : public random_engine_wrapper { 0110 ENGINE& engine; 0111 random_engine(ENGINE& e) : engine(e) {} 0112 virtual result_type operator()() const { 0113 static constexpr double norm = random_engine_wrapper::range() / (double(ENGINE::max() - ENGINE::min())); 0114 return result_type(double(engine()) * norm); 0115 } 0116 }; 0117 0118 protected: 0119 #ifdef __GSL_FALPHA_NOISE 0120 long ptr = -1; 0121 double * arr = nullptr; 0122 #endif 0123 /// Number of poles used for the approximation 0124 size_t m_poles = 0; 0125 /// The variance of the pink noise distribution 0126 double m_variance = -1e0; 0127 /// The alpha coefficient for the 1/f**alpha generated noise 0128 double m_alpha = -1e0; 0129 /// Array of multipliers 0130 std::vector<double> m_multipliers {}; 0131 /// Array of buffered values 0132 std::vector<double> m_values {}; 0133 /// Normal distribution with variance for the white noise generation 0134 std::normal_distribution<double> m_distribution; 0135 0136 /// Internal usage for the transformation from the normal distruted white noise to pink noise 0137 double compute(double gaussian); 0138 /// Internal implementation of the normalization of the variance 0139 void normalizeVariance(const random_engine_wrapper& engine, size_t shots); 0140 0141 public: 0142 /// Default constructor. Requires a later call to init(...) 0143 FalphaNoise() = default; 0144 /// Initializing constructor. Leaves the enerator full functional 0145 FalphaNoise(size_t poles, double alpha, double variance); 0146 /// Initializing constructor with 5 poles. Leaves the enerator full functional 0147 FalphaNoise(double alpha, double variance); 0148 /// Default destructor 0149 virtual ~FalphaNoise() = default; 0150 /// Access variance value 0151 double variance() const { return m_variance; } 0152 /// Access alpha value 0153 double alpha() const { return m_alpha; } 0154 /// Initialize the 1/f**alpha random generator. If already called reconfigures. 0155 void init(size_t poles, double alpha, double variance); 0156 /// Approximatively compute proper variance and apply computed value 0157 void normalize(size_t shots=10000); 0158 /// Approximatively compute proper variance using external ranfom engine and apply computed value 0159 template <typename ENGINE> void normalize(ENGINE& engine, size_t shots=10000); 0160 /// Retrieve the next random number of the sequence 0161 template <typename ENGINE> double operator()(ENGINE& engine); 0162 }; 0163 0164 /// Retrieve the next random number of the sequence 0165 template <typename ENGINE> inline double FalphaNoise::operator()(ENGINE& engine) { 0166 return compute(m_distribution(engine)); 0167 } 0168 /// Approximatively compute proper variance using external ranfom engine and apply computed value 0169 template <typename ENGINE> void FalphaNoise::normalize(ENGINE& engine, size_t shots) { 0170 normalizeVariance(random_engine<ENGINE>(engine), shots); 0171 } 0172 } // End namespace detail 0173 } // End namespace dd4hep 0174 #endif // DDDIGI_NOISE_FALPHANOISE_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |