Commit cc6cab83 authored by Robert Frohl's avatar Robert Frohl
Browse files

[CHANGE] made the discussed (with Sebastian E.) changes to WHistogram

parent 7d44c9b3
......@@ -22,135 +22,198 @@
//
//---------------------------------------------------------------------------
#include <iostream> // test() -> std::cout
#include <cmath> // test() -> log()
#include <map>
#include <utility>
#include <list>
#include <cmath> // test() -> log() ?
//#include <limits> // std::numeric_limits<double>
#include <cstring> // memset(), remove when using C++0x and {0} to initiate the arrays to zero
#include <iostream> // test() -> std::cout ?
//#include <map>
//#include <list>
//#include <utility>
#include "WAssert.h"
#include "WLimits.h"
#include "WHistogram.h"
WHistogram::WHistogram() : uniformInterval( 0 )
WHistogram::WHistogram( boost::shared_ptr< WValueSetBase > valueSet, unsigned int nBuckets )
{
mappingPointer.first = mapping.begin();
mappingPointer.second = 0;
m_nInitialBuckets = nBuckets;
m_initialBuckets = new unsigned int[m_nInitialBuckets];
m_mappedBuckets = 0;
// initiate array to zero
memset( m_initialBuckets, 0, m_nInitialBuckets * sizeof( unsigned int ) );
//*m_initialBuckets = {0}; // this should works with C++0x (instead memset), TEST IT!
// calculate min max
m_minimum = wlimits::MAX_DOUBLE; //std::numeric_limits<double>::max(); // double min ?
m_maximum = wlimits::MIN_DOUBLE; //std::numeric_limits<double>::min(); // double max ?
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;
}
// create base histogram
m_bucketSize = ( m_maximum - m_minimum ) / static_cast<double>( m_nInitialBuckets ); // rounding ? static_cast needed ?
for( size_t i = 0; i < valueSet->size(); ++i )
{
double tmp = valueSet->getScalarDouble( i );
increment( tmp );
}
}
WHistogram::WHistogram( unsigned int interval ) : uniformInterval( interval )
WHistogram::WHistogram( const WHistogram& histogram )
{
mappingPointer.first = mapping.begin();
mappingPointer.second = 0;
// copy constructor
m_nInitialBuckets = histogram.getNInitialBuckets();
m_initialBuckets = new unsigned int[m_nInitialBuckets];
memcpy( m_initialBuckets, histogram.getInitialBuckets(), m_nInitialBuckets * sizeof( unsigned int ) );
m_bucketSize = histogram.getBucketSize();
m_mappedBuckets = 0;
m_nMappedBuckets = 0;
m_minimum = histogram.getMin();
m_maximum = histogram.getMax();
}
WHistogram::~WHistogram()
{
delete[] m_initialBuckets;
delete[] m_mappedBuckets;
}
unsigned int* WHistogram::getInitialBuckets() const
{
return m_initialBuckets;
}
void WHistogram::add( double value )
unsigned int WHistogram::getNInitialBuckets() const
{
// IF( MIN || MAX needed ) : here!
elements[value]++;
return m_nInitialBuckets;
}
void WHistogram::setUniformInterval( unsigned int interval )
double WHistogram::getBucketSize() const
{
// negativ ?
//WAssert( elements.size > 0, "No elements in WHistogram." );
uniformInterval = interval;
calculateMapping();
return m_bucketSize;
}
void WHistogram::calculateMapping()
void WHistogram::increment( double value )
{
if( mapping.size() != 0 ) // is there already a mapping ?
WAssert( m_bucketSize > 0.0, "bucket size to small." ); // ? test & output correct ?
unsigned int index = static_cast<unsigned int>( value / m_bucketSize ); // round down correctly?
( *( m_initialBuckets + index ) )++;
}
void WHistogram::setInterval( double intervalSize )
{
calculateMapping( intervalSize );
}
void WHistogram::calculateMapping( double intervalSize )
{
unsigned int ratio = static_cast<unsigned int>( intervalSize / m_bucketSize );
WAssert( ratio > 1, "the new interval size has to be greater than 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 )
{
mapping.clear();
delete[] m_mappedBuckets;
m_mappedBuckets = 0;
}
unsigned int count = 0;
unsigned int value = 0;
for( std::map< double, WBar >::const_iterator iter = elements.begin(); iter != elements.end(); ++iter )
m_mappedBuckets = new unsigned int[m_nMappedBuckets];
memset( m_mappedBuckets, 0, m_nMappedBuckets * sizeof( unsigned int ) );
//*m_mappedBuckets = {0}; // works with C++0x
unsigned int index = 0;
for( unsigned int i = 0; i != m_nInitialBuckets; ++i )
{
if( count == uniformInterval )
if( i % ratio == 0 && i != 0 )
{
mapping.push_back( std::pair< const WBar*, unsigned int >( &iter->second, value ) );
count = 0;
value = iter->second.getValue();
}
else
{
value += iter->second.getValue();
count++;
index++;
}
*( m_mappedBuckets + index ) += *( m_initialBuckets + i );
}
}
unsigned int WHistogram::operator[]( unsigned int position )
{
// out of range ?
if(mappingPointer.second == 0 || mappingPointer.second > position )
unsigned int* ptr = 0;
if( m_mappedBuckets )
{
mappingPointer.first = mapping.begin();
mappingPointer.second = 0;
ptr = m_mappedBuckets;
}
for( unsigned int t = mappingPointer.second; t != position; ++t )
else
{
mappingPointer.first++;
ptr = m_initialBuckets;
}
mappingPointer.second = position; // == mappingPointer.second++
return mappingPointer.first->second;
return *(ptr + position);
}
void WHistogram::setInterval( const std::list<unsigned int>& rangeList )
unsigned int WHistogram::at( unsigned int index )
{
if( mapping.size() != 0 ) // is there already a mapping ?
WAssert( index > m_nMappedBuckets, "WHistogram: index out of range." );
unsigned int* ptr = 0;
if( m_mappedBuckets )
{
mapping.clear();
ptr = m_mappedBuckets;
}
std::list<unsigned int>::const_iterator iter;
for( iter = rangeList.begin(); iter != rangeList.end(); ++iter )
else
{
std::map< double, WBar >::const_iterator elementsIter = elements.begin();
unsigned int barHeight = elementsIter->second.getValue();
for( unsigned int i = 0; i != *iter; ++i )
{
elementsIter++;
barHeight += elementsIter->second.getValue();
}
// elementsIter has to point at the first element of the next bucket
elementsIter++;
mapping.push_back( std::pair< const WBar*, unsigned int >( &elementsIter->second, barHeight ) );
ptr = m_initialBuckets;
}
return *(m_mappedBuckets + index);
}
unsigned int WHistogram::size() const
{
return m_mappedBuckets ? m_nMappedBuckets : m_nInitialBuckets;
}
double WHistogram::getMin() const
{
return m_minimum;
}
double WHistogram::getMax() const
{
return m_maximum;
}
void WHistogram::test()
{
calculateMapping();
unsigned int* ptr;
unsigned int histSize;
if( m_mappedBuckets )
{
ptr = m_mappedBuckets;
histSize = m_nMappedBuckets;
}
else
{
ptr = m_initialBuckets;
histSize = m_nInitialBuckets;
}
// unsigned int rangeStart= 0;
// std::list< std:pair< WBar*, unsigned int > >::iterator iter;
// std::list< std:pair< WBucket*, unsigned int > >::iterator iter;
// for(iter = mapping.begin(); iter != mapping.end(); iter++ )
// {
// std::cout << iter->second << ": " << rangeStart << " - " << rangeStart+uniformInterval;
// rangeStart += uniformInterval;
// }
std::cout << mapping.size() << std::endl;
std::list< std::pair< const WBar*, unsigned int > >::iterator it = mapping.begin();
for(it = mapping.begin(); it != mapping.end(); ++it)
{
std::cout << it->second << " ";
}
std::cout << std::endl;
for( unsigned int y = 10; y != 0; --y )
{
std::cout << "|";
std::list< std::pair< const WBar*, unsigned int > >::iterator iter = mapping.begin();
for( unsigned int x = 0; x != mapping.size(); ++x )
unsigned int* h_ptr = ptr;
for( unsigned int x = 0; x != histSize; ++x )
{
if( log( static_cast<double>( iter->second ) ) > static_cast<double>( (y-1)*2 ) )
if( log( static_cast<double>( *h_ptr ) ) > static_cast<double>( (y-1)*2 ) )
{
std::cout << " #";
}
......@@ -158,12 +221,12 @@ void WHistogram::test()
{
std::cout << " ";
}
iter++;
h_ptr++;
}
std::cout << " |\n";
}
std::cout << "-";
for(unsigned int i = 0; i != mapping.size(); ++i)
for(unsigned int i = 0; i != histSize; ++i)
{
std::cout << "--";
}
......
......@@ -29,187 +29,160 @@
#include <list>
#include <utility>
#include <boost/shared_ptr.hpp>
#include "../dataHandler/WValueSet.h"
//#include "../dataHandler/WDataSetScalar.h"
/**
* Used to track (later: display) the occurrence frequencies of values in a value set.
**/
class WHistogram
{
/**
* To compare the elements of the std::map used in WHistogram.
**/
class cmp
{
public:
/**
* Compares two double values.
*
* \param p1 first value
* \param p2 second value
*
* \return the same bolean value as applying the less-than operator (a<b)
**/
bool operator()( double const& p1, double const& p2 ) const
{
return p1 < p2;
}
};
/**
* WBar is an element of WHistogram, where the range of monitored values equals 1.
* Meaning WBar represents the amount of each specific value in the value set.
**/
class WBar
{
private:
/**
* Represents this bars height.
**/
unsigned int value;
//unsigned int distance;
//std::pair<int, int> range;
public:
/**
* Default constructor.
**/
WBar() : value( 0 )
{
}
/**
* Clones this WBar from another WBar.
*
* \param bar WBar which serves as the origin of the height.
**/
explicit WBar( WBar const& bar ) : value( bar.value )
{
}
/**
* Destroys this Bar instance.
**/
~WBar()
{
}
/**
* Postfix inkrement (x++) the bar by one.
**/
WBar& operator++( int ) // x++
{
WBar* tmp = this;
tmp->value++;
return *tmp;
}
/**
* Prefix inkrement (++x) the bar by one.
**/
WBar& operator++() // ++x
{
WBar* tmp = this;
tmp->value++;
return *tmp;
}
/**
* To access the height of the specific bar.
*
* \return the value of the bar.
**/
unsigned int getValue() const
{
return value;
}
};
private:
/**
* Describes the uniform size of a bucket in the mapped histogram.
* The smalest value in the ValueSet
**/
double m_minimum;
/**
* The biggest value in the ValueSet
**/
unsigned int uniformInterval;
double m_maximum;
/**
* Pointer used to speed up operator[]( unsigned int ) if the parameter increases by 1
* each call (supposed standard behaviour).
* Size of one bucket in the initial histogram.
**/
std::pair< std::list<std::pair< const WBar*, unsigned int > >::iterator, unsigned int > mappingPointer;
double m_bucketSize;
/**
* Orderd sequence of WBar, which only account for specific values(the
* double value).
* Pointer to all initial buckets of the histogram.
**/
std::map< double, WBar, cmp > elements;
unsigned int* m_initialBuckets;
/**
* The Mapping, to gain bar's with a range greater than 1, is stored as
* std::pair<WBar, unsigned int>.
* Where the unsigned int is the the height of the specific bar.
* The *WBar is the initial point (related to the std::map<> elements)
* of the next bar.
* Number of buckets in the initial histogram.
**/
std::list< std::pair< const WBar*, unsigned int > > mapping;
unsigned int m_nInitialBuckets;
/**
* Creates the mapping from the given range.
* Pointer to all the buckets in the mapped histogram.
**/
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 ie. while iterating over WValueSet.
*
* \param value value to increment
**/
void increment( double value );
protected:
/**
* Return the initial buckets.
*
* \return m_initialBuckets
**/
void calculateMapping(); // for uniformInterval only
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;
public:
/**
* Default constructor.
* Constructor.
*
* \param valueSet source of the data for the histogram
* \param nBuckets number of buckets this histogram should display
**/
WHistogram();
WHistogram( boost::shared_ptr< WValueSetBase > valueSet, unsigned int nBuckets = 1000 );
/**
* Constructs a histogram with a given uniform intervall.
* Copy constructor.
*
* \param interval the interval size if uniform intervals are used
* \param histogram another WHisogram
**/
explicit WHistogram( unsigned int interval );
explicit WHistogram( const WHistogram& histogram );
/**
* Destroys this Histogram instance.
* Destructor.
**/
~WHistogram();
/**
* Add an element to one of the WBar.
* Set the new intervall size.
*
* \param intervalSize size of the interval for each mapped bucket.
**/
void setInterval( double intervalSize );
/**
* Get the size of the bucket.
*
* \param value the bar that represents value in the histogram is increased bye one
* \param index which buckets size is to be returned, starts with 0 which is the bucket
* containing the smalest values.
*
* \return elements in the bucket
**/
void add( double value );
unsigned int operator[]( unsigned int index );
/**
* Set and change the uniform interval.
* Each time a new mapping is created.
* 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 smalest values
*
* \param interval the new bucket size
* \return elements in the bucket
**/
void setUniformInterval( unsigned int interval );
unsigned int at( unsigned int index );
/**
* Sets intervals that are not uniform.
* A new mapping is created each time.
* Returns the number of bars in the histogram with the actual mapping.
*
* \param rangeList list that represents the size of each bucket starting with the lowest
* value
* \return number of buckets
**/
void setInterval( const std::list<unsigned int>& rangeList );
unsigned int size() const;
/**
* Get the height of a bar.
* Retruns the minimum value in the value set.
*
* \param position which bars height is to be returned, starts with 0 which is the bar with
* the smalest values
* \return minimum
**/
double getMin() const;
/**
* Retruns the maximum value in the value set.
*
* \return height of the bar i.e. size of the bucket
* \return maximum
**/
unsigned int operator[]( unsigned int position ); // const;
double getMax() const;
/**
* Simple output to std::cout to test functionality.
* to test if the histogram works
**/
void test();
};
......
......@@ -43,20 +43,25 @@ 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;
histogram.setUniformInterval( 8 );
for( size_t i = 0; i < newValueSet->size(); ++i )
{
double tmp = newValueSet->getScalarDouble( i );
max = max < tmp ? tmp : max;
min = min > tmp ? tmp : min;
histogram.add( tmp );
}
m_maximum = max;
m_minimum = min;
histogram.test();
//double max = wlimits::MIN_DOUBLE;
//double min = wlimits::MAX_DOUBLE;
m_histogram = boost::shared_ptr< WHistogram >( new WHistogram( newValueSet ) );
//m_histogram.setUniformInterval( 8 );
//for( size_t i = 0; i < newValueSet->size(); ++i )
//{
// double tmp = newValueSet->getScalarDouble( i );
// max = max < tmp ? tmp : max;
// min = min > tmp ? tmp : min;
// //histogram.add( tmp );
//}
//boost::shared_ptr< WHistogram > hist( new WHistogram(*m_histogram) );
m_maximum = m_histogram->getMax();
m_minimum = m_histogram->getMin();
m_histogram->setInterval( 20.0 );
m_histogram->test();
//hist->setInterval(15.0);
//hist->test();
}
WDataSetScalar::WDataSetScalar()
......@@ -77,6 +82,7 @@ WDataSetScalar::WDataSetScalar( boost::shared_ptr< WValueSetBase > newValueSet,
WAssert( newValueSet->order() == 0, "The value set does not contain scalars." );