mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Initial templated Distribution class where a distribution is
accumulated for each component of the template parameter.
This commit is contained in:
81
applications/test/Distribution/DistributionTest.C
Normal file
81
applications/test/Distribution/DistributionTest.C
Normal file
@ -0,0 +1,81 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Application
|
||||
DistributionTest
|
||||
|
||||
Description
|
||||
Test the Distribution class
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "vector.H"
|
||||
#include "labelVector.H"
|
||||
#include "tensor.H"
|
||||
#include "Distribution.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Distribution<scalar> dS(scalar(3.0));
|
||||
Distribution<vector> dV(vector(0.1, 0.24, 0.18));
|
||||
Distribution<labelVector> dLV(labelVector(2,3,4));
|
||||
|
||||
dS.add(1.0);
|
||||
dS.add(2.0);
|
||||
dS.add(12.0);
|
||||
dS.add(1.3);
|
||||
|
||||
Info<< dS << nl << dS.raw() << endl;
|
||||
|
||||
vector vA(1.2, 1.3, 1.1);
|
||||
vector vB(1.3, 1.5, 1.6);
|
||||
vector vC(0.5, 5.3, 1.1);
|
||||
|
||||
dV.add(vA);
|
||||
dV.add(vB);
|
||||
dV.add(vC);
|
||||
|
||||
Info<< dV << nl << dV.raw() << endl;
|
||||
|
||||
labelVector lVA(6, 8, 11);
|
||||
labelVector lVB(-12, -3, 6);
|
||||
labelVector lVC(-4, -2, 5);
|
||||
|
||||
dLV.add(lVA);
|
||||
dLV.add(lVB);
|
||||
dLV.add(lVC);
|
||||
|
||||
Info<< dLV << nl << dLV.raw() << endl;
|
||||
|
||||
Info<< nl << "End" << nl << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
3
applications/test/Distribution/Make/files
Normal file
3
applications/test/Distribution/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
DistributionTest.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/DistributionTest
|
||||
3
applications/test/Distribution/Make/options
Normal file
3
applications/test/Distribution/Make/options
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
|
||||
|
||||
@ -377,7 +377,7 @@ DebugSwitches
|
||||
displacementLaplacian 0;
|
||||
displacementSBRStress 0;
|
||||
distanceSurface 0;
|
||||
distribution 0;
|
||||
Distribution 0;
|
||||
downwind 0;
|
||||
dragModel 0;
|
||||
duplicatePoints 0;
|
||||
|
||||
@ -0,0 +1,227 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2009-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"
|
||||
|
||||
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::Distribution<Type>::Distribution()
|
||||
:
|
||||
List< Map<label> >(pTraits<Type>::nComponents),
|
||||
binWidth_(pTraits<Type>::one)
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::Distribution<Type>::Distribution(const Type& binWidth)
|
||||
:
|
||||
List< Map<label> >(pTraits<Type>::nComponents),
|
||||
binWidth_(binWidth)
|
||||
{}
|
||||
|
||||
|
||||
// template<class Type>
|
||||
// Foam::Distribution<Type>::Distribution
|
||||
// (
|
||||
// const cmptType& binWidth
|
||||
// )
|
||||
// :
|
||||
// List< Map<label> >(pTraits<Type>::nComponents),
|
||||
// binWidth_(binWidth*pTraits<Type>::one)
|
||||
// {}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::Distribution<Type>::Distribution(const Distribution<Type>& d)
|
||||
:
|
||||
List< Map<label> >(static_cast< const List< Map<label> >& >(d)),
|
||||
binWidth_(d.binWidth())
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::Distribution<Type>::~Distribution()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::Distribution<Type>::add(const Type& valueToAdd)
|
||||
{
|
||||
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; cmpt++)
|
||||
{
|
||||
Map<label>& cmptDistribution = (*this)[cmpt];
|
||||
|
||||
Map<label>::iterator iter(cmptDistribution.begin());
|
||||
|
||||
label n =
|
||||
label(component(valueToAdd, cmpt)/component(binWidth_, cmpt))
|
||||
- label(neg(component(valueToAdd, cmpt)/component(binWidth_, cmpt)));
|
||||
|
||||
iter = cmptDistribution.find(n);
|
||||
|
||||
if (iter == cmptDistribution.end())
|
||||
{
|
||||
cmptDistribution.insert(n,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmptDistribution[n]++;
|
||||
}
|
||||
|
||||
if (cmptDistribution[n] < 0)
|
||||
{
|
||||
FatalErrorIn("Distribution::add(const scalar valueToAdd)")
|
||||
<< "Accumulated Distribution value has become negative: "
|
||||
<< "bin = " << (0.5 + scalar(n))*component(binWidth_, cmpt)
|
||||
<< ", value = " << cmptDistribution[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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::Distribution<Type>::insertMissingKeys()
|
||||
{
|
||||
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; cmpt++)
|
||||
{
|
||||
Map<label>& cmptDistribution = (*this)[cmpt];
|
||||
|
||||
Map<label>::iterator iter(cmptDistribution.begin());
|
||||
|
||||
List<label> keys = cmptDistribution.sortedToc();
|
||||
|
||||
if (keys.size())
|
||||
{
|
||||
for (label k = keys[0]; k < keys[keys.size()-1]; k++)
|
||||
{
|
||||
iter = cmptDistribution.find(k);
|
||||
|
||||
if (iter == cmptDistribution.end())
|
||||
{
|
||||
cmptDistribution.insert(k,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::List< Foam::List< Foam::Pair<Foam::scalar> > >Foam::
|
||||
Distribution<Type>::raw()
|
||||
{
|
||||
List< List < Pair<scalar> > > rawDistributions(pTraits<Type>::nComponents);
|
||||
|
||||
insertMissingKeys();
|
||||
|
||||
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; cmpt++)
|
||||
{
|
||||
Map<label>& cmptDistribution = (*this)[cmpt];
|
||||
|
||||
List<label> keys = cmptDistribution.sortedToc();
|
||||
|
||||
List<Pair<scalar> >& rawDist = rawDistributions[cmpt];
|
||||
|
||||
rawDist.setSize(keys.size());
|
||||
|
||||
forAll(keys,k)
|
||||
{
|
||||
label key = keys[k];
|
||||
|
||||
rawDist[k].first() = (0.5 + scalar(key))*component(binWidth_, cmpt);
|
||||
|
||||
rawDist[k].second() = scalar(cmptDistribution[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return rawDistributions;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::Distribution<Type>::operator=
|
||||
(
|
||||
const Distribution<Type>& rhs
|
||||
)
|
||||
{
|
||||
// Check for assignment to self
|
||||
if (this == &rhs)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Foam::Distribution<Type>::operator="
|
||||
"(const Foam::Distribution<Type>&)"
|
||||
) << "Attempted assignment to self"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
List< Map<label> >::operator=(rhs);
|
||||
|
||||
binWidth_ = rhs.binWidth();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::Ostream& Foam::operator<<
|
||||
(
|
||||
Ostream& os,
|
||||
const Distribution<Type>& d
|
||||
)
|
||||
{
|
||||
os << d.binWidth_
|
||||
<< static_cast<const List< Map<label> >& >(d);
|
||||
|
||||
// Check state of Ostream
|
||||
os.check
|
||||
(
|
||||
"Ostream& operator<<(Ostream&, "
|
||||
"const Distribution&)"
|
||||
);
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,173 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2009-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 component values.
|
||||
Specified bin resolution automatic generation of bins.
|
||||
|
||||
SourceFiles
|
||||
DistributionI.H
|
||||
Distribution.C
|
||||
DistributionIO.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Distribution_H
|
||||
#define Distribution_H
|
||||
|
||||
#include "Map.H"
|
||||
#include "Pair.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<class Type>
|
||||
class Distribution;
|
||||
|
||||
template<class Type>
|
||||
Ostream& operator<<(Ostream&, const Distribution<Type>&);
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class Distribution Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class Distribution
|
||||
:
|
||||
public List< Map<label> >
|
||||
{
|
||||
// Private data
|
||||
|
||||
Type binWidth_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
// //- Disallow default bitwise copy construct
|
||||
// Distribution(const Distribution<Type>&);
|
||||
|
||||
// //- Disallow default bitwise assignment
|
||||
// void operator=(const Distribution<Type>&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Component type
|
||||
typedef typename pTraits<Type>::cmptType cmptType;
|
||||
|
||||
|
||||
// Static data members
|
||||
|
||||
// static void write
|
||||
// (
|
||||
// const fileName& file,
|
||||
// const List<Pair<scalar> >& pairs
|
||||
// );
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
Distribution();
|
||||
|
||||
//- Construct from separate binWidth for each component
|
||||
Distribution(const Type& binWidth);
|
||||
|
||||
// //- Construct from single binWidth for each component
|
||||
// Distribution(const cmptType& binWidth);
|
||||
|
||||
//- Construct as copy
|
||||
Distribution(const Distribution& d);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~Distribution();
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Type totalEntries() const;
|
||||
|
||||
// Type mean() const;
|
||||
|
||||
// Type median();
|
||||
|
||||
void add(const Type& valueToAdd);
|
||||
|
||||
void insertMissingKeys();
|
||||
|
||||
// List<Pair<scalar> > normalised();
|
||||
|
||||
// List<Pair<scalar> > normalisedMinusMean();
|
||||
|
||||
// List<Pair<scalar> > normalisedShifted(scalar shift Value);
|
||||
|
||||
List< List < Pair<scalar> > > raw();
|
||||
|
||||
// Access
|
||||
|
||||
inline const Type& binWidth() const;
|
||||
|
||||
// Member Operators
|
||||
|
||||
void operator=(const Distribution<Type>&);
|
||||
|
||||
|
||||
// Friend Functions
|
||||
|
||||
// Friend Operators
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Ostream& operator<< <Type>
|
||||
(
|
||||
Ostream&,
|
||||
const Distribution<Type>&
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "DistributionI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "Distribution.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2009-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 * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
inline const Type& Foam::Distribution<Type>::binWidth() const
|
||||
{
|
||||
return binWidth_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,479 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,151 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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