Free cookie consent management tool by TermsFeed Policy Generator

source: branches/DataAnalysis.IslandAlgorithms/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs @ 16279

Last change on this file since 16279 was 11457, checked in by bburlacu, 10 years ago

#2218: Moved the SymbolicExpressionImporter from HeuristicLab.Tests to HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer.

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