#ifndef MINIMISATION_HH
#define MINIMISATION_HH

#include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh>
#include <dune/common/stdstreams.hh>

#include <dune/fufem/arithmetic.hh>
#include <dune/fufem/interval.hh>
#include <dune/tnnmg/problem-classes/bisection.hh>

#include "mydirectionalconvexfunction.hh"

template <class Functional>
void descentMinimisation(Functional const &J,
                         typename Functional::SmallVector &x,
                         typename Functional::SmallVector const &v,
                         Bisection const &bisection) {
  using SmallVector = typename Functional::SmallVector;
  using LocalNonlinearity = typename Functional::Nonlinearity;

  MyDirectionalConvexFunction<LocalNonlinearity> const JRest(
      computeDirectionalA(J.A, v), computeDirectionalb(J.A, J.b, x, v), *J.phi,
      x, v);
  // }}}

  int count;
  double const stepsize = bisection.minimize(JRest, 0.0, 0.0, count);

  Arithmetic::addProduct(x, stepsize, v);
}

template <class Functional>
void minimise(Functional const &J, typename Functional::SmallVector &x,
              size_t steps, Bisection const &bisection) {
  using SmallVector = typename Functional::SmallVector;

  for (size_t step = 0; step < steps; ++step) {
    SmallVector v;
    J.gradient(x, v);
    if (v.two_norm() == 0.0)
      return;

    v *= -1;

    descentMinimisation(J, x, v, bisection);
  }
}
#endif