Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.Algorithms.DataAnalysis.PGE/3.3/src/go-symexpr/expr.go @ 16620

Last change on this file since 16620 was 16620, checked in by hmaislin, 5 years ago

#2929: Reorganized folder structure for make script, removed explicit marshalling, erased go-side logging

File size: 8.8 KB
Line 
1// Package symexpr implements symbolic equations as an AST.
2// It aims to provide ease of dynamic manipulation of the tree.
3//
4// This work comes out of my Masters thesis at Binghamton University
5// and is geared towards Symbolic Regression.
6//
7package symexpr
8
9import (
10  "fmt"
11  "math"
12)
13
14type ExprType int
15
16const (
17  NULL ExprType = iota
18
19  STARTLEAF
20  CONSTANT  // indexed constant, useful for non-linear regression tasks
21  CONSTANTF // floating point constant
22  TIME      // useful when looking at time series and RK4 integration
23  SYSTEM    // i use this like a variable that changes between experiments, but not with time (mass,size,etc.)
24  VAR       // a canonical variable
25  LASTLEAF
26
27  STARTFUNC
28  NEG
29  ABS
30  SQRT
31  SIN
32  COS
33  TAN
34  EXP
35  LOG
36  LASTFUNC
37
38  POWI // Expr^Integer
39  POWF // Expr^Float
40  POWE // Expr^Expr
41  DIV  // Expr/Expr
42
43  ADD // these can have more than two child nodes
44  MUL // this eases sorting and simplification
45
46  EXPR_MAX
47  STARTVAR // for serialization reduction of variables
48)
49
50// Expr is the interface to all node types for the AST of mathematical expression
51//
52type Expr interface {
53
54  // types.go (this file)
55  ExprType() ExprType
56  Clone() Expr
57
58  // stats.go
59  Size() int
60  Depth() int
61  Height() int
62  NumChildren() int
63  CalcExprStats()
64  calcExprStatsR(depth int, pos *int)
65
66  // compare.go
67  AmILess(rhs Expr) bool
68  AmIEqual(rhs Expr) bool
69  AmISame(rhs Expr) bool       // equality without coefficient values/index
70  AmIAlmostSame(rhs Expr) bool // adds flexibility to mul comparison to AmISame
71  Sort()
72
73  // has.go
74  HasVar() bool
75  HasVarI(i int) bool
76  NumVar() int
77
78  // DFS for a floating point valued ConstantF
79  HasConst() bool
80  // DFS for a indexed valued Constant
81  HasConstI(i int) bool
82  // Counts the number of indexed Constant nodes
83  NumConstants() int
84
85  // convert.go
86
87  // Converts indexed Constant nodes to ConstantF nodes
88  // using the input slice as the values for replacement
89  ConvertToConstantFs(cs []float64) Expr
90  // DFS converting float valued constants to indexed constants
91  // the input should be an empty slice
92  // the output is an appended slice the size = |ConstantF| in the tree
93  ConvertToConstants(cs []float64) ([]float64, Expr)
94  //   IndexConstants( ci int ) int
95
96  // getset.go
97  // DFS retrieval of a node by index
98  GetExpr(pos *int) Expr
99  // DFS replacement of a node and it's subtree
100  // replaced is used to discontinue the DFS after replacement
101  // replace_me gets triggered when pos == 0 and informs the parent node to replace the respective child node
102  SetExpr(pos *int, e Expr) (replace_me, replaced bool)
103
104  // print.go
105
106  // prints the AST
107  String() string
108
109  // creates an integer representation of the AST in ~prefix notation
110  // The input is an empty slice, output is the representation.
111  // The output is generally the ExprType integer value
112  // Associative operators (+ & *) also include the number of children.
113  // The terminal nodes include the index when appropriate.
114  Serial([]int) []int
115  StackSerial([]int) []int
116
117  // Pretty print acts like String, but replaces the internal indexed
118  // formatting with user specified strings and values
119  PrettyPrint(dnames, snames []string, cvals []float64) string
120  //  WriteString( buf *bytes.Buffer )
121
122  // Similar to PrettyPrint, but in latex format
123  Latex(dnames, snames []string, cvals []float64) string
124  Javascript(dnames, snames []string, cvals []float64) string
125
126  // eval.go
127  // Evaluates an expression at one point
128  // t is a time value
129  // x are the input Var values
130  // c are the indexed Constant values
131  // s are the indexed System values
132  // the output is the result of DFS evaluation
133  Eval(t float64, x, c, s []float64) float64
134
135  // simp.go
136  Simplify(rules SimpRules) Expr
137
138  // deriv.go
139  // Calculate the derivative w.r.t. Var_i
140  DerivVar(i int) Expr
141  // Calculate the derivative w.r.t. Constant_i
142  DerivConst(i int) Expr
143}
144
145type ExprArray []Expr
146
147func (p ExprArray) Len() int      { return len(p) }
148func (p ExprArray) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
149func (p ExprArray) Less(i, j int) bool {
150  if p[i] == nil && p[j] == nil {
151    return false
152  }
153  if p[i] == nil {
154    return false
155  }
156  if p[j] == nil {
157    return true
158  }
159  return p[i].AmILess(p[j])
160}
161
162// Null Leaf  (shouldn't really appear)
163// This is a sample for the other node types
164type Null struct {
165  ExprStats
166}
167
168func NewNull() *Null               { return new(Null) }
169func (n *Null) ExprType() ExprType { return NULL }
170func (n *Null) Clone() Expr        { return NewNull() }
171
172func (n *Null) CalcExprStats() {
173  n.depth = 1
174  n.height = 1
175  n.size = 1
176  n.pos = 0
177  n.numchld = 0
178}
179func (n *Null) calcExprStatsR(depth int, pos *int) {
180  n.depth = depth + 1
181  n.height = 1
182  n.size = 1
183  n.pos = *pos
184  (*pos)++
185  n.numchld = 0
186}
187
188func (n *Null) AmILess(r Expr) bool       { return NULL < r.ExprType() }
189func (n *Null) AmIEqual(r Expr) bool      { return r.ExprType() == NULL }
190func (n *Null) AmISame(r Expr) bool       { return r.ExprType() == NULL }
191func (n *Null) AmIAlmostSame(r Expr) bool { return r.ExprType() == NULL }
192func (n *Null) Sort()                     { return }
193
194func (n *Null) HasVar() bool         { return false }
195func (n *Null) HasVarI(i int) bool   { return false }
196func (n *Null) NumVar() int          { return 0 }
197func (n *Null) HasConst() bool       { return false }
198func (n *Null) HasConstI(i int) bool { return false }
199func (n *Null) NumConstants() int    { return 0 }
200
201func (n *Null) ConvertToConstantFs(cs []float64) Expr             { return n }
202func (n *Null) ConvertToConstants(cs []float64) ([]float64, Expr) { return cs, n }
203
204func (n *Null) GetExpr(pos *int) Expr {
205  if (*pos) == 0 {
206    return n
207  }
208  (*pos)--
209  return nil
210}
211func (n *Null) SetExpr(pos *int, e Expr) (replace_me, replaced bool) {
212  if (*pos) == 0 {
213    return true, false
214  }
215  (*pos)--
216  return false, false
217}
218
219func (n *Null) String() string                                              { return "NULL" }
220func (n *Null) Serial(sofar []int) []int                                    { return append(sofar, int(NULL)) }
221func (n *Null) StackSerial(sofar []int) []int                               { return append(sofar, int(NULL)) }
222func (n *Null) PrettyPrint(dnames, snames []string, cvals []float64) string { return "NULL" }
223func (n *Null) Latex(dnames, snames []string, cvals []float64) string       { return "NULL" }
224func (n *Null) Javascript(dnames, snames []string, cvals []float64) string  { return "null" }
225
226func (n *Null) Eval(t float64, x, c, s []float64) float64 { return math.NaN() }
227
228func (n *Null) Simplify(rules SimpRules) Expr { return n }
229
230func (n *Null) DerivConst(i int) Expr { return &ConstantF{F: 0} }
231func (n *Null) DerivVar(i int) Expr   { return &ConstantF{F: 0} }
232
233func DumpExprTypes() {
234  fmt.Printf("ExprTypes:\n")
235  fmt.Printf("---------------\n")
236
237  fmt.Printf("NULL:      %d\n", int(NULL))
238
239  fmt.Printf("STARTLEAF: %d\n", int(STARTLEAF))
240  fmt.Printf("CONSTANT:  %d\n", int(CONSTANT))
241  fmt.Printf("TIME:      %d\n", int(TIME))
242  fmt.Printf("SYSTEM:    %d\n", int(SYSTEM))
243  fmt.Printf("VAR:       %d\n", int(VAR))
244  fmt.Printf("LASTLEAF:  %d\n", int(LASTLEAF))
245
246  fmt.Printf("STARTFUNC: %d\n", int(STARTFUNC))
247  fmt.Printf("NEG:       %d\n", int(NEG))
248  fmt.Printf("ABS:       %d\n", int(ABS))
249  fmt.Printf("SQRT:      %d\n", int(SQRT))
250  fmt.Printf("SIN:       %d\n", int(SIN))
251  fmt.Printf("COS:       %d\n", int(COS))
252  fmt.Printf("TAN:       %d\n", int(TAN))
253  fmt.Printf("EXP:       %d\n", int(EXP))
254  fmt.Printf("LOG:       %d\n", int(LOG))
255  fmt.Printf("LASTFUNC:  %d\n", int(LASTFUNC))
256
257  fmt.Printf("POWI:      %d\n", int(POWI))
258  fmt.Printf("POWF:      %d\n", int(POWF))
259  fmt.Printf("POWE:      %d\n", int(POWE))
260  fmt.Printf("DIV:       %d\n", int(DIV))
261
262  fmt.Printf("ADD:       %d\n", int(ADD))
263  fmt.Printf("MUL:       %d\n", int(MUL))
264
265  fmt.Printf("EXPR_MAX:  %d\n", int(EXPR_MAX))
266  fmt.Printf("STARTVAR:  %d\n", int(STARTVAR))
267
268}
269
270func (e ExprType) String() string {
271  switch e {
272  case NULL:
273    return "NULL"
274  case STARTLEAF:
275    return "STARTLEAF"
276  case CONSTANT:
277    return "CONSTANT"
278  case CONSTANTF:
279    return "CONSTANTF"
280  case TIME:
281    return "TIME"
282  case SYSTEM:
283    return "SYSTEM"
284  case VAR:
285    return "VAR"
286  case LASTLEAF:
287    return "LASTLEAF"
288  case STARTFUNC:
289    return "STARTFUNC"
290  case NEG:
291    return "NEG"
292  case ABS:
293    return "ABS"
294  case SQRT:
295    return "SQRT"
296  case SIN:
297    return "SIN"
298  case COS:
299    return "COS"
300  case TAN:
301    return "TAN"
302  case EXP:
303    return "EXP"
304  case LOG:
305    return "LOG"
306  case LASTFUNC:
307    return "LASTFUNC"
308  case POWI:
309    return "POWI"
310  case POWF:
311    return "POWF"
312  case POWE:
313    return "POWE"
314  case DIV:
315    return "DIV"
316  case ADD:
317    return "ADD"
318  case MUL:
319    return "MUL"
320  case EXPR_MAX:
321    return "EXPR_MAX"
322  case STARTVAR:
323    return "STARTVAR"
324  default:
325    return "Unknown ExprType"
326  }
327  return "Unknown ExprType"
328}
Note: See TracBrowser for help on using the repository browser.