github.com/gopherd/gonum@v0.0.4/optimize/functions/minsurf_test.go (about)

     1  // Copyright ©2015 The Gonum Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package functions
     6  
     7  import (
     8  	"math"
     9  	"testing"
    10  
    11  	"github.com/gopherd/gonum/diff/fd"
    12  	"github.com/gopherd/gonum/floats"
    13  )
    14  
    15  func TestMinimalSurface(t *testing.T) {
    16  	t.Parallel()
    17  	for _, size := range [][2]int{
    18  		{20, 30},
    19  		{30, 30},
    20  		{50, 40},
    21  	} {
    22  		f := NewMinimalSurface(size[0], size[1])
    23  		x0 := f.InitX()
    24  		grad := make([]float64, len(x0))
    25  		f.Grad(grad, x0)
    26  		fdGrad := fd.Gradient(nil, f.Func, x0, &fd.Settings{Formula: fd.Central})
    27  
    28  		// Test that the numerical and analytical gradients agree.
    29  		dist := floats.Distance(grad, fdGrad, math.Inf(1))
    30  		if dist > 1e-9 {
    31  			t.Errorf("grid %v x %v: numerical and analytical gradient do not match. |fdGrad - grad|_∞ = %v",
    32  				size[0], size[1], dist)
    33  		}
    34  
    35  		// Test that the gradient at the minimum is small enough.
    36  		// In some sense this test is not completely correct because ExactX
    37  		// returns the exact solution to the continuous problem projected on the
    38  		// grid, not the exact solution to the discrete problem which we are
    39  		// solving. This is the reason why a relatively loose tolerance 1e-4
    40  		// must be used.
    41  		xSol := f.ExactX()
    42  		f.Grad(grad, xSol)
    43  		norm := floats.Norm(grad, math.Inf(1))
    44  		if norm > 1e-4 {
    45  			t.Errorf("grid %v x %v: gradient at the minimum not small enough. |grad|_∞ = %v",
    46  				size[0], size[1], norm)
    47  		}
    48  	}
    49  }