Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/28/18 15:44:31 (6 years ago)
Author:
mkommend
Message:

#2974: Added unit tests and refactoring.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2974_Constants_Optimization/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/ConstantsOptimizationEvaluator.cs

    r16459 r16461  
    131131    }
    132132
    133 
    134133    private static readonly object locker = new object();
    135134    public override IOperation InstrumentedApply() {
     
    189188    }
    190189
     190    [ThreadStatic]
     191    private static double[,] x = null;
     192    [ThreadStatic]
     193    private static IDataset ds = null;
     194    [ThreadStatic]
     195    private static Dictionary<DataForVariable, AutoDiff.Variable> parameters;
     196
    191197    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
    192198      ISymbolicExpressionTree tree, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling,
     
    195201      bool updateConstantsInTree = true, Action<double[], double, object> iterationCallback = null, EvaluationsCounter counter = null) {
    196202
     203      if (ds == null || ds != problemData.Dataset) {
     204        ds = problemData.Dataset;
     205        parameters = ConstantsOptimization.Util.ExtractParameters(problemData.Dataset);
     206        x = ConstantsOptimization.Util.ExtractData(ds, parameters.Keys, rows);
     207       
     208      }
     209      double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
     210
    197211
    198212      // numeric constants in the tree become variables for constant opt
     
    201215      // variable name, variable value (for factor vars) and lag as a DataForVariable object.
    202216      // A dictionary is used to find parameters
    203       double[] initialConstants;
    204       var parameters = new List<TreeToAutoDiffTermConverter.DataForVariable>();
    205 
    206217      TreeToAutoDiffTermConverter.ParametricFunction func;
    207218      TreeToAutoDiffTermConverter.ParametricFunctionGradient func_grad;
    208       if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, out parameters, out initialConstants, out func, out func_grad))
     219
     220      if (!TreeToAutoDiffTermConverter.TryConvertToAutoDiff(tree, updateVariableWeights, applyLinearScaling, parameters, out func, out func_grad))
    209221        throw new NotSupportedException("Could not optimize constants of symbolic expression tree due to not supported symbols used in the tree.");
    210222      if (parameters.Count == 0) return 0.0; // gkronber: constant expressions always have a R² of 0.0
    211       //var parameterEntries = parameters.ToArray(); // order of entries must be the same for x
     223
     224      var initialConstants = ConstantsOptimization.Util.ExtractConstants(tree);
    212225
    213226      //extract inital constants
     
    231244      int retVal;
    232245
    233       IDataset ds = problemData.Dataset;
    234       var x = ConstantsOptimization.Util.ExtractData(ds, parameters, rows);
    235       double[] y = ds.GetDoubleValues(problemData.TargetVariable, rows).ToArray();
     246
    236247      int n = x.GetLength(0);
    237248      int m = x.GetLength(1);
     
    263274          var tmp = new double[c.Length - 2];
    264275          Array.Copy(c, 2, tmp, 0, tmp.Length);
    265           UpdateConstants(tree, tmp, updateVariableWeights);
    266         } else UpdateConstants(tree, c, updateVariableWeights);
     276          ConstantsOptimization.Util.UpdateConstants(tree, tmp);
     277        } else ConstantsOptimization.Util.UpdateConstants(tree, c);
    267278      }
    268279      var quality = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, tree, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling);
    269280
    270       if (!updateConstantsInTree) UpdateConstants(tree, initialConstants, updateVariableWeights);
     281      if (!updateConstantsInTree)
     282        ConstantsOptimization.Util.UpdateConstants(tree, initialConstants);
    271283
    272284      if (originalQuality - quality > 0.001 || double.IsNaN(quality)) {
    273         UpdateConstants(tree, initialConstants, updateVariableWeights);
     285        ConstantsOptimization.Util.UpdateConstants(tree, initialConstants);
    274286        return originalQuality;
    275287      }
    276288      return quality;
    277     }
    278 
    279     private static void UpdateConstants(ISymbolicExpressionTree tree, double[] constants, bool updateVariableWeights) {
    280       int i = 0;
    281       foreach (var node in tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>()) {
    282         ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
    283         VariableTreeNodeBase variableTreeNodeBase = node as VariableTreeNodeBase;
    284         FactorVariableTreeNode factorVarTreeNode = node as FactorVariableTreeNode;
    285         if (constantTreeNode != null)
    286           constantTreeNode.Value = constants[i++];
    287         else if (updateVariableWeights && variableTreeNodeBase != null)
    288           variableTreeNodeBase.Weight = constants[i++];
    289         else if (factorVarTreeNode != null) {
    290           for (int j = 0; j < factorVarTreeNode.Weights.Length; j++)
    291             factorVarTreeNode.Weights[j] = constants[i++];
    292         }
    293       }
    294289    }
    295290
Note: See TracChangeset for help on using the changeset viewer.