Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Trunk/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicExpressionImporter.cs @ 6843

Last change on this file since 6843 was 6809, checked in by gkronber, 13 years ago

#1480 added check if row index lies within the possible range of the dataset and implemented interpretation of time series symbols in the IL emitting interpreter. Added test cases for evaluation of time series symbols.

File size: 8.5 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Diagnostics;
25using System.Linq;
26using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
27
28namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Tests {
29  internal class SymbolicExpressionImporter {
30    private const string VARSTART = "VAR";
31    private const string LAGGEDVARSTART = "LAGVARIABLE";
32    private const string INTEGRALSTART = "INTEG";
33    private const string DEFUNSTART = "DEFUN";
34    private const string ARGSTART = "ARG";
35    private const string INVOKESTART = "CALL";
36    private const string TIMELAGSTART = "LAG";
37    private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>()
38      {
39        {"+", new Addition()},
40        {"/", new Division()},
41        {"*", new Multiplication()},
42        {"-", new Subtraction()},
43        {"EXP", new Exponential()},
44        {"LOG", new Logarithm()},
45        {"POW", new Power()},
46        {"ROOT", new Root()},
47        {"SIN",new Sine()},
48        {"COS", new Cosine()},
49        {"TAN", new Tangent()},
50        {"MEAN", new Average()},
51        {"IF", new IfThenElse()},
52        {">", new GreaterThan()},
53        {"<", new LessThan()},
54        {"AND", new And()},
55        {"OR", new Or()},
56        {"NOT", new Not()},
57        {"DIFF", new Derivative()},
58        {"PROG", new ProgramRootSymbol()},
59        {"MAIN", new StartSymbol()},
60      };
61
62    Constant constant = new Constant();
63    Variable variable = new Variable();
64    LaggedVariable laggedVariable = new LaggedVariable();
65    Defun defun = new Defun();
66    TimeLag timeLag = new TimeLag();
67    Integral integral = new Integral();
68
69    ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
70    StartSymbol startSymbol = new StartSymbol();
71
72    public SymbolicExpressionImporter() {
73    }
74
75    internal ISymbolicExpressionTree Import(string str) {
76      str = str.Replace("(", " ( ").Replace(")", " ) ");
77      ISymbolicExpressionTreeNode root = programRootSymbol.CreateTreeNode();
78      ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
79      ISymbolicExpressionTreeNode mainBranch = ParseSexp(new Queue<Token>(GetTokenStream(str)));
80      if (mainBranch.Symbol is ProgramRootSymbol) {
81        // when a root symbol was parsed => use main branch as root
82        root = mainBranch;
83      } else {
84        // only a main branch was given => insert the main branch into the default tree template
85        root.AddSubtree(start);
86        start.AddSubtree(mainBranch);
87      }
88      return new SymbolicExpressionTree(root);
89    }
90
91    private IEnumerable<Token> GetTokenStream(string str) {
92      return
93             from strToken in str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).AsEnumerable()
94             let t = Token.Parse(strToken)
95             where t != null
96             select t;
97    }
98
99    private ISymbolicExpressionTreeNode ParseSexp(Queue<Token> tokens) {
100      if (tokens.Peek().Symbol == TokenSymbol.LPAR) {
101        ISymbolicExpressionTreeNode tree;
102        Expect(Token.LPAR, tokens);
103        if (tokens.Peek().StringValue.StartsWith(VARSTART)) {
104          tree = ParseVariable(tokens);
105        } else if (tokens.Peek().StringValue.StartsWith(LAGGEDVARSTART)) {
106          tree = ParseLaggedVariable(tokens);
107        } else if (tokens.Peek().StringValue.StartsWith(TIMELAGSTART)) {
108          tree = ParseTimeLag(tokens);
109          tree.AddSubtree(ParseSexp(tokens));
110        } else if (tokens.Peek().StringValue.StartsWith(INTEGRALSTART)) {
111          tree = ParseIntegral(tokens);
112          tree.AddSubtree(ParseSexp(tokens));
113        } else if (tokens.Peek().StringValue.StartsWith(DEFUNSTART)) {
114          tree = ParseDefun(tokens);
115          while (!tokens.Peek().Equals(Token.RPAR)) {
116            tree.AddSubtree(ParseSexp(tokens));
117          }
118        } else if (tokens.Peek().StringValue.StartsWith(ARGSTART)) {
119          tree = ParseArgument(tokens);
120        } else if (tokens.Peek().StringValue.StartsWith(INVOKESTART)) {
121          tree = ParseInvoke(tokens);
122          while (!tokens.Peek().Equals(Token.RPAR)) {
123            tree.AddSubtree(ParseSexp(tokens));
124          }
125        } else {
126          Token curToken = tokens.Dequeue();
127          tree = CreateTree(curToken);
128          while (!tokens.Peek().Equals(Token.RPAR)) {
129            tree.AddSubtree(ParseSexp(tokens));
130          }
131        }
132        Expect(Token.RPAR, tokens);
133        return tree;
134      } else if (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
135        ConstantTreeNode t = (ConstantTreeNode)constant.CreateTreeNode();
136        t.Value = tokens.Dequeue().DoubleValue;
137        return t;
138      } else throw new FormatException("Expected function or constant symbol");
139    }
140
141    private ISymbolicExpressionTreeNode ParseInvoke(Queue<Token> tokens) {
142      Token invokeTok = tokens.Dequeue();
143      Debug.Assert(invokeTok.StringValue == "CALL");
144      InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue);
145      ISymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode();
146      return invokeNode;
147    }
148
149    private ISymbolicExpressionTreeNode ParseArgument(Queue<Token> tokens) {
150      Token argTok = tokens.Dequeue();
151      Debug.Assert(argTok.StringValue == "ARG");
152      Argument argument = new Argument((int)tokens.Dequeue().DoubleValue);
153      ISymbolicExpressionTreeNode argNode = argument.CreateTreeNode();
154      return argNode;
155    }
156
157    private ISymbolicExpressionTreeNode ParseDefun(Queue<Token> tokens) {
158      Token defTok = tokens.Dequeue();
159      Debug.Assert(defTok.StringValue == "DEFUN");
160      DefunTreeNode t = (DefunTreeNode)defun.CreateTreeNode();
161      t.FunctionName = tokens.Dequeue().StringValue;
162      return t;
163    }
164
165    private ISymbolicExpressionTreeNode ParseTimeLag(Queue<Token> tokens) {
166      Token varTok = tokens.Dequeue();
167      Debug.Assert(varTok.StringValue == "LAG");
168      LaggedTreeNode t = (LaggedTreeNode)timeLag.CreateTreeNode();
169      t.Lag = (int)tokens.Dequeue().DoubleValue;
170      return t;
171    }
172
173    private ISymbolicExpressionTreeNode ParseIntegral(Queue<Token> tokens) {
174      Token varTok = tokens.Dequeue();
175      Debug.Assert(varTok.StringValue == "INTEGRAL");
176      LaggedTreeNode t = (LaggedTreeNode)integral.CreateTreeNode();
177      t.Lag = (int)tokens.Dequeue().DoubleValue;
178      return t;
179    }
180
181    private ISymbolicExpressionTreeNode ParseVariable(Queue<Token> tokens) {
182      Token varTok = tokens.Dequeue();
183      Debug.Assert(varTok.StringValue == "VARIABLE");
184      VariableTreeNode t = (VariableTreeNode)variable.CreateTreeNode();
185      t.Weight = tokens.Dequeue().DoubleValue;
186      t.VariableName = tokens.Dequeue().StringValue;
187      return t;
188    }
189
190    private ISymbolicExpressionTreeNode ParseLaggedVariable(Queue<Token> tokens) {
191      Token varTok = tokens.Dequeue();
192      Debug.Assert(varTok.StringValue == "LAGVARIABLE");
193      LaggedVariableTreeNode t = (LaggedVariableTreeNode)laggedVariable.CreateTreeNode();
194      t.Weight = tokens.Dequeue().DoubleValue;
195      t.VariableName = tokens.Dequeue().StringValue;
196      t.Lag = (int)tokens.Dequeue().DoubleValue;
197      return t;
198    }
199
200    private ISymbolicExpressionTreeNode CreateTree(Token token) {
201      if (token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
202      return knownSymbols[token.StringValue].CreateTreeNode();
203    }
204
205    private void Expect(Token token, Queue<Token> tokens) {
206      Token cur = tokens.Dequeue();
207      if (!token.Equals(cur)) throw new FormatException("Expected: " + token.StringValue + ", but got: " + cur.StringValue);
208    }
209  }
210}
Note: See TracBrowser for help on using the repository browser.