diff --git a/grow/definition.go b/grow/definition.go index f23a717..2024cb6 100644 --- a/grow/definition.go +++ b/grow/definition.go @@ -76,7 +76,7 @@ func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) { Mutate(def, prog) - scores, err := def.score(prog) + scores, err := def.Score(prog) if err != nil { // Can never get best score continue @@ -104,23 +104,7 @@ func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) { } } -func (def *Definition) buildSampleRanks() { - for col := 0; col < len(def.Samples[0].Out); col++ { - rank := []int{} - - for i := 0; i < len(def.Samples); i++ { - rank = append(rank, i) - } - - sort.SliceStable(rank, func(i, j int) bool { - return def.Samples[i].Out[col] < def.Samples[j].Out[col] - }) - - def.SampleRanks = append(def.SampleRanks, rank) - } -} - -func (def *Definition) score(prog *vm.Program) ([]*Score, error) { +func (def *Definition) GetOutputs(prog *vm.Program) ([][]uint64, error) { outputs := [][]uint64{} for _, sample := range def.Samples { @@ -144,16 +128,25 @@ func (def *Definition) score(prog *vm.Program) ([]*Score, error) { outputs = append(outputs, output) } + return outputs, nil +} + +func (def *Definition) Score(prog *vm.Program) ([]*Score, error) { + outputs, err := def.GetOutputs(prog) + if err != nil { + return nil, err + } + // TODO: Points for proximity to target values? // TODO: Points for correlation coeficient with target values across samples? return []*Score{ - def.scoreMatching(outputs), - def.scoreRank(outputs), + def.ScoreMatching(outputs), + def.ScoreRank(outputs), }, nil } -func (def *Definition) scoreMatching(outputs [][]uint64) *Score { +func (def *Definition) ScoreMatching(outputs [][]uint64) *Score { ret := &Score{} for s, sample := range def.Samples { @@ -169,7 +162,7 @@ func (def *Definition) scoreMatching(outputs [][]uint64) *Score { return ret } -func (def *Definition) scoreRank(outputs [][]uint64) *Score { +func (def *Definition) ScoreRank(outputs [][]uint64) *Score { ranks := [][]int{} for col := 0; col < len(outputs[0]); col++ { @@ -201,6 +194,22 @@ func (def *Definition) scoreRank(outputs [][]uint64) *Score { return ret } +func (def *Definition) buildSampleRanks() { + for col := 0; col < len(def.Samples[0].Out); col++ { + rank := []int{} + + for i := 0; i < len(def.Samples); i++ { + rank = append(rank, i) + } + + sort.SliceStable(rank, func(i, j int) bool { + return def.Samples[i].Out[col] < def.Samples[j].Out[col] + }) + + def.SampleRanks = append(def.SampleRanks, rank) + } +} + func (def *Definition) scoreIsBetter(old, new []*Score) bool { if old == nil { return true @@ -247,7 +256,7 @@ func (def *Definition) minifyProgram(prog *vm.Program) error { } func (def *Definition) minifyFunction(prog *vm.Program, f int) error { - baseScores, err := def.score(prog) + baseScores, err := def.Score(prog) if err != nil { return err } @@ -262,7 +271,7 @@ func (def *Definition) minifyFunction(prog *vm.Program, f int) error { copy(tmp, prog.Functions[f].Instructions) prog.Functions[f].Instructions = append(tmp[:i], tmp[i+1:]...) - newScores, err := def.score(prog) + newScores, err := def.Score(prog) // XXX: Use all scores if err == nil && newScores[0].Current >= baseScores[0].Current { loop = true diff --git a/grow/fit/config.go b/grow/fit/config.go new file mode 100644 index 0000000..da5de55 --- /dev/null +++ b/grow/fit/config.go @@ -0,0 +1,10 @@ +package main + +import "github.com/firestuff/subcoding/grow" +import "github.com/firestuff/subcoding/vm" + +type Config struct { + Definition *grow.Definition `yaml:"definition"` + + Programs map[string]*vm.Program `yaml:"programs"` +} diff --git a/grow/fit/main.go b/grow/fit/main.go new file mode 100644 index 0000000..434b550 --- /dev/null +++ b/grow/fit/main.go @@ -0,0 +1,13 @@ +package main + +import "flag" +import "log" + +func main() { + confPath := flag.String("conf-path", "", "path to config YAML file") + flag.Parse() + + if *confPath == "" { + log.Fatal("Please specify --conf-path") + } +}