ENH: distributionModels: replace input variable names with de facto conventions

Previous naming conventions for input variables in the
normal, multiNormal, RosinRammler, and massRosinRammler
distributions were heuristic and did not reflect
the de facto conventions being used in statistics.
This commit is contained in:
Kutalmis Bercin
2021-08-24 10:39:35 +01:00
parent 89289b0716
commit 07cd88abd0
8 changed files with 115 additions and 75 deletions

View File

@ -49,7 +49,7 @@ Foam::distributionModels::RosinRammler::RosinRammler
)
:
distributionModel(typeName, dict, rndGen),
d_(distributionModelDict_.get<scalar>("d")),
lambda_(distributionModelDict_.getCompat<scalar>("lambda", {{"d", 2112}})),
n_(distributionModelDict_.get<scalar>("n"))
{
const word parcelBasisType =
@ -63,11 +63,11 @@ Foam::distributionModels::RosinRammler::RosinRammler
<< endl;
}
if (d_ < VSMALL || n_ < VSMALL)
if (lambda_ < VSMALL || n_ < VSMALL)
{
FatalErrorInFunction
<< "Scale/Shape parameter cannot be equal to or less than zero:"
<< " d = " << d_
<< " lambda = " << lambda_
<< " n = " << n_
<< exit(FatalError);
}
@ -79,7 +79,7 @@ Foam::distributionModels::RosinRammler::RosinRammler
Foam::distributionModels::RosinRammler::RosinRammler(const RosinRammler& p)
:
distributionModel(p),
d_(p.d_),
lambda_(p.lambda_),
n_(p.n_)
{}
@ -88,16 +88,16 @@ Foam::distributionModels::RosinRammler::RosinRammler(const RosinRammler& p)
Foam::scalar Foam::distributionModels::RosinRammler::sample() const
{
const scalar minValueByDPowN = pow(minValue_/d_, n_);
const scalar K = 1 - exp(- pow(maxValue_/d_, n_) + minValueByDPowN);
const scalar minValueByDPowN = pow(minValue_/lambda_, n_);
const scalar K = 1 - exp(- pow(maxValue_/lambda_, n_) + minValueByDPowN);
const scalar y = rndGen_.sample01<scalar>();
return d_*pow(minValueByDPowN - log(1 - K*y), 1/n_);
return lambda_*pow(minValueByDPowN - log(1 - K*y), 1/n_);
}
Foam::scalar Foam::distributionModels::RosinRammler::meanValue() const
{
return d_;
return lambda_;
}

View File

@ -63,13 +63,11 @@ class RosinRammler
{
// Private Data
// Model coefficients
//- Scale parameter
scalar lambda_;
//- Scale parameter
scalar d_;
//- Shape parameter
scalar n_;
//- Shape parameter
scalar n_;
public:

View File

@ -50,14 +50,14 @@ Foam::distributionModels::massRosinRammler::massRosinRammler
)
:
distributionModel(typeName, dict, rndGen),
d_(distributionModelDict_.get<scalar>("d")),
lambda_(distributionModelDict_.getCompat<scalar>("lambda", {{"d", 2112}})),
n_(distributionModelDict_.get<scalar>("n"))
{
if (d_ < VSMALL || n_ < VSMALL)
if (lambda_ < VSMALL || n_ < VSMALL)
{
FatalErrorInFunction
<< "Scale/Shape parameter cannot be equal to or less than zero:"
<< " d = " << d_
<< " lambda = " << lambda_
<< " n = " << n_
<< exit(FatalError);
}
@ -72,7 +72,7 @@ Foam::distributionModels::massRosinRammler::massRosinRammler
)
:
distributionModel(p),
d_(p.d_),
lambda_(p.lambda_),
n_(p.n_)
{}
@ -89,7 +89,7 @@ Foam::scalar Foam::distributionModels::massRosinRammler::sample() const
const scalar a = 3/n_ + 1;
const scalar P = rndGen_.sample01<scalar>();
const scalar x = Math::invIncGamma(a, P);
d = d_*pow(x, 1/n_);
d = lambda_*pow(x, 1/n_);
} while (d < minValue_ || d > maxValue_);
return d;
@ -98,7 +98,7 @@ Foam::scalar Foam::distributionModels::massRosinRammler::sample() const
Foam::scalar Foam::distributionModels::massRosinRammler::meanValue() const
{
return d_;
return lambda_;
}

View File

@ -74,7 +74,7 @@ class massRosinRammler
// Private Data
//- Scale parameter
scalar d_;
scalar lambda_;
//- Shape parameter
scalar n_;

View File

@ -49,35 +49,67 @@ Foam::distributionModels::multiNormal::multiNormal
)
:
distributionModel(typeName, dict, rndGen),
range_(maxValue_ - minValue_),
expectation_(distributionModelDict_.lookup("expectation")),
variance_(distributionModelDict_.lookup("variance")),
strength_(distributionModelDict_.lookup("strength"))
mu_
(
distributionModelDict_.lookupCompat
(
"mu",
{{"expectation", 2112}}
)
),
sigma_
(
distributionModelDict_.lookupCompat
(
"sigma",
{{"variance", 2112}}
)
),
weight_
(
distributionModelDict_.lookupCompat
(
"weight",
{{"strength", 2112}}
)
)
{
check();
scalar sMax = 0;
label n = strength_.size();
for (label i=0; i<n; i++)
scalar sum = 0;
for (label i = 0; i < weight_.size(); ++i)
{
scalar x = expectation_[i];
scalar s = strength_[i];
for (label j=0; j<n; j++)
if (i > 0 && weight_[i] < weight_[i-1])
{
if (i!=j)
{
scalar x2 = (x - expectation_[j])/variance_[j];
scalar y = exp(-0.5*x2*x2);
s += strength_[j]*y;
}
FatalErrorInFunction
<< type() << "distribution: "
<< "Weights must be specified in a monotonic order." << nl
<< "Please see the row i = " << i << nl
<< "weight[i-1] = " << weight_[i-1] << nl
<< "weight[i] = " << weight_[i]
<< exit(FatalError);
}
sMax = max(sMax, s);
sum += weight_[i];
}
for (label i=0; i<n; i++)
if (sum < VSMALL)
{
strength_[i] /= sMax;
FatalErrorInFunction
<< type() << "distribution: "
<< "The sum of weights cannot be zero." << nl
<< "weight = " << weight_
<< exit(FatalError);
}
for (label i = 1; i < weight_.size(); ++i)
{
weight_[i] += weight_[i-1];
}
for (auto& w : weight_)
{
w /= sum;
}
}
@ -85,10 +117,9 @@ Foam::distributionModels::multiNormal::multiNormal
Foam::distributionModels::multiNormal::multiNormal(const multiNormal& p)
:
distributionModel(p),
range_(p.range_),
expectation_(p.expectation_),
variance_(p.variance_),
strength_(p.strength_)
mu_(p.mu_),
sigma_(p.sigma_),
weight_(p.weight_)
{}
@ -98,7 +129,7 @@ Foam::scalar Foam::distributionModels::multiNormal::sample() const
{
scalar y = 0;
scalar x = 0;
label n = expectation_.size();
label n = mu_.size();
bool success = false;
while (!success)
@ -109,9 +140,9 @@ Foam::scalar Foam::distributionModels::multiNormal::sample() const
for (label i=0; i<n; i++)
{
scalar nu = expectation_[i];
scalar sigma = variance_[i];
scalar s = strength_[i];
scalar nu = mu_[i];
scalar sigma = sigma_[i];
scalar s = weight_[i];
scalar v = (x - nu)/sigma;
p += s*exp(-0.5*v*v);
}
@ -128,10 +159,10 @@ Foam::scalar Foam::distributionModels::multiNormal::sample() const
Foam::scalar Foam::distributionModels::multiNormal::meanValue() const
{
scalar mean = 0.0;
forAll(strength_, i)
scalar mean = 0;
forAll(weight_, i)
{
mean += strength_[i]*expectation_[i];
mean += weight_[i]*mu_[i];
}
return mean;

View File

@ -62,15 +62,15 @@ class multiNormal
{
// Private Data
//- Distribution range
scalar range_;
//- List of means of the parent general normal distributions
List<scalar> mu_;
//- List of standard deviations of
//- the parent general normal distributions
List<scalar> sigma_;
// Model coefficients
List<scalar> expectation_;
List<scalar> variance_;
List<scalar> strength_;
//- List of weights of a given distribution in the mixture
List<scalar> weight_;
public:

View File

@ -50,15 +50,28 @@ Foam::distributionModels::normal::normal
)
:
distributionModel(typeName, dict, rndGen),
expectation_(distributionModelDict_.get<scalar>("expectation")),
variance_(distributionModelDict_.get<scalar>("variance")),
a_(0.147)
mu_
(
distributionModelDict_.getCompat<scalar>
(
"mu",
{{"expectation", 2112}}
)
),
sigma_
(
distributionModelDict_.getCompat<scalar>
(
"sigma",
{{"variance", 2112}}
)
)
{
if (mag(variance_) == 0)
if (mag(sigma_) == 0)
{
FatalErrorInFunction
<< "Standard deviation cannot be zero." << nl
<< " variance = " << variance_ << nl
<< " sigma = " << sigma_ << nl
<< exit(FatalError);
}
@ -69,9 +82,8 @@ Foam::distributionModels::normal::normal
Foam::distributionModels::normal::normal(const normal& p)
:
distributionModel(p),
expectation_(p.expectation_),
variance_(p.variance_),
a_(p.a_)
mu_(p.mu_),
sigma_(p.sigma_)
{}
@ -80,11 +92,11 @@ Foam::distributionModels::normal::normal(const normal& p)
Foam::scalar Foam::distributionModels::normal::sample() const
{
scalar a = erf((minValue_ - expectation_)/variance_);
scalar b = erf((maxValue_ - expectation_)/variance_);
scalar a = erf((minValue_ - mu_)/sigma_);
scalar b = erf((maxValue_ - mu_)/sigma_);
scalar y = rndGen_.sample01<scalar>();
scalar x = Math::erfInv(y*(b - a) + a)*variance_ + expectation_;
scalar x = Math::erfInv(y*(b - a) + a)*sigma_ + mu_;
// Note: numerical approximation of the inverse function yields slight
// inaccuracies
@ -97,7 +109,7 @@ Foam::scalar Foam::distributionModels::normal::sample() const
Foam::scalar Foam::distributionModels::normal::meanValue() const
{
return expectation_;
return mu_;
}

View File

@ -63,12 +63,11 @@ class normal
{
// Private Data
// Model coefficients
//- Mean of the parent general normal distribution
scalar mu_;
scalar expectation_;
scalar variance_;
scalar a_;
//- Standard deviation of the parent general normal distribution
scalar sigma_;
public: