Skip to content
Snippets Groups Projects
Commit 39773c1e authored by andrew-torda's avatar andrew-torda
Browse files

Ackley function working and tests seem OK.

parents
No related branches found
No related tags found
No related merge requests found
// Put ackley in here, so we can also write a little test
// We will code it in the n-dimensional version, even if we do not need it.
// Hard-coding 2, 3 or 4 dimensions would be faster (no for loop), but not so elegant.
package ackley
import (
"math"
)
const (
a float64 = 20
b = 0.2
c = 2 * math.Pi
)
// ackley calculates the n-dimensional ackley function for a slice x. The constants
// are hard-coded above.
func Ackley(x []float32) float64 {
var sum1, sum2 float64
for i := range x {
xx := float64(x[i])
sum1 += xx * xx
}
sum1 /= float64(len(x))
sum1 = math.Sqrt(sum1)
sum1 *= -b
sum1 = -a * math.Exp(sum1)
for i := range x {
sum2 += math.Cos(c * float64(x[i]))
}
sum2 /= float64(len(x))
sum2 = math.Exp(sum2)
t := sum1 - sum2 + a + math.E
return t
}
// 5 Aug 2021
// It is a bit hard to really test, but I can write a file that we
// can feed to something like gnuplot.
package ackley_test
import (
. "ackley"
"fmt"
"io"
"os"
"testing"
)
// A gridsize has a min and max and the number of increments between
type grdsz struct {
xmin, xmax float32
ninc int
}
func TestAckleyNd(t *testing.T) {
const tol = 1e-10
for i := 0; i < 10; i++ {
x := make([]float32, i)
y := Ackley(x)
if y < 0 {
y = -y
}
if y > tol {
t.Errorf("Ackley with %d dimension, got %g wanted 0", i, y)
}
}
}
func loopOver(x []float32, idim int, fOut io.Writer, grid grdsz) {
idim--
xinc := (grid.xmax - grid.xmin) / float32(grid.ninc-1)
for i := 0; i < grid.ninc; i++ {
x[idim] = grid.xmin + float32(i)*xinc
if idim > 0 {
loopOver(x, idim, fOut, grid)
}
if i == grid.ninc-1 {
if !(i == len(x)-1 && idim == len(x)-1) {
return
}
}
fmt.Fprintf(fOut, "%g", Ackley(x))
for _, r := range x {
fmt.Fprintf(fOut, ",%g", r)
}
fmt.Fprintln(fOut)
}
}
func TestAckley1d(t *testing.T) {
plotNotes := `# plotme with gnuplot plot1d.gplt
set datafile sep ","
set xlabel 'x'
set ylabel "ackley"
set term "jpeg"
set output "test1d.jpg"
plot 'test1d.dat' us 2:1 with line`
const fOutName = "test1d_delme.dat"
const plotNoteName = "plot1d_delme.gplt"
grid := grdsz{-10, 10, 500}
if fp, err := os.Create(fOutName); err != nil {
t.Errorf("fail create %s", fOutName)
} else {
defer fp.Close()
inc := (grid.xmax - grid.xmin) / float32(grid.ninc)
var xx [1]float32
for xx[0] = grid.xmin; xx[0] <= grid.xmax; xx[0] += inc {
fmt.Fprintf(fp, "%g,%g\n", Ackley(xx[:]), xx[0])
}
}
if fp, err := os.Create(plotNoteName); err != nil {
t.Errorf("opening %s", plotNoteName)
} else {
if _, err := fp.Write([]byte(plotNotes)); err != nil {
t.Errorf("Writing to %s", plotNoteName)
}
}
}
// TestAckley2d
func TestAckley2d(t *testing.T) {
plotNotes := `# plotme with gnuplot plot2d.gplt
set datafile sep ","
set xlab 'x'; set ylab 'y'
set zlabel "ackley"
set term "jpeg"
set output "test2d.jpg"
splot 'test2d.dat' us 2:3:1 with points`
const fOutName = "test2d_delme.dat"
const plotNoteName = "plot2d_delme.gplt"
grid := grdsz{-5, 5, 40}
var ioWrt io.Writer
if fp, err := os.Create(fOutName); err != nil {
t.Errorf("fail")
} else {
defer fp.Close()
ioWrt = fp
}
x := make([]float32, 2)
loopOver(x, 2, ioWrt, grid)
if fp, err := os.Create(plotNoteName); err != nil {
t.Errorf("opening %s", plotNoteName)
} else {
if _, err := fp.Write([]byte(plotNotes)); err != nil {
t.Errorf("Writing to %s", plotNoteName)
}
}
}
the ackley function .. in the word file
Run dlv in emacs under windows
dlv --allow-non-terminal-interactive=true debug
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment