Changeset 14351


Ignore:
Timestamp:
10/23/16 09:44:29 (6 years ago)
Author:
gkronber
Message:

#2650: merged r14332:14350 from trunk to branch

Location:
branches/symbreg-factors-2650
Files:
47 edited
14 copied

Legend:

Unmodified
Added
Removed
  • branches/symbreg-factors-2650

  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis

  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis.Views

  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/HeuristicLab.Algorithms.DataAnalysis.Views-3.4.csproj

    r14242 r14351  
    131131      <DependentUpon>OneFactorClassificationModelView.cs</DependentUpon>
    132132    </Compile>
     133    <Compile Include="RandomForestClassificationSolutionView.cs">
     134      <SubType>UserControl</SubType>
     135    </Compile>
     136    <Compile Include="RandomForestClassificationSolutionView.Designer.cs">
     137      <DependentUpon>RandomForestClassificationSolutionView.cs</DependentUpon>
     138    </Compile>
     139    <Compile Include="RandomForestModelView.cs">
     140      <SubType>UserControl</SubType>
     141    </Compile>
     142    <Compile Include="RandomForestModelView.Designer.cs">
     143      <DependentUpon>RandomForestModelView.cs</DependentUpon>
     144    </Compile>
     145    <Compile Include="RandomForestRegressionSolutionView.cs">
     146      <SubType>UserControl</SubType>
     147    </Compile>
     148    <Compile Include="RandomForestRegressionSolutionView.Designer.cs">
     149      <DependentUpon>RandomForestRegressionSolutionView.cs</DependentUpon>
     150    </Compile>
     151    <Compile Include="GradientBoostedTreesModelView.cs">
     152      <SubType>UserControl</SubType>
     153    </Compile>
     154    <Compile Include="GradientBoostedTreesModelView.Designer.cs">
     155      <DependentUpon>GradientBoostedTreesModelView.cs</DependentUpon>
     156    </Compile>
    133157    <Compile Include="MeanProdView.cs">
    134158      <SubType>UserControl</SubType>
     
    198222    <Compile Include="SupportVectorMachineModelView.Designer.cs">
    199223      <DependentUpon>SupportVectorMachineModelView.cs</DependentUpon>
     224    </Compile>
     225    <Compile Include="GradientBoostedTreesSolutionView.cs">
     226      <SubType>UserControl</SubType>
     227    </Compile>
     228    <Compile Include="GradientBoostedTreesSolutionView.Designer.cs">
     229      <DependentUpon>GradientBoostedTreesSolutionView.cs</DependentUpon>
    200230    </Compile>
    201231  </ItemGroup>
     
    251281      <Private>False</Private>
    252282    </ProjectReference>
     283    <ProjectReference Include="..\..\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding\3.4\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj">
     284      <Project>{06D4A186-9319-48A0-BADE-A2058D462EEA}</Project>
     285      <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
     286    </ProjectReference>
    253287    <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
    254288      <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
     
    275309      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
    276310      <Private>False</Private>
     311    </ProjectReference>
     312    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic.Classification\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.csproj">
     313      <Project>{05BAE4E1-A9FA-4644-AA77-42558720159E}</Project>
     314      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4</Name>
     315    </ProjectReference>
     316    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.csproj">
     317      <Project>{5AC82412-911B-4FA2-A013-EDC5E3F3FCC2}</Project>
     318      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4</Name>
     319    </ProjectReference>
     320    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic.Views\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj">
     321      <Project>{7a2531ce-3f7c-4f13-bcca-ed6dc27a7086}</Project>
     322      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4</Name>
     323    </ProjectReference>
     324    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj">
     325      <Project>{3d28463f-ec96-4d82-afee-38be91a0ca00}</Project>
     326      <Name>HeuristicLab.Problems.DataAnalysis.Symbolic-3.4</Name>
    277327    </ProjectReference>
    278328    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis.Views\3.4\HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj">
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/KMeansClusteringModelView.cs

    r14185 r14351  
    1919 */
    2020#endregion
    21 using System;
    2221using System.Linq;
    23 using System.IO;
    24 using System.Windows.Forms;
    2522using HeuristicLab.MainForm;
    2623using HeuristicLab.MainForm.WindowsForms;
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/Plugin.cs.frame

    r14195 r14351  
    3737  [PluginDependency("HeuristicLab.Data", "3.3")]
    3838  [PluginDependency("HeuristicLab.Data.Views", "3.3")]
     39  [PluginDependency("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding", "3.4")]
    3940  [PluginDependency("HeuristicLab.LibSVM", "3.12")]
    4041  [PluginDependency("HeuristicLab.MainForm", "3.3")]
     
    4445  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
    4546  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Views", "3.4")]
     47  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
     48  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Regression", "3.4")]
     49  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic.Classification", "3.4")]
    4650  public class HeuristicLabAlgorithmsDataAnalysisViewsPlugin : PluginBase {
    4751  }
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesAlgorithm.cs

    r14185 r14351  
    269269        } else {
    270270          // otherwise we produce a regression solution
    271           Results.Add(new Result("Solution", new RegressionSolution(model, problemData)));
     271          Results.Add(new Result("Solution", new GradientBoostedTreesSolution(model, problemData)));
    272272        }
    273273      }
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesSolution.cs

    r14185 r14351  
    2020#endregion
    2121
    22 using System.Collections.Generic;
    23 using System.Linq;
    2422using HeuristicLab.Common;
    2523using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeModel.cs

    r14185 r14351  
    2828using HeuristicLab.Common;
    2929using HeuristicLab.Core;
     30using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    3031using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    3132using HeuristicLab.Problems.DataAnalysis;
     33using HeuristicLab.Problems.DataAnalysis.Symbolic;
     34using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
    3235
    3336namespace HeuristicLab.Algorithms.DataAnalysis {
     
    210213    }
    211214
     215    /// <summary>
     216    /// Transforms the tree model to a symbolic regression solution
     217    /// </summary>
     218    /// <param name="problemData"></param>
     219    /// <returns>A new symbolic regression solution which matches the tree model</returns>
     220    public ISymbolicRegressionSolution CreateSymbolicRegressionSolution(IRegressionProblemData problemData) {
     221      var rootSy = new ProgramRootSymbol();
     222      var startSy = new StartSymbol();
     223      var varCondSy = new VariableCondition() { IgnoreSlope = true };
     224      var constSy = new Constant();
     225
     226      var startNode = startSy.CreateTreeNode();
     227      startNode.AddSubtree(CreateSymbolicRegressionTreeRecursive(tree, 0, varCondSy, constSy));
     228      var rootNode = rootSy.CreateTreeNode();
     229      rootNode.AddSubtree(startNode);
     230      var model = new SymbolicRegressionModel(TargetVariable, new SymbolicExpressionTree(rootNode), new SymbolicDataAnalysisExpressionTreeLinearInterpreter());
     231      return model.CreateRegressionSolution(problemData);
     232    }
     233
     234    private ISymbolicExpressionTreeNode CreateSymbolicRegressionTreeRecursive(TreeNode[] treeNodes, int nodeIdx, VariableCondition varCondSy, Constant constSy) {
     235      var curNode = treeNodes[nodeIdx];
     236      if (curNode.VarName == TreeNode.NO_VARIABLE) {
     237        var node = (ConstantTreeNode)constSy.CreateTreeNode();
     238        node.Value = curNode.Val;
     239        return node;
     240      } else {
     241        var node = (VariableConditionTreeNode)varCondSy.CreateTreeNode();
     242        node.VariableName = curNode.VarName;
     243        node.Threshold = curNode.Val;
     244
     245        var left = CreateSymbolicRegressionTreeRecursive(treeNodes, curNode.LeftIdx, varCondSy, constSy);
     246        var right = CreateSymbolicRegressionTreeRecursive(treeNodes, curNode.RightIdx, varCondSy, constSy);
     247        node.AddSubtree(left);
     248        node.AddSubtree(right);
     249        return node;
     250      }
     251    }
     252
     253
    212254    private string TreeToString(int idx, string part) {
    213255      var n = tree[idx];
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestClassificationSolution.cs

    r14185 r14351  
    3030  public interface IRandomForestClassificationSolution : IClassificationSolution {
    3131    new IRandomForestModel Model { get; }
     32    int NumberOfTrees { get; }
    3233  }
    3334}
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestModel.cs

    r14185 r14351  
    2020#endregion
    2121
    22 using HeuristicLab.Optimization;
     22using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2323using HeuristicLab.Problems.DataAnalysis;
    24 using HeuristicLab.Core;
    25 using System.Collections.Generic;
     24
    2625
    2726namespace HeuristicLab.Algorithms.DataAnalysis {
     
    3029  /// </summary>
    3130  public interface IRandomForestModel : IConfidenceRegressionModel, IClassificationModel {
     31    int NumberOfTrees { get; }
     32    ISymbolicExpressionTree ExtractTree(int treeIdx); // returns a specific tree from the random forest as a ISymbolicRegressionModel
    3233  }
    3334}
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/Interfaces/IRandomForestRegressionSolution.cs

    r14185 r14351  
    2020#endregion
    2121
    22 using HeuristicLab.Optimization;
    2322using HeuristicLab.Problems.DataAnalysis;
    24 using HeuristicLab.Core;
     23using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
    2524
    2625namespace HeuristicLab.Algorithms.DataAnalysis {
     
    3029  public interface IRandomForestRegressionSolution : IConfidenceRegressionSolution {
    3130    new IRandomForestModel Model { get; }
     31    int NumberOfTrees { get; }
    3232  }
    3333}
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs

    r14185 r14351  
    3838    }
    3939
     40    public int NumberOfTrees {
     41      get { return Model.NumberOfTrees; }
     42    }
     43
    4044    [StorableConstructor]
    4145    private RandomForestClassificationSolution(bool deserializing) : base(deserializing) { }
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs

    r14230 r14351  
    2525using HeuristicLab.Common;
    2626using HeuristicLab.Core;
     27using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2728using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2829using HeuristicLab.Problems.DataAnalysis;
     30using HeuristicLab.Problems.DataAnalysis.Symbolic;
    2931
    3032namespace HeuristicLab.Algorithms.DataAnalysis {
     
    4951    }
    5052
     53    public int NumberOfTrees {
     54      get { return nTrees; }
     55    }
    5156
    5257    // instead of storing the data of the model itself
     
    6469    [Storable]
    6570    private double m;
    66 
    6771
    6872    [StorableConstructor]
     
    197201    }
    198202
     203    public ISymbolicExpressionTree ExtractTree(int treeIdx) {
     204      // hoping that the internal representation of alglib is stable
     205
     206      // TREE FORMAT
     207      // W[Offs]      -   size of sub-array (for the tree)
     208      //     node info:
     209      // W[K+0]       -   variable number        (-1 for leaf mode)
     210      // W[K+1]       -   threshold              (class/value for leaf node)
     211      // W[K+2]       -   ">=" branch index      (absent for leaf node)
     212
     213      // skip irrelevant trees
     214      int offset = 0;
     215      for (int i = 0; i < treeIdx - 1; i++) {
     216        offset = offset + (int)Math.Round(randomForest.innerobj.trees[offset]);
     217      }
     218
     219      var constSy = new Constant();
     220      var varCondSy = new VariableCondition() { IgnoreSlope = true };
     221
     222      var node = CreateRegressionTreeRec(randomForest.innerobj.trees, offset, offset + 1, constSy, varCondSy);
     223
     224      var startNode = new StartSymbol().CreateTreeNode();
     225      startNode.AddSubtree(node);
     226      var root = new ProgramRootSymbol().CreateTreeNode();
     227      root.AddSubtree(startNode);
     228      return new SymbolicExpressionTree(root);
     229    }
     230
     231    private ISymbolicExpressionTreeNode CreateRegressionTreeRec(double[] trees, int offset, int k, Constant constSy, VariableCondition varCondSy) {
     232
     233      // alglib source for evaluation of one tree (dfprocessinternal)
     234      // offs = 0
     235      //
     236      // Set pointer to the root
     237      //
     238      // k = offs + 1;
     239      //
     240      // //
     241      // // Navigate through the tree
     242      // //
     243      // while (true) {
     244      //   if ((double)(df.trees[k]) == (double)(-1)) {
     245      //     if (df.nclasses == 1) {
     246      //       y[0] = y[0] + df.trees[k + 1];
     247      //     } else {
     248      //       idx = (int)Math.Round(df.trees[k + 1]);
     249      //       y[idx] = y[idx] + 1;
     250      //     }
     251      //     break;
     252      //   }
     253      //   if ((double)(x[(int)Math.Round(df.trees[k])]) < (double)(df.trees[k + 1])) {
     254      //     k = k + innernodewidth;
     255      //   } else {
     256      //     k = offs + (int)Math.Round(df.trees[k + 2]);
     257      //   }
     258      // }
     259
     260      if ((double)(trees[k]) == (double)(-1)) {
     261        var constNode = (ConstantTreeNode)constSy.CreateTreeNode();
     262        constNode.Value = trees[k + 1];
     263        return constNode;
     264      } else {
     265        var condNode = (VariableConditionTreeNode)varCondSy.CreateTreeNode();
     266        condNode.VariableName = AllowedInputVariables[(int)Math.Round(trees[k])];
     267        condNode.Threshold = trees[k + 1];
     268        condNode.Slope = double.PositiveInfinity;
     269
     270        var left = CreateRegressionTreeRec(trees, offset, k + 3, constSy, varCondSy);
     271        var right = CreateRegressionTreeRec(trees, offset, offset + (int)Math.Round(trees[k + 2]), constSy, varCondSy);
     272
     273        condNode.AddSubtree(left); // not 100% correct because interpreter uses: if(x <= thres) left() else right() and RF uses if(x < thres) left() else right() (see above)
     274        condNode.AddSubtree(right);
     275        return condNode;
     276      }
     277    }
     278
    199279
    200280    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
  • branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs

    r14185 r14351  
    2020#endregion
    2121
     22using System;
    2223using HeuristicLab.Common;
    2324using HeuristicLab.Core;
    2425using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
    2526using HeuristicLab.Problems.DataAnalysis;
     27using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
    2628
    2729namespace HeuristicLab.Algorithms.DataAnalysis {
     
    3638      get { return (IRandomForestModel)base.Model; }
    3739      set { base.Model = value; }
     40    }
     41
     42    public int NumberOfTrees {
     43      get { return Model.NumberOfTrees; }
    3844    }
    3945
  • branches/symbreg-factors-2650/HeuristicLab.DataPreprocessing/3.4

  • branches/symbreg-factors-2650/HeuristicLab.DataPreprocessing/3.4/PreprocessingContext.cs

    r14185 r14351  
    6767      if (problemData == null) throw new ArgumentNullException("problemData");
    6868      if (source != null && ExtractProblemData(source) != problemData)
    69         throw new ArgumentException("The ProblemData extracted from the Source is different than the given ProblemData.");
     69        source = null; // ignore the source if the source's problem data is different
    7070      Source = source ?? problemData;
    7171      var namedSource = Source as INamedItem;
  • branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding

  • branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Grammars/SymbolicExpressionGrammarBase.cs

    r14185 r14351  
    8282    protected SymbolicExpressionGrammarBase(bool deserializing)
    8383      : base(deserializing) {
    84       cachedMinExpressionLength = new Dictionary<string, int>();
    85       cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
    86       cachedMinExpressionDepth = new Dictionary<string, int>();
    87       cachedMaxExpressionDepth = new Dictionary<string, int>();
    88 
    89       cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
    90       cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
    9184
    9285      symbols = new Dictionary<string, ISymbol>();
     
    10093    protected SymbolicExpressionGrammarBase(SymbolicExpressionGrammarBase original, Cloner cloner)
    10194      : base(original, cloner) {
    102       cachedMinExpressionLength = new Dictionary<string, int>();
    103       cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
    104       cachedMinExpressionDepth = new Dictionary<string, int>();
    105       cachedMaxExpressionDepth = new Dictionary<string, int>();
    106 
    107       cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
    108       cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
    10995
    11096      symbols = original.symbols.ToDictionary(x => x.Key, y => cloner.Clone(y.Value));
     
    124110    protected SymbolicExpressionGrammarBase(string name, string description)
    125111      : base(name, description) {
    126       cachedMinExpressionLength = new Dictionary<string, int>();
    127       cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
    128       cachedMinExpressionDepth = new Dictionary<string, int>();
    129       cachedMaxExpressionDepth = new Dictionary<string, int>();
    130 
    131       cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
    132       cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
    133 
    134112      symbols = new Dictionary<string, ISymbol>();
    135113      symbolSubtreeCount = new Dictionary<string, Tuple<int, int>>();
     
    322300    }
    323301
    324     private readonly Dictionary<Tuple<string, string>, bool> cachedIsAllowedChildSymbol;
     302    private readonly Dictionary<Tuple<string, string>, bool> cachedIsAllowedChildSymbol = new Dictionary<Tuple<string, string>, bool>();
    325303    public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child) {
    326304      if (allowedChildSymbols.Count == 0) return false;
     
    352330    }
    353331
    354     private readonly Dictionary<Tuple<string, string, int>, bool> cachedIsAllowedChildSymbolIndex;
     332    private readonly Dictionary<Tuple<string, string, int>, bool> cachedIsAllowedChildSymbolIndex = new Dictionary<Tuple<string, string, int>, bool>();
    355333    public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
    356334      if (!child.Enabled) return false;
     
    412390    }
    413391
    414     private readonly Dictionary<string, int> cachedMinExpressionLength;
     392    private readonly Dictionary<string, int> cachedMinExpressionLength = new Dictionary<string, int>();
    415393    public int GetMinimumExpressionLength(ISymbol symbol) {
    416394      int res;
     
    423401        if (cachedMinExpressionLength.TryGetValue(symbol.Name, out res)) return res;
    424402
    425         res = GetMinimumExpressionLengthRec(symbol);
    426         foreach (var entry in cachedMinExpressionLength.Where(e => e.Value >= int.MaxValue).ToList()) {
    427           if (entry.Key != symbol.Name) cachedMinExpressionLength.Remove(entry.Key);
    428         }
    429         return res;
    430       }
    431     }
    432 
    433     private int GetMinimumExpressionLengthRec(ISymbol symbol) {
    434       int temp;
    435       if (!cachedMinExpressionLength.TryGetValue(symbol.Name, out temp)) {
    436         cachedMinExpressionLength[symbol.Name] = int.MaxValue; // prevent infinite recursion
    437         long sumOfMinExpressionLengths = 1 + (from argIndex in Enumerable.Range(0, GetMinimumSubtreeCount(symbol))
    438                                               let minForSlot = (long)(from s in GetAllowedChildSymbols(symbol, argIndex)
    439                                                                       where s.InitialFrequency > 0.0
    440                                                                       select GetMinimumExpressionLengthRec(s)).DefaultIfEmpty(0).Min()
    441                                               select minForSlot).DefaultIfEmpty(0).Sum();
    442 
    443         cachedMinExpressionLength[symbol.Name] = (int)Math.Min(sumOfMinExpressionLengths, int.MaxValue);
     403        GrammarUtils.CalculateMinimumExpressionLengths(this, cachedMinExpressionLength);
    444404        return cachedMinExpressionLength[symbol.Name];
    445405      }
    446       return temp;
    447     }
    448 
    449     private readonly Dictionary<Tuple<string, int>, int> cachedMaxExpressionLength;
     406    }
     407
     408
     409    private readonly Dictionary<Tuple<string, int>, int> cachedMaxExpressionLength = new Dictionary<Tuple<string, int>, int>();
    450410    public int GetMaximumExpressionLength(ISymbol symbol, int maxDepth) {
    451411      int temp;
     
    469429    }
    470430
    471     private readonly Dictionary<string, int> cachedMinExpressionDepth;
     431    private readonly Dictionary<string, int> cachedMinExpressionDepth = new Dictionary<string, int>();
    472432    public int GetMinimumExpressionDepth(ISymbol symbol) {
    473433      int res;
     
    480440        if (cachedMinExpressionDepth.TryGetValue(symbol.Name, out res)) return res;
    481441
    482         res = GetMinimumExpressionDepthRec(symbol);
    483         foreach (var entry in cachedMinExpressionDepth.Where(e => e.Value >= int.MaxValue).ToList()) {
    484           if (entry.Key != symbol.Name) cachedMinExpressionDepth.Remove(entry.Key);
    485         }
    486         return res;
    487       }
    488     }
    489     private int GetMinimumExpressionDepthRec(ISymbol symbol) {
    490       int temp;
    491       if (!cachedMinExpressionDepth.TryGetValue(symbol.Name, out temp)) {
    492         cachedMinExpressionDepth[symbol.Name] = int.MaxValue; // prevent infinite recursion
    493         long minDepth = 1 + (from argIndex in Enumerable.Range(0, GetMinimumSubtreeCount(symbol))
    494                              let minForSlot = (long)(from s in GetAllowedChildSymbols(symbol, argIndex)
    495                                                      where s.InitialFrequency > 0.0
    496                                                      select GetMinimumExpressionDepthRec(s)).DefaultIfEmpty(0).Min()
    497                              select minForSlot).DefaultIfEmpty(0).Max();
    498         cachedMinExpressionDepth[symbol.Name] = (int)Math.Min(minDepth, int.MaxValue);
     442        GrammarUtils.CalculateMinimumExpressionDepth(this, cachedMinExpressionDepth);
    499443        return cachedMinExpressionDepth[symbol.Name];
    500444      }
    501       return temp;
    502     }
    503 
    504     private readonly Dictionary<string, int> cachedMaxExpressionDepth;
     445    }
     446
     447    private readonly Dictionary<string, int> cachedMaxExpressionDepth = new Dictionary<string, int>();
    505448    public int GetMaximumExpressionDepth(ISymbol symbol) {
    506449      int temp;
  • branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj

    r12897 r14351  
    129129    <Compile Include="ArchitectureManipulators\SubroutineDuplicater.cs" />
    130130    <Compile Include="ArchitectureManipulators\SymbolicExpressionTreeArchitectureManipulator.cs" />
     131    <Compile Include="Grammars\GrammarUtils.cs" />
    131132    <Compile Include="SymbolicExpressionTreeProblem.cs" />
    132133    <Compile Include="Compiler\Instruction.cs" />
  • branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeEncoding.cs

    r14185 r14351  
    164164    public SymbolicExpressionTreeEncoding(string name, ISymbolicExpressionGrammar grammar, int maximumLength, int maximumDepth)
    165165      : base(name) {
    166       treeLengthParameter = new FixedValueParameter<IntValue>("Maximum Tree Length", "Maximal length of the symbolic expression.", new IntValue(maximumLength));
    167       treeDepthParameter = new FixedValueParameter<IntValue>("Maximum Tree Depth", "Maximal depth of the symbolic expression. The minimum depth needed for the algorithm is 3 because two levels are reserved for the ProgramRoot and the Start symbol.", new IntValue(maximumDepth));
    168       grammarParameter = new ValueParameter<ISymbolicExpressionGrammar>("Grammar", "The grammar that should be used for symbolic expression tree.", grammar);
    169       functionDefinitionsParameter = new FixedValueParameter<IntValue>("Function Definitions", "Maximal number of automatically defined functions", new IntValue(0));
    170       functionArgumentsParameter = new FixedValueParameter<IntValue>("Function Arguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0));
     166      treeLengthParameter = new FixedValueParameter<IntValue>(Name + ".Maximum Tree Length", "Maximal length of the symbolic expression.", new IntValue(maximumLength));
     167      treeDepthParameter = new FixedValueParameter<IntValue>(Name + ".Maximum Tree Depth", "Maximal depth of the symbolic expression. The minimum depth needed for the algorithm is 3 because two levels are reserved for the ProgramRoot and the Start symbol.", new IntValue(maximumDepth));
     168      grammarParameter = new ValueParameter<ISymbolicExpressionGrammar>(Name + ".Grammar", "The grammar that should be used for symbolic expression tree.", grammar);
     169      functionDefinitionsParameter = new FixedValueParameter<IntValue>(Name + ".Function Definitions", "Maximal number of automatically defined functions", new IntValue(0));
     170      functionArgumentsParameter = new FixedValueParameter<IntValue>(Name + ".Function Arguments", "Maximal number of arguments of automatically defined functions.", new IntValue(0));
    171171
    172172      Parameters.Add(treeLengthParameter);
  • branches/symbreg-factors-2650/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/SimpleSymbol.cs

    r14185 r14351  
    6161    }
    6262
     63    public SimpleSymbol(string name, int arity)
     64      : this(name, string.Empty, arity, arity) {
     65    }
     66
    6367    public SimpleSymbol(string name, string description, int minimumArity, int maximumArity)
    6468      : base(name, description) {
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis

  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic

  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression

  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4

  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs

    r14266 r14351  
    183183      List<string> variableNames = new List<string>();
    184184      List<string> categoricalVariableValues = new List<string>();
     185      List<int> lags = new List<int>();
    185186
    186187      AutoDiff.Term func;
    187       if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out func))
     188      if (!TryTransformToAutoDiff(tree.Root.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out func))
    188189        throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
    189190      if (variableNames.Count == 0) return 0.0; // gkronber: constant expressions always have a R² of 0.0
     
    235236      foreach (var r in rows) {
    236237        for (int col = 0; col < variableNames.Count; col++) {
     238          int lag = lags[col];
    237239          if (ds.VariableHasType<double>(variableNames[col])) {
    238             x[row, col] = ds.GetDoubleValue(variableNames[col], r);
     240            x[row, col] = ds.GetDoubleValue(variableNames[col], r + lag);
    239241          } else if (ds.VariableHasType<string>(variableNames[col])) {
    240242            x[row, col] = ds.GetStringValue(variableNames[col], r) == categoricalVariableValues[col] ? 1 : 0;
     
    257259        alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, null, null);
    258260        alglib.lsfitresults(state, out info, out c, out rep);
    259       }
    260       catch (ArithmeticException) {
     261      } catch (ArithmeticException) {
    261262        return originalQuality;
    262       }
    263       catch (alglib.alglibexception) {
     263      } catch (alglib.alglibexception) {
    264264        return originalQuality;
    265265      }
     
    312312
    313313    private static bool TryTransformToAutoDiff(ISymbolicExpressionTreeNode node, List<AutoDiff.Variable> variables, List<AutoDiff.Variable> parameters,
    314       List<string> variableNames, List<string> categoricalVariableValues, bool updateVariableWeights, out AutoDiff.Term term) {
     314      List<string> variableNames, List<int> lags, List<string> categoricalVariableValues, bool updateVariableWeights, out AutoDiff.Term term) {
    315315      if (node.Symbol is Constant) {
    316316        var var = new AutoDiff.Variable();
     
    325325        var varValue = factorVarNode != null ? factorVarNode.VariableValue : string.Empty;
    326326        var par = FindOrCreateParameter(varNode.VariableName, varValue, parameters, variableNames, categoricalVariableValues);
     327        lags.Add(0);
    327328
    328329        if (updateVariableWeights) {
     
    349350        return true;
    350351      }
     352      if (node.Symbol is LaggedVariable) {
     353        var varNode = node as LaggedVariableTreeNode;
     354        var par = new AutoDiff.Variable();
     355        parameters.Add(par);
     356        variableNames.Add(varNode.VariableName);
     357        lags.Add(varNode.Lag);
     358
     359        if (updateVariableWeights) {
     360          var w = new AutoDiff.Variable();
     361          variables.Add(w);
     362          term = AutoDiff.TermBuilder.Product(w, par);
     363        } else {
     364          term = par;
     365        }
     366        return true;
     367      }
    351368      if (node.Symbol is Addition) {
    352369        List<AutoDiff.Term> terms = new List<Term>();
    353370        foreach (var subTree in node.Subtrees) {
    354371          AutoDiff.Term t;
    355           if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     372          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    356373            term = null;
    357374            return false;
     
    366383        for (int i = 0; i < node.SubtreeCount; i++) {
    367384          AutoDiff.Term t;
    368           if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     385          if (!TryTransformToAutoDiff(node.GetSubtree(i), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    369386            term = null;
    370387            return false;
     
    381398        foreach (var subTree in node.Subtrees) {
    382399          AutoDiff.Term t;
    383           if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     400          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    384401            term = null;
    385402            return false;
     
    396413        foreach (var subTree in node.Subtrees) {
    397414          AutoDiff.Term t;
    398           if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     415          if (!TryTransformToAutoDiff(subTree, variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    399416            term = null;
    400417            return false;
     
    408425      if (node.Symbol is Logarithm) {
    409426        AutoDiff.Term t;
    410         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     427        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    411428          term = null;
    412429          return false;
     
    418435      if (node.Symbol is Exponential) {
    419436        AutoDiff.Term t;
    420         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     437        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    421438          term = null;
    422439          return false;
     
    428445      if (node.Symbol is Square) {
    429446        AutoDiff.Term t;
    430         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     447        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    431448          term = null;
    432449          return false;
     
    438455      if (node.Symbol is SquareRoot) {
    439456        AutoDiff.Term t;
    440         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     457        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    441458          term = null;
    442459          return false;
     
    448465      if (node.Symbol is Sine) {
    449466        AutoDiff.Term t;
    450         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     467        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    451468          term = null;
    452469          return false;
     
    458475      if (node.Symbol is Cosine) {
    459476        AutoDiff.Term t;
    460         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     477        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    461478          term = null;
    462479          return false;
     
    468485      if (node.Symbol is Tangent) {
    469486        AutoDiff.Term t;
    470         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     487        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    471488          term = null;
    472489          return false;
     
    478495      if (node.Symbol is Erf) {
    479496        AutoDiff.Term t;
    480         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     497        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    481498          term = null;
    482499          return false;
     
    488505      if (node.Symbol is Norm) {
    489506        AutoDiff.Term t;
    490         if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out t)) {
     507        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out t)) {
    491508          term = null;
    492509          return false;
     
    502519        variables.Add(alpha);
    503520        AutoDiff.Term branchTerm;
    504         if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, categoricalVariableValues, updateVariableWeights, out branchTerm)) {
     521        if (TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, lags, categoricalVariableValues, updateVariableWeights, out branchTerm)) {
    505522          term = branchTerm * alpha + beta;
    506523          return true;
     
    547564         !(n.Symbol is BinaryFactorVariable) &&
    548565         !(n.Symbol is FactorVariable) &&
     566         !(n.Symbol is LaggedVariable) &&
    549567         !(n.Symbol is Constant) &&
    550568         !(n.Symbol is Addition) &&
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs

    r14251 r14351  
    8181          }
    8282          strBuilder.Append(")");
     83        } else {
     84          // function with multiple arguments
     85          strBuilder.Append(token).Append("(");
     86          FormatRecursively(node.Subtrees.First(), strBuilder);
     87          foreach (var subtree in node.Subtrees.Skip(1)) {
     88            strBuilder.Append(", ");
     89            FormatRecursively(subtree, strBuilder);
     90          }
     91          strBuilder.Append(")");
    8392        }
    8493      } else if (node.SubtreeCount == 1) {
     
    94103          FormatRecursively(node.GetSubtree(0), strBuilder);
    95104        } else {
    96           // function
     105          // function with only one argument
    97106          strBuilder.Append(token).Append("(");
    98107          FormatRecursively(node.GetSubtree(0), strBuilder);
     
    101110      } else {
    102111        // no subtrees
    103         if (node.Symbol is Variable) {
     112        if (node.Symbol is LaggedVariable) {
     113          var varNode = node as LaggedVariableTreeNode;
     114          if (!varNode.Weight.IsAlmost(1.0)) {
     115            strBuilder.Append("(");
     116            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight);
     117            strBuilder.Append("*");
     118          }
     119          strBuilder.Append("LAG(");
     120          if (varNode.VariableName.Contains("'")) {
     121            strBuilder.AppendFormat("\"{0}\"", varNode.VariableName);
     122          } else {
     123            strBuilder.AppendFormat("'{0}'", varNode.VariableName);
     124          }
     125          strBuilder.Append(", ")
     126            .AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Lag)
     127            .Append(")");
     128        } else if (node.Symbol is Variable) {
    104129          var varNode = node as VariableTreeNode;
    105130          if (!varNode.Weight.IsAlmost(1.0)) {
     
    144169            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constNode.Value);
    145170          else
    146             strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value);     // (-1)
     171            strBuilder.AppendFormat(CultureInfo.InvariantCulture, "({0})", constNode.Value); // (-1
    147172        }
    148173      }
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs

    r14330 r14351  
    2626using System.Text;
    2727using HeuristicLab.Collections;
     28using HeuristicLab.Common;
    2829using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
    2930
     
    4849  /// </summary>
    4950  public sealed class InfixExpressionParser {
    50     private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Eq, End, NA };
     51    private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Comma, Eq, End, NA };
    5152    private class Token {
    5253      internal double doubleVal;
     
    114115        { "MEAN", new Average()},
    115116        { "IF", new IfThenElse()},
    116         { ">", new GreaterThan()},
    117         { "<", new LessThan()},
     117        { "GT", new GreaterThan()},
     118        { "LT", new LessThan()},
    118119        { "AND", new And()},
    119120        { "OR", new Or()},
     
    121122        { "XOR", new Xor()},
    122123        { "DIFF", new Derivative()},
     124        { "LAG", new LaggedVariable() },
    123125      };
    124126
     
    150152        }
    151153        if (char.IsDigit(str[pos])) {
    152           // read number (=> read until white space or operator)
     154          // read number (=> read until white space or operator or comma)
    153155          var sb = new StringBuilder();
    154156          sb.Append(str[pos]);
     
    159161            && str[pos] != '*'
    160162            && str[pos] != '/'
    161             && str[pos] != ')') {
     163            && str[pos] != ')'
     164            && str[pos] != ',') {
    162165            sb.Append(str[pos]);
    163166            pos++;
     
    226229          pos++;
    227230          yield return new Token { TokenType = TokenType.Eq, strVal = "=" };
     231        } else if (str[pos] == ',') {
     232          pos++;
     233          yield return new Token { TokenType = TokenType.Comma, strVal = "," };
    228234        } else {
    229235          throw new ArgumentException("Invalid character: " + str[pos]);
     
    232238    }
    233239
     240    // S       = Expr EOF
     241    // Expr    = ['-' | '+'] Term { '+' Term | '-' Term }
     242    // Term    = Fact { '*' Fact | '/' Fact }
     243    // Fact    = '(' Expr ')' | funcId '(' ArgList ')' | varId | number
     244    // ArgList = Expr { ',' Expr }
    234245    private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) {
    235246      var expr = ParseExpr(tokens);
     
    339350    }
    340351
    341     // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId [ = valId ] | number
     352    // Fact = '(' Expr ')' | 'LAG' '(' varId ',' ['+' | '-' ] number ')' | funcId '(' Expr ')' | varId [ = valId ] | number
    342353    private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) {
    343354      var next = tokens.Peek();
     
    359370          if (lPar.TokenType != TokenType.LeftPar)
    360371            throw new ArgumentException("expected (");
    361           var expr = ParseExpr(tokens);
     372
     373          // handle 'lag' specifically
     374          if (funcNode.Symbol is LaggedVariable) {
     375            var varId = tokens.Dequeue();
     376            if (varId.TokenType != TokenType.Identifier) throw new ArgumentException("Identifier expected. Format for lagged variables: \"lag(x, -1)\"");
     377            var comma = tokens.Dequeue();
     378            if (comma.TokenType != TokenType.Comma) throw new ArgumentException("',' expected, Format for lagged variables: \"lag(x, -1)\"");
     379            double sign = 1.0;
     380            if (tokens.Peek().strVal == "+" || tokens.Peek().strVal == "-") {
     381              // read sign
     382              var signTok = tokens.Dequeue();
     383              if (signTok.strVal == "-") sign = -1.0;
     384            }
     385            var lagToken = tokens.Dequeue();
     386            if (lagToken.TokenType != TokenType.Number) throw new ArgumentException("Number expected, Format for lagged variables: \"lag(x, -1)\"");
     387            if (!lagToken.doubleVal.IsAlmost(Math.Round(lagToken.doubleVal)))
     388              throw new ArgumentException("Time lags must be integer values");
     389            var laggedVarNode = funcNode as LaggedVariableTreeNode;
     390            laggedVarNode.VariableName = varId.strVal;
     391            laggedVarNode.Lag = (int)Math.Round(sign * lagToken.doubleVal);
     392            laggedVarNode.Weight = 1.0;
     393          } else {
     394            // functions
     395            var args = ParseArgList(tokens);
     396            // check number of arguments
     397            if (funcNode.Symbol.MinimumArity > args.Length || funcNode.Symbol.MaximumArity < args.Length) {
     398              throw new ArgumentException(string.Format("Symbol {0} requires between {1} and  {2} arguments.", funcId,
     399                funcNode.Symbol.MinimumArity, funcNode.Symbol.MaximumArity));
     400            }
     401            foreach (var arg in args) funcNode.AddSubtree(arg);
     402          }
     403
    362404          var rPar = tokens.Dequeue();
    363405          if (rPar.TokenType != TokenType.RightPar)
    364406            throw new ArgumentException("expected )");
    365407
    366           funcNode.AddSubtree(expr);
    367408          return funcNode;
    368409        } else {
     
    396437    }
    397438
     439    // ArgList = Expr { ',' Expr }
     440    private ISymbolicExpressionTreeNode[] ParseArgList(Queue<Token> tokens) {
     441      var exprList = new List<ISymbolicExpressionTreeNode>();
     442      exprList.Add(ParseExpr(tokens));
     443      while (tokens.Peek().TokenType != TokenType.RightPar) {
     444        var comma = tokens.Dequeue();
     445        if (comma.TokenType != TokenType.Comma) throw new ArgumentException("expected ',' ");
     446        exprList.Add(ParseExpr(tokens));
     447      }
     448      return exprList.ToArray();
     449    }
    398450  }
    399451}
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs

    r14185 r14351  
    614614        case OpCodes.VariableCondition: {
    615615            var variableConditionTreeNode = (VariableConditionTreeNode)node;
     616            if (variableConditionTreeNode.Symbol.IgnoreSlope) throw new NotSupportedException("Strict variable conditionals are not supported");
    616617            var variableName = variableConditionTreeNode.VariableName;
    617618            var indexExpr = Expression.Constant(variableIndices[variableName]);
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs

    r14251 r14351  
    488488            if (row < 0 || row >= dataset.Rows) return double.NaN;
    489489            var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
    490             double variableValue = ((IList<double>)currentInstr.data)[row];
    491             double x = variableValue - variableConditionTreeNode.Threshold;
    492             double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    493 
    494             double trueBranch = Evaluate(dataset, ref row, state);
    495             double falseBranch = Evaluate(dataset, ref row, state);
    496 
    497             return trueBranch * p + falseBranch * (1 - p);
     490            if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
     491              double variableValue = ((IList<double>)currentInstr.data)[row];
     492              double x = variableValue - variableConditionTreeNode.Threshold;
     493              double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
     494
     495              double trueBranch = Evaluate(dataset, ref row, state);
     496              double falseBranch = Evaluate(dataset, ref row, state);
     497
     498              return trueBranch * p + falseBranch * (1 - p);
     499            } else {
     500              // strict threshold
     501              double variableValue = ((IList<double>)currentInstr.data)[row];
     502              if (variableValue <= variableConditionTreeNode.Threshold) {
     503                var left = Evaluate(dataset, ref row, state);
     504                state.SkipInstructions();
     505                return left;
     506              } else {
     507                state.SkipInstructions();
     508                return Evaluate(dataset, ref row, state);
     509              }
     510            }
    498511          }
    499512        default:
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs

    r14330 r14351  
    126126    private readonly object syncRoot = new object();
    127127    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows) {
     128      if (!rows.Any()) return Enumerable.Empty<double>();
    128129      if (CheckExpressionsWithIntervalArithmetic)
    129130        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
     
    171172          if (row < 0 || row >= dataset.Rows) instr.value = double.NaN;
    172173          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
    173           double variableValue = ((IList<double>)instr.data)[row];
    174           double x = variableValue - variableConditionTreeNode.Threshold;
    175           double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
    176 
    177           double trueBranch = code[instr.childIndex].value;
    178           double falseBranch = code[instr.childIndex + 1].value;
    179 
    180           instr.value = trueBranch * p + falseBranch * (1 - p);
     174          if (!variableConditionTreeNode.Symbol.IgnoreSlope) {
     175            double variableValue = ((IList<double>)instr.data)[row];
     176            double x = variableValue - variableConditionTreeNode.Threshold;
     177            double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
     178
     179            double trueBranch = code[instr.childIndex].value;
     180            double falseBranch = code[instr.childIndex + 1].value;
     181
     182            instr.value = trueBranch * p + falseBranch * (1 - p);
     183          } else {
     184            double variableValue = ((IList<double>)instr.data)[row];
     185            if (variableValue <= variableConditionTreeNode.Threshold) {
     186              instr.value = code[instr.childIndex].value;
     187            } else {
     188              instr.value = code[instr.childIndex + 1].value;
     189            }
     190          }
    181191        } else if (instr.opCode == OpCodes.Add) {
    182192          double s = code[instr.childIndex].value;
     
    433443              for (int j = 1; j != seq.Length; ++j)
    434444                seq[j].skip = true;
    435             }
    436             break;
     445              break;
     446            }
    437447        }
    438448        #endregion
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableCondition.cs

    r14238 r14351  
    149149        }
    150150      }
     151    }
     152
     153    /// <summary>
     154    /// Flag to indicate if the interpreter should ignore the slope parameter (introduced for representation of expression trees)
     155    /// </summary>
     156    [Storable]
     157    private bool ignoreSlope;
     158    public bool IgnoreSlope {
     159      get { return ignoreSlope; }
     160      set { ignoreSlope = value; }
    151161    }
    152162
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/VariableConditionTreeNode.cs

    r14238 r14351  
    9696
    9797    public override string ToString() {
    98       if (slope.IsAlmost(0.0))
     98      if (slope.IsAlmost(0.0) || Symbol.IgnoreSlope) {
     99        return variableName + " < " + threshold.ToString("E4");
     100      } else {
    99101        return variableName + " > " + threshold.ToString("E4") + Environment.NewLine +
    100           "slope: " + slope.ToString("E4");
    101       else
    102         return variableName + " > " + threshold.ToString("E4");
     102               "slope: " + slope.ToString("E4");
     103      }
    103104    }
    104105  }
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views

  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj

    r14248 r14351  
    252252    <Compile Include="Regression\RegressionFeatureCorrelationView.Designer.cs">
    253253      <DependentUpon>RegressionFeatureCorrelationView.cs</DependentUpon>
     254    </Compile>
     255    <Compile Include="Regression\RegressionSolutionVariableImpactsView.cs">
     256      <SubType>UserControl</SubType>
     257    </Compile>
     258    <Compile Include="Regression\RegressionSolutionVariableImpactsView.Designer.cs">
     259      <DependentUpon>RegressionSolutionVariableImpactsView.cs</DependentUpon>
    254260    </Compile>
    255261    <Compile Include="Regression\RegressionSolutionGradientView.cs">
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs

    r14185 r14351  
    4646    /// </summary>
    4747    private void InitializeComponent() {
    48       this.btnImpactCalculation = new System.Windows.Forms.Button();
    4948      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
    5049      this.splitContainer.Panel1.SuspendLayout();
     
    5453      this.detailsGroupBox.SuspendLayout();
    5554      this.SuspendLayout();
    56       //
    57       // btnImpactCalculation
    58       //
    59       this.btnImpactCalculation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
    60       this.btnImpactCalculation.Image = HeuristicLab.Common.Resources.VSImageLibrary.Zoom;
    61       this.btnImpactCalculation.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
    62       this.btnImpactCalculation.Name = "btnImpactCalculation";
    63       this.btnImpactCalculation.TabIndex = 6;
    64       this.btnImpactCalculation.Size = new System.Drawing.Size(110, 24);
    65       this.btnImpactCalculation.Text = "Variable Impacts";
    66       this.btnImpactCalculation.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
    67       this.btnImpactCalculation.UseVisualStyleBackColor = true;
    68       this.btnImpactCalculation.Click += new System.EventHandler(this.btnImpactCalculation_Click);
    69       this.toolTip.SetToolTip(this.btnImpactCalculation, "Calculate impacts");
    70       //
    71       // flowLayoutPanel
    72       //
    73       this.flowLayoutPanel.Controls.Add(this.btnImpactCalculation);
    74       //
    75       // splitContainer
    76       //
    77       //
    7855      // itemsGroupBox
    7956      //
     
    10481
    10582    #endregion
    106 
    107     protected System.Windows.Forms.Button btnImpactCalculation;
    10883  }
    10984}
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs

    r14185 r14351  
    2020#endregion
    2121
    22 using System;
    23 using System.Linq;
    24 using System.Threading.Tasks;
    2522using System.Windows.Forms;
    2623using HeuristicLab.Core;
    27 using HeuristicLab.Data;
    28 using HeuristicLab.Data.Views;
    2924using HeuristicLab.MainForm;
    30 using HeuristicLab.MainForm.WindowsForms;
    3125
    3226namespace HeuristicLab.Problems.DataAnalysis.Views {
     
    4135      get { return (RegressionSolutionBase)base.Content; }
    4236      set { base.Content = value; }
    43     }
    44 
    45     protected override void SetEnabledStateOfControls() {
    46       base.SetEnabledStateOfControls();
    47       btnImpactCalculation.Enabled = Content != null && !Locked;
    48     }
    49 
    50     protected virtual void btnImpactCalculation_Click(object sender, EventArgs e) {
    51       var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
    52       var view = new StringConvertibleArrayView();
    53       view.Caption = Content.Name + " Variable Impacts";
    54       view.Show();
    55 
    56       Task.Factory.StartNew(() => {
    57         try {
    58           mainForm.AddOperationProgressToView(view, "Calculating variable impacts for " + Content.Name);
    59 
    60           var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content);
    61           var impactArray = new DoubleArray(impacts.Select(i => i.Item2).ToArray());
    62           impactArray.ElementNames = impacts.Select(i => i.Item1);
    63           view.Content = (DoubleArray)impactArray.AsReadOnly();
    64         }
    65         finally {
    66           mainForm.RemoveOperationProgressFromView(view);
    67         }
    68       });
    6937    }
    7038
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionVariableImpactsCalculator.cs

    r14249 r14351  
    171171          // new var has same empirical distribution but the relation to y is broken
    172172          rand = new FastRandom(31415);
    173           replacementValues = rows.Select(r => originalValues[r]).Shuffle(rand).ToList();
     173          // prepare a complete column for the dataset
     174          replacementValues = Enumerable.Repeat(double.NaN, dataset.Rows).ToList();
     175          // shuffle only the selected rows
     176          var shuffledValues = rows.Select(r => originalValues[r]).Shuffle(rand).ToList();
     177          int i = 0;
     178          // update column values
     179          foreach (var r in rows) {
     180            replacementValues[r] = shuffledValues[i++];
     181          }
    174182          break;
    175183        case ReplacementMethodEnum.Noise:
     
    177185          var stdDev = rows.Select(r => originalValues[r]).StandardDeviation();
    178186          rand = new FastRandom(31415);
    179           replacementValues = rows.Select(_ => NormalDistributedRandom.NextDouble(rand, avg, stdDev)).ToList();
     187          // prepare a complete column for the dataset
     188          replacementValues = Enumerable.Repeat(double.NaN, dataset.Rows).ToList();
     189          // update column values
     190          foreach (var r in rows) {
     191            replacementValues[r] = NormalDistributedRandom.NextDouble(rand, avg, stdDev);
     192          }
    180193          break;
    181194
  • branches/symbreg-factors-2650/HeuristicLab.Problems.Instances.DataAnalysis

  • branches/symbreg-factors-2650/HeuristicLab.Problems.Instances.DataAnalysis.Views

  • branches/symbreg-factors-2650/HeuristicLab.Problems.Instances.DataAnalysis.Views/3.3/DataAnalysisImportTypeDialog.cs

    r14330 r14351  
    8282          NumberFormatInfo = (NumberFormatInfo)DecimalSeparatorComboBox.SelectedValue,
    8383          DateTimeFormatInfo = (DateTimeFormatInfo)DateTimeFormatComboBox.SelectedValue,
    84           VariableNamesAvailable = CheckboxColumnNames.Checked
     84          VariableNamesAvailable = CheckboxColumnNames.Checked,
     85          Encoding = (Encoding) EncodingComboBox.SelectedValue
    8586        };
    8687      }
  • branches/symbreg-factors-2650/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisCSVFormat.cs

    r14185 r14351  
    2121
    2222using System.Globalization;
     23using System.Text;
    2324
    2425namespace HeuristicLab.Problems.Instances.DataAnalysis {
     
    2829    public DateTimeFormatInfo DateTimeFormatInfo { get; set; }
    2930    public bool VariableNamesAvailable { get; set; }
     31    public Encoding Encoding { get; set; }
    3032  }
    3133}
  • branches/symbreg-factors-2650/HeuristicLab.Problems.Instances.DataAnalysis/3.3/DataAnalysisInstanceProvider.cs

    r14185 r14351  
    4040    public TData ImportData(string path, ImportType type, DataAnalysisCSVFormat csvFormat) {
    4141      TableFileParser csvFileParser = new TableFileParser();
     42      csvFileParser.Encoding = csvFormat.Encoding;
    4243      long fileSize = new FileInfo(path).Length;
    4344      csvFileParser.ProgressChanged += (sender, e) => {
  • branches/symbreg-factors-2650/HeuristicLab.Tests

  • branches/symbreg-factors-2650/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/InfixExpressionParserTest.cs

    r14109 r14351  
    8686      Console.WriteLine(formatter.Format(parser.Parse("x1*x2+x3*x4")));
    8787
     88
     89      Console.WriteLine(formatter.Format(parser.Parse("POW(3, 2)")));
     90      Console.WriteLine(formatter.Format(parser.Parse("POW(3.1, 2.1)")));
     91      Console.WriteLine(formatter.Format(parser.Parse("POW(3.1 , 2.1)")));
     92      Console.WriteLine(formatter.Format(parser.Parse("POW(3.1 ,2.1)")));
     93      Console.WriteLine(formatter.Format(parser.Parse("POW(-3.1 , - 2.1)")));
     94      Console.WriteLine(formatter.Format(parser.Parse("ROOT(3, 2)")));
     95      Console.WriteLine(formatter.Format(parser.Parse("ROOT(3.1, 2.1)")));
     96      Console.WriteLine(formatter.Format(parser.Parse("ROOT(3.1 , 2.1)")));
     97      Console.WriteLine(formatter.Format(parser.Parse("ROOT(3.1 ,2.1)")));
     98      Console.WriteLine(formatter.Format(parser.Parse("ROOT(-3.1 , - 2.1)")));
     99
     100      Console.WriteLine(formatter.Format(parser.Parse("IF(GT( 0, 1), 1, 0)")));
     101      Console.WriteLine(formatter.Format(parser.Parse("IF(LT(0,1), 1 , 0)")));
     102
     103      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, 1)")));
     104      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, -1)")));
     105      Console.WriteLine(formatter.Format(parser.Parse("LAG(x, +1)")));
     106      Console.WriteLine(formatter.Format(parser.Parse("x * LAG('x', +1)")));
     107
    88108    }
    89109  }
  • branches/symbreg-factors-2650/HeuristicLab.Tests/HeuristicLab.Tests.csproj

    r14277 r14351  
    565565    <Compile Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4\SubroutineDuplicaterTest.cs" />
    566566    <Compile Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4\SubtreeCrossoverTest.cs" />
     567    <Compile Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4\GrammarsTest.cs" />
    567568    <Compile Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4\Util.cs" />
    568569    <Compile Include="HeuristicLab.Persistence-3.3\StorableAttributeTests.cs" />
Note: See TracChangeset for help on using the changeset viewer.