Commit 0050f80a authored by lmath's avatar lmath
Browse files

[ADD #157] Some improvements for the clustering algo (ported the distance metrics, almost)

    * fixed some unit tests, using snprintf which is non ANSI compliant
parent 7bec43fe
......@@ -22,4 +22,11 @@
//
//---------------------------------------------------------------------------
#include <algorithm>
#include "WDataSetFibers.h"
void WDataSetFibers::sortDescLength()
{
std::sort( m_fibers->begin(), m_fibers->end(), wmath::hasGreaterLengthThen );
}
......@@ -62,7 +62,13 @@ public:
return (*m_fibers)[index];
}
/**
* Sort fibers descending on their length.
*/
void sortDescLength();
protected:
private:
boost::shared_ptr< std::vector< wmath::WFiber > > m_fibers;
};
......
......@@ -25,6 +25,8 @@
#ifndef WGRIDREGULAR3D_TEST_H
#define WGRIDREGULAR3D_TEST_H
#include <cstdio>
#include <cxxtest/TestSuite.h>
#include "../WGridRegular3D.h"
......@@ -43,7 +45,7 @@ class ValueTraits<WVector3D>
public:
explicit ValueTraits( const WVector3D &m )
{
snprintf( _s, sizeof( _s ), "WVector3D( %.18f %.18f %.18f )", m[0], m[1], m[2] );
std::snprintf( _s, sizeof( _s ), "WVector3D( %.18f %.18f %.18f )", m[0], m[1], m[2] );
}
const char *asString() const
{
......
......@@ -22,7 +22,9 @@
//
//---------------------------------------------------------------------------
#include <algorithm>
#include <vector>
#include <utility>
#include "WFiber.h"
......@@ -32,5 +34,53 @@ namespace wmath
: WLine( points )
{
}
std::pair< double, double > WFiber::dXt_optimized( const WFiber &other,
const double thresholdSquare ) const
{
const WFiber &q = *this;
const WFiber &r = other;
const size_t qsize = q.size();
const size_t rsize = r.size();
double qr = 0.0;
double rq = 0.0;
std::vector< std::vector< double > > m( qsize, std::vector< double >( rsize, 0.0 ) );
for( size_t i = 0; i < qsize; ++i )
{
for( size_t j = 0; j < rsize; ++j )
{
m[i][j] = q[i].distanceSquare( r[j] );
}
}
double minSoFar;
for( size_t i = 0; i < qsize; ++i )
{
minSoFar = *( std::min_element( m[i].begin(), m[i].end() ) );
if( minSoFar > thresholdSquare )
{
qr += sqrt( minSoFar );
}
}
qr = qr / qsize;
for( size_t j = 0; j < rsize; ++j )
{
// TODO(math): MAX_FANTOM_DOUBLE correct this
minSoFar = 9999999999999999999.9; // _FANTOM_DOUBLE;
for( size_t i = 0; i < qsize; ++i )
{
if( m[i][j] < minSoFar )
{
minSoFar = m[i][j];
}
}
if( minSoFar > thresholdSquare )
{
rq += sqrt( minSoFar );
}
}
rq = rq / rsize;
return std::make_pair( qr, rq );
}
}
......@@ -26,6 +26,7 @@
#define WFIBER_H
#include <vector>
#include <utility>
#include "WLine.h"
......@@ -45,8 +46,52 @@ friend class WFiberTest;
public:
explicit WFiber( const std::vector< WPosition > &points );
/**
* TODO(math): document this method in more detail
* Optimized version which computes dt measure from qr and rq at once.
*/
std::pair< double, double > dXt_optimized( const WFiber &other,
const double thresholdSquare ) const;
/**
* Computes dt(Q, R, t) and dt(R, Q, t) and then the one which is smaller
* is returned. Note this distance metric is symmetric.
*
* \param other The other fiber "R", while this fiber is taken as "Q".
* \param thresholdSquare The threshold upto which the accumulated
* distances should be considered
*
* \return The minimum of dt(Q, R, t) and dt(R, Q, t)
*/
double dSt( const WFiber &other, const double thresholdSquare = 0.0 ) const;
/**
* Computes dt(Q, R, t) and dt(R, Q, t) and then the one which is smaller
* is returned. Note this distance metric is symmetric.
*
* \param other The other fiber "R", while this fiber is taken as "Q".
* \param thresholdSquare The threshold upto which the accumulated
* distances should be considered
*
* \return The maximum dt(Q, R, t) and dt(R, Q, t)
*/
double dLt( const WFiber &other, const double thresholdSquare = 0.0 ) const;
protected:
private:
};
/**
* Boolean predicate indicating that the first fiber has a greater length then
* the second one.
*
* \param first First fiber
* \param second Second fiber
*/
inline bool hasGreaterLengthThen( const WFiber &first,
const WFiber &second )
{
return first.size() > second.size();
}
}
#endif // WFIBER_H
......@@ -78,7 +78,7 @@ public:
/**
* Get number of points (length) the value consists of.
*/
inline size_t size() const
size_t size() const
{
return m_points.size();
}
......
......@@ -83,6 +83,26 @@ public:
return result;
}
/**
* Calculate euclidean square distance between this Position and another one.
*
* \param other The other position.
* \return Square distance.
*/
double distanceSquare( const WVector3D &other ) const
{
assert( this->size() == other.size() );
double dist = 0.0;
double tmp = 0;
unsigned int i = 0;
for ( i = 0 ; i < this->size(); i++)
{
tmp = (*this)[i] - other[i];
dist += tmp * tmp;
}
return dist;
}
protected:
private:
};
......
......@@ -25,6 +25,7 @@
#ifndef WFIBER_TEST_H
#define WFIBER_TEST_H
#include <string>
#include <vector>
#include <cxxtest/TestSuite.h>
......@@ -41,18 +42,18 @@ CXXTEST_TEMPLATE_INSTANTIATION
class ValueTraits< wmath::WFiber >
{
private:
char _s[256];
std::string _s;
public:
explicit ValueTraits( const wmath::WFiber &fib )
{
std::stringstream ss;
ss << fib;
snprintf( _s, ss.str().size(), "%s", ss.str().c_str() );
ss << "WFiber(" << fib << ")";
_s = ss.str();
}
const char *asString() const
{
return _s;
return _s.c_str();
}
};
}
......
......@@ -41,19 +41,18 @@ CXXTEST_TEMPLATE_INSTANTIATION
class ValueTraits< wmath::WLine >
{
private:
char _s[1024];
std::string _s;
public:
explicit ValueTraits( const wmath::WLine &line )
{
std::stringstream ss;
ss << line;
assert( ss.str().size() < 1024 && "custom value traits supports just 256 chars" );
snprintf( _s, ss.str().size(), "WLine(%s)", ss.str().c_str() );
ss << "WLine(" << line << ")";
_s = ss.str();
}
const char *asString() const
{
return _s;
return _s.c_str();
}
};
}
......
......@@ -23,6 +23,7 @@
//---------------------------------------------------------------------------
#include <string>
#include <vector>
#include <osg/Geode>
#include <osg/Geometry>
......@@ -74,8 +75,8 @@ void WFiberCulling::threadMain()
sleep( 1 );
}
boost::shared_ptr< const WDataSetFibers > fiberDS;
assert( fiberDS = boost::shared_dynamic_cast< const WDataSetFibers >( dataHandler->getSubject( 0 )->getDataSet( 0 ) ) );
boost::shared_ptr< WDataSetFibers > fiberDS;
assert( fiberDS = boost::shared_dynamic_cast< WDataSetFibers >( dataHandler->getSubject( 0 )->getDataSet( 0 ) ) );
// osg::ref_ptr< osg::Group > group = osg::ref_ptr< osg::Group >( new osg::Group );
//
......@@ -98,25 +99,29 @@ void WFiberCulling::threadMain()
}
}
void WFiberCulling::cullOutFibers( boost::shared_ptr< const WDataSetFibers > fibers )
void WFiberCulling::cullOutFibers( boost::shared_ptr< WDataSetFibers > fibers )
{
// size_t numFibers = fibers->size();
// std::cout << "Recoginzed " << numFibers << " fibers" << std::endl;
//
// fibers->sortDescLength(); // sort the fiber on their length (biggest first)
// std::cout << "Sorted fibers done." << std::endl;
//
// const double proximity_t_Square = m_proximity_t * m_proximity_t;
// std::vector< bool > unusedFibers( numFibers, false );
// for( size_t i = 0; i < numFibers; ++i ) { // loop over all streamlines
// if( unusedFibers[i] ) {
// continue;
// }
// const wmath::WFiber& q = (*fibers)[ i ];
// for( size_t j = i + 1; j < numFibers; ++j ) {
// if( unusedFibers[j] ) {
// continue;
// }
size_t numFibers = fibers->size();
std::cout << "Recoginzed " << numFibers << " fibers" << std::endl;
fibers->sortDescLength(); // sort the fiber on their length (biggest first)
std::cout << "Sorted fibers done." << std::endl;
const double proximity_t_Square = m_proximity_t * m_proximity_t;
std::vector< bool > unusedFibers( numFibers, false );
for( size_t i = 0; i < numFibers; ++i ) // loop over all streamlines
{
if( unusedFibers[i] )
{
continue;
}
const wmath::WFiber& q = (*fibers)[ i ];
for( size_t j = i + 1; j < numFibers; ++j )
{
if( unusedFibers[j] )
{
continue;
}
// const wmath::WFiber& r = (*fibers)[j];
// double dst = q.dSt( r, proximity_t_Square );
//
......@@ -129,9 +134,9 @@ void WFiberCulling::cullOutFibers( boost::shared_ptr< const WDataSetFibers > fib
// unusedFibers[j] = true;
// }
// }
// }
// }
//
}
}
// if( m_saveCulledCurves ) {
// saveFib( m_savePath, fibers, unusedFibers );
// std::cout << "Saving culled fibers to " << m_savePath << " done." << std::endl;
......
......@@ -70,7 +70,7 @@ protected:
*/
virtual void threadMain();
virtual void cullOutFibers( boost::shared_ptr< const WDataSetFibers > fibers );
virtual void cullOutFibers( boost::shared_ptr< WDataSetFibers > fibers );
/**
* Proximity threshold, which defines the minimum distance which should be
......
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