Changeset 14540


Ignore:
Timestamp:
01/04/17 14:49:12 (4 years ago)
Author:
gkronber
Message:

#2650: fixed bugs in simplifier (causing multiple references to the same tree nodes within a tree)

Location:
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs

    r14539 r14540  
    237237      var t = (BinaryFactorVariableTreeNode)binFactorVar.CreateTreeNode();
    238238      var varNameTok = tokens.Dequeue();
    239       Debug.Assert(tok.Symbol == TokenSymbol.SYMB);
     239      Debug.Assert(varNameTok.Symbol == TokenSymbol.SYMB);
    240240      t.VariableName = varNameTok.StringValue;
    241241
    242242      var varValTok = tokens.Dequeue();
    243       Debug.Assert(tok.Symbol == TokenSymbol.SYMB);
     243      Debug.Assert(varValTok.Symbol == TokenSymbol.SYMB);
    244244      t.VariableValue = varValTok.StringValue;
    245245
    246246      var weightTok = tokens.Dequeue();
    247       Debug.Assert(tok.Symbol == TokenSymbol.NUMBER);
     247      Debug.Assert(weightTok.Symbol == TokenSymbol.NUMBER);
    248248      t.Weight = weightTok.DoubleValue;
    249249
  • branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs

    r14539 r14540  
    2424using System;
    2525using System.Collections.Generic;
     26using System.Diagnostics;
    2627using System.Linq;
    2728using HeuristicLab.Common;
     
    6465      ISymbolicExpressionTreeNode rootNode = (new ProgramRootSymbol()).CreateTreeNode();
    6566      rootNode.AddSubtree(GetSimplifiedTree(macroExpandedTree));
     67
     68#if DEBUG
     69      // check that each node is only referenced once
     70      var nodes = rootNode.IterateNodesPrefix().ToArray();
     71      foreach(var n in nodes) if(nodes.Count(ni => ni == n) > 1) throw new InvalidOperationException();
     72#endif
    6673      return new SymbolicExpressionTree(rootNode);
    6774    }
     
    904911        return a.Subtrees
    905912          .Select(x => GetSimplifiedTree(x))
    906           .Select(x => MakeFraction(x, b))
     913          .Select(x => MakeFraction(x, GetSimplifiedTree(b)))
    907914          .Aggregate((c, d) => MakeSum(c, d));
    908915      } else if(IsMultiplication(a) && IsConstant(b)) {
     
    10841091      if(IsConstant(a) && IsConstant(b)) {
    10851092        // fold constants
    1086         ((ConstantTreeNode)a).Value *= ((ConstantTreeNode)b).Value;
    1087         return a;
     1093        return MakeConstant(((ConstantTreeNode)a).Value * ((ConstantTreeNode)b).Value);
    10881094      } else if(IsConstant(a)) {
    10891095        // a * $ => $ * a
     
    11231129        return a;
    11241130      } else if(IsConstant(b) && IsAddition(a) ||
    1125           IsFactor(b) && IsAddition(a)) {
     1131          IsFactor(b) && IsAddition(a) ||
     1132          IsBinFactor(b) && IsAddition(a)) {
    11261133        // multiply constants into additions
    1127         return a.Subtrees.Select(x => MakeProduct(x, b)).Aggregate((c, d) => MakeSum(c, d));
     1134        return a.Subtrees.Select(x => MakeProduct(GetSimplifiedTree(x), GetSimplifiedTree(b))).Aggregate((c, d) => MakeSum(c, d));
    11281135      } else if(IsDivision(a) && IsDivision(b)) {
    11291136        // (a1 / a2) * (b1 / b2) => (a1 * b1) / (a2 * b2)
     
    11461153      } else if(IsMultiplication(a)) {
    11471154        // a is already an multiplication => append b
    1148         a.AddSubtree(b);
     1155        a.AddSubtree(GetSimplifiedTree(b));
    11491156        MergeVariablesAndConstantsInProduct(a);
    11501157        return a;
     
    12561263    /// <summary>
    12571264    /// x => x * -1
    1258     /// Doesn't create new trees and manipulates x
     1265    /// Is only used in cases where it is not necessary to create new tree nodes. Manipulates x directly.
    12591266    /// </summary>
    12601267    /// <param name="x"></param>
     
    12931300    /// <summary>
    12941301    /// x => 1/x
    1295     /// Doesn't create new trees and manipulates x
     1302    /// Must create new tree nodes
    12961303    /// </summary>
    12971304    /// <param name="x"></param>
     
    13021309      } else if(IsFactor(x)) {
    13031310        var factorNode = (FactorVariableTreeNode)x;
    1304         for(int i = 0; i < factorNode.Weights.Length; i++) factorNode.Weights[i] = 1.0 / factorNode.Weights[i];
    1305         return factorNode;
     1311        return MakeFactor(factorNode.Symbol, factorNode.VariableName, factorNode.Weights.Select(w => 1.0 / w));
    13061312      } else if(IsDivision(x)) {
    13071313        return MakeFraction(x.GetSubtree(1), x.GetSubtree(0));
Note: See TracChangeset for help on using the changeset viewer.