Index: /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/StructuredSymbolicRegressionSingleObjectiveProblem.cs
===================================================================
--- /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/StructuredSymbolicRegressionSingleObjectiveProblem.cs (revision 18190)
+++ /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/StructuredSymbolicRegressionSingleObjectiveProblem.cs (revision 18191)
@@ -270,6 +270,6 @@
// NMSEConstraintsEvaluator sets linear scaling terms itself
- if (StructureTemplate.ApplyLinearScaling && !(TreeEvaluator is NMSESingleObjectiveConstraintsEvaluator)) {
- AdjustLinearScalingParams(ProblemData, tree, Interpreter);
+ if (ApplyLinearScaling && !(TreeEvaluator is NMSESingleObjectiveConstraintsEvaluator)) {
+ LinearScaling.AdjustLinearScalingParams(ProblemData, tree, Interpreter);
}
@@ -300,26 +300,4 @@
}
- private static void AdjustLinearScalingParams(IRegressionProblemData problemData, ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter) {
- var offsetNode = tree.Root.GetSubtree(0).GetSubtree(0);
- var scalingNode = offsetNode.Subtrees.Where(x => !(x is NumberTreeNode)).First();
-
- var offsetNumberNode = (NumberTreeNode)offsetNode.Subtrees.Where(x => x is NumberTreeNode).First();
- var scalingNumberNode = (NumberTreeNode)scalingNode.Subtrees.Where(x => x is NumberTreeNode).First();
-
- var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, problemData.TrainingIndices);
- var targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices);
-
- OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out double a, out double b, out OnlineCalculatorError error);
- if (error == OnlineCalculatorError.None) {
- offsetNumberNode.Value = a;
- scalingNumberNode.Value = b;
- }
- }
-
-
-
-
-
-
public void Load(IRegressionProblemData data) {
ProblemData = data;
Index: /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj (revision 18190)
+++ /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj (revision 18191)
@@ -188,4 +188,5 @@
+
Index: /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/LinearScaling.cs
===================================================================
--- /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/LinearScaling.cs (revision 18191)
+++ /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/LinearScaling.cs (revision 18191)
@@ -0,0 +1,92 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see .
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+ public static class LinearScaling {
+
+ public static ISymbolicExpressionTree AddLinearScalingTerms(ISymbolicExpressionTree tree, double offset = 0.0, double scale = 1.0) {
+ var startNode = tree.Root.Subtrees.First();
+ var template = startNode.Subtrees.First();
+
+ var addNode = new Addition().CreateTreeNode();
+ var mulNode = new Multiplication().CreateTreeNode();
+ var offsetNode = new NumberTreeNode(offset);
+ var scaleNode = new NumberTreeNode(scale);
+
+ addNode.AddSubtree(offsetNode);
+ addNode.AddSubtree(mulNode);
+ mulNode.AddSubtree(scaleNode);
+
+ startNode.RemoveSubtree(0);
+ startNode.AddSubtree(addNode);
+ mulNode.AddSubtree(template);
+ return tree;
+ }
+
+ public static void RemoveLinearScalingTerms(ISymbolicExpressionTree tree) {
+ var startNode = tree.Root.GetSubtree(0);
+ ExtractScalingTerms(tree, out NumberTreeNode offsetNode, out NumberTreeNode scaleNode);
+
+ var evaluationNode = scaleNode.Parent.GetSubtree(1); //move up to multiplication and take second child
+ startNode.RemoveSubtree(0);
+ startNode.AddSubtree(evaluationNode);
+ }
+
+ public static void ExtractScalingTerms(ISymbolicExpressionTree tree,
+ out NumberTreeNode offset, out NumberTreeNode scale) {
+ var startNode = tree.Root.Subtrees.First();
+
+ //check for scaling terms
+ var addNode = startNode.GetSubtree(0);
+ var offsetNode = addNode.GetSubtree(0);
+ var mulNode = addNode.GetSubtree(1);
+ var scaleNode = mulNode.GetSubtree(0);
+
+
+ var error = false;
+ if (addNode.Symbol is not Addition) error = true;
+ if (mulNode.Symbol is not Multiplication) error = true;
+ if (offsetNode is not NumberTreeNode) error = true;
+ if (scaleNode is not NumberTreeNode) error = true;
+ if (error) throw new ArgumentException("Scaling terms cannot be found.");
+
+ offset = (NumberTreeNode)offsetNode;
+ scale = (NumberTreeNode)scaleNode;
+ }
+
+ public static void AdjustLinearScalingParams(IRegressionProblemData problemData, ISymbolicExpressionTree tree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter) {
+ ExtractScalingTerms(tree, out NumberTreeNode offsetNode, out NumberTreeNode scaleNode);
+
+ var estimatedValues = interpreter.GetSymbolicExpressionTreeValues(tree, problemData.Dataset, problemData.TrainingIndices);
+ var targetValues = problemData.TargetVariableTrainingValues;
+
+ OnlineLinearScalingParameterCalculator.Calculate(estimatedValues, targetValues, out double a, out double b, out OnlineCalculatorError error);
+ if (error == OnlineCalculatorError.None) {
+ offsetNode.Value = a;
+ scaleNode.Value = b;
+ }
+ }
+ }
+}
Index: /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/StructureTemplate/StructureTemplate.cs
===================================================================
--- /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/StructureTemplate/StructureTemplate.cs (revision 18190)
+++ /branches/3136_Structural_GP/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/StructureTemplate/StructureTemplate.cs (revision 18191)
@@ -44,5 +44,5 @@
var parsedTree = Parser.Parse(template);
if (applyLinearScaling)
- parsedTree = AddLinearScalingTerms(parsedTree);
+ parsedTree = LinearScaling.AddLinearScalingTerms(parsedTree);
Tree = parsedTree;
OnChanged();
@@ -83,6 +83,6 @@
applyLinearScaling = value;
- if (applyLinearScaling) Tree = AddLinearScalingTerms(Tree);
- else Tree = RemoveLinearScalingTerms(Tree);
+ if (applyLinearScaling) LinearScaling.AddLinearScalingTerms(Tree);
+ else LinearScaling.RemoveLinearScalingTerms(Tree);
OnChanged();
@@ -120,5 +120,5 @@
private void AfterDeserialization() {
if (Tree == null && _oldTree != null) {
- if (ApplyLinearScaling) _oldTree = AddLinearScalingTerms(_oldTree);
+ if (ApplyLinearScaling) _oldTree = LinearScaling.AddLinearScalingTerms(_oldTree);
Tree = _oldTree;
_oldTree = null;
@@ -172,49 +172,4 @@
}
}
-
- private static ISymbolicExpressionTree AddLinearScalingTerms(ISymbolicExpressionTree tree) {
- var clonedTree = (ISymbolicExpressionTree)tree.Clone();
- var startNode = clonedTree.Root.Subtrees.First();
- var template = startNode.Subtrees.First();
-
- var addNode = new Addition().CreateTreeNode();
- var mulNode = new Multiplication().CreateTreeNode();
- var offsetNode = new NumberTreeNode(0.0);
- var scaleNode = new NumberTreeNode(1.0);
-
- addNode.AddSubtree(offsetNode);
- addNode.AddSubtree(mulNode);
- mulNode.AddSubtree(scaleNode);
-
- startNode.RemoveSubtree(0);
- startNode.AddSubtree(addNode);
- mulNode.AddSubtree(template);
- return clonedTree;
- }
-
- private static ISymbolicExpressionTree RemoveLinearScalingTerms(ISymbolicExpressionTree tree) {
- var clonedTree = (ISymbolicExpressionTree)tree.Clone();
- var startNode = clonedTree.Root.Subtrees.First();
-
- //check for scaling terms
- var addNode = startNode.GetSubtree(0);
- var offsetNode = addNode.GetSubtree(0);
- var mulNode = addNode.GetSubtree(1);
- var scaleNode = mulNode.GetSubtree(0);
- var templateNode = mulNode.GetSubtree(1);
-
- var error = false;
- if (addNode.Symbol is not Addition) error = true;
- if (mulNode.Symbol is not Multiplication) error = true;
- if (offsetNode is not NumberTreeNode offset || offset.Value != 0.0) error = true;
- if (scaleNode is not NumberTreeNode scale || scale.Value != 1.0) error = true;
- if (error) throw new ArgumentException("Scaling terms cannot be found.");
-
- startNode.RemoveSubtree(0);
- startNode.AddSubtree(templateNode);
-
- return clonedTree;
- }
-
private void OnSubFunctionChanged(object sender, EventArgs e) => OnChanged();
}