func TestFourDimensionalSoftmaxShouldFail2(t *testing.T) {
	var err error
	model := NewSoftmax(base.StochasticGA, .000001, 0, 3, 1, fdx, fdy)
	err = model.Learn()
	assert.Nil(t, err, "Learning error should be nil")
	var guess []float64
	var incorrect int
	var count int
	for i := -1.0; i < 1.0; i += 0.3 {
		for j := -1.0; j < 1.0; j += 0.3 {
			for k := -1.0; k < 1.0; k += 0.3 {
				guess, err = model.Predict([]float64{i, j, k})
				assert.Len(t, guess, 3, "Length of Softmax hypothesis output should be 3")
				prediction := maxI(guess)
				if i/2+j+2*k > 0 && -1*i-j-0.5*k > 0 {
					if prediction != 2 {
						incorrect++
					}
				} else if i/2+j+2*k > 0 && -1*i-j-0.5*k < 0 {
					if prediction != 1 {
						incorrect++
					}
				} else {
					if prediction != 0 {
						incorrect++
					}
				}
				for _, val := range guess {
					assert.True(t, val < 1.1, "Probability (%v) should always be less than 1", val)
					assert.True(t, val > -0.1, "Probability (%v) should always be greater than 0", val)
				}
				assert.Nil(t, err, "Prediction error should be nil")
				count++
			}
		}
	}
	fmt.Printf("Predictions: %v\n\tIncorrect: %v\n\tAccuracy Rate: %v percent\n", count, incorrect, 100*(1.0-float64(incorrect)/float64(count)))
	assert.True(t, float64(incorrect)/float64(count) > 0.1, "Accuracy should be bad (error rate > 0.1)")
}
same as above but with StochasticGA
package linear
import (
	"fmt"
	"os"
	"testing"
	"github.com/cdipaolo/goml/base"
	"github.com/stretchr/testify/assert"
)
var fdx [][]float64
var fdy []float64
var bdx [][]float64
var bdy []float64
var tdx [][]float64
var tdy []float64
func init() {
	err := os.MkdirAll("/tmp/.goml", os.ModePerm)
	if err != nil {
		panic(fmt.Sprintf("You should be able to create the directory for goml model persistance testing.\n\tError returned: %v\n", err.Error()))
	}
	fdx = [][]float64{}
	fdy = []float64{}
	for i := -2.0; i < 2.0; i += 0.2 {
		for j := -2.0; j < 2.0; j += 0.2 {
			for k := -2.0; k < 2.0; k += 0.2 {
				fdx = append(fdx, []float64{i, j, k})
				if i/2+j+2*k > 0 && -1*i-j-0.5*k > 0 {
					fdy = append(fdy, 2.0)
				} else if i/2+j+2*k > 0 && -1*i-j-0.5*k < 0 {
					fdy = append(fdy, 1.0)
				} else {
					fdy = append(fdy, 0.0)
				}
			}
		}
	}
	bdx = [][]float64{}
	bdy = []float64{}
	for i := -2.0; i < 2.0; i += 0.00073 {
		bdx = append(bdx, []float64{i})
		if i > 0.75 {
			bdy = append(bdy, 4.0)
		} else if i > 0.12 {
			bdy = append(bdy, 3.0)
		} else if i > -0.25 {
			bdy = append(bdy, 2.0)
		} else if i > -0.65 {
			bdy = append(bdy, 1.0)
		} else {
			bdy = append(bdy, 0.0)
		}
	}
	tdx = [][]float64{}
	tdy = []float64{}
	for i := -2.0; i < 2.0; i += 0.15 {
		for j := -2.0; j < 2.0; j += 0.15 {
			tdx = append(tdx, []float64{float64(i), float64(j)})
			if -2*i+j/2-0.5 > 0 && -1*i-j < 0 {
				tdy = append(tdy, 2.0)
			} else if -2*i+j/2-0.5 > 0 && -1*i-j > 0 {
				tdy = append(tdy, 1.0)
			} else {
				tdy = append(tdy, 0.0)
			}
		}
	}
}
func maxI(array []float64) int {
	var i int
	for j := range array {
		if array[j] > array[i] {
			i = j
		}
	}
	return i
}
func TestFourDimensionalSoftmaxShouldPass1(t *testing.T) {
	var err error
	model := NewSoftmax(base.BatchGA, 1e-5, 0, 3, 10, fdx, fdy)
	err = model.Learn()
	assert.Nil(t, err, "Learning error should be nil")
	var guess []float64
	var incorrect int
	var count int
	for i := -1.0; i < 1.0; i += 0.30 {
		for j := -1.0; j < 1.0; j += 0.30 {
			for k := -1.0; k < 1.0; k += 0.30 {
				guess, err = model.Predict([]float64{i, j, k})
				assert.Len(t, guess, 3, "Length of Softmax hypothesis output should be 3")
				prediction := maxI(guess)
				if i/2+j+2*k > 0 && -1*i-j-0.5*k > 0 {
					if prediction != 2 {
						incorrect++
					}
				} else if i/2+j+2*k > 0 && -1*i-j-0.5*k < 0 {
					if prediction != 1 {
						incorrect++
					}
				} else {
					if prediction != 0 {
						incorrect++
					}
				}
				for _, val := range guess {
					assert.True(t, val < 1.1, "Probability (%v) should always be less than 1", val)
					assert.True(t, val > -0.1, "Probability (%v) should always be greater than 0", val)
				}
				assert.Nil(t, err, "Prediction error should be nil")
				count++
			}
		}
	}
	fmt.Printf("Predictions: %v\n\tIncorrect: %v\n\tAccuracy Rate: %v percent\n", count, incorrect, 100*(1.0-float64(incorrect)/float64(count)))
	assert.True(t, float64(incorrect)/float64(count) < 0.14, "Accuracy should be greater than 86%")
}
func TestFourDimensionalSoftmaxShouldPass2(t *testing.T) {
	var err error
	model := NewSoftmax(base.StochasticGA, 1e-5, 0, 3, 10, fdx, fdy)
	err = model.Learn()
	assert.Nil(t, err, "Learning error should be nil")
	var guess []float64
	var incorrect int
	var count int
	for i := -1.0; i < 1.0; i += 0.3 {
		for j := -1.0; j < 1.0; j += 0.3 {
			for k := -1.0; k < 1.0; k += 0.3 {
				guess, err = model.Predict([]float64{i, j, k})
				assert.Len(t, guess, 3, "Length of Softmax hypothesis output should be 3")
				prediction := maxI(guess)
				if i/2+j+2*k > 0 && -1*i-j-0.5*k > 0 {
					if prediction != 2 {
						incorrect++
					}
				} else if i/2+j+2*k > 0 && -1*i-j-0.5*k < 0 {
					if prediction != 1 {
						incorrect++
					}
				} else {
					if prediction != 0 {
						incorrect++
					}
				}
				for _, val := range guess {
					assert.True(t, val < 1.1, "Probability (%v) should always be less than 1", val)
					assert.True(t, val > -0.1, "Probability (%v) should always be greater than 0", val)
				}
				assert.Nil(t, err, "Prediction error should be nil")
				count++
			}
		}
	}
	fmt.Printf("Predictions: %v\n\tIncorrect: %v\n\tAccuracy Rate: %v percent\n", count, incorrect, 100*(1.0-float64(incorrect)/float64(count)))
	assert.True(t, float64(incorrect)/float64(count) < 0.14, "Accuracy should be greater than 86%")
}
func TestFourDimensionalSoftmaxShouldFail1(t *testing.T) {
	var err error
	model := NewSoftmax(base.BatchGA, 1e-7, 0, 3, 1, fdx, fdy)
	err = model.Learn()
	assert.Nil(t, err, "Learning error should be nil")
	var guess []float64
	var incorrect int
	var count int
	for i := -1.0; i < 1.0; i += 0.3 {
		for j := -1.0; j < 1.0; j += 0.3 {
			for k := -1.0; k < 1.0; k += 0.3 {
				guess, err = model.Predict([]float64{i, j, k})
				assert.Len(t, guess, 3, "Length of Softmax hypothesis output should be 3")
				prediction := maxI(guess)
				if i/2+j+2*k > 0 && -1*i-j-0.5*k > 0 {
					if prediction != 2 {
						incorrect++
					}
				} else if i/2+j+2*k > 0 && -1*i-j-0.5*k < 0 {
					if prediction != 1 {
						incorrect++
					}
				} else {
					if prediction != 0 {
						incorrect++
					}
				}
				for _, val := range guess {
					assert.True(t, val < 1.1, "Probability (%v) should always be less than 1", val)
					assert.True(t, val > -0.1, "Probability (%v) should always be greater than 0", val)
				}
				assert.Nil(t, err, "Prediction error should be nil")
				count++
			}
		}
	}
	fmt.Printf("Predictions: %v\n\tIncorrect: %v\n\tAccuracy Rate: %v percent\n", count, incorrect, 100*(1.0-float64(incorrect)/float64(count)))
	assert.True(t, float64(incorrect)/float64(count) > 0.1, "Accuracy should be bad (error rate > 0.1)")
}