示例#1
0
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]

}
示例#2
0
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()

}
示例#3
0
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")
}