BornAgain  1.18.0
Simulate and fit neutron and x-ray scattering at grazing incidence
FTDistributions1D.cpp
Go to the documentation of this file.
1 // ************************************************************************** //
2 //
3 // BornAgain: simulate and fit scattering at grazing incidence
4 //
5 //! @file Sample/Correlations/FTDistributions1D.cpp
6 //! @brief Implements interface class IFTDistribution2D and children thereof.
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************** //
14 
17 #include "Base/Types/Exceptions.h"
19 #include <limits>
20 
21 namespace
22 {
23 const double CosineDistributionFactor = 1.0 / 3.0 - 2.0 / M_PI / M_PI;
24 }
25 
26 // ************************************************************************** //
27 // interface IFTDistribution1D
28 // ************************************************************************** //
29 
30 IFTDistribution1D::IFTDistribution1D(const NodeMeta& meta, const std::vector<double>& PValues)
31  : INode(nodeMetaUnion({{"Omega", "nm", "Half-width", 0, INF, 1.}}, meta), PValues),
32  m_omega(m_P[0])
33 {
34 }
35 
36 // ************************************************************************** //
37 // class FTDistribution1DCauchy
38 // ************************************************************************** //
39 
41  : IFTDistribution1D({"FTDistribution1DCauchy", "class_tooltip", {}}, P)
42 {
43 }
44 
46  : FTDistribution1DCauchy(std::vector<double>{omega})
47 {
48 }
49 
51 {
52  return new FTDistribution1DCauchy(m_omega);
53 }
54 
55 double FTDistribution1DCauchy::evaluate(double q) const
56 {
57  double sum_sq = q * q * m_omega * m_omega;
58  return 1.0 / (1.0 + sum_sq);
59 }
60 
62 {
63  return 2.0 * m_omega * m_omega;
64 }
65 
66 std::unique_ptr<IDistribution1DSampler> FTDistribution1DCauchy::createSampler() const
67 {
68  return std::make_unique<Distribution1DCauchySampler>(1 / m_omega);
69 }
70 
71 // ************************************************************************** //
72 // class FTDistribution1DGauss
73 // ************************************************************************** //
74 
76  : IFTDistribution1D({"FTDistribution1DGauss", "class_tooltip", {}}, P)
77 {
78 }
79 
81  : FTDistribution1DGauss(std::vector<double>{omega})
82 {
83 }
84 
86 {
87  return new FTDistribution1DGauss(m_omega);
88 }
89 
90 double FTDistribution1DGauss::evaluate(double q) const
91 {
92  double sum_sq = q * q * m_omega * m_omega;
93  return std::exp(-sum_sq / 2.0);
94 }
95 
97 {
98  return m_omega * m_omega;
99 }
100 
101 std::unique_ptr<IDistribution1DSampler> FTDistribution1DGauss::createSampler() const
102 {
103  return std::make_unique<Distribution1DGaussSampler>(0.0, m_omega);
104 }
105 
106 // ************************************************************************** //
107 // class FTDistribution1DGate
108 // ************************************************************************** //
109 
110 FTDistribution1DGate::FTDistribution1DGate(const std::vector<double> P)
111  : IFTDistribution1D({"FTDistribution1DGate", "class_tooltip", {}}, P)
112 {
113 }
114 
116  : FTDistribution1DGate(std::vector<double>{omega})
117 {
118 }
119 
121 {
122  return new FTDistribution1DGate(m_omega);
123 }
124 
125 double FTDistribution1DGate::evaluate(double q) const
126 {
127  return MathFunctions::sinc(q * m_omega);
128 }
129 
131 {
132  return m_omega * m_omega / 3.0;
133 }
134 
135 std::unique_ptr<IDistribution1DSampler> FTDistribution1DGate::createSampler() const
136 {
137  return std::make_unique<Distribution1DGateSampler>(-m_omega, m_omega);
138 }
139 
140 // ************************************************************************** //
141 // class FTDistribution1DTriangle
142 // ************************************************************************** //
143 
145  : IFTDistribution1D({"FTDistribution1DTriangle", "class_tooltip", {}}, P)
146 {
147 }
148 
150  : FTDistribution1DTriangle(std::vector<double>{omega})
151 {
152 }
153 
155 {
156  return new FTDistribution1DTriangle(m_omega);
157 }
158 
160 {
161  double sincqw2 = MathFunctions::sinc(q * m_omega / 2.0);
162  return sincqw2 * sincqw2;
163 }
164 
166 {
167  return m_omega * m_omega / 6.0;
168 }
169 
170 std::unique_ptr<IDistribution1DSampler> FTDistribution1DTriangle::createSampler() const
171 {
172  return std::make_unique<Distribution1DTriangleSampler>(m_omega);
173 }
174 
175 // ************************************************************************** //
176 // class FTDistribution1DCosine
177 // ************************************************************************** //
178 
180  : IFTDistribution1D({"FTDistribution1DCosine", "class_tooltip", {}}, P)
181 {
182 }
183 
185  : FTDistribution1DCosine(std::vector<double>{omega})
186 {
187 }
188 
190 {
191  return new FTDistribution1DCosine(m_omega);
192 }
193 
194 double FTDistribution1DCosine::evaluate(double q) const
195 {
196  double qw = std::abs(q * m_omega);
197  if (std::abs(1.0 - qw * qw / M_PI / M_PI) < std::numeric_limits<double>::epsilon())
198  return 0.5;
199  return MathFunctions::sinc(qw) / (1.0 - qw * qw / M_PI / M_PI);
200 }
201 
203 {
205 }
206 
207 std::unique_ptr<IDistribution1DSampler> FTDistribution1DCosine::createSampler() const
208 {
209  return std::make_unique<Distribution1DCosineSampler>(m_omega);
210 }
211 
212 // ************************************************************************** //
213 // class FTDistribution1DVoigt
214 // ************************************************************************** //
215 
218  {"FTDistribution1DVoigt",
219  "class_tooltip",
220  {{"Eta", "", "balances between Gauss (eta=0) and Cauchy (eta=1) limiting cases", -INF,
221  +INF, 0}}},
222  P),
223  m_eta(m_P[1])
224 {
225 }
226 
228  : FTDistribution1DVoigt(std::vector<double>{omega, eta})
229 {
230 }
231 
233 {
234  return new FTDistribution1DVoigt(m_omega, m_eta);
235 }
236 
237 double FTDistribution1DVoigt::evaluate(double q) const
238 {
239  double sum_sq = q * q * m_omega * m_omega;
240  return m_eta * std::exp(-sum_sq / 2.0) + (1.0 - m_eta) * 1.0 / (1.0 + sum_sq);
241 }
242 
244 {
245  return (2.0 - m_eta) * m_omega * m_omega;
246 }
247 
248 std::unique_ptr<IDistribution1DSampler> FTDistribution1DVoigt::createSampler() const
249 {
250  // TODO Need to implement 1D Voigt
251 
252  std::ostringstream ostr;
253  ostr << "FTDistribution1DVoigt::createSampler() -> Error in class initialization";
254  ostr << "\n\n Has not been implemented yet...stay tuned!";
256 }
Defines many exception classes in namespace Exceptionss.
Defines interface class IFTDistribution1D, and children thereof.
NodeMeta nodeMetaUnion(const std::vector< ParaMeta > &base, const NodeMeta &other)
Definition: INode.cpp:24
const double INF
Definition: INode.h:24
Defines M_PI and some more mathematical constants.
#define M_PI
Definition: MathConstants.h:39
Defines namespace MathFunctions.
Exponential IFTDistribution1D exp(-|omega*x|); its Fourier transform evaluate(q) is a Cauchy-Lorentzi...
FTDistribution1DCauchy * clone() const override final
double qSecondDerivative() const override final
Returns the negative of the second order derivative in q space around q=0.
std::unique_ptr< IDistribution1DSampler > createSampler() const override final
FTDistribution1DCauchy(const std::vector< double > P)
double evaluate(double q) const override final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
IFTDistribution1D consisting of one cosine wave [1+cos(pi*x/omega) if |x|<omega, and 0 otherwise]; it...
std::unique_ptr< IDistribution1DSampler > createSampler() const override final
FTDistribution1DCosine * clone() const override final
double evaluate(double q) const override final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
FTDistribution1DCosine(const std::vector< double > P)
double qSecondDerivative() const override final
Returns the negative of the second order derivative in q space around q=0.
Square gate IFTDistribution1D; its Fourier transform evaluate(q) is a sinc function starting at evalu...
double evaluate(double q) const override final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
double qSecondDerivative() const override final
Returns the negative of the second order derivative in q space around q=0.
FTDistribution1DGate(const std::vector< double > P)
std::unique_ptr< IDistribution1DSampler > createSampler() const override final
FTDistribution1DGate * clone() const override final
Gaussian IFTDistribution1D; its Fourier transform evaluate(q) is a Gaussian starting at evaluate(0)=1...
FTDistribution1DGauss(const std::vector< double > P)
FTDistribution1DGauss * clone() const override final
double qSecondDerivative() const override final
Returns the negative of the second order derivative in q space around q=0.
std::unique_ptr< IDistribution1DSampler > createSampler() const override final
double evaluate(double q) const override final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
Triangle IFTDistribution1D [1-|x|/omega if |x|<omega, and 0 otherwise]; its Fourier transform evaluat...
FTDistribution1DTriangle * clone() const override final
FTDistribution1DTriangle(const std::vector< double > P)
double evaluate(double q) const override final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
std::unique_ptr< IDistribution1DSampler > createSampler() const override final
double qSecondDerivative() const override final
Returns the negative of the second order derivative in q space around q=0.
IFTDistribution1D that provides a Fourier transform evaluate(q) in form of a pseudo-Voigt decay funct...
FTDistribution1DVoigt * clone() const override final
double evaluate(double q) const override final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
double qSecondDerivative() const override final
Returns the negative of the second order derivative in q space around q=0.
FTDistribution1DVoigt(const std::vector< double > P)
std::unique_ptr< IDistribution1DSampler > createSampler() const override final
Interface for a one-dimensional distribution, with normalization adjusted so that the Fourier transfo...
IFTDistribution1D(const NodeMeta &meta, const std::vector< double > &PValues)
const double & m_omega
double omega() const
Base class for tree-like structures containing parameterized objects.
Definition: INode.h:49
double sinc(double x)
sinc function:
Metadata of one model node.
Definition: INode.h:37