Changeset 18187


Ignore:
Timestamp:
01/12/22 15:07:18 (8 days ago)
Author:
mkommend
Message:

#3136: Refactored saved trees in structure template.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/StructureTemplate/StructureTemplate.cs

    r18164 r18187  
    1818      get => template;
    1919      set {
     20        if (value == template) return;
     21
    2022        template = value;
    21         Tree = Parser.Parse(template);
     23        var parsedTree = Parser.Parse(template);
     24        if (applyLinearScaling)
     25          parsedTree = AddLinearScalingTerms(parsedTree);
     26        Tree = parsedTree;
    2227        OnChanged();
    2328      }
     
    2530
    2631    [Storable]
    27     private ISymbolicExpressionTree treeWithoutLinearScaling;
    28     [Storable]
    29     private ISymbolicExpressionTree treeWithLinearScaling;
     32    private ISymbolicExpressionTree tree;
    3033    public ISymbolicExpressionTree Tree {
    31       get => ApplyLinearScaling ? treeWithLinearScaling : treeWithoutLinearScaling;
     34      get => tree;
    3235      private set {
    33         treeWithLinearScaling = AddLinearScalingTerms(value);
    34         treeWithoutLinearScaling = value;
     36        tree = value;
    3537
    3638        var newFunctions = GetSubFunctions();
    37         var oldFunctions = subFunctions?.Intersect(newFunctions) 
     39        var oldFunctions = subFunctions?.Intersect(newFunctions)
    3840                           ?? Enumerable.Empty<SubFunction>();
    3941        // adds new functions and keeps the old ones (if they match)
     
    5153      get => applyLinearScaling;
    5254      set {
     55        if (value == applyLinearScaling) return;
     56
    5357        applyLinearScaling = value;
     58        if (applyLinearScaling) Tree = AddLinearScalingTerms(Tree);
     59        else Tree = RemoveLinearScalingTerms(Tree);
     60
    5461        OnChanged();
    5562      }
     
    7582
    7683    protected StructureTemplate(StructureTemplate original, Cloner cloner) : base(original, cloner) {
    77       this.Tree = cloner.Clone(original.Tree);
    78       this.Template = original.Template;
    79       this.ApplyLinearScaling = original.ApplyLinearScaling;
     84      this.tree = cloner.Clone(original.tree);
     85      this.template = original.Template;
     86      this.applyLinearScaling = original.ApplyLinearScaling;
    8087      this.subFunctions = original.subFunctions.Select(cloner.Clone).ToList();
    8188      RegisterEventHandlers();
     
    96103    public void Reset() {
    97104      subFunctions = new List<SubFunction>();
    98       treeWithoutLinearScaling = null;
    99       treeWithLinearScaling = null;
    100       applyLinearScaling = false;
     105      tree = null;
    101106      Template = "f(_)";
    102       OnChanged();
    103107    }
    104108
     
    112116          var existingSubFunction = subFunctions.Where(x => x.Name == subFunctionTreeNode.Name).FirstOrDefault();
    113117          if (existingSubFunction != null) {
    114             // an existing subFunction needs the same signature
    115             if(!existingSubFunction.Arguments.SequenceEqual(subFunctionTreeNode.Arguments))
     118            // an existing subFunction must have the same signature
     119            if (!existingSubFunction.Arguments.SequenceEqual(subFunctionTreeNode.Arguments))
    116120              throw new ArgumentException(
    117121                $"The sub-function '{existingSubFunction.Name}' has (at least two) different signatures " +
     
    131135
    132136    private void RegisterEventHandlers() {
    133       foreach(var sf in SubFunctions) {
     137      foreach (var sf in SubFunctions) {
    134138        sf.Changed += OnSubFunctionChanged;
    135139      }
    136140    }
    137141
    138     private ISymbolicExpressionTree AddLinearScalingTerms(ISymbolicExpressionTree tree) {
     142    private static ISymbolicExpressionTree AddLinearScalingTerms(ISymbolicExpressionTree tree) {
    139143      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
    140144      var startNode = clonedTree.Root.Subtrees.First();
    141145      var template = startNode.Subtrees.First();
    142146
    143       var add = new Addition();
    144       var addNode = add.CreateTreeNode();
    145 
    146       var mul = new Multiplication();
    147       var mulNode = mul.CreateTreeNode();
    148 
    149       var offset = new Number();
    150       var offsetNode = (NumberTreeNode)offset.CreateTreeNode();
    151       offsetNode.Value = 0.0;
    152       var scale = new Number();
    153       var scaleNode = (NumberTreeNode)scale.CreateTreeNode();
    154       scaleNode.Value = 1.0;
     147      var addNode = new Addition().CreateTreeNode();
     148      var mulNode = new Multiplication().CreateTreeNode();
     149      var offsetNode = new NumberTreeNode(0.0);
     150      var scaleNode = new NumberTreeNode(1.0);
    155151
    156152      addNode.AddSubtree(offsetNode);
     
    164160    }
    165161
     162    private static ISymbolicExpressionTree RemoveLinearScalingTerms(ISymbolicExpressionTree tree) {
     163      var clonedTree = (ISymbolicExpressionTree)tree.Clone();
     164      var startNode = clonedTree.Root.Subtrees.First();
     165
     166      //check for scaling terms
     167      var addNode = startNode.GetSubtree(0);
     168      var offsetNode = addNode.GetSubtree(0);
     169      var mulNode = addNode.GetSubtree(1);
     170      var scaleNode = mulNode.GetSubtree(0);
     171      var templateNode = mulNode.GetSubtree(1);
     172
     173      var error = false;
     174      if (addNode.Symbol is not Addition) error = true;
     175      if (mulNode.Symbol is not Multiplication) error = true;
     176      if (offsetNode is not NumberTreeNode offset || offset.Value != 0.0) error = true;
     177      if (scaleNode is not NumberTreeNode scale || scale.Value != 1.0) error = true;
     178      if (error) throw new ArgumentException("Scaling terms cannot be found.");
     179
     180      startNode.RemoveSubtree(0);
     181      startNode.AddSubtree(templateNode);
     182
     183      return clonedTree;
     184    }
     185
    166186    private void OnSubFunctionChanged(object sender, EventArgs e) => OnChanged();
    167187  }
Note: See TracChangeset for help on using the changeset viewer.