Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/15/17 08:44:15 (7 years ago)
Author:
gkronber
Message:

#2704: added possibility to automatically adjust constants based on the distributions of evaluated expressions to allow limiting distributions for arguments of functions (e.g. log should have positive args only, exp should have rather small args only)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.ExpressionGenerator/HeuristicLab.ExpressionGenerator/3.4/ExpressionTemplate.cs

    r14485 r14873  
    2323using System.Collections.Generic;
    2424using System.Linq;
     25using HeuristicLab.Common;
    2526using HeuristicLab.Core;
    2627using HeuristicLab.Random;
     
    2829namespace HeuristicLab.ExpressionGenerator {
    2930  public abstract class ExpressionTemplate {
    30     private List<Tuple<Expression, double>> arguments;
    31     private readonly Func<IEnumerable<double>, double> transform;
     31    protected List<Tuple<Expression, double>> arguments;
     32    protected readonly Func<IEnumerable<double>, double> transform;
    3233    public string Label { get; set; }
    3334
    3435    protected Expression Instantiate(string name, IRandom random, int n, bool sampleWithRepetition = false) {
     36      var func = Expression.Function(name, transform, SampleArguments(random, n, sampleWithRepetition));
     37      func.Label = Label;
     38      return func;
     39    }
     40
     41    protected IEnumerable<Expression> SampleArguments(IRandom random, int n, bool sampleWithRepetition = false) {
    3542      var weights = arguments.Select(x => x.Item2);
    3643      var args = sampleWithRepetition
    3744       ? arguments.SampleProportional(random, n, weights).Select(x => x.Item1)
    3845       : arguments.SampleProportionalWithoutRepetition(random, n, weights).Select(x => x.Item1);
    39       var func = Expression.Function(name, transform, args);
    40       func.Label = Label;
    41       return func;
     46      return args;
    4247    }
    4348
     
    5863    }
    5964
    60     public void AddArguments(IEnumerable<Expression> expressions, IEnumerable<double> weights) { 
     65    public void AddArguments(IEnumerable<Expression> expressions, IEnumerable<double> weights) {
    6166      arguments = arguments ?? new List<Tuple<Expression, double>>();
    6267      arguments.AddRange(expressions.Zip(weights, Tuple.Create));
     
    8792    }
    8893  }
     94
     95  public class ScalingTemplate : ExpressionTemplate {
     96    private readonly IRandom scaledVariance;
     97    // w * expr
     98    public ScalingTemplate(IRandom scaledVariance = null) : base(ExpressionGenerator.Product) {
     99      this.scaledVariance = scaledVariance;
     100    }
     101
     102    public override Expression Instantiate(string name, IRandom random, bool sampleWithRepetition = false) {
     103      var expr = SampleArguments(random, 1, sampleWithRepetition).First();
     104
     105      // use the evaluator to determine variance of the sampled expression and initialize the constant accordingly to reach the target variance
     106      var @const = 1.0;
     107      if (scaledVariance != null) {
     108        var evaluator = new ExpressionEvaluator();
     109        var data = evaluator.GenerateData(expr, 10000);
     110        var variance = data[expr].VariancePop();
     111        @const = scaledVariance.NextDouble() / variance;
     112      }
     113
     114      var func = Expression.Function(name, transform, new Expression[] { Expression.Constant(name, @const), expr });
     115      func.Label = "*";
     116      return func;
     117    }
     118  }
     119
     120  public class OffsetTemplate : ExpressionTemplate {
     121    private readonly IRandom offset;
     122    // expr + offset
     123    public OffsetTemplate(IRandom offset = null) : base(ExpressionGenerator.Sum) {
     124      this.offset = offset;
     125    }
     126
     127    public override Expression Instantiate(string name, IRandom random, bool sampleWithRepetition = false) {
     128      var expr = SampleArguments(random, 1, sampleWithRepetition).First();
     129
     130      // use the evaluator to determine variance of the sampled expression and initialize the constant accordingly to reach the target offset
     131      var @const = 0.0;
     132      if (offset != null) {
     133        var evaluator = new ExpressionEvaluator();
     134        var data = evaluator.GenerateData(expr, 10000);
     135        var average = data[expr].Average();
     136        @const = offset.NextDouble() - average;
     137      }
     138
     139      var func = Expression.Function(name, transform, new Expression[] { Expression.Constant(name, @const), expr });
     140      func.Label = "+";
     141      return func;
     142    }
     143  }
     144
     145  public class RangeTemplate : ExpressionTemplate {
     146    private readonly IRandom minValue;
     147    private readonly IRandom valueRange;
     148    // expr + offset
     149    public RangeTemplate(IRandom minValue = null, IRandom valueRange = null) : base(null) {
     150      this.minValue = minValue;
     151      this.valueRange = valueRange;
     152    }
     153
     154    public override Expression Instantiate(string name, IRandom random, bool sampleWithRepetition = false) {
     155      var expr = SampleArguments(random, 1, sampleWithRepetition).First();
     156
     157      // use the evaluator to determine variance of the sampled expression and initialize the constant accordingly to reach the target offset
     158      var mult = 1.0;
     159      var add = 0.0;
     160
     161      if (minValue != null || valueRange != null) {
     162        var evaluator = new ExpressionEvaluator();
     163        var data = evaluator.GenerateData(expr, 10000);
     164        if (valueRange != null) {
     165          var targetRange = valueRange.NextDouble();
     166          var min = data[expr].Min();
     167          var max = data[expr].Max();
     168          var range = max - min;
     169          mult = targetRange / range;
     170          add = -min + min / mult;
     171        }
     172        if (minValue != null) {
     173          var targetMin = minValue.NextDouble();
     174          var min = data[expr].Min();
     175          add += (targetMin - min) / mult;
     176        }
     177
     178        expr = Expression.Function(name + "-toZero", ExpressionGenerator.Sum, new Expression[] { Expression.Constant("name-add0", add), expr });
     179        expr.Label = "+";
     180        expr = Expression.Function(name + "-mult", ExpressionGenerator.Product, new Expression[] { Expression.Constant("name-mult", mult), expr });
     181        expr.Label = "*";
     182      }
     183
     184      return expr;
     185    }
     186  }
    89187}
Note: See TracChangeset for help on using the changeset viewer.