Commit 6c346300 authored by Oliver Sander's avatar Oliver Sander
Browse files

Start writing a generic set of unit tests for convex functionals

These things can get really complicated, and small errors can go unnoticed
for a long time.

This first patch adds a first test for convexity, and applies it to the
NormFunctional class.
parent 7dac50bf
add_subdirectory("test")
install(FILES
convexfunctional.hh
cubeindicatorfunctional.hh
......
set(TESTS
normfunctionaltest
)
add_directory_test_target(_test_target)
add_dependencies(${_test_target} ${TESTS})
foreach(_test ${TESTS})
add_executable(${_test} ${_test}.cc)
target_link_libraries(${_test} ${DUNE_LIBS})
add_test(${_test} ${_test})
endforeach()
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_TNNMG_FUNCTIONALS_FUNCTIONALTEST_HH
#define DUNE_TNNMG_FUNCTIONALS_FUNCTIONALTEST_HH
/** \file
* \brief Contains various unit tests for nonlinear convex functionals
*/
namespace Dune {
namespace TNNMG {
/** \brief Test whether functional is convex
* \tparam Functional Type of the functional to be tested
* \param functional The functional to be tested
* \param testPoints Test convexity along segment between pairs of these points
*/
template <class Functional>
void testConvexity(const Functional& functional,
const std::vector<typename Functional::VectorType>& testPoints)
{
for (size_t i=0; i<testPoints.size(); i++)
for (size_t j=0; j<testPoints.size(); j++)
{
// short-hand for the two test points
const auto& p0 = testPoints[i];
const auto& p1 = testPoints[j];
// pre-compute functional values at the segment ends
double v0 = functional(p0);
double v1 = functional(p1);
// Test convexity at a few selected points between the two test points
for (double t : {0.0, 0.2, 0.4, 0.6, 0.8, 1.0})
{
// convex combination between the two test points
typename Functional::VectorType p(p0.size());
for (size_t k=0; k<p0.size(); k++)
for (size_t l=0; l<p0[k].size(); l++)
p[k][l] = (1-t)*p0[k][l] + t*p1[k][l];
// Test for convexity
if (functional(p) > ((1-t)*v0 + t*v1))
DUNE_THROW(Exception, "Functional is not convex!");
}
}
}
} // namespace TNNMG
} // namespace Dune
#endif // DUNE_TNNMG_FUNCTIONALS_FUNCTIONALTEST_HH
\ No newline at end of file
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#include <config.h>
#include <iostream>
#include <dune/tnnmg/functionals/normfunctional.hh>
#include <dune/tnnmg/functionals/test/functionaltest.hh>
using namespace Dune;
int main(int argc, char** argv) try
{
// Create a norm functional on (R^3)^2 for testing
std::vector<double> coefficients = {2.0, 3.0};
typedef TNNMG::NormFunctional<3> Functional;
Functional functional(coefficients);
// A set of local test points, i.e., values for a single vector block
std::vector<Functional::LocalVectorType> localTestPoints = {{0,0,0},
{1,0,0},
{0,-2,0},
{3.14,3.14,-4}};
// Create real test points (i.e., block vectors) from the given values for a single block
// TODO: Construct more combinations
std::vector<Functional::VectorType> testPoints(localTestPoints.size());
for (size_t i=0; i<testPoints.size(); i++)
{
testPoints[i].resize(coefficients.size());
std::fill(testPoints[i].begin(), testPoints[i].end(), localTestPoints[i]);
}
// Test whether the functional is convex
testConvexity(functional, testPoints);
return 0;
}
catch (Exception e)
{
std::cout << e << std::endl;
}
\ No newline at end of file
Supports Markdown
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