// Copyright ©2015 The gonum Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package functions import ( "math" "testing" "github.com/gonum/diff/fd" "github.com/gonum/floats" ) func TestMinimalSurface(t *testing.T) { for _, size := range [][2]int{ {20, 30}, {30, 30}, {50, 40}, } { f := NewMinimalSurface(size[0], size[1]) x0 := f.InitX() grad := make([]float64, len(x0)) f.Grad(grad, x0) fdGrad := fd.Gradient(nil, f.Func, x0, &fd.Settings{Formula: fd.Central}) // Test that the numerical and analytical gradients agree. dist := floats.Distance(grad, fdGrad, math.Inf(1)) if dist > 1e-9 { t.Errorf("grid %v x %v: numerical and analytical gradient do not match. |fdGrad - grad|_∞ = %v", size[0], size[1], dist) } // Test that the gradient at the minimum is small enough. // In some sense this test is not completely correct because ExactX // returns the exact solution to the continuous problem projected on the // grid, not the exact solution to the discrete problem which we are // solving. This is the reason why a relatively loose tolerance 1e-4 // must be used. xSol := f.ExactX() f.Grad(grad, xSol) norm := floats.Norm(grad, math.Inf(1)) if norm > 1e-4 { t.Errorf("grid %v x %v: gradient at the minimum not small enough. |grad|_∞ = %v", size[0], size[1], norm) } } }