Commit 74ea9edc authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[MERGE]

parents 8ec63581 4e7a277d
......@@ -27,6 +27,11 @@
#include <stdint.h>
#include <string>
#include <vector>
#include <boost/lexical_cast.hpp>
#include <string>
#include <list>
#include <utility>
......@@ -35,7 +40,7 @@
#include <boost/lexical_cast.hpp>
#include "math/WPosition.h"
#include "math/WMatrix4x4.h"
#include "math/WMatrix.h"
#include "WItemSelector.h"
#include "WColor.h"
......@@ -98,9 +103,9 @@ namespace WPVBaseTypes
typedef std::string PV_STRING; //!< base type used for every WPVString
typedef boost::filesystem::path PV_PATH; //!< base type used for every WPVFilename
typedef WItemSelector PV_SELECTION; //!< base type used for every WPVSelection
typedef WPosition PV_POSITION; //!< base type used for every WPVPosition
typedef WPosition PV_POSITION; //!< base type used for every WPVPosition
typedef WColor PV_COLOR; //!< base type used for every WPVColor
typedef WMatrix4x4 PV_MATRIX4X4; //!< base type used for every WPVMatrix4X4
typedef WMatrix4x4_2 PV_MATRIX4X4; //!< base type used for every WPVMatrix4X4
/**
* Enum denoting the possible trigger states. It is used for trigger properties.
......@@ -543,7 +548,22 @@ namespace PROPERTY_TYPE_HELPER
*/
WPVBaseTypes::PV_MATRIX4X4 create( const WPVBaseTypes::PV_MATRIX4X4& /*old*/, const std::string str )
{
return fromString( str );
WMatrix4x4_2 c;
std::vector< std::string > tokens;
tokens = string_utils::tokenize( str, ";" );
WAssert( tokens.size() >= 16, "There weren't 16 values for a 4x4 Matrix" );
size_t idx = 0;
for ( size_t row = 0; row < 4; ++row )
{
for ( size_t col = 0; col < 4; ++col )
{
c( row, col ) = boost::lexical_cast< double >( tokens[ idx ] );
idx++;
}
}
return c;
}
/**
......@@ -555,7 +575,64 @@ namespace PROPERTY_TYPE_HELPER
*/
std::string asString( const WPVBaseTypes::PV_MATRIX4X4& v )
{
return toString( v );
std::ostringstream out;
for ( size_t row = 0; row < 4; ++row )
{
for ( size_t col = 0; col < 4; ++col )
{
out << v( row, col ) << ";";
}
}
return out.str();
}
};
/**
* Class helping to create a new instance of the property content from an old one. Selections need this special care since they contain not
* serializable content which needs to be acquired from its predecessor instance.
*/
template<>
class WStringConversion< WPVBaseTypes::PV_POSITION >
{
public:
/**
* Creates a new instance of the type from a given string. Some classes need a predecessor which is also specified here.
*
* \param str the new value as string
*
* \return the new instance
*/
WPVBaseTypes::PV_POSITION create( const WPVBaseTypes::PV_POSITION& /*old*/, const std::string str )
{
WPVBaseTypes::PV_POSITION c;
std::vector< std::string > tokens;
tokens = string_utils::tokenize( str, ";" );
WAssert( tokens.size() >= 3, "There weren't 3 values for a 3D vector" );
size_t idx = 0;
for ( size_t col = 0; col < 3; ++col )
{
c[ col ] = boost::lexical_cast< double >( tokens[ idx ] );
idx++;
}
return c;
}
/**
* Creates a string from the specified value.
*
* \param v the value to convert
*
* \return the string representation
*/
std::string asString( const WPVBaseTypes::PV_POSITION& v )
{
std::ostringstream out;
for ( size_t col = 0; col < 3; ++col )
{
out << v[ col ] << ";";
}
return out.str();
}
};
}
......
......@@ -83,7 +83,7 @@ public:
*
* \return the condition
*/
boost::shared_ptr< WCondition > getChangeCondition();
boost::shared_ptr< WCondition > getChangeCondition() const;
protected:
......@@ -122,7 +122,7 @@ WSharedObject< T >::~WSharedObject()
}
template < typename T >
boost::shared_ptr< WCondition > WSharedObject< T >::getChangeCondition()
boost::shared_ptr< WCondition > WSharedObject< T >::getChangeCondition() const
{
return m_changeCondition;
}
......
......@@ -24,17 +24,16 @@
#include <vector>
#include "../../ext/Eigen/SVD"
#include "../WAssert.h"
#include "WLinearAlgebraFunctions.h"
#include "WMatrix.h"
#include "WMatrix4x4.h"
#include "WValue.h"
#include "WVector3D.h"
#ifdef OW_USE_OSSIM
#include "WOSSIMHelper.h"
#endif
WVector3D multMatrixWithVector3D( WMatrix<double> mat, WVector3D vec )
{
WVector3D result;
......@@ -301,32 +300,32 @@ bool linearIndependent( const WVector3D& u, const WVector3D& v )
return true;
}
void computeSVD( const WMatrix< double >& A,
WMatrix< double >& U,
WMatrix< double >& V,
WValue< double >& S )
void computeSVD( const WMatrix_2& A,
WMatrix_2& U,
WMatrix_2& V,
WVector_2& S )
{
#ifdef OW_USE_OSSIM
WOSSIMHelper::computeSVD( A, U, V, S );
#else
(void) A; (void) U; (void) V; (void) S; // NOLINT to prevent "unused variable" warnings
WAssert( false, "OpenWalnut must be compiled with OSSIM to support SVD." );
#endif
Eigen::JacobiSVD<WMatrix_2> svd( A, Eigen::ComputeFullU | Eigen::ComputeFullV );
U = svd.matrixU();
V = svd.matrixV();
S = svd.singularValues();
}
WMatrix<double> pseudoInverse( const WMatrix<double>& input )
WMatrix_2 pseudoInverse( const WMatrix_2& input )
{
// calc pseudo inverse
WMatrix< double > U( input.getNbRows(), input.getNbCols() );
WMatrix< double > V( input.getNbCols(), input.getNbCols() );
WValue< double > Svec( input.getNbCols() );
WMatrix_2 U( input.rows(), input.cols() );
WMatrix_2 V( input.cols(), input.cols() );
WVector_2 Svec( input.cols() );
computeSVD( input, U, V, Svec );
// create diagonal matrix S
WMatrix< double > S( input.getNbCols(), input.getNbCols() );
for ( size_t i = 0; i < Svec.size() && i < S.getNbRows() && i < S.getNbCols(); i++ )
S( i, i ) = ( Svec[ i ] == 0.0 ) ? 0.0 : 1.0 / Svec[ i ];
WMatrix_2 S( input.cols(), input.cols() );
S.setZero();
for ( int i = 0; i < Svec.size() && i < S.rows() && i < S.cols(); i++ )
{
S( i, i ) = ( Svec[ i ] == 0.0 ) ? 0.0 : 1.0 / Svec[ i ];
}
return WMatrix< double >( V*S*U.transposed() );
return WMatrix_2( V*S*U.transpose() );
}
......@@ -26,6 +26,7 @@
#define WLINEARALGEBRAFUNCTIONS_H
#include "../WExportCommon.h"
#include "WMatrix.h"
namespace osg
{
......@@ -115,8 +116,7 @@ bool OWCOMMON_EXPORT linearIndependent( const WVector3D& u, const WVector3D& v )
*
* \note This function needs the OSSIM library.
*/
void OWCOMMON_EXPORT computeSVD( const WMatrix< double >& A, WMatrix< double >& U,
WMatrix< double >& V, WValue< double >& S );
void OWCOMMON_EXPORT computeSVD( const WMatrix_2& A, WMatrix_2& U, WMatrix_2& V, WVector_2& S );
/**
* Calculates for a matrix the pseudo inverse.
......@@ -126,6 +126,6 @@ void OWCOMMON_EXPORT computeSVD( const WMatrix< double >& A, WMatrix< double >&
* \return Inverted Matrix
*
*/
WMatrix< double > OWCOMMON_EXPORT pseudoInverse( const WMatrix<double>& input );
WMatrix_2 OWCOMMON_EXPORT pseudoInverse( const WMatrix_2& input );
#endif // WLINEARALGEBRAFUNCTIONS_H
......@@ -31,12 +31,83 @@
#include "WValue.h"
#include "WVector3D.h"
#include "../WDefines.h"
#include "../../ext/Eigen/Core"
#include "../../ext/Eigen/LU"
/**
* A double 3 times 3 matrix. Stack-allocated. Column Major!
*
* Column Major indexes:
* [0 3 6
* 1 4 7
* 2 5 8]
* If you want to access coefficients using the operator( size_t, size_t ), the first parameter is still the row index, starting with 0.
*
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html
*/
typedef Eigen::Matrix< double, 3, 3 > WMatrix3x3_2;
/**
* A double 4 times 4 matrix. Stack-allocated. Column Major!
*
* Column Major indexes:
* [0 4 8 12
* 1 5 9 13
* 2 6 10 14
* 3 7 11 15]
* If you want to access coefficients using the operator( size_t, size_t ), the first parameter is still the row index, starting with 0.
*
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html
*/
typedef Eigen::Matrix< double, 4, 4 > WMatrix4x4_2;
/**
* A double matrix of dynamic size. Heap-allocated. Column Major!
* If you want to access coefficients using the operator( size_t, size_t ), the first parameter is still the row index, starting with 0.
*
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html
*/
typedef Eigen::MatrixXd WMatrix_2;
/**
* A complex double matrix of dynamic size. Heap-allocated.
* If you want to access coefficients using the operator( size_t, size_t ), the first parameter is still the row index, starting with 0.
*
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1Matrix.html
* \see http://eigen.tuxfamily.org/dox/classEigen_1_1MatrixBase.html
*/
typedef Eigen::MatrixXcd WMatrixComplex_2;
/**
* Converts a given WMatrix4x4_2 to an osg matrix.
*
* \param m the matrix to convert
*
* \return the converted matrix
*/
inline osg::Matrixd toOsgMatrixd( WMatrix4x4_2 m )
{
osg::Matrixd m2;
for ( size_t row = 0; row < 4; ++row )
{
for ( size_t col = 0; col < 4; ++col )
{
m2( row, col ) = m( row, col );
}
}
return m2;
}
/**
* Matrix template class with variable number of rows and columns.
* The access function are row-major, which means that the rows
* are the first parameter or index.
*/
template< typename T > class WMatrix : public WValue< T >
template< typename T > class OW_API_DEPRECATED WMatrix : public WValue< T >
{
public:
/**
......
......@@ -36,10 +36,12 @@
#include "../WAssert.h"
#include "../WStringUtils.h"
#include "../WDefines.h"
/**
* Use osg 4x4 matrices as WMatrix4x4
*/
typedef osg::Matrixd WMatrix4x4;
OW_API_DEPRECATED typedef osg::Matrixd WMatrix4x4;
/**
* Write a 4x4 matrix in string representation.
......@@ -48,7 +50,7 @@ typedef osg::Matrixd WMatrix4x4;
*
* \return the matrix as string
*/
inline std::string toString( const WMatrix4x4& c )
/*inline std::string toString( const WMatrix4x4& c )
{
std::ostringstream out;
for ( size_t row = 0; row < 4; ++row )
......@@ -60,7 +62,7 @@ inline std::string toString( const WMatrix4x4& c )
}
return out.str();
}
*/
/**
* Read a 4x4 matrix in string representation from the given string.
*
......@@ -68,7 +70,7 @@ inline std::string toString( const WMatrix4x4& c )
*
* \return the matrix
*/
inline WMatrix4x4 fromString( std::string str )
/*inline WMatrix4x4 fromString( std::string str )
{
WMatrix4x4 c;
std::vector< std::string > tokens;
......@@ -86,6 +88,6 @@ inline WMatrix4x4 fromString( std::string str )
}
return c;
}
}*/
#endif // WMATRIX4X4_H
......@@ -34,15 +34,16 @@
#include "WSymmetricSphericalHarmonic.h"
#include "WTensorSym.h"
#include "WUnitSphereCoordinates.h"
#include "WValue.h"
#include "WVector3D.h"
WSymmetricSphericalHarmonic::WSymmetricSphericalHarmonic() :
m_order( 0 ),
m_SHCoefficients( 0 )
m_order( 0 )
// ,
// m_SHCoefficients( 0 )
{
}
WSymmetricSphericalHarmonic::WSymmetricSphericalHarmonic( const WValue<double>& SHCoefficients ) :
WSymmetricSphericalHarmonic::WSymmetricSphericalHarmonic( const WVector_2& SHCoefficients ) :
m_SHCoefficients( SHCoefficients )
{
// calculate order from SHCoefficients.size:
......@@ -57,28 +58,28 @@ WSymmetricSphericalHarmonic::~WSymmetricSphericalHarmonic()
double WSymmetricSphericalHarmonic::getValue( double theta, double phi ) const
{
double result = 0.0;
int j = 0;
const double rootOf2 = std::sqrt( 2.0 );
for ( int k = 0; k <= static_cast<int>( m_order ); k+=2 )
{
// m = 1 .. k
for ( int m = 1; m <= k; m++ )
double result = 0.0;
int j = 0;
const double rootOf2 = std::sqrt( 2.0 );
for ( int k = 0; k <= static_cast<int>( m_order ); k+=2 )
{
j = ( k*k+k+2 ) / 2 + m;
result += m_SHCoefficients[ j-1 ] * rootOf2 *
static_cast<double>( std::pow( -1.0, m+1 ) ) * boost::math::spherical_harmonic_i( k, m, theta, phi );
}
// m = 0
result += m_SHCoefficients[ ( k*k+k+2 ) / 2 - 1 ] * boost::math::spherical_harmonic_r( k, 0, theta, phi );
// m = -k .. -1
for ( int m = -k; m < 0; m++ )
{
j = ( k*k+k+2 ) / 2 + m;
result += m_SHCoefficients[ j-1 ] * rootOf2 * boost::math::spherical_harmonic_r( k, -m, theta, phi );
// m = 1 .. k
for ( int m = 1; m <= k; m++ )
{
j = ( k*k+k+2 ) / 2 + m;
result += m_SHCoefficients[ j-1 ] * rootOf2 *
static_cast<double>( std::pow( -1.0, m+1 ) ) * boost::math::spherical_harmonic_i( k, m, theta, phi );
}
// m = 0
result += m_SHCoefficients[ ( k*k+k+2 ) / 2 - 1 ] * boost::math::spherical_harmonic_r( k, 0, theta, phi );
// m = -k .. -1
for ( int m = -k; m < 0; m++ )
{
j = ( k*k+k+2 ) / 2 + m;
result += m_SHCoefficients[ j-1 ] * rootOf2 * boost::math::spherical_harmonic_r( k, -m, theta, phi );
}
}
}
return result;
return result;
}
double WSymmetricSphericalHarmonic::getValue( const WUnitSphereCoordinates& coordinates ) const
......@@ -86,14 +87,14 @@ double WSymmetricSphericalHarmonic::getValue( const WUnitSphereCoordinates& coor
return getValue( coordinates.getTheta(), coordinates.getPhi() );
}
const WValue<double>& WSymmetricSphericalHarmonic::getCoefficients() const
const WVector_2& WSymmetricSphericalHarmonic::getCoefficients() const
{
return m_SHCoefficients;
}
WValue< double > WSymmetricSphericalHarmonic::getCoefficientsSchultz() const
WVector_2 WSymmetricSphericalHarmonic::getCoefficientsSchultz() const
{
WValue< double > res( m_SHCoefficients.size() );
WVector_2 res( m_SHCoefficients.size() );
size_t k = 0;
for ( int l = 0; l <= static_cast< int >( m_order ); l += 2 )
{
......@@ -114,9 +115,9 @@ WValue< double > WSymmetricSphericalHarmonic::getCoefficientsSchultz() const
return res;
}
WValue< std::complex< double > > WSymmetricSphericalHarmonic::getCoefficientsComplex() const
WVectorComplex_2 WSymmetricSphericalHarmonic::getCoefficientsComplex() const
{
WValue< std::complex< double > > res( m_SHCoefficients.size() );
WVectorComplex_2 res( m_SHCoefficients.size() );
size_t k = 0;
double r = 1.0 / sqrt( 2.0 );
std::complex< double > i( 0.0, -1.0 );
......@@ -187,30 +188,30 @@ double WSymmetricSphericalHarmonic::calcGFA( std::vector< WUnitSphereCoordinates
return gfa;
}
double WSymmetricSphericalHarmonic::calcGFA( WMatrix< double > const& B ) const
double WSymmetricSphericalHarmonic::calcGFA( const WMatrix_2& B ) const
{
// sh coeffs
WMatrix< double > s( B.getNbCols(), 1 );
WAssert( B.getNbCols() == m_SHCoefficients.size(), "" );
for( std::size_t k = 0; k < B.getNbCols(); ++k )
WMatrix_2 s( B.cols(), 1 );
WAssert( B.cols() == m_SHCoefficients.size(), "" );
for( int k = 0; k < B.cols(); ++k )
{
s( k, 0 ) = m_SHCoefficients[ k ];
}
s = B * s;
WAssert( s.getNbRows() == B.getNbRows(), "" );
WAssert( s.getNbCols() == 1u, "" );
WAssert( s.rows() == B.rows(), "" );
WAssert( s.cols() == 1u, "" );
double n = static_cast< double >( s.getNbRows() );
double n = static_cast< double >( s.rows() );
double d = 0.0;
double gfa = 0.0;
double mean = 0.0;
for( std::size_t i = 0; i < s.getNbRows(); ++i )
for( int i = 0; i < s.rows(); ++i )
{
mean += s( i, 0 );
}
mean /= n;
for( std::size_t i = 0; i < s.getNbRows(); ++i )
for( int i = 0; i < s.rows(); ++i )
{
double f = s( i, 0 );
// we use gfa as a temporary here
......@@ -238,12 +239,12 @@ double WSymmetricSphericalHarmonic::calcGFA( WMatrix< double > const& B ) const
return gfa;
}
void WSymmetricSphericalHarmonic::applyFunkRadonTransformation( WMatrix< double > const& frtMat )
void WSymmetricSphericalHarmonic::applyFunkRadonTransformation( const WMatrix_2& frtMat )
{
WAssert( frtMat.getNbCols() == m_SHCoefficients.size(), "" );
WAssert( frtMat.getNbRows() == m_SHCoefficients.size(), "" );
WAssert( frtMat.cols() == m_SHCoefficients.size(), "" );
WAssert( frtMat.rows() == m_SHCoefficients.size(), "" );
// Funk-Radon-Transformation as in Descoteaux's thesis
for ( size_t j = 0; j < m_SHCoefficients.size(); j++ )
for ( int j = 0; j < m_SHCoefficients.size(); j++ )
{
m_SHCoefficients[ j ] *= frtMat( j, j );
}
......@@ -254,7 +255,7 @@ size_t WSymmetricSphericalHarmonic::getOrder() const
return m_order;
}
WMatrix<double> WSymmetricSphericalHarmonic::getSHFittingMatrix( const std::vector< WVector3D >& orientations,
WMatrix_2 WSymmetricSphericalHarmonic::getSHFittingMatrix( const std::vector< WVector3D >& orientations,
int order,
double lambda,
bool withFRT )
......@@ -268,33 +269,34 @@ WMatrix<double> WSymmetricSphericalHarmonic::getSHFittingMatrix( const std::vect
return WSymmetricSphericalHarmonic::getSHFittingMatrix( sphereCoordinates, order, lambda, withFRT );
}
WMatrix<double> WSymmetricSphericalHarmonic::getSHFittingMatrix( const std::vector< WUnitSphereCoordinates >& orientations,
int order,
double lambda,
bool withFRT )
WMatrix_2 WSymmetricSphericalHarmonic::getSHFittingMatrix( const std::vector< WUnitSphereCoordinates >& orientations,
int order,
double lambda,
bool withFRT )
{
WMatrix<double> B( WSymmetricSphericalHarmonic::calcBaseMatrix( orientations, order ) );
WMatrix<double> Bt( B.transposed() );
WMatrix<double> result( Bt*B );
WMatrix_2 B( WSymmetricSphericalHarmonic::calcBaseMatrix( orientations, order ) );
WMatrix_2 Bt( B.transpose() );
WMatrix_2 result( Bt*B );
if ( lambda != 0.0 )
{
WMatrix<double> L( WSymmetricSphericalHarmonic::calcSmoothingMatrix( order ) );
WMatrix_2 L( WSymmetricSphericalHarmonic::calcSmoothingMatrix( order ) );
result += lambda*L;
}
result = pseudoInverse( result )*Bt;
// result *= Bt;
if ( withFRT )
{
WMatrix<double> P( WSymmetricSphericalHarmonic::calcFRTMatrix( order ) );
WMatrix_2 P( WSymmetricSphericalHarmonic::calcFRTMatrix( order ) );
return ( P * result );
}
return result;
}
WMatrix<double> WSymmetricSphericalHarmonic::calcBaseMatrix( const std::vector< WUnitSphereCoordinates >& orientations,
WMatrix_2 WSymmetricSphericalHarmonic::calcBaseMatrix( const std::vector< WUnitSphereCoordinates >& orientations,
int order )
{
WMatrix<double> B( orientations.size(), ( ( order + 1 ) * ( order + 2 ) ) / 2 );
WMatrix_2 B( orientations.size(), ( ( order + 1 ) * ( order + 2 ) ) / 2 );
// calc B Matrix like in the 2007 Descoteaux paper ("Regularized, Fast, and Robust Analytical Q-Ball Imaging")
int j = 0;
......@@ -325,10 +327,10 @@ WMatrix<double> WSymmetricSphericalHarmonic::calcBaseMatrix( const std::vector<
return B;
}
WMatrix< std::complex< double > >
WMatrixComplex_2
WSymmetricSphericalHarmonic::calcComplexBaseMatrix( std::vector< WUnitSphereCoordinates > const& orientations, int order )
{
WMatrix< std::complex< double > > B( orientations.size(), ( ( order + 1 ) * ( order + 2 ) ) / 2 );
WMatrixComplex_2 B( orientations.size(), ( ( order + 1 ) * ( order + 2 ) ) / 2 );
for( std::size_t row = 0; row < orientations.size(); row++ )
{
......@@ -355,11 +357,11 @@ WSymmetricSphericalHarmonic::calcComplexBaseMatrix( std::vector< WUnitSphereCoor
return B;
}
WMatrix<double> WSymmetricSphericalHarmonic::calcSmoothingMatrix( size_t order )