diff --git a/src/samplefunctional.hh b/src/samplefunctional.hh index f5531bf9871042b1f98d24cda95772d7cc6896c2..e69d3bfa9129917447c8842702679905d2f63183 100644 --- a/src/samplefunctional.hh +++ b/src/samplefunctional.hh @@ -157,6 +157,7 @@ void minimise(const Functional J, const typename Functional::SmallVector x, { // Debug Interval<double> D; JRest.subDiff(0, D); + dverb << "## Directional derivative (as per subdifferential of restriction): " << D[1] << " (coordinates of the restriction)" << std::endl; @@ -164,8 +165,16 @@ void minimise(const Functional J, const typename Functional::SmallVector x, 0); // We should not be minimising in this direction otherwise } - // FIXME: default values are used - Bisection bisection; + // WARNING: + // Using fastquadratic appears to be a very bad idea if D[1] is exactly zero. + // Huge steps that lead us back to where we came from are the result. + Bisection bisection( + 0.0, // acceptError: Stop if the search interval has + // become smaller than this number + 1.0, // acceptFactor: ? + 1e-12, // requiredResidual: ? + false, // fastQuadratic + 1e-14); // safety: acceptance factor for inexact minimization int count; // FIXME: The value of x_old should not matter if the factor is 1.0, correct? double const stepsize = bisection.minimize(JRest, 0.0, 1.0, count); diff --git a/src/test-gradient-method.cc b/src/test-gradient-method.cc index 44df1af2e39bc915d72dc82635b1d5caaf567958..6cc0694c40ee27097d5900544901c00fda83ca97 100644 --- a/src/test-gradient-method.cc +++ b/src/test-gradient-method.cc @@ -294,6 +294,41 @@ void testSampleFunction3D() { assert(std::abs(ret1 - ret3) < 1e-5); } +// Checks if reaching the minimum in one step leads to problems +void testSampleFunction2() { + int const dim = 2; + typedef Dune::SampleFunctional<dim> Functional; + + Functional::SmallMatrix A; + A[0][0] = 1; + A[0][1] = 0; + A[1][0] = 0; + A[1][1] = 1; + Functional::SmallVector b; + b[0] = 1; + b[1] = 1; + + Dune::SampleFunction f; + Functional J(A, b, Dune::MyNonlinearity<dim>(f)); + + Functional::SmallVector start = b; + + double const ret1 = functionTester(J, start, 2); + + // Something random + start[0] = 279; + start[1] = -96; + + double const ret2 = functionTester(J, start, 9); + assert(std::abs(ret1 - ret2) < 1e-5); + + start[0] = 0; + start[1] = 0; + + double const ret3 = functionTester(J, start, 2); + assert(std::abs(ret1 - ret3) < 1e-5); +} + int main() { try { testSampleFunction(); @@ -306,6 +341,8 @@ int main() { std::cout << std::endl << std::endl << std::endl; testHorribleFunctionLogarithmic(); std::cout << std::endl << std::endl << std::endl; + testSampleFunction2(); + std::cout << std::endl << std::endl << std::endl; testSampleFunction3D(); return 0; }