Commit 7357a3ef authored by Blake Nelson's avatar Blake Nelson

*** empty log message ***


git-svn-id: https://gforge.sci.utah.edu/svn/nektar/trunk@196 305cdda6-5ce1-45b3-a98d-dfc68c8b3305
parent e85e4edd
......@@ -53,16 +53,16 @@ namespace Nektar
const Expression<RhsExpressionPolicyType>& rhs,
typename boost::call_traits<ResultType>::reference result)
{
// typedef typename Expression<LhsExpressionPolicyType>::ResultType LhsType;
// typedef typename Expression<RhsExpressionPolicyType>::ResultType RhsType;
// lhs.Apply(result);
// rhs.template ApplyEqual<OpType<LhsType, RhsType> >(result);
typedef typename Expression<LhsExpressionPolicyType>::ResultType LhsType;
typedef typename Expression<RhsExpressionPolicyType>::ResultType RhsType;
LhsType lhs_temp(lhs);
RhsType rhs_temp(rhs);
OpType<LhsType, RhsType>::Apply(result, lhs_temp, rhs_temp);
lhs.Apply(result);
rhs.template ApplyEqual<OpType<LhsType, RhsType> >(result);
// typedef typename Expression<LhsExpressionPolicyType>::ResultType LhsType;
// typedef typename Expression<RhsExpressionPolicyType>::ResultType RhsType;
// LhsType lhs_temp(lhs);
// RhsType rhs_temp(rhs);
//
// OpType<LhsType, RhsType>::Apply(result, lhs_temp, rhs_temp);
}
};
......@@ -384,6 +384,9 @@ namespace Nektar
/**
$Log: BinaryExpression.hpp,v $
Revision 1.7 2006/11/08 04:17:32 bnelson
Made expressions work for complicated, nested expression templates - but suboptimally.
Revision 1.6 2006/11/06 17:07:18 bnelson
Continued work on creating temporaries as needed when sub-expression types don't match the type of the accumulator.
......
......@@ -57,6 +57,26 @@ namespace Nektar
{
return DefaultExpressionMetadata(rhs);
}
static DefaultExpressionMetadata CreateForAddition(const DefaultExpressionMetadata& lhs, const DefaultExpressionMetadata& rhs)
{
return DefaultExpressionMetadata(rhs);
}
static DefaultExpressionMetadata CreateForSubtraction(const DefaultExpressionMetadata& lhs, const DefaultExpressionMetadata& rhs)
{
return DefaultExpressionMetadata(rhs);
}
static DefaultExpressionMetadata CreateForMultiplication(const DefaultExpressionMetadata& lhs, const DefaultExpressionMetadata& rhs)
{
return DefaultExpressionMetadata(rhs);
}
static DefaultExpressionMetadata CreateForDivision(const DefaultExpressionMetadata& lhs, const DefaultExpressionMetadata& rhs)
{
return DefaultExpressionMetadata(rhs);
}
};
template<typename Type, typename enabled=void>
......@@ -79,6 +99,9 @@ namespace Nektar
#endif // NEKTAR_LIB_UTILITIES_EXPRESSION_METADATA_H
/**
$Log: $
$Log: ExpressionMetadata.hpp,v $
Revision 1.1 2006/09/14 02:09:00 bnelson
Fixed gcc compile errors
**/
......@@ -51,16 +51,39 @@
#include <LibUtilities/ExpressionTemplates/UnaryExpression.hpp>
#include <LibUtilities/ExpressionTemplates/UnaryExpressionTraits.hpp>
#include <LibUtilities/ExpressionTemplates/NegateOp.hpp>
#include <LibUtilities/ExpressionTemplates/NullOp.hpp>
#include <LibUtilities/ExpressionTemplates/BinaryExpressionTraits.hpp>
#include <LibUtilities/ExpressionTemplates/BinaryExpression.hpp>
#include <LibUtilities/ExpressionTemplates/BinaryExpressionOperators.hpp>
// Utility macros to generate the operators needed by a class supporting expression templates.
#define ENABLE_EXPRESSION_TEMPLATE_OPERATORS(className) \
expt::Expression<expt::BinaryExpressionPolicy< \
expt::Expression<expt::ConstantExpressionPolicy<className > >, \
expt::Expression<expt::ConstantExpressionPolicy<className > >, expt::AddOp> > \
operator+(const className& lhs, const className& rhs) \
{ \
typedef expt::Expression<expt::ConstantExpressionPolicy<className > > LhsExpressionType; \
typedef expt::Expression<expt::ConstantExpressionPolicy<className > > RhsExpressionType; \
\
return expt::Expression<expt::BinaryExpressionPolicy<LhsExpressionType, RhsExpressionType, expt::AddOp> >(LhsExpressionType(lhs), RhsExpressionType(rhs)); \
}
// Is this the correct place to put high level expression template documentation?
// To create an object that can use expression template:
//
// If you want to be able to add two objects together, you must
// 1. Provide an add method that takes three parameters: lhs, rhs, result.
// 2. Provide a += method.
#endif // NEKTAR_LIB_UTILITIES_EXPRESSION_TEMPLATES_HPP
/**
$Log: ExpressionTemplates.hpp,v $
Revision 1.5 2006/09/11 03:24:24 bnelson
Updated expression templates so they are all specializations of an Expression object, using policies to differentiate.
Revision 1.4 2006/08/28 02:39:53 bnelson
*** empty log message ***
......
......@@ -48,14 +48,6 @@ namespace Nektar
{
namespace expt
{
//template<typename InputExpressionPolicyType, typename RhsExpressionType, typename ResultType, template <typename, typename> class OpType>
//void EvaluateExpression(typename boost::call_traits<LhsExpressionType>::const_reference lhs,
// typename boost::call_traits<RhsExpressionType>::const_reference rhs,
// typename boost::call_traits<ResultType>::reference result,
// typename boost::enable_if<boost::is_same<typename LhsExpressionType::ResultType, ResultType> >::type* f0 = NULL,
// typename boost::enable_if<boost::is_same<typename RhsExpressionType::ResultType, ResultType> >::type* f1 = NULL)
//{
//}
template<typename InputExpressionPolicyType, template <typename> class OpType>
class UnaryExpressionPolicy
......@@ -110,7 +102,7 @@ namespace Nektar
// Evaluate the expression up to this point.
m_value.Apply(result);
// Now apply the negation to the operation.
// Now apply the operator to the result.
OpType<ResultType>::Apply(result);
}
......@@ -121,15 +113,6 @@ namespace Nektar
OpType<ResultType>::Apply(result);
}
// void Apply(typename boost::call_traits<ResultType>::reference result,
// typename boost::disable_if<boost::is_same<ResultType, ParameterType> >::type* = NULL)
// {
// ParameterType temp;
// m_value.Apply(temp);
//
// OpType<ParameterType>::Apply(result, temp);
// }
const MetadataType& GetMetadata() const
{
return m_metadata;
......@@ -154,6 +137,9 @@ namespace Nektar
/**
$Log: UnaryExpression.hpp,v $
Revision 1.6 2006/09/16 23:52:56 bnelson
Changed unary operations to rely on methods outside the class (to aid adding expression templates to classes that can't be modified)
Revision 1.5 2006/09/14 02:08:59 bnelson
Fixed gcc compile errors
......
......@@ -57,13 +57,13 @@ namespace Nektar
++numberConstructedFromInt;
}
CountedObject(const FICounterObject& rhs) :
CountedObject(const CountedObject<DerivedType>& rhs) :
value(rhs.value)
{
++numberCopied;
}
~CountedObject()
virtual ~CountedObject()
{
++numberDestroyed;
}
......@@ -105,26 +105,48 @@ namespace Nektar
unsigned int expectedDestroyed, unsigned int expectedCopied, unsigned int expectedCloned,
unsigned int expectedAssigned)
{
BOOST_CHECK(numberDefaultConstructed == expectedDefaultConstructed);
BOOST_CHECK(numberConstructedFromInt == expectedConstructedFromInt);
BOOST_CHECK(numberDestroyed == expectedDestroyed);
BOOST_CHECK(numberCopied == expectedCopied);
BOOST_CHECK(numberAssigned == expectedAssigned);
BOOST_CHECK(numberCloned == expectedCloned);
BOOST_CHECK_EQUAL(numberDefaultConstructed, expectedDefaultConstructed);
BOOST_CHECK_EQUAL(numberConstructedFromInt, expectedConstructedFromInt);
BOOST_CHECK_EQUAL(numberDestroyed, expectedDestroyed);
BOOST_CHECK_EQUAL(numberCopied, expectedCopied);
BOOST_CHECK_EQUAL(numberAssigned, expectedAssigned);
BOOST_CHECK_EQUAL(numberCloned, expectedCloned);
}
unsigned int value;
static unsigned int numberDefaultConstructed ;
static unsigned int numberDefaultConstructed;
static unsigned int numberConstructedFromInt;
static unsigned int numberDestroyed;
static unsigned int numberCopied;
static unsigned int numberAssigned;
static unsigned int numberCloned;
};
};
template<typename DerivedType>
unsigned int CountedObject<DerivedType>::numberDefaultConstructed = 0;
template<typename DerivedType>
unsigned int CountedObject<DerivedType>::numberConstructedFromInt = 0;
template<typename DerivedType>
unsigned int CountedObject<DerivedType>::numberDestroyed = 0;
template<typename DerivedType>
unsigned int CountedObject<DerivedType>::numberCopied = 0;
template<typename DerivedType>
unsigned int CountedObject<DerivedType>::numberAssigned = 0;
template<typename DerivedType>
unsigned int CountedObject<DerivedType>::numberCloned = 0;
}
#endif //NEKTAR_UNIT_TESTS_COUNTED_OBJECT_H
/**
$Log: $
$Log: CountedObject.h,v $
Revision 1.1 2006/11/11 01:32:52 bnelson
*** empty log message ***
**/
......@@ -34,6 +34,7 @@
///////////////////////////////////////////////////////////////////////////////
#include <UnitTests/testExpressionTemplates.h>
#include <UnitTests/CountedObject.h>
#include <LibUtilities/ExpressionTemplates/ExpressionTemplates.hpp>
......@@ -213,79 +214,115 @@ namespace Nektar
void testNekMatrixSomewhatComplicatedExpression()
{
{
double m1_buf[] = {-85, -55, -37, -35, 97, 50, 79, 56, 49};
double m2_buf[] = {63, 57, -59, 45, -8, -93, 92, 43, -62};
double m3_buf[] = {77, 66, 54, -5, 99, -61, -50, -12, -18};
NekMatrix<double> m1(3, 3, m1_buf);
NekMatrix<double> m2(3, 3, m2_buf);
NekMatrix<double> m3(3, 3, m3_buf);
NekMatrix<double> result = (m1*m2) + m3;
double result_buf[] = {-11157, -5930, 12478, 6755, -522, -10117, 11955, 6150, -12925};
NekMatrix<double> expectedResult(3,3,result_buf);
double epsilon = 1e-11;
for(unsigned int i = 0; i < 3; ++i)
{
for(unsigned int j = 0; j < 3; ++j)
{
BOOST_CHECK_CLOSE(result(i,j), expectedResult(i,j), epsilon);
}
}
NekMatrix<double> result1 = m3 + (m1*m2);
for(unsigned int i = 0; i < 3; ++i)
{
for(unsigned int j = 0; j < 3; ++j)
{
BOOST_CHECK_CLOSE(result1(i,j), expectedResult(i,j), epsilon);
}
}
}
// {
// double m1_buf[] = {-85, -55, -37, -35, 97, 50, 79, 56, 49};
// double m2_buf[] = {63, 57, -59, 45, -8, -93, 92, 43, -62};
// double m3_buf[] = {77, 66, 54, -5, 99, -61, -50, -12, -18};
//
// NekMatrix<double> m1(3, 3, m1_buf);
// NekMatrix<double> m2(3, 3, m2_buf);
// NekMatrix<double> m3(3, 3, m3_buf);
//
// NekMatrix<double> result = (m1*m2) + m3;
//
// double result_buf[] = {-11157, -5930, 12478, 6755, -522, -10117, 11955, 6150, -12925};
// NekMatrix<double> expectedResult(3,3,result_buf);
// double epsilon = 1e-11;
// for(unsigned int i = 0; i < 3; ++i)
// {
// for(unsigned int j = 0; j < 3; ++j)
// {
// BOOST_CHECK_CLOSE(result(i,j), expectedResult(i,j), epsilon);
// }
// }
//
// NekMatrix<double> result1 = m3 + (m1*m2);
// for(unsigned int i = 0; i < 3; ++i)
// {
// for(unsigned int j = 0; j < 3; ++j)
// {
// BOOST_CHECK_CLOSE(result1(i,j), expectedResult(i,j), epsilon);
// }
// }
// }
}
void testNekMatrixComplicatedExpression()
{
{
double m1_buf[] = {-85, -55, -37, -35, 97, 50, 79, 56, 49};
double m2_buf[] = {63, 57, -59, 45, -8, -93, 92, 43, -62};
double m3_buf[] = {31, -26, -62, 1, -47, -91, -47, -61, 41};
NekMatrix<double> m1(3, 3, m1_buf);
NekMatrix<double> m2(3, 3, m2_buf);
NekMatrix<double> m3(3, 3, m3_buf);
// {
// double m1_buf[] = {-85, -55, -37, -35, 97, 50, 79, 56, 49};
// double m2_buf[] = {63, 57, -59, 45, -8, -93, 92, 43, -62};
// double m3_buf[] = {31, -26, -62, 1, -47, -91, -47, -61, 41};
//
// NekMatrix<double> m1(3, 3, m1_buf);
// NekMatrix<double> m2(3, 3, m2_buf);
// NekMatrix<double> m3(3, 3, m3_buf);
//
// NekMatrix<double> result = (((m3-m1)*m3) * (m1-m2)) + m1*m2*m3;
//
// double result_buf[] = {-1279130, -1162366, 243990, -1663904, 1197403, 2021293, 547959, 1802365, 1422677};
// NekMatrix<double> expectedResult(3,3,result_buf);
//
// double epsilon = 1e-11;
// for(unsigned int i = 0; i < 3; ++i)
// {
// for(unsigned int j = 0; j < 3; ++j)
// {
// BOOST_CHECK_CLOSE(result(i,j), expectedResult(i,j), epsilon);
// }
// }
// }
}
class TestTemporary : public CountedObject<TestTemporary>
{
public:
TestTemporary() : CountedObject<TestTemporary>() {}
TestTemporary(const TestTemporary& rhs) : CountedObject<TestTemporary>(rhs) {}
virtual ~TestTemporary() {}
TestTemporary& operator=(const TestTemporary& rhs) { CountedObject<TestTemporary>::operator=(rhs); return *this; }
NekMatrix<double> result = (((m3-m1)*m3) * (m1-m2)) + m1*m2*m3;
template<typename PolicyType>
TestTemporary(const expt::Expression<PolicyType>& rhs) : CountedObject<TestTemporary>()
{
//BOOST_MPL_ASSERT(( boost::is_same<typename expt::Expression<PolicyType>::ResultType, TestTemporary ));
rhs.Apply(*this);
}
double result_buf[] = {-1279130, -1162366, 243990, -1663904, 1197403, 2021293, 547959, 1802365, 1422677};
NekMatrix<double> expectedResult(3,3,result_buf);
template<typename PolicyType>
TestTemporary& operator=(const expt::Expression<PolicyType>& rhs)
{
//BOOST_MPL_ASSERT(( boost::is_same<typename expt::Expression<PolicyType>::ResultType, TestTemporary ));
rhs.Apply(*this);
return *this;
}
double epsilon = 1e-11;
for(unsigned int i = 0; i < 3; ++i)
TestTemporary& operator+=(const TestTemporary& rhs)
{
for(unsigned int j = 0; j < 3; ++j)
{
BOOST_CHECK_CLOSE(result(i,j), expectedResult(i,j), epsilon);
}
return *this;
}
}
}
class CountedMatrix : public Nektar::NekMatrix<double>
{
private:
};
class CountedVector : public Nektar::NekVector<double>
void add(const TestTemporary& lhs, const TestTemporary& rhs, TestTemporary& result)
{
};
}
ENABLE_EXPRESSION_TEMPLATE_OPERATORS(TestTemporary);
// For these tests I will be testing items of the form A = B op C, where I vary
// the data types for A, B, and C, as well as op types, to get all possible combinations.
void testTemporaryGenerationFromSingleLevelBinaryExpressions()
{
TestTemporary a;
TestTemporary b;
CountedObject<TestTemporary>::clearCounters();
TestTemporary c = a + b;
CountedObject<TestTemporary>::check(1, 0, 0, 0, 0, 1);
}
}
......@@ -293,6 +330,9 @@ namespace Nektar
/**
$Log: testExpressionTemplates.cpp,v $
Revision 1.10 2006/11/11 01:32:52 bnelson
*** empty log message ***
Revision 1.9 2006/11/08 04:18:22 bnelson
Added more expression template tests.
......
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