Commit 7d24a4b2 authored by Mathias Goldau's avatar Mathias Goldau

[ADD] A simple uniform histogram

parent a8affea6
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <algorithm>
#include <iomanip>
#include <numeric>
#include "WAssert.h"
#include "WHistogram.h"
#include "WLimits.h"
#include "WLogger.h"
WHistogram::WHistogram( double min, double max, size_t size )
: m_bins( size, 0 ),
m_min( min ),
m_max( max )
{
if( min > max )
{
std::swap( m_min, m_max );
}
WAssert( m_bins.size() > 0, "Error: A histogram with a size of 0 does not make any sense" );
m_intervalWidth = std::abs( m_min - m_max ) / m_bins.size();
}
WHistogram::~WHistogram()
{
}
void WHistogram::insert( double value )
{
if( value > m_max || value < m_min )
{
wlog::warn( "WHistogram" ) << std::scientific << std::setprecision( 16 ) << "Inserted value out of bounds, thread: "
<< value << " as min, resp. max: " << m_min << "," << m_max;
return; // value = ( value > m_max ? m_max : m_min );
}
if( value == m_max )
{
value = m_max - wlimits::DBL_EPS;
}
m_bins.at( static_cast< size_t >( std::abs( value - m_min ) / m_intervalWidth ) )++;
}
size_t WHistogram::binSize() const
{
return m_bins.size();
}
size_t WHistogram::valuesSize() const
{
return std::accumulate( m_bins.begin(), m_bins.end(), 0 );
}
size_t WHistogram::operator[]( size_t index ) const
{
if( index >= m_bins.size() )
{
wlog::error( "WHistogram" ) << index << "th interval is not available, there are only: " << m_bins.size();
return 0;
}
return m_bins[ index ];
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WHISTOGRAM_H
#define WHISTOGRAM_H
#include <vector>
/**
* Container which associate values with (uniform width) bins (aka intervals or buckets).
*/
class WHistogram
{
public:
/**
* Default constructor.
*
* \param min
* \param max
* \param size
*/
WHistogram( double min, double max, size_t size = 1000 );
/**
* Default destructor.
*/
~WHistogram();
/**
* Inserts a given value within the given range (min, max) into exactly one bin and increment its size.
*
* \param value Value to insert.
*/
void insert( double value );
/**
* Computes number of invervals.
*
* \return Number of intervals.
*/
size_t binSize() const;
/**
* Computes the number of inserted values so far.
*
* \return Number of values so far.
*/
size_t valuesSize() const;
/**
* LooksUp how many elements are in this bin with the given index.
*
* \param index The bin number to look up for
*
* \return Number of values associated with this interval.
*/
size_t operator[]( size_t index ) const;
protected:
private:
/**
* Bins to associate with the values. Each bin has the width of m_intervalWidth;
*/
std::vector< size_t > m_bins;
/**
* Minimal value
*/
double m_min;
/**
* Maximal value
*/
double m_max;
/**
* The width of an interval is precomputed to save performance.
*/
double m_intervalWidth;
};
#endif // WHISTOGRAM_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WHISTOGRAM_TEST_H
#define WHISTOGRAM_TEST_H
#include <cxxtest/TestSuite.h>
#include "../WHistogram.h"
#include "../WLimits.h"
#include "../WLogger.h"
static WLogger logger;
/**
* Unit tests the WHistogram class.
*/
class WHistogramTest : public CxxTest::TestSuite
{
public:
/**
* Check when nothing was inserted every thing is empty.
*/
void testInitialization( void )
{
WHistogram h( 0.0, 1.0 );
TS_ASSERT_EQUALS( h.binSize(), 1000 );
TS_ASSERT_EQUALS( h.valuesSize(), 0 );
}
/**
* Check normal insertion inside the min max boundaries.
*/
void testInsert( void )
{
WHistogram h( 0.0, 1.0 );
h.insert( 0.7234 );
TS_ASSERT_EQUALS( h.binSize(), 1000 );
TS_ASSERT_EQUALS( h.valuesSize(), 1 );
TS_ASSERT_EQUALS( h[723], 1 );
}
/**
* If the value is directly on the borderline it counts to the right interval.
*/
void testInsertOnIntervalBorder( void )
{
WHistogram h( 0.0, 1.0 );
h.insert( 0.001 );
TS_ASSERT_EQUALS( h[1], 1 );
h.insert( 0.0039999 );
TS_ASSERT_EQUALS( h[3], 1 );
h.insert( 0.0070001 );
TS_ASSERT_EQUALS( h[7], 1 );
}
/**
* If the minimum is inserted the first bin should be incremented.
*/
void testInsertMin( void )
{
WHistogram h( 0.0, 1.0 );
h.insert( 0.0 );
TS_ASSERT_EQUALS( h[0], 1 );
TS_ASSERT_EQUALS( h[1], 0 );
}
/**
* If the maximum is inserted the right most interval is used.
*/
void testInsertMax( void )
{
WHistogram h( 0.0, 1.0 );
h.insert( 0.0 );
h.insert( 1.0 );
TS_ASSERT_EQUALS( h[999], 1 );
TS_ASSERT_EQUALS( h[0], 1 );
}
/**
* If above the maximum values are inserted a warning should be printed and nothing should happen.
*/
void testInsertOutOfBounds( void )
{
WHistogram h( 0.0, 1.0 );
h.insert( 1.0 + wlimits::DBL_EPS );
h.insert( 0.0 - wlimits::DBL_EPS );
for( size_t i = 0; i < h.binSize(); ++i )
{
TS_ASSERT_EQUALS( h[i], 0 );
}
}
/**
* For each insert this number should increase by one.
*/
void testOperatorToGetNumberOfElementsInsideTheBin( void )
{
WHistogram h( 0.0, 1.0 );
for( size_t i = 0; i < h.binSize(); ++i )
{
TS_ASSERT_EQUALS( h[i], 0 );
}
h.insert( 0.0 );
h.insert( 0.0 );
TS_ASSERT_EQUALS( h.valuesSize(), 2 );
}
};
#endif // WHISTOGRAM_TEST_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment