Free cookie consent management tool by TermsFeed Policy Generator

source: branches/Breadcrumbs/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicExpressionImporter.cs @ 11001

Last change on this file since 11001 was 9785, checked in by abeham, 11 years ago

#2088: Added test attributes for Problems.DataAnalysis

File size: 9.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2013 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        {"AIRYA", new AiryA()},
51        {"AIRYB", new AiryB()},
52        {"BESSEL", new Bessel()},
53        {"COSINT", new CosineIntegral()},
54        {"SININT", new SineIntegral()},
55        {"HYPCOSINT", new HyperbolicCosineIntegral()},
56        {"HYPSININT", new HyperbolicSineIntegral()},
57        {"FRESNELSININT", new FresnelSineIntegral()},
58        {"FRESNELCOSINT", new FresnelCosineIntegral()},
59        {"NORM", new Norm()},
60        {"ERF", new Erf()},
61        {"GAMMA", new Gamma()},
62        {"PSI", new Psi()},
63        {"DAWSON", new Dawson()},
64        {"EXPINT", new ExponentialIntegralEi()},
65        {"MEAN", new Average()},
66        {"IF", new IfThenElse()},
67        {">", new GreaterThan()},
68        {"<", new LessThan()},
69        {"AND", new And()},
70        {"OR", new Or()},
71        {"NOT", new Not()},
72        {"DIFF", new Derivative()},
73        {"PROG", new ProgramRootSymbol()},
74        {"MAIN", new StartSymbol()},
75      };
76
77    Constant constant = new Constant();
78    Variable variable = new Variable();
79    LaggedVariable laggedVariable = new LaggedVariable();
80    Defun defun = new Defun();
81    TimeLag timeLag = new TimeLag();
82    Integral integral = new Integral();
83
84    ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
85    StartSymbol startSymbol = new StartSymbol();
86
87    internal ISymbolicExpressionTree Import(string str) {
88      str = str.Replace("(", " ( ").Replace(")", " ) ");
89      ISymbolicExpressionTreeNode root = programRootSymbol.CreateTreeNode();
90      ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
91      ISymbolicExpressionTreeNode mainBranch = ParseSexp(new Queue<Token>(GetTokenStream(str)));
92      if (mainBranch.Symbol is ProgramRootSymbol) {
93        // when a root symbol was parsed => use main branch as root
94        root = mainBranch;
95      } else {
96        // only a main branch was given => insert the main branch into the default tree template
97        root.AddSubtree(start);
98        start.AddSubtree(mainBranch);
99      }
100      return new SymbolicExpressionTree(root);
101    }
102
103    private IEnumerable<Token> GetTokenStream(string str) {
104      return
105             from strToken in str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).AsEnumerable()
106             let t = Token.Parse(strToken)
107             where t != null
108             select t;
109    }
110
111    private ISymbolicExpressionTreeNode ParseSexp(Queue<Token> tokens) {
112      if (tokens.Peek().Symbol == TokenSymbol.LPAR) {
113        ISymbolicExpressionTreeNode tree;
114        Expect(Token.LPAR, tokens);
115        if (tokens.Peek().StringValue.StartsWith(VARSTART)) {
116          tree = ParseVariable(tokens);
117        } else if (tokens.Peek().StringValue.StartsWith(LAGGEDVARSTART)) {
118          tree = ParseLaggedVariable(tokens);
119        } else if (tokens.Peek().StringValue.StartsWith(TIMELAGSTART)) {
120          tree = ParseTimeLag(tokens);
121          tree.AddSubtree(ParseSexp(tokens));
122        } else if (tokens.Peek().StringValue.StartsWith(INTEGRALSTART)) {
123          tree = ParseIntegral(tokens);
124          tree.AddSubtree(ParseSexp(tokens));
125        } else if (tokens.Peek().StringValue.StartsWith(DEFUNSTART)) {
126          tree = ParseDefun(tokens);
127          while (!tokens.Peek().Equals(Token.RPAR)) {
128            tree.AddSubtree(ParseSexp(tokens));
129          }
130        } else if (tokens.Peek().StringValue.StartsWith(ARGSTART)) {
131          tree = ParseArgument(tokens);
132        } else if (tokens.Peek().StringValue.StartsWith(INVOKESTART)) {
133          tree = ParseInvoke(tokens);
134          while (!tokens.Peek().Equals(Token.RPAR)) {
135            tree.AddSubtree(ParseSexp(tokens));
136          }
137        } else {
138          Token curToken = tokens.Dequeue();
139          tree = CreateTree(curToken);
140          while (!tokens.Peek().Equals(Token.RPAR)) {
141            tree.AddSubtree(ParseSexp(tokens));
142          }
143        }
144        Expect(Token.RPAR, tokens);
145        return tree;
146      } else if (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
147        ConstantTreeNode t = (ConstantTreeNode)constant.CreateTreeNode();
148        t.Value = tokens.Dequeue().DoubleValue;
149        return t;
150      } else throw new FormatException("Expected function or constant symbol");
151    }
152
153    private ISymbolicExpressionTreeNode ParseInvoke(Queue<Token> tokens) {
154      Token invokeTok = tokens.Dequeue();
155      Debug.Assert(invokeTok.StringValue == "CALL");
156      InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue);
157      ISymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode();
158      return invokeNode;
159    }
160
161    private ISymbolicExpressionTreeNode ParseArgument(Queue<Token> tokens) {
162      Token argTok = tokens.Dequeue();
163      Debug.Assert(argTok.StringValue == "ARG");
164      Argument argument = new Argument((int)tokens.Dequeue().DoubleValue);
165      ISymbolicExpressionTreeNode argNode = argument.CreateTreeNode();
166      return argNode;
167    }
168
169    private ISymbolicExpressionTreeNode ParseDefun(Queue<Token> tokens) {
170      Token defTok = tokens.Dequeue();
171      Debug.Assert(defTok.StringValue == "DEFUN");
172      DefunTreeNode t = (DefunTreeNode)defun.CreateTreeNode();
173      t.FunctionName = tokens.Dequeue().StringValue;
174      return t;
175    }
176
177    private ISymbolicExpressionTreeNode ParseTimeLag(Queue<Token> tokens) {
178      Token varTok = tokens.Dequeue();
179      Debug.Assert(varTok.StringValue == "LAG");
180      LaggedTreeNode t = (LaggedTreeNode)timeLag.CreateTreeNode();
181      t.Lag = (int)tokens.Dequeue().DoubleValue;
182      return t;
183    }
184
185    private ISymbolicExpressionTreeNode ParseIntegral(Queue<Token> tokens) {
186      Token varTok = tokens.Dequeue();
187      Debug.Assert(varTok.StringValue == "INTEGRAL");
188      LaggedTreeNode t = (LaggedTreeNode)integral.CreateTreeNode();
189      t.Lag = (int)tokens.Dequeue().DoubleValue;
190      return t;
191    }
192
193    private ISymbolicExpressionTreeNode ParseVariable(Queue<Token> tokens) {
194      Token varTok = tokens.Dequeue();
195      Debug.Assert(varTok.StringValue == "VARIABLE");
196      VariableTreeNode t = (VariableTreeNode)variable.CreateTreeNode();
197      t.Weight = tokens.Dequeue().DoubleValue;
198      t.VariableName = tokens.Dequeue().StringValue;
199      return t;
200    }
201
202    private ISymbolicExpressionTreeNode ParseLaggedVariable(Queue<Token> tokens) {
203      Token varTok = tokens.Dequeue();
204      Debug.Assert(varTok.StringValue == "LAGVARIABLE");
205      LaggedVariableTreeNode t = (LaggedVariableTreeNode)laggedVariable.CreateTreeNode();
206      t.Weight = tokens.Dequeue().DoubleValue;
207      t.VariableName = tokens.Dequeue().StringValue;
208      t.Lag = (int)tokens.Dequeue().DoubleValue;
209      return t;
210    }
211
212    private ISymbolicExpressionTreeNode CreateTree(Token token) {
213      if (token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
214      return knownSymbols[token.StringValue].CreateTreeNode();
215    }
216
217    private void Expect(Token token, Queue<Token> tokens) {
218      Token cur = tokens.Dequeue();
219      if (!token.Equals(cur)) throw new FormatException("Expected: " + token.StringValue + ", but got: " + cur.StringValue);
220    }
221  }
222}
Note: See TracBrowser for help on using the repository browser.