func (s *Softmax) UpdateTrainingSet(trainingSet [][]float64, expectedResults []float64) error {
	if len(trainingSet) == 0 {
		return fmt.Errorf("Error: length of given training set is 0! Need data!")
	}
	if len(expectedResults) == 0 {
		return fmt.Errorf("Error: length of given result data set is 0! Need expected results!")
	}
	s.trainingSet = trainingSet
	s.expectedResults = expectedResults
	return nil
}
UpdateTrainingSet takes in a new training set (variable x)
as well as a new result set (y). This could be useful if
you want to retrain a model starting with the parameter
vector of a previous training session, but most of the time
wouldn't be used.
package linear
import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"math"
	"os"
	"github.com/cdipaolo/goml/base"
)
type Softmax struct {
	alpha          float64
	regularization float64
	maxIterations  int
	k int
	method base.OptimizationMethod
	trainingSet     [][]float64
	expectedResults []float64
	Parameters [][]float64 `json:"theta"`
	Output io.Writer
}
func abs(x float64) float64 {
	if x < 0 {
		return -1 * x
	}
	return x
}
func NewSoftmax(method base.OptimizationMethod, alpha, regularization float64, k, maxIterations int, trainingSet [][]float64, expectedResults []float64, features ...int) *Softmax {
	params := make([][]float64, k)
	if len(features) != 0 {
		for i := range params {
			params[i] = make([]float64, features[0]+1)
		}
	} else if trainingSet == nil || len(trainingSet) == 0 {
		for i := range params {
			params[i] = []float64{}
		}
	} else {
		for i := range params {
			params[i] = make([]float64, len((trainingSet)[0])+1)
		}
	}
	return &Softmax{
		alpha:          alpha,
		regularization: regularization,
		maxIterations:  maxIterations,
		k: k,
		method: method,
		trainingSet:     trainingSet,
		expectedResults: expectedResults,
		Parameters: params,
		Output: os.Stdout,
	}
}