source: branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/ExpressionGenerator.cs @ 14515

Last change on this file since 14515 was 14515, checked in by bburlacu, 4 years ago

#2704: Fix infix formatting bug, refactored generation of polynomial to respect user choices (with or without exp/log).

File size: 4.9 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2016 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 HeuristicLab.Core;
26using HeuristicLab.Random;
27
28namespace HeuristicLab.ExpressionGenerator {
29  public static class ExpressionGenerator {
30    public static IEnumerable<Expression> GenerateRandomDistributedVariables(int numberOfVariables, string variablePrefix, IRandom randomDistribution) {
31      return Enumerable.Range(1, numberOfVariables).Select(x => Expression.RandomVariable(string.Format("{0}{1}", variablePrefix, x), randomDistribution));
32    }
33
34    public static Expression Polynomial(IRandom uniformRandom, Expression[] variables, bool useLog, bool useExp) {
35      const int count = 10; // how many instances of each template should be produce?
36      int i = 1;
37      // the main template
38      var template = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 2, count)) { Label = "+" };
39      template.AddArguments(variables);
40
41      var sumTemplate = new RandomArityTemplate(Sum, new UniformDistributedRandom(uniformRandom, 1, variables.Length)) { Label = "+" };
42      sumTemplate.AddArguments(variables);
43
44      var productTemplate = new RandomArityTemplate(Product, new UniformDistributedRandom(uniformRandom, 1, variables.Length)) { Label = "*" };
45      productTemplate.AddArguments(variables);
46
47      var inverseTemplate = new FixedArityTemplate(Division, 1) { Label = "/" };
48      inverseTemplate.AddArguments(variables);
49      inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => sumTemplate.Instantiate(string.Format("sum{0}", i++), uniformRandom)));
50      inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => productTemplate.Instantiate(string.Format("prod{0}", i++), uniformRandom)));
51
52      if (useLog) {
53        var logTemplate = new FixedArityTemplate(Log, 1) { Label = "log" };
54        logTemplate.AddArguments(variables);
55        logTemplate.AddArguments(Enumerable.Range(1, count).Select(x => sumTemplate.Instantiate(string.Format("sum{0}", i++), uniformRandom)));
56        template.AddArguments(Enumerable.Range(1, count).Select(x => logTemplate.Instantiate(string.Format("log{0}", i++), uniformRandom)));
57        inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => logTemplate.Instantiate(string.Format("log{0}", i++), uniformRandom)));
58      }
59
60      if (useExp) {
61        var expTemplate = new FixedArityTemplate(Exp, 1) { Label = "exp" };
62        expTemplate.AddArguments(variables);
63        expTemplate.AddArguments(Enumerable.Range(1, count).Select(x => productTemplate.Instantiate(string.Format("prod{0}", i++), uniformRandom)));
64        template.AddArguments(Enumerable.Range(1, count).Select(x => expTemplate.Instantiate(string.Format("exp{0}", i++), uniformRandom)));
65        inverseTemplate.AddArguments(Enumerable.Range(1, count).Select(x => expTemplate.Instantiate(string.Format("exp{0}", i++), uniformRandom)));
66      }
67
68      template.AddArguments(Enumerable.Range(1, count).Select(x => inverseTemplate.Instantiate(string.Format("inv{0}", i++), uniformRandom)));
69      return template.Instantiate("polynomial", uniformRandom);
70    }
71
72    #region static functions
73    private static double Sum(IEnumerable<double> args) {
74      return args.Sum();
75    }
76
77    private static double Product(IEnumerable<double> args) {
78      return args.Aggregate((x, y) => x * y);
79    }
80
81    private static double Division(IEnumerable<double> args) {
82      if (args.Count() == 1)
83        return 1 / args.First();
84
85      return args.Aggregate((x, y) => x / y);
86    }
87
88    private static double Subtraction(IEnumerable<double> args) {
89      if (args.Count() == 1)
90        return -args.First();
91
92      return args.Aggregate((x, y) => x - y);
93    }
94
95    private static double Exp(IEnumerable<double> args) {
96      return Math.Exp(args.Single());
97    }
98
99    private static double Log(IEnumerable<double> args) {
100      return Math.Log(args.Single());
101    }
102
103    private static double Square(IEnumerable<double> args) {
104      var v = args.Single();
105      return v * v;
106    }
107    #endregion
108  }
109}
Note: See TracBrowser for help on using the repository browser.