Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Tests/SymbolicExpressionImporter.cs @ 4027

Last change on this file since 4027 was 3841, checked in by gkronber, 14 years ago

Extended set of available functions for symbolic regression and added test cases for the extended function set. #1013

File size: 6.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 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.Linq;
25using System.Text;
26using System.IO;
27using System.Diagnostics;
28using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
29using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
31
32namespace HeuristicLab.Problems.DataAnalysis.Tests {
33  internal class SymbolicExpressionImporter {
34    private const string VARSTART = "VAR";
35    private const string DEFUNSTART = "DEFUN";
36    private const string ARGSTART = "ARG";
37    private const string INVOKESTART = "CALL";
38    private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>()
39      {
40        {"+", new Addition()},
41        {"/", new Division()},
42        {"*", new Multiplication()},
43        {"-", new Subtraction()},
44        {"EXP", new Exponential()},
45        {"LOG", new Logarithm()},
46        {"SIN",new Sine()},
47        {"COS", new Cosine()},
48        {"TAN", new Tangent()},
49        {"MEAN", new Average()},
50        {"IF", new IfThenElse()},
51        {">", new GreaterThan()},
52        {"<", new LessThan()},
53        {"AND", new And()},
54        {"OR", new Or()},
55        {"NOT", new Not()},
56        {"PROG", new ProgramRootSymbol()},
57        {"MAIN", new StartSymbol()},
58      };
59
60    Constant constant = new Constant();
61    Variable variable = new Variable();
62    Defun defun = new Defun();
63
64    ProgramRootSymbol programRootSymbol = new ProgramRootSymbol();
65    StartSymbol startSymbol = new StartSymbol();
66
67    public SymbolicExpressionImporter() {
68    }
69
70    internal SymbolicExpressionTree Import(string str) {
71      str = str.Replace("(", " ( ").Replace(")", " ) ");
72      SymbolicExpressionTreeNode root = programRootSymbol.CreateTreeNode();
73      SymbolicExpressionTreeNode start = startSymbol.CreateTreeNode();
74      SymbolicExpressionTreeNode mainBranch = ParseSexp(new Queue<Token>(GetTokenStream(str)));
75      if (mainBranch.Symbol is ProgramRootSymbol) {
76        // when a root symbol was parsed => use main branch as root
77        root = mainBranch;
78      } else {
79        // only a main branch was given => insert the main branch into the default tree template
80        root.AddSubTree(start);
81        start.AddSubTree(mainBranch);
82      }
83      return new SymbolicExpressionTree(root);
84    }
85
86    private IEnumerable<Token> GetTokenStream(string str) {
87      return
88             from strToken in str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).AsEnumerable()
89             let t = Token.Parse(strToken)
90             where t != null
91             select t;
92    }
93
94    private SymbolicExpressionTreeNode ParseSexp(Queue<Token> tokens) {
95      if (tokens.Peek().Symbol == TokenSymbol.LPAR) {
96        SymbolicExpressionTreeNode tree;
97        Expect(Token.LPAR, tokens);
98        if (tokens.Peek().StringValue.StartsWith(VARSTART)) {
99          tree = ParseVariable(tokens);
100        } else if (tokens.Peek().StringValue.StartsWith(DEFUNSTART)) {
101          tree = ParseDefun(tokens);
102          while (!tokens.Peek().Equals(Token.RPAR)) {
103            tree.AddSubTree(ParseSexp(tokens));
104          }
105        } else if (tokens.Peek().StringValue.StartsWith(ARGSTART)) {
106          tree = ParseArgument(tokens);
107        } else if (tokens.Peek().StringValue.StartsWith(INVOKESTART)) {
108          tree = ParseInvoke(tokens);
109          while (!tokens.Peek().Equals(Token.RPAR)) {
110            tree.AddSubTree(ParseSexp(tokens));
111          }
112        } else {
113          Token curToken = tokens.Dequeue();
114          tree = CreateTree(curToken);
115          while (!tokens.Peek().Equals(Token.RPAR)) {
116            tree.AddSubTree(ParseSexp(tokens));
117          }
118        }
119        Expect(Token.RPAR, tokens);
120        return tree;
121      } else if (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
122        ConstantTreeNode t = (ConstantTreeNode)constant.CreateTreeNode();
123        t.Value = tokens.Dequeue().DoubleValue;
124        return t;
125      } else throw new FormatException("Expected function or constant symbol");
126    }
127
128    private SymbolicExpressionTreeNode ParseInvoke(Queue<Token> tokens) {
129      Token invokeTok = tokens.Dequeue();
130      Debug.Assert(invokeTok.StringValue == "CALL");
131      InvokeFunction invokeSym = new InvokeFunction(tokens.Dequeue().StringValue);
132      SymbolicExpressionTreeNode invokeNode = invokeSym.CreateTreeNode();
133      return invokeNode;
134    }
135
136    private SymbolicExpressionTreeNode ParseArgument(Queue<Token> tokens) {
137      Token argTok = tokens.Dequeue();
138      Debug.Assert(argTok.StringValue == "ARG");
139      Argument argument = new Argument((int)tokens.Dequeue().DoubleValue);
140      SymbolicExpressionTreeNode argNode = argument.CreateTreeNode();
141      return argNode;
142    }
143
144    private SymbolicExpressionTreeNode ParseDefun(Queue<Token> tokens) {
145      Token defTok = tokens.Dequeue();
146      Debug.Assert(defTok.StringValue == "DEFUN");
147      DefunTreeNode t = (DefunTreeNode)defun.CreateTreeNode();
148      t.FunctionName = tokens.Dequeue().StringValue;
149      return t;
150    }
151
152    private SymbolicExpressionTreeNode ParseVariable(Queue<Token> tokens) {
153      Token varTok = tokens.Dequeue();
154      Debug.Assert(varTok.StringValue == "VARIABLE");
155      VariableTreeNode t = (VariableTreeNode)variable.CreateTreeNode();
156      t.Weight = tokens.Dequeue().DoubleValue;
157      t.VariableName = tokens.Dequeue().StringValue;
158      return t;
159    }
160
161    private SymbolicExpressionTreeNode CreateTree(Token token) {
162      if (token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
163      return knownSymbols[token.StringValue].CreateTreeNode();
164    }
165
166    private void Expect(Token token, Queue<Token> tokens) {
167      Token cur = tokens.Dequeue();
168      if (!token.Equals(cur)) throw new FormatException("Expected: " + token.StringValue + ", but got: " + cur.StringValue);
169    }
170  }
171}
Note: See TracBrowser for help on using the repository browser.