Commit ff304736 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[MERGE] - took nice new histogram class from branch rfrohl in default

parents f863e5aa 934c0cfb
......@@ -43,17 +43,16 @@ WDataSetScalar::WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
WAssert( newValueSet->size() == newGrid->size(), "Number of values unequal number of positions in grid." );
WAssert( newValueSet->order() == 0, "The value set does not contain scalars." );
double max = wlimits::MIN_DOUBLE;
double min = wlimits::MAX_DOUBLE;
for( size_t i = 0; i < newValueSet->size(); ++i )
{
double tmp = newValueSet->getScalarDouble( i );
max = max < tmp ? tmp : max;
min = min > tmp ? tmp : min;
}
m_maximum = max;
m_minimum = min;
m_histogram = boost::shared_ptr< WHistogram >( new WHistogram( newValueSet ) );
m_maximum = m_histogram->getMax();
m_minimum = m_histogram->getMin();
// TEST
//boost::shared_ptr< WHistogram > hist( new WHistogram( *m_histogram, 15 ) );
//m_histogram->setInterval( 20.0 );
//m_histogram->test();
//hist->setInterval( 15.0 );
//hist->test();
}
WDataSetScalar::WDataSetScalar()
......@@ -74,6 +73,8 @@ WDataSetScalar::WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
WAssert( newValueSet->order() == 0, "The value set does not contain scalars." );
WAssert( max >= min, "max must be at least as large as min." );
// TODO(ebaum, rfrohl): WHistogram calculates min/max, change constructor
m_histogram = boost::shared_ptr< WHistogram >( new WHistogram( newValueSet ) );
m_maximum = max;
m_minimum = min;
}
......@@ -84,11 +85,13 @@ WDataSetScalar::~WDataSetScalar()
double WDataSetScalar::getMax() const
{
//change to whistogram->getMax()?
return m_maximum;
}
double WDataSetScalar::getMin() const
{
//change to whistogram->getMin()?
return m_minimum;
}
......
......@@ -25,6 +25,8 @@
#ifndef WDATASETSCALAR_H
#define WDATASETSCALAR_H
#include "datastructures/WHistogram.h"
#include "WDataSetSingle.h"
/**
......@@ -127,6 +129,11 @@ protected:
private:
double m_maximum; //!< Largest scalar of data set.
double m_minimum; //!< Smallest scalar of data set.
/**
* The histogram for later use.
**/
boost::shared_ptr< WHistogram > m_histogram;
};
template< typename T > T WDataSetScalar::getValueAt( int x, int y, int z ) const
......
//---------------------------------------------------------------------------
//
// 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 <cstring> // memset()
#include "../../common/WAssert.h"
#include "../../common/WLimits.h"
#include "WValueSetHistogram.h"
WValueSetHistogram::WValueSetHistogram( boost::shared_ptr< WValueSetBase > valueSet )
{
// calculate min max
m_minimum = wlimits::MAX_DOUBLE;
m_maximum = wlimits::MIN_DOUBLE;
double minDistance = wlimits::MAX_DOUBLE;
for( size_t i = 0; i != valueSet->size(); ++i )
{
double tmp = valueSet->getScalarDouble( i );
m_maximum = m_maximum < tmp ? tmp : m_maximum;
m_minimum = m_minimum > tmp ? tmp : m_minimum;
if( m_minimum != tmp && m_minimum != wlimits::MAX_DOUBLE )
{
minDistance = tmp - m_minimum < minDistance ? tmp - m_minimum : minDistance;
}
if( m_maximum != tmp && m_maximum != wlimits::MIN_DOUBLE )
{
minDistance = m_maximum - tmp < minDistance ? m_maximum - tmp : minDistance;
}
}
// create base histogram
m_nInitialBuckets = ( ( m_maximum - m_minimum ) / minDistance ) + 1;
m_bucketSize = minDistance;
unsigned int* initialBuckets = new unsigned int[m_nInitialBuckets];
// initialize array to zero
memset( initialBuckets, 0, m_nInitialBuckets * sizeof( unsigned int ) );
//*initialBuckets = { 0 }; // this should works with C++0x (instead memset), TEST IT!
m_initialBuckets = boost::shared_array< unsigned int >( initialBuckets );
m_nMappedBuckets = 0;
for( size_t i = 0; i < valueSet->size(); ++i )
{
double tmp = valueSet->getScalarDouble( i );
increment( tmp );
}
}
WValueSetHistogram::WValueSetHistogram( const WValueSetBase& valueSet )
{
// calculate min max
m_minimum = wlimits::MAX_DOUBLE;
m_maximum = wlimits::MIN_DOUBLE;
double minDistance = wlimits::MAX_DOUBLE;
for( size_t i = 0; i != valueSet.size(); ++i )
{
double tmp = valueSet.getScalarDouble( i );
m_maximum = m_maximum < tmp ? tmp : m_maximum;
m_minimum = m_minimum > tmp ? tmp : m_minimum;
if( m_minimum != tmp && m_minimum != wlimits::MAX_DOUBLE )
{
minDistance = tmp - m_minimum < minDistance ? tmp - m_minimum : minDistance;
}
if( m_maximum != tmp && m_maximum != wlimits::MIN_DOUBLE )
{
minDistance = m_maximum - tmp < minDistance ? m_maximum - tmp : minDistance;
}
}
// create base histogram
m_nInitialBuckets = ( ( m_maximum - m_minimum ) / minDistance ) + 1;
m_bucketSize = minDistance;
unsigned int* initialBuckets = new unsigned int[m_nInitialBuckets];
// initialize array to zero
memset( initialBuckets, 0, m_nInitialBuckets * sizeof( unsigned int ) );
//*initialBuckets = { 0 }; // this should works with C++0x (instead memset), TEST IT!
m_initialBuckets = boost::shared_array< unsigned int >( initialBuckets );
m_nMappedBuckets = 0;
for( size_t i = 0; i < valueSet.size(); ++i )
{
double tmp = valueSet.getScalarDouble( i );
increment( tmp );
}
}
WValueSetHistogram::WValueSetHistogram( const WValueSetHistogram& histogram, double intervalSize )
{
// copy constructor
m_nInitialBuckets = histogram.getNInitialBuckets();
m_initialBuckets = boost::shared_array< unsigned int >( histogram.getInitialBuckets() );
m_bucketSize = histogram.getBucketSize();
m_nMappedBuckets = 0;
m_minimum = histogram.getMin();
m_maximum = histogram.getMax();
if( intervalSize != 0.0 )
{
WAssert( intervalSize > 0.0, "WValueSetHistogram::WValueSetHistogram : intervalSize has to be greater then zero." );
calculateMapping( intervalSize );
}
}
WValueSetHistogram::~WValueSetHistogram()
{
}
boost::shared_array< unsigned int > WValueSetHistogram::getInitialBuckets() const
{
return m_initialBuckets;
}
unsigned int WValueSetHistogram::getNInitialBuckets() const
{
return m_nInitialBuckets;
}
double WValueSetHistogram::getBucketSize() const
{
return m_bucketSize;
}
void WValueSetHistogram::increment( double value )
{
WAssert( m_bucketSize > 0.0, "WValueSetHistogram::increment() : m_bucketSize to small." );
unsigned int index = static_cast<unsigned int>( value / m_bucketSize );
m_initialBuckets[index]++;
}
unsigned int WValueSetHistogram::setInterval( double intervalSize )
{
if( m_bucketSize == intervalSize )
{
if( m_mappedBuckets )
{
m_mappedBuckets.reset();
m_nMappedBuckets = 0;
}
}
else
{
calculateMapping( intervalSize );
}
return m_nMappedBuckets;
}
void WValueSetHistogram::calculateMapping( double intervalSize )
{
unsigned int ratio = static_cast<unsigned int>( intervalSize / m_bucketSize );
WAssert( ratio > 1, "WValueSetHistogram::calculateMapping() : intervalSize has to be greater then the original size." );
// number of elements in the new mapped histogram = division + (round up)
m_nMappedBuckets = m_nInitialBuckets / ratio + ( m_nInitialBuckets % ratio > 0 ? 1 : 0 );
if( m_mappedBuckets )
{
m_mappedBuckets.reset();
}
unsigned int* mappedBuckets = new unsigned int[m_nMappedBuckets];
memset( mappedBuckets, 0, m_nMappedBuckets * sizeof( unsigned int ) );
//*mappedBuckets = { 0 }; // works with C++0x
boost::scoped_array< unsigned int > scoped( mappedBuckets );
m_mappedBuckets.swap( scoped );
unsigned int index = 0;
for( unsigned int i = 0; i != m_nInitialBuckets; ++i )
{
if( i % ratio == 0 && i != 0 )
{
index++;
}
m_mappedBuckets[index] += m_initialBuckets[i];
}
}
unsigned int WValueSetHistogram::operator[]( unsigned int index )
{
unsigned int value = 0;
if( m_mappedBuckets )
{
index = m_mappedBuckets[index];
}
else
{
value = m_initialBuckets[index];
}
return value;
}
unsigned int WValueSetHistogram::at( unsigned int index )
{
unsigned int value = 0;
if( m_mappedBuckets )
{
WAssert( index < m_nMappedBuckets, "WValueSetHistogram::at() : index out of range." );
value = m_mappedBuckets[index];
}
else
{
WAssert( index < m_nInitialBuckets, "WValueSetHistogram::at() : index out of range." );
value = m_initialBuckets[index];
}
return value;
}
unsigned int WValueSetHistogram::size() const
{
return (m_mappedBuckets ? m_nMappedBuckets : m_nInitialBuckets);
}
double WValueSetHistogram::getMin() const
{
return m_minimum;
}
double WValueSetHistogram::getMax() const
{
return m_maximum;
}
//---------------------------------------------------------------------------
//
// 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 WVALUESETHISTOGRAM_H
#define WVALUESETHISTOGRAM_H
#include <map>
#include <list>
#include <utility>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_array.hpp>
#include "../WValueSet.h"
/**
* Used to find the occurrence frequencies of values in a value set. It implements a classical histogram but allows easy modification of bucket
* sizes without unnecessary recalculation of the whole histogram.
*
* \note This histogram is different from from WValueSetHistogram which is a generic histogram class.
*/
class WValueSetHistogram
{
public:
/**
* Constructor. Creates the histogram for the specified value set.
*
* \param valueSet source of the data for the histogram
*/
explicit WValueSetHistogram( boost::shared_ptr< WValueSetBase > valueSet );
/**
* Constructor. Creates the histogram for the specified value set.
*
* \param valueSet source of the data for the histogram
*/
explicit WValueSetHistogram( const WValueSetBase& valueSet );
/**
* Copy constructor. If another interval size is given setInterval() is called and
* the mapped histogram is calculated.
*
* \param histogram another WValueSetHistogram
* \param intervalSize the size of one bucket in the mapped histogram
*/
explicit WValueSetHistogram( const WValueSetHistogram& histogram, double intervalSize = 0.0 );
/**
* Destructor.
*/
~WValueSetHistogram();
/**
* Set the new interval size.
*
* \param intervalSize size of the interval for each mapped bucket.
*
* \return size of the new (mapped) histogram.
*/
unsigned int setInterval( double intervalSize );
/**
* Get the size of the bucket.
*
* \param index which buckets size is to be returned, starts with 0 which is the bucket
* containing the smallest values.
*
* \return elements in the bucket.
*/
unsigned int operator[]( unsigned int index );
/**
* Get the size of the bucket. Testing if the position is valid.
*
* \param index which buckets size is to be returned, starts with 0 which is the bar with
* the smallest values
*
* \return elements in the bucket
*/
unsigned int at( unsigned int index );
/**
* Returns the number of bars in the histogram with the actual mapping.
*
* \return number of buckets
*/
unsigned int size() const;
/**
* Returns the minimum value in the value set.
*
* \return minimum
*/
double getMin() const;
/**
* Returns the maximum value in the value set.
*
* \return maximum
*/
double getMax() const;
protected:
/**
* Return the initial buckets.
*
* \return m_initialBuckets
*/
boost::shared_array< unsigned int > getInitialBuckets() const;
/**
* Return the number of initial buckets.
*
* \return m_nInitialBuckets
*/
unsigned int getNInitialBuckets() const;
/**
* Return the size of one initial bucket.
*
* \return m_bucketSize
*/
double getBucketSize() const;
private:
/**
* The smallest value in the ValueSet
*/
double m_minimum;
/**
* The biggest value in the ValueSet
*/
double m_maximum;
/**
* Size of one bucket in the initial histogram.
*/
double m_bucketSize;
/**
* Pointer to all initial buckets of the histogram.
*/
boost::shared_array< unsigned int > m_initialBuckets;
/**
* Number of buckets in the initial histogram.
*/
unsigned int m_nInitialBuckets;
/**
* Pointer to all the buckets in the mapped histogram.
*/
boost::scoped_array< unsigned int > m_mappedBuckets;
/**
* Tracks the number of a buckets in the mapped histogram.
*/
unsigned int m_nMappedBuckets;
/**
* To calculate the new buckets
*
* \param intervalSize the size of one bucket
*/
void calculateMapping( double intervalSize );
/**
* increment the value by one, contains the logic to find the element place in the array.
* Should only be used in the constructor i.e. while iterating over WValueSet.
*
* \param value value to increment
*/
void increment( double value );
};
#endif // WVALUESETHISTOGRAM_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 <stdint.h>
#include <vector>
#include <cxxtest/TestSuite.h>
#include "../../WValueSet.h"
//#include "../../WDataHandlerEnums.h"
//#include "../../WValueSetBase.h"
#include "../WHistogram.h"
/**
* Test WHistogram
**/
class WHistogramTest : public CxxTest::TestSuite
{
public:
/**
* Test instantiation
**/
void testInstantiation( void )
{
double a[2] = { 0.0, 3.1415 };
const std::vector< double > v( a, a + sizeof( a ) / sizeof( double ) );
WValueSet< double >* valueSet = new WValueSet< double >( 0, 1, v, W_DT_DOUBLE );
TS_ASSERT_THROWS_NOTHING( WHistogram hist( *valueSet ) );
boost::shared_ptr< WValueSet< double > > vsPtr( valueSet );
TS_ASSERT_THROWS_NOTHING( WHistogram hist( vsPtr ) );
}
/**
* Test operator[]
**/
void testOperator( void )
{
double a[4] = { 0.0, 1.0, 1.0, 4.0 };
const std::vector< double > v( a, a + sizeof( a ) / sizeof( double ) );
WValueSet< double >* valueSet = new WValueSet< double >( 0, 1, v, W_DT_DOUBLE );
WHistogram hist( *valueSet );
TS_ASSERT_EQUALS( hist[0], 1 ); // 0.0
TS_ASSERT_EQUALS( hist[1], 2 ); // 1.0
TS_ASSERT_EQUALS( hist[2], 0 ); // 2.0
TS_ASSERT_EQUALS( hist[3], 0 ); // 3.0
TS_ASSERT_EQUALS( hist[4], 1 ); // 4.0
}
/**
* Test at()
**/
void testAt( void )
{
double a[4] = { 0.0, 1.0, 1.0, 4.0 };
const std::vector< double > v( a, a + sizeof( a ) / sizeof( double ) );
WValueSet< double >* valueSet = new WValueSet< double >( 0, 1, v, W_DT_DOUBLE );
WHistogram hist( *valueSet );
TS_ASSERT_EQUALS( hist.at( 0 ), 1 ); // 0.0
TS_ASSERT_EQUALS( hist.at( 1 ), 2 ); // 1.0
TS_ASSERT_EQUALS( hist.at( 2 ), 0 ); // 2.0
TS_ASSERT_EQUALS( hist.at( 3 ), 0 ); // 3.0
TS_ASSERT_EQUALS( hist.at( 4 ), 1 ); // 4.0
TS_ASSERT_THROWS_ANYTHING( hist.at( 5 ) );
}
/**
* Test getMin(), getMax()
**/
void testMinMax( void )
{
double a[4] = { 0.0, -5.0, 1.0, 2.0 };
const std::vector< double > v( a, a + sizeof( a ) / sizeof( double ) );
WValueSet< double >* valueSet = new WValueSet< double >( 0, 1, v, W_DT_DOUBLE );
WHistogram hist( *valueSet );
TS_ASSERT_EQUALS( hist.getMin(), -5.0 );
TS_ASSERT_EQUALS( hist.getMax(), 2.0 );
}
/**
* Test size(), setInterval()
**/
void testSizeSetInterval( void )
{
double a[4] = { 0.0, 4.0, 1.0, 2.0 };
const std::vector< double > v( a, a + sizeof( a ) / sizeof( double ) );
WValueSet< double >* valueSet = new WValueSet< double >( 0, 1, v, W_DT_DOUBLE );
WHistogram hist( *valueSet );