mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: Distribution. Removing oldDistribution reference code.
This commit is contained in:
@ -1,479 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "Distribution.H"
|
||||
#include "OFstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(Distribution, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::Distribution::write
|
||||
(
|
||||
const fileName& file,
|
||||
const List<Pair<scalar> >& pairs
|
||||
)
|
||||
{
|
||||
OFstream os(file);
|
||||
|
||||
forAll(pairs, i)
|
||||
{
|
||||
os << pairs[i].first() << ' ' << pairs[i].second() << nl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Distribution::Distribution()
|
||||
:
|
||||
Map<label>(),
|
||||
binWidth_(1)
|
||||
{}
|
||||
|
||||
|
||||
Foam::Distribution::Distribution(const scalar binWidth)
|
||||
:
|
||||
Map<label>(),
|
||||
binWidth_(binWidth)
|
||||
{}
|
||||
|
||||
|
||||
Foam::Distribution::Distribution(const Distribution& d)
|
||||
:
|
||||
Map<label>(static_cast< Map<label> >(d)),
|
||||
binWidth_(d.binWidth())
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Distribution::~Distribution()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::Distribution::totalEntries() const
|
||||
{
|
||||
label sumOfEntries = 0;
|
||||
|
||||
forAllConstIter(Map<label>, *this, iter)
|
||||
{
|
||||
sumOfEntries += iter();
|
||||
|
||||
if (sumOfEntries < 0)
|
||||
{
|
||||
WarningIn("label Distribution::totalEntries()")
|
||||
<< "Accumulated Distribution values total has become negative: "
|
||||
<< "sumOfEntries = " << sumOfEntries
|
||||
<< ". This is most likely to be because too many samples "
|
||||
<< "have been added to the bins and the label has 'rolled "
|
||||
<< "round'. Try Distribution::approxTotalEntries which "
|
||||
<< "returns a scalar." << endl;
|
||||
|
||||
sumOfEntries = -1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sumOfEntries;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::Distribution::approxTotalEntries() const
|
||||
{
|
||||
scalar sumOfEntries = 0;
|
||||
|
||||
forAllConstIter(Map<label>, *this, iter)
|
||||
{
|
||||
sumOfEntries += scalar(iter());
|
||||
}
|
||||
|
||||
return sumOfEntries;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::Distribution::mean() const
|
||||
{
|
||||
scalar runningSum = 0;
|
||||
|
||||
scalar totEnt = approxTotalEntries();
|
||||
|
||||
List<label> keys = toc();
|
||||
|
||||
forAll(keys,k)
|
||||
{
|
||||
label key = keys[k];
|
||||
|
||||
runningSum +=
|
||||
(0.5 + scalar(key))
|
||||
*binWidth_
|
||||
*scalar((*this)[key])
|
||||
/totEnt;
|
||||
}
|
||||
|
||||
return runningSum;
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::Distribution::median()
|
||||
{
|
||||
// From:
|
||||
// http://mathworld.wolfram.com/StatisticalMedian.html
|
||||
// The statistical median is the value of the Distribution variable
|
||||
// where the cumulative Distribution = 0.5.
|
||||
|
||||
scalar median = 0.0;
|
||||
|
||||
scalar runningSum = 0.0;
|
||||
|
||||
List<Pair<scalar> > normDist(normalised());
|
||||
|
||||
if (normDist.size())
|
||||
{
|
||||
if (normDist.size() == 1)
|
||||
{
|
||||
median = normDist[0].first();
|
||||
}
|
||||
else if
|
||||
(
|
||||
normDist.size() > 1
|
||||
&& normDist[0].second()*binWidth_ > 0.5
|
||||
)
|
||||
{
|
||||
scalar xk = normDist[1].first();
|
||||
scalar xkm1 = normDist[0].first();
|
||||
scalar Sk =
|
||||
(normDist[0].second() + normDist[1].second())*binWidth_;
|
||||
scalar Skm1 = normDist[0].second()*binWidth_;
|
||||
|
||||
median = (0.5 - Skm1)*(xk - xkm1)/(Sk - Skm1) + xkm1;
|
||||
}
|
||||
else
|
||||
{
|
||||
label lastNonZeroIndex = 0;
|
||||
|
||||
forAll(normDist,nD)
|
||||
{
|
||||
if (runningSum + (normDist[nD].second()*binWidth_) > 0.5)
|
||||
{
|
||||
scalar xk = normDist[nD].first();
|
||||
scalar xkm1 = normDist[lastNonZeroIndex].first();
|
||||
scalar Sk = runningSum + (normDist[nD].second()*binWidth_);
|
||||
scalar Skm1 = runningSum;
|
||||
|
||||
median = (0.5 - Skm1)*(xk - xkm1)/(Sk - Skm1) + xkm1;
|
||||
|
||||
break;
|
||||
}
|
||||
else if (normDist[nD].second() > 0.0)
|
||||
{
|
||||
runningSum += normDist[nD].second()*binWidth_;
|
||||
|
||||
lastNonZeroIndex = nD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return median;
|
||||
}
|
||||
|
||||
|
||||
void Foam::Distribution::add(const scalar valueToAdd)
|
||||
{
|
||||
iterator iter(this->begin());
|
||||
|
||||
label n = label(valueToAdd/binWidth_) - label(neg(valueToAdd/binWidth_));
|
||||
|
||||
iter = find(n);
|
||||
|
||||
if (iter == this->end())
|
||||
{
|
||||
this->insert(n,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*this)[n]++;
|
||||
}
|
||||
|
||||
if ((*this)[n] < 0)
|
||||
{
|
||||
FatalErrorIn("Distribution::add(const scalar valueToAdd)")
|
||||
<< "Accumulated Distribution value has become negative: "
|
||||
<< "bin = " << (0.5 + scalar(n)) * binWidth_
|
||||
<< ", value = " << (*this)[n]
|
||||
<< ". This is most likely to be because too many samples "
|
||||
<< "have been added to a bin and the label has 'rolled round'"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::Distribution::add(const label valueToAdd)
|
||||
{
|
||||
add(scalar(valueToAdd));
|
||||
}
|
||||
|
||||
|
||||
void Foam::Distribution::insertMissingKeys()
|
||||
{
|
||||
iterator iter(this->begin());
|
||||
|
||||
List<label> keys = toc();
|
||||
|
||||
sort(keys);
|
||||
|
||||
if (keys.size())
|
||||
{
|
||||
for (label k = keys[0]; k < keys[keys.size()-1]; k++)
|
||||
{
|
||||
iter = find(k);
|
||||
|
||||
if (iter == this->end())
|
||||
{
|
||||
this->insert(k,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::Pair<Foam::scalar> > Foam::Distribution::normalised()
|
||||
{
|
||||
scalar totEnt = approxTotalEntries();
|
||||
|
||||
insertMissingKeys();
|
||||
|
||||
List<label> keys = toc();
|
||||
|
||||
sort(keys);
|
||||
|
||||
List<Pair<scalar> > normDist(size());
|
||||
|
||||
forAll(keys,k)
|
||||
{
|
||||
label key = keys[k];
|
||||
|
||||
normDist[k].first() = (0.5 + scalar(key))*binWidth_;
|
||||
|
||||
normDist[k].second() = scalar((*this)[key])/totEnt/binWidth_;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "totEnt: " << totEnt << endl;
|
||||
}
|
||||
|
||||
return normDist;
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::Pair<Foam::scalar> > Foam::Distribution::normalisedMinusMean()
|
||||
{
|
||||
return normalisedShifted(mean());
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::Pair<Foam::scalar> > Foam::Distribution::normalisedShifted
|
||||
(
|
||||
scalar shiftValue
|
||||
)
|
||||
{
|
||||
List<Pair<scalar> > oldDist(normalised());
|
||||
|
||||
List<Pair<scalar> > newDist(oldDist.size());
|
||||
|
||||
forAll(oldDist,u)
|
||||
{
|
||||
oldDist[u].first() -= shiftValue;
|
||||
}
|
||||
|
||||
scalar lowestOldBin = oldDist[0].first()/binWidth_ - 0.5;
|
||||
|
||||
label lowestNewKey = label
|
||||
(
|
||||
lowestOldBin + 0.5*sign(lowestOldBin)
|
||||
);
|
||||
|
||||
scalar interpolationStartDirection =
|
||||
sign(scalar(lowestNewKey) - lowestOldBin);
|
||||
|
||||
label newKey = lowestNewKey;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< shiftValue
|
||||
<< nl << lowestOldBin
|
||||
<< nl << lowestNewKey
|
||||
<< nl << interpolationStartDirection
|
||||
<< endl;
|
||||
|
||||
scalar checkNormalisation = 0;
|
||||
|
||||
forAll (oldDist, oD)
|
||||
{
|
||||
checkNormalisation += oldDist[oD].second()*binWidth_;
|
||||
}
|
||||
|
||||
Info<< "Initial normalisation = " << checkNormalisation << endl;
|
||||
}
|
||||
|
||||
forAll(oldDist,u)
|
||||
{
|
||||
newDist[u].first() = (0.5 + scalar(newKey)) * binWidth_;
|
||||
|
||||
if (interpolationStartDirection < 0)
|
||||
{
|
||||
if (u == 0)
|
||||
{
|
||||
newDist[u].second() =
|
||||
(0.5 + scalar(newKey))*oldDist[u].second()
|
||||
- oldDist[u].second()
|
||||
*(oldDist[u].first() - binWidth_)/ binWidth_;
|
||||
}
|
||||
else
|
||||
{
|
||||
newDist[u].second() =
|
||||
(0.5 + scalar(newKey))
|
||||
*(oldDist[u].second() - oldDist[u-1].second())
|
||||
+
|
||||
(
|
||||
oldDist[u-1].second()*oldDist[u].first()
|
||||
- oldDist[u].second()*oldDist[u-1].first()
|
||||
)
|
||||
/binWidth_;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (u == oldDist.size() - 1)
|
||||
{
|
||||
newDist[u].second() =
|
||||
(0.5 + scalar(newKey))*-oldDist[u].second()
|
||||
+ oldDist[u].second()*(oldDist[u].first() + binWidth_)
|
||||
/binWidth_;
|
||||
}
|
||||
else
|
||||
{
|
||||
newDist[u].second() =
|
||||
(0.5 + scalar(newKey))
|
||||
*(oldDist[u+1].second() - oldDist[u].second())
|
||||
+
|
||||
(
|
||||
oldDist[u].second()*oldDist[u+1].first()
|
||||
- oldDist[u+1].second()*oldDist[u].first()
|
||||
)
|
||||
/binWidth_;
|
||||
}
|
||||
}
|
||||
|
||||
newKey++;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
scalar checkNormalisation = 0;
|
||||
|
||||
forAll (newDist, nD)
|
||||
{
|
||||
checkNormalisation += newDist[nD].second()*binWidth_;
|
||||
}
|
||||
|
||||
Info<< "Shifted normalisation = " << checkNormalisation << endl;
|
||||
}
|
||||
|
||||
return newDist;
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::Pair<Foam::scalar> > Foam::Distribution::raw()
|
||||
{
|
||||
insertMissingKeys();
|
||||
|
||||
List<label> keys = toc();
|
||||
|
||||
sort(keys);
|
||||
|
||||
List<Pair<scalar> > rawDist(size());
|
||||
|
||||
forAll(keys,k)
|
||||
{
|
||||
label key = keys[k];
|
||||
|
||||
rawDist[k].first() = (0.5 + scalar(key))*binWidth_;
|
||||
|
||||
rawDist[k].second() = scalar((*this)[key]);
|
||||
}
|
||||
|
||||
return rawDist;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::Distribution::operator=(const Distribution& rhs)
|
||||
{
|
||||
// Check for assignment to self
|
||||
if (this == &rhs)
|
||||
{
|
||||
FatalErrorIn("Distribution::operator=(const Distribution&)")
|
||||
<< "Attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
Map<label>::operator=(rhs);
|
||||
|
||||
binWidth_ = rhs.binWidth();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const Distribution& d)
|
||||
{
|
||||
os << d.binWidth_
|
||||
<< static_cast<const Map<label>&>(d);
|
||||
|
||||
// Check state of Ostream
|
||||
os.check
|
||||
(
|
||||
"Ostream& operator<<(Ostream&, "
|
||||
"const Distribution&)"
|
||||
);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,151 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::Distribution
|
||||
|
||||
Description
|
||||
Accumulating histogram of values.
|
||||
Specified bin resolution automatic generation of bins.
|
||||
|
||||
SourceFiles
|
||||
DistributionI.H
|
||||
Distribution.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Distribution_H
|
||||
#define Distribution_H
|
||||
|
||||
#include "Map.H"
|
||||
#include "Pair.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Distribution Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class Distribution
|
||||
:
|
||||
public Map<label>
|
||||
{
|
||||
// Private data
|
||||
|
||||
scalar binWidth_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
|
||||
TypeName("Distribution");
|
||||
|
||||
// Static functions
|
||||
|
||||
//- Write to file, for a Distribution object 'dist' use, for
|
||||
// example:
|
||||
// Distribution::write("outputFile", dist.normalised());
|
||||
static void write
|
||||
(
|
||||
const fileName& file,
|
||||
const List<Pair<scalar> >& pairs
|
||||
);
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
Distribution();
|
||||
|
||||
//- Construct from binWidth
|
||||
Distribution(const scalar binWidth);
|
||||
|
||||
//- Construct as copy
|
||||
Distribution(const Distribution&);
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~Distribution();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
label totalEntries() const;
|
||||
|
||||
scalar approxTotalEntries() const;
|
||||
|
||||
scalar mean() const;
|
||||
|
||||
scalar median();
|
||||
|
||||
//- Add a value to the appropriate bin of the Distribution.
|
||||
void add(const scalar valueToAdd);
|
||||
|
||||
void add(const label valueToAdd);
|
||||
|
||||
void insertMissingKeys();
|
||||
|
||||
List<Pair<scalar> > normalised();
|
||||
|
||||
List<Pair<scalar> > normalisedMinusMean();
|
||||
|
||||
List<Pair<scalar> > normalisedShifted(scalar shiftValue);
|
||||
|
||||
List<Pair<scalar> > raw();
|
||||
|
||||
|
||||
// Access
|
||||
|
||||
inline scalar binWidth() const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
void operator=(const Distribution&);
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Ostream& operator<<(Ostream&, const Distribution&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "DistributionI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,35 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2008-2009 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::scalar Foam::Distribution::binWidth() const
|
||||
{
|
||||
return binWidth_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user