func (isle *EqnIsland) selecting() { // isle.mainLog.Println("Selecting EqnIsland ", isle.id, isle.gen) // select within brood to pareto isle.selectBroodToPareto(probs.GPSORT_PRE_ERR) // add migrants to pareto (may need to increase size) pLen := isle.pareto.Len() isle.pareto = append(isle.pareto, isle.migrants...) // sort pareto queue := probs.NewQueueFromArray(isle.pareto) queue.SetSort(probs.GPSORT_PARETO_PRE_ERR) queue.Sort() // select for parents (just a copy from pareto to parents) for i := 0; i < isle.numEqns; i++ { isle.parents[i] = isle.pareto[i] } isle.pareto = isle.pareto[:pLen] }
func (isle *EqnIsland) init() { fmt.Println("Initializing EqnIsland ", isle.id) // create random number generator isle.rng = rand.New(rand.NewSource(rand.Int63())) // init logs isle.initLogs() isle.mainLog.Println("Initializing EqnIsland ", isle.id) isle.minError = 1000000.0 isle.trie = new(IpreNode) isle.trie.val = -1 isle.trie.next = make(map[int]*IpreNode) // create random equations isle.initEqns() // evaluate initial equations isle.initEval() // select within brood to pareto isle.selectBroodToPareto(probs.GPSORT_TRN_ERR) isle.eqnsLog.Println("EqnIsle Init Best of Brood") for i := 0; i < isle.numEqns; i++ { isle.eqnsLog.Println(isle.pareto[i]) } isle.eqnsLog.Println() isle.eqnsLog.Println() // sort pareto queue := probs.NewQueueFromArray(isle.pareto) queue.SetSort(probs.GPSORT_PARETO_TRN_ERR) queue.Sort() isle.eqnsLog.Println("EqnIsle Init Pareto Sorted") for i := 0; i < isle.numEqns; i++ { isle.eqnsLog.Println(isle.pareto[i]) } isle.eqnsLog.Println() isle.eqnsLog.Println() // select for parents (just a copy from pareto to parents) for i := 0; i < isle.numEqns; i++ { isle.parents[i] = isle.pareto[i] } // report best eqns isle.report() // rpt := make(probs.ExprReportArray, isle.eqnRptCount) // for i := 0; i < isle.eqnRptCount; i++ { // // fmt.Println(i) // rpt[i] = isle.parents[i].Clone() // } // isle.eqnRpt <- &rpt isle.breed() // flush logs at end of init isle.flushLogs() }
func (GS *GpsrSearch) checkMessages() { // check messages from superior if !GS.stop { select { case cmd, ok := <-GS.commup.Cmds: if ok { if cmd == -1 { GS.stop = true GS.doStop() } } default: goto nocmd } nocmd: } // check generations for { select { case egen, ok := <-GS.eqnGen: if ok { GS.eqnGenCtr[egen[0]] = egen[1] } case sgen, ok := <-GS.ssetGen: if ok { GS.ssetGenCtr[sgen[0]] = sgen[1] } default: goto nogen } } nogen: // check for equations for i := 0; i < len(GS.per_eqns); i++ { select { case eqns, ok := <-GS.eqnRpt[i]: if ok { for !atomic.CompareAndSwapInt32(&GS.per_eqlock, 0, 1) { time.Sleep(time.Microsecond) } GS.per_eqns[i] = eqns atomic.StoreInt32(&GS.per_eqlock, 0) GS.per_equpd[i]++ i-- // so we get the latest report } // so we don't wait indefinitely for msg in select default: continue } } peSum := 0 for _, s := range GS.per_equpd { peSum += s } if peSum >= len(GS.per_equpd) && peSum > 0 && !firstMsgCheck { for i, _ := range GS.per_equpd { GS.per_equpd[i] = 0 } go func() { for !atomic.CompareAndSwapInt32(&GS.gof_eqlock, 0, 1) { time.Sleep(time.Microsecond) } GS.accumExprReports() GS.pnts = calcEqnErrs(GS.eqns.GetQueue(), GS.prob) GS.publishErrors() // GS.reportExprs() atomic.StoreInt32(&GS.gof_eqlock, 0) }() } // check for subsets for i := 0; i < len(GS.per_sset); i++ { select { case sset, ok := <-GS.ssetRpt[i]: if ok { // fmt.Println("sset comm ", len(sset)) GS.per_sset[i] = sset GS.per_ssupd[i]++ i-- // to get the latest } // so we don't wait indefinitely for msg in select default: continue } } psSum := 0 for _, s := range GS.per_ssupd { psSum += s } if psSum >= len(GS.per_ssupd) && psSum > 0 && !firstMsgCheck { for i, _ := range GS.per_ssupd { GS.per_ssupd[i] = 0 } GS.accumSSets() GS.publishSSets() } firstMsgCheck = false } func (GS *GpsrSearch) accumExprReports() { if GS.eqnsUnion == nil { // the plus 1 is for the already accumulated eqns in GS.eqns tmp := make(probs.ExprReportArray, (GS.cnfg.numEqnIsles+1)*GS.cnfg.numEqns) GS.eqnsUnion = probs.NewQueueFromArray(tmp) GS.eqnsUnion.SetSort(probs.GPSORT_PARETO_TST_ERR) } if GS.eqns == nil { tmp := make(probs.ExprReportArray, GS.cnfg.numEqns) GS.eqns = probs.NewQueueFromArray(tmp) GS.eqns.SetSort(probs.GPSORT_PARETO_TST_ERR) } // fill union for !atomic.CompareAndSwapInt32(&GS.per_eqlock, 0, 1) { time.Sleep(time.Microsecond) } union := GS.eqnsUnion.GetQueue() p1, p2 := 0, 0 for i := 0; i < GS.cnfg.numEqnIsles; i++ { p1 = i * GS.cnfg.numEqns p2 = p1 + GS.cnfg.numEqns copy(union[p1:p2], *(GS.per_eqns[i])) } p1 = p2 p2 += GS.cnfg.numEqns copy(union[p1:p2], GS.eqns.GetQueue()) atomic.StoreInt32(&GS.per_eqlock, 0) // remove duplicates sort.Sort(union) // ipretree accounting for _, r := range union { if r == nil || r.Expr() == nil { continue } GS.neqns++ e := r.Expr() serial := make([]int, 0, 64) serial = e.Serial(serial) GS.trie.InsertSerial(serial) } last := 0 for union[last] == nil { last++ } for i := last + 1; i < len(union); i++ { if union[i] == nil { continue } if union[i].Expr().AmIAlmostSame(union[last].Expr()) { union[i] = nil } else { last = i } } // evaluate union members on test data calcEqnTestErr(union, GS.prob) errSum, errCnt := 0.0, 0 for _, r := range union { if r == nil { continue } if r.TestError() < GS.minError { GS.minError = r.TestError() } errSum += r.TestError() errCnt++ } GS.fitnessLog.Println(GS.gen, GS.neqns, GS.trie.cnt, GS.trie.vst, errSum/float64(errCnt), GS.minError) // pareto sort union by test error GS.eqnsUnion.Sort() // copy |GS.cnfg.numEqns| from union to GS.eqns copy(GS.eqns.GetQueue(), GS.eqnsUnion.GetQueue()[:GS.cnfg.numEqns]) GS.eqns.Sort() } func (GS *GpsrSearch) publishErrors() { GS.mainLog.Println("publishing Errors") for _, ep := range GS.errPub { // fmt.Println(i) ep <- GS.pnts } } func (GS *GpsrSearch) accumSSets() { if GS.ssetUnion == nil { GS.ssetUnion = make([]ssetIsleMem, (GS.cnfg.numSSetIsles+1)*GS.cnfg.ssetRptCount) } if GS.sset == nil { GS.sset = make([]ssetIsleMem, GS.cnfg.ssetRptCount) } union := GS.ssetUnion p1, p2 := 0, 0 for i := 0; i < GS.cnfg.numSSetIsles; i++ { p1 = i * GS.cnfg.ssetRptCount p2 = p1 + GS.cnfg.ssetRptCount // fmt.Println("SSet Accum: ", i, p1, p2) // fmt.Println(len(GS.per_sset), len(union)) copy(union[p1:p2], GS.per_sset[i]) } p1 = p2 p2 += GS.cnfg.ssetRptCount copy(union[p1:p2], GS.sset) // for i, u := range union { // fmt.Println("union ", i, u) // } if GS.rng.Intn(2) == 0 { sort.Sort(ssetVarArray{union}) copy(GS.sset, union[:GS.cnfg.ssetRptCount]) sort.Sort(ssetErrArray(GS.sset)) } else { sort.Sort(ssetErrArray(union)) copy(GS.sset, union[:GS.cnfg.ssetRptCount]) sort.Sort(ssetVarArray{GS.sset}) } } func (GS *GpsrSearch) publishSSets() { pub := make([]*probs.PntSubset, GS.cnfg.ssetRptCount) for i := 0; i < GS.cnfg.ssetRptCount; i++ { p := GS.rng.Intn(len(GS.sset)) pub[i] = makeSubsetFromMem(GS.prob, GS.sset[p]) } for _, sp := range GS.ssetPub { sp <- pub } } func (GS *GpsrSearch) reportExprs() { cnt := GS.cnfg.gpsrRptCount rpt := make(probs.ExprReportArray, cnt) copy(rpt, GS.eqns.GetQueue()[:cnt]) GS.eqnsLog.Println("GEN: ", GS.gen, len(rpt)) for i, r := range rpt { GS.eqnsLog.Println(i, r.Expr().Latex(GS.prob.Train[0].GetIndepNames(), GS.prob.Train[0].GetSysNames(), r.Coeff())) GS.eqnsLog.Println(r, "\n") } GS.commup.Rpts <- &rpt } func (GS *GpsrSearch) doStop() { num_subs := len(GS.eqnIsles) + len(GS.ssetIsles) done := make(chan int, num_subs) for i, _ := range GS.eqnCmd { func() { C := GS.eqnCmd[i] c := i go func() { C <- -1 fmt.Printf("sent -1 to eqn %d\n", c) <-C done <- 1 }() }() } for i, _ := range GS.ssetCmd { func() { C := GS.ssetCmd[i] c := i go func() { C <- -1 fmt.Printf("sent -1 to sset %d\n", c) <-C done <- 1 }() }() } cnt := 0 for cnt < num_subs { GS.checkMessages() // select { // case _, ok := <-done: // if ok { // cnt++ // fmt.Println("GS.done.cnt = ", cnt, num_subs) // } // default: // continue // } _, ok := <-done if ok { cnt++ fmt.Println("GS.done.cnt = ", cnt, num_subs) } } fmt.Println("GS: Done Killing") }