- Timestamp:
- 11/19/21 16:07:45 (3 years ago)
- Location:
- branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4
- Files:
-
- 15 edited
- 6 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs
r17226 r18086 149 149 return Product(Product(CreateConstant(3.0), Square(f)), Derive(f, variableName)); 150 150 } 151 if (branch.Symbol is Power) { 152 // HL evaluators handle power strangely (exponent is rounded to an integer) 153 // here we only support the case when the exponent is a constant integer 154 var exponent = branch.GetSubtree(1) as ConstantTreeNode; 155 if (exponent != null && Math.Truncate(exponent.Value) == exponent.Value) { 156 var newPower = (ISymbolicExpressionTreeNode)branch.Clone(); 157 var f = (ISymbolicExpressionTreeNode)newPower.GetSubtree(0).Clone(); 158 var newExponent = (ConstantTreeNode)newPower.GetSubtree(1); 159 newExponent.Value -= 1; 160 return Product(Product(CreateConstant(exponent.Value), newPower), Derive(f, variableName)); 161 } else throw new NotSupportedException("Cannot derive non-integer powers"); 162 } 151 163 if (branch.Symbol is Absolute) { 152 164 var f = (ISymbolicExpressionTreeNode)branch.GetSubtree(0).Clone(); … … 263 275 !(n.Symbol is Cube) && 264 276 !(n.Symbol is CubeRoot) && 277 !(n.Symbol is Power) && 265 278 !(n.Symbol is Absolute) && 266 279 !(n.Symbol is AnalyticQuotient) && 280 !(n.Symbol is HyperbolicTangent) && 267 281 !(n.Symbol is Sine) && 268 282 !(n.Symbol is Cosine) && -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
r17226 r18086 784 784 } else if (IsExp(node)) { 785 785 return MakeExp(MakeProduct(node.GetSubtree(0), MakeConstant(2.0))); // sqr(exp(x)) = exp(2x) 786 } else if (IsSquare(node)) { 787 return MakePower(node.GetSubtree(0), MakeConstant(4)); 786 788 } else if (IsCube(node)) { 787 789 return MakePower(node.GetSubtree(0), MakeConstant(6)); … … 809 811 } else if (IsSquare(node)) { 810 812 return MakePower(node.GetSubtree(0), MakeConstant(6)); 813 } else if (IsCube(node)) { 814 return MakePower(node.GetSubtree(0), MakeConstant(9)); 811 815 } else { 812 816 var cubeNode = cubeSymbol.CreateTreeNode(); … … 933 937 var constB = b as ConstantTreeNode; 934 938 var constBValue = Math.Round(constB.Value); 935 if (constBValue.IsAlmost(1.0)) { 939 if (constBValue == 1.0) { 940 // root(a, 1) => a 936 941 return a; 937 } else if (constBValue.IsAlmost(0.0)) { 938 return MakeConstant(1.0); 939 } else if (constBValue.IsAlmost(-1.0)) { 942 } else if (constBValue == 0.0) { 943 // root(a, 0) is not defined 944 //return MakeConstant(1.0); 945 return MakeConstant(double.NaN); 946 } else if (constBValue == -1.0) { 947 // root(a, -1) => a^(-1/1) => 1/a 940 948 return MakeFraction(MakeConstant(1.0), a); 941 949 } else if (constBValue < 0) { 950 // root(a, -b) => a^(-1/b) => (1/a)^(1/b) => root(1, b) / root(a, b) => 1 / root(a, b) 942 951 var rootNode = rootSymbol.CreateTreeNode(); 943 952 rootNode.AddSubtree(a); … … 987 996 var constB = b as ConstantTreeNode; 988 997 double exponent = Math.Round(constB.Value); 989 if (exponent.IsAlmost(0.0)) { 998 if (exponent == 0.0) { 999 // a^0 => 1 990 1000 return MakeConstant(1.0); 991 } else if (exponent.IsAlmost(1.0)) { 1001 } else if (exponent == 1.0) { 1002 // a^1 => a 992 1003 return a; 993 } else if (exponent.IsAlmost(-1.0)) { 1004 } else if (exponent == -1.0) { 1005 // a^-1 => 1/a 994 1006 return MakeFraction(MakeConstant(1.0), a); 995 1007 } else if (exponent < 0) { 1008 // a^-b => (1/a)^b => 1/(a^b) 996 1009 var powNode = powSymbol.CreateTreeNode(); 997 1010 powNode.AddSubtree(a); … … 1018 1031 // fold constants 1019 1032 return MakeConstant(((ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value); 1020 } else if ((IsConstant(a) && !((ConstantTreeNode)a).Value.IsAlmost(1.0))) { 1033 } else if ((IsConstant(a) && ((ConstantTreeNode)a).Value != 1.0)) { 1034 // a / x => (a * 1/a) / (x * 1/a) => 1 / (x * 1/a) 1021 1035 return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a))); 1022 1036 } else if (IsVariableBase(a) && IsConstant(b)) { … … 1094 1108 // b is not constant => make sure constant is on the right 1095 1109 return MakeSum(b, a); 1096 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value .IsAlmost(0.0)) {1110 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) { 1097 1111 // x + 0 => x 1098 1112 return a; … … 1210 1224 foreach (var unchangedSubtree in unchangedSubtrees) 1211 1225 sum.AddSubtree(unchangedSubtree); 1212 if ( !constant.IsAlmost(0.0)) {1226 if (constant != 0.0) { 1213 1227 sum.AddSubtree(MakeConstant(constant)); 1214 1228 } … … 1268 1282 if (wi < 0) throw new ArgumentException(); 1269 1283 return MakeBinFactor(node1.Symbol, node1.VariableName, node1.VariableValue, node1.Weight * node0.Weights[wi]); 1270 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value .IsAlmost(1.0)) {1284 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 1.0) { 1271 1285 // $ * 1.0 => $ 1272 1286 return a; 1273 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value .IsAlmost(0.0)) {1287 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) { 1274 1288 return MakeConstant(0); 1275 1289 } else if (IsConstant(b) && IsVariableBase(a)) { … … 1419 1433 prod.AddSubtree(unchangedSubtree); 1420 1434 1421 if ( !constantProduct.IsAlmost(1.0)) {1435 if (constantProduct != 1.0) { 1422 1436 prod.AddSubtree(MakeConstant(constantProduct)); 1423 1437 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
r17226 r18086 258 258 if (node.Symbol is CubeRoot) { 259 259 return cbrt(ConvertToAutoDiff(node.GetSubtree(0))); 260 } 261 if (node.Symbol is Power) { 262 var powerNode = node.GetSubtree(1) as ConstantTreeNode; 263 if (powerNode == null) 264 throw new NotSupportedException("Only integer powers are allowed in parameter optimization. Try to use exp() and log() instead of the power symbol."); 265 var intPower = Math.Truncate(powerNode.Value); 266 if (intPower != powerNode.Value) 267 throw new NotSupportedException("Only integer powers are allowed in parameter optimization. Try to use exp() and log() instead of the power symbol."); 268 return AutoDiff.TermBuilder.Power(ConvertToAutoDiff(node.GetSubtree(0)), intPower); 260 269 } 261 270 if (node.Symbol is Sine) { … … 340 349 !(n.Symbol is AnalyticQuotient) && 341 350 !(n.Symbol is Cube) && 342 !(n.Symbol is CubeRoot) 351 !(n.Symbol is CubeRoot) && 352 !(n.Symbol is Power) 343 353 select n).Any(); 344 354 return !containsUnknownSymbol; -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Creators/MultiSymbolicDataAnalysisExpressionCreator.cs
r17226 r18086 44 44 private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth"; 45 45 private const string SymbolicExpressionTreeGrammarParameterName = "SymbolicExpressionTreeGrammar"; 46 private const string ClonedSymbolicExpressionTreeGrammarParameterName = "ClonedSymbolicExpressionTreeGrammar";47 46 48 47 public override bool CanChangeName { … … 66 65 get { return (IValueLookupParameter<ISymbolicExpressionGrammar>)Parameters[SymbolicExpressionTreeGrammarParameterName]; } 67 66 } 68 public ILookupParameter<ISymbolicExpressionGrammar> ClonedSymbolicExpressionTreeGrammarParameter {69 get { return (ILookupParameter<ISymbolicExpressionGrammar>)Parameters[ClonedSymbolicExpressionTreeGrammarParameterName]; }70 }71 67 #endregion 72 68 … … 80 76 Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "The maximal length (number of nodes) of the symbolic expression tree.")); 81 77 Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0).")); 82 Parameters.Add(new ValueLookupParameter<ISymbolicExpressionGrammar>(SymbolicExpressionTreeGrammarParameterName, "The tree grammar that defines the correct syntax of symbolic expression trees that should be created.")); 83 Parameters.Add(new LookupParameter<ISymbolicExpressionGrammar>(ClonedSymbolicExpressionTreeGrammarParameterName, "An immutable clone of the concrete grammar that is actually used to create and manipulate trees.")); 78 Parameters.Add(new ValueLookupParameter<ISymbolicExpressionGrammar>(SymbolicExpressionTreeGrammarParameterName, "The tree grammar that defines the correct syntax of symbolic expression trees that should be created.")); 84 79 85 80 List<ISymbolicDataAnalysisSolutionCreator> list = new List<ISymbolicDataAnalysisSolutionCreator>(); … … 96 91 } 97 92 98 public override IOperation InstrumentedApply() {99 if (ClonedSymbolicExpressionTreeGrammarParameter.ActualValue == null) {100 SymbolicExpressionTreeGrammarParameter.ActualValue.ReadOnly = true;101 IScope globalScope = ExecutionContext.Scope;102 while (globalScope.Parent != null)103 globalScope = globalScope.Parent;104 105 globalScope.Variables.Add(new Core.Variable(ClonedSymbolicExpressionTreeGrammarParameterName, (ISymbolicExpressionGrammar)SymbolicExpressionTreeGrammarParameter.ActualValue.Clone()));106 }107 return base.InstrumentedApply();108 }109 93 110 94 public ISymbolicExpressionTree CreateTree(IRandom random, ISymbolicExpressionGrammar grammar, int maxTreeLength, int maxTreeDepth) { -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
r17586 r18086 38 38 // operators 39 39 if (token == "+" || token == "-" || token == "OR" || token == "XOR" || 40 token == "*" || token == "/" || token == "AND" || 41 token == "^") { 40 token == "*" || token == "/" || token == "AND") { 42 41 strBuilder.Append("("); 43 42 FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants); … … 46 45 strBuilder.Append(" ").Append(token).Append(" "); 47 46 FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants); 47 } 48 49 strBuilder.Append(")"); 50 } else if (token == "^") { 51 // handle integer powers directly 52 strBuilder.Append("("); 53 FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants); 54 55 var power = node.GetSubtree(1); 56 if(power is ConstantTreeNode constNode && Math.Truncate(constNode.Value) == constNode.Value) { 57 strBuilder.Append(" ").Append(token).Append(" ").Append(constNode.Value.ToString(formatString, numberFormat)); 58 } else { 59 strBuilder.Append(" ").Append(token).Append(" "); 60 FormatRecursively(power, strBuilder, numberFormat, formatString, constants); 48 61 } 49 62 … … 83 96 if (!varNode.Weight.IsAlmost(1.0)) { 84 97 strBuilder.Append("("); 85 if (constants != null) { 86 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", varNode.Weight); 87 } else { 88 strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat)); 89 } 98 AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat); 90 99 strBuilder.Append("*"); 91 100 } 92 101 93 102 strBuilder.Append("LAG("); 94 if (varNode.VariableName.Contains("'")) 95 strBuilder.AppendFormat("\"{0}\"", varNode.VariableName); 96 else 97 strBuilder.AppendFormat("'{0}'", varNode.VariableName); 98 103 AppendVariableName(strBuilder, varNode.VariableName); 99 104 strBuilder.Append(", ") 100 105 .AppendFormat(numberFormat, "{0}", varNode.Lag) 101 106 .Append(")"); 107 if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")"); 102 108 } else if (node.Symbol is Variable) { 103 109 var varNode = node as VariableTreeNode; 104 110 if (!varNode.Weight.IsAlmost(1.0)) { 105 111 strBuilder.Append("("); 106 if (constants != null) { 107 string constantKey = $"c_{constants.Count}"; 108 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constantKey); 109 constants.Add(new KeyValuePair<string, double>(constantKey, varNode.Weight)); 110 } else { 111 strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat)); 112 } 113 112 AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat); 114 113 strBuilder.Append("*"); 115 114 } 116 115 117 if (varNode.VariableName.Contains("'")) 118 strBuilder.AppendFormat("\"{0}\"", varNode.VariableName); 119 else 120 strBuilder.AppendFormat("'{0}'", varNode.VariableName); 116 AppendVariableName(strBuilder, varNode.VariableName); 121 117 122 118 if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")"); 123 119 } else if (node.Symbol is FactorVariable) { 124 120 var factorNode = node as FactorVariableTreeNode; 125 if (factorNode.VariableName.Contains("'")) 126 strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName); 127 else 128 strBuilder.AppendFormat("'{0}'", factorNode.VariableName); 129 130 strBuilder.AppendFormat("[{0}]", 131 string.Join(", ", factorNode.Weights.Select(w => w.ToString(formatString, numberFormat)))); 121 AppendVariableName(strBuilder, factorNode.VariableName); 122 123 strBuilder.Append("["); 124 for (int i = 0; i < factorNode.Weights.Length; i++) { 125 if (i > 0) strBuilder.Append(", "); 126 AppendConstant(strBuilder, constants, factorNode.Weights[i], formatString, numberFormat); 127 } 128 strBuilder.Append("]"); 132 129 } else if (node.Symbol is BinaryFactorVariable) { 133 130 var factorNode = node as BinaryFactorVariableTreeNode; 134 131 if (!factorNode.Weight.IsAlmost(1.0)) { 135 132 strBuilder.Append("("); 136 if (constants != null) { 137 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", factorNode.Weight); 138 } else { 139 strBuilder.Append(factorNode.Weight.ToString(formatString, numberFormat)); 140 } 133 AppendConstant(strBuilder, constants, factorNode.Weight, formatString, numberFormat); 141 134 142 135 strBuilder.Append("*"); 143 136 } 144 137 145 if (factorNode.VariableName.Contains("'")) 146 strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName); 147 else 148 strBuilder.AppendFormat("'{0}'", factorNode.VariableName); 149 138 AppendVariableName(strBuilder, factorNode.VariableName); 150 139 strBuilder.Append(" = "); 151 if (factorNode.VariableValue.Contains("'")) 152 strBuilder.AppendFormat("\"{0}\"", factorNode.VariableValue); 153 else 154 strBuilder.AppendFormat("'{0}'", factorNode.VariableValue); 140 AppendVariableName(strBuilder, factorNode.VariableValue); 155 141 156 142 if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")"); 157 143 } else if (node.Symbol is Constant) { 158 144 var constNode = node as ConstantTreeNode; 159 if (constants != null) { 160 string constantKey = $"c_{constants.Count}"; 161 162 strBuilder.AppendFormat(CultureInfo.InvariantCulture, constantKey); 163 constants.Add(new KeyValuePair<string, double>(constantKey, constNode.Value)); 145 if (constants == null && constNode.Value < 0) { 146 strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat)) 147 .Append(")"); // (-1 164 148 } else { 165 if (constNode.Value >= 0.0) 166 strBuilder.Append(constNode.Value.ToString(formatString, numberFormat)); 167 else 168 strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat)) 169 .Append(")"); // (-1 149 AppendConstant(strBuilder, constants, constNode.Value, formatString, numberFormat); 170 150 } 171 151 } 172 152 } 153 } 154 155 private static void AppendConstant(StringBuilder strBuilder, List<KeyValuePair<string, double>> constants, double value, string formatString, NumberFormatInfo numberFormat) { 156 if (constants != null) { 157 string constantKey = $"c_{constants.Count}"; 158 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", constantKey); 159 constants.Add(new KeyValuePair<string, double>(constantKey, value)); 160 } else { 161 strBuilder.Append(value.ToString(formatString, numberFormat)); 162 } 163 } 164 165 private static void AppendVariableName(StringBuilder strBuilder, string name) { 166 if (name.Contains("'")) 167 strBuilder.AppendFormat("\"{0}\"", name); 168 else 169 strBuilder.AppendFormat("'{0}'", name); 173 170 } 174 171 -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionCSharpFormatter.cs
r17226 r18086 154 154 strBuilder.Append(" / Math.Sqrt(1 + Math.Pow("); 155 155 FormatRecursively(node.GetSubtree(1), strBuilder); 156 strBuilder.Append(" , 2) ) ");156 strBuilder.Append(" , 2) ) )"); 157 157 } else { 158 158 throw new NotSupportedException("Formatting of symbol: " + node.Symbol + " not supported for C# symbolic expression tree formatter."); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
r17226 r18086 517 517 518 518 private void FormatStartSymbol(StringBuilder strBuilder) { 519 strBuilder.Append(targetVariable ?? "target_" + (targetCount++));519 strBuilder.Append(targetVariable != null ? EscapeLatexString(targetVariable) : "\\text{target}_{" + targetCount++ + "}"); 520 520 if (containsTimeSeriesSymbol) 521 521 strBuilder.Append("(t)"); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionPythonFormatter.cs
r17922 r18086 58 58 } 59 59 60 private st ring GenerateHeader(ISymbolicExpressionTree symbolicExpressionTree) {60 private static string GenerateHeader(ISymbolicExpressionTree symbolicExpressionTree) { 61 61 StringBuilder strBuilder = new StringBuilder(); 62 62 … … 102 102 } 103 103 104 private st ring GenerateNecessaryImports(int mathLibCounter, int statisticLibCounter) {104 private static string GenerateNecessaryImports(int mathLibCounter, int statisticLibCounter) { 105 105 StringBuilder strBuilder = new StringBuilder(); 106 106 if (mathLibCounter > 0 || statisticLibCounter > 0) { … … 115 115 } 116 116 117 private st ring GenerateIfThenElseSource(int evaluateIfCounter) {117 private static string GenerateIfThenElseSource(int evaluateIfCounter) { 118 118 StringBuilder strBuilder = new StringBuilder(); 119 119 if (evaluateIfCounter > 0) { … … 128 128 } 129 129 130 private st ring GenerateModelEvaluationFunction(ISet<string> variables) {130 private static string GenerateModelEvaluationFunction(ISet<string> variables) { 131 131 StringBuilder strBuilder = new StringBuilder(); 132 132 strBuilder.Append("def evaluate("); … … 142 142 } 143 143 144 private void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {144 private static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { 145 145 ISymbol symbol = node.Symbol; 146 146 if (symbol is ProgramRootSymbol) … … 208 208 } 209 209 210 private st ring VariableName2Identifier(string variableName) => variableName.Replace(" ", "_");211 212 private void FormatNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string prefixSymbol = "", string openingSymbol = "(", string closingSymbol = ")", string infixSymbol = ",") {210 private static string VariableName2Identifier(string variableName) => variableName.Replace(" ", "_"); 211 212 private static void FormatNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string prefixSymbol = "", string openingSymbol = "(", string closingSymbol = ")", string infixSymbol = ",") { 213 213 strBuilder.Append($"{prefixSymbol}{openingSymbol}"); 214 214 foreach (var child in node.Subtrees) { … … 220 220 } 221 221 222 private void FormatVariableTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {222 private static void FormatVariableTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { 223 223 var varNode = node as VariableTreeNode; 224 224 var formattedVariable = VariableName2Identifier(varNode.VariableName); … … 227 227 } 228 228 229 private void FormatConstantTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {229 private static void FormatConstantTreeNode(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { 230 230 var constNode = node as ConstantTreeNode; 231 231 strBuilder.Append(constNode.Value.ToString("g17", CultureInfo.InvariantCulture)); 232 232 } 233 233 234 private void FormatPower(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string exponent) {234 private static void FormatPower(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, string exponent) { 235 235 strBuilder.Append("math.pow("); 236 236 FormatRecursively(node.GetSubtree(0), strBuilder); … … 238 238 } 239 239 240 private void FormatRoot(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {240 private static void FormatRoot(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { 241 241 strBuilder.Append("math.pow("); 242 242 FormatRecursively(node.GetSubtree(0), strBuilder); … … 246 246 } 247 247 248 private void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {248 private static void FormatSubtraction(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { 249 249 if (node.SubtreeCount == 1) { 250 250 strBuilder.Append("-"); … … 256 256 } 257 257 258 private void FormatDivision(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {258 private static void FormatDivision(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { 259 259 strBuilder.Append("("); 260 260 if (node.SubtreeCount == 1) { … … 273 273 } 274 274 275 private void FormatAnalyticQuotient(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) {275 private static void FormatAnalyticQuotient(ISymbolicExpressionTreeNode node, StringBuilder strBuilder) { 276 276 strBuilder.Append("("); 277 277 FormatRecursively(node.GetSubtree(0), strBuilder); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r17457 r18086 99 99 </PropertyGroup> 100 100 <ItemGroup> 101 <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 102 <HintPath>..\..\bin\ALGLIB-3.7.0.dll</HintPath> 101 <Reference Include="ALGLIB-3.17.0, Version=3.17.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 102 <SpecificVersion>False</SpecificVersion> 103 <HintPath>..\..\bin\ALGLIB-3.17.0.dll</HintPath> 103 104 <Private>False</Private> 104 105 </Reference> … … 107 108 <Private>False</Private> 108 109 </Reference> 109 <Reference Include="HEAL.Attic, Version=1. 0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">110 <Reference Include="HEAL.Attic, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 110 111 <SpecificVersion>False</SpecificVersion> 111 112 <HintPath>..\..\bin\HEAL.Attic.dll</HintPath> … … 153 154 <Compile Include="Crossovers\SymbolicDataAnalysisExpressionDiversityPreservingCrossover.cs" /> 154 155 <Compile Include="Formatters\InfixExpressionFormatter.cs" /> 156 <Compile Include="Formatters\SymbolicDataAnalysisExpressionPythonFormatter.cs" /> 155 157 <Compile Include="Formatters\TSQLExpressionFormatter.cs" /> 156 158 <Compile Include="Formatters\SymbolicDataAnalysisExpressionMathematicaFormatter.cs" /> 157 159 <Compile Include="Formatters\SymbolicDataAnalysisExpressionCSharpFormatter.cs" /> 158 160 <Compile Include="Grammars\DataAnalysisGrammar.cs" /> 161 <Compile Include="Grammars\LinearScalingGrammar.cs" /> 159 162 <Compile Include="Hashing\HashExtensions.cs" /> 160 163 <Compile Include="Hashing\HashUtil.cs" /> … … 163 166 <Compile Include="Importer\SymbolicExpressionImporter.cs" /> 164 167 <Compile Include="Importer\Token.cs" /> 168 <Compile Include="Interfaces\IBoundsEstimator.cs" /> 165 169 <Compile Include="Interfaces\IModelBacktransformator.cs" /> 166 170 <Compile Include="Interfaces\IVariableTreeNode.cs" /> … … 168 172 <Compile Include="Interpreter\BatchInstruction.cs" /> 169 173 <Compile Include="Interpreter\BatchOperations.cs" /> 174 <Compile Include="Interpreter\IntervalArithBoundsEstimator.cs" /> 175 <Compile Include="Interpreter\IntervalArithCompiledExpressionBoundsEstimator.cs" /> 170 176 <Compile Include="Interpreter\IntervalInterpreter.cs" /> 171 177 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" /> 172 178 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs" /> 173 179 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs" /> 180 <Compile Include="IntervalUtil.cs" /> 174 181 <Compile Include="Selectors\DiversitySelector.cs" /> 175 182 <Compile Include="SymbolicDataAnalysisExpressionTreeAverageSimilarityCalculator.cs" /> -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
r17226 r18086 64 64 } 65 65 66 private class Symbol NameComparer : IEqualityComparer<ISymbol>, IComparer<ISymbol> {66 private class SymbolComparer : IEqualityComparer<ISymbol>, IComparer<ISymbol> { 67 67 public int Compare(ISymbol x, ISymbol y) { 68 68 return x.Name.CompareTo(y.Name); … … 70 70 71 71 public bool Equals(ISymbol x, ISymbol y) { 72 return Compare(x, y) == 0;72 return x.GetType() == y.GetType(); 73 73 } 74 74 75 75 public int GetHashCode(ISymbol obj) { 76 return obj. Name.GetHashCode();76 return obj.GetType().GetHashCode(); 77 77 } 78 78 } … … 80 80 // the lookup table is also used in the corresponding formatter 81 81 internal static readonly BidirectionalLookup<string, ISymbol> 82 knownSymbols = new BidirectionalLookup<string, ISymbol>(StringComparer.InvariantCulture, new Symbol NameComparer());82 knownSymbols = new BidirectionalLookup<string, ISymbol>(StringComparer.InvariantCulture, new SymbolComparer()); 83 83 84 84 private Constant constant = new Constant(); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalArithBoundsEstimator.cs
r17903 r18086 53 53 private IntervalArithBoundsEstimator(StorableConstructorFlag _) : base(_) { } 54 54 55 pr ivateIntervalArithBoundsEstimator(IntervalArithBoundsEstimator original, Cloner cloner) : base(original, cloner) { }55 protected IntervalArithBoundsEstimator(IntervalArithBoundsEstimator original, Cloner cloner) : base(original, cloner) { } 56 56 57 57 public IntervalArithBoundsEstimator() : base("Interval Arithmetic Bounds Estimator", … … 223 223 break; 224 224 } 225 case OpCodes.Power: { 226 var a = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 227 var b = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 228 // support only integer powers 229 if (b.LowerBound == b.UpperBound && Math.Truncate(b.LowerBound) == b.LowerBound) { 230 result = Interval.Power(a, (int)b.LowerBound); 231 } else { 232 throw new NotSupportedException("Interval is only supported for integer powers"); 233 } 234 break; 235 } 225 236 case OpCodes.Absolute: { 226 237 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); … … 232 243 for (var i = 1; i < currentInstr.nArguments; i++) { 233 244 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 234 result = Interval.Analytic alQuotient(result, argumentInterval);245 result = Interval.AnalyticQuotient(result, argumentInterval); 235 246 } 236 247 … … 329 340 !(n.Symbol is Cube) && 330 341 !(n.Symbol is CubeRoot) && 342 !(n.Symbol is Power) && 331 343 !(n.Symbol is Absolute) && 332 344 !(n.Symbol is AnalyticQuotient) -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalArithCompiledExpressionBoundsEstimator.cs
r17903 r18086 75 75 76 76 [StorableConstructor] 77 pr ivateIntervalArithCompiledExpressionBoundsEstimator(StorableConstructorFlag _) : base(_) { }78 79 pr ivateIntervalArithCompiledExpressionBoundsEstimator(IntervalArithCompiledExpressionBoundsEstimator original, Cloner cloner) : base(original, cloner) { }77 protected IntervalArithCompiledExpressionBoundsEstimator(StorableConstructorFlag _) : base(_) { } 78 79 protected IntervalArithCompiledExpressionBoundsEstimator(IntervalArithCompiledExpressionBoundsEstimator original, Cloner cloner) : base(original, cloner) { } 80 80 81 81 public override IDeepCloneable Clone(Cloner cloner) { … … 194 194 return Expression.Divide(e1, e2); 195 195 } 196 case OpCodes.AnalyticQuotient: { 197 var a = expr(node.GetSubtree(0)); 198 var b = expr(node.GetSubtree(1)); 199 var fun = typeof(Interval).GetMethod(methodName[opCode], new[] { a.Type, b.Type }); 200 return Expression.Call(fun, a, b); 201 } 196 202 // all these cases share the same code: get method info by name, emit call expression 197 203 case OpCodes.Exp: … … 205 211 case OpCodes.SquareRoot: 206 212 case OpCodes.CubeRoot: 207 case OpCodes.Absolute: 208 case OpCodes.AnalyticQuotient: { 213 case OpCodes.Absolute: { 209 214 var arg = expr(node.GetSubtree(0)); 210 215 var fun = typeof(Interval).GetMethod(methodName[opCode], new[] { arg.Type }); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs
r17586 r18086 1 1 #region License Information 2 2 3 /* HeuristicLab 3 4 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) … … 18 19 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 19 20 */ 21 20 22 #endregion 21 23 … … 32 34 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 33 35 [StorableType("DE6C1E1E-D7C1-4070-847E-63B68562B10C")] 34 [Item("IntervalInterpreter", "Int perter for calculation of intervals of symbolic models.")]36 [Item("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.")] 35 37 public sealed class IntervalInterpreter : ParameterizedNamedItem, IStatefulItem { 36 37 38 private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions"; 38 39 public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter { 40 get { return (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; } 41 } 39 public IFixedValueParameter<IntValue> EvaluatedSolutionsParameter => 40 (IFixedValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; 42 41 43 42 public int EvaluatedSolutions { 44 get { return EvaluatedSolutionsParameter.Value.Value; }45 set { EvaluatedSolutionsParameter.Value.Value = value; }43 get => EvaluatedSolutionsParameter.Value.Value; 44 set => EvaluatedSolutionsParameter.Value.Value = value; 46 45 } 47 46 48 47 [StorableConstructor] 49 48 private IntervalInterpreter(StorableConstructorFlag _) : base(_) { } 49 50 50 private IntervalInterpreter(IntervalInterpreter original, Cloner cloner) 51 51 : base(original, cloner) { } 52 52 53 53 public IntervalInterpreter() 54 : base("IntervalInterpreter", "Intperter for calculation of intervals of symbolic models.") { 55 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 54 : base("IntervalInterpreter", "Interpreter for calculation of intervals of symbolic models.") { 55 Parameters.Add(new FixedValueParameter<IntValue>(EvaluatedSolutionsParameterName, 56 "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0))); 56 57 } 57 58 … … 63 64 64 65 #region IStatefulItem Members 66 65 67 public void InitializeState() { 66 68 EvaluatedSolutions = 0; 67 69 } 70 68 71 public void ClearState() { } 72 69 73 #endregion 70 74 71 public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IDataset dataset, IEnumerable<int> rows = null) { 75 public Interval GetSymbolicExpressionTreeInterval( 76 ISymbolicExpressionTree tree, IDataset dataset, 77 IEnumerable<int> rows = null) { 72 78 var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows); 73 79 return GetSymbolicExpressionTreeInterval(tree, variableRanges); 74 80 } 75 81 76 public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, IDataset dataset, 77 out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals, IEnumerable<int> rows = null) { 82 public Interval GetSymbolicExpressionTreeIntervals( 83 ISymbolicExpressionTree tree, IDataset dataset, 84 out IDictionary<ISymbolicExpressionTreeNode, Interval> 85 nodeIntervals, IEnumerable<int> rows = null) { 78 86 var variableRanges = DatasetUtil.GetVariableRanges(dataset, rows); 79 87 return GetSymbolicExpressionTreeIntervals(tree, variableRanges, out nodeIntervals); 80 88 } 81 89 82 public Interval GetSymbolicExpressionTreeInterval(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) { 90 public Interval GetSymbolicExpressionTreeInterval( 91 ISymbolicExpressionTree tree, 92 IReadOnlyDictionary<string, Interval> variableRanges) { 83 93 lock (syncRoot) { 84 94 EvaluatedSolutions++; 85 95 } 86 int instructionCount = 0; 96 97 Interval outputInterval; 98 99 var instructionCount = 0; 87 100 var instructions = PrepareInterpreterState(tree, variableRanges); 88 var outputInterval = Evaluate(instructions, ref instructionCount); 89 90 // because of numerical errors the bounds might be incorrect 91 if (outputInterval.LowerBound <= outputInterval.UpperBound) 92 return outputInterval; 93 else 94 return new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 95 } 96 97 98 public Interval GetSymbolicExpressionTreeIntervals(ISymbolicExpressionTree tree, 99 IReadOnlyDictionary<string, Interval> variableRanges, out IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals) { 101 outputInterval = Evaluate(instructions, ref instructionCount); 102 103 return outputInterval.LowerBound <= outputInterval.UpperBound 104 ? outputInterval 105 : new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 106 } 107 108 109 public Interval GetSymbolicExpressionTreeIntervals( 110 ISymbolicExpressionTree tree, 111 IReadOnlyDictionary<string, Interval> variableRanges, 112 out IDictionary<ISymbolicExpressionTreeNode, Interval> 113 nodeIntervals) { 100 114 lock (syncRoot) { 101 115 EvaluatedSolutions++; 102 116 } 103 int instructionCount = 0; 117 104 118 var intervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>(); 105 119 var instructions = PrepareInterpreterState(tree, variableRanges); 106 var outputInterval = Evaluate(instructions, ref instructionCount, intervals); 107 108 // fix incorrect intervals if necessary (could occur because of numerical errors) 120 121 Interval outputInterval; 122 var instructionCount = 0; 123 outputInterval = Evaluate(instructions, ref instructionCount, intervals); 124 109 125 nodeIntervals = new Dictionary<ISymbolicExpressionTreeNode, Interval>(); 110 126 foreach (var kvp in intervals) { … … 119 135 if (outputInterval.IsInfiniteOrUndefined || outputInterval.LowerBound <= outputInterval.UpperBound) 120 136 return outputInterval; 121 else 122 return new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 123 } 124 125 126 private static Instruction[] PrepareInterpreterState(ISymbolicExpressionTree tree, IReadOnlyDictionary<string, Interval> variableRanges) { 137 138 return new Interval(outputInterval.UpperBound, outputInterval.LowerBound); 139 } 140 141 142 private static Instruction[] PrepareInterpreterState( 143 ISymbolicExpressionTree tree, 144 IReadOnlyDictionary<string, Interval> variableRanges) { 127 145 if (variableRanges == null) 128 146 throw new ArgumentNullException("No variablew ranges are present!", nameof(variableRanges)); 129 147 130 //Check if all variables used in the tree are present in the dataset 131 foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName).Distinct()) { 132 if (!variableRanges.ContainsKey(variable)) throw new InvalidOperationException($"No ranges for variable {variable} is present"); 133 } 134 135 Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode); 136 foreach (Instruction instr in code.Where(i => i.opCode == OpCodes.Variable)) { 148 // Check if all variables used in the tree are present in the dataset 149 foreach (var variable in tree.IterateNodesPrefix().OfType<VariableTreeNode>().Select(n => n.VariableName) 150 .Distinct()) 151 if (!variableRanges.ContainsKey(variable)) 152 throw new InvalidOperationException($"No ranges for variable {variable} is present"); 153 154 var code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode); 155 foreach (var instr in code.Where(i => i.opCode == OpCodes.Variable)) { 137 156 var variableTreeNode = (VariableTreeNode)instr.dynamicNode; 138 157 instr.data = variableRanges[variableTreeNode.VariableName]; 139 158 } 159 140 160 return code; 141 161 } 142 162 143 private Interval Evaluate(Instruction[] instructions, ref int instructionCounter, IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null) { 144 Instruction currentInstr = instructions[instructionCounter]; 145 //Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side 146 //Update instructionCounter, whenever Evaluate is called 163 // Use ref parameter, because the tree will be iterated through recursively from the left-side branch to the right side 164 // Update instructionCounter, whenever Evaluate is called 165 public static Interval Evaluate( 166 Instruction[] instructions, ref int instructionCounter, 167 IDictionary<ISymbolicExpressionTreeNode, Interval> nodeIntervals = null, 168 IReadOnlyDictionary<string, Interval> variableIntervals = null) { 169 var currentInstr = instructions[instructionCounter]; 170 147 171 instructionCounter++; 148 Interval result = null;172 Interval result; 149 173 150 174 switch (currentInstr.opCode) { 151 //Variables, Constants, ...152 175 case OpCodes.Variable: { 153 176 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode; 154 177 var weightInterval = new Interval(variableTreeNode.Weight, variableTreeNode.Weight); 155 var variableInterval = (Interval)currentInstr.data; 178 179 Interval variableInterval; 180 if (variableIntervals != null && variableIntervals.ContainsKey(variableTreeNode.VariableName)) 181 variableInterval = variableIntervals[variableTreeNode.VariableName]; 182 else 183 variableInterval = (Interval)currentInstr.data; 156 184 157 185 result = Interval.Multiply(variableInterval, weightInterval); … … 163 191 break; 164 192 } 165 //Elementary arithmetic rules166 193 case OpCodes.Add: { 167 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );168 for ( inti = 1; i < currentInstr.nArguments; i++) {169 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );194 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 195 for (var i = 1; i < currentInstr.nArguments; i++) { 196 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 170 197 result = Interval.Add(result, argumentInterval); 171 198 } 199 172 200 break; 173 201 } 174 202 case OpCodes.Sub: { 175 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );203 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 176 204 if (currentInstr.nArguments == 1) 177 205 result = Interval.Multiply(new Interval(-1, -1), result); 178 206 179 for ( inti = 1; i < currentInstr.nArguments; i++) {180 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );207 for (var i = 1; i < currentInstr.nArguments; i++) { 208 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 181 209 result = Interval.Subtract(result, argumentInterval); 182 210 } 211 183 212 break; 184 213 } 185 214 case OpCodes.Mul: { 186 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );187 for ( inti = 1; i < currentInstr.nArguments; i++) {188 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );215 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 216 for (var i = 1; i < currentInstr.nArguments; i++) { 217 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 189 218 result = Interval.Multiply(result, argumentInterval); 190 219 } 220 191 221 break; 192 222 } 193 223 case OpCodes.Div: { 194 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );224 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 195 225 if (currentInstr.nArguments == 1) 196 226 result = Interval.Divide(new Interval(1, 1), result); 197 227 198 for ( inti = 1; i < currentInstr.nArguments; i++) {199 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );228 for (var i = 1; i < currentInstr.nArguments; i++) { 229 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 200 230 result = Interval.Divide(result, argumentInterval); 201 231 } 202 break; 203 }204 //Trigonometric functions232 233 break; 234 } 205 235 case OpCodes.Sin: { 206 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );236 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 207 237 result = Interval.Sine(argumentInterval); 208 238 break; 209 239 } 210 240 case OpCodes.Cos: { 211 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );241 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 212 242 result = Interval.Cosine(argumentInterval); 213 243 break; 214 244 } 215 245 case OpCodes.Tan: { 216 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );246 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 217 247 result = Interval.Tangens(argumentInterval); 218 248 break; 219 249 } 220 250 case OpCodes.Tanh: { 221 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );251 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 222 252 result = Interval.HyperbolicTangent(argumentInterval); 223 253 break; 224 254 } 225 //Exponential functions226 255 case OpCodes.Log: { 227 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );256 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 228 257 result = Interval.Logarithm(argumentInterval); 229 258 break; 230 259 } 231 260 case OpCodes.Exp: { 232 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );261 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 233 262 result = Interval.Exponential(argumentInterval); 234 263 break; 235 264 } 236 265 case OpCodes.Square: { 237 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );266 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 238 267 result = Interval.Square(argumentInterval); 239 268 break; 240 269 } 241 270 case OpCodes.SquareRoot: { 242 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );271 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 243 272 result = Interval.SquareRoot(argumentInterval); 244 273 break; 245 274 } 246 275 case OpCodes.Cube: { 247 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );276 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 248 277 result = Interval.Cube(argumentInterval); 249 278 break; 250 279 } 251 280 case OpCodes.CubeRoot: { 252 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );281 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 253 282 result = Interval.CubicRoot(argumentInterval); 254 283 break; 255 284 } 285 case OpCodes.Power: { 286 var a = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 287 var b = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 288 // support only integer powers 289 if (b.LowerBound == b.UpperBound && Math.Truncate(b.LowerBound) == b.LowerBound) { 290 result = Interval.Power(a, (int)b.LowerBound); 291 } else { 292 throw new NotSupportedException("Interval is only supported for integer powers"); 293 } 294 break; 295 } 296 256 297 case OpCodes.Absolute: { 257 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );298 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 258 299 result = Interval.Absolute(argumentInterval); 259 300 break; 260 301 } 261 302 case OpCodes.AnalyticQuotient: { 262 result = Evaluate(instructions, ref instructionCounter, nodeIntervals );263 for (var i = 1; i < currentInstr.nArguments; i++) { 264 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );265 result = Interval.Analytic alQuotient(result, argumentInterval);303 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 304 for (var i = 1; i < currentInstr.nArguments; i++) { 305 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 306 result = Interval.AnalyticQuotient(result, argumentInterval); 266 307 } 267 308 … … 272 313 } 273 314 274 if ( nodeIntervals != null)315 if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode))) 275 316 nodeIntervals.Add(currentInstr.dynamicNode, result); 276 317 … … 278 319 } 279 320 321 280 322 public static bool IsCompatible(ISymbolicExpressionTree tree) { 281 var containsUnknownSyumbol = ( 282 from n in tree.Root.GetSubtree(0).IterateNodesPrefix() 283 where 284 !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) && 323 foreach (var n in tree.Root.GetSubtree(0).IterateNodesPrefix()) { 324 if ( 325 !(n.Symbol is Variable) && 285 326 !(n.Symbol is Constant) && 286 327 !(n.Symbol is StartSymbol) && … … 292 333 !(n.Symbol is Cosine) && 293 334 !(n.Symbol is Tangent) && 335 !(n.Symbol is HyperbolicTangent) && 294 336 !(n.Symbol is Logarithm) && 295 337 !(n.Symbol is Exponential) && … … 298 340 !(n.Symbol is Cube) && 299 341 !(n.Symbol is CubeRoot) && 342 !(n.Symbol is Power) && 300 343 !(n.Symbol is Absolute) && 301 !(n.Symbol is AnalyticQuotient) 302 select n).Any(); 303 return !containsUnknownSyumbol; 344 !(n.Symbol is AnalyticQuotient)) return false; 345 346 else if (n.Symbol is Power) { 347 // only integer exponents are supported 348 var exp = n.GetSubtree(1) as ConstantTreeNode; 349 if (exp == null || exp.Value != Math.Truncate(exp.Value)) return false; 350 } 351 } 352 return true; 304 353 } 305 354 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs
r17226 r18086 144 144 { typeof(Cosine), OpCodes.Cos }, 145 145 { typeof(Tangent), OpCodes.Tan }, 146 { typeof 146 { typeof(HyperbolicTangent), OpCodes.Tanh}, 147 147 { typeof(Logarithm), OpCodes.Log }, 148 148 { typeof(Exponential), OpCodes.Exp }, -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs
r17457 r18086 222 222 223 223 private double[] GetValues(ISymbolicExpressionTree tree, IDataset dataset, int[] rows) { 224 if (cachedData == null || cachedDataset != dataset ) {224 if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) { 225 225 InitCache(dataset); 226 226 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs
r17457 r18086 127 127 if (!rows.Any()) return Enumerable.Empty<double>(); 128 128 129 if (cachedData == null || cachedDataset != dataset ) {129 if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) { 130 130 InitCache(dataset); 131 131 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/IntervalUtil.cs
r17903 r18086 39 39 var varRanges = variableRanges.GetReadonlyDictionary(); 40 40 41 if ( constraint.Variable != null&& !varRanges.ContainsKey(constraint.Variable)) {41 if (!string.IsNullOrEmpty(constraint.Variable) && !varRanges.ContainsKey(constraint.Variable)) { 42 42 throw new ArgumentException( 43 $" The given variable {constraint.Variable} in the constraint does not exist in the model.",43 $"No variable range found for variable {constraint.Variable} used in the constraints.", 44 44 nameof(constraint)); 45 45 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Plugin.cs.frame
r17226 r18086 28 28 [Plugin("HeuristicLab.Problems.DataAnalysis.Symbolic","Provides base classes for symbolic data analysis tasks.", "3.4.12.$WCREV$")] 29 29 [PluginFile("HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll", PluginFileType.Assembly)] 30 [PluginDependency("HeuristicLab.ALGLIB", "3. 7.0")]30 [PluginDependency("HeuristicLab.ALGLIB", "3.17.0")] 31 31 [PluginDependency("HeuristicLab.AutoDiff", "1.0")] 32 32 [PluginDependency("HeuristicLab.Analysis", "3.3")] -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisMultiObjectiveProblem.cs
r17695 r18086 26 26 using HeuristicLab.Core; 27 27 using HeuristicLab.Data; 28 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 28 29 using HeuristicLab.Optimization; 29 30 using HeuristicLab.Parameters; … … 32 33 [StorableType("E9876DF8-ACFA-41C8-93B7-FA40C57CE459")] 33 34 public abstract class SymbolicDataAnalysisMultiObjectiveProblem<T, U> : SymbolicDataAnalysisProblem<T, U>, ISymbolicDataAnalysisMultiObjectiveProblem 34 where T : class, IDataAnalysisProblemData35 where T : class, IDataAnalysisProblemData 35 36 where U : class, ISymbolicDataAnalysisMultiObjectiveEvaluator<T> { 36 37 private const string MaximizationParameterName = "Maximization"; … … 102 103 op.MaximizationParameter.ActualName = MaximizationParameterName; 103 104 } 105 106 // these two crossover operators are compatible with single-objective problems only so we remove them from the operators collection 107 bool pred(IItem x) { 108 return x is SymbolicDataAnalysisExpressionDeterministicBestCrossover<T> || x is SymbolicDataAnalysisExpressionContextAwareCrossover<T>; 109 }; 110 Operators.RemoveAll(pred); 111 // if a multi crossover is present, remove them from its operator collection 112 var cx = Operators.FirstOrDefault(x => x is MultiSymbolicDataAnalysisExpressionCrossover<T>); 113 if (cx != null) { 114 var multiCrossover = (MultiSymbolicDataAnalysisExpressionCrossover<T>)cx; 115 var items = multiCrossover.Operators.Where(pred).Cast<ISymbolicExpressionTreeCrossover>().ToList(); 116 foreach (var item in items) { 117 multiCrossover.Operators.Remove(item); 118 } 119 } 104 120 } 105 121
Note: See TracChangeset
for help on using the changeset viewer.