func (gp *GP) Add(x []float64, y float64) {
	gp.dirty = true
	gp.inputs = append(gp.inputs, x)
	gp.outputs = append(gp.outputs, y)
}
Add bulk adds XY pairs.
package gp
import (
	"fmt"
	"math"
	"github.com/pkg/errors"
	"gonum.org/v1/gonum/floats"
	"gonum.org/v1/gonum/mat"
	"gonum.org/v1/gonum/stat"
)
var ErrFactorizeFailed = errors.New("failed to factorize")
type GP struct {
	inputs  [][]float64
	outputs []float64
	inputNames []string
	outputName string
	cov   Cov
	noise float64
	alpha        *mat.VecDense
	l            *mat.Cholesky
	mean, stddev float64
	n     int
	dirty bool
}
func New(cov Cov, noise float64) *GP {
	return &GP{
		cov:   cov,
		noise: noise,
	}
}
func (gp *GP) SetNames(inputs []string, output string) {
	gp.inputNames = inputs
	gp.outputName = output
}
func (gp GP) Name(i int) string {
	if len(gp.inputNames) > i {
		name := gp.inputNames[i]
		if len(name) > 0 {
			return name
		}
	}
	return fmt.Sprintf("x[%d]", i)
}
func (gp GP) OutputName() string {
	if len(gp.outputName) > 0 {
		return gp.outputName
	}
	return "y"
}
func (gp GP) RawData() ([][]float64, []float64) {
	inputs := make([][]float64, len(gp.inputs))
	for i, s := range gp.inputs {
		input := make([]float64, len(s))
		copy(input, s)
		inputs[i] = input
	}
	outputs := make([]float64, len(gp.outputs))
	copy(outputs, gp.outputs)
	return inputs, outputs
}
func (gp GP) Dims() int {
	if len(gp.inputs) > 0 {
		return len(gp.inputs[0])
	}
	return 0
}