Free cookie consent management tool by TermsFeed Policy Generator

Changeset 3294


Ignore:
Timestamp:
04/09/10 17:28:32 (14 years ago)
Author:
gkronber
Message:

Added first version of architecture altering operators for ADFs. #290 (Implement ADFs)

Location:
trunk/sources
Files:
29 added
1 deleted
42 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab 3.3.sln

    r3272 r3294  
    238238EndProject
    239239Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Regression-3.3", "HeuristicLab.Problems.DataAnalysis.Regression\3.3\HeuristicLab.Problems.DataAnalysis.Regression-3.3.csproj", "{BDF86B1D-630E-4CE2-8A49-8C90B1BDE4C9}"
     240EndProject
     241Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.Tests", "HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.3\Tests\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.Tests.csproj", "{8824925E-3E00-4543-8293-7DDACE4737F8}"
    240242EndProject
    241243Global
     
    13351337    {BDF86B1D-630E-4CE2-8A49-8C90B1BDE4C9}.Services|x64.ActiveCfg = Release|x64
    13361338    {BDF86B1D-630E-4CE2-8A49-8C90B1BDE4C9}.Services|x86.ActiveCfg = Release|x86
     1339    {8824925E-3E00-4543-8293-7DDACE4737F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
     1340    {8824925E-3E00-4543-8293-7DDACE4737F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
     1341    {8824925E-3E00-4543-8293-7DDACE4737F8}.Debug|x64.ActiveCfg = Debug|Any CPU
     1342    {8824925E-3E00-4543-8293-7DDACE4737F8}.Debug|x86.ActiveCfg = Debug|Any CPU
     1343    {8824925E-3E00-4543-8293-7DDACE4737F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
     1344    {8824925E-3E00-4543-8293-7DDACE4737F8}.Release|Any CPU.Build.0 = Release|Any CPU
     1345    {8824925E-3E00-4543-8293-7DDACE4737F8}.Release|x64.ActiveCfg = Release|Any CPU
     1346    {8824925E-3E00-4543-8293-7DDACE4737F8}.Release|x86.ActiveCfg = Release|Any CPU
     1347    {8824925E-3E00-4543-8293-7DDACE4737F8}.Services|Any CPU.ActiveCfg = Release|Any CPU
     1348    {8824925E-3E00-4543-8293-7DDACE4737F8}.Services|Any CPU.Build.0 = Release|Any CPU
     1349    {8824925E-3E00-4543-8293-7DDACE4737F8}.Services|x64.ActiveCfg = Release|Any CPU
     1350    {8824925E-3E00-4543-8293-7DDACE4737F8}.Services|x86.ActiveCfg = Release|Any CPU
    13371351  EndGlobalSection
    13381352  GlobalSection(SolutionProperties) = preSolution
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.3/GraphicalSymbolicExpressionTreeView.cs

    r3244 r3294  
    3131using HeuristicLab.MainForm;
    3232using HeuristicLab.MainForm.WindowsForms;
     33using HeuristicLab.Core.Views;
    3334
    3435namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views {
    3536  [View("Graphical SymbolicExpressionTree View")]
    3637  [Content(typeof(SymbolicExpressionTree), true)]
    37   public partial class GraphicalSymbolicExpressionTreeView : AsynchronousContentView {
     38  public partial class GraphicalSymbolicExpressionTreeView : ItemView {
    3839    public new SymbolicExpressionTree Content {
    3940      get { return (SymbolicExpressionTree)base.Content; }
     
    6061      }
    6162    }
    62    
    63     //private VisualFunctionTreeModel visualModel;
    64     //public VisualFunctionTreeModel VisualModel {
    65     //  get { return this.visualModel; }
    66     //  private set {
    67     //    if (value != this.visualModel) {
    68     //      if (this.visualModel != null)
    69     //        this.visualModel.Changed -= new EventHandler(model_Changed);
    70 
    71     //      if (value == null) {
    72     //        this.Caption = "Formula tree";
    73     //        this.functionTreeChart.FunctionTree = null;
    74     //      } else {
    75     //        value.Changed += new EventHandler(model_Changed);
    76     //        this.functionTreeChart.FunctionTree = value.FunctionTree;
    77     //        this.Caption = value.ModelName + " formula tree";
    78     //      }
    79     //      this.visualModel = value;
    80     //    }
    81     //  }
    82     //}
    83 
    84     private void functionTreeChart_FunctionTreeClicked(object sender, MouseEventArgs e) {
    85       VisualSymbolicExpressionTreeNode visualFunctionTreeNode = (VisualSymbolicExpressionTreeNode)sender;
    86       visualFunctionTreeNode.LineColor = Color.Red;
    87       this.symbolicExpressionTreeChart.Repaint();
    88     }
    89 
    90     private void functionTreeChart_FunctionTreeDoubleClicked(object sender, MouseEventArgs e) {
    91       VisualSymbolicExpressionTreeNode visualFunctionTreeNode = (VisualSymbolicExpressionTreeNode)sender;
    92       visualFunctionTreeNode.FillColor = Color.Blue;
    93       this.symbolicExpressionTreeChart.Repaint();
    94     }
    9563  }
    9664}
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.3.csproj

    r3244 r3294  
    8989    </Compile>
    9090    <Compile Include="HeuristicLabEncodingsSymbolicExpressionTreeEncodingViewsPlugin.cs" />
     91    <Compile Include="PropertiesView.cs">
     92      <SubType>UserControl</SubType>
     93    </Compile>
     94    <Compile Include="PropertiesView.Designer.cs">
     95      <DependentUpon>PropertiesView.cs</DependentUpon>
     96    </Compile>
    9197    <Compile Include="Properties\AssemblyInfo.cs" />
    9298    <Compile Include="Properties\Resources.Designer.cs">
     
    110116  </ItemGroup>
    111117  <ItemGroup>
     118    <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
     119      <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
     120      <Name>HeuristicLab.Core.Views-3.3</Name>
     121    </ProjectReference>
    112122    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
    113123      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
     
    140150      <DependentUpon>GraphicalSymbolicExpressionTreeView.cs</DependentUpon>
    141151    </EmbeddedResource>
     152    <EmbeddedResource Include="PropertiesView.resx">
     153      <DependentUpon>PropertiesView.cs</DependentUpon>
     154    </EmbeddedResource>
    142155    <EmbeddedResource Include="Properties\Resources.resx">
    143156      <Generator>ResXFileCodeGenerator</Generator>
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.3/SymbolicExpressionTreeChart.cs

    r3244 r3294  
    3030
    3131namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views {
    32   public partial class SymbolicExpressionTreeChart : UserControl {
     32  public sealed partial class SymbolicExpressionTreeChart : UserControl {
    3333    private StringFormat stringFormat;
    3434    private Dictionary<SymbolicExpressionTreeNode, VisualSymbolicExpressionTreeNode> visualTreeNodes;
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Creators/ProbabilisticTreeCreator.cs

    r3270 r3294  
    3737
    3838    protected override SymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight) {
    39       return Apply(random, grammar, maxTreeSize.Value, maxTreeHeight.Value);
     39      return Create(random, grammar, maxTreeSize.Value, maxTreeHeight.Value);
    4040    }
    4141
    42     public SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeSize, int maxTreeHeight) {
     42    public static SymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeSize, int maxTreeHeight) {
    4343      // tree size is limited by the grammar and by the explicit size constraints
    44       int allowedMinSize = grammar.MinimalExpressionLength(grammar.StartSymbol);
    45       int allowedMaxSize = Math.Min(maxTreeSize, grammar.MaximalExpressionLength(grammar.StartSymbol));
     44      int allowedMinSize = grammar.GetMinExpressionLength(grammar.StartSymbol);
     45      int allowedMaxSize = Math.Min(maxTreeSize, grammar.GetMaxExpressionLength(grammar.StartSymbol));
    4646      // select a target tree size uniformly in the possible range (as determined by explicit limits and limits of the grammar)
    4747      int treeSize = random.Next(allowedMinSize, allowedMaxSize);
     
    4949      do {
    5050        try {
    51           tree.Root = PTC2(random, grammar, grammar.StartSymbol, treeSize + 1, maxTreeHeight + 1);
     51          tree.Root = grammar.ProgramRootSymbol.CreateTreeNode();
     52          tree.Root.AddSubTree(PTC2(random, grammar, grammar.StartSymbol, treeSize + 1, maxTreeHeight + 1));
    5253        }
    5354        catch (ArgumentException) {
     
    5556          treeSize = random.Next(allowedMinSize, allowedMaxSize);
    5657        }
    57       } while (tree.Root == null || tree.Size > maxTreeSize || tree.Height > maxTreeHeight);
     58      } while (tree.Root.SubTrees.Count == 0 || tree.Size > maxTreeSize || tree.Height > maxTreeHeight);
     59      System.Diagnostics.Debug.Assert(grammar.IsValidExpression(tree));
    5860      return tree;
    5961    }
    6062
    61     private Symbol SelectRandomSymbol(IRandom random, IEnumerable<Symbol> symbols) {
     63    private static Symbol SelectRandomSymbol(IRandom random, IEnumerable<Symbol> symbols) {
    6264      var symbolList = symbols.ToList();
    63       var ticketsSum = symbolList.Select(x => x.Tickets.Value).Sum();
     65      var ticketsSum = symbolList.Select(x => x.InitialFrequency).Sum();
    6466      var r = random.NextDouble() * ticketsSum;
    6567      double aggregatedTickets = 0;
    6668      for (int i = 0; i < symbolList.Count; i++) {
    67         aggregatedTickets += symbolList[i].Tickets.Value;
     69        aggregatedTickets += symbolList[i].InitialFrequency;
    6870        if (aggregatedTickets >= r) {
    6971          return symbolList[i];
     
    7577
    7678
    77     private SymbolicExpressionTreeNode PTC2(IRandom random, ISymbolicExpressionGrammar grammar, Symbol rootSymbol, int size, int maxDepth) {
     79    public static SymbolicExpressionTreeNode PTC2(IRandom random, ISymbolicExpressionGrammar grammar, Symbol rootSymbol, int size, int maxDepth) {
    7880      SymbolicExpressionTreeNode root = rootSymbol.CreateTreeNode();
    7981      if (size <= 1 || maxDepth <= 1) return root;
    80       List<object[]> list = new List<object[]>();
     82      List<object[]> extensionPoints = new List<object[]>();
    8183      int currentSize = 1;
    82       int totalListMinSize = grammar.MinimalExpressionLength(rootSymbol) - 1;
     84      int totalListMinSize = grammar.GetMinExpressionLength(rootSymbol) - 1;
    8385
    8486      int actualArity = SampleArity(random, grammar, rootSymbol, size);
     
    8688        // insert a dummy sub-tree and add the pending extension to the list
    8789        root.AddSubTree(null);
    88         list.Add(new object[] { root, i, 2 });
     90        extensionPoints.Add(new object[] { root, i, 2 });
    8991      }
    9092
    9193      // while there are pending extension points and we have not reached the limit of adding new extension points
    92       while (list.Count > 0 && totalListMinSize + currentSize < size) {
    93         int randomIndex = random.Next(list.Count);
    94         object[] nextExtension = list[randomIndex];
    95         list.RemoveAt(randomIndex);
     94      while (extensionPoints.Count > 0 && totalListMinSize + currentSize < size) {
     95        int randomIndex = random.Next(extensionPoints.Count);
     96        object[] nextExtension = extensionPoints[randomIndex];
     97        extensionPoints.RemoveAt(randomIndex);
    9698        SymbolicExpressionTreeNode parent = (SymbolicExpressionTreeNode)nextExtension[0];
    9799        int argumentIndex = (int)nextExtension[1];
    98100        int extensionDepth = (int)nextExtension[2];
    99         if (extensionDepth + grammar.MinimalExpressionDepth(parent.Symbol) >= maxDepth) {
     101        if (extensionDepth + grammar.GetMinExpressionDepth(parent.Symbol) >= maxDepth) {
    100102          parent.RemoveSubTree(argumentIndex);
    101           SymbolicExpressionTreeNode branch = CreateMinimalTree(random, grammar, grammar.AllowedSymbols(parent.Symbol, argumentIndex));
     103          SymbolicExpressionTreeNode branch = CreateMinimalTree(random, grammar, grammar.GetAllowedSymbols(parent.Symbol, argumentIndex));
    102104          parent.InsertSubTree(argumentIndex, branch); // insert a smallest possible tree
    103105          currentSize += branch.GetSize();
    104106          totalListMinSize -= branch.GetSize();
    105107        } else {
    106           var allowedSubFunctions = from s in grammar.AllowedSymbols(parent.Symbol, argumentIndex)
    107                                     where grammar.MinimalExpressionDepth(parent.Symbol) + extensionDepth - 1 < maxDepth
    108                                     where grammar.MaximalExpressionLength(s) > size - totalListMinSize - currentSize ||
     108          var allowedSubFunctions = from s in grammar.GetAllowedSymbols(parent.Symbol, argumentIndex)
     109                                    where grammar.GetMinExpressionDepth(parent.Symbol) + extensionDepth - 1 < maxDepth
     110                                    where grammar.GetMaxExpressionLength(s) > size - totalListMinSize - currentSize ||
    109111                                          totalListMinSize + currentSize >= size * 0.9 // if the necessary size is almost reached then also allow
    110112                                    // terminals or terminal-branches
     
    121123            // insert a dummy sub-tree and add the pending extension to the list
    122124            newTree.AddSubTree(null);
    123             list.Add(new object[] { newTree, i, extensionDepth + 1 });
     125            extensionPoints.Add(new object[] { newTree, i, extensionDepth + 1 });
    124126          }
    125           totalListMinSize += grammar.MinimalExpressionLength(selectedSymbol);
     127          totalListMinSize += grammar.GetMinExpressionLength(selectedSymbol);
    126128        }
    127129      }
    128130      // fill all pending extension points
    129       while (list.Count > 0) {
    130         int randomIndex = random.Next(list.Count);
    131         object[] nextExtension = list[randomIndex];
    132         list.RemoveAt(randomIndex);
     131      while (extensionPoints.Count > 0) {
     132        int randomIndex = random.Next(extensionPoints.Count);
     133        object[] nextExtension = extensionPoints[randomIndex];
     134        extensionPoints.RemoveAt(randomIndex);
    133135        SymbolicExpressionTreeNode parent = (SymbolicExpressionTreeNode)nextExtension[0];
    134136        int a = (int)nextExtension[1];
     
    136138        parent.RemoveSubTree(a);
    137139        parent.InsertSubTree(a,
    138           CreateMinimalTree(random, grammar, grammar.AllowedSymbols(parent.Symbol, a))); // append a tree with minimal possible height
     140          CreateMinimalTree(random, grammar, grammar.GetAllowedSymbols(parent.Symbol, a))); // append a tree with minimal possible height
    139141      }
    140142      return root;
    141143    }
    142144
    143     private int SampleArity(IRandom random, ISymbolicExpressionGrammar grammar, Symbol symbol, int targetSize) {
     145    private static int SampleArity(IRandom random, ISymbolicExpressionGrammar grammar, Symbol symbol, int targetSize) {
    144146      // select actualArity randomly with the constraint that the sub-trees in the minimal arity can become large enough
    145       int minArity = grammar.MinSubTrees(symbol);
    146       int maxArity = grammar.MaxSubTrees(symbol);
     147      int minArity = grammar.GetMinSubTreeCount(symbol);
     148      int maxArity = grammar.GetMaxSubTreeCount(symbol);
    147149      if (maxArity > targetSize) {
    148150        maxArity = targetSize;
     
    152154      long aggregatedLongestExpressionLength = 0;
    153155      for (int i = 0; i < maxArity; i++) {
    154         aggregatedLongestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i)
    155                                               select grammar.MaximalExpressionLength(s)).Max();
     156        aggregatedLongestExpressionLength += (from s in grammar.GetAllowedSymbols(symbol, i)
     157                                              select grammar.GetMaxExpressionLength(s)).Max();
    156158        if (aggregatedLongestExpressionLength < targetSize) minArity = i;
    157159        else break;
     
    162164      long aggregatedShortestExpressionLength = 0;
    163165      for (int i = 0; i < maxArity; i++) {
    164         aggregatedShortestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i)
    165                                                select grammar.MinimalExpressionLength(s)).Min();
     166        aggregatedShortestExpressionLength += (from s in grammar.GetAllowedSymbols(symbol, i)
     167                                               select grammar.GetMinExpressionLength(s)).Min();
    166168        if (aggregatedShortestExpressionLength > targetSize) {
    167169          maxArity = i;
     
    173175    }
    174176
    175     private SymbolicExpressionTreeNode CreateMinimalTree(IRandom random, ISymbolicExpressionGrammar grammar, IEnumerable<Symbol> symbols) {
     177    private static SymbolicExpressionTreeNode CreateMinimalTree(IRandom random, ISymbolicExpressionGrammar grammar, IEnumerable<Symbol> symbols) {
    176178      // determine possible symbols that will lead to the smallest possible tree
    177179      var possibleSymbols = (from s in symbols
    178                              group s by grammar.MinimalExpressionLength(s) into g
     180                             group s by grammar.GetMinExpressionLength(s) into g
    179181                             orderby g.Key
    180182                             select g).First();
     
    182184      // build minimal tree by recursive application
    183185      var tree = selectedSymbol.CreateTreeNode();
    184       for (int i = 0; i < grammar.MinSubTrees(selectedSymbol); i++)
    185         tree.AddSubTree(CreateMinimalTree(random, grammar, grammar.AllowedSymbols(selectedSymbol, i)));
     186      for (int i = 0; i < grammar.GetMinSubTreeCount(selectedSymbol); i++)
     187        tree.AddSubTree(CreateMinimalTree(random, grammar, grammar.GetAllowedSymbols(selectedSymbol, i)));
    186188      return tree;
    187189    }
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/SubtreeCrossover.cs

    r3237 r3294  
    2727using System;
    2828using HeuristicLab.Parameters;
     29using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols;
    2930namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
    3031
     
    3940  [StorableClass]
    4041  public class SubtreeCrossover : SymbolicExpressionTreeCrossover {
    41     private const int MAX_TRIES = 100;
    42 
    4342    public IValueLookupParameter<PercentValue> InternalCrossoverPointProbabilityParameter {
    4443      get { return (IValueLookupParameter<PercentValue>)Parameters["InternalCrossoverPointProbability"]; }
     
    5251    protected override SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar,
    5352      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
    54       IntValue maxTreeSize, IntValue maxTreeHeight) {
    55       return Apply(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value);
     53      IntValue maxTreeSize, IntValue maxTreeHeight, out bool success) {
     54      return Cross(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value, out success);
    5655    }
    5756
    58     public static SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar,
     57    public static SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar,
    5958      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
    60       double internalCrossoverPointProbability, int maxTreeSize, int maxTreeHeight) {
    61       int tries = 0;
    62       while (tries++ < MAX_TRIES) {
    63         // select a random crossover point in the first parent
    64         SymbolicExpressionTreeNode crossoverPoint0;
    65         int replacedSubtreeIndex;
    66         SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, out crossoverPoint0, out replacedSubtreeIndex);
     59      double internalCrossoverPointProbability, int maxTreeSize, int maxTreeHeight, out bool success) {
     60      // select a random crossover point in the first parent
     61      SymbolicExpressionTreeNode crossoverPoint0;
     62      int replacedSubtreeIndex;
     63      SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, out crossoverPoint0, out replacedSubtreeIndex);
    6764
    68         // calculate the max size and height that the inserted branch can have
    69         int maxInsertedBranchSize = maxTreeSize - (parent0.Size - crossoverPoint0.SubTrees[replacedSubtreeIndex].GetSize());
    70         int maxInsertedBranchHeight = maxTreeHeight - GetBranchLevel(parent0.Root, crossoverPoint0);
     65      // calculate the max size and height that the inserted branch can have
     66      int maxInsertedBranchSize = maxTreeSize - (parent0.Size - crossoverPoint0.SubTrees[replacedSubtreeIndex].GetSize());
     67      int maxInsertedBranchHeight = maxTreeHeight - GetBranchLevel(parent0.Root, crossoverPoint0);
    7168
    72         var allowedBranches = from branch in IterateNodes(parent1.Root)
    73                               where branch.GetSize() < maxInsertedBranchSize
    74                               where branch.GetHeight() < maxInsertedBranchHeight
    75                               where grammar.AllowedSymbols(crossoverPoint0.Symbol, replacedSubtreeIndex).Contains(branch.Symbol)
    76                               select branch;
     69      var allowedBranches = from branch in IterateNodes(parent1.Root)
     70                            where branch.GetSize() < maxInsertedBranchSize
     71                            where branch.GetHeight() < maxInsertedBranchHeight
     72                            where grammar.GetAllowedSymbols(crossoverPoint0.Symbol, replacedSubtreeIndex).Contains(branch.Symbol)
     73                            where IsMatchingPointType(parent0, crossoverPoint0, branch)
     74                            select branch;
    7775
    78         if (allowedBranches.Count() > 0) {
    79           var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability);
     76      if (allowedBranches.Count() > 0) {
     77        var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability);
    8078
    81           // manipulate the tree of parent0 in place
    82           // replace the branch in tree0 with the selected branch from tree1
    83           crossoverPoint0.RemoveSubTree(replacedSubtreeIndex);
    84           crossoverPoint0.InsertSubTree(replacedSubtreeIndex, selectedBranch);
    85           return parent0;
    86         }
     79        // manipulate the tree of parent0 in place
     80        // replace the branch in tree0 with the selected branch from tree1
     81        crossoverPoint0.RemoveSubTree(replacedSubtreeIndex);
     82        crossoverPoint0.InsertSubTree(replacedSubtreeIndex, selectedBranch);
     83        success = true;
     84        return parent0;
    8785      }
    8886
    89       // TODO: we should have a way to track the number of failed crossover attempts
    90       // for now just return the first parent unchanged
     87      success = false;
    9188      return parent0;
     89    }
     90
     91    private static bool IsMatchingPointType(SymbolicExpressionTree tree, SymbolicExpressionTreeNode parent, SymbolicExpressionTreeNode newBranch) {
     92      var functionCalls = (from node in IterateNodes(newBranch)
     93                           let invokeNode = node as InvokeFunctionTreeNode
     94                           let argNode = node as ArgumentTreeNode
     95                           where invokeNode != null || argNode != null
     96                           let name = invokeNode != null ? invokeNode.InvokedFunctionName : "ARG" + argNode.ArgumentIndex
     97                           let argCount = invokeNode != null ? invokeNode.SubTrees.Count : 0
     98                           select new { FunctionName = name, FunctionArgumentCount = argCount }).Distinct();
     99      var definingBranch = GetDefiningBranch(tree, parent);
     100      if (definingBranch == null) return false;
     101      foreach (var functionCall in functionCalls) {
     102        if (!definingBranch.DynamicSymbols.Contains(functionCall.FunctionName) ||
     103          definingBranch.GetDynamicSymbolArgumentCount(functionCall.FunctionName) != functionCall.FunctionArgumentCount)
     104          return false;
     105      }
     106      return true;
     107    }
     108
     109    private static SymbolicExpressionTreeNode GetDefiningBranch(SymbolicExpressionTree tree, SymbolicExpressionTreeNode parent) {
     110      foreach (var treeNode in tree.Root.SubTrees) {
     111        if (IterateNodes(treeNode).Contains(parent)) return treeNode;
     112      }
     113      return null;
    92114    }
    93115
     
    95117      var crossoverPoints = from branch in IterateNodes(parent0.Root)
    96118                            where branch.SubTrees.Count > 0
     119                            where !(branch.Symbol is ProgramRootSymbol)
    97120                            from index in Enumerable.Range(0, branch.SubTrees.Count)
    98121                            let p = new { CrossoverPoint = branch, SubtreeIndex = index, IsLeaf = branch.SubTrees[index].SubTrees.Count == 0 }
     
    101124                                     where !p.IsLeaf
    102125                                     select p).ToList();
    103       // select internal crossover point or leaf
    104       if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) {
     126      var leafCrossoverPoints = (from p in crossoverPoints
     127                                 where p.IsLeaf
     128                                 select p).ToList();
     129      if (internalCrossoverPoints.Count == 0) {
     130        var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
     131        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
     132        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
     133      } else if (leafCrossoverPoints.Count == 0) {
     134        var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
     135        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
     136        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
     137      } else if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) {
     138        // select internal crossover point or leaf
    105139        var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
    106140        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
    107141        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
    108142      } else {
    109         var leafCrossoverPoints = (from p in crossoverPoints
    110                                    where p.IsLeaf
    111                                    select p).ToList();
    112143        var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
    113144        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
     
    125156                                     from branch in g
    126157                                     select branch).ToList();
    127       if (random.NextDouble() < internalNodeProbability && allowedInternalBranches.Count > 0) {
     158      var allowedLeafBranches = (from g in groupedBranches
     159                                 where g.Key == 0
     160                                 from leaf in g
     161                                 select leaf).ToList();
     162      if (allowedInternalBranches.Count == 0) {
     163        return allowedLeafBranches[random.Next(allowedLeafBranches.Count)];
     164      } else if (allowedLeafBranches.Count == 0) {
     165        return allowedInternalBranches[random.Next(allowedInternalBranches.Count)];
     166      } else if (random.NextDouble() < internalNodeProbability) {
     167        // when leaf and internal nodes are possible then choose either a leaf or internal node with internalNodeProbability
    128168        return allowedInternalBranches[random.Next(allowedInternalBranches.Count)];
    129169      } else {
    130         var allowedLeafBranches = (from g in groupedBranches
    131                                    where g.Key == 0
    132                                    from leaf in g
    133                                    select leaf).ToList();
    134170        return allowedLeafBranches[random.Next(allowedLeafBranches.Count)];
    135171      }
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.csproj

    r3256 r3294  
    8383  </ItemGroup>
    8484  <ItemGroup>
     85    <Compile Include="ArchitectureAlteringOperators\ArgumentDuplicater.cs" />
     86    <Compile Include="ArchitectureAlteringOperators\ArgumentCreater.cs" />
     87    <Compile Include="ArchitectureAlteringOperators\ArgumentDeleter.cs" />
     88    <Compile Include="ArchitectureAlteringOperators\RandomArchitectureAlteringOperator.cs" />
     89    <Compile Include="ArchitectureAlteringOperators\SubroutineDeleter.cs" />
     90    <Compile Include="ArchitectureAlteringOperators\SubroutineCreater.cs">
     91      <SubType>Code</SubType>
     92    </Compile>
     93    <Compile Include="ArchitectureAlteringOperators\SubroutineDuplicater.cs">
     94      <SubType>Code</SubType>
     95    </Compile>
     96    <Compile Include="DefaultSymbolicExpressionGrammar.cs">
     97      <SubType>Code</SubType>
     98    </Compile>
     99    <Compile Include="SymbolicExpressionTreeArchitectureAlteringOperator.cs" />
     100    <Compile Include="SymbolicExpressionTreeOperator.cs" />
     101    <Compile Include="Instruction.cs" />
     102    <Compile Include="SymbolicExpressionTreeCompiler.cs" />
     103    <Compile Include="SymbolicExpressionTreeManipulator.cs" />
    85104    <Compile Include="SymbolicExpressionTreeTerminalNode.cs" />
    86105    <Compile Include="Crossovers\SubtreeCrossover.cs" />
     
    89108    <Compile Include="HeuristicLabEncodingsSymbolicExpressionTreeEncodingPlugin.cs" />
    90109    <Compile Include="Interfaces\ISymbolicExpressionTreeOperator.cs" />
    91     <Compile Include="SymbolicExpressionGrammar.cs" />
    92110    <Compile Include="SymbolicExpressionTreeCreator.cs" />
    93111    <Compile Include="SymbolicExpressionTree.cs" />
     
    97115    <Compile Include="SymbolicExpressionTreeNode.cs" />
    98116    <Compile Include="Symbols\Addition.cs" />
    99     <Compile Include="Symbols\Prog.cs" />
    100     <Compile Include="GeneralSymbolicExpressionTreeEvaluator.cs" />
     117    <Compile Include="Symbols\Argument.cs" />
     118    <Compile Include="Symbols\ArgumentTreeNode.cs" />
    101119    <Compile Include="Symbols\StartSymbol.cs" />
     120    <Compile Include="Symbols\InvokeFunction.cs" />
     121    <Compile Include="Symbols\InvokeFunctionTreeNode.cs" />
     122    <Compile Include="Symbols\DefunTreeNode.cs" />
     123    <Compile Include="Symbols\Defun.cs" />
     124    <Compile Include="Symbols\ProgramRootSymbol.cs" />
    102125    <Compile Include="Symbols\Division.cs" />
    103126    <Compile Include="Symbols\Multiplication.cs" />
    104127    <Compile Include="Symbols\Subtraction.cs" />
     128    <Compile Include="Symbols\Values.cs">
     129      <SubType>Code</SubType>
     130    </Compile>
     131    <Compile Include="Symbols\ValuesTreeNode.cs">
     132      <SubType>Code</SubType>
     133    </Compile>
    105134  </ItemGroup>
    106135  <ItemGroup>
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Interfaces/ISymbolicExpressionGrammar.cs

    r3237 r3294  
    3131  public interface ISymbolicExpressionGrammar : IItem {
    3232    Symbol StartSymbol { get; }
    33     // IEnumerable<Symbol> Symbols { get; }
    34 
    35     // void AddSymbol(Symbol symbol);
    36     // void RemoveSymbol(Symbol symbol);
    37 
    38     IEnumerable<Symbol> AllowedSymbols(Symbol parent, int argumentIndex);
    39     int MinimalExpressionLength(Symbol start);
    40     int MaximalExpressionLength(Symbol start);
    41     int MinimalExpressionDepth(Symbol start);
    42     int MinSubTrees(Symbol start);
    43     int MaxSubTrees(Symbol start);
     33    Symbol ProgramRootSymbol { get; }
     34    IEnumerable<Symbol> GetAllowedSymbols(Symbol parent, int argumentIndex);
     35    int GetMinExpressionLength(Symbol start);
     36    int GetMaxExpressionLength(Symbol start);
     37    int GetMinExpressionDepth(Symbol start);
     38    int GetMinSubTreeCount(Symbol start);
     39    int GetMaxSubTreeCount(Symbol start);
    4440
    4541    bool IsValidExpression(SymbolicExpressionTree expression);
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Symbol.cs

    r3269 r3294  
    3232  [StorableClass]
    3333  [Item("Symbol", "Represents a symbol in a symbolic function tree.")]
    34   public abstract class Symbol : ParameterizedNamedItem {
    35     #region Parameter Properties
    36     public IValueParameter<DoubleValue> TicketsParameter {
    37       get { return (IValueParameter<DoubleValue>)Parameters["Tickets"]; }
    38     }
    39     #endregion
    40 
     34  public abstract class Symbol : NamedItem {
    4135    #region Properties
    42     public DoubleValue Tickets {
    43       get { return TicketsParameter.Value; }
     36    private double initialFrequency;
     37    public double InitialFrequency {
     38      get { return initialFrequency; }
    4439      set {
    45         if (value.Value < 0.0) throw new ArgumentException("Number of tickets must be positive");
    46         TicketsParameter.Value = value;
     40        if (value < 0.0) throw new ArgumentException("InitialFrequency must be positive");
     41        initialFrequency = value;
    4742      }
    4843    }
     
    5146    protected Symbol()
    5247      : base() {
    53       Parameters.Add(new ValueParameter<DoubleValue>("Tickets", new DoubleValue(1.0)));
     48      this.name = ItemName;
     49      this.description = ItemDescription;
     50      initialFrequency = 1.0;
    5451    }
    5552
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTree.cs

    r3252 r3294  
    3232  [StorableClass]
    3333  [Item("SymbolicExpressionTree", "Represents a symbolic expression tree.")]
    34   public class SymbolicExpressionTree : Item {   
     34  public class SymbolicExpressionTree : Item {
    3535    [Storable]
    3636    private SymbolicExpressionTreeNode root;
     
    4646    }
    4747
     48    public SymbolicExpressionTreeNode ResultProducingExpression {
     49      get { return root.SubTrees[0].SubTrees[0]; }
     50    }
     51
     52    [Storable]
     53    private Dictionary<int, IEnumerable<string>> allowedFunctionsInBranch;
     54
    4855    public int Size {
    4956      get {
     
    5865    }
    5966
    60     public SymbolicExpressionTree() : base() { }
     67    public SymbolicExpressionTree()
     68      : base() {
     69      allowedFunctionsInBranch = new Dictionary<int, IEnumerable<string>>();
     70    }
    6171
    62     public SymbolicExpressionTree(SymbolicExpressionTreeNode root) : base() { }
     72    public SymbolicExpressionTree(SymbolicExpressionTreeNode root)
     73      : base() {
     74      allowedFunctionsInBranch = new Dictionary<int, IEnumerable<string>>();
     75    }
    6376
    6477    public IEnumerable<SymbolicExpressionTreeNode> IterateNodesPrefix() {
     
    87100      cloner.RegisterClonedObject(this, clone);
    88101      clone.root = (SymbolicExpressionTreeNode)this.root.Clone();
     102      clone.allowedFunctionsInBranch = new Dictionary<int, IEnumerable<string>>(allowedFunctionsInBranch);
    89103      return clone;
    90104    }
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeCreator.cs

    r3269 r3294  
    3434  [Item("SymbolicExpressionTreeCreator", "A base class for operators creating symbolic expression trees.")]
    3535  [StorableClass]
    36   public abstract class SymbolicExpressionTreeCreator : SingleSuccessorOperator, ISolutionCreator, IStochasticOperator, ISymbolicExpressionTreeOperator {
    37     private const string RandomParameterName = "Random";
    38     private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
    39     private const string MaxTreeSizeParameterName = "MaxTreeSize";
    40     private const string MaxTreeHeightParameterName = "MaxTreeHeight";
    41     private const string SymbolicExpressionGrammarParameterName = "SymbolicExpressionGrammar";
    42 
    43     public override bool CanChangeName {
    44       get { return false; }
    45     }
    46 
    47     public ILookupParameter<IRandom> RandomParameter {
    48       get { return (LookupParameter<IRandom>)Parameters[RandomParameterName]; }
    49     }
    50     public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
    51       get { return (ILookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
    52     }
    53     public IValueLookupParameter<IntValue> MaxTreeSizeParameter {
    54       get { return (IValueLookupParameter<IntValue>)Parameters[MaxTreeSizeParameterName]; }
    55     }
    56     public IValueLookupParameter<IntValue> MaxTreeHeightParameter {
    57       get { return (IValueLookupParameter<IntValue>)Parameters[MaxTreeHeightParameterName]; }
    58     }
    59     public ILookupParameter<ISymbolicExpressionGrammar> SymbolicExpressionGrammarParameter {
    60       get { return (ILookupParameter<ISymbolicExpressionGrammar>)Parameters[SymbolicExpressionGrammarParameterName]; }
    61     }
    62 
     36  public abstract class SymbolicExpressionTreeCreator : SymbolicExpressionTreeOperator, ISolutionCreator {
    6337    protected SymbolicExpressionTreeCreator()
    6438      : base() {
    65       Parameters.Add(new LookupParameter<IRandom>(RandomParameterName, "The pseudo random number generator which should be used for stochastic solution creation operators."));
    66       Parameters.Add(new LookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree that should be initialized."));
    67       Parameters.Add(new ValueLookupParameter<IntValue>(MaxTreeSizeParameterName, "The maximal size (number of nodes) of the symbolic expression tree that should be initialized."));
    68       Parameters.Add(new ValueLookupParameter<IntValue>(MaxTreeHeightParameterName, "The maximal height of the symbolic expression tree that should be initialized (a tree with one node has height = 0)."));
    69       Parameters.Add(new LookupParameter<ISymbolicExpressionGrammar>(SymbolicExpressionGrammarParameterName, "The grammar that defines the allowed symbols and syntax of the symbolic expression trees."));
    7039    }
    7140
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeCrossover.cs

    r3239 r3294  
    3535  [Item("SymbolicExpressionTreeCrossover", "A base class for operators that perform a crossover of symbolic expression trees.")]
    3636  [StorableClass]
    37   public abstract class SymbolicExpressionTreeCrossover : SingleSuccessorOperator, ICrossover, IStochasticOperator, ISymbolicExpressionTreeOperator {
    38     public override bool CanChangeName {
    39       get { return false; }
     37  public abstract class SymbolicExpressionTreeCrossover : SymbolicExpressionTreeOperator, ICrossover {
     38    private const string ParentsParameterName = "Parents";
     39    private const string ChildParameterName = "Child";
     40    private const string FailedCrossoverEventsParameterName = "FailedCrossoverEvents";
     41    public ILookupParameter<ItemArray<SymbolicExpressionTree>> ParentsParameter {
     42      get { return (SubScopesLookupParameter<SymbolicExpressionTree>)Parameters[ParentsParameterName]; }
     43    }
     44    public ILookupParameter<SymbolicExpressionTree> ChildParameter {
     45      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters[ChildParameterName]; }
     46    }
     47    public IValueParameter<IntValue> FailedCrossoverEventsParameter {
     48      get { return (ValueParameter<IntValue>)Parameters[FailedCrossoverEventsParameterName]; }
    4049    }
    4150
    42     public ILookupParameter<IRandom> RandomParameter {
    43       get { return (LookupParameter<IRandom>)Parameters["Random"]; }
     51    public IntValue FailedCrossoverEvents {
     52      get { return FailedCrossoverEventsParameter.Value; }
    4453    }
    45     public ILookupParameter<ItemArray<SymbolicExpressionTree>> ParentsParameter {
    46       get { return (SubScopesLookupParameter<SymbolicExpressionTree>)Parameters["Parents"]; }
    47     }
    48     public ILookupParameter<SymbolicExpressionTree> ChildParameter {
    49       get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["Child"]; }
    50     }
    51     public IValueLookupParameter<IntValue> MaxTreeSizeParameter {
    52       get { return (IValueLookupParameter<IntValue>)Parameters["MaxTreeSize"]; }
    53     }
    54     public IValueLookupParameter<IntValue> MaxTreeHeightParameter {
    55       get { return (IValueLookupParameter<IntValue>)Parameters["MaxTreeHeight"]; }
    56     }
    57     public ILookupParameter<ISymbolicExpressionGrammar> SymbolicExpressionGrammarParameter {
    58       get { return (ILookupParameter<ISymbolicExpressionGrammar>)Parameters["SymbolicExpressionGrammar"]; }
    59     }
    60 
    6154    protected SymbolicExpressionTreeCrossover()
    6255      : base() {
    63       Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
    64       Parameters.Add(new SubScopesLookupParameter<SymbolicExpressionTree>("Parents", "The parent symbolic expression trees which should be crossed."));
    65       Parameters.Add(new ValueLookupParameter<IntValue>("MaxTreeSize", "The maximal size (number of nodes) of the symbolic expression tree that should be initialized."));
    66       Parameters.Add(new ValueLookupParameter<IntValue>("MaxTreeHeight", "The maximal height of the symbolic expression tree that should be initialized (a tree with one node has height = 0)."));
    67       Parameters.Add(new LookupParameter<ISymbolicExpressionGrammar>("SymbolicExpressionGrammar", "The grammar that defines the allowed symbols and syntax of the symbolic expression trees."));
    68       Parameters.Add(new LookupParameter<SymbolicExpressionTree>("Child", "The child symbolic expression tree resulting from the crossover."));
     56      Parameters.Add(new SubScopesLookupParameter<SymbolicExpressionTree>(ParentsParameterName, "The parent symbolic expression trees which should be crossed."));
     57      Parameters.Add(new LookupParameter<SymbolicExpressionTree>(ChildParameterName, "The child symbolic expression tree resulting from the crossover."));
     58      Parameters.Add(new ValueParameter<IntValue>(FailedCrossoverEventsParameterName, "The number of failed crossover events (child is an exact copy of a parent)", new IntValue()));
    6959    }
    7060
     
    8676      }
    8777
     78      bool success;
    8879      SymbolicExpressionTree result = Cross(random, grammar, parent0, parent1,
    89         MaxTreeSizeParameter.ActualValue, MaxTreeHeightParameter.ActualValue);
     80        MaxTreeSizeParameter.ActualValue, MaxTreeHeightParameter.ActualValue, out success);
     81     
     82      if (!success) FailedCrossoverEvents.Value++;
     83
    9084      Debug.Assert(result.Size <= MaxTreeSizeParameter.ActualValue.Value);
    9185      Debug.Assert(result.Height <= MaxTreeHeightParameter.ActualValue.Value);
    92       Debug.Assert(grammar.IsValidExpression(result));
     86      // Debug.Assert(grammar.IsValidExpression(result));
    9387      ChildParameter.ActualValue = result;
    9488      return base.Apply();
     
    9791    protected abstract SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar,
    9892      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
    99       IntValue maxTreeSize, IntValue maxTreeHeight);
     93      IntValue maxTreeSize, IntValue maxTreeHeight, out bool success);
    10094  }
    10195}
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeManipulator.cs

    r3239 r3294  
    3131  /// A base class for operators that manipulate real-valued vectors.
    3232  /// </summary>
    33   [Item("RealVectorManipulator", "A base class for operators that manipulate real-valued vectors.")]
     33  [Item("SymbolicExpressionTreeManipulator", "A base class for operators that manipulate symbolic expression trees.")]
    3434  [StorableClass]
    35   public abstract class RealVectorManipulator : SingleSuccessorOperator, IRealVectorManipulator, IStochasticOperator, ISymbolicExpressionTreeOperator {
    36     public override bool CanChangeName {
    37       get { return false; }
     35  public abstract class SymbolicExpressionTreeManipulator : SymbolicExpressionTreeOperator, IManipulator {
     36    private const string FailedManipulationEventsParameterName = "FailedManipulationEvents";
     37
     38    #region Parameter Properties
     39    public IValueParameter<IntValue> FailedManipulationEventsParameter {
     40      get { return (IValueParameter<IntValue>)Parameters[FailedManipulationEventsParameterName]; }
    3841    }
     42    #endregion
    3943
    40     public ILookupParameter<IRandom> RandomParameter {
    41       get { return (LookupParameter<IRandom>)Parameters["Random"]; }
     44    #region Properties
     45    public IntValue FailedManipulationEvents {
     46      get { return FailedManipulationEventsParameter.Value; }
    4247    }
    43     public ILookupParameter<RealVector> RealVectorParameter {
    44       get { return (ILookupParameter<RealVector>)Parameters["RealVector"]; }
    45     }
    46     public IValueLookupParameter<DoubleMatrix> BoundsParameter {
    47       get { return (IValueLookupParameter<DoubleMatrix>)Parameters["Bounds"]; }
    48     }
     48    #endregion
    4949
    50     protected RealVectorManipulator()
     50    public SymbolicExpressionTreeManipulator()
    5151      : base() {
    52       Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
    53       Parameters.Add(new LookupParameter<RealVector>("RealVector", "The vector which should be manipulated."));
    54       Parameters.Add(new ValueLookupParameter<DoubleMatrix>("Bounds", "The lower and upper bounds of the real vector."));
     52      Parameters.Add(new ValueParameter<IntValue>(FailedManipulationEventsParameterName, "The number of failed manipulation events.", new IntValue()));
    5553    }
    5654
    5755    public sealed override IOperation Apply() {
    58       RealVector vector = RealVectorParameter.ActualValue;
    59       Manipulate(RandomParameter.ActualValue, vector);
    60       DoubleMatrix bounds = BoundsParameter.ActualValue;
    61       if (bounds != null) BoundsChecker.Apply(vector, bounds);
     56      SymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
     57      bool success;
     58      Manipulate(RandomParameter.ActualValue, tree, SymbolicExpressionGrammarParameter.ActualValue,
     59        MaxTreeSizeParameter.ActualValue, MaxTreeHeightParameter.ActualValue, out success);
     60
     61      if (!success) FailedManipulationEvents.Value++;
    6262      return base.Apply();
    6363    }
    6464
    65     protected abstract void Manipulate(IRandom random, RealVector realVector);
     65    protected abstract void Manipulate(IRandom random, SymbolicExpressionTree symbolicExpressionTree, ISymbolicExpressionGrammar grammar,
     66      IntValue maxTreeSize, IntValue maxTreeHeight, out bool success);
    6667  }
    6768}
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeNode.cs

    r3269 r3294  
    2121
    2222using System;
     23using System.Linq;
    2324using System.Collections.Generic;
    2425using System.Text;
     
    2728using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2829using HeuristicLab.Data;
     30using System.Diagnostics;
    2931
    3032namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
     
    4648    protected SymbolicExpressionTreeNode(SymbolicExpressionTreeNode original) {
    4749      symbol = original.symbol;
    48       this.subTrees = new List<SymbolicExpressionTreeNode>();
     50      subTrees = new List<SymbolicExpressionTreeNode>();
    4951      foreach (var subtree in original.SubTrees) {
    5052        AddSubTree((SymbolicExpressionTreeNode)subtree.Clone());
    5153      }
     54      dynamicSymbols = new Dictionary<string, int>(original.dynamicSymbols);
    5255    }
    5356
     
    7679      return maxHeight + 1;
    7780    }
    78    
     81
     82    [Storable]
     83    private Dictionary<string, int> dynamicSymbols = new Dictionary<string, int>();
     84    public void AddDynamicSymbol(string symbolName) {
     85      Debug.Assert(!dynamicSymbols.ContainsKey(symbolName));
     86      dynamicSymbols[symbolName] = 0;
     87    }
     88
     89    public void AddDynamicSymbol(string symbolName, int nArguments) {
     90      AddDynamicSymbol(symbolName);
     91      SetDynamicSymbolArgumentCount(symbolName, nArguments);
     92    }
     93
     94    public void RemoveDynamicSymbol(string symbolName) {
     95      dynamicSymbols.Remove(symbolName);
     96    }
     97
     98    public IEnumerable<string> DynamicSymbols {
     99      get { return dynamicSymbols.Keys; }
     100    }
     101
     102    public int GetDynamicSymbolArgumentCount(string symbolName) {
     103      return dynamicSymbols[symbolName];
     104    }
     105    public void SetDynamicSymbolArgumentCount(string symbolName, int nArguments) {
     106      Debug.Assert(dynamicSymbols.ContainsKey(symbolName));
     107      dynamicSymbols[symbolName] = nArguments;
     108    }
     109
    79110    public virtual void ResetLocalParameters(IRandom random) { }
    80111    public virtual void ShakeLocalParameters(IRandom random, double shakingFactor) { }
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Symbols/Addition.cs

    r3256 r3294  
    2020#endregion
    2121
     22using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     23using HeuristicLab.Core;
    2224namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols {
     25  [StorableClass]
     26  [Item("Addition", "Symbol that represents the + operator.")]
    2327  public sealed class Addition : Symbol {
    2428  }
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Symbols/Division.cs

    r3256 r3294  
    2020#endregion
    2121
     22using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     23using HeuristicLab.Core;
    2224namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols {
     25  [StorableClass]
     26  [Item("Division", "Symbol that represents the / operator.")]
    2327  public sealed class Division : Symbol {
    2428  }
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Symbols/Multiplication.cs

    r3256 r3294  
    2020#endregion
    2121
     22using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     23using HeuristicLab.Core;
    2224namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols {
     25  [StorableClass]
     26  [Item("Multiplication", "Symbol that represents the * operator.")]
    2327  public sealed class Multiplication : Symbol {
    2428  }
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Symbols/StartSymbol.cs

    r3256 r3294  
    2020#endregion
    2121
     22using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     23using HeuristicLab.Core;
    2224namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols {
     25  [StorableClass]
     26  [Item("StartSymbol", "Special symbol that represents the starting node of the result producing branch of a symbolic expression tree.")]
    2327  public sealed class StartSymbol : Symbol {
     28    public override bool CanChangeName {
     29      get {
     30        return false;
     31      }
     32    }
    2433  }
    2534}
  • trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Symbols/Subtraction.cs

    r3256 r3294  
    2020#endregion
    2121
     22using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     23using HeuristicLab.Core;
    2224namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols {
     25  [StorableClass]
     26  [Item("Subtraction", "Symbol that represents the - operator.")]
    2327  public sealed class Subtraction : Symbol {
    2428  }
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/AntInterpreter.cs

    r3239 r3294  
    2121
    2222using System;
     23using System.Linq;
    2324using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2425using HeuristicLab.Data;
    2526using System.Collections.Generic;
     27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.GeneralSymbols;
    2628
    2729namespace HeuristicLab.Problems.ArtificialAnt {
     
    8082      // expression evaluated completly => start at root again
    8183      if (nodeStack.Count == 0)
    82         nodeStack.Push(Expression.Root.SubTrees[0]);
     84        nodeStack.Push(Expression.ResultProducingExpression);
    8385      var currentNode = nodeStack.Pop();
    8486      if (currentNode.Symbol is Left) {
     
    112114        nodeStack.Push(currentNode.SubTrees[0]);
    113115        return;
     116      } else if (currentNode.Symbol is InvokeFunction) {
     117        var invokeNode = currentNode as InvokeFunctionTreeNode;
     118        var funBranch = (from node in expression.Root.SubTrees
     119                         let funNode = node as DefunTreeNode
     120                         where funNode != null
     121                         where funNode.Name == invokeNode.InvokedFunctionName
     122                         select funNode).FirstOrDefault();
     123        if (funBranch == null) throw new InvalidOperationException("Can't find definition of function " + invokeNode.InvokedFunctionName);
     124        nodeStack.Push(funBranch.SubTrees[0]);
     125        foreach (var subTree in invokeNode.SubTrees)
     126          nodeStack.Push(subTree);
     127      } else if(currentNode.Symbol is Argument) {
     128        // do nothing
    114129      } else {
    115130        throw new InvalidOperationException(currentNode.Symbol.ToString());
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/ArtificialAntExpressionGrammar.cs

    r3257 r3294  
    3030namespace HeuristicLab.Problems.ArtificialAnt {
    3131  [StorableClass]
    32   public class ArtificialAntExpressionGrammar : Item, ISymbolicExpressionGrammar {
     32  public class ArtificialAntExpressionGrammar : DefaultSymbolicExpressionGrammar {
    3333
    3434    public ArtificialAntExpressionGrammar()
    35       : base() {
    36     }
    37     #region ISymbolicExpressionGrammar Members
    38 
    39     [Storable]
    40     private StartSymbol startSymbol = new StartSymbol();
    41     public Symbol StartSymbol {
    42       get { return startSymbol; }
     35      : base(0, 3, 0, 3) {
     36      Initialize();
    4337    }
    4438
    45     [Storable]
    46     private static List<Symbol> allSymbols = new List<Symbol>() {
    47       new IfFoodAhead(),
    48       new Prog2(),
    49       new Prog3(),
    50       new Move(),
    51       new Left(),
    52       new Right()
    53     };
    54     [Storable]
    55     private Dictionary<Type, Dictionary<int, IEnumerable<Symbol>>> allowedSymbols = new Dictionary<Type, Dictionary<int, IEnumerable<Symbol>>>() {
    56       {
    57         typeof(StartSymbol),
    58         new Dictionary<int, IEnumerable<Symbol>>()
    59         {
    60           { 0, allSymbols},
     39    private void Initialize() {
     40      var ifFoodAhead = new IfFoodAhead();
     41      var prog2 = new Prog2();
     42      var prog3 = new Prog3();
     43      var move = new Move();
     44      var left = new Left();
     45      var right = new Right();
     46      var defun = new Defun();
     47      var invoke = new InvokeFunction();
     48      var allSymbols = new List<Symbol>() { ifFoodAhead, prog2, prog3, move, left, right };
     49      var nonTerminalSymbols = new List<Symbol>() { ifFoodAhead, prog2, prog3 };
     50      SetMinSubTreeCount(ifFoodAhead, 2);
     51      SetMaxSubTreeCount(ifFoodAhead, 2);
     52      SetMinSubTreeCount(prog2, 2);
     53      SetMaxSubTreeCount(prog2, 2);
     54      SetMinSubTreeCount(prog3, 3);
     55      SetMaxSubTreeCount(prog3, 3);
     56      SetMinSubTreeCount(move, 0);
     57      SetMaxSubTreeCount(move, 0);
     58      SetMinSubTreeCount(left, 0);
     59      SetMaxSubTreeCount(left, 0);
     60      SetMinSubTreeCount(right, 0);
     61      SetMaxSubTreeCount(right, 0);
     62      foreach (var sym in allSymbols) {
     63        AddAllowedSymbols(StartSymbol, 0, sym);
     64        AddAllowedSymbols(defun, 0, sym);
     65
     66        for (int i = 0; i < GetMaxSubTreeCount(invoke); i++) {
     67          AddAllowedSymbols(invoke, i, sym);
    6168        }
    62       },      {
    63         typeof(IfFoodAhead),
    64         new Dictionary<int, IEnumerable<Symbol>>()
    65         {
    66           { 0, allSymbols},
    67           { 1, allSymbols}
     69      }
     70      foreach (var sym in nonTerminalSymbols) {
     71        for (int argIndex = 0; argIndex < GetMaxSubTreeCount(sym); argIndex++) {
     72          AddAllowedSymbols(sym, argIndex, invoke);
    6873        }
    69       },
    70       {
    71         typeof(Prog2),
    72         new Dictionary<int, IEnumerable<Symbol>>()
    73         {
    74           { 0, allSymbols},
    75           { 1, allSymbols}
     74      }
     75      foreach (var nonTerminal in nonTerminalSymbols) {
     76        foreach (var child in allSymbols) {
     77          for (int argIndex = 0; argIndex < GetMaxSubTreeCount(nonTerminal); argIndex++) {
     78            AddAllowedSymbols(nonTerminal, argIndex, child);
     79          }
    7680        }
    77       },
    78       {
    79         typeof(Prog3),
    80         new Dictionary<int, IEnumerable<Symbol>>()
    81         {
    82           { 0, allSymbols},
    83           { 1, allSymbols},
    84           { 2, allSymbols}
    85         }
    86       },
    87     };
    88     public IEnumerable<Symbol> AllowedSymbols(Symbol parent, int argumentIndex) {
    89       return allowedSymbols[parent.GetType()][argumentIndex];
    90     }
     81      }
    9182
    92     [Storable]
    93     private Dictionary<Type, int> minLength = new Dictionary<Type, int>() {
    94       {typeof(StartSymbol), 1},
    95       {typeof(IfFoodAhead), 3},
    96       {typeof(Prog2), 3},
    97       {typeof(Prog3), 4},
    98       {typeof(Move), 1},
    99       {typeof(Left), 1},
    100       {typeof(Right), 1}
    101     };
    102     public int MinimalExpressionLength(Symbol start) {
    103       return minLength[start.GetType()];
    104     }
    105 
    106     [Storable]
    107     private Dictionary<Type, int> maxLength = new Dictionary<Type, int>() {
    108       {typeof(StartSymbol), int.MaxValue},
    109       {typeof(IfFoodAhead), int.MaxValue},
    110       {typeof(Prog2), int.MaxValue},
    111       {typeof(Prog3), int.MaxValue},
    112       {typeof(Move), 1},
    113       {typeof(Left), 1},
    114       {typeof(Right), 1}
    115     };
    116     public int MaximalExpressionLength(Symbol start) {
    117       return maxLength[start.GetType()];
    118     }
    119 
    120     [Storable]
    121     private Dictionary<Type, int> minDepth = new Dictionary<Type, int>() {
    122       {typeof(StartSymbol), 1},
    123       {typeof(IfFoodAhead), 1},
    124       {typeof(Prog2), 1},
    125       {typeof(Prog3), 1},
    126       {typeof(Move), 0},
    127       {typeof(Left), 0},
    128       {typeof(Right), 0}
    129     };
    130     public int MinimalExpressionDepth(Symbol start) {
    131       return minDepth[start.GetType()];
    132     }
    133 
    134 
    135     [Storable]
    136     private Dictionary<Type, int> subTrees = new Dictionary<Type, int>() {
    137       {typeof(StartSymbol), 1},
    138       {typeof(IfFoodAhead), 2},
    139       {typeof(Prog2), 2},
    140       {typeof(Prog3), 3},
    141       {typeof(Move), 0},
    142       {typeof(Left), 0},
    143       {typeof(Right), 0}
    144     };
    145     public int MinSubTrees(Symbol start) {
    146       return subTrees[start.GetType()];
    147     }
    148     public int MaxSubTrees(Symbol start) {
    149       return subTrees[start.GetType()];
    150     }
    151 
    152     #endregion
    153 
    154     #region ISymbolicExpressionGrammar Members
    155 
    156 
    157     public bool IsValidExpression(SymbolicExpressionTree expression) {
    158       if (expression.Root.Symbol != StartSymbol) return false;
    159       return IsValidExpression(expression.Root);
    160     }
    161 
    162     #endregion
    163 
    164     private bool IsValidExpression(SymbolicExpressionTreeNode root) {
    165       if (root.SubTrees.Count < MinSubTrees(root.Symbol)) return false;
    166       if (root.SubTrees.Count > MaxSubTrees(root.Symbol)) return false;
    167       for (int i = 0; i < root.SubTrees.Count; i++) {
    168         if (!AllowedSymbols(root.Symbol, i).Contains(root.SubTrees[i].Symbol)) return false;
    169         if (!IsValidExpression(root.SubTrees[i])) return false;
    170       }
    171       return true;
    17283    }
    17384  }
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/ArtificialAntProblem.cs

    r3251 r3294  
    107107      get { return (ValueParameter<IntValue>)Parameters["MaxExpressionDepth"]; }
    108108    }
     109    public ValueParameter<IntValue> MaxFunctionDefinitionsParameter {
     110      get { return (ValueParameter<IntValue>)Parameters["MaxFunctionDefinitions"]; }
     111    }
     112    public ValueParameter<IntValue> MaxFunctionArgumentsParameter {
     113      get { return (ValueParameter<IntValue>)Parameters["MaxFunctionArguments"]; }
     114    }
    109115    public ValueParameter<BoolMatrix> WorldParameter {
    110116      get { return (ValueParameter<BoolMatrix>)Parameters["World"]; }
     
    195201      Parameters.Add(new ValueParameter<IntValue>("MaxExpressionLength", "Maximal length of the expression to control the artificial ant.", new IntValue(100)));
    196202      Parameters.Add(new ValueParameter<IntValue>("MaxExpressionDepth", "Maximal depth of the expression to control the artificial ant.", new IntValue(10)));
     203      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionDefinitions", "Maximal number of automatically defined functions in the expression to control the artificial ant.", new IntValue(3)));
     204      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionArguments", "Maximal number of arguments of automatically defined functions in the expression to control the artificial ant.", new IntValue(3)));
    197205      Parameters.Add(new ValueParameter<BoolMatrix>("World", "The world for the artificial ant with scattered food items.", world));
    198206      Parameters.Add(new ValueParameter<IntValue>("MaxTimeSteps", "The number of time steps the artificial ant has available to collect all food items.", new IntValue(600)));
     
    333341        op.ChildParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
    334342      }
     343      foreach (SymbolicExpressionTreeManipulator op in Operators.OfType<SymbolicExpressionTreeManipulator>()) {
     344        op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
     345      }
     346      foreach (SymbolicExpressionTreeArchitectureAlteringOperator op in Operators.OfType<SymbolicExpressionTreeArchitectureAlteringOperator>()) {
     347        op.MaxFunctionDefiningBranchesParameter.ActualName = MaxFunctionDefinitionsParameter.Name;
     348        op.MaxFunctionArgumentsParameter.ActualName = MaxFunctionArgumentsParameter.Name;
     349      }
    335350    }
    336351
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/Symbols/IfFoodAhead.cs

    r3223 r3294  
    2121
    2222using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     23using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     24using HeuristicLab.Core;
    2325namespace HeuristicLab.Problems.ArtificialAnt {
     26  [StorableClass]
     27  [Item("IfFoodAhead", "Represents the if-food-ahead symbol in a artificial ant expression.")]
    2428  public sealed class IfFoodAhead : Symbol {
    2529  }
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/Symbols/Left.cs

    r3223 r3294  
    2121
    2222using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     23using HeuristicLab.Core;
     24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2325namespace HeuristicLab.Problems.ArtificialAnt {
     26  [StorableClass]
     27  [Item("Left", "Represents the turn-left symbol in a artificial ant expression.")]
    2428  public sealed class Left : Symbol {
    2529  }
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/Symbols/Move.cs

    r3223 r3294  
    2121
    2222using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     23using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     24using HeuristicLab.Core;
    2325namespace HeuristicLab.Problems.ArtificialAnt {
     26  [StorableClass]
     27  [Item("Move", "Represents the move-forward symbol in a artificial ant expression.")]
    2428  public sealed class Move : Symbol {
    2529  }
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/Symbols/Prog2.cs

    r3223 r3294  
    2222
    2323using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     25using HeuristicLab.Core;
    2426namespace HeuristicLab.Problems.ArtificialAnt {
     27  [StorableClass]
     28  [Item("Prog2", "Represents the sequence symbol with 2 sub-trees in a artificial ant expression.")]
    2529  public sealed class Prog2 : Symbol {
    2630  }
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/Symbols/Prog3.cs

    r3269 r3294  
    2121
    2222using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     23using HeuristicLab.Core;
     24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2325namespace HeuristicLab.Problems.ArtificialAnt {
     26  [StorableClass]
     27  [Item("Prog3", "Represents the sequence symbol with 3 sub-trees in a artificial ant expression.")]
    2428  public sealed class Prog3 : Symbol {
    25     public Prog3()
    26       : base() {
    27     }
    2829  }
    2930}
  • trunk/sources/HeuristicLab.Problems.ArtificialAnt/3.3/Symbols/Right.cs

    r3223 r3294  
    2121
    2222using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
     23using HeuristicLab.Core;
     24using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2325namespace HeuristicLab.Problems.ArtificialAnt {
     26  [StorableClass]
     27  [Item("Right", "Represents the turn-right symbol in a artificial ant expression.")]
    2428  public sealed class Right : Symbol {
    2529  }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/HeuristicLab.Problems.DataAnalysis.Regression-3.3.csproj

    r3265 r3294  
    8585    <None Include="HeuristicLabProblemsDataAnalysisRegressionPlugin.cs.frame" />
    8686    <None Include="Properties\AssemblyInfo.frame" />
     87    <Compile Include="RegressionProblemDataView.cs">
     88      <SubType>UserControl</SubType>
     89    </Compile>
     90    <Compile Include="RegressionProblemDataView.Designer.cs">
     91      <DependentUpon>RegressionProblemDataView.cs</DependentUpon>
     92    </Compile>
     93    <Compile Include="RegressionProblemData.cs" />
    8794    <Compile Include="CsvFileParser.cs" />
    8895    <Compile Include="DataFormatException.cs" />
     
    96103    <Compile Include="HeuristicLabProblemsDataAnalysisRegressionPlugin.cs" />
    97104    <Compile Include="Properties\AssemblyInfo.cs" />
    98     <Compile Include="Symbolic\SymbolicRegressionProblemView.cs">
    99       <SubType>UserControl</SubType>
    100     </Compile>
    101     <Compile Include="Symbolic\SymbolicRegressionProblemView.Designer.cs">
    102       <DependentUpon>SymbolicRegressionProblemView.cs</DependentUpon>
    103     </Compile>
    104105    <Compile Include="Symbolic\Symbols\Constant.cs" />
    105106    <Compile Include="Symbolic\Symbols\ConstantTreeNode.cs" />
    106107    <Compile Include="Symbolic\Symbols\Variable.cs" />
    107108    <Compile Include="Symbolic\Symbols\VariableTreeNode.cs" />
    108     <Compile Include="RegressionProblemView.cs">
    109       <SubType>UserControl</SubType>
    110     </Compile>
    111     <Compile Include="RegressionProblemView.Designer.cs">
    112       <DependentUpon>RegressionProblemView.cs</DependentUpon>
    113     </Compile>
    114109  </ItemGroup>
    115110  <ItemGroup>
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/RegressionProblem.cs

    r3264 r3294  
    3737  [StorableClass]
    3838  public class RegressionProblem : ParameterizedNamedItem {
     39    private const string RegressionProblemDataParameterName = "RegressionProblemData";
    3940    public override Image ItemImage {
    4041      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Type; }
     
    4243
    4344    #region Parameter Properties
    44     public ValueParameter<Dataset> DatasetParameter {
    45       get { return (ValueParameter<Dataset>)Parameters["Dataset"]; }
    46     }
    47     public ValueParameter<StringValue> TargetVariableParameter {
    48       get { return (ValueParameter<StringValue>)Parameters["TargetVariable"]; }
    49     }
    50     public ValueParameter<ItemList<StringValue>> InputVariablesParameter {
    51       get { return (ValueParameter<ItemList<StringValue>>)Parameters["InputVariables"]; }
    52     }
    53     public ValueParameter<IntValue> TrainingSamplesStartParameter {
    54       get { return (ValueParameter<IntValue>)Parameters["TrainingSamplesStart"]; }
    55     }
    56     public ValueParameter<IntValue> TrainingSamplesEndParameter {
    57       get { return (ValueParameter<IntValue>)Parameters["TrainingSamplesEnd"]; }
    58     }
    59     public OptionalValueParameter<IntValue> ValidationSamplesStartParameter {
    60       get { return (OptionalValueParameter<IntValue>)Parameters["ValidationSamplesStart"]; }
    61     }
    62     public OptionalValueParameter<IntValue> ValidationSamplesEndParameter {
    63       get { return (OptionalValueParameter<IntValue>)Parameters["ValidationSamplesEnd"]; }
    64     }
    65     public ValueParameter<IntValue> TestSamplesStartParameter {
    66       get { return (ValueParameter<IntValue>)Parameters["TestSamplesStart"]; }
    67     }
    68     public ValueParameter<IntValue> TestSamplesEndParameter {
    69       get { return (ValueParameter<IntValue>)Parameters["TestSamplesEnd"]; }
     45    public ValueParameter<RegressionProblemData> RegressionProblemDataParameter {
     46      get { return (ValueParameter<RegressionProblemData>)Parameters[RegressionProblemDataParameterName]; }
    7047    }
    7148    #endregion
    7249    #region properties
    73     public Dataset Dataset {
    74       get { return DatasetParameter.Value; }
    75       set { DatasetParameter.Value = value; }
    76     }
    77     public StringValue TargetVariable {
    78       get { return TargetVariableParameter.Value; }
    79       set { TargetVariableParameter.Value = value; }
    80     }
    81     public ItemList<StringValue> InputVariables {
    82       get { return InputVariablesParameter.Value; }
    83       set { InputVariablesParameter.Value = value; }
    84     }
    85     public IntValue TrainingSamplesStart {
    86       get { return TrainingSamplesStartParameter.Value; }
    87       set { TrainingSamplesStartParameter.Value = value; }
    88     }
    89     public IntValue TrainingSamplesEnd {
    90       get { return TrainingSamplesEndParameter.Value; }
    91       set { TrainingSamplesEndParameter.Value = value; }
    92     }
    93     public IntValue ValidationSamplesStart {
    94       get { return ValidationSamplesStartParameter.Value; }
    95       set { ValidationSamplesStartParameter.Value = value; }
    96     }
    97     public IntValue ValidationSamplesEnd {
    98       get { return ValidationSamplesEndParameter.Value; }
    99       set { ValidationSamplesEndParameter.Value = value; }
    100     }
    101     public IntValue TestSamplesStart {
    102       get { return TestSamplesStartParameter.Value; }
    103       set { TestSamplesStartParameter.Value = value; }
    104     }
    105     public IntValue TestSamplesEnd {
    106       get { return TestSamplesEndParameter.Value; }
    107       set { TestSamplesEndParameter.Value = value; }
     50    public RegressionProblemData RegressionProblemData {
     51      get { return RegressionProblemDataParameter.Value; }
     52      set { RegressionProblemDataParameter.Value = value; }
    10853    }
    10954    #endregion
     
    11156    public RegressionProblem()
    11257      : base() {
    113       var dataset = new Dataset();
    114       // TODO: wiring for sanity checks of parameter values based on dataset (target & input variables available?, training and test partition correct?...)
    115       Parameters.Add(new ValueParameter<Dataset>("Dataset", "The data set containing data to be analyzer.", dataset));
    116       Parameters.Add(new ValueParameter<StringValue>("TargetVariable", "The target variable for which a regression model should be created.", new StringValue()));
    117       Parameters.Add(new ValueParameter<ItemList<StringValue>>("InputVariables", "The input variables (regressors) that are available for the regression model.", new ItemList<StringValue>()));
    118       Parameters.Add(new ValueParameter<IntValue>("TrainingSamplesStart", "The start index of the training partition.", new IntValue()));
    119       Parameters.Add(new ValueParameter<IntValue>("TrainingSamplesEnd", "The end index of the training partition.", new IntValue()));
    120       Parameters.Add(new OptionalValueParameter<IntValue>("ValidationSamplesStart", "The start index of the validation partition."));
    121       Parameters.Add(new OptionalValueParameter<IntValue>("ValidationSamplesEnd", "The end index of the validation partition."));
    122       Parameters.Add(new ValueParameter<IntValue>("TestSamplesStart", "The start index of the test partition.", new IntValue()));
    123       Parameters.Add(new ValueParameter<IntValue>("TestSamplesEnd", "The end index of the test partition.", new IntValue()));
     58      Parameters.Add(new ValueParameter<RegressionProblemData>(RegressionProblemDataParameterName, "The data set, target variable and input variables of the regression problem.", new RegressionProblemData()));
    12459    }
    12560
    12661    [StorableConstructor]
    12762    private RegressionProblem(bool deserializing) : base() { }
    128 
    129     public virtual void ImportFromFile(string fileName) {
    130       var csvFileParser = new CsvFileParser();
    131       csvFileParser.Parse(fileName);
    132       Name = "Regression Problem (imported from " + Path.GetFileName(fileName);
    133       Dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
    134       Dataset.Name = Path.GetFileName(fileName);
    135       TargetVariable = new StringValue(Dataset.VariableNames.First());
    136       InputVariables = new ItemList<StringValue>(Dataset.VariableNames.Skip(1).Select(s => new StringValue(s)));
    137       TrainingSamplesStart = new IntValue(0);
    138       TrainingSamplesEnd = new IntValue(csvFileParser.Rows);
    139       TestSamplesStart = new IntValue(0);
    140       TestSamplesEnd = new IntValue(csvFileParser.Rows);
    141     }
    14263  }
    14364}
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/ArithmeticExpressionGrammar.cs

    r3269 r3294  
    3232namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
    3333  [StorableClass]
    34   public class ArithmeticExpressionGrammar : NamedItemCollection<Symbol>, ISymbolicExpressionGrammar {
    35 
     34  [Item("ArithmeticExpressionGrammar", "Represents a grammar for functional expressions using only arithmetic operations.")]
     35  public class ArithmeticExpressionGrammar : DefaultSymbolicExpressionGrammar {
     36    [Storable]
    3637    private List<string> variableNames = new List<string>();
    3738    public IEnumerable<string> VariableNames {
     
    3940      set {
    4041        variableNames = new List<string>(value);
    41         var variable = (HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable)allSymbols[5];
    42         variable.VariableNames = new ItemList<HeuristicLab.Data.StringValue>(variableNames.Select(x => new StringValue(x)));
     42        variableSymbol.VariableNames = variableNames;
    4343      }
    4444    }
    4545
     46    [Storable]
     47    private HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable variableSymbol;
     48
    4649    public ArithmeticExpressionGrammar()
    47       : this(allSymbols) {
     50      : base(0, 0, 0, 0) {
     51      Initialize();
    4852    }
    4953
    50     public ArithmeticExpressionGrammar(IEnumerable<Symbol> symbols)
    51       : base(symbols) {
    52       allSymbols = new List<Symbol>(symbols);
    53     }
     54    private void Initialize() {
     55      var add = new Addition();
     56      var sub = new Subtraction();
     57      var mul = new Multiplication();
     58      var div = new Division();
     59      var constant = new Constant();
     60      variableSymbol = new HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable();
    5461
    55     #region ISymbolicExpressionGrammar Members
    56     [Storable]
    57     private StartSymbol startSymbol = new StartSymbol();
    58     public Symbol StartSymbol {
    59       get { return startSymbol; }
    60     }
    61 
    62     [Storable]
    63     private static List<Symbol> allSymbols = new List<Symbol>() {
    64       new Addition(),
    65       new Subtraction(),
    66       new Multiplication(),
    67       new Division(),
    68       new Constant(),
    69       new HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable()
    70     };
    71     [Storable]
    72     private Dictionary<Type, Dictionary<int, IEnumerable<Symbol>>> allowedSymbols = new Dictionary<Type, Dictionary<int, IEnumerable<Symbol>>>() {
    73       {
    74         typeof(StartSymbol),
    75         new Dictionary<int, IEnumerable<Symbol>>()
    76         {
    77           { 0, allSymbols},
    78         }
    79       },      {
    80         typeof(Addition),
    81         new Dictionary<int, IEnumerable<Symbol>>()
    82         {
    83           { 0, allSymbols},
    84           { 1, allSymbols}
    85         }
    86       },
    87       {
    88         typeof(Subtraction),
    89         new Dictionary<int, IEnumerable<Symbol>>()
    90         {
    91           { 0, allSymbols},
    92           { 1, allSymbols}
    93         }
    94       },
    95       {
    96         typeof(Multiplication),
    97         new Dictionary<int, IEnumerable<Symbol>>()
    98         {
    99           { 0, allSymbols},
    100           { 1, allSymbols}
    101         }
    102       },
    103       {
    104         typeof(Division),
    105         new Dictionary<int, IEnumerable<Symbol>>()
    106         {
    107           { 0, allSymbols},
    108           { 1, allSymbols}
    109         }
    110       },
    111     };
    112     public IEnumerable<Symbol> AllowedSymbols(Symbol parent, int argumentIndex) {
    113       return allowedSymbols[parent.GetType()][argumentIndex];
    114     }
    115 
    116     [Storable]
    117     private Dictionary<Type, int> minLength = new Dictionary<Type, int>() {
    118       {typeof(StartSymbol), 1},
    119       {typeof(Addition), 3},
    120       {typeof(Subtraction), 3},
    121       {typeof(Multiplication), 4},
    122       {typeof(Division), 4},
    123       {typeof(Constant), 1},
    124       {typeof(HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable), 1},
    125     };
    126     public int MinimalExpressionLength(Symbol start) {
    127       return minLength[start.GetType()];
    128     }
    129 
    130     [Storable]
    131     private Dictionary<Type, int> maxLength = new Dictionary<Type, int>() {
    132       {typeof(StartSymbol), int.MaxValue},
    133       {typeof(Addition), int.MaxValue},
    134       {typeof(Subtraction), int.MaxValue},
    135       {typeof(Multiplication), int.MaxValue},
    136       {typeof(Division), int.MaxValue},
    137       {typeof(HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable), 1},
    138       {typeof(Constant), 1},
    139     };
    140     public int MaximalExpressionLength(Symbol start) {
    141       return maxLength[start.GetType()];
    142     }
    143 
    144     [Storable]
    145     private Dictionary<Type, int> minDepth = new Dictionary<Type, int>() {
    146       {typeof(StartSymbol), 1},
    147       {typeof(Addition), 1},
    148       {typeof(Subtraction), 1},
    149       {typeof(Multiplication), 1},
    150       {typeof(Division), 1},
    151       {typeof(Constant), 0},
    152       {typeof(HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable), 0}
    153     };
    154     public int MinimalExpressionDepth(Symbol start) {
    155       return minDepth[start.GetType()];
    156     }
    157 
    158     [Storable]
    159     private Dictionary<Type, int> subTrees = new Dictionary<Type, int>() {
    160       {typeof(StartSymbol), 1},
    161       {typeof(Addition), 2},
    162       {typeof(Subtraction), 2},
    163       {typeof(Multiplication), 2},
    164       {typeof(Division), 2},
    165       {typeof(HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable), 0},
    166       {typeof(Constant), 0},
    167     };
    168     public int MinSubTrees(Symbol start) {
    169       return subTrees[start.GetType()];
    170     }
    171     public int MaxSubTrees(Symbol start) {
    172       return subTrees[start.GetType()];
    173     }
    174 
    175     #endregion
    176 
    177     #region ISymbolicExpressionGrammar Members
     62      var allSymbols = new List<Symbol>() { add, sub, mul, div, constant, variableSymbol };
     63      var functionSymbols = new List<Symbol>() { add, sub, mul, div };
     64      allSymbols.ForEach(s => AddAllowedSymbols(StartSymbol, 0, s));
    17865
    17966
    180     public bool IsValidExpression(SymbolicExpressionTree expression) {
    181       if (expression.Root.Symbol != StartSymbol) return false;
    182       return IsValidExpression(expression.Root);
    183     }
    184 
    185     #endregion
    186 
    187     private bool IsValidExpression(SymbolicExpressionTreeNode root) {
    188       if (root.SubTrees.Count < MinSubTrees(root.Symbol)) return false;
    189       if (root.SubTrees.Count > MaxSubTrees(root.Symbol)) return false;
    190       for (int i = 0; i < root.SubTrees.Count; i++) {
    191         if (!AllowedSymbols(root.Symbol, i).Contains(root.SubTrees[i].Symbol)) return false;
    192         if (!IsValidExpression(root.SubTrees[i])) return false;
     67      SetMinSubTreeCount(constant, 0);
     68      SetMaxSubTreeCount(constant, 0);
     69      SetMinSubTreeCount(variableSymbol, 0);
     70      SetMaxSubTreeCount(variableSymbol, 0);
     71      int maxSubTrees = 3;
     72      foreach (var functionSymbol in functionSymbols) {
     73        SetMinSubTreeCount(functionSymbol, 1);
     74        SetMaxSubTreeCount(functionSymbol, maxSubTrees);
     75        foreach (var childSymbol in allSymbols) {
     76          for (int argumentIndex = 0; argumentIndex < maxSubTrees; argumentIndex++) {
     77            AddAllowedSymbols(functionSymbol, argumentIndex, childSymbol);
     78          }
     79        }
    19380      }
    194       return true;
    19581    }
    19682  }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/ISymbolicRegressionEvaluator.cs

    r3253 r3294  
    3737  public interface ISymbolicRegressionEvaluator : ISingleObjectiveEvaluator {
    3838    ILookupParameter<SymbolicExpressionTree> FunctionTreeParameter { get; }
    39     ILookupParameter<Dataset> DatasetParameter { get; }
    40     ILookupParameter<StringValue> TargetVariableParameter { get; }
    41     ILookupParameter<IntValue> SamplesStartParameter { get; }
    42     ILookupParameter<IntValue> SamplesEndParameter { get; }
     39    ILookupParameter<RegressionProblemData> RegressionProblemDataParameter { get; }
    4340    ILookupParameter<DoubleValue> NumberOfEvaluatedNodesParameter { get; }
    4441  }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SimpleArithmeticExpressionEvaluator.cs

    r3269 r3294  
    3030
    3131namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic {
    32   /// <summary>
    33   /// Evaluates FunctionTrees recursively by interpretation of the function symbols in each node.
    34   /// Simple unoptimized code, arithmetic expressions only.
    35   /// Not thread-safe!
    36   /// </summary>
    3732  [StorableClass]
    3833  [Item("SimpleArithmeticExpressionEvaluator", "Default evaluator for arithmetic symbolic expression trees.")]
    39   public class SimpleArithmeticExpressionEvaluator : GeneralSymbolicExpressionTreeEvaluator {
     34  public class SimpleArithmeticExpressionEvaluator {
    4035    private Dataset dataset;
    4136    private int row;
     37    private Instruction[] code;
     38    private int pc;
    4239    public IEnumerable<double> EstimatedValues(SymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
    4340      this.dataset = dataset;
     41      var compiler = new SymbolicExpressionTreeCompiler();
     42      code = compiler.Compile(tree);
    4443      foreach (var row in rows) {
    4544        this.row = row;
    46         var estimatedValue = Evaluate(tree.Root.SubTrees[0]);
     45        pc = 0;
     46        var estimatedValue = Evaluate();
    4747        if (double.IsNaN(estimatedValue) || double.IsInfinity(estimatedValue)) yield return 0.0;
    4848        else yield return estimatedValue;
     
    5050    }
    5151
    52     public override double Evaluate(SymbolicExpressionTreeNode node) {
    53       if (node.Symbol is HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols.Variable) {
    54         var variableTreeNode = node as VariableTreeNode;
    55         return dataset[row, dataset.VariableIndex(variableTreeNode.VariableName)] * variableTreeNode.Weight;
    56       } else if (node.Symbol is Constant) {
    57         return ((ConstantTreeNode)node).Value;
    58       } else {
    59         return base.Evaluate(node);
     52    public double Evaluate() {
     53      var currentInstr = code[pc++];
     54      switch (currentInstr.symbol) {
     55        case CodeSymbol.Add: {
     56            double s = 0.0;
     57            for (int i = 0; i < currentInstr.nArguments; i++) {
     58              s += Evaluate();
     59            }
     60            return s;
     61          }
     62        case CodeSymbol.Sub: {
     63            double s = Evaluate();
     64            for (int i = 1; i < currentInstr.nArguments; i++) {
     65              s -= Evaluate();
     66            }
     67            return s;
     68          }
     69        case CodeSymbol.Mul: {
     70            double p = Evaluate();
     71            for (int i = 1; i < currentInstr.nArguments; i++) {
     72              p *= Evaluate();
     73            }
     74            return p;
     75          }
     76        case CodeSymbol.Div: {
     77            double p = Evaluate();
     78            for (int i = 1; i < currentInstr.nArguments; i++) {
     79              p /= Evaluate();
     80            }
     81            return p;
     82          }
     83        case CodeSymbol.Dynamic: {
     84            if (currentInstr.dynamicNode is VariableTreeNode) {
     85              var variableTreeNode = currentInstr.dynamicNode as VariableTreeNode;
     86              return dataset[row, dataset.GetVariableIndex(variableTreeNode.VariableName)] * variableTreeNode.Weight;
     87            } else if (currentInstr.dynamicNode is ConstantTreeNode) {
     88              return ((ConstantTreeNode)currentInstr.dynamicNode).Value;
     89            } else throw new NotSupportedException();
     90          }
     91        default: throw new NotSupportedException();
    6092      }
    6193    }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionEvaluator.cs

    r3253 r3294  
    3939  [StorableClass]
    4040  public abstract class SymbolicRegressionEvaluator : SingleSuccessorOperator, ISymbolicRegressionEvaluator {
     41    private const string QualityParameterName = "Quality";
     42    private const string FunctionTreeParameterName = "FunctionTree";
     43    private const string RegressionProblemDataParameterName = "RegressionProblemData";
     44    private const string NumberOfEvaluatedNodexParameterName = "NumberOfEvaluatedNodes";
    4145    #region ISymbolicRegressionEvaluator Members
    4246
    4347    public ILookupParameter<DoubleValue> QualityParameter {
    44       get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
     48      get { return (ILookupParameter<DoubleValue>)Parameters[QualityParameterName]; }
    4549    }
    4650
    4751    public ILookupParameter<SymbolicExpressionTree> FunctionTreeParameter {
    48       get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["FunctionTree"]; }
     52      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters[FunctionTreeParameterName]; }
    4953    }
    5054
    51     public ILookupParameter<Dataset> DatasetParameter {
    52       get { return (ILookupParameter<Dataset>)Parameters["Dataset"]; }
     55    public ILookupParameter<RegressionProblemData> RegressionProblemDataParameter {
     56      get { return (ILookupParameter<RegressionProblemData>)Parameters[RegressionProblemDataParameterName]; }
    5357    }
    5458
    55     public ILookupParameter<StringValue> TargetVariableParameter {
    56       get { return (ILookupParameter<StringValue>)Parameters["TargetVariable"]; }
    57     }
     59    //public ILookupParameter<IntValue> SamplesStartParameter {
     60    //  get { return (ILookupParameter<IntValue>)Parameters["SamplesStart"]; }
     61    //}
    5862
    59     public ILookupParameter<IntValue> SamplesStartParameter {
    60       get { return (ILookupParameter<IntValue>)Parameters["SamplesStart"]; }
    61     }
    62 
    63     public ILookupParameter<IntValue> SamplesEndParameter {
    64       get { return (ILookupParameter<IntValue>)Parameters["SamplesEnd"]; }
    65     }
     63    //public ILookupParameter<IntValue> SamplesEndParameter {
     64    //  get { return (ILookupParameter<IntValue>)Parameters["SamplesEnd"]; }
     65    //}
    6666
    6767    public ILookupParameter<DoubleValue> NumberOfEvaluatedNodesParameter {
    68       get { return (ILookupParameter<DoubleValue>)Parameters["NumberOfEvaluatedNodes"]; }
     68      get { return (ILookupParameter<DoubleValue>)Parameters[NumberOfEvaluatedNodexParameterName]; }
    6969    }
    7070
     
    7373    public SymbolicRegressionEvaluator()
    7474      : base() {
    75       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the evaluated symbolic regression solution."));
    76       Parameters.Add(new LookupParameter<SymbolicExpressionTree>("FunctionTree", "The symbolic regression solution encoded as a symbolic expression tree."));
    77       Parameters.Add(new LookupParameter<Dataset>("Dataset", "The data set on which the symbolic regression solution should be evaluated."));
    78       Parameters.Add(new LookupParameter<StringValue>("TargetVariable", "The target variable of the symbolic regression solution."));
    79       Parameters.Add(new LookupParameter<IntValue>("SamplesStart", "The start index of the partition of the data set on which the symbolic regression solution should be evaluated."));
    80       Parameters.Add(new LookupParameter<IntValue>("SamplesEnd", "The end index of the partition of the data set on which the symbolic regression solution should be evaluated."));
    81       Parameters.Add(new LookupParameter<DoubleValue>("NumberOfEvaluatedNodes", "The number of evaluated nodes so far (for performance measurements.)"));
     75      Parameters.Add(new LookupParameter<DoubleValue>(QualityParameterName, "The quality of the evaluated symbolic regression solution."));
     76      Parameters.Add(new LookupParameter<SymbolicExpressionTree>(FunctionTreeParameterName, "The symbolic regression solution encoded as a symbolic expression tree."));
     77      Parameters.Add(new LookupParameter<RegressionProblemData>(RegressionProblemDataParameterName, "The data set on which the symbolic regression solution should be evaluated."));
     78      Parameters.Add(new LookupParameter<DoubleValue>(NumberOfEvaluatedNodexParameterName, "The number of evaluated nodes so far (for performance measurements.)"));
    8279    }
    8380
    8481    public override IOperation Apply() {
    8582      SymbolicExpressionTree solution = FunctionTreeParameter.ActualValue;
    86       Dataset dataset = DatasetParameter.ActualValue;
    87       StringValue targetVariable = TargetVariableParameter.ActualValue;
    88       IntValue samplesStart = SamplesStartParameter.ActualValue;
    89       IntValue samplesEnd = SamplesEndParameter.ActualValue;
     83      RegressionProblemData regressionProblemData = RegressionProblemDataParameter.ActualValue;
    9084      DoubleValue numberOfEvaluatedNodes = NumberOfEvaluatedNodesParameter.ActualValue;
    9185     
    92       QualityParameter.ActualValue = new DoubleValue(Evaluate(solution, dataset, targetVariable, samplesStart, samplesEnd, numberOfEvaluatedNodes));
     86      QualityParameter.ActualValue = new DoubleValue(Evaluate(solution, regressionProblemData.Dataset, regressionProblemData.TargetVariable, regressionProblemData.TrainingSamplesStart, regressionProblemData.TrainingSamplesEnd, numberOfEvaluatedNodes));
    9387      return null;
    9488    }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionMeanSquaredErrorEvaluator.cs

    r3257 r3294  
    4141  public class SymbolicRegressionMeanSquaredErrorEvaluator : SymbolicRegressionEvaluator {
    4242    protected override double Evaluate(SymbolicExpressionTree solution, Dataset dataset, StringValue targetVariable, IntValue samplesStart, IntValue samplesEnd, DoubleValue numberOfEvaluatedNodes) {
    43       double mse = Apply(solution, dataset, targetVariable.Value, samplesStart.Value, samplesEnd.Value);
     43      double mse = Calculate(solution, dataset, targetVariable.Value, samplesStart.Value, samplesEnd.Value);
    4444      numberOfEvaluatedNodes.Value += solution.Size * (samplesEnd.Value - samplesStart.Value);
    4545      return mse;
    4646    }
    4747
    48     public static double Apply(SymbolicExpressionTree solution, Dataset dataset, string targetVariable, int start, int end) {
     48    public static double Calculate(SymbolicExpressionTree solution, Dataset dataset, string targetVariable, int start, int end) {
    4949      SimpleArithmeticExpressionEvaluator evaluator = new SimpleArithmeticExpressionEvaluator();
     50      int targetVariableIndex = dataset.GetVariableIndex(targetVariable);
    5051      var estimatedValues = evaluator.EstimatedValues(solution, dataset, Enumerable.Range(start, end - start));
    51       var originalValues = dataset.VariableValues(targetVariable, start, end);
    52       var values = new DoubleMatrix(MatrixExtensions<double>.Create(estimatedValues.ToArray(), originalValues));
    53       return SimpleMSEEvaluator.Calculate(values);
     52      var originalValues = from row in Enumerable.Range(start, end - start) select dataset[row, targetVariableIndex];
     53      return SimpleMSEEvaluator.Calculate(originalValues, estimatedValues);
    5454    }
    5555  }
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/SymbolicRegressionProblem.cs

    r3269 r3294  
    7171      get { return (ValueParameter<DoubleValue>)Parameters["NumberOfEvaluatedNodes"]; }
    7272    }
     73    public ValueParameter<IntValue> MaxFunctionDefiningBranchesParameter {
     74      get { return (ValueParameter<IntValue>)Parameters["MaxFunctionDefiningBranches"]; }
     75    }
     76    public ValueParameter<IntValue> MaxFunctionArgumentsParameter {
     77      get { return (ValueParameter<IntValue>)Parameters["MaxFunctionArguments"]; }
     78    }
    7379    public OptionalValueParameter<ISingleObjectiveSolutionsVisualizer> VisualizerParameter {
    7480      get { return (OptionalValueParameter<ISingleObjectiveSolutionsVisualizer>)Parameters["Visualizer"]; }
     
    142148      Parameters.Add(new ValueParameter<IntValue>("MaxExpressionLength", "Maximal length of the symbolic expression.", new IntValue(100)));
    143149      Parameters.Add(new ValueParameter<IntValue>("MaxExpressionDepth", "Maximal depth of the symbolic expression.", new IntValue(10)));
     150      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionDefiningBranches", "Maximal number of automatically defined functions.", new IntValue(3)));
     151      Parameters.Add(new ValueParameter<IntValue>("MaxFunctionArguments", "Maximal number of arguments of automatically defined functions.", new IntValue(3)));
    144152      Parameters.Add(new ValueParameter<DoubleValue>("NumberOfEvaluatedNodes", "The total number of evaluated function tree nodes (for performance measurements.)", new DoubleValue()));
    145153      Parameters.Add(new ValueParameter<ISingleObjectiveSolutionsVisualizer>("Visualizer", "The operator which should be used to visualize artificial ant solutions.", null));
     
    147155      creator.SymbolicExpressionTreeParameter.ActualName = "SymbolicRegressionModel";
    148156      evaluator.QualityParameter.ActualName = "TrainingMeanSquaredError";
    149       InputVariablesParameter.ValueChanged += new EventHandler(InputVariablesParameter_ValueChanged);
     157      RegressionProblemDataParameter.ValueChanged += new EventHandler(RegressionProblemDataParameter_ValueChanged);
     158      RegressionProblemData.InputVariablesChanged += new EventHandler(RegressionProblemData_InputVariablesChanged);
    150159      ParameterizeSolutionCreator();
    151160      ParameterizeEvaluator();
     
    155164    }
    156165
    157     void InputVariablesParameter_ValueChanged(object sender, EventArgs e) {
    158       FunctionTreeGrammar.VariableNames = InputVariablesParameter.Value.Select(x => x.Value);
     166    void RegressionProblemDataParameter_ValueChanged(object sender, EventArgs e) {
     167      RegressionProblemData.InputVariablesChanged += new EventHandler(RegressionProblemData_InputVariablesChanged);
     168    }
     169
     170    void RegressionProblemData_InputVariablesChanged(object sender, EventArgs e) {
     171      FunctionTreeGrammar.VariableNames = RegressionProblemData.InputVariables.Select(x => x.Value);
    159172    }
    160173
     
    250263    private void ParameterizeEvaluator() {
    251264      Evaluator.FunctionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
    252       Evaluator.SamplesStartParameter.ActualName = TrainingSamplesStartParameter.Name;
    253       Evaluator.SamplesEndParameter.ActualName = TrainingSamplesEndParameter.Name;
     265      Evaluator.RegressionProblemDataParameter.ActualName = RegressionProblemDataParameter.Name;
    254266    }
    255267    private void ParameterizeVisualizer() {
     
    277289      foreach (ISymbolicRegressionEvaluator op in Operators.OfType<ISymbolicRegressionEvaluator>()) {
    278290        op.FunctionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
    279         op.DatasetParameter.ActualName = DatasetParameter.Name;
     291        op.RegressionProblemDataParameter.ActualName = RegressionProblemDataParameter.Name;
    280292        op.NumberOfEvaluatedNodesParameter.ActualName = NumberOfEvaluatedNodesParameter.Name;
    281         op.TargetVariableParameter.ActualName = TargetVariableParameter.Name;
    282         op.SamplesStartParameter.ActualName = TrainingSamplesStartParameter.Name;
    283         op.SamplesEndParameter.ActualName = TrainingSamplesEndParameter.Name;
    284293      }
    285294      foreach (SymbolicExpressionTreeCrossover op in Operators.OfType<SymbolicExpressionTreeCrossover>()) {
     
    287296        op.ChildParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
    288297      }
     298      foreach (SymbolicExpressionTreeManipulator op in Operators.OfType<SymbolicExpressionTreeManipulator>()) {
     299        op.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
     300      }
     301      foreach (SymbolicExpressionTreeArchitectureAlteringOperator op in Operators.OfType<SymbolicExpressionTreeArchitectureAlteringOperator>()) {
     302      }
    289303    }
    290304    #endregion
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Symbols/Constant.cs

    r3269 r3294  
    3131  [Item("Constant", "Represents a constant value.")]
    3232  public sealed class Constant : Symbol {
    33     #region Parameter Properties
    34     public IValueParameter<DoubleValue> MinValueParameter {
    35       get { return (IValueParameter<DoubleValue>)Parameters["MinValue"]; }
     33    #region Propeties
     34    private double minValue;
     35    public double MinValue {
     36      get { return minValue; }
     37      set { minValue = value; }
    3638    }
    37     public IValueParameter<DoubleValue> MaxValueParameter {
    38       get { return (IValueParameter<DoubleValue>)Parameters["MaxValue"]; }
    39     }
    40     #endregion
    41     #region Propeties
    42     public DoubleValue MinValue {
    43       get { return MinValueParameter.Value; }
    44       set { MinValueParameter.Value = value; }
    45     }
    46     public DoubleValue MaxValue {
    47       get { return MaxValueParameter.Value; }
    48       set { MaxValueParameter.Value = value; }
     39    private double maxValue;
     40    public double MaxValue {
     41      get { return maxValue; }
     42      set { maxValue = value; }
    4943    }
    5044    #endregion
    5145    public Constant()
    5246      : base() {
    53       Parameters.Add(new ValueParameter<DoubleValue>("MinValue", "The minimal value of the constant.", new DoubleValue(-20.0)));
    54       Parameters.Add(new ValueParameter<DoubleValue>("MaxValue", "The maximal value of the constant.", new DoubleValue(20.0)));
    5547    }
    5648
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Symbols/ConstantTreeNode.cs

    r3269 r3294  
    5555    public override void ResetLocalParameters(IRandom random) {
    5656      base.ResetLocalParameters(random);
    57       var range = Symbol.MaxValue.Value - Symbol.MaxValue.Value;
    58       Value = random.NextDouble() * range - Symbol.MinValue.Value;
     57      var range = Symbol.MaxValue - Symbol.MaxValue;
     58      Value = random.NextDouble() * range - Symbol.MinValue;
    5959    }
    6060
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Symbols/Variable.cs

    r3269 r3294  
    2727using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2828using HeuristicLab.Parameters;
     29using System.Collections.Generic;
     30using System;
    2931namespace HeuristicLab.Problems.DataAnalysis.Regression.Symbolic.Symbols {
    3032  [StorableClass]
    3133  [Item("Variable", "Represents a variable value.")]
    3234  public sealed class Variable : Symbol {
    33     #region Parameter Properties
    34     public IValueParameter<DoubleValue> WeightNuParameter {
    35       get { return (IValueParameter<DoubleValue>)Parameters["WeightNu"]; }
     35    #region Properties
     36    private double weightNu;
     37    [Storable]
     38    public double WeightNu {
     39      get { return weightNu; }
     40      set { weightNu = value; }
    3641    }
    37     public IValueParameter<DoubleValue> WeightSigmaParameter {
    38       get { return (IValueParameter<DoubleValue>)Parameters["WeightSigma"]; }
     42    private double weightSigma;
     43    [Storable]
     44    public double WeightSigma {
     45      get { return weightSigma; }
     46      set {
     47        if (weightSigma < 0.0) throw new ArgumentException("Negative sigma is not allowed.");
     48        weightSigma = value;
     49      }
    3950    }
    40     public IValueParameter<ItemList<StringValue>> VariableNamesParameter {
    41       get { return (IValueParameter<ItemList<StringValue>>)Parameters["VariableNames"]; }
    42     }
    43     #endregion
    44     #region Properties
    45     public DoubleValue WeightNu {
    46       get { return WeightNuParameter.Value; }
    47       set { WeightNuParameter.Value = value; }
    48     }
    49     public DoubleValue WeightSigma {
    50       get { return WeightSigmaParameter.Value; }
    51       set { WeightSigmaParameter.Value = value; }
    52     }
    53     public ItemList<StringValue> VariableNames {
    54       get { return VariableNamesParameter.Value; }
    55       set { VariableNamesParameter.Value = value; }
     51    private List<string> variableNames;
     52    [Storable]
     53    public ICollection<string> VariableNames {
     54      get { return variableNames; }
     55      set {
     56        if (value == null) throw new ArgumentNullException();
     57        variableNames.Clear();
     58        variableNames.AddRange(value);
     59      }
    5660    }
    5761    #endregion
    5862    public Variable()
    5963      : base() {
    60       Parameters.Add(new ValueParameter<DoubleValue>("WeightNu", "The mean value for the initialization of weight ((N(nu, sigma)).", new DoubleValue(1.0)));
    61       Parameters.Add(new ValueParameter<DoubleValue>("WeightSigma", "The sigma value for the initialization of weight (N(nu, sigma))", new DoubleValue(1.0)));
    62       Parameters.Add(new ValueParameter<ItemList<StringValue>>("VariableNames", "The list of possible variable names for initialization."));
     64      weightNu = 1.0;
     65      weightSigma = 1.0;
     66      variableNames = new List<string>();
    6367    }
    6468
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Regression/3.3/Symbolic/Symbols/VariableTreeNode.cs

    r3269 r3294  
    5757    public override void ResetLocalParameters(IRandom random) {
    5858      base.ResetLocalParameters(random);
    59       var normalDistributedRNG = new NormalDistributedRandom(random, Symbol.WeightNu.Value, Symbol.WeightSigma.Value);
     59      var normalDistributedRNG = new NormalDistributedRandom(random, Symbol.WeightNu, Symbol.WeightSigma);
    6060      weight = normalDistributedRNG.NextDouble();
    61       int variableIndex = random.Next(0, Symbol.VariableNames.Count);
    62       variableName = Symbol.VariableNames[variableIndex].Value;
     61      var variableList = new List<string>(Symbol.VariableNames);
     62      int variableIndex = random.Next(0, variableList.Count);
     63      variableName = variableList[variableIndex];
    6364    }
    6465
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Dataset.cs

    r3264 r3294  
    3535  [StorableClass]
    3636  public sealed class Dataset : NamedItem, IStringConvertibleMatrix {
    37     private Dictionary<int, Dictionary<int, double>>[] cachedMeans;
    38     private Dictionary<int, Dictionary<int, double>>[] cachedRanges;
    39     private bool cachedValuesInvalidated = true;
    40 
    4137    public Dataset()
    4238      : this(new string[] { "x" }, new double[,] { { 0.0 } }) {
     
    5349    }
    5450
     51    [Storable]
    5552    private StringArray variableNames;
    5653    public IEnumerable<string> VariableNames {
     
    5855    }
    5956
     57    [Storable]
    6058    private DoubleMatrix data;
    6159    private DoubleMatrix Data {
     
    9391    // access to full columns
    9492    public double[] this[string variableName] {
    95       get { return VariableValues(VariableIndex(variableName), 0, data.Rows); }
    96     }
    97 
    98     public double[] VariableValues(int variableIndex, int start, int end) {
     93      get { return GetVariableValues(GetVariableIndex(variableName), 0, data.Rows); }
     94    }
     95
     96    public double[] GetVariableValues(int variableIndex, int start, int end) {
    9997      if (start < 0 || !(start <= end))
    10098        throw new ArgumentException("Start must be between 0 and end (" + end + ").");
     
    108106    }
    109107
    110     public double[] VariableValues(string variableName, int start, int end) {
    111       return VariableValues(VariableIndex(variableName), start, end);
     108    public double[] GetVariableValues(string variableName, int start, int end) {
     109      return GetVariableValues(GetVariableIndex(variableName), start, end);
    112110    }
    113111
    114112    #region Variable name methods
    115     public string VariableName(int variableIndex) {
     113    public string GetVariableName(int variableIndex) {
    116114      return variableNames[variableIndex];
    117115    }
    118116
    119     public int VariableIndex(string variableName) {
     117    public int GetVariableIndex(string variableName) {
    120118      for (int i = 0; i < variableNames.Length; i++) {
    121119        if (variableNames[i].Equals(variableName)) return i;
     
    125123
    126124    public void SetVariableName(int variableIndex, string name) {
     125      if (variableNames.Contains(name)) throw new ArgumentException("The data set already contains a variable with name " + name + ".");
    127126      variableNames[variableIndex] = name;
    128127    }
     
    131130
    132131    #region variable statistics
    133     public double Mean(string variableName) {
    134       return Mean(VariableIndex(variableName));
    135     }
    136 
    137     public double Mean(string variableName, int start, int end) {
    138       return Mean(VariableIndex(variableName), start, end);
    139     }
    140 
    141     public double Mean(int variableIndex) {
    142       return Mean(variableIndex, 0, data.Rows);
    143     }
    144 
    145     public double Mean(int variableIndex, int start, int end) {
    146       if (cachedValuesInvalidated) CreateDictionaries();
    147       if (!cachedMeans[variableIndex].ContainsKey(start) || !cachedMeans[variableIndex][start].ContainsKey(end)) {
    148         double mean = VariableValues(variableIndex, start, end).Average();
    149         if (!cachedMeans[variableIndex].ContainsKey(start)) cachedMeans[variableIndex][start] = new Dictionary<int, double>();
    150         cachedMeans[variableIndex][start][end] = mean;
    151         return mean;
    152       } else {
    153         return cachedMeans[variableIndex][start][end];
    154       }
    155     }
    156 
    157     public double Range(string variableName) {
    158       return Range(VariableIndex(variableName));
    159     }
    160 
    161     public double Range(int variableIndex) {
    162       return Range(variableIndex, 0, data.Rows);
    163     }
    164 
    165     public double Range(string variableName, int start, int end) {
    166       return Range(VariableIndex(variableName), start, end);
    167     }
    168 
    169     public double Range(int variableIndex, int start, int end) {
    170       if (cachedValuesInvalidated) CreateDictionaries();
    171       if (!cachedRanges[variableIndex].ContainsKey(start) || !cachedRanges[variableIndex][start].ContainsKey(end)) {
    172         var values = VariableValues(variableIndex, start, end);
    173         double range = values.Max() - values.Min();
    174         if (!cachedRanges[variableIndex].ContainsKey(start)) cachedRanges[variableIndex][start] = new Dictionary<int, double>();
    175         cachedRanges[variableIndex][start][end] = range;
    176         return range;
    177       } else {
    178         return cachedRanges[variableIndex][start][end];
    179       }
    180     }
    181 
    182     public double Max(string variableName) {
    183       return Max(VariableIndex(variableName));
    184     }
    185 
    186     public double Max(int variableIndex) {
    187       return Max(variableIndex, 0, data.Rows);
    188     }
    189 
    190     public double Max(string variableName, int start, int end) {
    191       return Max(VariableIndex(variableName), start, end);
    192     }
    193 
    194     public double Max(int variableIndex, int start, int end) {
    195       return VariableValues(variableIndex, start, end).Max();
    196     }
    197 
    198     public double Min(string variableName) {
    199       return Min(VariableIndex(variableName));
    200     }
    201 
    202     public double Min(int variableIndex) {
    203       return Min(variableIndex, 0, data.Rows);
    204     }
    205 
    206     public double Min(string variableName, int start, int end) {
    207       return Min(VariableIndex(variableName), start, end);
    208     }
    209 
    210     public double Min(int variableIndex, int start, int end) {
    211       return VariableValues(variableIndex, start, end).Min();
    212     }
    213 
    214     public int MissingValues(string variableName) {
    215       return MissingValues(VariableIndex(variableName));
    216     }
    217     public int MissingValues(int variableIndex) {
    218       return MissingValues(variableIndex, 0, data.Rows);
    219     }
    220 
    221     public int MissingValues(string variableName, int start, int end) {
    222       return MissingValues(VariableIndex(variableName), start, end);
    223     }
    224 
    225     public int MissingValues(int variableIndex, int start, int end) {
    226       return VariableValues(variableIndex, start, end).Count(x => double.IsNaN(x));
     132    public double GetMean(string variableName) {
     133      return GetMean(GetVariableIndex(variableName));
     134    }
     135
     136    public double GetMean(string variableName, int start, int end) {
     137      return GetMean(GetVariableIndex(variableName), start, end);
     138    }
     139
     140    public double GetMean(int variableIndex) {
     141      return GetMean(variableIndex, 0, data.Rows);
     142    }
     143
     144    public double GetMean(int variableIndex, int start, int end) {
     145      return GetVariableValues(variableIndex, start, end).Average();
     146    }
     147
     148    public double GetRange(string variableName) {
     149      return GetRange(GetVariableIndex(variableName));
     150    }
     151
     152    public double GetRange(int variableIndex) {
     153      return GetRange(variableIndex, 0, data.Rows);
     154    }
     155
     156    public double GetRange(string variableName, int start, int end) {
     157      return GetRange(GetVariableIndex(variableName), start, end);
     158    }
     159
     160    public double GetRange(int variableIndex, int start, int end) {
     161      var values = GetVariableValues(variableIndex, start, end);
     162      return values.Max() - values.Min();
     163    }
     164
     165    public double GetMax(string variableName) {
     166      return GetMax(GetVariableIndex(variableName));
     167    }
     168
     169    public double GetMax(int variableIndex) {
     170      return GetMax(variableIndex, 0, data.Rows);
     171    }
     172
     173    public double GetMax(string variableName, int start, int end) {
     174      return GetMax(GetVariableIndex(variableName), start, end);
     175    }
     176
     177    public double GetMax(int variableIndex, int start, int end) {
     178      return GetVariableValues(variableIndex, start, end).Max();
     179    }
     180
     181    public double GetMin(string variableName) {
     182      return GetMin(GetVariableIndex(variableName));
     183    }
     184
     185    public double GetMin(int variableIndex) {
     186      return GetMin(variableIndex, 0, data.Rows);
     187    }
     188
     189    public double GetMin(string variableName, int start, int end) {
     190      return GetMin(GetVariableIndex(variableName), start, end);
     191    }
     192
     193    public double GetMin(int variableIndex, int start, int end) {
     194      return GetVariableValues(variableIndex, start, end).Min();
     195    }
     196
     197    public int GetMissingValues(string variableName) {
     198      return GetMissingValues(GetVariableIndex(variableName));
     199    }
     200    public int GetMissingValues(int variableIndex) {
     201      return GetMissingValues(variableIndex, 0, data.Rows);
     202    }
     203
     204    public int GetMissingValues(string variableName, int start, int end) {
     205      return GetMissingValues(GetVariableIndex(variableName), start, end);
     206    }
     207
     208    public int GetMissingValues(int variableIndex, int start, int end) {
     209      return GetVariableValues(variableIndex, start, end).Count(x => double.IsNaN(x));
    227210    }
    228211
    229212    #endregion
    230 
    231     private void CreateDictionaries() {
    232       // keep a means and ranges dictionary for each column (possible target variable) of the dataset.
    233       cachedMeans = new Dictionary<int, Dictionary<int, double>>[data.Columns];
    234       cachedRanges = new Dictionary<int, Dictionary<int, double>>[data.Columns];
    235       for (int i = 0; i < data.Columns; i++) {
    236         cachedMeans[i] = new Dictionary<int, Dictionary<int, double>>();
    237         cachedRanges[i] = new Dictionary<int, Dictionary<int, double>>();
    238       }
    239       cachedValuesInvalidated = false;
    240     }
    241213
    242214    public override IDeepCloneable Clone(Cloner cloner) {
     
    250222    public event EventHandler<EventArgs<int, int>> DataChanged;
    251223    private void OnDataChanged(EventArgs<int, int> e) {
    252       cachedValuesInvalidated = true;
    253 
    254224      var listeners = DataChanged;
    255225      if (listeners != null) listeners(this, e);
     
    257227    public event EventHandler Reset;
    258228    private void OnReset(EventArgs e) {
    259       cachedValuesInvalidated = true;
    260 
    261229      var listeners = Reset;
    262230      if (listeners != null) listeners(this, e);
     
    305273            }
    306274          }
    307           string formatString = new StringBuilder().Append('#', (int)Math.Log10(value) + 1).ToString(); // >= 100 variables => ###
     275          string formatString = new StringBuilder().Append('0', (int)Math.Log10(value) + 1).ToString(); // >= 100 variables => ###
    308276          for (int column = 0; column < value; column++) {
    309277            if (column < data.Columns)
     
    334302    public bool SetValue(string value, int rowIndex, int columnIndex) {
    335303      if (rowIndex == 0) {
    336         // set variable name
    337         variableNames[columnIndex] = value;
    338         return true;
     304        // check if the variable name is already used
     305        if (variableNames.Contains(value)) {
     306          return false;
     307        } else {
     308          variableNames[columnIndex] = value;
     309          return true;
     310        }
    339311      } else {
    340312        double v;
  • trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMSEEvaluator.cs

    r3253 r3294  
    3939    }
    4040
    41     public static double Calculate(DoubleMatrix values) {
    42       double sse = 0;
    43       double cnt = 0;
    44       for (int i = 0; i < values.Rows; i++) {
    45         double estimated = values[i, ESTIMATION_INDEX];
    46         double target = values[i, ORIGINAL_INDEX];
    47         if (!double.IsNaN(estimated) && !double.IsInfinity(estimated) &&
    48             !double.IsNaN(target) && !double.IsInfinity(target)) {
    49           double error = estimated - target;
     41    public static double Calculate(IEnumerable<double> original, IEnumerable<double> estimated) {
     42      double sse = 0.0;
     43      int cnt = 0;
     44      var originalEnumerator = original.GetEnumerator();
     45      var estimatedEnumerator = estimated.GetEnumerator();
     46      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
     47        double e = estimatedEnumerator.Current;
     48        double o = originalEnumerator.Current;
     49        if (!double.IsNaN(e) && !double.IsInfinity(e) &&
     50            !double.IsNaN(o) && !double.IsInfinity(o)) {
     51          double error = e - o;
    5052          sse += error * error;
    5153          cnt++;
    5254        }
    5355      }
    54       if (cnt > 0) {
     56      if (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext()) {
     57        throw new ArgumentException("Number of elements in original and estimated enumeration doesn't match.");
     58      } else if (cnt == 0) {
     59        throw new ArgumentException("Mean squared errors is not defined for input vectors of NaN or Inf");
     60      } else {
    5561        double mse = sse / cnt;
    5662        return mse;
    57       } else {
    58         throw new ArgumentException("Mean squared errors is not defined for input vectors of NaN or Inf");
    5963      }
     64    }
     65
     66    public static double Calculate(DoubleMatrix values) {
     67      var original = from row in Enumerable.Range(0, values.Rows)
     68                     select values[row, ORIGINAL_INDEX];
     69      var estimated = from row in Enumerable.Range(0, values.Rows)
     70                      select values[row, ORIGINAL_INDEX];
     71      return Calculate(original, estimated);
    6072    }
    6173  }
Note: See TracChangeset for help on using the changeset viewer.