Commit d280e6cf authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[MERGE]

parents e1ad61ec eea0f2b4
......@@ -35,7 +35,7 @@ namespace wmath
*
* WBinom< n, k >::value = n! / ( k!(n-k)! ).
*
* \note For k > n, compilation fails.
* \note For k > n or n == k == 0, compilation fails.
*/
template< std::size_t n, std::size_t k >
struct WBinom
......@@ -98,6 +98,66 @@ struct WBinom< 0, k >
{
};
/**
* Compute the nth power of a value.
*
* For base == exponent == 0, compilation fails.
*/
template< std::size_t base, std::size_t exponent >
struct WPower
{
/**
* Using an enum here instead of a static constant.
*/
enum
{
/**
* The computed value.
*/
value = base * WPower< base, exponent - 1 >::value
};
};
/**
* Compute the nth power of a value.
*
* Specialization for exponent = 0.
*/
template< std::size_t base >
struct WPower< base, 0 >
{
/**
* Using an enum here instead of a static constant.
*/
enum
{
/**
* The computed value.
*/
value = 1
};
};
/**
* Compute the nth power of a value.
*
* Specialization for exponent = 0.
*/
template< std::size_t exponent >
struct WPower< 0, exponent >
{
/**
* Using an enum here instead of a static constant.
*/
enum
{
/**
* The computed value.
*/
value = 0
};
};
} // namespace wmath
#endif // WCOMPILETIMEFUNCTIONS_H
......@@ -43,8 +43,9 @@ namespace wmath
* in each direction.
* The third template parameter is the datatype of the components, which is double by default.
*
* \note The dimension may never be 0.
* \note The type Data_T may not throw exceptions on construction, destruction or
* during operator =.
* during any assignment operator.
*
* Access to specific elements of the tensor can be achieved in 2 ways:
*
......@@ -90,6 +91,15 @@ class WTensor< order, 0, Data_T >
{
};
/**
* Specialization for dim = 0 and order = 0. This essentially prohibits
* instantiation of a 0-dimensional tensor.
*/
template< typename Data_T >
class WTensor< 0, 0, Data_T >
{
};
// ###################### special case WTensor<> of order 0 ##############################
/**
......
......@@ -54,13 +54,16 @@ class WTensorBaseSym;
* the datatype of the elements.
*
* \note The type Data_T may not throw exceptions on construction, destruction or
* during operator =.
* during any assignment operator.
*
* \see WTensor
*/
template< std::size_t order, std::size_t dim, typename Data_T >
class WTensorBase
{
// Make the appropriate tensor of order + 1 a friend, so it has access to the getPos() member.
friend class WTensorBase< order + 1, dim, Data_T >;
public:
friend class WTensor_test;
......@@ -122,12 +125,25 @@ public:
template< typename Index_T >
Data_T const& operator[] ( Index_T const* const indices ) const;
protected:
//friend class WTensorBaseSym< order, dim, Data_T >;
/**
* Compare this WTensorBase to another one.
*
* \param other The WBensorBase to compare to.
*
* \return True, iff this tensors' elements are equal to another tensors' elements.
*/
bool operator == ( WTensorBase const& other );
// Make the appropriate tensor of order + 1 a friend, so it has access to the getPos() member.
friend class WTensorBase< order + 1, dim, Data_T >;
/**
* Compare this WTensorBase to another one.
*
* \param other The WBensorBase to compare to.
*
* \return True, iff this tensors' elements are not equal to another tensors' elements.
*/
bool operator != ( WTensorBase const& other );
protected:
/**
* Standard constructor.
*
......@@ -160,7 +176,7 @@ protected:
* \return The position of the element.
*/
template< typename Index_T >
static inline std::size_t const getPos( Index_T const* const pos );
static inline std::size_t getPos( Index_T const* const pos );
/**
* Get the reference to an element in the data vector.
......@@ -187,7 +203,7 @@ private:
/**
* The number of elements to store.
*/
dataSize = dim * WTensorBase< order - 1, dim, Data_T >::dataSize
dataSize = WPower< dim, order >::value
};
};
......@@ -206,27 +222,14 @@ protected:
* Calculate the position of the element in the data vector. This
* is essentially the standard case of the recursion.
*
* \param pos An array of indices.
*
* \return 0.
*/
template< typename Index_T >
static inline std::size_t const getPos( Index_T const* const pos )
template< typename PIndex_T >
static inline std::size_t getPos( PIndex_T /* pos */ )
{
return 0;
}
/**
* Declare a compile-time constant as enum and not as static constant.
*/
enum
{
/**
* The number of data elements.
*/
dataSize = 1
};
private:
/**
......@@ -266,6 +269,7 @@ template< std::size_t order, std::size_t dim, typename Data_T >
WTensorBase< order, dim, Data_T > const& WTensorBase< order, dim, Data_T >::operator = ( WTensorBase const& t )
{
m_data = t.m_data;
return *this;
}
template< std::size_t order, std::size_t dim, typename Data_T >
......@@ -282,7 +286,7 @@ std::size_t WTensorBase< order, dim, Data_T >::getOrder() const
template< std::size_t order, std::size_t dim, typename Data_T >
template< typename Index_T >
std::size_t const WTensorBase< order, dim, Data_T >::getPos( Index_T const* const pos )
std::size_t WTensorBase< order, dim, Data_T >::getPos( Index_T const* const pos )
{
return WTensorBase< order - 1, dim, Data_T >::getPos( pos ) * dim + pos[ order - 1 ];
}
......@@ -293,10 +297,9 @@ Data_T const& WTensorBase< order, dim, Data_T >::getAt( Index_T const* const pos
{
for( std::size_t k = 0; k < order; ++k )
{
WAssert( pos[ k ] < dim, "" );
WAssert( static_cast< std::size_t >( pos[ k ] ) < dim, "" );
}
std::size_t p = getPos( pos );
WAssert( p < m_data.size(), "" );
return m_data[ p ];
}
......@@ -329,6 +332,18 @@ Data_T const& WTensorBase< order, dim, Data_T >::operator[] ( Index_T const* con
return getAt( indices );
}
template< std::size_t order, std::size_t dim, typename Data_T >
bool WTensorBase< order, dim, Data_T >::operator == ( WTensorBase const& other )
{
return m_data == other.m_data;
}
template< std::size_t order, std::size_t dim, typename Data_T >
bool WTensorBase< order, dim, Data_T >::operator != ( WTensorBase const& other )
{
return m_data != other.m_data;
}
// ################################# class WTensorBaseSym<> #####################################
/**
......@@ -338,7 +353,7 @@ Data_T const& WTensorBase< order, dim, Data_T >::operator[] ( Index_T const* con
* the datatype of the elements.
*
* \note The type Data_T may not throw exceptions on construction, destruction or
* during operator =.
* during any assignment operator.
*
* \see WTensorSym
*/
......@@ -404,6 +419,24 @@ public:
template< typename Index_T >
Data_T const& operator[] ( Index_T const* const indices ) const;
/**
* Compare this WTensorBaseSym to another one.
*
* \param other The WBensorBaseSym to compare to.
*
* \return True, iff this tensors' elements are equal to another tensors' elements.
*/
bool operator == ( WTensorBaseSym const& other );
/**
* Compare this WTensorBaseSym to another one.
*
* \param other The WBensorBaseSym to compare to.
*
* \return True, iff this tensors' elements are not equal to another tensors' elements.
*/
bool operator != ( WTensorBaseSym const& other );
protected:
/**
......@@ -427,7 +460,7 @@ protected:
*
* \return *this.
*/
WTensorBaseSym& operator = ( WTensorBaseSym const& t );
WTensorBaseSym const& operator = ( WTensorBaseSym const& t );
/**
* Get the reference to an element in the data vector.
......@@ -483,7 +516,7 @@ private:
* \return The position that corresponds to the indices.
*/
template< typename Index_T >
inline std::size_t const getAt( Index_T const* const pos ) const;
inline std::size_t getAt( Index_T const* const pos ) const;
using WTensorBase< order, dim, std::size_t >::getPos;
......@@ -515,7 +548,7 @@ private:
*
* \param p The position to copy.
*/
explicit Position( Position const& p );
Position( Position const& p ); // NOLINT not explicit because of std::map
/**
* Increment position.
......@@ -629,7 +662,7 @@ template< std::size_t order, std::size_t dim, typename Data_T >
typename WTensorBaseSym< order, dim, Data_T >::PositionIndexer::Position
WTensorBaseSym< order, dim, Data_T >::PositionIndexer::Position::operator() ()
{
Position res = *this;
Position res( *this );
std::sort( res.begin(), res.end() );
return res;
}
......@@ -687,7 +720,7 @@ WTensorBaseSym< order, dim, Data_T >::PositionIndexer::PositionIndexer()
}
p.clear();
for( std::size_t k = 0; k < WTensorBase< order, dim, std::size_t >::dataSize; ++k )
for( std::size_t k = 0; k < WPower< dim, order >::value; ++k )
{
Position _p( p() );
......@@ -700,7 +733,7 @@ WTensorBaseSym< order, dim, Data_T >::PositionIndexer::PositionIndexer()
template< std::size_t order, std::size_t dim, typename Data_T >
template< typename Index_T >
std::size_t const WTensorBaseSym< order, dim, Data_T >::PositionIndexer::getAt( Index_T const* const pos ) const
std::size_t WTensorBaseSym< order, dim, Data_T >::PositionIndexer::getAt( Index_T const* const pos ) const
{
return this->operator[] ( pos );
}
......@@ -720,9 +753,22 @@ WTensorBaseSym< order, dim, Data_T >::WTensorBaseSym( WTensorBaseSym const& t )
}
template< std::size_t order, std::size_t dim, typename Data_T >
WTensorBaseSym< order, dim, Data_T >& WTensorBaseSym< order, dim, Data_T >::operator = ( WTensorBaseSym const& t )
WTensorBaseSym< order, dim, Data_T > const& WTensorBaseSym< order, dim, Data_T >::operator = ( WTensorBaseSym const& t )
{
m_data = t.m_data;
return *this;
}
template< std::size_t order, std::size_t dim, typename Data_T >
std::size_t WTensorBaseSym< order, dim, Data_T >::getDimension() const
{
return dim;
}
template< std::size_t order, std::size_t dim, typename Data_T >
std::size_t WTensorBaseSym< order, dim, Data_T >::getOrder() const
{
return order;
}
template< std::size_t order, std::size_t dim, typename Data_T >
......@@ -763,6 +809,18 @@ Data_T const& WTensorBaseSym< order, dim, Data_T >::operator[] ( Index_T const*
return getAt( indices );
}
template< std::size_t order, std::size_t dim, typename Data_T >
bool WTensorBaseSym< order, dim, Data_T >::operator == ( WTensorBaseSym const& other )
{
return m_data == other.m_data;
}
template< std::size_t order, std::size_t dim, typename Data_T >
bool WTensorBaseSym< order, dim, Data_T >::operator != ( WTensorBaseSym const& other )
{
return m_data != other.m_data;
}
//template< std::size_t order, std::size_t dim, typename Data_T >
//WTensorBaseSym< order, dim, Data_T >::operator WTensorBase< order, dim, Data_T > () const
//{
......
......@@ -46,8 +46,9 @@ namespace wmath
* in each direction.
* The third template parameter is the datatype of the components, which is double by default.
*
* \note The dimension may never be 0.
* \note The type Data_T may not throw exceptions on construction, destruction or
* during operator =.
* during any assignment operator.
*
* Access to specific elements of the tensor can be achieved in 2 ways:
*
......@@ -63,7 +64,7 @@ namespace wmath
* memory overhead per class (i.e. per allocation of the template parameters), which is of
* constant size and thus does not depend on the number of instances.
*
* Usage and operators are the same as with WTensor. Note, that changes to an
* Usage and operators are the same as with WTensor. Note that changes to an
* element t(i,j,k,...) also change every element whose indices are a permutation of i,j,k... .
* \see WTensor
*/
......@@ -78,6 +79,14 @@ class WTensorSym : public WTensorFunc< WTensorBaseSym, order, dim, Data_T >
// return WTensor< order, T >( *this );
//}
/**
* Disallow instantiation of a symmetric tensor that has a dimension of 0.
*/
template< std::size_t order, typename Data_T >
class WTensorSym< order, 0, Data_T >
{
};
// ###################### special case WTensorSym< T, 0 > ##############################
/**
......
//---------------------------------------------------------------------------
//
// 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 WCOMPILETIMEFUNCTIONS_TEST_H
#define WCOMPILETIMEFUNCTIONS_TEST_H
#include <string>
#include <vector>
#include <cxxtest/TestSuite.h>
#include "../WCompileTimeFunctions.h"
/**
* Test class for WBinom and WPower template.
*/
class WCompileTimeFunctionsTest : public CxxTest::TestSuite
{
public:
/**
* Test WBinom.
*/
void testWBinom()
{
std::size_t value;
value = wmath::WBinom< 1, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 1, 1 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 2, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 2, 1 >::value;
TS_ASSERT_EQUALS( value, 2 );
value = wmath::WBinom< 2, 2 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 3, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 3, 1 >::value;
TS_ASSERT_EQUALS( value, 3 );
value = wmath::WBinom< 3, 2 >::value;
TS_ASSERT_EQUALS( value, 3 );
value = wmath::WBinom< 3, 3 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 4, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 4, 1 >::value;
TS_ASSERT_EQUALS( value, 4 );
value = wmath::WBinom< 4, 2 >::value;
TS_ASSERT_EQUALS( value, 6 );
value = wmath::WBinom< 4, 3 >::value;
TS_ASSERT_EQUALS( value, 4 );
value = wmath::WBinom< 4, 4 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 5, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 5, 1 >::value;
TS_ASSERT_EQUALS( value, 5 );
value = wmath::WBinom< 5, 2 >::value;
TS_ASSERT_EQUALS( value, 10 );
value = wmath::WBinom< 5, 3 >::value;
TS_ASSERT_EQUALS( value, 10 );
value = wmath::WBinom< 5, 4 >::value;
TS_ASSERT_EQUALS( value, 5 );
value = wmath::WBinom< 5, 5 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 6, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WBinom< 6, 1 >::value;
TS_ASSERT_EQUALS( value, 6 );
value = wmath::WBinom< 6, 2 >::value;
TS_ASSERT_EQUALS( value, 15 );
value = wmath::WBinom< 6, 3 >::value;
TS_ASSERT_EQUALS( value, 20 );
value = wmath::WBinom< 6, 4 >::value;
TS_ASSERT_EQUALS( value, 15 );
value = wmath::WBinom< 6, 5 >::value;
TS_ASSERT_EQUALS( value, 6 );
value = wmath::WBinom< 6, 6 >::value;
TS_ASSERT_EQUALS( value, 1 );
}
/**
* Test WPower.
*/
void testWPower()
{
std::size_t value;
value = wmath::WPower< 1, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 2, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 3, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 4, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 5, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 6, 0 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 1, 1 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 2, 1 >::value;
TS_ASSERT_EQUALS( value, 2 );
value = wmath::WPower< 3, 1 >::value;
TS_ASSERT_EQUALS( value, 3 );
value = wmath::WPower< 4, 1 >::value;
TS_ASSERT_EQUALS( value, 4 );
value = wmath::WPower< 5, 1 >::value;
TS_ASSERT_EQUALS( value, 5 );
value = wmath::WPower< 0, 2 >::value;
TS_ASSERT_EQUALS( value, 0 );
value = wmath::WPower< 1, 2 >::value;
TS_ASSERT_EQUALS( value, 1 );
value = wmath::WPower< 2, 2 >::value;
TS_ASSERT_EQUALS( value, 4 );
value = wmath::WPower< 3, 2 >::value;
TS_ASSERT_EQUALS( value, 9 );
value = wmath::WPower< 4, 2 >::value;
TS_ASSERT_EQUALS( value, 16 );
value = wmath::WPower< 5, 2 >::value;
TS_ASSERT_EQUALS( value, 25 );
value = wmath::WPower< 6, 2 >::value;
TS_ASSERT_EQUALS( value, 36 );
value = wmath::WPower< 3, 3 >::value;
TS_ASSERT_EQUALS( value, 27 );
value = wmath::WPower< 4, 3 >::value;
TS_ASSERT_EQUALS( value, 64 );
value = wmath::WPower< 5, 3 >::value;
TS_ASSERT_EQUALS( value, 125 );
value = wmath::WPower< 2, 4 >::value;
TS_ASSERT_EQUALS( value, 16 );
value = wmath::WPower< 3, 4 >::value;
TS_ASSERT_EQUALS( value, 81 );
value = wmath::WPower< 2, 5 >::value;
TS_ASSERT_EQUALS( value, 32 );
value = wmath::WPower< 3, 5 >::value;
TS_ASSERT_EQUALS( value, 243 );
}
};
#endif // WCOMPILETIMEFUNCTIONS_TEST_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 WTENSORSYM_TEST_H
#define WTENSORSYM_TEST_H
#include <string>
#include <vector>
#include <algorithm>
#include <cxxtest/TestSuite.h>
#include "../WTensorSym.h"
/**
* Test class for the WTensorSym template.
*/
class WTensorSymTest : public CxxTest::TestSuite
{
public:
/**