1 | package problems
|
---|
2 |
|
---|
3 | import (
|
---|
4 | "bufio"
|
---|
5 | "fmt"
|
---|
6 | "log"
|
---|
7 | "strconv"
|
---|
8 | "strings"
|
---|
9 |
|
---|
10 | expr "github.com/verdverm/go-symexpr"
|
---|
11 | )
|
---|
12 |
|
---|
13 | type TreeParams struct {
|
---|
14 |
|
---|
15 | // bounds on tree
|
---|
16 | MaxSize, MaxDepth,
|
---|
17 | MinSize, MinDepth int
|
---|
18 |
|
---|
19 | // usable terms at each location
|
---|
20 | RootsS, NodesS, LeafsS, NonTrigS []string
|
---|
21 | RootsT, NodesT, LeafsT, NonTrigT []expr.ExprType
|
---|
22 | Roots, Nodes, Leafs, NonTrig []expr.Expr
|
---|
23 |
|
---|
24 | // simplify options
|
---|
25 | DoSimp bool
|
---|
26 | SRules expr.SimpRules
|
---|
27 |
|
---|
28 | // bounds on some operands
|
---|
29 | UsableVars []int
|
---|
30 | NumDim, NumSys, NumCoeff int
|
---|
31 |
|
---|
32 | // tpm bounds on tree (for subtree distributions)
|
---|
33 | TmpMaxSize, TmpMaxDepth,
|
---|
34 | TmpMinSize, TmpMinDepth int
|
---|
35 |
|
---|
36 | // Current values
|
---|
37 | CurrSize, CurrDepth int
|
---|
38 | InTrig bool
|
---|
39 | CoeffCount int
|
---|
40 | }
|
---|
41 |
|
---|
42 | func (t *TreeParams) Clone() *TreeParams {
|
---|
43 | n := new(TreeParams)
|
---|
44 | n.MaxSize = t.MaxSize
|
---|
45 | n.MaxDepth = t.MaxDepth
|
---|
46 | n.MinSize = t.MinSize
|
---|
47 | n.MinDepth = t.MinDepth
|
---|
48 |
|
---|
49 | n.RootsS = make([]string, len(t.RootsS))
|
---|
50 | copy(n.RootsS, t.RootsS)
|
---|
51 | n.NodesS = make([]string, len(t.NodesS))
|
---|
52 | copy(n.NodesS, t.NodesS)
|
---|
53 | n.LeafsS = make([]string, len(t.LeafsS))
|
---|
54 | copy(n.LeafsS, t.LeafsS)
|
---|
55 | n.NonTrigS = make([]string, len(t.NonTrigS))
|
---|
56 | copy(n.NonTrigS, t.NonTrigS)
|
---|
57 |
|
---|
58 | n.RootsT = make([]expr.ExprType, len(t.RootsT))
|
---|
59 | copy(n.RootsT, t.RootsT)
|
---|
60 | n.NodesT = make([]expr.ExprType, len(t.NodesT))
|
---|
61 | copy(n.NodesT, t.NodesT)
|
---|
62 | n.LeafsT = make([]expr.ExprType, len(t.LeafsT))
|
---|
63 | copy(n.LeafsT, t.LeafsT)
|
---|
64 | n.NonTrigT = make([]expr.ExprType, len(t.NonTrigT))
|
---|
65 | copy(n.NonTrigT, t.NonTrigT)
|
---|
66 |
|
---|
67 | n.Roots = make([]expr.Expr, len(t.Roots))
|
---|
68 | copy(n.Roots, t.Roots)
|
---|
69 | n.Nodes = make([]expr.Expr, len(t.Nodes))
|
---|
70 | copy(n.Nodes, t.Nodes)
|
---|
71 | n.Leafs = make([]expr.Expr, len(t.Leafs))
|
---|
72 | copy(n.Leafs, t.Leafs)
|
---|
73 | n.NonTrig = make([]expr.Expr, len(t.NonTrig))
|
---|
74 | copy(n.NonTrig, t.NonTrig)
|
---|
75 |
|
---|
76 | n.DoSimp = t.DoSimp
|
---|
77 | n.SRules = t.SRules
|
---|
78 |
|
---|
79 | n.UsableVars = make([]int, len(t.UsableVars))
|
---|
80 | copy(n.UsableVars, t.UsableVars)
|
---|
81 |
|
---|
82 | n.NumDim = t.NumDim
|
---|
83 | n.NumSys = t.NumSys
|
---|
84 | n.NumCoeff = t.NumCoeff
|
---|
85 |
|
---|
86 | return n
|
---|
87 | }
|
---|
88 | func ParseTreeParams(field, value string, config interface{}) (found bool, err error) {
|
---|
89 |
|
---|
90 | TP := config.(*TreeParams)
|
---|
91 | found = true
|
---|
92 |
|
---|
93 | switch strings.ToUpper(field) {
|
---|
94 | case "ROOTS":
|
---|
95 | TP.RootsS = strings.Fields(value)
|
---|
96 | TP.RootsT, TP.Roots = fillExprStuff(TP.RootsS)
|
---|
97 | case "NODES":
|
---|
98 | TP.NodesS = strings.Fields(value)
|
---|
99 | TP.NodesT, TP.Nodes = fillExprStuff(TP.NodesS)
|
---|
100 | case "NONTRIG":
|
---|
101 | TP.NonTrigS = strings.Fields(value)
|
---|
102 | TP.NonTrigT, TP.NonTrig = fillExprStuff(TP.NonTrigS)
|
---|
103 | case "LEAFS":
|
---|
104 | TP.LeafsS = strings.Fields(value)
|
---|
105 | TP.LeafsT, TP.Leafs = fillExprStuff(TP.LeafsS)
|
---|
106 |
|
---|
107 | case "USABLEVARS":
|
---|
108 | usable := strings.Fields(value)
|
---|
109 | for _, v := range usable {
|
---|
110 | ival, cerr := strconv.Atoi(v)
|
---|
111 | if cerr != nil {
|
---|
112 | log.Printf("Expected integer for UsableDim\n")
|
---|
113 | return found, cerr
|
---|
114 | }
|
---|
115 | TP.UsableVars = append(TP.UsableVars, ival)
|
---|
116 | }
|
---|
117 |
|
---|
118 | case "MAXSIZE":
|
---|
119 | ival, cerr := strconv.Atoi(value)
|
---|
120 | if cerr != nil {
|
---|
121 | log.Printf("Expected integer for MaxSize\n")
|
---|
122 | return found, cerr
|
---|
123 | }
|
---|
124 | TP.MaxSize = ival
|
---|
125 | case "MINSIZE":
|
---|
126 | ival, cerr := strconv.Atoi(value)
|
---|
127 | if cerr != nil {
|
---|
128 | log.Printf("Expected integer for UsableDim\n")
|
---|
129 | return found, cerr
|
---|
130 | }
|
---|
131 | TP.MinSize = ival
|
---|
132 | case "MAXDEPTH":
|
---|
133 | ival, cerr := strconv.Atoi(value)
|
---|
134 | if cerr != nil {
|
---|
135 | log.Printf("Expected integer for UsableDim\n")
|
---|
136 | return found, cerr
|
---|
137 | }
|
---|
138 | TP.MaxDepth = ival
|
---|
139 | case "MINDEPTH":
|
---|
140 | ival, cerr := strconv.Atoi(value)
|
---|
141 | if cerr != nil {
|
---|
142 | log.Printf("Expected integer for UsableDim\n")
|
---|
143 | return found, cerr
|
---|
144 | }
|
---|
145 | TP.MinDepth = ival
|
---|
146 |
|
---|
147 | default:
|
---|
148 | found = false
|
---|
149 | log.Printf("Problem Config Not Implemented: %s, %s\n\n", field, value)
|
---|
150 |
|
---|
151 | }
|
---|
152 | return
|
---|
153 | }
|
---|
154 |
|
---|
155 | func fillExprStuff(names []string) (types []expr.ExprType, exprs []expr.Expr) {
|
---|
156 | types = make([]expr.ExprType, len(names))
|
---|
157 | exprs = make([]expr.Expr, len(names))
|
---|
158 | for i, n := range names {
|
---|
159 | switch strings.ToLower(n) {
|
---|
160 | case "constant":
|
---|
161 | types[i] = expr.CONSTANT
|
---|
162 | exprs[i] = new(expr.Constant)
|
---|
163 | case "constantf":
|
---|
164 | types[i] = expr.CONSTANTF
|
---|
165 | exprs[i] = new(expr.ConstantF)
|
---|
166 | case "time":
|
---|
167 | types[i] = expr.TIME
|
---|
168 | exprs[i] = new(expr.Time)
|
---|
169 | case "system":
|
---|
170 | types[i] = expr.SYSTEM
|
---|
171 | exprs[i] = new(expr.System)
|
---|
172 | case "var":
|
---|
173 | types[i] = expr.VAR
|
---|
174 | exprs[i] = new(expr.Var)
|
---|
175 |
|
---|
176 | case "neg":
|
---|
177 | types[i] = expr.NEG
|
---|
178 | exprs[i] = new(expr.Neg)
|
---|
179 | case "abs":
|
---|
180 | types[i] = expr.ABS
|
---|
181 | exprs[i] = new(expr.Abs)
|
---|
182 | case "sqrt":
|
---|
183 | types[i] = expr.SQRT
|
---|
184 | exprs[i] = new(expr.Sqrt)
|
---|
185 | case "sin":
|
---|
186 | types[i] = expr.SIN
|
---|
187 | exprs[i] = new(expr.Sin)
|
---|
188 | case "cos":
|
---|
189 | types[i] = expr.COS
|
---|
190 | exprs[i] = new(expr.Cos)
|
---|
191 | case "tan":
|
---|
192 | types[i] = expr.TAN
|
---|
193 | exprs[i] = new(expr.Tan)
|
---|
194 | case "exp":
|
---|
195 | types[i] = expr.EXP
|
---|
196 | exprs[i] = new(expr.Exp)
|
---|
197 | case "log":
|
---|
198 | types[i] = expr.LOG
|
---|
199 | exprs[i] = new(expr.Log)
|
---|
200 |
|
---|
201 | case "powi":
|
---|
202 | types[i] = expr.POWI
|
---|
203 | exprs[i] = new(expr.PowI)
|
---|
204 | case "powf":
|
---|
205 | types[i] = expr.POWF
|
---|
206 | exprs[i] = new(expr.PowF)
|
---|
207 | case "powe":
|
---|
208 | types[i] = expr.POWE
|
---|
209 | exprs[i] = new(expr.PowE)
|
---|
210 |
|
---|
211 | case "add":
|
---|
212 | types[i] = expr.ADD
|
---|
213 | exprs[i] = expr.NewAdd()
|
---|
214 | case "mul":
|
---|
215 | types[i] = expr.MUL
|
---|
216 | exprs[i] = expr.NewMul()
|
---|
217 | case "div":
|
---|
218 | types[i] = expr.DIV
|
---|
219 | exprs[i] = new(expr.Div)
|
---|
220 | default:
|
---|
221 | log.Fatalf("Unknown ExprType: %s\n", n)
|
---|
222 | }
|
---|
223 | }
|
---|
224 | return
|
---|
225 | }
|
---|
226 |
|
---|
227 | func (tp *TreeParams) CheckExprTmp(e expr.Expr) bool {
|
---|
228 | if e.Size() < tp.TmpMinSize || e.Size() > tp.TmpMaxSize ||
|
---|
229 | e.Height() < tp.TmpMinDepth || e.Height() > tp.TmpMaxDepth {
|
---|
230 | return false
|
---|
231 | }
|
---|
232 | return true
|
---|
233 | }
|
---|
234 | func (tp *TreeParams) CheckExpr(e expr.Expr) bool {
|
---|
235 | if e.Size() < tp.MinSize {
|
---|
236 | // fmt.Printf( "Too SMALL: e:%v l:%v\n", e.Size(), tp.TmpMinSize )
|
---|
237 | return false
|
---|
238 | } else if e.Size() > tp.MaxSize {
|
---|
239 | // fmt.Printf( "Too LARGE: e:%v l:%v\n", e.Size(), tp.TmpMaxSize )
|
---|
240 | return false
|
---|
241 | } else if e.Height() < tp.MinDepth {
|
---|
242 | // fmt.Printf( "Too SHORT: e:%v l:%v\n", e.Height(), tp.TmpMinDepth )
|
---|
243 | return false
|
---|
244 | } else if e.Height() > tp.MaxDepth {
|
---|
245 | // fmt.Printf( "Too TALL: e:%v l:%v\n", e.Height(), tp.TmpMaxDepth )
|
---|
246 | return false
|
---|
247 | }
|
---|
248 | return true
|
---|
249 | }
|
---|
250 |
|
---|
251 | func (tp *TreeParams) CheckExprLog(e expr.Expr, log *bufio.Writer) bool {
|
---|
252 | // if e.Size() < tp.TmpMinSize || e.Size() > tp.TmpMaxSize ||
|
---|
253 | // e.Height() < tp.TmpMinDepth || e.Height() > tp.TmpMaxDepth {
|
---|
254 | // return false
|
---|
255 | // }
|
---|
256 | if e.Size() < tp.MinSize {
|
---|
257 | fmt.Fprintf(log, "Too SMALL: e:%v l:%v\n", e.Size(), tp.MinSize)
|
---|
258 | return false
|
---|
259 | } else if e.Size() > tp.MaxSize {
|
---|
260 | fmt.Fprintf(log, "Too LARGE: e:%v l:%v\n", e.Size(), tp.MaxSize)
|
---|
261 | return false
|
---|
262 | } else if e.Height() < tp.MinDepth {
|
---|
263 | fmt.Fprintf(log, "Too SHORT: e:%v l:%v\n", e.Height(), tp.MinDepth)
|
---|
264 | return false
|
---|
265 | } else if e.Height() > tp.MaxDepth {
|
---|
266 | fmt.Fprintf(log, "Too TALL: e:%v l:%v\n", e.Height(), tp.MaxDepth)
|
---|
267 | return false
|
---|
268 | }
|
---|
269 | return true
|
---|
270 | }
|
---|
271 | func (tp *TreeParams) CheckExprPrint(e expr.Expr) bool {
|
---|
272 | // if e.Size() < tp.TmpMinSize || e.Size() > tp.TmpMaxSize ||
|
---|
273 | // e.Height() < tp.TmpMinDepth || e.Height() > tp.TmpMaxDepth {
|
---|
274 | // return false
|
---|
275 | // }
|
---|
276 | if e.Size() < tp.MinSize {
|
---|
277 | fmt.Printf("Too SMALL: e:%v l:%v\n", e.Size(), tp.MinSize)
|
---|
278 | return false
|
---|
279 | } else if e.Size() > tp.MaxSize {
|
---|
280 | fmt.Printf("Too LARGE: e:%v l:%v\n", e.Size(), tp.MaxSize)
|
---|
281 | return false
|
---|
282 | } else if e.Height() < tp.MinDepth {
|
---|
283 | fmt.Printf("Too SHORT: e:%v l:%v\n", e.Height(), tp.MinDepth)
|
---|
284 | return false
|
---|
285 | } else if e.Height() > tp.MaxDepth {
|
---|
286 | fmt.Printf("Too TALL: e:%v l:%v\n", e.Height(), tp.MaxDepth)
|
---|
287 | return false
|
---|
288 | }
|
---|
289 | return true
|
---|
290 | }
|
---|
291 |
|
---|
292 | func (tp *TreeParams) ResetCurr() {
|
---|
293 | tp.CurrSize, tp.CurrDepth, tp.InTrig, tp.CoeffCount = 0, 0, false, 0
|
---|
294 | }
|
---|
295 | func (tp *TreeParams) ResetTemp() {
|
---|
296 | tp.TmpMaxSize, tp.TmpMaxDepth = tp.MaxSize, tp.MaxDepth
|
---|
297 | tp.TmpMinSize, tp.TmpMinDepth = tp.MinSize, tp.MinDepth
|
---|
298 | }
|
---|