private void GenerateHeader(StringBuilder strBuilder, ISymbolicExpressionTree symbolicExpressionTree) { HashSet <string> floatVarNames = new HashSet <string>(); foreach (var node in symbolicExpressionTree.IterateNodesPostfix().Where(x => x is VariableTreeNode || x is VariableConditionTreeNode)) { floatVarNames.Add(((IVariableTreeNode)node).VariableName); } var sortedFloatIdentifiers = floatVarNames.OrderBy(n => n, new NaturalStringComparer()).Select(n => VariableName2Identifier(n)).ToList(); HashSet <string> varcharVarNames = new HashSet <string>(); foreach (var node in symbolicExpressionTree.IterateNodesPostfix().Where(x => x is BinaryFactorVariableTreeNode || x is FactorVariableTreeNode)) { varcharVarNames.Add(((IVariableTreeNode)node).VariableName); } var sortedVarcharIdentifiers = varcharVarNames.OrderBy(n => n, new NaturalStringComparer()).Select(n => VariableName2Identifier(n)).ToList(); //Generate comment and instructions strBuilder.Append("-- generated. created function can be used like 'SELECT dbo.REGRESSIONMODEL("); strBuilder.Append(string.Join(", ", sortedVarcharIdentifiers)); if (varcharVarNames.Any() && floatVarNames.Any()) { strBuilder.Append(","); } strBuilder.Append(string.Join(", ", sortedFloatIdentifiers)); strBuilder.AppendLine(")'"); strBuilder.AppendLine("-- use the expression after the RETURN statement if you want to incorporate the model in a query without creating a function."); //Generate function header strBuilder.Append("CREATE FUNCTION dbo.REGRESSIONMODEL("); strBuilder.Append(string.Join(", ", sortedVarcharIdentifiers.Select(n => string.Format("{0} NVARCHAR(max)", n)))); if (varcharVarNames.Any() && floatVarNames.Any()) { strBuilder.Append(","); } strBuilder.Append(string.Join(", ", sortedFloatIdentifiers.Select(n => string.Format("{0} FLOAT", n)))); strBuilder.AppendLine(")"); //start function body strBuilder.AppendLine("RETURNS FLOAT"); strBuilder.AppendLine("BEGIN"); //add variable declaration for convenience strBuilder.AppendLineIndented(1, "-- added variable declaration for convenience"); foreach (var name in sortedVarcharIdentifiers) { strBuilder.AppendLineIndented(1, string.Format("-- DECLARE {0} NVARCHAR(max) = ''", name)); } foreach (var name in sortedFloatIdentifiers) { strBuilder.AppendLineIndented(1, string.Format("-- DECLARE {0} FLOAT = 0.0", name)); } strBuilder.AppendLineIndented(1, "-- SELECT"); strBuilder.AppendLine("RETURN "); }
private bool IsValid(ISymbolicExpressionTree tree) { treeChart.Tree = tree; treeChart.Repaint(); // check if all nodes have a legal arity var nodes = tree.IterateNodesPostfix().ToList(); bool valid = !nodes.Any(node => node.SubtreeCount <GetMinArity(node.Symbol) || node.SubtreeCount> node.Symbol.MaximumArity); if (valid) { // check if all variables are contained in the dataset var variables = new HashSet <string>(Content.ProblemData.Dataset.DoubleVariables); valid = nodes.OfType <VariableTreeNode>().All(x => variables.Contains(x.VariableName)); } if (valid) { btnOptimizeConstants.Enabled = true; btnSimplify.Enabled = true; treeStatusValue.Visible = false; } else { btnOptimizeConstants.Enabled = false; btnSimplify.Enabled = false; treeStatusValue.Visible = true; } this.Refresh(); return(valid); }
public string Format(ISymbolicExpressionTree symbolicExpressionTree) { currentLag = 0; currentIndexNumber = 0; var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("rows = ???"); stringBuilder.AppendLine(FormatOnlyExpression(symbolicExpressionTree.Root) + ";"); stringBuilder.AppendLine(); stringBuilder.AppendLine("function y = log_(x)"); stringBuilder.AppendLine(" if(x<=0) y = NaN;"); stringBuilder.AppendLine(" else y = log(x);"); stringBuilder.AppendLine(" end"); stringBuilder.AppendLine("end"); stringBuilder.AppendLine(); stringBuilder.AppendLine("function y = fivePoint(f0, f1, f3, f4)"); stringBuilder.AppendLine(" y = (f0 + 2*f1 - 2*f3 - f4) / 8;"); stringBuilder.AppendLine("end"); var factorVariableNames = symbolicExpressionTree.IterateNodesPostfix() .OfType <FactorVariableTreeNode>() .Select(n => n.VariableName) .Distinct(); foreach (var factorVarName in factorVariableNames) { var factorSymb = symbolicExpressionTree.IterateNodesPostfix() .OfType <FactorVariableTreeNode>() .First(n => n.VariableName == factorVarName) .Symbol; stringBuilder.AppendFormat("function y = switch_{0}(val, v)", factorVarName).AppendLine(); var values = factorSymb.GetVariableValues(factorVarName).ToArray(); stringBuilder.AppendLine("switch val"); for (int i = 0; i < values.Length; i++) { stringBuilder.AppendFormat(CultureInfo.InvariantCulture, " case \"{0}\" y = v({1})", values[i], i).AppendLine(); } stringBuilder.AppendLine("end"); stringBuilder.AppendLine(); } return(stringBuilder.ToString()); }
private void GenerateHeader(StringBuilder strBuilder, ISymbolicExpressionTree symbolicExpressionTree) { strBuilder.AppendLine("using System;"); strBuilder.AppendLine("using System.Linq;" + Environment.NewLine); strBuilder.AppendLine("namespace HeuristicLab.Models {"); strBuilder.AppendLine("public static class Model {"); GenerateAverageSource(strBuilder); GenerateCbrtSource(strBuilder); GenerateIfThenElseSource(strBuilder); GenerateFactorSource(strBuilder); GenerateBinaryFactorSource(strBuilder); strBuilder.Append(Environment.NewLine + "public static double Evaluate ("); // here we don't have access to problemData to determine the type for each variable (double/string) therefore we must distinguish based on the symbol type HashSet <string> doubleVarNames = new HashSet <string>(); foreach (var node in symbolicExpressionTree.IterateNodesPostfix().Where(x => x is VariableTreeNode || x is VariableConditionTreeNode)) { doubleVarNames.Add(((IVariableTreeNode)node).VariableName); } HashSet <string> stringVarNames = new HashSet <string>(); foreach (var node in symbolicExpressionTree.IterateNodesPostfix().Where(x => x is BinaryFactorVariableTreeNode || x is FactorVariableTreeNode)) { stringVarNames.Add(((IVariableTreeNode)node).VariableName); } var orderedNames = stringVarNames.OrderBy(n => n, new NaturalStringComparer()).Select(n => "string " + VariableName2Identifier(n) + " /* " + n + " */"); strBuilder.Append(string.Join(", ", orderedNames)); if (stringVarNames.Any() && doubleVarNames.Any()) { strBuilder.AppendLine(","); } orderedNames = doubleVarNames.OrderBy(n => n, new NaturalStringComparer()).Select(n => "double " + VariableName2Identifier(n) + " /* " + n + " */"); strBuilder.Append(string.Join(", ", orderedNames)); strBuilder.AppendLine(") {"); strBuilder.Append("double result = "); }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable <int> rows, bool applyLinearScaling, int decimalPlaces) { double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling); if (decimalPlaces >= 0) { r2 = Math.Round(r2, decimalPlaces); } return(new double[2] { r2, solution.IterateNodesPostfix().Sum(n => n.GetLength()) }); // sum of the length of the whole sub-tree for each node }
public static void InitTree(ISymbolicExpressionTree tree, MersenneTwister twister, List<string> varNames) { foreach (var node in tree.IterateNodesPostfix()) { if (node is VariableTreeNode) { var varNode = node as VariableTreeNode; varNode.Weight = twister.NextDouble() * 20.0 - 10.0; varNode.VariableName = varNames[twister.Next(varNames.Count)]; } else if (node is ConstantTreeNode) { var constantNode = node as ConstantTreeNode; constantNode.Value = twister.NextDouble() * 20.0 - 10.0; } } }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable <int> rows, bool applyLinearScaling, int decimalPlaces) { double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling); if (decimalPlaces >= 0) { r2 = Math.Round(r2, decimalPlaces); } return(new double[2] { r2, solution.IterateNodesPostfix().OfType <IVariableTreeNode>().Count() }); // count the number of variables }
public static void IsValid(ISymbolicExpressionTree tree) { int reportedSize = tree.Length; int actualSize = tree.IterateNodesPostfix().Count(); Assert.AreEqual(actualSize, reportedSize); foreach (var defunTreeNode in tree.Root.Subtrees.OfType <DefunTreeNode>()) { int arity = defunTreeNode.NumberOfArguments; foreach (var argTreenode in defunTreeNode.IterateNodesPrefix().OfType <ArgumentTreeNode>()) { Assert.IsTrue(argTreenode.SubtreeCount == 0); Assert.IsTrue(((Argument)argTreenode.Symbol).ArgumentIndex < arity); } foreach (var argSymbol in Enumerable.Range(0, defunTreeNode.NumberOfArguments).Select(x => new Argument(x))) { Assert.IsTrue(defunTreeNode.Grammar.ContainsSymbol(argSymbol)); Assert.IsTrue(defunTreeNode.Grammar.GetMaximumSubtreeCount(argSymbol) == 0); Assert.IsTrue(defunTreeNode.Grammar.GetMinimumSubtreeCount(argSymbol) == 0); } var invoke = new InvokeFunction(defunTreeNode.FunctionName); foreach (var otherRootNode in tree.Root.Subtrees) { if (otherRootNode.Grammar.ContainsSymbol(invoke)) { Assert.IsTrue(otherRootNode.Grammar.GetMinimumSubtreeCount(invoke) == arity); Assert.IsTrue(otherRootNode.Grammar.GetMaximumSubtreeCount(invoke) == arity); Assert.IsFalse(otherRootNode.Grammar.IsAllowedChildSymbol(invoke, invoke)); for (int i = 0; i < arity; i++) { Assert.IsFalse(otherRootNode.Grammar.IsAllowedChildSymbol(invoke, invoke, i)); } } } } foreach (var subtree in tree.Root.Subtrees) { if (tree.Root.Grammar.GetType().Name != "EmptySymbolicExpressionTreeGrammar") { Assert.AreNotSame(subtree.Grammar, tree.Root.Grammar); } IsValid(subtree.Grammar); } IsValid(tree.Root.Grammar); IsValid(tree.Root); }
public static void InitTree(ISymbolicExpressionTree tree, MersenneTwister twister, List <string> varNames) { foreach (var node in tree.IterateNodesPostfix()) { if (node is VariableTreeNode) { var varNode = node as VariableTreeNode; varNode.Weight = twister.NextDouble() * 20.0 - 10.0; varNode.VariableName = varNames[twister.Next(varNames.Count)]; } else if (node is ConstantTreeNode) { var constantNode = node as ConstantTreeNode; constantNode.Value = twister.NextDouble() * 20.0 - 10.0; } } }
private bool IsValid(ISymbolicExpressionTree tree) { treeChart.Tree = tree; treeChart.Repaint(); bool valid = !tree.IterateNodesPostfix().Any(node => node.SubtreeCount <GetMinArity(node.Symbol) || node.SubtreeCount> node.Symbol.MaximumArity); if (valid) { btnOptimizeConstants.Enabled = true; btnSimplify.Enabled = true; treeStatusValue.Visible = false; } else { btnOptimizeConstants.Enabled = false; btnSimplify.Enabled = false; treeStatusValue.Visible = true; } this.Refresh(); return(valid); }
private void GenerateHeader(StringBuilder strBuilder, ISymbolicExpressionTree symbolicExpressionTree) { strBuilder.AppendLine("using System;"); strBuilder.AppendLine("using System.Linq;" + Environment.NewLine); strBuilder.AppendLine("namespace HeuristicLab.Models {"); strBuilder.AppendLine("public static class Model {"); GenerateAverageSource(strBuilder); GenerateIfThenElseSource(strBuilder); strBuilder.Append(Environment.NewLine + "public static double Evaluate ("); HashSet <string> varNames = new HashSet <string>(); foreach (var node in symbolicExpressionTree.IterateNodesPostfix().Where(x => x is VariableTreeNode)) { varNames.Add(((VariableTreeNode)node).VariableName); } var orderedNames = varNames.OrderBy(n => n, new NaturalStringComparer()).Select(n => "double " + n); strBuilder.Append(string.Join(", ", orderedNames)); strBuilder.AppendLine(") {"); strBuilder.Append("double result = "); }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) { double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling); if (decimalPlaces >= 0) r2 = Math.Round(r2, decimalPlaces); return new double[2] { r2, solution.IterateNodesPostfix().OfType<VariableTreeNode>().Count() }; // count the number of variables }
private static bool CreateNewArgumentForDefun(IRandom random, ISymbolicExpressionTree tree, DefunTreeNode defunBranch, ArgumentTreeNode newArgumentNode) { // select a random cut point in the function defining branch // the branch at the cut point is to be replaced by a new argument node var cutPoints = (from node in defunBranch.IterateNodesPrefix() where node.Subtrees.Count() > 0 && !node.IterateNodesPrefix().OfType<ArgumentTreeNode>().Any() && !node.IterateNodesPrefix().OfType<InvokeFunctionTreeNode>().Any() from subtree in node.Subtrees select new CutPoint(node, subtree)).ToList(); if (cutPoints.Count() == 0) // no cut point found => abort; return false; var selectedCutPoint = cutPoints[random.Next(cutPoints.Count)]; // replace the branch at the cut point with an argument node var replacedBranch = selectedCutPoint.Child; selectedCutPoint.Parent.RemoveSubtree(selectedCutPoint.ChildIndex); selectedCutPoint.Parent.InsertSubtree(selectedCutPoint.ChildIndex, newArgumentNode); // find all old invocations of the selected ADF and attach a cloned version of the replaced branch (with all argument-nodes expanded) // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed var invocationNodes = (from node in tree.IterateNodesPostfix().OfType<InvokeFunctionTreeNode>() where node.Symbol.FunctionName == defunBranch.FunctionName where node.Subtrees.Count() == defunBranch.NumberOfArguments select node).ToList(); // do this repeatedly until no matching invocations are found while (invocationNodes.Count > 0) { List<ISymbolicExpressionTreeNode> newlyAddedBranches = new List<ISymbolicExpressionTreeNode>(); foreach (var invocationNode in invocationNodes) { // check that the invocation node really has the correct number of arguments if (invocationNode.Subtrees.Count() != defunBranch.NumberOfArguments) throw new InvalidOperationException(); // append a new argument branch after expanding all argument nodes var clonedBranch = (ISymbolicExpressionTreeNode)replacedBranch.Clone(); clonedBranch = ReplaceArgumentsInBranch(clonedBranch, invocationNode.Subtrees); invocationNode.InsertSubtree(newArgumentNode.Symbol.ArgumentIndex, clonedBranch); newlyAddedBranches.Add(clonedBranch); } // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed invocationNodes = (from newlyAddedBranch in newlyAddedBranches from node in newlyAddedBranch.IterateNodesPostfix().OfType<InvokeFunctionTreeNode>() where node.Symbol.FunctionName == defunBranch.FunctionName where node.Subtrees.Count() == defunBranch.NumberOfArguments select node).ToList(); } // increase expected number of arguments of function defining branch // it's possible that the number of actually referenced arguments was reduced (all references were replaced by a single new argument) // but the number of expected arguments is increased anyway defunBranch.NumberOfArguments++; defunBranch.Grammar.AddSymbol(newArgumentNode.Symbol); defunBranch.Grammar.SetSubtreeCount(newArgumentNode.Symbol, 0, 0); // allow the argument as child of any other symbol GrammarModifier.SetAllowedParentSymbols(defunBranch.Grammar, selectedCutPoint.Child.Symbol, newArgumentNode.Symbol); foreach (var subtree in tree.Root.Subtrees) { // when the changed function is known in the branch then update the number of arguments var matchingSymbol = subtree.Grammar.Symbols.OfType<InvokeFunction>().Where(s => s.FunctionName == defunBranch.FunctionName).SingleOrDefault(); if (matchingSymbol != null) { subtree.Grammar.SetSubtreeCount(matchingSymbol, defunBranch.NumberOfArguments, defunBranch.NumberOfArguments); foreach (var symb in subtree.Grammar.Symbols) { if (symb is StartSymbol || symb is ProgramRootSymbol) continue; if (symb.Name == matchingSymbol.Name) continue; //don't allow invoke as child of invoke if (subtree.Grammar.IsAllowedChildSymbol(selectedCutPoint.Parent.Symbol, symb, selectedCutPoint.ChildIndex)) subtree.Grammar.AddAllowedChildSymbol(matchingSymbol, symb, newArgumentNode.Symbol.ArgumentIndex); } } } return true; }
private static bool CreateNewArgumentForDefun(IRandom random, ISymbolicExpressionTree tree, DefunTreeNode defunBranch, ArgumentTreeNode newArgumentNode) { // select a random cut point in the function defining branch // the branch at the cut point is to be replaced by a new argument node var cutPoints = (from node in defunBranch.IterateNodesPrefix() where node.Subtrees.Count() > 0 && !node.IterateNodesPrefix().OfType <ArgumentTreeNode>().Any() && !node.IterateNodesPrefix().OfType <InvokeFunctionTreeNode>().Any() from subtree in node.Subtrees select new CutPoint(node, subtree)).ToList(); if (cutPoints.Count() == 0) { // no cut point found => abort; return(false); } var selectedCutPoint = cutPoints[random.Next(cutPoints.Count)]; // replace the branch at the cut point with an argument node var replacedBranch = selectedCutPoint.Child; selectedCutPoint.Parent.RemoveSubtree(selectedCutPoint.ChildIndex); selectedCutPoint.Parent.InsertSubtree(selectedCutPoint.ChildIndex, newArgumentNode); // find all old invocations of the selected ADF and attach a cloned version of the replaced branch (with all argument-nodes expanded) // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed var invocationNodes = (from node in tree.IterateNodesPostfix().OfType <InvokeFunctionTreeNode>() where node.Symbol.FunctionName == defunBranch.FunctionName where node.Subtrees.Count() == defunBranch.NumberOfArguments select node).ToList(); // do this repeatedly until no matching invocations are found while (invocationNodes.Count > 0) { List <ISymbolicExpressionTreeNode> newlyAddedBranches = new List <ISymbolicExpressionTreeNode>(); foreach (var invocationNode in invocationNodes) { // check that the invocation node really has the correct number of arguments if (invocationNode.Subtrees.Count() != defunBranch.NumberOfArguments) { throw new InvalidOperationException(); } // append a new argument branch after expanding all argument nodes var clonedBranch = (ISymbolicExpressionTreeNode)replacedBranch.Clone(); clonedBranch = ReplaceArgumentsInBranch(clonedBranch, invocationNode.Subtrees); invocationNode.InsertSubtree(newArgumentNode.Symbol.ArgumentIndex, clonedBranch); newlyAddedBranches.Add(clonedBranch); } // iterate in post-fix order to make sure that the subtrees of n are already adapted when n is processed invocationNodes = (from newlyAddedBranch in newlyAddedBranches from node in newlyAddedBranch.IterateNodesPostfix().OfType <InvokeFunctionTreeNode>() where node.Symbol.FunctionName == defunBranch.FunctionName where node.Subtrees.Count() == defunBranch.NumberOfArguments select node).ToList(); } // increase expected number of arguments of function defining branch // it's possible that the number of actually referenced arguments was reduced (all references were replaced by a single new argument) // but the number of expected arguments is increased anyway defunBranch.NumberOfArguments++; defunBranch.Grammar.AddSymbol(newArgumentNode.Symbol); defunBranch.Grammar.SetSubtreeCount(newArgumentNode.Symbol, 0, 0); // allow the argument as child of any other symbol GrammarModifier.SetAllowedParentSymbols(defunBranch.Grammar, selectedCutPoint.Child.Symbol, newArgumentNode.Symbol); foreach (var subtree in tree.Root.Subtrees) { // when the changed function is known in the branch then update the number of arguments var matchingSymbol = subtree.Grammar.Symbols.OfType <InvokeFunction>().Where(s => s.FunctionName == defunBranch.FunctionName).SingleOrDefault(); if (matchingSymbol != null) { subtree.Grammar.SetSubtreeCount(matchingSymbol, defunBranch.NumberOfArguments, defunBranch.NumberOfArguments); foreach (var symb in subtree.Grammar.Symbols) { if (symb is StartSymbol || symb is ProgramRootSymbol) { continue; } if (symb.Name == matchingSymbol.Name) { continue; //don't allow invoke as child of invoke } if (subtree.Grammar.IsAllowedChildSymbol(selectedCutPoint.Parent.Symbol, symb, selectedCutPoint.ChildIndex)) { subtree.Grammar.AddAllowedChildSymbol(matchingSymbol, symb, newArgumentNode.Symbol.ArgumentIndex); } } } } return(true); }
private bool IsValid(ISymbolicExpressionTree tree) { treeChart.Tree = tree; treeChart.Repaint(); bool valid = !tree.IterateNodesPostfix().Any(node => node.SubtreeCount < GetMinArity(node.Symbol) || node.SubtreeCount > node.Symbol.MaximumArity); if (valid) { btnOptimizeConstants.Enabled = true; btnSimplify.Enabled = true; treeStatusValue.Visible = false; } else { btnOptimizeConstants.Enabled = false; btnSimplify.Enabled = false; treeStatusValue.Visible = true; } this.Refresh(); return valid; }
private void GenerateHeader(StringBuilder strBuilder, ISymbolicExpressionTree symbolicExpressionTree) { strBuilder.AppendLine("using System;"); strBuilder.AppendLine("using System.Linq;" + Environment.NewLine); strBuilder.AppendLine("namespace HeuristicLab.Models {"); strBuilder.AppendLine("public static class Model {"); GenerateAverageSource(strBuilder); GenerateIfThenElseSource(strBuilder); strBuilder.Append(Environment.NewLine + "public static double Evaluate ("); HashSet<string> varNames = new HashSet<string>(); foreach (var node in symbolicExpressionTree.IterateNodesPostfix().Where(x => x is VariableTreeNode)) { varNames.Add(((VariableTreeNode)node).VariableName); } var orderedNames = varNames.OrderBy(n => n, new NaturalStringComparer()).Select(n => "double " + n); strBuilder.Append(string.Join(", ", orderedNames)); strBuilder.AppendLine(") {"); strBuilder.Append("double result = "); }
public static void IsValid(ISymbolicExpressionTree tree) { int reportedSize = tree.Length; int actualSize = tree.IterateNodesPostfix().Count(); Assert.AreEqual(actualSize, reportedSize); foreach (var defunTreeNode in tree.Root.Subtrees.OfType<DefunTreeNode>()) { int arity = defunTreeNode.NumberOfArguments; foreach (var argTreenode in defunTreeNode.IterateNodesPrefix().OfType<ArgumentTreeNode>()) { Assert.IsTrue(argTreenode.SubtreeCount == 0); Assert.IsTrue(((Argument)argTreenode.Symbol).ArgumentIndex < arity); } foreach (var argSymbol in Enumerable.Range(0, defunTreeNode.NumberOfArguments).Select(x => new Argument(x))) { Assert.IsTrue(defunTreeNode.Grammar.ContainsSymbol(argSymbol)); Assert.IsTrue(defunTreeNode.Grammar.GetMaximumSubtreeCount(argSymbol) == 0); Assert.IsTrue(defunTreeNode.Grammar.GetMinimumSubtreeCount(argSymbol) == 0); } var invoke = new InvokeFunction(defunTreeNode.FunctionName); foreach (var otherRootNode in tree.Root.Subtrees) { if (otherRootNode.Grammar.ContainsSymbol(invoke)) { Assert.IsTrue(otherRootNode.Grammar.GetMinimumSubtreeCount(invoke) == arity); Assert.IsTrue(otherRootNode.Grammar.GetMaximumSubtreeCount(invoke) == arity); Assert.IsFalse(otherRootNode.Grammar.IsAllowedChildSymbol(invoke, invoke)); for (int i = 0; i < arity; i++) { Assert.IsFalse(otherRootNode.Grammar.IsAllowedChildSymbol(invoke, invoke, i)); } } } } foreach (var subtree in tree.Root.Subtrees) { if (tree.Root.Grammar.GetType().Name != "EmptySymbolicExpressionTreeGrammar") Assert.AreNotSame(subtree.Grammar, tree.Root.Grammar); IsValid(subtree.Grammar); } IsValid(tree.Root.Grammar); IsValid(tree.Root); }
public static double[] Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows, bool applyLinearScaling, int decimalPlaces) { double r2 = SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, problemData, rows, applyLinearScaling); if (decimalPlaces >= 0) r2 = Math.Round(r2, decimalPlaces); return new double[2] { r2, solution.IterateNodesPostfix().Sum(n => n.GetLength()) }; // sum of the length of the whole sub-tree for each node }