Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/Compile.txt
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/Compile.txt	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/Compile.txt	(revision 16191)
@@ -0,0 +1,5 @@
+cd ~/go/src/github.com_del/verdverm/go-pge/plug
+
+export GOGC=off; export GODEBUG=cgocheck=0; CGO_ENABLED=1 go build -ldflags="-s -w " -buildmode=c-archive pge.go && cp pge.a /c/MinGW/lib64/libpge.a
+
+gcc -shared -pthread -o go-pge.dll pge.c pge.a -lWinMM -lntdll -lWS2_32  -L/c/Users/Hansi/Downloads/clapackgcc/ -L/c/Users/Hansi/go/src/github.com/verdverm/go-levmar/levmar-2.6/liblevmar.a -lm -llevmar -llapack -lblas -lf2c -L/lib64 -ltmglib && cp go-pge.dll /c/Users/Hansi/source/repos/TestPGELib/TestPGELib/bin/Debug -f && cp go-pge.dll /c/Users/Hansi/BachelorArbeit/2929_PrioritizedGrammarEnumeration/bin/go-pge.dll -f
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/bbsr.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/bbsr.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/bbsr.go	(revision 16191)
@@ -0,0 +1,98 @@
+package pge
+
+import (
+	"fmt"
+	// "sort"
+
+	probs "github.com/verdverm/go-pge/problems"
+	expr "github.com/verdverm/go-symexpr"
+)
+
+func (PS *PgeSearch) GenInitExpr() *probs.ReportQueue {
+
+	fmt.Println("Call gen method")
+
+
+	switch PS.cnfg.initMethod {
+	case "method1":
+		return PS.GenInitExprMethod1()
+	case "method2":
+		return PS.GenInitExprMethod2()
+	case "method3":
+		return PS.GenInitExprMethod3()
+	default:
+		fmt.Println("Unknown init method")
+	}
+	return nil
+}
+
+func (PS *PgeSearch) Expand(O expr.Expr) (ret []expr.Expr) {
+	var exprs []expr.Expr
+
+	switch PS.cnfg.growMethod {
+	case "method1":
+		exprs = PS.ExpandMethod1(O)
+	case "method2":
+		exprs = PS.ExpandMethod2(O)
+	case "method3":
+		exprs = PS.ExpandMethod3(O)
+	default:
+		fmt.Println("Unknown expand method")
+	}
+
+	// convert and simplify
+	for i, e := range exprs {
+		if e == nil {
+			continue
+		}
+		defer func() {
+			if r := recover(); r != nil {
+				fmt.Printf("Recovered in Expand %v   %d %v", r, i, e)
+				exprs[i] = nil
+			}
+		}()
+		c := make([]float64, 0)
+		// fmt.Printf("Preconv   %v\n", e)
+		c, eqn := e.ConvertToConstants(c)
+		e.CalcExprStats()
+		// fmt.Printf("Postconv  %v\n", eqn)
+
+		// fmt.Printf("Presimp  %v\n", eqn)
+		exprs[i] = eqn.Simplify(PS.cnfg.simprules)
+		// fmt.Printf("Postsimp  %v\n\n", exprs[i])
+		// serial := make([]int, 0, 64)
+		// serial = exprs[i].Serial(serial)
+		// fmt.Printf("Postsimp  %v   %v\n\n", exprs[i], serial)
+	}
+
+	// sort.Sort(expr.ExprArray(exprs))
+
+	// remove duplicates
+
+	// last := 0
+	// for last < len(exprs) && exprs[last] == nil {
+	// 	last++
+	// }
+	// for i := last + 1; i < len(exprs); i++ {
+	// 	if exprs[i] == nil {
+	// 		continue
+	// 	}
+	// 	if exprs[i].AmIAlmostSame(exprs[last]) {
+	// 		exprs[i] = nil
+	// 	} else {
+	// 		last = i
+	// 	}
+	// }
+
+	// copy to ret, ignoring nil & bad expressions ...
+	for _, e := range exprs {
+		if e == nil {
+			continue
+		}
+		// if !PS.cnfg.treecfg.CheckExpr(e) {
+		// 	continue
+		// }
+		ret = append(ret, e)
+	}
+	return ret
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/ipre_trie.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/ipre_trie.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/ipre_trie.go	(revision 16191)
@@ -0,0 +1,42 @@
+package pge
+
+type IpreNode struct {
+	val int
+	cnt int
+	vst int
+
+	next map[int]*IpreNode
+}
+
+func (n *IpreNode) InsertSerial(s []int) (did_ins bool) {
+	in, _ := n.next[s[0]]
+
+	// does this branch exist?
+	if in == nil {
+		in = new(IpreNode)
+		in.val = s[0]
+		in.next = make(map[int]*IpreNode)
+		n.next[s[0]] = in
+		did_ins = true
+	}
+
+	// recursive call to insert
+	if len(s) > 1 {
+		did_ins = in.InsertSerial(s[1:]) || did_ins
+	}
+
+	// visitation accounting  
+	// (-1 is the root of the memoization tree)
+	in.vst++
+	if n.val == -1 {
+		n.vst++
+	}
+	if did_ins {
+		in.cnt++
+		if n.val == -1 {
+			n.cnt++
+		}
+	}
+
+	return did_ins
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.c
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.c	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.c	(revision 16191)
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdio.h>
+#include <string.h>
+#include "pge.h"
+
+void testGet(GoInt param, char* param2, int paramn) {
+	TestGet(param, param2, paramn);
+}
+
+void initTreeParams(char* Roots, char* Nodes, char* NonTrig, char* Leafs, void* UsableVars, GoInt UsableVarsN, GoInt MaxSize, GoInt MinSize, GoInt MaxDepth, GoInt MinDepth) {
+	InitTreeParams(Roots, Nodes, NonTrig, Leafs, UsableVars, UsableVarsN, MaxSize, MinSize, MaxDepth, MinDepth);
+}
+
+void addTrainData(char* indepNames, char* depndNames, void* matrix, GoInt nEntries) {
+	AddTrainData(indepNames, depndNames, matrix, nEntries);
+}
+
+void addTestData(char* indepNames, char* depndNames, void* matrix, GoInt nEntries) {
+	AddTestData(indepNames, depndNames, matrix, nEntries);
+}
+
+char* getStepResult(GoInt* nobestpush, GoInt* bestnewminerr, GoInt* bestlen1, GoInt* bestlen2, GoInt* testscore, void* coeff, GoInt* ncoeff) {
+	return GetStepResult(nobestpush, bestnewminerr, bestlen1, bestlen2, testscore, coeff, ncoeff);
+}
+
+void initSearch(GoInt maxGen, GoInt pgeRptEpoch, GoInt pgeRptCount, GoInt pgeArchiveCap, GoInt peelCnt, GoInt evalrCount, GoFloat64 zeroEpsilon, char* initMethod, char* growMethod, GoInt sortType) {
+	InitSearch(maxGen, pgeRptEpoch, pgeRptCount, pgeArchiveCap, peelCnt, evalrCount, zeroEpsilon, initMethod, growMethod, sortType);
+}
+
+void initProblem(char* Name, GoInt MaxIter, GoFloat64 HitRatio, GoInt SearchVar, char* ProblemTypeString, GoInt numProcs) {
+	 InitProblem(Name, MaxIter, HitRatio, SearchVar, ProblemTypeString, numProcs);
+}
+
+GoInt getMaxIterW() {
+	return GetMaxIterW();
+}
+
+void setMaxIterW(GoInt iter) {
+	SetMaxIterW(iter);
+}
+
+void setPeelCountW(GoInt cnt) {
+	SetPeelCountW(cnt);
+}
+
+void setInitMethodW(GoString init) {
+	SetInitMethodW(init);
+}
+
+void setGrowMethodW(GoString grow) {
+	SetGrowMethodW(grow);
+}
+
+void setEvalrCountW(GoInt cnt) {
+	SetEvalrCountW(cnt);
+}
+
+void evaluateW() {
+	EvaluateW();
+}
+
+void runW() {
+	RunW();
+}
+
+void loopW() {
+	LoopW();
+}
+
+void stepW() {
+	StepW();
+}
+
+void cleanW() {
+	CleanW();
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.go	(revision 16191)
@@ -0,0 +1,232 @@
+package main
+
+import "C"
+import (
+	"pge"
+	"unsafe"
+	"fmt"
+	rt "runtime"
+	rand "math/rand"
+	"strings"
+	probs "github.com/verdverm/go-pge/problems"
+)
+
+func main() {
+
+}
+
+var cps *pge.PgeSearch
+var tp *probs.TreeParams
+var epcomm *probs.ExprProblemComm
+var trainDatas []*probs.PointSet
+var testDatas []*probs.PointSet
+var testDatasN int
+var trainDatasN int
+var ep *probs.ExprProblem
+var per_eqns []*probs.ExprReportArray
+
+var trainData *probs.PointSet
+var testData *probs.PointSet
+
+var stepResult []*pge.PeelResult
+var resultNr int
+
+//export InitSearch
+func InitSearch(maxGen int, pgeRptEpoch int, pgeRptCount int, pgeArchiveCap int, peelCnt int, evalrCount int, zeroEpsilon float64, initMethod *C.char, growMethod *C.char, sortType int) {
+	cps = new(pge.PgeSearch)
+	
+	goInitMethod := C.GoString(initMethod);
+	goGrowMethod := C.GoString(growMethod);
+	
+	testDatasN = 0 
+	trainDatasN = 0
+
+	cps.CreateDS(maxGen, pgeRptEpoch, pgeRptCount, pgeArchiveCap, peelCnt, evalrCount, zeroEpsilon, goInitMethod, goGrowMethod, sortType)
+	
+	cps.SetPeelCount(peelCnt)
+	cps.SetGrowMethod(goGrowMethod)
+	cps.SetInitMethod(goInitMethod)
+	cps.SetEvalrCount(evalrCount)
+}
+
+//export InitTreeParams
+func InitTreeParams(Roots *C.char, Nodes *C.char, NonTrig *C.char, Leafs *C.char, UsableVars unsafe.Pointer, nUseableVars int, MaxSize int, MinSize int, MaxDepth int, MinDepth int) {
+	tp = new(probs.TreeParams)
+	goRoots := C.GoString(Roots)
+	goNodes := C.GoString(Nodes)
+	goNonTrig := C.GoString(NonTrig)
+	goLeafs := C.GoString(Leafs)
+	goUsableVars := CIntArrayToSlice(UsableVars, nUseableVars)
+	tp.CreateTreeParams(goRoots, goNodes, goNonTrig, goLeafs, goUsableVars, MaxSize, MinSize, MaxDepth, MinDepth)
+}
+
+//export AddTrainData
+func AddTrainData(indepNames *C.char, depndNames *C.char, matrix unsafe.Pointer, nEntries int) {
+	trainDatas = make([]*probs.PointSet, 1)
+	trainData = new(probs.PointSet)
+	
+	goIndepNames := strings.Split(C.GoString(indepNames), " ")
+	goDepndNames := strings.Split(C.GoString(depndNames), " ")
+	
+	trainData.InitTrainData(goIndepNames, goDepndNames, matrix, nEntries)
+	
+	trainDatas[trainDatasN] = trainData
+	trainDatasN++
+}
+
+//export AddTestData
+func AddTestData(indepNames *C.char, depndNames *C.char, matrix unsafe.Pointer, nEntries int) {
+	testDatas = make([]*probs.PointSet, 1)
+	testData = new(probs.PointSet)
+	
+	goIndepNames := strings.Split(C.GoString(indepNames), " ")
+	goDepndNames := strings.Split(C.GoString(depndNames), " ")
+	
+	testData.InitTrainData(goIndepNames, goDepndNames, matrix, nEntries)
+	testDatas[testDatasN] = testData
+	testDatasN++
+}
+
+//export InitProblem
+func InitProblem(Name *C.char, MaxIter int, HitRatio float64, SearchVar int, ProblemTypeString *C.char, numProcs int) {	
+	ep = new(probs.ExprProblem)	
+	goName := C.GoString(Name)
+	goProblemTypeString := C.GoString(ProblemTypeString)
+	
+	ep.CreatePS(goName, MaxIter, HitRatio, SearchVar, goProblemTypeString)
+	ep.TreeCfg = tp;
+	ep.UsableVars = tp.UsableVars		
+	
+	cps.SetMaxIter(MaxIter)
+	per_eqns = make([]*probs.ExprReportArray, 1)
+	
+	ep.Train = trainDatas
+	ep.Test = testDatas
+	
+	initDone := make(chan int)
+	rt.GOMAXPROCS(numProcs)
+	rand.Seed(rand.Int63())
+	
+	epcomm = new(probs.ExprProblemComm)
+	
+	epcomm.Cmds = make(chan int)
+    epcomm.Rpts = make(chan *probs.ExprReportArray, 64)
+	epcomm.Gen = make(chan [2]int, 64)
+	
+	cps.SetProb(ep)
+	cps.Init(initDone, ep, "dummy", epcomm)
+}
+
+//export GetMaxIterW
+func GetMaxIterW() int {
+	return cps.GetMaxIter()
+}
+
+//export SetMaxIterW
+func SetMaxIterW(iter int) {
+	cps.SetMaxIter(iter)
+}
+
+//export SetPeelCountW
+func SetPeelCountW(cnt int) {
+	cps.SetPeelCount(cnt)
+}
+
+//export SetInitMethodW
+func SetInitMethodW(init string) {
+	cps.SetInitMethod(init)
+}
+
+//export SetGrowMethodW
+func SetGrowMethodW(grow string) {
+	cps.SetGrowMethod(grow)
+}
+
+//export SetEvalrCountW
+func SetEvalrCountW(cnt int) {
+	cps.SetEvalrCount(cnt)
+}
+
+//export EvaluateW
+func EvaluateW() {
+	cps.Evaluate()
+}
+
+//export RunW
+func RunW() {
+	cps.Run()
+}
+
+//export LoopW
+func LoopW() {
+	cps.Loop()
+}
+
+//export GetStepResult
+func GetStepResult(nobestpush *int, bestnewminerr *int, bestlen1 *int, bestlen2 *int, testscore *int, coeff unsafe.Pointer, ncoeff *int) *C.char {
+	*nobestpush = 0
+	*bestnewminerr = 0
+	*bestlen1 = 0
+	*bestlen2 = 0
+	*testscore = 0
+	
+	if resultNr < cps.GetPeelCount() {
+		elem := stepResult[resultNr]
+		resultNr++
+		if elem.Nobestpush {
+			*nobestpush = 1;
+		} else {
+			if elem.BestNewMinErr {
+				*bestnewminerr = 1
+			}
+			*testscore = elem.TestScore
+			*ncoeff = len(elem.Coeff)
+			for i := 0; i < len(elem.Coeff); i++ {
+				item := (*float64) (unsafe.Pointer( uintptr(unsafe.Pointer(coeff)) + unsafe.Sizeof(float64(0)) * uintptr(i) ))
+				*item = elem.Coeff[i]
+			}
+			*bestlen1 = elem.Bestlen1
+			*bestlen2 = elem.Bestlen2
+			return C.CString(elem.Expre.String())
+		}
+	}
+	return C.CString("")
+}
+
+//export StepW
+func StepW() {
+	resultNr = 0
+	stepResult = cps.SingleStep()
+}
+
+//export CheckStop
+func CheckStop() bool {
+	if cps.GetIter() > GetMaxIterW() {
+		return true
+	}
+	return false	
+}
+
+func CIntArrayToSlice(matrix unsafe.Pointer, nEntries int) []int {
+	res := make([]int, nEntries)
+	for i := 0; i < nEntries; i++ {
+		item := (*int) (unsafe.Pointer( uintptr(unsafe.Pointer(matrix)) + unsafe.Sizeof(int(0)) * uintptr(i) ))
+		res[i] = *item
+	}
+	return res
+}
+
+
+//export TestGet
+func TestGet(nix int, nix2 *C.char, nnix2 C.int) {
+	fmt.Printf("TEST INT VALUE: %v \n", nix);
+	fmt.Printf("TEST STRING VALUE: %v \n", nix2);
+	var nixgo string
+	nixgo = C.GoString(nix2);//, nnix2);	
+	fmt.Printf("TEST STRING AS GOSTR VALUE: %v \n", nixgo);
+}
+
+//export CleanW
+func CleanW() {
+	cps.Clean()
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.h
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.h	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge.h	(revision 16191)
@@ -0,0 +1,108 @@
+/* Code generated by cmd/cgo; DO NOT EDIT. */
+
+/* package command-line-arguments */
+
+
+#line 1 "cgo-builtin-prolog"
+
+#include <stddef.h> /* for ptrdiff_t below */
+
+#ifndef GO_CGO_EXPORT_PROLOGUE_H
+#define GO_CGO_EXPORT_PROLOGUE_H
+
+typedef struct { const char *p; ptrdiff_t n; } _GoString_;
+
+#endif
+
+/* Start of preamble from import "C" comments.  */
+
+
+
+
+/* End of preamble from import "C" comments.  */
+
+
+/* Start of boilerplate cgo prologue.  */
+#line 1 "cgo-gcc-export-header-prolog"
+
+#ifndef GO_CGO_PROLOGUE_H
+#define GO_CGO_PROLOGUE_H
+
+typedef signed char GoInt8;
+typedef unsigned char GoUint8;
+typedef short GoInt16;
+typedef unsigned short GoUint16;
+typedef int GoInt32;
+typedef unsigned int GoUint32;
+typedef long long GoInt64;
+typedef unsigned long long GoUint64;
+typedef GoInt64 GoInt;
+typedef GoUint64 GoUint;
+typedef __SIZE_TYPE__ GoUintptr;
+typedef float GoFloat32;
+typedef double GoFloat64;
+typedef float _Complex GoComplex64;
+typedef double _Complex GoComplex128;
+
+/*
+  static assertion to make sure the file is being used on architecture
+  at least with matching size of GoInt.
+*/
+typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
+
+typedef _GoString_ GoString;
+typedef void *GoMap;
+typedef void *GoChan;
+typedef struct { void *t; void *v; } GoInterface;
+typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
+
+#endif
+
+/* End of boilerplate cgo prologue.  */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+extern void InitSearch(GoInt p0, GoInt p1, GoInt p2, GoInt p3, GoInt p4, GoInt p5, GoFloat64 p6, char* p7, char* p8, GoInt p9);
+
+extern void InitTreeParams(char* p0, char* p1, char* p2, char* p3, void* p4, GoInt p5, GoInt p6, GoInt p7, GoInt p8, GoInt p9);
+
+extern void AddTrainData(char* p0, char* p1, void* p2, GoInt p3);
+
+extern void AddTestData(char* p0, char* p1, void* p2, GoInt p3);
+
+extern void InitProblem(char* p0, GoInt p1, GoFloat64 p2, GoInt p3, char* p4, GoInt p5);
+
+extern GoInt GetMaxIterW();
+
+extern void SetMaxIterW(GoInt p0);
+
+extern void SetPeelCountW(GoInt p0);
+
+extern void SetInitMethodW(GoString p0);
+
+extern void SetGrowMethodW(GoString p0);
+
+extern void SetEvalrCountW(GoInt p0);
+
+extern void EvaluateW();
+
+extern void RunW();
+
+extern void LoopW();
+
+extern char* GetStepResult(GoInt* p0, GoInt* p1, GoInt* p2, GoInt* p3, GoInt* p4, void* p5, GoInt* p6);
+
+extern void StepW();
+
+extern GoUint8 CheckStop();
+
+extern void TestGet(GoInt p0, char* p1, int p2);
+
+extern void CleanW();
+
+#ifdef __cplusplus
+}
+#endif
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_1.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_1.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_1.go	(revision 16191)
@@ -0,0 +1,247 @@
+package pge
+
+import (
+	// "fmt"
+	"sort"
+
+	expr "github.com/verdverm/go-symexpr"
+)
+
+func (PS *PgeSearch) ExpandMethod1(O expr.Expr) (ret []expr.Expr) {
+	O.Sort()
+	ret = make([]expr.Expr, 0)
+	// fmt.Printf("Expanding expression:  %v\n", O)
+
+	for i := 0; i < O.Size(); i++ {
+		I := i
+		E := O.GetExpr(&I)
+		switch E.ExprType() {
+		case expr.ADD:
+			tmp := PS.AddTermToExprMethod1(O, E, i)
+			ret = append(ret, tmp[:]...)
+
+		case expr.MUL:
+			tmp := PS.WidenTermInExprMethod1(O, E, i)
+			ret = append(ret, tmp[:]...)
+
+		case expr.VAR:
+			tmp := PS.DeepenTermInExprMethod1(O, E, i)
+			ret = append(ret, tmp[:]...)
+
+		default: // expr.DIV,expr.COS,expr.SIN,expr.EXP,expr.LOG,expr.ABS,expr.POW
+			continue
+
+		}
+	}
+
+	return ret
+}
+
+// add another term to an add expr
+func (PS *PgeSearch) AddTermToExprMethod1(O, E expr.Expr, pos int) (ret []expr.Expr) {
+	ret = make([]expr.Expr, 0)
+	A := E.(*expr.Add)
+
+	// f() + cL
+	for _, L := range PS.GenLeafs {
+		c := new(expr.Constant)
+		c.P = -1
+		l := L.Clone()
+
+		// mul it
+		M := expr.NewMul()
+		M.Insert(c)
+		M.Insert(l)
+
+		// skip if the same term already exists in the add
+		skip := false
+		for _, e := range A.CS {
+			if e == nil {
+				continue
+			}
+			// fmt.Printf("ACMP  %v  %v\n", M, e)
+			if e.AmIAlmostSame(M) || M.AmIAlmostSame(e) {
+				skip = true
+				break
+			}
+		}
+		if skip {
+			continue
+		}
+
+		C := O.Clone()
+		P := pos
+		AM := C.GetExpr(&P).(*expr.Add)
+		AM.Insert(M)
+		sort.Sort(AM)
+		C.CalcExprStats()
+		good := PS.cnfg.treecfg.CheckExpr(C)
+		if good {
+			ret = append(ret, C)
+		}
+	}
+
+	// f() + c*node(L)
+	for _, N := range PS.GenNodes {
+		for _, L := range PS.GenLeafs {
+
+			c := new(expr.Constant)
+			c.P = -1
+
+			l := L.Clone()
+			n := N.Clone()
+			p := 1
+			n.SetExpr(&p, l)
+
+			var E expr.Expr
+			if N.ExprType() == expr.DIV {
+				E = expr.NewDiv(c, l)
+			} else {
+				// mul it
+				M := expr.NewMul()
+				M.Insert(c)
+				M.Insert(n)
+				E = M
+			}
+
+			// skip if the same term already exists in the add
+			skip := false
+			for _, e := range A.CS {
+				if e == nil {
+					continue
+				}
+				// fmt.Printf("ACMP  %v  %v\n", M, e)
+				if e.AmIAlmostSame(E) || E.AmIAlmostSame(e) {
+					skip = true
+					break
+				}
+			}
+			if skip {
+				continue
+			}
+
+			// fmt.Println(E.String())
+
+			C := O.Clone()
+			P := pos
+			AM := C.GetExpr(&P).(*expr.Add)
+			AM.Insert(E)
+			sort.Sort(AM)
+			C.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(C)
+			if good {
+				ret = append(ret, C)
+			}
+		}
+	}
+
+	return ret
+}
+
+// add complexity to a single multiplication term
+func (PS *PgeSearch) WidenTermInExprMethod1(O, E expr.Expr, pos int) (ret []expr.Expr) {
+	ret = make([]expr.Expr, 0)
+
+	// insert leafs  f()*L
+	for _, L := range PS.GenLeafs {
+		l := L.Clone()
+		C := O.Clone()
+		P := pos
+		e := C.GetExpr(&P)
+		// fmt.Printf("pos(%d): %v\n", pos, e)
+		M := e.(*expr.Mul)
+		M.Insert(l)
+		sort.Sort(M)
+		C.CalcExprStats()
+		good := PS.cnfg.treecfg.CheckExpr(C)
+		if good {
+			ret = append(ret, C)
+		}
+	}
+
+	// insert node(L)  :  f() * c*node(L)
+	for _, N := range PS.GenNodes {
+		for _, L := range PS.GenLeafs {
+			c := new(expr.Constant)
+			c.P = -1
+
+			l := L.Clone()
+			n := N.Clone()
+			p := 1
+			n.SetExpr(&p, l)
+
+			var E expr.Expr
+			if N.ExprType() == expr.DIV {
+				E = expr.NewDiv(c, l)
+			} else {
+				// mul it
+				M := expr.NewMul()
+				M.Insert(c)
+				M.Insert(n)
+				E = M
+			}
+
+			C := O.Clone()
+			P := pos
+			e := C.GetExpr(&P)
+			// fmt.Printf("pos(%d): %v\n", pos, e)
+			M := e.(*expr.Mul)
+
+			M.Insert(E)
+			sort.Sort(M)
+			C.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(C)
+			if good {
+				ret = append(ret, C)
+			}
+		}
+	}
+	return ret
+}
+
+// change any term to something more complex...
+func (PS *PgeSearch) DeepenTermInExprMethod1(O, E expr.Expr, pos int) []expr.Expr {
+	exprs := make([]expr.Expr, 0)
+
+	// make into add
+	A := expr.NewAdd()
+	A.Insert(E.Clone())
+	OA := A.Clone()
+	exprs = append(exprs, PS.AddTermToExprMethod1(OA, A, 0)[:]...)
+
+	// make into mul
+	M := expr.NewMul()
+	M.Insert(E.Clone())
+	OM := M.Clone()
+	exprs = append(exprs, PS.WidenTermInExprMethod1(OM, M, 0)[:]...)
+
+	// // make into div
+	// if E.ExprType() != expr.DIV {
+	// 	D := new(expr.Div)
+	// 	c := new(expr.Constant)
+	// 	c.P = -1
+	// 	D.Numer = c
+	// 	D.Denom = E.Clone()
+	// 	exprs = append(exprs, D)
+	// }
+
+	// make inside of nodes
+	for _, N := range PS.GenNodes {
+		if N.ExprType() == expr.DIV {
+			continue
+		}
+		T := N.Clone()
+		P := 1
+		T.SetExpr(&P, E.Clone())
+		exprs = append(exprs, T)
+	}
+
+	ret := make([]expr.Expr, 0)
+	for _, e := range exprs {
+		C := O.Clone()
+		P := pos
+		C.SetExpr(&P, e)
+		ret = append(ret, C)
+	}
+	return ret
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_2.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_2.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_2.go	(revision 16191)
@@ -0,0 +1,203 @@
+package pge
+
+import (
+	// "fmt"
+	"sort"
+
+	expr "github.com/verdverm/go-symexpr"
+)
+
+func (PS *PgeSearch) ExpandMethod2(O expr.Expr) (ret []expr.Expr) {
+	O.Sort()
+	ret = make([]expr.Expr, 0)
+	// fmt.Printf("Expanding expression:  %v\n", O)
+
+	add := O.(*expr.Add)
+
+	// adding term to addition
+	for _, B := range PS.ffxBases {
+		found := false
+		for _, C := range add.CS {
+			// fmt.Printf("checking %v in %v\n", B, add)
+			if C.AmISame(B) {
+				// fmt.Println("found\n\n")
+				found = true
+				break
+			}
+		}
+		if !found {
+			e := O.Clone()
+			a := e.(*expr.Add)
+			a.Insert(B.Clone())
+			sort.Sort(a)
+			a.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(a)
+			if good {
+				ret = append(ret, a)
+			}
+			// fmt.Printf("grew  %v\n\n", a)
+			// ret = append(ret, a)
+		}
+	}
+
+	// extending terms in addition
+	for _, B := range PS.ffxBases {
+		for i, C := range add.CS {
+			if C.ExprType() == expr.MUL {
+				m := C.(*expr.Mul)
+				if len(m.CS) > 3 {
+					continue
+				}
+			}
+			e := O.Clone()
+			a := e.(*expr.Add)
+			mul := expr.NewMul()
+			mul.Insert(a.CS[i])
+			mul.Insert(B.Clone())
+			a.CS[i] = mul
+			sort.Sort(a)
+			a.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(a)
+			if good {
+				ret = append(ret, a)
+			}
+			// fmt.Printf("grew  %v\n\n", a)
+			ret = append(ret, a)
+		}
+	}
+
+	// deepening terms 
+	// if len(add.CS) < 2 {
+	// 	return ret
+	// }
+	for i, C := range add.CS {
+		if C.ExprType() == expr.MUL {
+			m := C.(*expr.Mul)
+			if len(m.CS) != 2 {
+				continue
+			}
+			if m.CS[1].ExprType() == expr.ADD {
+				continue
+			}
+		} else {
+			continue
+		}
+
+		for _, B := range PS.ffxBases {
+			e := O.Clone()
+			a := e.(*expr.Add)
+			m := a.CS[i].(*expr.Mul)
+			n := m.CS[1]
+
+			switch n.ExprType() {
+			case expr.SQRT:
+				A := expr.NewAdd()
+				A.Insert(n.(*expr.Sqrt).C)
+				A.Insert(B.Clone())
+				n.(*expr.Sqrt).C = A
+			case expr.SIN:
+				A := expr.NewAdd()
+				A.Insert(n.(*expr.Sin).C)
+				A.Insert(B.Clone())
+				n.(*expr.Sin).C = A
+			case expr.COS:
+				A := expr.NewAdd()
+				A.Insert(n.(*expr.Cos).C)
+				A.Insert(B.Clone())
+				n.(*expr.Cos).C = A
+			case expr.TAN:
+				A := expr.NewAdd()
+				A.Insert(n.(*expr.Tan).C)
+				A.Insert(B.Clone())
+				n.(*expr.Tan).C = A
+			case expr.EXP:
+				A := expr.NewAdd()
+				A.Insert(n.(*expr.Exp).C)
+				A.Insert(B.Clone())
+				n.(*expr.Exp).C = A
+			case expr.LOG:
+				A := expr.NewAdd()
+				A.Insert(n.(*expr.Log).C)
+				A.Insert(B.Clone())
+				n.(*expr.Log).C = A
+
+			default:
+				A := expr.NewAdd()
+				A.Insert(m.CS[1])
+				A.Insert(B.Clone())
+				m.CS[1] = A
+			}
+			sort.Sort(a)
+			a.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(a)
+			if good {
+				ret = append(ret, a)
+			}
+			// fmt.Printf("grew  %v\n", a)
+			ret = append(ret, a)
+		}
+	}
+	for i, C := range add.CS {
+		if C.ExprType() == expr.MUL {
+			m := C.(*expr.Mul)
+			if len(m.CS) != 2 {
+				continue
+			}
+			if m.CS[1].ExprType() == expr.ADD {
+				continue
+			}
+		} else {
+			continue
+		}
+
+		for _, B := range PS.ffxBases {
+			e := O.Clone()
+			a := e.(*expr.Add)
+			m := a.CS[i].(*expr.Mul)
+			n := m.CS[1]
+
+			switch n.ExprType() {
+			case expr.SQRT:
+				M := expr.NewMul()
+				M.Insert(n.(*expr.Sqrt).C)
+				M.Insert(B.Clone())
+				n.(*expr.Sqrt).C = M
+			case expr.SIN:
+				M := expr.NewMul()
+				M.Insert(n.(*expr.Sin).C)
+				M.Insert(B.Clone())
+				n.(*expr.Sin).C = M
+			case expr.COS:
+				M := expr.NewMul()
+				M.Insert(n.(*expr.Cos).C)
+				M.Insert(B.Clone())
+				n.(*expr.Cos).C = M
+			case expr.TAN:
+				M := expr.NewMul()
+				M.Insert(n.(*expr.Tan).C)
+				M.Insert(B.Clone())
+				n.(*expr.Tan).C = M
+			case expr.EXP:
+				M := expr.NewMul()
+				M.Insert(n.(*expr.Exp).C)
+				M.Insert(B.Clone())
+				n.(*expr.Exp).C = M
+			case expr.LOG:
+				M := expr.NewMul()
+				M.Insert(n.(*expr.Log).C)
+				M.Insert(B.Clone())
+				n.(*expr.Log).C = M
+			}
+			sort.Sort(a)
+			a.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(a)
+			if good {
+				ret = append(ret, a)
+			}
+			// fmt.Printf("grew  %v\n", a)
+			ret = append(ret, a)
+		}
+	}
+	// fmt.Println("Len of ret = ", len(ret))
+	return ret
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_3.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_3.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_expand_method_3.go	(revision 16191)
@@ -0,0 +1,71 @@
+package pge
+
+import (
+	// "fmt"
+	"sort"
+
+	expr "github.com/verdverm/go-symexpr"
+)
+
+func (PS *PgeSearch) ExpandMethod3(O expr.Expr) (ret []expr.Expr) {
+	O.Sort()
+	ret = make([]expr.Expr, 0)
+	// fmt.Printf("Expanding expression:  %v\n", O)
+
+	add := O.(*expr.Add)
+
+	// adding term to addition
+	for _, B := range PS.ffxBases {
+		found := false
+		for _, C := range add.CS {
+			// fmt.Printf("checking %v in %v\n", B, add)
+			if C.AmISame(B) {
+				// fmt.Println("found\n\n")
+				found = true
+				break
+			}
+		}
+		if !found {
+			e := O.Clone()
+			a := e.(*expr.Add)
+			a.Insert(B.Clone())
+			sort.Sort(a)
+			a.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(a)
+			if good {
+				ret = append(ret, a)
+			}
+			// fmt.Printf("grew  %v\n\n", a)
+			// ret = append(ret, a)
+		}
+	}
+
+	// extending terms in addition
+	for _, B := range PS.ffxBases {
+		for i, C := range add.CS {
+			if C.ExprType() == expr.MUL {
+				m := C.(*expr.Mul)
+				if len(m.CS) > 3 {
+					continue
+				}
+			}
+			e := O.Clone()
+			a := e.(*expr.Add)
+			mul := expr.NewMul()
+			mul.Insert(a.CS[i])
+			mul.Insert(B.Clone())
+			a.CS[i] = mul
+			sort.Sort(a)
+			a.CalcExprStats()
+			good := PS.cnfg.treecfg.CheckExpr(a)
+			if good {
+				ret = append(ret, a)
+			}
+			// fmt.Printf("grew  %v\n\n", a)
+			ret = append(ret, a)
+		}
+	}
+
+	// fmt.Println("Len of ret = ", len(ret))
+	return ret
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_1.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_1.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_1.go	(revision 16191)
@@ -0,0 +1,121 @@
+package pge
+
+import (
+	"fmt"
+
+	probs "github.com/verdverm/go-pge/problems"
+	expr "github.com/verdverm/go-symexpr"
+)
+
+func (PS *PgeSearch) GenInitExprMethod1() *probs.ReportQueue {
+	fmt.Printf("generating initial expressions\n")
+
+	GP := PS.cnfg.treecfg
+
+	eList := make([]expr.Expr, 0)
+
+	for _, T := range GP.Roots {
+		switch T.ExprType() {
+		case expr.ADD:
+			eList = append(eList, PS.GenInitExprAddMethod1()[:]...)
+		case expr.MUL:
+			eList = append(eList, PS.GenInitExprMulMethod1()[:]...)
+		case expr.DIV:
+			eList = append(eList, PS.GenInitExprDivMethod1()[:]...)
+		default:
+			fmt.Printf("Error in GenInitExpr: unknown ROOT %d\n", T)
+		}
+	}
+
+	exprs := probs.NewReportQueue()
+	// exprs.SetSort(PS.cnfg.sortType)
+	exprs.SetSort(probs.PESORT_PARETO_TST_ERR)
+	
+	for i, e := range eList {
+	
+		serial := make([]int, 0, 64)
+		serial = e.Serial(serial)
+		PS.Trie.InsertSerial(serial)
+		// on train data
+
+		//fmt.Printf("RegressExpr:  e: %v  || PS.prob: %v\n", e, PS.prob)
+		re := RegressExpr(e, PS.prob)  //DER DO
+		//fmt.Printf("RegressExpr:  e: %v  || PS.prob: %v || %v \n", e, PS.prob, re)
+		
+		re.SetUnitID(i)
+		exprs.Push(re)
+	}
+
+	exprs.Sort()
+	return exprs
+}
+
+func (PS *PgeSearch) GenInitExprAddMethod1() []expr.Expr {
+
+	exprs := make([]expr.Expr, 0)
+
+	// WARNING adding a single coefficient results in the same traversal but with the added extra coefficient
+	cf := new(expr.Constant)
+	cf.P = 1
+	af := new(expr.Add)
+	af.Insert(cf)
+	exprs = append(exprs, af)
+
+	for _, i := range PS.cnfg.treecfg.UsableVars {
+		c := new(expr.Constant)
+		c.P = -1
+		v := new(expr.Var)
+		v.P = i
+
+		m := expr.NewMul()
+		m.Insert(c)
+		m.Insert(v)
+
+		a := expr.NewAdd()
+		a.Insert(m)
+		exprs = append(exprs, a)
+	}
+
+	fmt.Println("Initial Add:  ", exprs)
+	return exprs
+}
+
+func (PS *PgeSearch) GenInitExprMulMethod1() []expr.Expr {
+	exprs := make([]expr.Expr, 0)
+
+	for _, i := range PS.cnfg.treecfg.UsableVars {
+		c := new(expr.Constant)
+		c.P = -1
+		v := new(expr.Var)
+		v.P = i
+
+		m := expr.NewMul()
+		m.Insert(c)
+		m.Insert(v)
+
+		exprs = append(exprs, m)
+	}
+
+	fmt.Println("Initial Mul:  ", exprs)
+	return exprs
+}
+
+func (PS *PgeSearch) GenInitExprDivMethod1() []expr.Expr {
+	exprs := make([]expr.Expr, 0)
+
+	for _, i := range PS.cnfg.treecfg.UsableVars {
+		c := new(expr.Constant)
+		c.P = -1
+		v := new(expr.Var)
+		v.P = i
+
+		d := new(expr.Div)
+		d.Numer = c
+		d.Denom = v
+
+		exprs = append(exprs, d)
+	}
+
+	fmt.Println("Initial Div:  ", exprs)
+	return exprs
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_2.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_2.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_2.go	(revision 16191)
@@ -0,0 +1,92 @@
+package pge
+
+import (
+	"fmt"
+
+	probs "github.com/verdverm/go-pge/problems"
+	expr "github.com/verdverm/go-symexpr"
+)
+
+// This is the FFXish style init function
+func (PS *PgeSearch) GenInitExprMethod2() *probs.ReportQueue {
+	fmt.Printf("generating initial expressions\n")
+
+	GP := PS.cnfg.treecfg
+	fmt.Printf("%v\n", GP)
+
+	bases := make([]expr.Expr, 0)
+
+	// single constant
+	bases = append(bases, expr.NewConstant(-1))
+
+	// c*x_i
+	for _, v := range PS.prob.UsableVars {
+		mul := expr.NewMul()
+		mul.Insert(expr.NewConstant(-1))
+		mul.Insert(expr.NewVar(v))
+		bases = append(bases, mul)
+	}
+
+	// c*x_i^p & c*x_i^-p
+	for p := 2; p <= 4; p++ {
+		for _, v := range PS.prob.UsableVars {
+			// positive powers
+			mul := expr.NewMul()
+			mul.Insert(expr.NewConstant(-1))
+			mul.Insert(expr.NewPowI(expr.NewVar(v), p))
+			bases = append(bases, mul)
+
+			// negative powers
+			nul := expr.NewMul()
+			nul.Insert(expr.NewConstant(-1))
+			nul.Insert(expr.NewPowI(expr.NewVar(v), -p))
+			bases = append(bases, nul)
+		}
+	}
+
+	// c*N(d*x_i)
+	for _, N := range PS.GenNodes {
+		if N.ExprType() == expr.DIV || N.ExprType() == expr.ADD || N.ExprType() == expr.MUL {
+			continue
+		}
+		for _, v := range PS.prob.UsableVars {
+			// positive powers
+			mul := expr.NewMul()
+			mul.Insert(expr.NewConstant(-1))
+
+			nul := expr.NewMul()
+			nul.Insert(expr.NewConstant(-1))
+			nul.Insert(expr.NewVar(v))
+
+			n := N.Clone()
+			p := 1
+			n.SetExpr(&p, nul)
+			mul.Insert(n)
+			bases = append(bases, mul)
+		}
+	}
+
+	// copy bases for use later in expand
+	PS.ffxBases = make([]expr.Expr, len(bases))
+	for i, b := range bases {
+		PS.ffxBases[i] = b.Clone()
+	}
+
+	exprs := probs.NewReportQueue()
+	// exprs.SetSort(PS.cnfg.sortType)
+	exprs.SetSort(probs.PESORT_PARETO_TST_ERR)
+
+	for i, e := range bases {
+		fmt.Printf("%d:  %v\n", i, e)
+		serial := make([]int, 0, 64)
+		serial = e.Serial(serial)
+		PS.Trie.InsertSerial(serial)
+		// on train data
+		re := RegressExpr(e, PS.prob)
+		re.SetUnitID(i)
+		exprs.Push(re)
+	}
+	exprs.Sort()
+
+	return exprs
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_3.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_3.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_init_method_3.go	(revision 16191)
@@ -0,0 +1,92 @@
+package pge
+
+import (
+	"fmt"
+
+	probs "github.com/verdverm/go-pge/problems"
+	expr "github.com/verdverm/go-symexpr"
+)
+
+// This is the FFXish style init function
+func (PS *PgeSearch) GenInitExprMethod3() *probs.ReportQueue {
+	fmt.Printf("generating initial expressions\n")
+
+	GP := PS.cnfg.treecfg
+	fmt.Printf("%v\n", GP)
+
+	bases := make([]expr.Expr, 0)
+
+	// single constant
+	bases = append(bases, expr.NewConstant(-1))
+
+	// c*x_i
+	for _, v := range PS.prob.UsableVars {
+		mul := expr.NewMul()
+		mul.Insert(expr.NewConstant(-1))
+		mul.Insert(expr.NewVar(v))
+		bases = append(bases, mul)
+	}
+
+	// c*x_i^p & c*x_i^-p
+	for p := 2; p <= 4; p++ {
+		for _, v := range PS.prob.UsableVars {
+			// positive powers
+			mul := expr.NewMul()
+			mul.Insert(expr.NewConstant(-1))
+			mul.Insert(expr.NewPowI(expr.NewVar(v), p))
+			bases = append(bases, mul)
+
+			// negative powers
+			nul := expr.NewMul()
+			nul.Insert(expr.NewConstant(-1))
+			nul.Insert(expr.NewPowI(expr.NewVar(v), -p))
+			bases = append(bases, nul)
+		}
+	}
+
+	// c*N(d*x_i)
+	for _, N := range PS.GenNodes {
+		if N.ExprType() == expr.DIV || N.ExprType() == expr.ADD || N.ExprType() == expr.MUL {
+			continue
+		}
+		for _, v := range PS.prob.UsableVars {
+			// positive powers
+			mul := expr.NewMul()
+			mul.Insert(expr.NewConstant(-1))
+
+			nul := expr.NewMul()
+			nul.Insert(expr.NewConstant(-1))
+			nul.Insert(expr.NewVar(v))
+
+			n := N.Clone()
+			p := 1
+			n.SetExpr(&p, nul)
+			mul.Insert(n)
+			bases = append(bases, mul)
+		}
+	}
+
+	// copy bases for use later in expand
+	PS.ffxBases = make([]expr.Expr, len(bases))
+	for i, b := range bases {
+		PS.ffxBases[i] = b.Clone()
+	}
+
+	exprs := probs.NewReportQueue()
+	// exprs.SetSort(PS.cnfg.sortType)
+	exprs.SetSort(probs.PESORT_PARETO_TST_ERR)
+
+	for i, e := range bases {
+		fmt.Printf("%d:  %v\n", i, e)
+		serial := make([]int, 0, 64)
+		serial = e.Serial(serial)
+		PS.Trie.InsertSerial(serial)
+		// on train data
+		re := RegressExpr(e, PS.prob)
+		re.SetUnitID(i)
+		exprs.Push(re)
+	}
+	exprs.Sort()
+
+	return exprs
+}
Index: /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_search.go
===================================================================
--- /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_search.go	(revision 16191)
+++ /branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/plug/pge_search.go	(revision 16191)
@@ -0,0 +1,890 @@
+package pge
+
+import (
+	"bufio"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"math"
+	"os"
+	"strconv"
+	"strings"
+
+	levmar "github.com/verdverm/go-levmar"
+	config "github.com/verdverm/go-pge/config"
+	probs "github.com/verdverm/go-pge/problems"
+	expr "github.com/verdverm/go-symexpr"
+)
+
+type PgeConfig struct {
+	// search params
+	maxGen        int
+	pgeRptEpoch   int
+	pgeRptCount   int
+	pgeArchiveCap int
+
+	simprules expr.SimpRules
+	treecfg   *probs.TreeParams
+
+	// PGE specific options
+	peelCnt     int
+	sortType    probs.SortType
+	zeroEpsilon float64
+
+	initMethod string
+	growMethod string
+
+	evalrCount int
+}
+
+func pgeConfigParser(field, value string, config interface{}) (err error) {
+
+	PC := config.(*PgeConfig)
+
+	switch strings.ToUpper(field) {
+	case "MAXGEN":
+		PC.maxGen, err = strconv.Atoi(value)
+	case "PGERPTEPOCH":
+		PC.pgeRptEpoch, err = strconv.Atoi(value)
+	case "PGERPTCOUNT":
+		PC.pgeRptCount, err = strconv.Atoi(value)
+	case "PGEARCHIVECAP":
+		PC.pgeArchiveCap, err = strconv.Atoi(value)
+
+	case "PEELCOUNT":
+		PC.peelCnt, err = strconv.Atoi(value)
+
+	case "EVALRCOUNT":
+		PC.evalrCount, err = strconv.Atoi(value)
+
+	case "SORTTYPE":
+		switch strings.ToLower(value) {
+		case "paretotrainerror":
+			PC.sortType = probs.PESORT_PARETO_TRN_ERR
+		case "paretotesterror":
+			PC.sortType = probs.PESORT_PARETO_TST_ERR
+
+		default:
+			log.Printf("PGE Config Not Implemented: %s, %s\n\n", field, value)
+		}
+
+	case "ZEROEPSILON":
+		PC.zeroEpsilon, err = strconv.ParseFloat(value, 64)
+
+	default:
+		// check augillary parsable structures [only TreeParams for now]
+		if PC.treecfg == nil {
+			PC.treecfg = new(probs.TreeParams)
+		}
+		found, ferr := probs.ParseTreeParams(field, value, PC.treecfg)
+		if ferr != nil {
+			log.Fatalf("error parsing PGE - treecfg Config\n")
+			return ferr
+		}
+		if !found {
+			log.Printf("PGE Config Not Implemented: %s, %s\n\n", field, value)
+		}
+
+	}
+	return
+}
+
+type PgeSearch struct {
+	id   int
+	cnfg PgeConfig
+	prob *probs.ExprProblem
+	iter int
+	stop bool
+
+	// comm up
+	commup *probs.ExprProblemComm
+
+	// comm down
+
+	// best exprs
+	Best *probs.ReportQueue
+
+	// training data in C format
+	c_input  []levmar.C_double
+	c_ygiven []levmar.C_double
+
+	// logs
+	logDir     string
+	mainLog    *log.Logger
+	mainLogBuf *bufio.Writer
+	eqnsLog    *log.Logger
+	eqnsLogBuf *bufio.Writer
+	errLog     *log.Logger
+	errLogBuf  *bufio.Writer
+
+	fitnessLog    *log.Logger
+	fitnessLogBuf *bufio.Writer
+	ipreLog       *log.Logger
+	ipreLogBuf    *bufio.Writer
+
+	// equations visited
+	Trie  *IpreNode
+	Queue *probs.ReportQueue
+
+	// eval channels
+	eval_in  chan expr.Expr
+	eval_out chan *probs.ExprReport
+
+	// genStuff
+	GenRoots   []expr.Expr
+	GenLeafs   []expr.Expr
+	GenNodes   []expr.Expr
+	GenNonTrig []expr.Expr
+
+	// FFXish stuff
+	ffxBases []expr.Expr
+
+	// statistics
+	neqns    int
+	ipreCnt  int
+	maxSize  int
+	maxScore int
+	minError float64
+}
+
+func (PS *PgeSearch) GetMaxIter() int {
+	return PS.cnfg.maxGen
+}
+func (PS *PgeSearch) GetPeelCount() int {
+	return PS.cnfg.peelCnt
+}
+func (PS *PgeSearch) SetMaxIter(iter int) {
+	PS.cnfg.maxGen = iter
+}
+func (PS *PgeSearch) SetPeelCount(cnt int) {
+	PS.cnfg.peelCnt = cnt
+}
+func (PS *PgeSearch) SetInitMethod(init string) {
+	PS.cnfg.initMethod = init
+}
+func (PS *PgeSearch) SetGrowMethod(grow string) {
+	PS.cnfg.growMethod = grow
+}
+func (PS *PgeSearch) SetEvalrCount(cnt int) {
+	PS.cnfg.evalrCount = cnt
+}
+
+func (PS *PgeSearch) ParseConfig(filename string) {
+	fmt.Printf("Parsing PGE Config: %s\n", filename)
+	data, err := ioutil.ReadFile(filename)
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = config.ParseConfig(data, pgeConfigParser, &PS.cnfg)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func (PS *PgeSearch) Init(done chan int, prob *probs.ExprProblem, logdir string, input interface{}) {
+
+	//fmt.Printf("Init'n PGE\n")
+	// setup data
+
+	// open logs
+	PS.initLogs(logdir)
+	
+	PS.stop = false
+
+	// copy in common config options
+	PS.prob = prob
+	if PS.cnfg.treecfg == nil {
+		PS.cnfg.treecfg = PS.prob.TreeCfg.Clone()
+	}
+	srules := expr.DefaultRules()
+	srules.ConvertConsts = true
+	PS.cnfg.simprules = srules
+
+	//fmt.Println("Roots:   ", PS.cnfg.treecfg.RootsS)
+	//fmt.Println("Nodes:   ", PS.cnfg.treecfg.NodesS)
+	//fmt.Println("Leafs:   ", PS.cnfg.treecfg.LeafsS)
+	//fmt.Println("NonTrig: ", PS.cnfg.treecfg.NonTrigS)
+
+	PS.GenRoots = make([]expr.Expr, len(PS.cnfg.treecfg.Roots))
+	for i := 0; i < len(PS.GenRoots); i++ {
+		PS.GenRoots[i] = PS.cnfg.treecfg.Roots[i].Clone()
+	}
+	PS.GenNodes = make([]expr.Expr, len(PS.cnfg.treecfg.Nodes))
+	for i := 0; i < len(PS.GenNodes); i++ {
+		PS.GenNodes[i] = PS.cnfg.treecfg.Nodes[i].Clone()
+	}
+	PS.GenNonTrig = make([]expr.Expr, len(PS.cnfg.treecfg.NonTrig))
+	for i := 0; i < len(PS.GenNonTrig); i++ {
+		PS.GenNonTrig[i] = PS.cnfg.treecfg.NonTrig[i].Clone()
+	}
+
+	PS.GenLeafs = make([]expr.Expr, 0)
+	for _, t := range PS.cnfg.treecfg.LeafsT {
+		switch t {
+		case expr.TIME:
+			PS.GenLeafs = append(PS.GenLeafs, expr.NewTime())
+
+		case expr.VAR:
+			//fmt.Println("Use Vars: ", PS.cnfg.treecfg.UsableVars)
+			for _, i := range PS.cnfg.treecfg.UsableVars {
+				PS.GenLeafs = append(PS.GenLeafs, expr.NewVar(i))
+			}
+
+		case expr.SYSTEM:
+			for i := 0; i < PS.prob.Train[0].NumSys(); i++ {
+				PS.GenLeafs = append(PS.GenLeafs, expr.NewSystem(i))
+			}
+
+		}
+	}
+	/*** FIX ME
+	PS.GenLeafs = make([]expr.Expr, len(PS.cnfg.treecfg.Leafs))
+	for i := 0; i < len(PS.GenLeafs); i++ {
+		PS.GenLeafs[i] = PS.cnfg.treecfg.Leafs[i].Clone()
+	}
+	***/
+
+	//fmt.Println("Roots:   ", PS.GenRoots)
+	//fmt.Println("Nodes:   ", PS.GenNodes)
+	//fmt.Println("Leafs:   ", PS.GenLeafs)
+	//fmt.Println("NonTrig: ", PS.GenNonTrig)
+
+	// setup communication struct
+	PS.commup = input.(*probs.ExprProblemComm)
+
+	// initialize bbq
+	PS.Trie = new(IpreNode)
+	PS.Trie.val = -1
+	PS.Trie.next = make(map[int]*IpreNode)
+
+	PS.Best = probs.NewReportQueue()
+	PS.Best.SetSort(probs.GPSORT_PARETO_TST_ERR)
+
+	PS.Queue = PS.GenInitExpr()
+	PS.Queue.SetSort(probs.PESORT_PARETO_TST_ERR)
+
+	PS.neqns = PS.Queue.Len()
+
+	PS.minError = math.Inf(1)
+
+	PS.eval_in = make(chan expr.Expr, 4048)
+	PS.eval_out = make(chan *probs.ExprReport, 4048)
+
+	for i := 0; i < PS.cnfg.evalrCount; i++ {
+		go PS.Evaluate()
+	}
+}
+
+func (PS *PgeSearch) Evaluate() {
+
+	for !PS.stop {
+		e := <-PS.eval_in
+		if e == nil {
+			continue
+		}
+		re := RegressExpr(e, PS.prob)
+		//fmt.Printf("reg: %v\n", re)
+		PS.eval_out <- re
+	}
+
+}
+
+func (PS *PgeSearch) Run() {
+	fmt.Printf("Running PGE\n")
+
+	PS.Loop()
+
+	fmt.Println("PGE exitting")
+
+	PS.Clean()
+	PS.commup.Cmds <- -1
+}
+
+func (PS *PgeSearch) Loop() {
+
+	PS.checkMessages()
+	for !PS.stop {
+
+		fmt.Println("in: PS.step() ", PS.iter)
+		PS.Step()
+
+		// if PS.iter%PS.cnfg.pgeRptEpoch == 0 {
+		PS.reportExpr()
+		// }
+
+		// report current iteration
+		PS.commup.Gen <- [2]int{PS.id, PS.iter}
+		PS.iter++
+
+		PS.Clean()
+
+		PS.checkMessages()
+
+	}
+
+	// done expanding, pull the rest of the regressed solutions from the queue
+	p := 0
+	for PS.Queue.Len() > 0 {
+		e := PS.Queue.Pop().(*probs.ExprReport)
+
+		bPush := true
+		if len(e.Coeff()) == 1 && math.Abs(e.Coeff()[0]) < PS.cnfg.zeroEpsilon {
+			// fmt.Println("No Best Push")
+			bPush = false
+		}
+
+		if bPush {
+			// fmt.Printf("pop/push(%d,%d): %v\n", p, PS.Best.Len(), e.Expr())
+			PS.Best.Push(e)
+			p++
+		}
+
+		if e.TestScore() > PS.maxScore {
+			PS.maxScore = e.TestScore()
+		}
+		if e.TestError() < PS.minError {
+			PS.minError = e.TestError()
+			fmt.Printf("EXITING New Min Error:  %v\n", e)
+		}
+		if e.Size() > PS.maxSize {
+			PS.maxSize = e.Size()
+		}
+	}
+
+	fmt.Println("PGE sending last report")
+	PS.reportExpr()
+
+}
+
+func (PS *PgeSearch) Step() {
+	loop := 0
+	eval_cnt := 0 // for channeled eval
+
+	es := PS.peel()
+
+	ex := PS.expandPeeled(es)
+
+	for cnt := range ex {
+		E := ex[cnt]
+
+		if E == nil {
+			continue
+		}
+
+		for _, e := range E {
+			if e == nil {
+				continue
+			}
+			if !PS.cnfg.treecfg.CheckExpr(e) {
+				continue
+			}
+
+			// check ipre_trie
+			serial := make([]int, 0, 64)
+			serial = e.Serial(serial)
+			ins := PS.Trie.InsertSerial(serial)
+			if !ins {
+				continue
+			}
+
+			// for serial eval
+			// re := RegressExpr(e, PS.prob)
+
+			// start channeled eval
+			PS.eval_in <- e
+			eval_cnt++
+		}
+	}
+	for i := 0; i < eval_cnt; i++ {
+		re := <-PS.eval_out
+		// end channeled eval
+
+		// check for NaN/Inf in re.error  and  if so, skip
+		if math.IsNaN(re.TestError()) || math.IsInf(re.TestError(), 0) {
+			// fmt.Printf("Bad Error\n%v\n", re)
+			continue
+		}
+
+		if re.TestError() < PS.minError {
+			PS.minError = re.TestError()
+		}
+
+		// check for coeff == 0
+		doIns := true
+		for _, c := range re.Coeff() {
+			// i > 0 for free coeff
+			if math.Abs(c) < PS.cnfg.zeroEpsilon {
+				doIns = false
+				break
+			}
+		}
+
+		if doIns {
+			re.SetProcID(PS.id)
+			re.SetIterID(PS.iter)
+			re.SetUnitID(loop)
+			re.SetUniqID(PS.neqns)
+			loop++
+			PS.neqns++
+			// fmt.Printf("Queue.Push(): %v\n%v\n\n", re.Expr(), serial)
+			// fmt.Printf("Queue.Push(): %v\n", re)
+			// fmt.Printf("Queue.Push(): %v\n", re.Expr())
+
+			PS.Queue.Push(re)
+
+		}
+	}
+	// } // for sequential eval
+	PS.Queue.Sort()
+}
+
+func (PS *PgeSearch) peel() []*probs.ExprReport {
+	es := make([]*probs.ExprReport, PS.cnfg.peelCnt)
+	for p := 0; p < PS.cnfg.peelCnt && PS.Queue.Len() > 0; p++ {
+		e := PS.Queue.Pop().(*probs.ExprReport)
+		bPush := true
+		if len(e.Coeff()) == 1 && math.Abs(e.Coeff()[0]) < PS.cnfg.zeroEpsilon {
+			fmt.Println("No Best Push")
+			p--
+			continue
+		}
+
+		if bPush {
+			fmt.Printf("pop/push DO(%d,%d): %v\n", p, PS.Best.Len(), e.Expr())
+			PS.Best.Push(e)
+		}
+
+		es[p] = e
+
+		if e.TestScore() > PS.maxScore {
+			PS.maxScore = e.TestScore()
+		}
+		if e.TestError() < PS.minError {
+			PS.minError = e.TestError()
+			fmt.Printf("Best New Min Error:  %v\n", e)
+		}
+		if e.Size() > PS.maxSize {
+			PS.maxSize = e.Size()
+		}
+
+	}
+	return es
+}
+
+
+type PeelResult struct {
+	Es *probs.ExprReport
+
+	Nobestpush bool
+	BestNewMinErr bool
+	
+	Bestlen1 int
+	Bestlen2 int
+	
+	Coeff []float64
+	TestScore int
+	
+	Expre expr.Expr
+	ExpreRe *probs.ExprReport
+}
+
+
+func (PS *PgeSearch) SingleStep() []*PeelResult {
+	loop := 0
+	eval_cnt := 0
+	PR := PS.peelRes()
+	
+	es := make([]*probs.ExprReport, len(PR))
+	
+	for i, elem := range PR {
+		es[i] = elem.ExpreRe
+	}
+	
+	ex := PS.expandPeeled(es)
+
+	for cnt := range ex {
+		E := ex[cnt]
+		if E == nil {
+			continue
+		}
+		for _, e := range E {
+			if e == nil {
+				continue
+			}
+			if !PS.cnfg.treecfg.CheckExpr(e) {
+				continue
+			}
+			serial := make([]int, 0, 64)
+			serial = e.Serial(serial)
+			ins := PS.Trie.InsertSerial(serial)
+			
+			if !ins {
+				continue
+			}
+			PS.eval_in <- e
+			eval_cnt++
+		}
+	}
+	for i := 0; i < eval_cnt; i++ {
+		re := <-PS.eval_out
+		if math.IsNaN(re.TestError()) || math.IsInf(re.TestError(), 0) {
+			continue
+		}
+		if re.TestError() < PS.minError {
+			PS.minError = re.TestError()
+		}
+		doIns := true
+		for _, c := range re.Coeff() {
+			if math.Abs(c) < PS.cnfg.zeroEpsilon {
+				doIns = false
+				break
+			}
+		}
+		if doIns {
+			re.SetProcID(PS.id)
+			re.SetIterID(PS.iter)
+			re.SetUnitID(loop)
+			re.SetUniqID(PS.neqns)
+			loop++
+			PS.neqns++
+			PS.Queue.Push(re)
+		}
+	}
+	PS.Queue.Sort()
+
+	PS.reportExpr()	
+	PS.iter++
+	
+	return PR
+}
+
+func (PS *PgeSearch) peelRes() []*PeelResult {
+	//es := make([]*probs.ExprReport, PS.cnfg.peelCnt)
+	PRes := make([]*PeelResult, PS.cnfg.peelCnt)
+	
+	for p := 0; p < PS.cnfg.peelCnt && PS.Queue.Len() > 0; p++ {
+		PR := new(PeelResult)
+		
+		PR.BestNewMinErr = false
+		PR.Nobestpush = false
+		
+		e := PS.Queue.Pop().(*probs.ExprReport)
+		
+		bPush := true
+		if len(e.Coeff()) == 1 && math.Abs(e.Coeff()[0]) < PS.cnfg.zeroEpsilon {
+			//fmt.Println("No Best Push")
+			PR.Nobestpush = true
+			p--
+			continue
+		}
+
+		if bPush {
+			//fmt.Printf("pop/push (%d,%d): %v\n", p, PS.Best.Len(), e.Expr())
+			PR.Bestlen1 = p
+			PR.Bestlen2 = PS.Best.Len()
+			PR.Expre = e.Expr()
+			PR.ExpreRe = e
+			PS.Best.Push(e)
+		}
+
+		//es[p] = e
+		PR.Es = e
+		PR.Coeff = e.Coeff()
+		PR.TestScore = e.TestScore()
+		
+		
+		if e.TestScore() > PS.maxScore {
+			PS.maxScore = e.TestScore()
+		}
+		if e.TestError() < PS.minError {
+			PS.minError = e.TestError()
+			PR.BestNewMinErr = true
+			//fmt.Printf("Best New Min Error:  %v\n", e)
+		}
+		if e.Size() > PS.maxSize {
+			PS.maxSize = e.Size()
+		}
+		
+		PRes[p] = PR
+	}
+	
+	return PRes
+}
+
+
+func (PS *PgeSearch) expandPeeled(es []*probs.ExprReport) [][]expr.Expr {
+	eqns := make([][]expr.Expr, PS.cnfg.peelCnt)
+	for p := 0; p < PS.cnfg.peelCnt; p++ {
+		if es[p] == nil {
+			continue
+		}
+		// fmt.Printf("expand(%d): %v\n", p, es[p].Expr())
+		if es[p].Expr().ExprType() != expr.ADD {
+			add := expr.NewAdd()
+			add.Insert(es[p].Expr())
+			add.CalcExprStats()
+			es[p].SetExpr(add)
+		}
+		eqns[p] = PS.Expand(es[p].Expr())
+		// fmt.Printf("Results:\n")
+		// for i, e := range eqns[p] {
+		// 	fmt.Printf("%d,%d:  %v\n", p, i, e)
+		// }
+		// fmt.Println()
+	}
+	return eqns
+}
+
+func (PS *PgeSearch) reportExpr() {
+
+	cnt := PS.cnfg.pgeRptCount
+	PS.Best.Sort()
+
+	// repot best equations
+	rpt := make(probs.ExprReportArray, cnt)
+	if PS.Best.Len() < cnt {
+		cnt = PS.Best.Len()
+	}
+	copy(rpt, PS.Best.GetQueue()[:cnt])
+
+	errSum, errCnt := 0.0, 0
+	PS.eqnsLog.Println("\n\nReport", PS.iter)
+	for i, r := range rpt {
+		PS.eqnsLog.Printf("\n%d:  %v\n", i, r)
+		if r != nil && r.Expr() != nil {
+			errSum += r.TestError()
+			errCnt++
+		}
+	}
+
+	PS.mainLog.Printf("Iter: %d  %f  %f\n", PS.iter, errSum/float64(errCnt), PS.minError)
+
+	PS.ipreLog.Println(PS.iter, PS.neqns, PS.Trie.cnt, PS.Trie.vst)
+	PS.fitnessLog.Println(PS.iter, PS.neqns, PS.Trie.cnt, PS.Trie.vst, errSum/float64(errCnt), PS.minError)
+
+	PS.commup.Rpts <- &rpt
+
+}
+
+func (PS *PgeSearch) Clean() {
+	PS.errLogBuf.Flush()
+	PS.mainLogBuf.Flush()
+	PS.eqnsLogBuf.Flush()
+	PS.fitnessLogBuf.Flush()
+	PS.ipreLogBuf.Flush()
+}
+
+func (PS *PgeSearch) initLogs(logdir string) {
+	// open logs
+	PS.logDir = logdir + "pge/"
+	os.Mkdir(PS.logDir, os.ModePerm)
+	tmpF0, err5 := os.Create(PS.logDir + "pge:err.log")
+	if err5 != nil {
+		log.Fatal("couldn't create errs log")
+	}
+	PS.errLogBuf = bufio.NewWriter(tmpF0)
+	PS.errLogBuf.Flush()
+	PS.errLog = log.New(PS.errLogBuf, "", log.LstdFlags)
+
+	tmpF1, err1 := os.Create(PS.logDir + "pge:main.log")
+	if err1 != nil {
+		log.Fatal("couldn't create main log")
+	}
+	PS.mainLogBuf = bufio.NewWriter(tmpF1)
+	PS.mainLogBuf.Flush()
+	PS.mainLog = log.New(PS.mainLogBuf, "", log.LstdFlags)
+
+	tmpF2, err2 := os.Create(PS.logDir + "pge:eqns.log")
+	if err2 != nil {
+		log.Fatal("couldn't create eqns log")
+	}
+	PS.eqnsLogBuf = bufio.NewWriter(tmpF2)
+	PS.eqnsLogBuf.Flush()
+	PS.eqnsLog = log.New(PS.eqnsLogBuf, "", 0)
+
+	tmpF3, err3 := os.Create(PS.logDir + "pge:fitness.log")
+	if err3 != nil {
+		log.Fatal("couldn't create eqns log")
+	}
+	PS.fitnessLogBuf = bufio.NewWriter(tmpF3)
+	PS.fitnessLogBuf.Flush()
+	PS.fitnessLog = log.New(PS.fitnessLogBuf, "", log.Ltime|log.Lmicroseconds)
+
+	tmpF4, err4 := os.Create(PS.logDir + "pge:ipre.log")
+	if err4 != nil {
+		log.Fatal("couldn't create eqns log")
+	}
+	PS.ipreLogBuf = bufio.NewWriter(tmpF4)
+	PS.ipreLogBuf.Flush()
+	PS.ipreLog = log.New(PS.ipreLogBuf, "", log.Ltime|log.Lmicroseconds)
+}
+
+func (PS *PgeSearch) checkMessages() {
+
+	// check messages from superior
+	select {
+	case cmd, ok := <-PS.commup.Cmds:
+		if ok {
+			if cmd == -1 {
+				fmt.Println("PGE: stop sig recv'd")
+				PS.stop = true
+				return
+			}
+		}
+	default:
+		return
+	}
+}
+
+var c_input, c_ygiven []levmar.C_double
+
+func RegressExpr(E expr.Expr, P *probs.ExprProblem) (R *probs.ExprReport) {
+
+	guess := make([]float64, 0)
+	guess, eqn := E.ConvertToConstants(guess)
+
+	var coeff []float64
+	if len(guess) > 0 {
+
+		//fmt.Printf("IMREGEXP %v %v\n", P.SearchType, P.SearchVar)
+		//fmt.Printf("REGPTrain %T | %#v | %v\n", P.Train, P.Train, P.Train)
+		//fmt.Printf("eqn %T | %#v | %v\n", eqn, eqn, eqn)
+		//fmt.Printf("guess %T | %#v | %v\n", guess, guess, guess)
+
+		// Callback version
+		
+		
+		coeff = levmar.LevmarExpr(eqn, P.SearchVar, P.SearchType, guess, P.Train, P.Test)
+		
+
+		// Stack version
+		// x_dim := P.Train[0].NumDim()
+		// if c_input == nil {
+		// 	ps := P.Train[0].NumPoints()
+		// 	PS := len(P.Train) * ps
+		// 	x_tot := PS * x_dim
+
+		// 	c_input = make([]levmar.C_double, x_tot)
+		// 	c_ygiven = make([]levmar.C_double, PS)
+
+		// 	for i1, T := range P.Train {
+		// 		for i2, p := range T.Points() {
+		// 			i := i1*ps + i2
+		// 			c_ygiven[i] = levmar.MakeCDouble(p.Depnd(P.SearchVar))
+		// 			for i3, x_p := range p.Indeps() {
+		// 				j := i1*ps*x_dim + i2*x_dim + i3
+		// 				c_input[j] = levmar.MakeCDouble(x_p)
+		// 			}
+		// 		}
+		// 	}
+		// }
+		// coeff = levmar.StackLevmarExpr(eqn, x_dim, guess, c_ygiven, c_input)
+
+		// serial := make([]int, 0)
+		// serial = eqn.StackSerial(serial)
+		// fmt.Printf("StackSerial: %v\n", serial)
+		// fmt.Printf("%v\n%v\n%v\n\n", eqn, coeff, steff)
+	}
+
+	R = new(probs.ExprReport)
+	R.SetExpr(eqn) /*.ConvertToConstantFs(coeff)*/
+
+	R.SetCoeff(coeff)
+	R.Expr().CalcExprStats()
+
+	// hitsL1, hitsL2, evalCnt, nanCnt, infCnt, l1_err, l2_err := scoreExpr(E, P, coeff)
+	_, _, _, trnNanCnt, _, trn_l1_err, _ := scoreExpr(E, P, P.Train, coeff)
+	_, _, tstEvalCnt, tstNanCnt, _, tst_l1_err, tst_l2_err := scoreExpr(E, P, P.Test, coeff)
+
+	R.SetTrainScore(trnNanCnt)
+	R.SetTrainError(trn_l1_err)
+
+	R.SetPredScore(tstNanCnt)
+	R.SetTestScore(tstEvalCnt)
+	R.SetTestError(tst_l1_err)
+	R.SetPredError(tst_l2_err)
+
+	return R
+}
+
+func scoreExpr(e expr.Expr, P *probs.ExprProblem, dataSets []*probs.PointSet, coeff []float64) (hitsL1, hitsL2, evalCnt, nanCnt, infCnt int, l1_err, l2_err float64) {
+	var l1_sum, l2_sum float64
+	for _, PS := range dataSets {
+		for _, p := range PS.Points() {
+			y := p.Depnd(P.SearchVar)
+			var out float64
+			if P.SearchType == probs.ExprBenchmark {
+				out = e.Eval(0, p.Indeps(), coeff, PS.SysVals())
+			} else if P.SearchType == probs.ExprDiffeq {
+				out = e.Eval(p.Indep(0), p.Indeps()[1:], coeff, PS.SysVals())
+			}
+
+			if math.IsNaN(out) {
+				nanCnt++
+				continue
+			} else if math.IsInf(out, 0) {
+				infCnt++
+				continue
+			} else {
+				evalCnt++
+			}
+
+			diff := out - y
+			l1_val := math.Abs(diff)
+			l2_val := diff * diff
+			l1_sum += l1_val
+			l2_sum += l2_val
+
+			if l1_val < P.HitRatio {
+				hitsL1++
+			}
+			if l2_val < P.HitRatio {
+				hitsL2++
+			}
+		}
+	}
+
+	if evalCnt == 0 {
+		l1_err = math.NaN()
+		l2_err = math.NaN()
+	} else {
+		fEvalCnt := float64(evalCnt + 1)
+		l1_err = l1_sum / fEvalCnt
+		l2_err = math.Sqrt(l2_sum / fEvalCnt)
+	}
+
+	return
+}
+
+func (PS *PgeSearch) CreateDS(maxGen int, pgeRptEpoch int, pgeRptCount int, pgeArchiveCap int, peelCnt int, evalrCount int, zeroEpsilon float64, initMethod string, growMethod string, sortType int) {
+	PS.id = 0 //maxGen
+	
+	var PC PgeConfig
+	
+	PC.pgeRptEpoch = pgeRptEpoch
+	PC.pgeRptCount = pgeRptCount
+	PC.pgeArchiveCap = pgeArchiveCap
+	PC.peelCnt = peelCnt
+	PC.evalrCount = evalrCount
+	PC.zeroEpsilon = zeroEpsilon
+	PC.initMethod = initMethod
+	PC.growMethod = growMethod
+
+	if sortType == 1 {
+		PC.sortType = probs.PESORT_PARETO_TRN_ERR
+	} else {	
+		PC.sortType = probs.PESORT_PARETO_TST_ERR
+	}
+
+	PC.maxGen = maxGen
+	PS.cnfg = PC
+		
+	PS.iter = 0
+}
+
+func (PS *PgeSearch) SetProb(ep *probs.ExprProblem) {
+	PS.prob = ep
+}
+func (PS *PgeSearch) GetIter() int {
+	return PS.iter
+}
