Changeset 17928 for branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic
- Timestamp:
- 04/06/21 13:13:32 (4 years ago)
- Location:
- branches/3026_IntegrationIntoSymSpace
- Files:
-
- 20 edited
- 8 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3026_IntegrationIntoSymSpace
- Property svn:mergeinfo changed
-
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic
- Property svn:mergeinfo changed
-
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/DerivativeCalculator.cs
r17180 r17928 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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeSimplifier.cs
r17180 r17928 933 933 var constB = b as ConstantTreeNode; 934 934 var constBValue = Math.Round(constB.Value); 935 if (constBValue.IsAlmost(1.0)) { 935 if (constBValue == 1.0) { 936 // root(a, 1) => a 936 937 return a; 937 } else if (constBValue.IsAlmost(0.0)) { 938 return MakeConstant(1.0); 939 } else if (constBValue.IsAlmost(-1.0)) { 938 } else if (constBValue == 0.0) { 939 // root(a, 0) is not defined 940 //return MakeConstant(1.0); 941 return MakeConstant(double.NaN); 942 } else if (constBValue == -1.0) { 943 // root(a, -1) => a^(-1/1) => 1/a 940 944 return MakeFraction(MakeConstant(1.0), a); 941 945 } else if (constBValue < 0) { 946 // root(a, -b) => a^(-1/b) => (1/a)^(1/b) => root(1, b) / root(a, b) => 1 / root(a, b) 942 947 var rootNode = rootSymbol.CreateTreeNode(); 943 948 rootNode.AddSubtree(a); … … 987 992 var constB = b as ConstantTreeNode; 988 993 double exponent = Math.Round(constB.Value); 989 if (exponent.IsAlmost(0.0)) { 994 if (exponent == 0.0) { 995 // a^0 => 1 990 996 return MakeConstant(1.0); 991 } else if (exponent.IsAlmost(1.0)) { 997 } else if (exponent == 1.0) { 998 // a^1 => a 992 999 return a; 993 } else if (exponent.IsAlmost(-1.0)) { 1000 } else if (exponent == -1.0) { 1001 // a^-1 => 1/a 994 1002 return MakeFraction(MakeConstant(1.0), a); 995 1003 } else if (exponent < 0) { 1004 // a^-b => (1/a)^b => 1/(a^b) 996 1005 var powNode = powSymbol.CreateTreeNode(); 997 1006 powNode.AddSubtree(a); … … 1018 1027 // fold constants 1019 1028 return MakeConstant(((ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value); 1020 } else if ((IsConstant(a) && !((ConstantTreeNode)a).Value.IsAlmost(1.0))) { 1029 } else if ((IsConstant(a) && ((ConstantTreeNode)a).Value != 1.0)) { 1030 // a / x => (a * 1/a) / (x * 1/a) => 1 / (x * 1/a) 1021 1031 return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a))); 1022 1032 } else if (IsVariableBase(a) && IsConstant(b)) { … … 1094 1104 // b is not constant => make sure constant is on the right 1095 1105 return MakeSum(b, a); 1096 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value .IsAlmost(0.0)) {1106 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) { 1097 1107 // x + 0 => x 1098 1108 return a; … … 1210 1220 foreach (var unchangedSubtree in unchangedSubtrees) 1211 1221 sum.AddSubtree(unchangedSubtree); 1212 if ( !constant.IsAlmost(0.0)) {1222 if (constant != 0.0) { 1213 1223 sum.AddSubtree(MakeConstant(constant)); 1214 1224 } … … 1268 1278 if (wi < 0) throw new ArgumentException(); 1269 1279 return MakeBinFactor(node1.Symbol, node1.VariableName, node1.VariableValue, node1.Weight * node0.Weights[wi]); 1270 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value .IsAlmost(1.0)) {1280 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 1.0) { 1271 1281 // $ * 1.0 => $ 1272 1282 return a; 1273 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value .IsAlmost(0.0)) {1283 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value == 0.0) { 1274 1284 return MakeConstant(0); 1275 1285 } else if (IsConstant(b) && IsVariableBase(a)) { … … 1419 1429 prod.AddSubtree(unchangedSubtree); 1420 1430 1421 if ( !constantProduct.IsAlmost(1.0)) {1431 if (constantProduct != 1.0) { 1422 1432 prod.AddSubtree(MakeConstant(constantProduct)); 1423 1433 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Converters/TreeToAutoDiffTermConverter.cs
r17180 r17928 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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
r17180 r17928 21 21 22 22 using System; 23 using System.Collections.Generic; 23 24 using System.Globalization; 24 25 using System.Linq; 25 26 using System.Text; 27 using HEAL.Attic; 26 28 using HeuristicLab.Common; 27 29 using HeuristicLab.Core; 28 30 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 using HEAL.Attic;30 31 31 32 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 33 public static class BaseInfixExpressionFormatter { 34 public static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, 35 NumberFormatInfo numberFormat, string formatString, List<KeyValuePair<string, double>> constants = null) { 36 if (node.SubtreeCount > 1) { 37 var token = GetToken(node.Symbol); 38 // operators 39 if (token == "+" || token == "-" || token == "OR" || token == "XOR" || 40 token == "*" || token == "/" || token == "AND") { 41 strBuilder.Append("("); 42 FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants); 43 44 foreach (var subtree in node.Subtrees.Skip(1)) { 45 strBuilder.Append(" ").Append(token).Append(" "); 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); 61 } 62 63 strBuilder.Append(")"); 64 } else { 65 // function with multiple arguments 66 strBuilder.Append(token).Append("("); 67 FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString, constants); 68 foreach (var subtree in node.Subtrees.Skip(1)) { 69 strBuilder.Append(", "); 70 FormatRecursively(subtree, strBuilder, numberFormat, formatString, constants); 71 } 72 73 strBuilder.Append(")"); 74 } 75 } else if (node.SubtreeCount == 1) { 76 var token = GetToken(node.Symbol); 77 if (token == "-" || token == "NOT") { 78 strBuilder.Append("(").Append(token).Append("("); 79 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants); 80 strBuilder.Append("))"); 81 } else if (token == "/") { 82 strBuilder.Append("1/"); 83 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants); 84 } else if (token == "+" || token == "*") { 85 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants); 86 } else { 87 // function with only one argument 88 strBuilder.Append(token).Append("("); 89 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString, constants); 90 strBuilder.Append(")"); 91 } 92 } else { 93 // no subtrees 94 if (node.Symbol is LaggedVariable) { 95 var varNode = node as LaggedVariableTreeNode; 96 if (!varNode.Weight.IsAlmost(1.0)) { 97 strBuilder.Append("("); 98 AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat); 99 strBuilder.Append("*"); 100 } 101 102 strBuilder.Append("LAG("); 103 AppendVariableName(strBuilder, varNode.VariableName); 104 strBuilder.Append(", ") 105 .AppendFormat(numberFormat, "{0}", varNode.Lag) 106 .Append(")"); 107 if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")"); 108 } else if (node.Symbol is Variable) { 109 var varNode = node as VariableTreeNode; 110 if (!varNode.Weight.IsAlmost(1.0)) { 111 strBuilder.Append("("); 112 AppendConstant(strBuilder, constants, varNode.Weight, formatString, numberFormat); 113 strBuilder.Append("*"); 114 } 115 116 AppendVariableName(strBuilder, varNode.VariableName); 117 118 if (!varNode.Weight.IsAlmost(1.0)) strBuilder.Append(")"); 119 } else if (node.Symbol is FactorVariable) { 120 var factorNode = node as FactorVariableTreeNode; 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("]"); 129 } else if (node.Symbol is BinaryFactorVariable) { 130 var factorNode = node as BinaryFactorVariableTreeNode; 131 if (!factorNode.Weight.IsAlmost(1.0)) { 132 strBuilder.Append("("); 133 AppendConstant(strBuilder, constants, factorNode.Weight, formatString, numberFormat); 134 135 strBuilder.Append("*"); 136 } 137 138 AppendVariableName(strBuilder, factorNode.VariableName); 139 strBuilder.Append(" = "); 140 AppendVariableName(strBuilder, factorNode.VariableValue); 141 142 if (!factorNode.Weight.IsAlmost(1.0)) strBuilder.Append(")"); 143 } else if (node.Symbol is Constant) { 144 var constNode = node as ConstantTreeNode; 145 if (constants == null && constNode.Value < 0) { 146 strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat)) 147 .Append(")"); // (-1 148 } else { 149 AppendConstant(strBuilder, constants, constNode.Value, formatString, numberFormat); 150 } 151 } 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); 170 } 171 172 private static string GetToken(ISymbol symbol) { 173 var tok = InfixExpressionParser.knownSymbols.GetBySecond(symbol).FirstOrDefault(); 174 if (tok == null) 175 throw new ArgumentException(string.Format("Unknown symbol {0} found.", symbol.Name)); 176 return tok; 177 } 178 } 179 32 180 /// <summary> 33 181 /// Formats mathematical expressions in infix form. E.g. x1 * (3.0 * x2 + x3) 34 182 /// </summary> 35 183 [StorableType("6FE2C83D-A594-4ABF-B101-5AEAEA6D3E3D")] 36 [Item("Infix Symbolic Expression Tree Formatter", "A string formatter that converts symbolic expression trees to infix expressions.")]37 184 [Item("Infix Symbolic Expression Tree Formatter", 185 "A string formatter that converts symbolic expression trees to infix expressions.")] 38 186 public sealed class InfixExpressionFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter { 39 40 41 187 [StorableConstructor] 42 188 private InfixExpressionFormatter(StorableConstructorFlag _) : base(_) { } 189 43 190 private InfixExpressionFormatter(InfixExpressionFormatter original, Cloner cloner) : base(original, cloner) { } 191 44 192 public InfixExpressionFormatter() 45 193 : base() { … … 47 195 Description = ItemDescription; 48 196 } 197 49 198 public override IDeepCloneable Clone(Cloner cloner) { 50 199 return new InfixExpressionFormatter(this, cloner); … … 58 207 /// <param name="formatString">The format string for numeric parameters (e.g. \"G4\" to limit to 4 digits, default is \"G\")</param> 59 208 /// <returns>Infix expression</returns> 60 public string Format(ISymbolicExpressionTree symbolicExpressionTree, NumberFormatInfo numberFormat, string formatString="G") { 209 public string Format(ISymbolicExpressionTree symbolicExpressionTree, NumberFormatInfo numberFormat, 210 string formatString = "G") { 61 211 // skip root and start symbols 62 212 StringBuilder strBuilder = new StringBuilder(); 63 FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0), strBuilder, numberFormat, formatString); 213 BaseInfixExpressionFormatter.FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0), 214 strBuilder, numberFormat, formatString); 64 215 return strBuilder.ToString(); 65 216 } … … 68 219 return Format(symbolicExpressionTree, NumberFormatInfo.InvariantInfo); 69 220 } 70 71 private static void FormatRecursively(ISymbolicExpressionTreeNode node, StringBuilder strBuilder, NumberFormatInfo numberFormat, string formatString) { 72 if (node.SubtreeCount > 1) { 73 var token = GetToken(node.Symbol); 74 // operators 75 if (token == "+" || token == "-" || token == "OR" || token == "XOR" || 76 token == "*" || token == "/" || token == "AND" || 77 token == "^") { 78 strBuilder.Append("("); 79 FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString); 80 81 foreach (var subtree in node.Subtrees.Skip(1)) { 82 strBuilder.Append(" ").Append(token).Append(" "); 83 FormatRecursively(subtree, strBuilder, numberFormat, formatString); 84 } 85 strBuilder.Append(")"); 86 } else { 87 // function with multiple arguments 88 strBuilder.Append(token).Append("("); 89 FormatRecursively(node.Subtrees.First(), strBuilder, numberFormat, formatString); 90 foreach (var subtree in node.Subtrees.Skip(1)) { 91 strBuilder.Append(", "); 92 FormatRecursively(subtree, strBuilder, numberFormat, formatString); 93 } 94 strBuilder.Append(")"); 95 } 96 } else if (node.SubtreeCount == 1) { 97 var token = GetToken(node.Symbol); 98 if (token == "-" || token == "NOT") { 99 strBuilder.Append("(").Append(token).Append("("); 100 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString); 101 strBuilder.Append("))"); 102 } else if (token == "/") { 103 strBuilder.Append("1/"); 104 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString); 105 } else if (token == "+" || token == "*") { 106 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString); 107 } else { 108 // function with only one argument 109 strBuilder.Append(token).Append("("); 110 FormatRecursively(node.GetSubtree(0), strBuilder, numberFormat, formatString); 111 strBuilder.Append(")"); 112 } 113 } else { 114 // no subtrees 115 if (node.Symbol is LaggedVariable) { 116 var varNode = node as LaggedVariableTreeNode; 117 if (!varNode.Weight.IsAlmost(1.0)) { 118 strBuilder.Append("("); 119 strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat)); 120 strBuilder.Append("*"); 121 } 122 strBuilder.Append("LAG("); 123 if (varNode.VariableName.Contains("'")) { 124 strBuilder.AppendFormat("\"{0}\"", varNode.VariableName); 125 } else { 126 strBuilder.AppendFormat("'{0}'", varNode.VariableName); 127 } 128 strBuilder.Append(", ") 129 .AppendFormat(numberFormat, "{0}", varNode.Lag) 130 .Append(")"); 131 } else if (node.Symbol is Variable) { 132 var varNode = node as VariableTreeNode; 133 if (!varNode.Weight.IsAlmost(1.0)) { 134 strBuilder.Append("("); 135 strBuilder.Append(varNode.Weight.ToString(formatString, numberFormat)); 136 strBuilder.Append("*"); 137 } 138 if (varNode.VariableName.Contains("'")) { 139 strBuilder.AppendFormat("\"{0}\"", varNode.VariableName); 140 } else { 141 strBuilder.AppendFormat("'{0}'", varNode.VariableName); 142 } 143 if (!varNode.Weight.IsAlmost(1.0)) { 144 strBuilder.Append(")"); 145 } 146 } else if (node.Symbol is FactorVariable) { 147 var factorNode = node as FactorVariableTreeNode; 148 if (factorNode.VariableName.Contains("'")) { 149 strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName); 150 } else { 151 strBuilder.AppendFormat("'{0}'", factorNode.VariableName); 152 } 153 strBuilder.AppendFormat("[{0}]", 154 string.Join(", ", factorNode.Weights.Select(w => w.ToString(formatString, numberFormat)))); 155 } else if (node.Symbol is BinaryFactorVariable) { 156 var factorNode = node as BinaryFactorVariableTreeNode; 157 if (!factorNode.Weight.IsAlmost(1.0)) { 158 strBuilder.Append("("); 159 strBuilder.Append(factorNode.Weight.ToString(formatString, numberFormat)); 160 strBuilder.Append("*"); 161 } 162 if (factorNode.VariableName.Contains("'")) { 163 strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName); 164 } else { 165 strBuilder.AppendFormat("'{0}'", factorNode.VariableName); 166 } 167 strBuilder.Append(" = "); 168 if (factorNode.VariableValue.Contains("'")) { 169 strBuilder.AppendFormat("\"{0}\"", factorNode.VariableValue); 170 } else { 171 strBuilder.AppendFormat("'{0}'", factorNode.VariableValue); 172 } 173 174 if (!factorNode.Weight.IsAlmost(1.0)) { 175 strBuilder.Append(")"); 176 } 177 178 } else if (node.Symbol is Constant) { 179 var constNode = node as ConstantTreeNode; 180 if (constNode.Value >= 0.0) 181 strBuilder.Append(constNode.Value.ToString(formatString, numberFormat)); 182 else 183 strBuilder.Append("(").Append(constNode.Value.ToString(formatString, numberFormat)).Append(")"); // (-1 184 } 221 } 222 223 [StorableType("54D917E8-134E-4066-9A60-2737C12D81DC")] 224 [Item("Infix String Formater", "Formatter for symbolic expressions, which produces an infix expression " + 225 "as well as a list of all coefficient values")] 226 public sealed class InfixExpressionStringFormatter : NamedItem, ISymbolicExpressionTreeStringFormatter { 227 [StorableConstructor] 228 private InfixExpressionStringFormatter(StorableConstructorFlag _) : base(_) { } 229 230 private InfixExpressionStringFormatter(InfixExpressionStringFormatter original, Cloner cloner) : base(original, cloner) { } 231 232 public InfixExpressionStringFormatter() : base() { 233 Name = ItemName; 234 Description = ItemDescription; 235 } 236 237 public override IDeepCloneable Clone(Cloner cloner) { 238 return new InfixExpressionStringFormatter(this, cloner); 239 } 240 241 public string Format(ISymbolicExpressionTree symbolicExpressionTree) { 242 StringBuilder strBuilder = new StringBuilder(); 243 var constants = new List<KeyValuePair<string, double>>(); 244 BaseInfixExpressionFormatter.FormatRecursively(symbolicExpressionTree.Root.GetSubtree(0).GetSubtree(0), 245 strBuilder, NumberFormatInfo.InvariantInfo, "G", constants); 246 strBuilder.Append($"{Environment.NewLine}{Environment.NewLine}"); 247 248 int maxDigits = GetDigits(constants.Count); 249 int padding = constants.Max(x => x.Value.ToString("F12", CultureInfo.InvariantCulture).Length); 250 foreach (var constant in constants) { 251 int digits = GetDigits(Int32.Parse(constant.Key.Substring(2))); 252 strBuilder.Append($"{constant.Key}{new String(' ', maxDigits - digits)} = " + 253 string.Format($"{{0,{padding}:F12}}", constant.Value, CultureInfo.InvariantCulture) + 254 Environment.NewLine); 185 255 } 186 } 187 188 private static string GetToken(ISymbol symbol) {189 var tok = InfixExpressionParser.knownSymbols.GetBySecond(symbol).FirstOrDefault(); 190 if (tok == null)191 throw new ArgumentException(string.Format("Unknown symbol {0} found.", symbol.Name));192 return tok;256 257 return strBuilder.ToString(); 258 } 259 260 private int GetDigits(int x) { 261 if (x == 0) return 1; 262 return (int)Math.Floor(Math.Log10(x) + 1); 193 263 } 194 264 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionCSharpFormatter.cs
r17180 r17928 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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/SymbolicDataAnalysisExpressionLatexFormatter.cs
r17180 r17928 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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs
r17180 r17928 21 21 22 22 using System.Collections.Generic; 23 using HEAL.Attic; 23 24 using HeuristicLab.Common; 24 25 using HeuristicLab.Core; 25 26 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 26 using HEAL.Attic;27 27 using HeuristicLab.PluginInfrastructure; 28 28 … … 31 31 [StorableType("FCBA02B7-5D29-42F5-A64C-A60AD8EA475D")] 32 32 [Item("ArithmeticExpressionGrammar", "Represents a grammar for functional expressions using only arithmetic operations.")] 33 public class ArithmeticExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {33 public class ArithmeticExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar { 34 34 35 35 [StorableConstructor] … … 56 56 var factorVariableSymbol = new FactorVariable(); 57 57 58 var allSymbols = new List<Symbol>() { add, sub, mul, div, constant, variableSymbol, binFactorVariableSymbol, factorVariableSymbol };58 var allSymbols = new List<Symbol>() { add, sub, mul, div, constant, variableSymbol, binFactorVariableSymbol, factorVariableSymbol }; 59 59 var functionSymbols = new List<Symbol>() { add, sub, mul, div }; 60 60 -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs
r17180 r17928 22 22 using System.Collections.Generic; 23 23 using System.Linq; 24 using HEAL.Attic; 24 25 using HeuristicLab.Common; 25 26 using HeuristicLab.Core; 26 27 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 27 using HEAL.Attic;28 28 29 29 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 30 30 [StorableType("44B0829C-1CB5-4BE9-9514-BBA54FAB2912")] 31 31 [Item("FullFunctionalExpressionGrammar", "Represents a grammar for functional expressions using all available functions.")] 32 public class FullFunctionalExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {32 public class FullFunctionalExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar { 33 33 [StorableConstructor] 34 34 protected FullFunctionalExpressionGrammar(StorableConstructorFlag _) : base(_) { } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs
r17180 r17928 22 22 using System.Collections.Generic; 23 23 using System.Linq; 24 using HEAL.Attic; 24 25 using HeuristicLab.Common; 25 26 using HeuristicLab.Core; 26 27 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 27 using HEAL.Attic;28 28 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 29 29 [StorableType("36A22322-0627-4E25-A468-F2A788AF6D46")] 30 30 [Item("TypeCoherentExpressionGrammar", "Represents a grammar for functional expressions in which special syntactic constraints are enforced so that boolean and real-valued expressions are not mixed.")] 31 public class TypeCoherentExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {31 public class TypeCoherentExpressionGrammar : DataAnalysisGrammar, ISymbolicDataAnalysisGrammar { 32 32 private const string ArithmeticFunctionsName = "Arithmetic Functions"; 33 33 private const string TrigonometricFunctionsName = "Trigonometric Functions"; … … 117 117 #region group symbol declaration 118 118 var arithmeticSymbols = new GroupSymbol(ArithmeticFunctionsName, new List<ISymbol>() { add, sub, mul, div, mean }); 119 var trigonometricSymbols = new GroupSymbol(TrigonometricFunctionsName, new List<ISymbol>() { sin, cos, tan, tanh });120 var exponentialAndLogarithmicSymbols = new GroupSymbol(ExponentialFunctionsName, new List<ISymbol> { exp, log });119 var trigonometricSymbols = new GroupSymbol(TrigonometricFunctionsName, new List<ISymbol>() { sin, cos, tan, tanh }); 120 var exponentialAndLogarithmicSymbols = new GroupSymbol(ExponentialFunctionsName, new List<ISymbol> { exp, log }); 121 121 var specialFunctions = new GroupSymbol(SpecialFunctionsName, new List<ISymbol> { abs, airyA, airyB, bessel, cosineIntegral, dawson, erf, expIntegralEi, 122 122 fresnelCosineIntegral,fresnelSineIntegral,gamma,hypCosineIntegral,hypSineIntegral,norm, psi, sineIntegral, analyticalQuotient}); … … 149 149 SetSubtreeCount(cubeRoot, 1, 1); 150 150 SetSubtreeCount(exponentialAndLogarithmicSymbols, 1, 1); 151 foreach (var sy in specialFunctions.Symbols.Except(new[] { analyticalQuotient})) {151 foreach (var sy in specialFunctions.Symbols.Except(new[] { analyticalQuotient })) { 152 152 SetSubtreeCount(sy, 1, 1); 153 153 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r16980 r17928 107 107 <Private>False</Private> 108 108 </Reference> 109 <Reference Include="HEAL.Attic, Version=1. 0.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">109 <Reference Include="HEAL.Attic, Version=1.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL"> 110 110 <SpecificVersion>False</SpecificVersion> 111 111 <HintPath>..\..\bin\HEAL.Attic.dll</HintPath> … … 150 150 <Compile Include="Converters\DerivativeCalculator.cs" /> 151 151 <Compile Include="Converters\TreeToAutoDiffTermConverter.cs" /> 152 <Compile Include="Creators\SymbolicDataAnalysisExpressionBalancedTreeCreator.cs" /> 152 153 <Compile Include="Crossovers\SymbolicDataAnalysisExpressionDiversityPreservingCrossover.cs" /> 153 154 <Compile Include="Formatters\InfixExpressionFormatter.cs" /> 155 <Compile Include="Formatters\SymbolicDataAnalysisExpressionPythonFormatter.cs" /> 154 156 <Compile Include="Formatters\TSQLExpressionFormatter.cs" /> 155 157 <Compile Include="Formatters\SymbolicDataAnalysisExpressionMathematicaFormatter.cs" /> 156 158 <Compile Include="Formatters\SymbolicDataAnalysisExpressionCSharpFormatter.cs" /> 159 <Compile Include="Grammars\DataAnalysisGrammar.cs" /> 160 <Compile Include="Grammars\IntervalArithmeticGrammar.cs" /> 157 161 <Compile Include="Hashing\HashExtensions.cs" /> 158 162 <Compile Include="Hashing\HashUtil.cs" /> … … 161 165 <Compile Include="Importer\SymbolicExpressionImporter.cs" /> 162 166 <Compile Include="Importer\Token.cs" /> 167 <Compile Include="Interfaces\IBoundsEstimator.cs" /> 163 168 <Compile Include="Interfaces\IModelBacktransformator.cs" /> 164 169 <Compile Include="Interfaces\IVariableTreeNode.cs" /> … … 166 171 <Compile Include="Interpreter\BatchInstruction.cs" /> 167 172 <Compile Include="Interpreter\BatchOperations.cs" /> 173 <Compile Include="Interpreter\IntervalArithBoundsEstimator.cs" /> 174 <Compile Include="Interpreter\IntervalArithCompiledExpressionBoundsEstimator.cs" /> 168 175 <Compile Include="Interpreter\IntervalInterpreter.cs" /> 169 176 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" /> 170 177 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs" /> 171 178 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs" /> 179 <Compile Include="IntervalUtil.cs" /> 172 180 <Compile Include="Selectors\DiversitySelector.cs" /> 173 181 <Compile Include="SymbolicDataAnalysisExpressionTreeAverageSimilarityCalculator.cs" /> -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
r17180 r17928 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/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisGrammar.cs
r17180 r17928 20 20 #endregion 21 21 22 using HEAL.Attic; 22 23 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 23 using HEAL.Attic;24 24 25 25 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 26 26 [StorableType("5b0720d7-b1f0-4c2f-893e-cd2549e20e9e")] 27 27 public interface ISymbolicDataAnalysisGrammar : ISymbolicExpressionGrammar { 28 void ConfigureVariableSymbols(IDataAnalysisProblemData problemData); 28 29 } 29 30 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/IntervalInterpreter.cs
r17180 r17928 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 … … 23 25 using System.Collections.Generic; 24 26 using System.Linq; 27 using HEAL.Attic; 25 28 using HeuristicLab.Common; 26 29 using HeuristicLab.Core; 27 30 using HeuristicLab.Data; 28 31 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 29 using HEAL.Attic;30 32 using HeuristicLab.Parameters; 31 33 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, IDictionary<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 IDictionary<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, IDictionary<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 case OpCodes.Power: {237 result = Evaluate(instructions, ref instructionCounter, nodeIntervals);238 for (int i = 1; i < currentInstr.nArguments; i++) {239 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);240 result = Interval.Power(result, argumentInterval);241 }242 break;243 }244 265 case OpCodes.Square: { 245 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );266 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 246 267 result = Interval.Square(argumentInterval); 247 268 break; 248 269 } 249 case OpCodes.Root: {250 result = Evaluate(instructions, ref instructionCounter, nodeIntervals);251 for (int i = 1; i < currentInstr.nArguments; i++) {252 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals);253 result = Interval.Root(result, argumentInterval);254 }255 break;256 }257 270 case OpCodes.SquareRoot: { 258 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals );271 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 259 272 result = Interval.SquareRoot(argumentInterval); 273 break; 274 } 275 case OpCodes.Cube: { 276 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 277 result = Interval.Cube(argumentInterval); 278 break; 279 } 280 case OpCodes.CubeRoot: { 281 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 282 result = Interval.CubicRoot(argumentInterval); 283 break; 284 } 285 case OpCodes.Absolute: { 286 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 287 result = Interval.Absolute(argumentInterval); 288 break; 289 } 290 case OpCodes.AnalyticQuotient: { 291 result = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 292 for (var i = 1; i < currentInstr.nArguments; i++) { 293 var argumentInterval = Evaluate(instructions, ref instructionCounter, nodeIntervals, variableIntervals); 294 result = Interval.AnalyticQuotient(result, argumentInterval); 295 } 296 260 297 break; 261 298 } … … 264 301 } 265 302 266 if ( nodeIntervals != null)303 if (!(nodeIntervals == null || nodeIntervals.ContainsKey(currentInstr.dynamicNode))) 267 304 nodeIntervals.Add(currentInstr.dynamicNode, result); 268 305 … … 270 307 } 271 308 309 272 310 public static bool IsCompatible(ISymbolicExpressionTree tree) { 273 var containsUnknownSy umbol= (311 var containsUnknownSymbols = ( 274 312 from n in tree.Root.GetSubtree(0).IterateNodesPrefix() 275 313 where 314 !(n.Symbol is Variable) && 315 !(n.Symbol is Constant) && 276 316 !(n.Symbol is StartSymbol) && 277 317 !(n.Symbol is Addition) && … … 282 322 !(n.Symbol is Cosine) && 283 323 !(n.Symbol is Tangent) && 324 !(n.Symbol is HyperbolicTangent) && 284 325 !(n.Symbol is Logarithm) && 285 326 !(n.Symbol is Exponential) && 286 !(n.Symbol is Power) &&287 327 !(n.Symbol is Square) && 288 !(n.Symbol is Root) &&289 328 !(n.Symbol is SquareRoot) && 290 !(n.Symbol is Problems.DataAnalysis.Symbolic.Variable) && 291 !(n.Symbol is Constant) 329 !(n.Symbol is Cube) && 330 !(n.Symbol is CubeRoot) && 331 !(n.Symbol is Absolute) && 332 !(n.Symbol is AnalyticQuotient) 292 333 select n).Any(); 293 return !containsUnknownSy umbol;334 return !containsUnknownSymbols; 294 335 } 295 336 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs
r17180 r17928 52 52 private static readonly MethodInfo Log = typeof(Math).GetMethod("Log", new[] { typeof(double) }); 53 53 private static readonly MethodInfo IsNaN = typeof(double).GetMethod("IsNaN"); 54 private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost" );54 private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost", new Type[] { typeof(double), typeof(double)}); 55 55 private static readonly MethodInfo Gamma = typeof(alglib).GetMethod("gammafunction", new[] { typeof(double) }); 56 56 private static readonly MethodInfo Psi = typeof(alglib).GetMethod("psi", new[] { typeof(double) }); -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeBatchInterpreter.cs
r16768 r17928 1 using System; 1 #region License Information 2 /* HeuristicLab 3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 * 5 * This file is part of HeuristicLab. 6 * 7 * HeuristicLab is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * HeuristicLab is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 #endregion 21 22 using System; 2 23 using System.Collections.Generic; 3 24 using System.Linq; … … 181 202 182 203 [ThreadStatic] 183 private Dictionary<string, double[]> cachedData;204 private static Dictionary<string, double[]> cachedData; 184 205 185 206 [ThreadStatic] 186 private IDataset dataset;207 private static IDataset cachedDataset; 187 208 188 209 private void InitCache(IDataset dataset) { 189 this.dataset = dataset;210 cachedDataset = dataset; 190 211 cachedData = new Dictionary<string, double[]>(); 191 212 foreach (var v in dataset.DoubleVariables) { … … 196 217 public void InitializeState() { 197 218 cachedData = null; 198 dataset = null;219 cachedDataset = null; 199 220 EvaluatedSolutions = 0; 200 221 } 201 222 202 223 private double[] GetValues(ISymbolicExpressionTree tree, IDataset dataset, int[] rows) { 203 if (cachedData == null || this.dataset != dataset) {224 if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) { 204 225 InitCache(dataset); 205 226 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeNativeInterpreter.cs
r17180 r17928 99 99 100 100 [ThreadStatic] 101 private IDataset dataset;101 private static IDataset cachedDataset; 102 102 103 103 private static readonly HashSet<byte> supportedOpCodes = new HashSet<byte>() { … … 127 127 if (!rows.Any()) return Enumerable.Empty<double>(); 128 128 129 if (cachedData == null || this.dataset != dataset) {129 if (cachedData == null || cachedDataset != dataset || cachedDataset is ModifiableDataset) { 130 130 InitCache(dataset); 131 131 } … … 152 152 153 153 private void InitCache(IDataset dataset) { 154 this.dataset = dataset;154 cachedDataset = dataset; 155 155 156 156 // free handles to old data … … 178 178 cachedData = null; 179 179 } 180 dataset = null;180 cachedDataset = null; 181 181 EvaluatedSolutions = 0; 182 182 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisMultiObjectiveProblem.cs
r17180 r17928 21 21 22 22 using System.Linq; 23 using HEAL.Attic; 23 24 using HeuristicLab.Common; 24 25 using HeuristicLab.Core; 25 26 using HeuristicLab.Data; 27 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 26 28 using HeuristicLab.Optimization; 27 29 using HeuristicLab.Parameters; 28 using HEAL.Attic;29 30 30 31 namespace HeuristicLab.Problems.DataAnalysis.Symbolic { 31 32 [StorableType("E9876DF8-ACFA-41C8-93B7-FA40C57CE459")] 32 33 public abstract class SymbolicDataAnalysisMultiObjectiveProblem<T, U, V> : SymbolicDataAnalysisProblem<T, U, V>, ISymbolicDataAnalysisMultiObjectiveProblem 33 where T : class, IDataAnalysisProblemData34 where T : class, IDataAnalysisProblemData 34 35 where U : class, ISymbolicDataAnalysisMultiObjectiveEvaluator<T> 35 36 where V : class, ISymbolicDataAnalysisSolutionCreator { … … 97 98 op.MaximizationParameter.ActualName = MaximizationParameterName; 98 99 } 100 101 // these two crossover operators are compatible with single-objective problems only so we remove them from the operators collection 102 bool pred(IItem x) { 103 return x is SymbolicDataAnalysisExpressionDeterministicBestCrossover<T> || x is SymbolicDataAnalysisExpressionContextAwareCrossover<T>; 104 }; 105 Operators.RemoveAll(pred); 106 // if a multi crossover is present, remove them from its operator collection 107 var cx = Operators.FirstOrDefault(x => x is MultiSymbolicDataAnalysisExpressionCrossover<T>); 108 if (cx != null) { 109 var multiCrossover = (MultiSymbolicDataAnalysisExpressionCrossover<T>)cx; 110 var items = multiCrossover.Operators.Where(pred).Cast<ISymbolicExpressionTreeCrossover>().ToList(); 111 foreach (var item in items) { 112 multiCrossover.Operators.Remove(item); 113 } 114 } 99 115 } 100 116 } -
branches/3026_IntegrationIntoSymSpace/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisProblem.cs
r17180 r17928 24 24 using System.Drawing; 25 25 using System.Linq; 26 using HEAL.Attic; 26 27 using HeuristicLab.Common; 27 28 using HeuristicLab.Common.Resources; … … 31 32 using HeuristicLab.Optimization; 32 33 using HeuristicLab.Parameters; 33 using HEAL.Attic;34 34 using HeuristicLab.PluginInfrastructure; 35 35 using HeuristicLab.Problems.Instances; … … 210 210 protected virtual void UpdateGrammar() { 211 211 var problemData = ProblemData; 212 var ds = problemData.Dataset;213 212 var grammar = SymbolicExpressionTreeGrammar; 213 214 214 grammar.MaximumFunctionArguments = MaximumFunctionArguments.Value; 215 215 grammar.MaximumFunctionDefinitions = MaximumFunctionDefinitions.Value; 216 foreach (var varSymbol in grammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.VariableBase>()) { 217 if (!varSymbol.Fixed) { 218 varSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => ds.VariableHasType<double>(x)); 219 varSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => ds.VariableHasType<double>(x)); 220 } 221 } 222 foreach (var factorSymbol in grammar.Symbols.OfType<BinaryFactorVariable>()) { 223 if (!factorSymbol.Fixed) { 224 factorSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => ds.VariableHasType<string>(x)); 225 factorSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => ds.VariableHasType<string>(x)); 226 factorSymbol.VariableValues = factorSymbol.VariableNames 227 .ToDictionary(varName => varName, varName => ds.GetStringValues(varName).Distinct().ToList()); 228 } 229 } 230 foreach (var factorSymbol in grammar.Symbols.OfType<FactorVariable>()) { 231 if (!factorSymbol.Fixed) { 232 factorSymbol.AllVariableNames = problemData.InputVariables.Select(x => x.Value).Where(x => ds.VariableHasType<string>(x)); 233 factorSymbol.VariableNames = problemData.AllowedInputVariables.Where(x => ds.VariableHasType<string>(x)); 234 factorSymbol.VariableValues = factorSymbol.VariableNames 235 .ToDictionary(varName => varName, 236 varName => ds.GetStringValues(varName).Distinct() 237 .Select((n, i) => Tuple.Create(n, i)) 238 .ToDictionary(tup => tup.Item1, tup => tup.Item2)); 239 } 240 } 216 217 grammar.ConfigureVariableSymbols(problemData); 241 218 } 242 219
Note: See TracChangeset
for help on using the changeset viewer.