source: branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/go-code/go-pge/problems/report.go @ 16080

Last change on this file since 16080 was 16080, checked in by hmaislin, 16 months ago

#2929 initial commit of working PGE version

File size: 33.8 KB
Line 
1package problems
2
3import (
4  "container/list"
5  "fmt"
6  expr "github.com/verdverm/go-symexpr"
7  "sort"
8)
9
10var MAX_BBQ_SIZE = 1 << 20
11
12type SortType int
13
14const (
15  SORT_NULL SortType = iota
16
17  GPSORT_SIZE
18
19  GPSORT_PRE_HIT
20  GPSORT_TRN_HIT
21  GPSORT_TST_HIT
22  GPSORT_PRE_ERR
23  GPSORT_TRN_ERR
24  GPSORT_TST_ERR
25
26  GPSORT_SIZE_PRE_HIT
27  GPSORT_SIZE_TRN_HIT
28  GPSORT_SIZE_TST_HIT
29  GPSORT_SIZE_PRE_ERR
30  GPSORT_SIZE_TRN_ERR
31  GPSORT_SIZE_TST_ERR
32
33  GPSORT_PRE_HIT_SIZE
34  GPSORT_TRN_HIT_SIZE
35  GPSORT_TST_HIT_SIZE
36  GPSORT_PRE_ERR_SIZE
37  GPSORT_TRN_ERR_SIZE
38  GPSORT_TST_ERR_SIZE
39
40  GPSORT_PARETO_PRE_ERR
41  GPSORT_PARETO_TRN_ERR
42  GPSORT_PARETO_TST_ERR
43  GPSORT_PARETO_PRE_HIT
44  GPSORT_PARETO_TRN_HIT
45  GPSORT_PARETO_TST_HIT
46
47  PESORT_SIZE
48
49  PESORT_PRE_HIT
50  PESORT_TRN_HIT
51  PESORT_TST_HIT
52  PESORT_PRE_ERR
53  PESORT_TRN_ERR
54  PESORT_TST_ERR
55
56  PESORT_SIZE_PRE_HIT
57  PESORT_SIZE_TRN_HIT
58  PESORT_SIZE_TST_HIT
59  PESORT_SIZE_PRE_ERR
60  PESORT_SIZE_TRN_ERR
61  PESORT_SIZE_TST_ERR
62
63  PESORT_PRE_HIT_SIZE
64  PESORT_TRN_HIT_SIZE
65  PESORT_TST_HIT_SIZE
66  PESORT_PRE_ERR_SIZE
67  PESORT_TRN_ERR_SIZE
68  PESORT_TST_ERR_SIZE
69
70  PESORT_PARETO_PRE_ERR
71  PESORT_PARETO_TRN_ERR
72  PESORT_PARETO_TST_ERR
73  PESORT_PARETO_PRE_HIT
74  PESORT_PARETO_TRN_HIT
75  PESORT_PARETO_TST_HIT
76)
77
78type ExprReport struct {
79  expr  expr.Expr
80  coeff []float64
81
82  // metrics
83  size                             int
84  predError, trainError, testError float64
85  predScore, trainScore, testScore int
86
87  // per data set metrics, if multiple data sets used
88  predErrz  []float64
89  predHitz  []int
90  trainErrz []float64
91  trainHitz []int
92  testErrz  []float64
93  testHitz  []int
94
95  // ids
96  uniqID int // unique ID among all exprs ?
97  procID int // ID of the search process
98  iterID int // iteration of the search
99  unitID int // ID with respect to the search
100  index  int // used internally in containers
101
102  // production information
103  // p1,p2 int  // parent IDs
104  // method int // method that produced this expression
105}
106
107func (r *ExprReport) Size() int {
108  if r.size == 0 {
109    r.size = r.expr.Size()
110  }
111  return r.size
112}
113
114func (r *ExprReport) Clone() *ExprReport {
115  ret := new(ExprReport)
116  ret.expr = r.expr.Clone()
117  ret.expr.CalcExprStats()
118  ret.coeff = make([]float64, len(r.coeff))
119  copy(ret.coeff, r.coeff)
120
121  ret.predError = r.predError
122  ret.trainError = r.trainError
123  ret.testError = r.testError
124  ret.predScore = r.predScore
125  ret.trainScore = r.trainScore
126  ret.testScore = r.testScore
127
128  ret.predErrz = make([]float64, len(r.predErrz))
129  copy(ret.predErrz, r.predErrz)
130  ret.predHitz = make([]int, len(r.predHitz))
131  copy(ret.predHitz, r.predHitz)
132  ret.trainErrz = make([]float64, len(r.trainErrz))
133  copy(ret.trainErrz, r.trainErrz)
134  ret.trainHitz = make([]int, len(r.trainHitz))
135  copy(ret.trainHitz, r.trainHitz)
136  ret.testErrz = make([]float64, len(r.testErrz))
137  copy(ret.testErrz, r.testErrz)
138  ret.testHitz = make([]int, len(r.testHitz))
139  copy(ret.testHitz, r.testHitz)
140
141  ret.uniqID = r.uniqID
142  ret.procID = r.procID
143  ret.iterID = r.iterID
144  ret.unitID = r.unitID
145
146  return ret
147}
148
149var reportFormatString = `%v
150coeff: %v
151size: %4d   depth: %4d   
152uId:  %4d   pId:   %4d
153iId:  %4d   tId:   %4d
154
155train NaNs: %4d
156train L1:   %f
157
158test  NaNs: %4d
159test Evals: %4d   
160test  L1:   %f
161test  L2:   %f
162`
163
164func (r *ExprReport) String() string {
165
166  return fmt.Sprintf(reportFormatString,
167    r.expr, r.Coeff(),
168    r.expr.Size(), r.expr.Height(),
169    r.uniqID, r.procID, r.iterID, r.unitID,
170    r.trainScore, r.trainError,
171    r.predScore, r.testScore, r.testError, r.predError)
172}
173func (r *ExprReport) Latex(dnames, snames []string, cvals []float64) string {
174
175  return fmt.Sprintf(reportFormatString,
176    r.expr.PrettyPrint(dnames, snames, cvals), r.Coeff(),
177    r.expr.Size(), r.expr.Height(),
178    r.uniqID, r.procID, r.iterID, r.unitID,
179    r.trainScore, r.testScore, r.trainError, r.testError, r.predError)
180}
181
182func (r *ExprReport) Expr() expr.Expr     { return r.expr }
183func (r *ExprReport) SetExpr(e expr.Expr) { r.expr = e }
184
185func (r *ExprReport) Coeff() []float64     { return r.coeff }
186func (r *ExprReport) SetCoeff(c []float64) { r.coeff = c }
187
188func (r *ExprReport) PredScore() int     { return r.predScore }
189func (r *ExprReport) SetPredScore(s int) { r.predScore = s }
190
191func (r *ExprReport) PredError() float64     { return r.predError }
192func (r *ExprReport) SetPredError(e float64) { r.predError = e }
193
194func (r *ExprReport) TrainScore() int     { return r.trainScore }
195func (r *ExprReport) SetTrainScore(s int) { r.trainScore = s }
196
197func (r *ExprReport) TrainError() float64     { return r.trainError }
198func (r *ExprReport) SetTrainError(e float64) { r.trainError = e }
199
200func (r *ExprReport) TestScore() int     { return r.testScore }
201func (r *ExprReport) SetTestScore(s int) { r.testScore = s }
202
203func (r *ExprReport) TestError() float64     { return r.testError }
204func (r *ExprReport) SetTestError(e float64) { r.testError = e }
205
206func (r *ExprReport) PredScoreZ() []int     { return r.predHitz }
207func (r *ExprReport) SetPredScoreZ(s []int) { r.predHitz = s }
208
209func (r *ExprReport) PredErrorZ() []float64     { return r.predErrz }
210func (r *ExprReport) SetPredErrorZ(e []float64) { r.predErrz = e }
211
212func (r *ExprReport) TrainScoreZ() []int     { return r.trainHitz }
213func (r *ExprReport) SetTrainScoreZ(s []int) { r.trainHitz = s }
214
215func (r *ExprReport) TrainErrorZ() []float64     { return r.trainErrz }
216func (r *ExprReport) SetTrainErrorZ(e []float64) { r.trainErrz = e }
217
218func (r *ExprReport) TestScoreZ() []int     { return r.testHitz }
219func (r *ExprReport) SetTestScoreZ(s []int) { r.testHitz = s }
220
221func (r *ExprReport) TestErrorZ() []float64     { return r.testErrz }
222func (r *ExprReport) SetTestErrorZ(e []float64) { r.testErrz = e }
223
224func (r *ExprReport) UniqID() int     { return r.uniqID }
225func (r *ExprReport) SetUniqID(i int) { r.uniqID = i }
226
227func (r *ExprReport) ProcID() int     { return r.procID }
228func (r *ExprReport) SetProcID(i int) { r.procID = i }
229
230func (r *ExprReport) IterID() int     { return r.iterID }
231func (r *ExprReport) SetIterID(i int) { r.iterID = i }
232
233func (r *ExprReport) UnitID() int     { return r.unitID }
234func (r *ExprReport) SetUnitID(i int) { r.unitID = i }
235
236// Array of ExprReports
237type ExprReportArray []*ExprReport
238
239func (p ExprReportArray) Len() int      { return len(p) }
240func (p ExprReportArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
241func (p ExprReportArray) Less(i, j int) bool {
242  if p[i] == nil || p[i].expr == nil {
243    return false
244  }
245  if p[j] == nil || p[j].expr == nil {
246    return true
247  }
248  return p[i].expr.AmILess(p[j].expr)
249}
250
251type ExprReportArrayPredError struct {
252  Array ExprReportArray
253}
254
255func (p ExprReportArrayPredError) Len() int      { return len(p.Array) }
256func (p ExprReportArrayPredError) Swap(i, j int) { p.Array[i], p.Array[j] = p.Array[j], p.Array[i] }
257func (p ExprReportArrayPredError) Less(i, j int) bool {
258  if p.Array[i] == nil || p.Array[i].expr == nil {
259    return false
260  }
261  if p.Array[j] == nil || p.Array[j].expr == nil {
262    return true
263  }
264  return p.Array[i].predError < p.Array[j].predError
265}
266
267type ReportListNode struct {
268  Rpt      *ExprReport
269  prv, nxt *ReportListNode
270}
271
272func (self *ReportListNode) Next() *ReportListNode {
273  return self.nxt
274}
275func (self *ReportListNode) Prev() *ReportListNode {
276  return self.prv
277}
278
279type ReportList struct {
280  length int
281  Head   *ReportListNode
282  Tail   *ReportListNode
283}
284
285func (self *ReportList) Len() int {
286  return self.length
287}
288
289func (self *ReportList) Front() (node *ReportListNode) {
290  return self.Head
291}
292func (self *ReportList) Back() (node *ReportListNode) {
293  return self.Tail
294}
295
296func (self *ReportList) PushFront(rpt *ExprReport) {
297  tmp := new(ReportListNode)
298  tmp.Rpt = rpt
299  tmp.nxt = self.Head
300  if self.Head != nil {
301    self.Head.prv = tmp
302  }
303  self.Head = tmp
304  if self.Tail == nil {
305    self.Tail = tmp
306  }
307  self.length++
308}
309func (self *ReportList) PushBack(rpt *ExprReport) {
310  tmp := new(ReportListNode)
311  tmp.Rpt = rpt
312  tmp.prv = self.Tail
313  if self.Tail != nil {
314    self.Tail.nxt = tmp
315  }
316  self.Tail = tmp
317  if self.Head == nil {
318    self.Head = tmp
319  }
320  self.length++
321}
322func (self *ReportList) Remove(node *ReportListNode) {
323  if node.prv != nil {
324    node.prv.nxt = node.nxt
325  } else {
326    self.Head = node.nxt
327  }
328  if node.nxt != nil {
329    node.nxt.prv = node.prv
330  } else {
331    self.Tail = node.prv
332  }
333  node.prv = nil
334  node.nxt = nil
335  self.length--
336}
337
338// Enhanced ExprReport Array with variable sorting methods
339// NOTE!!!  the storage is reverse order
340type ReportQueue struct {
341  queue      []*ExprReport
342  less       func(i, j *ExprReport) bool
343  sortmethod SortType
344}
345
346func NewQueueFromArray(era ExprReportArray) *ReportQueue {
347  Q := new(ReportQueue)
348  Q.queue = era
349  return Q
350}
351
352func NewReportQueue() *ReportQueue {
353  B := new(ReportQueue)
354  B.queue = make([]*ExprReport, 0, MAX_BBQ_SIZE)
355  return B
356}
357
358func (bb ReportQueue) Len() int { return len(bb.queue) }
359func (bb ReportQueue) Less(i, j int) bool {
360  if bb.queue[i] == nil {
361    return false
362  }
363  if bb.queue[j] == nil {
364    return true
365  }
366  return bb.less(bb.queue[i], bb.queue[j])
367}
368func (bb ReportQueue) Swap(i, j int) {
369  bb.queue[i], bb.queue[j] = bb.queue[j], bb.queue[i]
370  if bb.queue[i] != nil {
371    bb.queue[i].index = i
372  }
373  if bb.queue[j] != nil {
374    bb.queue[j].index = j
375  }
376}
377func (bb *ReportQueue) Push(x interface{}) {
378  // Push and Pop use pointer receivers because they modify the slice's length,
379  // not just its contents.
380  // To simplify indexing expressions in these methods, we save a copy of the
381  // slice object. We could instead write (*pq)[i].
382  if len(bb.queue) == cap(bb.queue) {
383    B := make([]*ExprReport, 0, len(bb.queue)*2)
384    copy(B[:len(bb.queue)], (bb.queue)[:])
385    bb.queue = B
386  }
387  a := bb.queue[:]
388  n := len(a)
389  a = a[0 : n+1]
390  item := x.(*ExprReport)
391  item.index = n
392  a[n] = item
393  bb.queue = a
394}
395
396func (bb *ReportQueue) Pop() interface{} {
397  a := bb.queue
398  n := len(a)
399  item := a[n-1]
400  item.index = -1 // for safety
401  bb.queue = a[0 : n-1]
402  return item
403}
404
405func (bb *ReportQueue) GetReport(pos int) (er *ExprReport) {
406  return bb.queue[pos]
407}
408func (bb *ReportQueue) SetReport(pos int, er *ExprReport) {
409  bb.queue[pos] = er
410}
411func (bb *ReportQueue) GetQueue() ExprReportArray {
412  return bb.queue
413}
414
415func (bb *ReportQueue) SetSort(sortmethod SortType) {
416  // all of the methods need to be reversed conceptually except for paretos
417  // this is because the queue push/pops from the back
418  bb.sortmethod = sortmethod
419
420  switch sortmethod {
421  case GPSORT_SIZE:
422    bb.less = lessSize
423
424  case GPSORT_PRE_HIT:
425    bb.less = lessPredHits
426  case GPSORT_TRN_HIT:
427    bb.less = lessTrainHits
428  case GPSORT_TST_HIT:
429    bb.less = lessTestHits
430  case GPSORT_PRE_ERR:
431    bb.less = lessPredError
432  case GPSORT_TRN_ERR:
433    bb.less = lessTrainError
434  case GPSORT_TST_ERR:
435    bb.less = lessTestError
436
437  case GPSORT_SIZE_PRE_HIT:
438    bb.less = lessSizePredHits
439  case GPSORT_SIZE_TRN_HIT:
440    bb.less = lessSizeTrainHits
441  case GPSORT_SIZE_TST_HIT:
442    bb.less = lessSizeTestHits
443  case GPSORT_SIZE_PRE_ERR:
444    bb.less = lessSizePredError
445  case GPSORT_SIZE_TRN_ERR:
446    bb.less = lessSizeTrainError
447  case GPSORT_SIZE_TST_ERR:
448    bb.less = lessSizeTestError
449
450  case GPSORT_PRE_HIT_SIZE:
451    bb.less = lessPredHitsSize
452  case GPSORT_TRN_HIT_SIZE:
453    bb.less = lessTrainHitsSize
454  case GPSORT_TST_HIT_SIZE:
455    bb.less = lessTestHitsSize
456  case GPSORT_PRE_ERR_SIZE:
457    bb.less = lessPredErrorSize
458  case GPSORT_TRN_ERR_SIZE:
459    bb.less = lessTrainErrorSize
460  case GPSORT_TST_ERR_SIZE:
461    bb.less = lessTestErrorSize
462
463  // we use more here because of the heap / queue
464  case PESORT_SIZE:
465    bb.less = moreSize
466
467  case PESORT_PRE_HIT:
468    bb.less = morePredHits
469  case PESORT_TRN_HIT:
470    bb.less = moreTrainHits
471  case PESORT_TST_HIT:
472    bb.less = moreTestHits
473  case PESORT_PRE_ERR:
474    bb.less = morePredError
475  case PESORT_TRN_ERR:
476    bb.less = moreTrainError
477  case PESORT_TST_ERR:
478    bb.less = moreTestError
479
480  case PESORT_SIZE_PRE_HIT:
481    bb.less = moreSizePredHits
482  case PESORT_SIZE_TRN_HIT:
483    bb.less = moreSizeTrainHits
484  case PESORT_SIZE_TST_HIT:
485    bb.less = moreSizeTestHits
486  case PESORT_SIZE_PRE_ERR:
487    bb.less = moreSizePredError
488  case PESORT_SIZE_TRN_ERR:
489    bb.less = moreSizeTrainError
490  case PESORT_SIZE_TST_ERR:
491    bb.less = moreSizeTestError
492
493  case PESORT_PRE_HIT_SIZE:
494    bb.less = morePredHitsSize
495  case PESORT_TRN_HIT_SIZE:
496    bb.less = moreTrainHitsSize
497  case PESORT_TST_HIT_SIZE:
498    bb.less = moreTestHitsSize
499  case PESORT_PRE_ERR_SIZE:
500    bb.less = morePredErrorSize
501  case PESORT_TRN_ERR_SIZE:
502    bb.less = moreTrainErrorSize
503  case PESORT_TST_ERR_SIZE:
504    bb.less = moreTestErrorSize
505
506  default:
507    // fmt.Printf("unknown sort method\n")
508  }
509
510}
511
512func (bb *ReportQueue) Sort() {
513  // all of the methods need to be reversed conceptually except for paretos
514  // this is because the queue push/pops from the back
515  switch bb.sortmethod {
516  case GPSORT_PARETO_PRE_ERR:
517    bb.GP_ParetoPredError()
518    bb.reverseQueue()
519  case GPSORT_PARETO_TRN_ERR:
520    bb.GP_ParetoTrainError()
521    bb.reverseQueue()
522  case GPSORT_PARETO_TST_ERR:
523    bb.GP_ParetoTestError()
524    bb.reverseQueue()
525  case GPSORT_PARETO_PRE_HIT:
526    bb.GP_ParetoPredHits()
527    bb.reverseQueue()
528  case GPSORT_PARETO_TRN_HIT:
529    bb.GP_ParetoTrainHits()
530    bb.reverseQueue()
531  case GPSORT_PARETO_TST_HIT:
532    bb.GP_ParetoTestHits()
533    bb.reverseQueue()
534
535  case PESORT_PARETO_PRE_ERR:
536    bb.PE_ParetoPredError()
537  case PESORT_PARETO_TRN_ERR:
538    bb.PE_ParetoTrainError()
539  case PESORT_PARETO_TST_ERR:
540    bb.PE_ParetoTestError()
541  case PESORT_PARETO_PRE_HIT:
542    bb.PE_ParetoPredHits()
543  case PESORT_PARETO_TRN_HIT:
544    bb.PE_ParetoTrainHits()
545  case PESORT_PARETO_TST_HIT:
546    bb.PE_ParetoTestHits()
547
548  default:
549    sort.Sort(bb)
550  }
551
552}
553
554func (self *ReportQueue) Reverse() {
555  self.reverseQueue()
556}
557
558func (bb *ReportQueue) reverseQueue() {
559  i, j := 0, len(bb.queue)-1
560  for i < j {
561    bb.Swap(i, j)
562    i++
563    j--
564  }
565}
566
567func lessSize(l, r *ExprReport) bool {
568  sz := l.Size() - r.Size()
569  if sz < 0 {
570    return true
571  } else if sz > 0 {
572    return false
573  }
574  return l.expr.AmILess(r.expr)
575}
576func moreSize(l, r *ExprReport) bool {
577  sz := l.Size() - r.Size()
578  if sz < 0 {
579    return false
580  } else if sz > 0 {
581    return true
582  }
583  return l.expr.AmILess(r.expr)
584}
585
586func lessPredHits(l, r *ExprReport) bool {
587  sc := l.predScore - r.predScore
588  if sc > 0 {
589    return true
590  } else if sc < 0 {
591    return false
592  }
593  return l.expr.AmILess(r.expr)
594}
595func lessTrainHits(l, r *ExprReport) bool {
596  sc := l.trainScore - r.trainScore
597  if sc > 0 {
598    return true
599  } else if sc < 0 {
600    return false
601  }
602  return l.expr.AmILess(r.expr)
603}
604func lessTestHits(l, r *ExprReport) bool {
605  sc := l.testScore - r.testScore
606  if sc > 0 {
607    return true
608  } else if sc < 0 {
609    return false
610  }
611  return l.expr.AmILess(r.expr)
612}
613
614func lessPredError(l, r *ExprReport) bool {
615  sc := l.predError - r.predError
616  if sc < 0.0 {
617    return true
618  } else if sc > 0.0 {
619    return false
620  }
621  return l.expr.AmILess(r.expr)
622}
623func lessTrainError(l, r *ExprReport) bool {
624  sc := l.trainError - r.trainError
625  if sc < 0.0 {
626    return true
627  } else if sc > 0.0 {
628    return false
629  }
630  return l.expr.AmILess(r.expr)
631}
632func lessTestError(l, r *ExprReport) bool {
633  sc := l.testError - r.testError
634  if sc < 0.0 {
635    return true
636  } else if sc > 0.0 {
637    return false
638  }
639  return l.expr.AmILess(r.expr)
640}
641
642func lessSizePredHits(l, r *ExprReport) bool {
643  sz := l.Size() - r.Size()
644  if sz < 0 {
645    return true
646  } else if sz > 0 {
647    return false
648  }
649  sc := l.predScore - r.predScore
650  if sc > 0 {
651    return true
652  } else if sc < 0 {
653    return false
654  }
655  return l.expr.AmILess(r.expr)
656}
657func lessSizeTrainHits(l, r *ExprReport) bool {
658  sz := l.Size() - r.Size()
659  if sz < 0 {
660    return true
661  } else if sz > 0 {
662    return false
663  }
664  sc := l.trainScore - r.trainScore
665  if sc > 0 {
666    return true
667  } else if sc < 0 {
668    return false
669  }
670  return l.expr.AmILess(r.expr)
671}
672func lessSizeTestHits(l, r *ExprReport) bool {
673  sz := l.Size() - r.Size()
674  if sz < 0 {
675    return true
676  } else if sz > 0 {
677    return false
678  }
679  sc := l.testScore - r.testScore
680  if sc > 0 {
681    return true
682  } else if sc < 0 {
683    return false
684  }
685  return l.expr.AmILess(r.expr)
686}
687
688func lessSizePredError(l, r *ExprReport) bool {
689  sz := l.Size() - r.Size()
690  if sz < 0 {
691    return true
692  } else if sz > 0 {
693    return false
694  }
695  sc := l.predError - r.predError
696  if sc < 0.0 {
697    return true
698  } else if sc > 0.0 {
699    return false
700  }
701  return l.expr.AmILess(r.expr)
702}
703func lessSizeTrainError(l, r *ExprReport) bool {
704  sz := l.Size() - r.Size()
705  if sz < 0 {
706    return true
707  } else if sz > 0 {
708    return false
709  }
710  sc := l.trainError - r.trainError
711  if sc < 0.0 {
712    return true
713  } else if sc > 0.0 {
714    return false
715  }
716  return l.expr.AmILess(r.expr)
717}
718func lessSizeTestError(l, r *ExprReport) bool {
719  sz := l.Size() - r.Size()
720  if sz < 0 {
721    return true
722  } else if sz > 0 {
723    return false
724  }
725  sc := l.testError - r.testError
726  if sc < 0.0 {
727    return true
728  } else if sc > 0.0 {
729    return false
730  }
731  return l.expr.AmILess(r.expr)
732}
733
734func lessPredHitsSize(l, r *ExprReport) bool {
735  sc := l.predScore - r.predScore
736  if sc > 0 {
737    return true
738  } else if sc < 0 {
739    return false
740  }
741  sz := l.Size() - r.Size()
742  if sz < 0 {
743    return true
744  } else if sz > 0 {
745    return false
746  }
747  return l.expr.AmILess(r.expr)
748}
749func lessTrainHitsSize(l, r *ExprReport) bool {
750  sc := l.trainScore - r.trainScore
751  if sc > 0 {
752    return true
753  } else if sc < 0 {
754    return false
755  }
756  sz := l.Size() - r.Size()
757  if sz < 0 {
758    return true
759  } else if sz > 0 {
760    return false
761  }
762  return l.expr.AmILess(r.expr)
763}
764func lessTestHitsSize(l, r *ExprReport) bool {
765  sc := l.testScore - r.testScore
766  if sc > 0 {
767    return true
768  } else if sc < 0 {
769    return false
770  }
771  sz := l.Size() - r.Size()
772  if sz < 0 {
773    return true
774  } else if sz > 0 {
775    return false
776  }
777  return l.expr.AmILess(r.expr)
778}
779
780func lessPredErrorSize(l, r *ExprReport) bool {
781  sc := l.predError - r.predError
782  if sc < 0.0 {
783    return true
784  } else if sc > 0.0 {
785    return false
786  }
787  sz := l.Size() - r.Size()
788  if sz < 0 {
789    return true
790  } else if sz > 0 {
791    return false
792  }
793  return l.expr.AmILess(r.expr)
794}
795func lessTrainErrorSize(l, r *ExprReport) bool {
796  sc := l.trainError - r.trainError
797  if sc < 0.0 {
798    return true
799  } else if sc > 0.0 {
800    return false
801  }
802  sz := l.Size() - r.Size()
803  if sz < 0 {
804    return true
805  } else if sz > 0 {
806    return false
807  }
808  return l.expr.AmILess(r.expr)
809}
810func lessTestErrorSize(l, r *ExprReport) bool {
811  sc := l.testError - r.testError
812  if sc < 0.0 {
813    return true
814  } else if sc > 0.0 {
815    return false
816  }
817  sz := l.Size() - r.Size()
818  if sz < 0 {
819    return true
820  } else if sz > 0 {
821    return false
822  }
823  return l.expr.AmILess(r.expr)
824}
825
826func morePredHits(l, r *ExprReport) bool {
827  sc := l.predScore - r.predScore
828  if sc > 0 {
829    return false
830  } else if sc < 0 {
831    return true
832  }
833  return l.expr.AmILess(r.expr)
834}
835func moreTrainHits(l, r *ExprReport) bool {
836  sc := l.trainScore - r.trainScore
837  if sc > 0 {
838    return false
839  } else if sc < 0 {
840    return true
841  }
842  return l.expr.AmILess(r.expr)
843}
844func moreTestHits(l, r *ExprReport) bool {
845  sc := l.testScore - r.testScore
846  if sc > 0 {
847    return false
848  } else if sc < 0 {
849    return true
850  }
851  return l.expr.AmILess(r.expr)
852}
853func morePredError(l, r *ExprReport) bool {
854  sc := l.predError - r.predError
855  if sc < 0.0 {
856    return false
857  } else if sc > 0.0 {
858    return true
859  }
860  return l.expr.AmILess(r.expr)
861}
862func moreTrainError(l, r *ExprReport) bool {
863  sc := l.trainError - r.trainError
864  if sc < 0.0 {
865    return false
866  } else if sc > 0.0 {
867    return true
868  }
869  return l.expr.AmILess(r.expr)
870}
871func moreTestError(l, r *ExprReport) bool {
872  sc := l.testError - r.testError
873  if sc < 0.0 {
874    return false
875  } else if sc > 0.0 {
876    return true
877  }
878  return l.expr.AmILess(r.expr)
879}
880
881func moreSizePredHits(l, r *ExprReport) bool {
882  sz := l.Size() - r.Size()
883  if sz < 0 {
884    return false
885  } else if sz > 0 {
886    return true
887  }
888  sc := l.predScore - r.predScore
889  if sc > 0 {
890    return false
891  } else if sc < 0 {
892    return true
893  }
894  return l.expr.AmILess(r.expr)
895}
896func moreSizeTrainHits(l, r *ExprReport) bool {
897  sz := l.Size() - r.Size()
898  if sz < 0 {
899    return false
900  } else if sz > 0 {
901    return true
902  }
903  sc := l.trainScore - r.trainScore
904  if sc > 0 {
905    return false
906  } else if sc < 0 {
907    return true
908  }
909  return l.expr.AmILess(r.expr)
910}
911func moreSizeTestHits(l, r *ExprReport) bool {
912  sz := l.Size() - r.Size()
913  if sz < 0 {
914    return false
915  } else if sz > 0 {
916    return true
917  }
918  sc := l.testScore - r.testScore
919  if sc > 0 {
920    return false
921  } else if sc < 0 {
922    return true
923  }
924  return l.expr.AmILess(r.expr)
925}
926
927func moreSizePredError(l, r *ExprReport) bool {
928  sz := l.Size() - r.Size()
929  if sz < 0 {
930    return false
931  } else if sz > 0 {
932    return true
933  }
934  sc := l.predError - r.predError
935  if sc < 0.0 {
936    return false
937  } else if sc > 0.0 {
938    return true
939  }
940  return l.expr.AmILess(r.expr)
941}
942func moreSizeTrainError(l, r *ExprReport) bool {
943  sz := l.Size() - r.Size()
944  if sz < 0 {
945    return false
946  } else if sz > 0 {
947    return true
948  }
949  sc := l.trainError - r.trainError
950  if sc < 0.0 {
951    return false
952  } else if sc > 0.0 {
953    return true
954  }
955  return l.expr.AmILess(r.expr)
956}
957func moreSizeTestError(l, r *ExprReport) bool {
958  sz := l.Size() - r.Size()
959  if sz < 0 {
960    return false
961  } else if sz > 0 {
962    return true
963  }
964  sc := l.testError - r.testError
965  if sc < 0.0 {
966    return false
967  } else if sc > 0.0 {
968    return true
969  }
970  return l.expr.AmILess(r.expr)
971}
972
973func morePredHitsSize(l, r *ExprReport) bool {
974  sc := l.predScore - r.predScore
975  if sc > 0 {
976    return false
977  } else if sc < 0 {
978    return true
979  }
980  sz := l.Size() - r.Size()
981  if sz < 0 {
982    return false
983  } else if sz > 0 {
984    return true
985  }
986  return l.expr.AmILess(r.expr)
987}
988func moreTrainHitsSize(l, r *ExprReport) bool {
989  sc := l.trainScore - r.trainScore
990  if sc > 0 {
991    return false
992  } else if sc < 0 {
993    return true
994  }
995  sz := l.Size() - r.Size()
996  if sz < 0 {
997    return false
998  } else if sz > 0 {
999    return true
1000  }
1001  return l.expr.AmILess(r.expr)
1002}
1003func moreTestHitsSize(l, r *ExprReport) bool {
1004  sc := l.testScore - r.testScore
1005  if sc > 0 {
1006    return false
1007  } else if sc < 0 {
1008    return true
1009  }
1010  sz := l.Size() - r.Size()
1011  if sz < 0 {
1012    return false
1013  } else if sz > 0 {
1014    return true
1015  }
1016  return l.expr.AmILess(r.expr)
1017}
1018
1019func morePredErrorSize(l, r *ExprReport) bool {
1020  sc := l.predError - r.predError
1021  if sc < 0.0 {
1022    return false
1023  } else if sc > 0.0 {
1024    return true
1025  }
1026  sz := l.Size() - r.Size()
1027  if sz < 0 {
1028    return false
1029  } else if sz > 0 {
1030    return true
1031  }
1032  return l.expr.AmILess(r.expr)
1033}
1034func moreTrainErrorSize(l, r *ExprReport) bool {
1035  sc := l.trainError - r.trainError
1036  if sc < 0.0 {
1037    return false
1038  } else if sc > 0.0 {
1039    return true
1040  }
1041  sz := l.Size() - r.Size()
1042  if sz < 0 {
1043    return false
1044  } else if sz > 0 {
1045    return true
1046  }
1047  return l.expr.AmILess(r.expr)
1048}
1049func moreTestErrorSize(l, r *ExprReport) bool {
1050  sc := l.testError - r.testError
1051  if sc < 0.0 {
1052    return false
1053  } else if sc > 0.0 {
1054    return true
1055  }
1056  sz := l.Size() - r.Size()
1057  if sz < 0 {
1058    return false
1059  } else if sz > 0 {
1060    return true
1061  }
1062  return l.expr.AmILess(r.expr)
1063}
1064
1065func (bb *ReportQueue) GP_ParetoPredHits() {
1066  bb.less = lessSizePredHits
1067  sort.Sort(bb)
1068
1069  var pareto list.List
1070  pareto.Init()
1071  for i, _ := range bb.queue {
1072    if bb.queue[i] == nil {
1073      continue
1074    }
1075    pareto.PushBack(bb.queue[i])
1076  }
1077
1078  over := len(bb.queue) - 1
1079  for pareto.Len() > 0 && over >= 0 {
1080    pe := pareto.Front()
1081    eLast := pe
1082    pb := pe.Value.(*ExprReport)
1083    cSize := pb.Size()
1084    cScore := pb.predScore
1085    pe = pe.Next()
1086    for pe != nil && over >= 0 {
1087      pb := pe.Value.(*ExprReport)
1088      if pb.Size() > cSize {
1089        cSize = pb.Size()
1090        if pb.predScore < cScore {
1091          cScore = pb.predScore
1092          bb.queue[over] = eLast.Value.(*ExprReport)
1093          over--
1094          pareto.Remove(eLast)
1095          eLast = pe
1096        }
1097      }
1098      pe = pe.Next()
1099    }
1100    if over < 0 {
1101      break
1102    }
1103
1104    bb.queue[over] = eLast.Value.(*ExprReport)
1105    over--
1106    pareto.Remove(eLast)
1107  }
1108}
1109
1110func (bb *ReportQueue) GP_ParetoTrainHits() {
1111  bb.less = lessSizeTrainHits
1112  sort.Sort(bb)
1113
1114  var pareto list.List
1115  pareto.Init()
1116  for i, _ := range bb.queue {
1117    if bb.queue[i] == nil {
1118      continue
1119    }
1120    pareto.PushBack(bb.queue[i])
1121  }
1122
1123  over := len(bb.queue) - 1
1124  for pareto.Len() > 0 && over >= 0 {
1125    pe := pareto.Front()
1126    eLast := pe
1127    pb := pe.Value.(*ExprReport)
1128    cSize := pb.Size()
1129    cScore := pb.trainScore
1130    pe = pe.Next()
1131    for pe != nil && over >= 0 {
1132      pb := pe.Value.(*ExprReport)
1133      if pb.Size() > cSize {
1134        cSize = pb.Size()
1135        if pb.trainScore < cScore {
1136          cScore = pb.trainScore
1137          bb.queue[over] = eLast.Value.(*ExprReport)
1138          over--
1139          pareto.Remove(eLast)
1140          eLast = pe
1141        }
1142      }
1143      pe = pe.Next()
1144    }
1145    if over < 0 {
1146      break
1147    }
1148
1149    bb.queue[over] = eLast.Value.(*ExprReport)
1150    over--
1151    pareto.Remove(eLast)
1152  }
1153}
1154
1155func (bb *ReportQueue) GP_ParetoTestHits() {
1156  bb.less = lessSizeTestHits
1157  sort.Sort(bb)
1158
1159  var pareto list.List
1160  pareto.Init()
1161  for i, _ := range bb.queue {
1162    if bb.queue[i] == nil {
1163      continue
1164    }
1165    pareto.PushBack(bb.queue[i])
1166  }
1167
1168  over := len(bb.queue) - 1
1169  for pareto.Len() > 0 && over >= 0 {
1170    pe := pareto.Front()
1171    eLast := pe
1172    pb := pe.Value.(*ExprReport)
1173    cSize := pb.Size()
1174    cScore := pb.testScore
1175    pe = pe.Next()
1176    for pe != nil && over >= 0 {
1177      pb := pe.Value.(*ExprReport)
1178      if pb.Size() > cSize {
1179        cSize = pb.Size()
1180        if pb.testScore < cScore {
1181          cScore = pb.testScore
1182          bb.queue[over] = eLast.Value.(*ExprReport)
1183          over--
1184          pareto.Remove(eLast)
1185          eLast = pe
1186        }
1187      }
1188      pe = pe.Next()
1189    }
1190    if over < 0 {
1191      break
1192    }
1193
1194    bb.queue[over] = eLast.Value.(*ExprReport)
1195    over--
1196    pareto.Remove(eLast)
1197  }
1198}
1199
1200func (bb *ReportQueue) GP_ParetoPredError() {
1201  bb.less = lessSizePredError
1202  sort.Sort(bb)
1203
1204  // var pareto list.List
1205  // pareto.Init()
1206  var pareto ReportList
1207  for i, _ := range bb.queue {
1208    if bb.queue[i] == nil {
1209      continue
1210    }
1211    pareto.PushBack(bb.queue[i])
1212  }
1213
1214  over := len(bb.queue) - 1
1215  for pareto.Len() > 0 && over >= 0 {
1216    pe := pareto.Front()
1217    eLast := pe
1218    // pb := pe.Value.(*ExprReport)
1219    pb := pe.Rpt
1220    cSize := pb.Size()
1221    cScore := pb.predError
1222    pe = pe.Next()
1223    for pe != nil && over >= 0 {
1224      // pb := pe.Value.(*ExprReport)
1225      pb := pe.Rpt
1226      sz := pb.Size()
1227      if sz > cSize {
1228        cSize = sz
1229        if pb.predError < cScore {
1230          cScore = pb.predError
1231          // bb.queue[over] = eLast.Value.(*ExprReport)
1232          bb.queue[over] = eLast.Rpt
1233          over--
1234          pareto.Remove(eLast)
1235          eLast = pe
1236        }
1237      }
1238      pe = pe.Next()
1239    }
1240    if over < 0 {
1241      break
1242    }
1243
1244    // bb.queue[over] = eLast.Value.(*ExprReport)
1245    bb.queue[over] = eLast.Rpt
1246    over--
1247    pareto.Remove(eLast)
1248  }
1249}
1250
1251func (bb *ReportQueue) GP_ParetoTrainError() {
1252  bb.less = lessSizeTrainError
1253  sort.Sort(bb)
1254
1255  var pareto list.List
1256  pareto.Init()
1257  for i, _ := range bb.queue {
1258    if bb.queue[i] == nil {
1259      continue
1260    }
1261    pareto.PushBack(bb.queue[i])
1262  }
1263
1264  over := len(bb.queue) - 1
1265  for pareto.Len() > 0 && over >= 0 {
1266    pe := pareto.Front()
1267    eLast := pe
1268    pb := pe.Value.(*ExprReport)
1269    cSize := pb.Size()
1270    cScore := pb.trainError
1271    pe = pe.Next()
1272    for pe != nil && over >= 0 {
1273      pb := pe.Value.(*ExprReport)
1274      if pb.Size() > cSize {
1275        cSize = pb.Size()
1276        if pb.trainError < cScore {
1277          cScore = pb.trainError
1278          bb.queue[over] = eLast.Value.(*ExprReport)
1279          over--
1280          pareto.Remove(eLast)
1281          eLast = pe
1282        }
1283      }
1284      pe = pe.Next()
1285    }
1286    if over < 0 {
1287      break
1288    }
1289
1290    bb.queue[over] = eLast.Value.(*ExprReport)
1291    over--
1292    pareto.Remove(eLast)
1293  }
1294}
1295
1296func (bb *ReportQueue) GP_ParetoTestError() {
1297  bb.less = lessSizeTestError
1298  sort.Sort(bb)
1299
1300  var pareto list.List
1301  pareto.Init()
1302  for i, _ := range bb.queue {
1303    if bb.queue[i] == nil {
1304      continue
1305    }
1306    pareto.PushBack(bb.queue[i])
1307  }
1308
1309  over := len(bb.queue) - 1
1310  for pareto.Len() > 0 && over >= 0 {
1311    pe := pareto.Front()
1312    eLast := pe
1313    pb := pe.Value.(*ExprReport)
1314    cSize := pb.Size()
1315    cScore := pb.testError
1316    pe = pe.Next()
1317    for pe != nil && over >= 0 {
1318      pb := pe.Value.(*ExprReport)
1319      if pb.Size() > cSize {
1320        cSize = pb.Size()
1321        if pb.testError < cScore {
1322          cScore = pb.testError
1323          bb.queue[over] = eLast.Value.(*ExprReport)
1324          over--
1325          pareto.Remove(eLast)
1326          eLast = pe
1327        }
1328      }
1329      pe = pe.Next()
1330    }
1331    if over < 0 {
1332      break
1333    }
1334
1335    bb.queue[over] = eLast.Value.(*ExprReport)
1336    over--
1337    pareto.Remove(eLast)
1338  }
1339}
1340
1341func (bb *ReportQueue) PE_ParetoPredHits() {
1342  bb.less = lessSizePredHits
1343  sort.Sort(bb)
1344
1345  var pareto list.List
1346  pareto.Init()
1347  for i, _ := range bb.queue {
1348    if bb.queue[i] == nil {
1349      continue
1350    }
1351    pareto.PushBack(bb.queue[i])
1352  }
1353
1354  over := len(bb.queue) - 1
1355  for pareto.Len() > 0 && over >= 0 {
1356    pe := pareto.Front()
1357    eLast := pe
1358    pb := pe.Value.(*ExprReport)
1359    cSize := pb.Size()
1360    cScore := pb.predScore
1361    pe = pe.Next()
1362    for pe != nil && over >= 0 {
1363      pb := pe.Value.(*ExprReport)
1364      if pb.predScore > cScore {
1365        cScore = pb.predScore
1366        if pb.Size() > cSize {
1367          bb.queue[over] = eLast.Value.(*ExprReport)
1368          over--
1369          pareto.Remove(eLast)
1370          cSize = pb.Size()
1371          eLast = pe
1372        }
1373      }
1374      pe = pe.Next()
1375    }
1376    if over < 0 {
1377      break
1378    }
1379
1380    bb.queue[over] = eLast.Value.(*ExprReport)
1381    over--
1382    pareto.Remove(eLast)
1383  }
1384}
1385
1386func (bb *ReportQueue) PE_ParetoTrainHits() {
1387  bb.less = lessSizeTrainHits
1388  sort.Sort(bb)
1389
1390  var pareto list.List
1391  pareto.Init()
1392  for i, _ := range bb.queue {
1393    if bb.queue[i] == nil {
1394      continue
1395    }
1396    pareto.PushBack(bb.queue[i])
1397  }
1398
1399  over := len(bb.queue) - 1
1400  for pareto.Len() > 0 && over >= 0 {
1401    pe := pareto.Front()
1402    eLast := pe
1403    pb := pe.Value.(*ExprReport)
1404    cSize := pb.Size()
1405    cScore := pb.trainScore
1406    pe = pe.Next()
1407    for pe != nil && over >= 0 {
1408      pb := pe.Value.(*ExprReport)
1409      if pb.trainScore > cScore {
1410        cScore = pb.trainScore
1411        if pb.Size() > cSize {
1412          bb.queue[over] = eLast.Value.(*ExprReport)
1413          over--
1414          pareto.Remove(eLast)
1415          cSize = pb.Size()
1416          eLast = pe
1417        }
1418      }
1419      pe = pe.Next()
1420    }
1421    if over < 0 {
1422      break
1423    }
1424
1425    bb.queue[over] = eLast.Value.(*ExprReport)
1426    over--
1427    pareto.Remove(eLast)
1428  }
1429}
1430
1431func (bb *ReportQueue) PE_ParetoTestHits() {
1432  bb.less = lessSizeTestHits
1433  sort.Sort(bb)
1434
1435  var pareto list.List
1436  pareto.Init()
1437  for i, _ := range bb.queue {
1438    if bb.queue[i] == nil {
1439      continue
1440    }
1441    pareto.PushBack(bb.queue[i])
1442  }
1443
1444  over := len(bb.queue) - 1
1445  for pareto.Len() > 0 && over >= 0 {
1446    pe := pareto.Front()
1447    eLast := pe
1448    pb := pe.Value.(*ExprReport)
1449    cSize := pb.Size()
1450    cScore := pb.testScore
1451    pe = pe.Next()
1452    for pe != nil && over >= 0 {
1453      pb := pe.Value.(*ExprReport)
1454      if pb.testScore > cScore {
1455        cScore = pb.testScore
1456        if pb.Size() > cSize {
1457          bb.queue[over] = eLast.Value.(*ExprReport)
1458          over--
1459          pareto.Remove(eLast)
1460          cSize = pb.Size()
1461          eLast = pe
1462        }
1463      }
1464      pe = pe.Next()
1465    }
1466    if over < 0 {
1467      break
1468    }
1469
1470    bb.queue[over] = eLast.Value.(*ExprReport)
1471    over--
1472    pareto.Remove(eLast)
1473  }
1474}
1475
1476func (bb *ReportQueue) PE_ParetoPredError() {
1477  bb.less = lessSizePredError
1478  sort.Sort(bb)
1479
1480  // var pareto list.List
1481  // pareto.Init()
1482  var pareto ReportList
1483  for i, _ := range bb.queue {
1484    if bb.queue[i] == nil {
1485      continue
1486    }
1487    pareto.PushBack(bb.queue[i])
1488  }
1489
1490  over := len(bb.queue) - 1
1491  for pareto.Len() > 0 && over >= 0 {
1492    pe := pareto.Front()
1493    eLast := pe
1494    // pb := pe.Value.(*ExprReport)
1495    pb := pe.Rpt
1496    cSize := pb.Size()
1497    cScore := pb.predError
1498    pe = pe.Next()
1499    for pe != nil && over >= 0 {
1500      // pb = pe.Value.(*ExprReport)
1501      pb = pe.Rpt
1502      if pb.predError < cScore {
1503        cScore = pb.predError
1504        if pb.Size() > cSize {
1505          // bb.queue[over] = eLast.Value.(*ExprReport)
1506          bb.queue[over] = eLast.Rpt
1507          over--
1508          pareto.Remove(eLast)
1509          cSize = pb.Size()
1510          eLast = pe
1511        }
1512      }
1513      pe = pe.Next()
1514    }
1515    if over < 0 {
1516      break
1517    }
1518
1519    // bb.queue[over] = eLast.Value.(*ExprReport)
1520    bb.queue[over] = eLast.Rpt
1521    over--
1522    pareto.Remove(eLast)
1523  }
1524}
1525
1526func (bb *ReportQueue) PE_ParetoTrainError() {
1527  bb.less = lessSizeTrainError
1528  sort.Sort(bb)
1529
1530  var pareto list.List
1531  pareto.Init()
1532  for i, _ := range bb.queue {
1533    if bb.queue[i] == nil {
1534      continue
1535    }
1536    pareto.PushBack(bb.queue[i])
1537  }
1538
1539  over := len(bb.queue) - 1
1540  for pareto.Len() > 0 && over >= 0 {
1541    pe := pareto.Front()
1542    eLast := pe
1543    pb := pe.Value.(*ExprReport)
1544    cSize := pb.Size()
1545    cScore := pb.trainError
1546    pe = pe.Next()
1547    for pe != nil && over >= 0 {
1548      pb := pe.Value.(*ExprReport)
1549      if pb.trainError < cScore {
1550        cScore = pb.trainError
1551        if pb.Size() > cSize {
1552          bb.queue[over] = eLast.Value.(*ExprReport)
1553          over--
1554          pareto.Remove(eLast)
1555          cSize = pb.Size()
1556          eLast = pe
1557        }
1558      }
1559      pe = pe.Next()
1560    }
1561    if over < 0 {
1562      break
1563    }
1564
1565    bb.queue[over] = eLast.Value.(*ExprReport)
1566    over--
1567    pareto.Remove(eLast)
1568  }
1569}
1570
1571func (bb *ReportQueue) PE_ParetoTestError() {
1572  bb.less = lessSizeTestError
1573  sort.Sort(bb)
1574
1575  var pareto list.List
1576  pareto.Init()
1577  for i, _ := range bb.queue {
1578    if bb.queue[i] == nil {
1579      continue
1580    }
1581    pareto.PushBack(bb.queue[i])
1582  }
1583
1584  over := len(bb.queue) - 1
1585  for pareto.Len() > 0 && over >= 0 {
1586    pe := pareto.Front()
1587    eLast := pe
1588    pb := pe.Value.(*ExprReport)
1589    cSize := pb.Size()
1590    cScore := pb.testError
1591    pe = pe.Next()
1592    for pe != nil && over >= 0 {
1593      pb := pe.Value.(*ExprReport)
1594      if pb.testError < cScore {
1595        cScore = pb.testError
1596        if pb.Size() > cSize {
1597          bb.queue[over] = eLast.Value.(*ExprReport)
1598          over--
1599          pareto.Remove(eLast)
1600          cSize = pb.Size()
1601          eLast = pe
1602        }
1603      }
1604      pe = pe.Next()
1605    }
1606    if over < 0 {
1607      break
1608    }
1609
1610    bb.queue[over] = eLast.Value.(*ExprReport)
1611    over--
1612    pareto.Remove(eLast)
1613  }
1614}
Note: See TracBrowser for help on using the repository browser.