BornAgain  1.19.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 reflection and scattering
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 
16 #include "Base/Math/Constants.h"
17 #include "Base/Math/Functions.h"
18 #include <limits>
19 
20 namespace {
21 const double CosineDistributionFactor = 1.0 / 3.0 - 2.0 / M_PI / M_PI;
22 }
23 
24 // ************************************************************************************************
25 // interface IFTDistribution1D
26 // ************************************************************************************************
27 
28 IFTDistribution1D::IFTDistribution1D(const NodeMeta& meta, const std::vector<double>& PValues)
29  : INode(nodeMetaUnion({{"Omega", "nm", "Half-width", 0, INF, 1.}}, meta), PValues)
30  , m_omega(m_P[0])
31 {
32 }
33 
34 // ************************************************************************************************
35 // class FTDistribution1DCauchy
36 // ************************************************************************************************
37 
39  : IFTDistribution1D({"FTDistribution1DCauchy", "class_tooltip", {}}, P)
40 {
41 }
42 
44  : FTDistribution1DCauchy(std::vector<double>{omega})
45 {
46 }
47 
49 {
50  return new FTDistribution1DCauchy(m_omega);
51 }
52 
53 double FTDistribution1DCauchy::evaluate(double q) const
54 {
55  double sum_sq = q * q * m_omega * m_omega;
56  return 1.0 / (1.0 + sum_sq);
57 }
58 
60 {
61  return 2.0 * m_omega * m_omega;
62 }
63 
64 std::unique_ptr<IDistribution1DSampler> FTDistribution1DCauchy::createSampler() const
65 {
66  return std::make_unique<Distribution1DCauchySampler>(1 / m_omega);
67 }
68 
69 // ************************************************************************************************
70 // class FTDistribution1DGauss
71 // ************************************************************************************************
72 
74  : IFTDistribution1D({"FTDistribution1DGauss", "class_tooltip", {}}, P)
75 {
76 }
77 
79  : FTDistribution1DGauss(std::vector<double>{omega})
80 {
81 }
82 
84 {
85  return new FTDistribution1DGauss(m_omega);
86 }
87 
88 double FTDistribution1DGauss::evaluate(double q) const
89 {
90  double sum_sq = q * q * m_omega * m_omega;
91  return std::exp(-sum_sq / 2.0);
92 }
93 
95 {
96  return m_omega * m_omega;
97 }
98 
99 std::unique_ptr<IDistribution1DSampler> FTDistribution1DGauss::createSampler() const
100 {
101  return std::make_unique<Distribution1DGaussSampler>(0.0, m_omega);
102 }
103 
104 // ************************************************************************************************
105 // class FTDistribution1DGate
106 // ************************************************************************************************
107 
108 FTDistribution1DGate::FTDistribution1DGate(const std::vector<double> P)
109  : IFTDistribution1D({"FTDistribution1DGate", "class_tooltip", {}}, P)
110 {
111 }
112 
114  : FTDistribution1DGate(std::vector<double>{omega})
115 {
116 }
117 
119 {
120  return new FTDistribution1DGate(m_omega);
121 }
122 
123 double FTDistribution1DGate::evaluate(double q) const
124 {
125  return Math::sinc(q * m_omega);
126 }
127 
129 {
130  return m_omega * m_omega / 3.0;
131 }
132 
133 std::unique_ptr<IDistribution1DSampler> FTDistribution1DGate::createSampler() const
134 {
135  return std::make_unique<Distribution1DGateSampler>(-m_omega, m_omega);
136 }
137 
138 // ************************************************************************************************
139 // class FTDistribution1DTriangle
140 // ************************************************************************************************
141 
143  : IFTDistribution1D({"FTDistribution1DTriangle", "class_tooltip", {}}, P)
144 {
145 }
146 
148  : FTDistribution1DTriangle(std::vector<double>{omega})
149 {
150 }
151 
153 {
154  return new FTDistribution1DTriangle(m_omega);
155 }
156 
158 {
159  double sincqw2 = Math::sinc(q * m_omega / 2.0);
160  return sincqw2 * sincqw2;
161 }
162 
164 {
165  return m_omega * m_omega / 6.0;
166 }
167 
168 std::unique_ptr<IDistribution1DSampler> FTDistribution1DTriangle::createSampler() const
169 {
170  return std::make_unique<Distribution1DTriangleSampler>(m_omega);
171 }
172 
173 // ************************************************************************************************
174 // class FTDistribution1DCosine
175 // ************************************************************************************************
176 
178  : IFTDistribution1D({"FTDistribution1DCosine", "class_tooltip", {}}, P)
179 {
180 }
181 
183  : FTDistribution1DCosine(std::vector<double>{omega})
184 {
185 }
186 
188 {
189  return new FTDistribution1DCosine(m_omega);
190 }
191 
192 double FTDistribution1DCosine::evaluate(double q) const
193 {
194  double qw = std::abs(q * m_omega);
195  if (std::abs(1.0 - qw * qw / M_PI / M_PI) < std::numeric_limits<double>::epsilon())
196  return 0.5;
197  return Math::sinc(qw) / (1.0 - qw * qw / M_PI / M_PI);
198 }
199 
201 {
202  return CosineDistributionFactor * m_omega * m_omega;
203 }
204 
205 std::unique_ptr<IDistribution1DSampler> FTDistribution1DCosine::createSampler() const
206 {
207  return std::make_unique<Distribution1DCosineSampler>(m_omega);
208 }
209 
210 // ************************************************************************************************
211 // class FTDistribution1DVoigt
212 // ************************************************************************************************
213 
216  {"FTDistribution1DVoigt",
217  "class_tooltip",
218  {{"Eta", "", "balances between Gauss (eta=0) and Cauchy (eta=1) limiting cases", -INF,
219  +INF, 0}}},
220  P)
221  , m_eta(m_P[1])
222 {
223 }
224 
226  : FTDistribution1DVoigt(std::vector<double>{omega, eta})
227 {
228 }
229 
231 {
232  return new FTDistribution1DVoigt(m_omega, m_eta);
233 }
234 
235 double FTDistribution1DVoigt::evaluate(double q) const
236 {
237  double sum_sq = q * q * m_omega * m_omega;
238  return m_eta * std::exp(-sum_sq / 2.0) + (1.0 - m_eta) * 1.0 / (1.0 + sum_sq);
239 }
240 
242 {
243  return (2.0 - m_eta) * m_omega * m_omega;
244 }
245 
246 std::unique_ptr<IDistribution1DSampler> FTDistribution1DVoigt::createSampler() const
247 {
248  // TODO Need to implement 1D Voigt
249 
250  std::ostringstream ostr;
251  ostr << "FTDistribution1DVoigt::createSampler() -> Error in class initialization";
252  ostr << "\n\n Has not been implemented yet...stay tuned!";
253  throw std::runtime_error(ostr.str());
254 }
Defines M_PI and some more mathematical constants.
#define M_PI
Definition: Constants.h:44
Defines interface class IFTDistribution1D, and children thereof.
Defines functions in namespace Math.
NodeMeta nodeMetaUnion(const std::vector< ParaMeta > &base, const NodeMeta &other)
Definition: INode.cpp:23
const double INF
Definition: INode.h:25
Exponential IFTDistribution1D exp(-|omega*x|); its Fourier transform evaluate(q) is a Cauchy-Lorentzi...
double qSecondDerivative() const final
Returns the negative of the second order derivative in q space around q=0.
FTDistribution1DCauchy * clone() const final
std::unique_ptr< IDistribution1DSampler > createSampler() const final
FTDistribution1DCauchy(const std::vector< double > P)
double evaluate(double q) const 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 final
double evaluate(double q) const final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
FTDistribution1DCosine * clone() const final
FTDistribution1DCosine(const std::vector< double > P)
double qSecondDerivative() const 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...
FTDistribution1DGate * clone() const final
FTDistribution1DGate(const std::vector< double > P)
std::unique_ptr< IDistribution1DSampler > createSampler() const final
double qSecondDerivative() const final
Returns the negative of the second order derivative in q space around q=0.
double evaluate(double q) const final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
Gaussian IFTDistribution1D; its Fourier transform evaluate(q) is a Gaussian starting at evaluate(0)=1...
FTDistribution1DGauss(const std::vector< double > P)
std::unique_ptr< IDistribution1DSampler > createSampler() const final
double qSecondDerivative() const final
Returns the negative of the second order derivative in q space around q=0.
FTDistribution1DGauss * clone() const final
double evaluate(double q) const 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...
double qSecondDerivative() const final
Returns the negative of the second order derivative in q space around q=0.
FTDistribution1DTriangle(const std::vector< double > P)
FTDistribution1DTriangle * clone() const final
double evaluate(double q) const final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
std::unique_ptr< IDistribution1DSampler > createSampler() const final
IFTDistribution1D that provides a Fourier transform evaluate(q) in form of a pseudo-Voigt decay funct...
double evaluate(double q) const final
Returns Fourier transform of this distribution; is a decay function starting at evaluate(0)=1.
double qSecondDerivative() const final
Returns the negative of the second order derivative in q space around q=0.
FTDistribution1DVoigt * clone() const final
std::unique_ptr< IDistribution1DSampler > createSampler() const final
FTDistribution1DVoigt(const std::vector< double > P)
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:
Definition: Functions.cpp:53
Definition: filesystem.h:81
Metadata of one model node.
Definition: INode.h:38