ENH: Distribution. Removing oldDistribution reference code.

This commit is contained in:
graham
2010-02-10 18:31:01 +00:00
parent 867f419731
commit 93dd3050b1
3 changed files with 0 additions and 665 deletions

View File

@ -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;
}
// ************************************************************************* //

View File

@ -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
// ************************************************************************* //

View File

@ -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_;
}
// ************************************************************************* //