Skip to content
Snippets Groups Projects
Forked from agnumpde / dune-tectonic
771 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
test-gradient-sample.cc 1.63 KiB
/* Checks if the descent direction is computed correctly using the
   analytic solution; also checks if the algorithm converges
   regardless of where it starts */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <cassert>

#include <dune/common/shared_ptr.hh>

#include <dune/tectonic/samplefunctional.hh>

#include "test-gradient-method-nicefunction.hh"
#include "test-gradient-method-helper.hh"

int main() {
  int const dim = 2;
  typedef Dune::SampleFunctional<dim> Functional;
  typedef Functional::SmallMatrix SmallMatrix;
  typedef Functional::SmallVector SmallVector;

  SmallMatrix A;
  A[0][0] = 3;
  A[0][1] = A[1][0] = 1.5;
  A[1][1] = 4;
  SmallVector b;
  b[0] = 1;
  b[1] = 2;

  auto f = Dune::make_shared<Dune::SampleFunction<2> const>();
  auto phi = Dune::make_shared<Functional::NonlinearityType const>(f);
  Functional J(A, b, phi);

  SmallVector start = b;
  start *= 17;

  /*
    j(x)
    = Ax - b + 2/|x| x
    = 17*(6, 9.5) - (1, 2) + 2/sqrt(5) (1, 2)
    = (102 - 1 + 2/sqrt(5), 161.5 - 2 + 4/sqrt(5))
  */
  SmallVector analytic_descent;
  analytic_descent[0] = -(102 - 1 + 2 / sqrt(5));
  analytic_descent[1] = -(161.5 - 2 + 4 / sqrt(5));
  SmallVector numerical_descent;
  J.descentDirection(start, numerical_descent);
  assert(two_distance<dim>(analytic_descent, numerical_descent) < 1e-10);

  double const ret1 = functionTester(J, start, 6);

  // Something random
  start[0] = 279;
  start[1] = -96;

  double const ret2 = functionTester(J, start, 10);
  assert(std::abs(ret1 - ret2) < 1e-5);

  start[0] = 0;
  start[1] = 0;

  double const ret3 = functionTester(J, start, 3);
  assert(std::abs(ret1 - ret3) < 1e-5);
}