From ef695ed05c84593dd101caebb59db70523f1fa75 Mon Sep 17 00:00:00 2001 From: Elias Pipping <elias.pipping@fu-berlin.de> Date: Mon, 5 Sep 2011 17:40:13 +0200 Subject: [PATCH] Populate with sample code --- src/Makefile.am | 41 ++++--- src/bisection-simpler-example.cc | 53 +++++++++ src/bisection-simpler-example2-gradient.cc | 125 +++++++++++++++++++++ src/bisection-simpler-example2.cc | 58 ++++++++++ 4 files changed, 256 insertions(+), 21 deletions(-) create mode 100644 src/bisection-simpler-example.cc create mode 100644 src/bisection-simpler-example2-gradient.cc create mode 100644 src/bisection-simpler-example2.cc diff --git a/src/Makefile.am b/src/Makefile.am index 963b653b..a57492b1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,33 +1,32 @@ SUBDIRS = -noinst_PROGRAMS = dune_tectonic - -dune_tectonic_SOURCES = dune_tectonic.cc - -dune_tectonic_CPPFLAGS = $(AM_CPPFLAGS) \ - $(DUNEMPICPPFLAGS) \ - $(UG_CPPFLAGS) \ - $(AMIRAMESH_CPPFLAGS) \ - $(ALBERTA_CPPFLAGS) \ +noinst_PROGRAMS = \ + bisection-simpler-example \ + bisection-simpler-example2 \ + bisection-simpler-example2-gradient + +bisection_simpler_example_SOURCES = bisection-simpler-example.cc +bisection_simpler_example2_SOURCES = bisection-simpler-example2.cc +bisection_simpler_example2_gradient_SOURCES = bisection-simpler-example2-gradient.cc + +check-am: + ./bisection-simpler-example + ./bisection-simpler-example2 + ./bisection-simpler-example2-gradient + +AM_CPPFLAGS = \ + $(DUNE_CPPFLAGS) \ $(ALUGRID_CPPFLAGS) + # The libraries have to be given in reverse order (most basic libraries # last). Also, due to some misunderstanding, a lot of libraries include the # -L option in LDFLAGS instead of LIBS -- so we have to include the LDFLAGS # here as well. -dune_tectonic_LDADD = \ +LDADD = \ $(DUNE_LDFLAGS) $(DUNE_LIBS) \ - $(ALUGRID_LDFLAGS) $(ALUGRID_LIBS) \ - $(ALBERTA_LDFLAGS) $(ALBERTA_LIBS) \ - $(AMIRAMESH_LDFLAGS) $(AMIRAMESH_LIBS) \ - $(UG_LDFLAGS) $(UG_LIBS) \ - $(DUNEMPILIBS) \ - $(LDADD) -dune_tectonic_LDFLAGS = $(AM_LDFLAGS) \ - $(DUNEMPILDFLAGS) \ - $(UG_LDFLAGS) \ - $(AMIRAMESH_LDFLAGS) \ - $(ALBERTA_LDFLAGS) \ + $(ALUGRID_LDFLAGS) $(ALUGRID_LIBS) +AM_LDFLAGS = \ $(ALUGRID_LDFLAGS) \ $(DUNE_LDFLAGS) diff --git a/src/bisection-simpler-example.cc b/src/bisection-simpler-example.cc new file mode 100644 index 00000000..f3ca7273 --- /dev/null +++ b/src/bisection-simpler-example.cc @@ -0,0 +1,53 @@ +#include <dune/fufem/interval.hh> + +#include <dune/tnnmg/nonlinearities/smallfunctional.hh> +#include <dune/tnnmg/problem-classes/bisection.hh> + +#include <cassert> +#include <limits> + +class SampleFunctional : public SmallFunctional<2> { +public: + SampleFunctional(SmallMatrix A, SmallVector b) : A_(A), b_(b) {} + + double operator()(const SmallVector v) const { + SmallVector y; + A_.mv(v, y); // y = Av + y /= 2; // y = 1/2 Av + y -= b_; // y = 1/2 Av - b + return y * v; // <1/2 Av - b,v> + } + + SmallVector d(const SmallVector v) const { + SmallVector y; + A_.mv(v, y); // y = Av + y -= b_; // y = Av - b + return y; + } + + SmallMatrix d2(const SmallVector v) const { return A_; } + +private: + SmallMatrix A_; + SmallVector b_; +}; + +int main() { + int dim = 2; + SampleFunctional::SmallMatrix A; + A[0][0] = 3; + A[0][1] = 0; + A[1][0] = 0; + A[1][1] = 3; + SampleFunctional::SmallVector b; + b[0] = 1; + b[1] = 2; + + SampleFunctional J(A, b); + + assert(J(b) == 2.5); + + assert(b.two_norm() == sqrt(5)); + assert(b.two_norm2() == 5); + return 0; +} diff --git a/src/bisection-simpler-example2-gradient.cc b/src/bisection-simpler-example2-gradient.cc new file mode 100644 index 00000000..2637a48f --- /dev/null +++ b/src/bisection-simpler-example2-gradient.cc @@ -0,0 +1,125 @@ +// FIXME: is there a bette way to do this? +//#define DUNE_MINIMAL_DEBUG_LEVEL 2 +#include <dune/common/stdstreams.hh> + +#include <dune/fufem/interval.hh> + +#include <dune/tnnmg/nonlinearities/smallfunctional.hh> +#include <dune/tnnmg/problem-classes/bisection.hh> + +#include <cassert> +#include <limits> + +template <int dimension> +class SampleFunctional : public SmallFunctional<dimension> { +public: + typedef typename SmallFunctional<dimension>::SmallMatrix SmallMatrix; + typedef typename SmallFunctional<dimension>::SmallVector SmallVector; + + SampleFunctional(SmallMatrix A, SmallVector b) : A_(A), b_(b) {} + + double operator()(const SmallVector v) const { + SmallVector y; + A_.mv(v, y); // y = Av + y /= 2; // y = 1/2 Av + y -= b_; // y = 1/2 Av - b + return y * v; // <1/2 Av - b,v> + } + + SmallVector d(const SmallVector v) const { + SmallVector y; + A_.mv(v, y); // y = Av + y -= b_; // y = Av - b + return y; + } + + SmallMatrix d2(const SmallVector v) const { return A_; } + + // extending the interface here + double directionalDerivative(const SmallVector x, + const SmallVector dir) const { + SmallVector grad = d(x); + return grad * dir; + } + + SmallVector minimise(const SmallVector x, int iterations) const { + SmallVector descDir = d(x); + descDir *= -1; // The negative gradient + + Dune::dverb << "Starting at x with J(x) = " << operator()(x) << std::endl; + Dune::dverb << "Minimizing in direction w with dJ(x,w) = " + << directionalDerivative(x, descDir) << std::endl; + + double l = 0; + double r = 1; + SmallVector tmp = descDir; + tmp *= r; + while (directionalDerivative(x + tmp, descDir) < 0) { + l = r; + r *= 2; + tmp *= 2; + Dune::dverb << "Widened interval!" << std::endl; + } + Dune::dverb << "Interval now [" << l << "," << r << "]" << std::endl; + + // Debugging + { + SmallVector tmpl = tmp; + tmpl *= l; + SmallVector tmpr = tmp; + tmpr *= r; + assert(directionalDerivative(x + tmpl, descDir) < 0); + assert(directionalDerivative(x + tmpr, descDir) > 0); + } + + double m = l / 2 + r / 2; + SmallVector middle; + for (size_t count = 0; count < iterations; ++count) { + Dune::dverb << "now at m = " << m << std::endl; + Dune::dverb << "Value of J here: " << operator()(x + middle) << std::endl; + + middle = descDir; + middle *= m; + + double derivative = directionalDerivative(x + middle, descDir); + + if (derivative < 0) { + l = m; + m = (m + r) / 2; + } else if (derivative > 0) { + r = m; + m = (l + m) / 2; + } else + break; + } + return middle; + } + +private: + SmallMatrix A_; + SmallVector b_; +}; + +int main() { + int const dim = 2; + typedef SampleFunctional<dim> SampleFunctional; + + SampleFunctional::SmallMatrix A; + A[0][0] = 3; + A[0][1] = 0; + A[1][0] = 0; + A[1][1] = 3; + SampleFunctional::SmallVector b; + b[0] = 1; + b[1] = 2; + + SampleFunctional J(A, b); + + SampleFunctional::SmallVector start = b; + start *= 17; + SampleFunctional::SmallVector correction = J.minimise(start, 20); + assert(J(start + correction) <= J(start)); + std::cout << J(start + correction) << std::endl; + + return 0; +} diff --git a/src/bisection-simpler-example2.cc b/src/bisection-simpler-example2.cc new file mode 100644 index 00000000..dde6268c --- /dev/null +++ b/src/bisection-simpler-example2.cc @@ -0,0 +1,58 @@ +#include <dune/fufem/interval.hh> + +#include <dune/tnnmg/nonlinearities/smallfunctional.hh> +#include <dune/tnnmg/problem-classes/bisection.hh> + +#include <cassert> +#include <limits> + +template <int dimension> +class SampleFunctional : public SmallFunctional<dimension> { +public: + typedef typename SmallFunctional<dimension>::SmallMatrix SmallMatrix; + typedef typename SmallFunctional<dimension>::SmallVector SmallVector; + + SampleFunctional(SmallMatrix A, SmallVector b) : A_(A), b_(b) {} + + double operator()(const SmallVector v) const { + SmallVector y; + A_.mv(v, y); // y = Av + y /= 2; // y = 1/2 Av + y -= b_; // y = 1/2 Av - b + return y * v; // <1/2 Av - b,v> + } + + SmallVector d(const SmallVector v) const { + SmallVector y; + A_.mv(v, y); // y = Av + y -= b_; // y = Av - b + return y; + } + + SmallMatrix d2(const SmallVector v) const { return A_; } + +private: + SmallMatrix A_; + SmallVector b_; +}; + +int main() { + int const dim = 2; + + SampleFunctional<dim>::SmallMatrix A; + A[0][0] = 3; + A[0][1] = 0; + A[1][0] = 0; + A[1][1] = 3; + SampleFunctional<dim>::SmallVector b; + b[0] = 1; + b[1] = 2; + + SampleFunctional<dim> J(A, b); + + assert(J(b) == 2.5); + + assert(b.two_norm() == sqrt(5)); + assert(b.two_norm2() == 5); + return 0; +} -- GitLab