Changeset 14251
- Timestamp:
- 08/10/16 20:10:25 (8 years ago)
- Location:
- branches/symbreg-factors-2650
- Files:
-
- 1 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/symbreg-factors-2650/HeuristicLab.Algorithms.DataAnalysis/3.4/NonlinearRegression/NonlinearRegression.cs
r14109 r14251 27 27 using HeuristicLab.Data; 28 28 using HeuristicLab.Parameters; 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;30 29 using HeuristicLab.Optimization; 31 30 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; … … 93 92 var parser = new InfixExpressionParser(); 94 93 var tree = parser.Parse(modelStructure); 95 var simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier(); 96 94 // parser handles double and string variables equally by creating a VariableTreeNode 95 // post-process to replace VariableTreeNodes by FactorVariableTreeNodes for all string variables 96 var factorSymbol = new FactorVariable(); 97 factorSymbol.VariableNames = 98 problemData.AllowedInputVariables.Where(name => problemData.Dataset.VariableHasType<string>(name)); 99 factorSymbol.AllVariableNames = factorSymbol.VariableNames; 100 factorSymbol.VariableValues = 101 factorSymbol.VariableNames.Select(name => new KeyValuePair<string, List<string>>(name, problemData.Dataset.GetReadOnlyStringValues(name).Distinct().ToList())); 102 103 foreach (var parent in tree.IterateNodesPrefix().ToArray()) { 104 for (int i = 0; i < parent.SubtreeCount; i++) { 105 var child = parent.GetSubtree(i) as VariableTreeNode; 106 if (child != null && factorSymbol.VariableNames.Contains(child.VariableName)) { 107 parent.RemoveSubtree(i); 108 var factorTreeNode = (FactorVariableTreeNode)factorSymbol.CreateTreeNode(); 109 factorTreeNode.VariableName = child.VariableName; 110 factorTreeNode.Weights = 111 factorTreeNode.Symbol.GetVariableValues(factorTreeNode.VariableName).Select(_ => 1.0).ToArray(); // weight = 1.0 for each value 112 parent.InsertSubtree(i, factorTreeNode); 113 } 114 } 115 } 116 97 117 if (!SymbolicRegressionConstantOptimizationEvaluator.CanOptimizeConstants(tree)) throw new ArgumentException("The optimizer does not support the specified model structure."); 98 118 99 119 var interpreter = new SymbolicDataAnalysisExpressionTreeLinearInterpreter(); 100 SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, problemData.TrainingIndices, 120 SymbolicRegressionConstantOptimizationEvaluator.OptimizeConstants(interpreter, tree, problemData, problemData.TrainingIndices, 101 121 applyLinearScaling: false, maxIterations: maxIterations, 102 122 updateVariableWeights: false, updateConstantsInTree: true); -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/SolutionComparisonView.cs
r14249 r14251 21 21 22 22 using System; 23 using System.Collections; 23 24 using System.Collections.Generic; 24 25 using System.Linq; … … 53 54 if (!problemData.TrainingIndices.Any()) return null; // don't create an comparison models if the problem does not have a training set (e.g. loaded into an existing model) 54 55 55 var usedDoubleVariables = 56 symbolicSolution.Model.SymbolicExpressionTree.IterateNodesPostfix() 57 .OfType<VariableTreeNode>() 58 .Select(node => node.VariableName) 59 .Concat( 60 symbolicSolution.Model.SymbolicExpressionTree.IterateNodesPostfix() 61 .OfType<VariableConditionTreeNode>() 62 .Select(node => node.VariableName) 63 ) 56 var usedVariables = Content.Model.SymbolicExpressionTree.IterateNodesPostfix() 57 .OfType<IVariableTreeNode>() 58 .Select(node => node.VariableName).ToArray(); 59 60 var usedDoubleVariables = usedVariables 61 .Where(name => problemData.Dataset.VariableHasType<double>(name)) 64 62 .Distinct(); 65 63 66 var usedFactorVariables = 67 symbolicSolution.Model.SymbolicExpressionTree.IterateNodesPostfix() 68 .OfType<BinaryFactorVariableTreeNode>() 69 .Select(node => Tuple.Create(node.VariableName, node.VariableValue)) 64 var usedFactorVariables = usedVariables 65 .Where(name => problemData.Dataset.VariableHasType<string>(name)) 70 66 .Distinct(); 67 68 // gkronber: for binary factors we actually produce a binary variable in the new dataset 69 // but only if the variable is not used as a full factor anyway (LR creates binary columns anyway) 70 var usedBinaryFactors = 71 Content.Model.SymbolicExpressionTree.IterateNodesPostfix().OfType<BinaryFactorVariableTreeNode>() 72 .Where(node => !usedFactorVariables.Contains(node.VariableName)) 73 .Select(node => Tuple.Create(node.VariableValue, node.VariableValue)); 71 74 72 75 // create a new problem and dataset 73 76 var variableNames = 74 77 usedDoubleVariables 75 .Concat(usedFactorVariables.Select(t => t.Item1 + "=" + t.Item2)) 78 .Concat(usedFactorVariables) 79 .Concat(usedBinaryFactors.Select(t => t.Item1 + "=" + t.Item2)) 76 80 .Concat(new string[] { problemData.TargetVariable }) 77 81 .ToArray(); 78 82 var variableValues = 79 usedDoubleVariables.Select(name => problemData.Dataset.GetDoubleValues(name).ToList()) 83 usedDoubleVariables.Select(name => (IList)problemData.Dataset.GetDoubleValues(name).ToList()) 84 .Concat(usedFactorVariables.Select(name => problemData.Dataset.GetStringValues(name).ToList())) 80 85 .Concat( 81 // create binary variable82 used FactorVariables.Select(t => problemData.Dataset.GetReadOnlyStringValues(t.Item1).Select(val => val == t.Item2 ? 1.0 : 0.0).ToList())86 // create binary variable 87 usedBinaryFactors.Select(t => problemData.Dataset.GetReadOnlyStringValues(t.Item1).Select(val => val == t.Item2 ? 1.0 : 0.0).ToList()) 83 88 ) 84 89 .Concat(new[] { problemData.Dataset.GetDoubleValues(problemData.TargetVariable).ToList() }); -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/SymbolicRegressionSolutionErrorCharacteristicsCurveView.cs
r14249 r14251 21 21 22 22 using System; 23 using System.Collections; 23 24 using System.Collections.Generic; 24 25 using System.Diagnostics.Contracts; … … 47 48 if (!problemData.TrainingIndices.Any()) return null; // don't create an LR model if the problem does not have a training set (e.g. loaded into an existing model) 48 49 49 var usedDoubleVariables = 50 Content.Model.SymbolicExpressionTree.IterateNodesPostfix() 51 .OfType<VariableTreeNode>() 52 .Select(node => node.VariableName) 53 .Concat( 54 Content.Model.SymbolicExpressionTree.IterateNodesPostfix() 55 .OfType<VariableConditionTreeNode>() 56 .Select(node => node.VariableName) 57 ) 50 var usedVariables = Content.Model.SymbolicExpressionTree.IterateNodesPostfix() 51 .OfType<IVariableTreeNode>() 52 .Select(node => node.VariableName).ToArray(); 53 54 var usedDoubleVariables = usedVariables 55 .Where(name => problemData.Dataset.VariableHasType<double>(name)) 58 56 .Distinct(); 59 57 60 var usedFactorVariables = 61 Content.Model.SymbolicExpressionTree.IterateNodesPostfix() 62 .OfType<BinaryFactorVariableTreeNode>() 63 .Select(node => Tuple.Create(node.VariableName, node.VariableValue)) 58 var usedFactorVariables = usedVariables 59 .Where(name => problemData.Dataset.VariableHasType<string>(name)) 64 60 .Distinct(); 61 62 // gkronber: for binary factors we actually produce a binary variable in the new dataset 63 // but only if the variable is not used as a full factor anyway (LR creates binary columns anyway) 64 var usedBinaryFactors = 65 Content.Model.SymbolicExpressionTree.IterateNodesPostfix().OfType<BinaryFactorVariableTreeNode>() 66 .Where(node => !usedFactorVariables.Contains(node.VariableName)) 67 .Select(node => Tuple.Create(node.VariableValue, node.VariableValue)); 65 68 66 69 // create a new problem and dataset 67 70 var variableNames = 68 71 usedDoubleVariables 69 .Concat(usedFactorVariables.Select(t => t.Item1 + "=" + t.Item2)) 72 .Concat(usedFactorVariables) 73 .Concat(usedBinaryFactors.Select(t => t.Item1 + "=" + t.Item2)) 70 74 .Concat(new string[] { problemData.TargetVariable }) 71 75 .ToArray(); 72 76 var variableValues = 73 usedDoubleVariables.Select(name => problemData.Dataset.GetDoubleValues(name).ToList()) 77 usedDoubleVariables.Select(name => (IList)problemData.Dataset.GetDoubleValues(name).ToList()) 78 .Concat(usedFactorVariables.Select(name => problemData.Dataset.GetStringValues(name).ToList())) 74 79 .Concat( 75 // create binary variable76 used FactorVariables.Select(t => problemData.Dataset.GetReadOnlyStringValues(t.Item1).Select(val => val == t.Item2 ? 1.0 : 0.0).ToList())80 // create binary variable 81 usedBinaryFactors.Select(t => problemData.Dataset.GetReadOnlyStringValues(t.Item1).Select(val => val == t.Item2 ? 1.0 : 0.0).ToList()) 77 82 ) 78 83 .Concat(new[] { problemData.Dataset.GetDoubleValues(problemData.TargetVariable).ToList() }); -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs
r14249 r14251 194 194 terminalNodes = tree.Root.IterateNodesPrefix().OfType<SymbolicExpressionTreeTerminalNode>().ToList(); 195 195 else 196 terminalNodes = new List<SymbolicExpressionTreeTerminalNode>(tree.Root.IterateNodesPrefix().OfType<ConstantTreeNode>()); 196 terminalNodes = new List<SymbolicExpressionTreeTerminalNode> 197 (tree.Root.IterateNodesPrefix() 198 .OfType<SymbolicExpressionTreeTerminalNode>() 199 .Where(node => node is ConstantTreeNode || node is FactorVariableTreeNode)); 197 200 198 201 //extract inital constants … … 214 217 c[i++] = binFactorVarTreeNode.Weight; 215 218 else if (factorVarTreeNode != null) { 219 // gkronber: a factorVariableTreeNode holds a category-specific constant therefore we can consider factors to be the same as constants 216 220 foreach (var w in factorVarTreeNode.Weights) c[i++] = w; 217 221 } … … 252 256 alglib.lsfitfit(state, function_cx_1_func, function_cx_1_grad, null, null); 253 257 alglib.lsfitresults(state, out info, out c, out rep); 254 } catch (ArithmeticException) { 258 } 259 catch (ArithmeticException) { 255 260 return originalQuality; 256 } catch (alglib.alglibexception) { 261 } 262 catch (alglib.alglibexception) { 257 263 return originalQuality; 258 264 } … … 284 290 binFactorVarTreeNode.Weight = constants[i++]; 285 291 else if (factorVarTreeNode != null) { 286 foreach (var w in factorVarTreeNode.Weights) constants[i++] = w; 292 for (int j = 0; j < factorVarTreeNode.Weights.Length; j++) 293 factorVarTreeNode.Weights[j] = constants[i++]; 287 294 } 288 295 } -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableView.cs
r14243 r14251 29 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views; 30 30 using HeuristicLab.MainForm; 31 using HeuristicLab.MainForm.WindowsForms;32 31 33 32 34 33 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views { 35 34 [View("Variable View")] 36 [Content(typeof(Variable), true)] 37 [Content(typeof(BinaryFactorVariable), true)] 35 [Content(typeof(VariableBase), true)] 38 36 public partial class VariableView : SymbolView { 39 37 private CheckedItemCollectionView<StringValue> variableNamesView; -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Formatters/InfixExpressionFormatter.cs
r14026 r14251 116 116 strBuilder.Append(")"); 117 117 } 118 } else if (node.Symbol is FactorVariable) { 119 var factorNode = node as FactorVariableTreeNode; 120 if (factorNode.VariableName.Contains("'")) { 121 strBuilder.AppendFormat("\"{0}\"", factorNode.VariableName); 122 } else { 123 strBuilder.AppendFormat("'{0}'", factorNode.VariableName); 124 } 125 } else if (node.Symbol is BinaryFactorVariable) { 126 var factorNode = node as BinaryFactorVariableTreeNode; 127 if (!factorNode.Weight.IsAlmost(1.0)) { 128 strBuilder.Append("("); 129 strBuilder.AppendFormat(CultureInfo.InvariantCulture, "{0}", factorNode.Weight); 130 strBuilder.Append("*"); 131 } 132 if (factorNode.VariableName.Contains("'")) { 133 strBuilder.AppendFormat("\"{0}={1}\"", factorNode.VariableName, factorNode.VariableValue); 134 } else { 135 strBuilder.AppendFormat("'{0}={1}'", factorNode.VariableName, factorNode.VariableValue); 136 } 137 if (!factorNode.Weight.IsAlmost(1.0)) { 138 strBuilder.Append(")"); 139 } 140 118 141 } else if (node.Symbol is Constant) { 119 142 var constNode = node as ConstantTreeNode; -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
r14249 r14251 140 140 <Compile Include="Importer\Token.cs" /> 141 141 <Compile Include="Interfaces\IModelBacktransformator.cs" /> 142 <Compile Include="Interfaces\IVariableTreeNode.cs" /> 142 143 <Compile Include="Interfaces\IVariableSymbol.cs" /> 143 144 <Compile Include="Interpreter\SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs" /> -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/InfixExpressionParser.cs
r14026 r14251 32 32 /// Parses mathematical expressions in infix form. E.g. x1 * (3.0 * x2 + x3) 33 33 /// Identifier format (functions or variables): '_' | letter { '_' | letter | digit } 34 /// Variables names can be set under quotes "" or '' because variable names might contain spaces. 34 /// Variables names and variable values can be set under quotes "" or '' because variable names might contain spaces. 35 /// Variable = ident | " ident " | ' ident ' 35 36 /// It is also possible to use functions e.g. log("x1") or real-valued constants e.g. 3.1415 . 36 37 /// Variable names are case sensitive. Function names are not case sensitive. 38 /// 39 /// 40 /// S = Expr EOF 41 /// Expr = ['-' | '+'] Term { '+' Term | '-' Term } 42 /// Term = Fact { '*' Fact | '/' Fact } 43 /// Fact = '(' Expr ')' | funcId '(' Expr ')' | VarExpr | number 44 /// VarExpr = varId [ '=' varVal] 45 /// varId = ident | ' ident ' | " ident " 46 /// varVal = ident | ' ident ' | " ident " 47 /// ident = '_' | letter { '_' | letter | digit } 37 48 /// </summary> 38 49 public sealed class InfixExpressionParser { 39 private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, E nd, NA };50 private enum TokenType { Operator, Identifier, Number, LeftPar, RightPar, Eq, End, NA }; 40 51 private class Token { 41 52 internal double doubleVal; … … 64 75 private Constant constant = new Constant(); 65 76 private Variable variable = new Variable(); 77 private BinaryFactorVariable binaryFactorVar = new BinaryFactorVariable(); 66 78 67 79 private ProgramRootSymbol programRootSymbol = new ProgramRootSymbol(); … … 143 155 pos++; 144 156 while (pos < str.Length && !char.IsWhiteSpace(str[pos]) 145 && (str[pos] != '+' || str[pos -1] == 'e' || str[pos-1] == 'E') // continue reading exponents157 && (str[pos] != '+' || str[pos - 1] == 'e' || str[pos - 1] == 'E') // continue reading exponents 146 158 && (str[pos] != '-' || str[pos - 1] == 'e' || str[pos - 1] == 'E') 147 && str[pos] != '*' 159 && str[pos] != '*' 148 160 && str[pos] != '/' 149 161 && str[pos] != ')') { … … 211 223 pos++; 212 224 yield return new Token { TokenType = TokenType.RightPar, strVal = ")" }; 213 } 214 } 215 } 216 217 // S = Expr EOF 218 // Expr = ['-' | '+'] Term { '+' Term | '-' Term } 219 // Term = Fact { '*' Fact | '/' Fact } 220 // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number 225 } else if (str[pos] == '=') { 226 pos++; 227 yield return new Token { TokenType = TokenType.Eq, strVal = "=" }; 228 } 229 } 230 } 231 221 232 private ISymbolicExpressionTreeNode ParseS(Queue<Token> tokens) { 222 233 var expr = ParseExpr(tokens); … … 326 337 } 327 338 328 // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId | number339 // Fact = '(' Expr ')' | funcId '(' Expr ')' | varId [ = valId ] | number 329 340 private ISymbolicExpressionTreeNode ParseFact(Queue<Token> tokens) { 330 341 var next = tokens.Peek(); … … 355 366 } else { 356 367 // variable 357 var varNode = (VariableTreeNode)variable.CreateTreeNode(); 358 varNode.Weight = 1.0; 359 varNode.VariableName = idTok.strVal; 360 return varNode; 368 if (tokens.Peek().TokenType == TokenType.Eq) { 369 // binary factor 370 tokens.Dequeue(); // skip Eq 371 var valTok = tokens.Dequeue(); 372 if (valTok.TokenType != TokenType.Identifier) throw new ArgumentException("expected identifier"); 373 var binFactorNode = (BinaryFactorVariableTreeNode)binaryFactorVar.CreateTreeNode(); 374 binFactorNode.Weight = 1.0; 375 binFactorNode.VariableName = idTok.strVal; 376 binFactorNode.VariableValue = valTok.strVal; 377 return binFactorNode; 378 } else { 379 // variable 380 var varNode = (VariableTreeNode)variable.CreateTreeNode(); 381 varNode.Weight = 1.0; 382 varNode.VariableName = idTok.strVal; 383 return varNode; 384 } 361 385 } 362 386 } else if (next.TokenType == TokenType.Number) { … … 369 393 } 370 394 } 395 371 396 } 372 397 } -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/IVariableSymbol.cs
r14238 r14251 24 24 25 25 /// <summary> 26 /// Any symbol that references a variable 26 /// Any symbol that references a variable (includes terminal as well as non-terminal symbols) 27 27 /// </summary> 28 28 public interface IVariableSymbol : ISymbol { 29 29 } 30 31 /// <summary>32 /// Any tree node that references a variable33 /// </summary>34 public interface IVariableTreeNode : ISymbolicExpressionTreeNode {35 string VariableName { get; }36 }37 30 } -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
r14249 r14251 145 145 instr.data = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName); 146 146 } else if (instr.opCode == OpCodes.FactorVariable) { 147 var factorTreeNode = instr.dynamicNode as FactorVariableTreeNode; 148 instr.data = dataset.GetReadOnlyStringValues(factorTreeNode.VariableName); 149 } else if (instr.opCode == OpCodes.BinaryFactorVariable) { 147 150 var factorTreeNode = instr.dynamicNode as BinaryFactorVariableTreeNode; 148 151 instr.data = dataset.GetReadOnlyStringValues(factorTreeNode.VariableName); -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeSimplifier.cs
r14249 r14251 1 1 #region License Information 2 2 3 /* HeuristicLab 3 4 * Copyright (C) 2002-2016 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 … … 24 26 using System.Linq; 25 27 using HeuristicLab.Common; 28 using HeuristicLab.Core; 26 29 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 27 30 … … 66 69 67 70 // the argumentTrees list contains already expanded trees used as arguments for invocations 68 private ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node, IList<ISymbolicExpressionTreeNode> argumentTrees) { 71 private ISymbolicExpressionTreeNode MacroExpand(ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode node, 72 IList<ISymbolicExpressionTreeNode> argumentTrees) { 69 73 List<ISymbolicExpressionTreeNode> subtrees = new List<ISymbolicExpressionTreeNode>(node.Subtrees); 70 74 while (node.SubtreeCount > 0) node.RemoveSubtree(0); … … 98 102 } 99 103 100 101 104 #region symbol predicates 105 102 106 // arithmetic 103 107 private bool IsDivision(ISymbolicExpressionTreeNode node) { … … 120 124 return node.Symbol is Average; 121 125 } 126 122 127 // exponential 123 128 private bool IsLog(ISymbolicExpressionTreeNode node) { 124 129 return node.Symbol is Logarithm; 125 130 } 131 126 132 private bool IsExp(ISymbolicExpressionTreeNode node) { 127 133 return node.Symbol is Exponential; 128 134 } 135 129 136 private bool IsRoot(ISymbolicExpressionTreeNode node) { 130 137 return node.Symbol is Root; 131 138 } 139 132 140 private bool IsSquare(ISymbolicExpressionTreeNode node) { 133 141 return node.Symbol is Square; 134 142 } 143 135 144 private bool IsSquareRoot(ISymbolicExpressionTreeNode node) { 136 145 return node.Symbol is SquareRoot; 137 146 } 147 138 148 private bool IsPower(ISymbolicExpressionTreeNode node) { 139 149 return node.Symbol is Power; 140 150 } 151 141 152 // trigonometric 142 153 private bool IsSine(ISymbolicExpressionTreeNode node) { 143 154 return node.Symbol is Sine; 144 155 } 156 145 157 private bool IsCosine(ISymbolicExpressionTreeNode node) { 146 158 return node.Symbol is Cosine; 147 159 } 160 148 161 private bool IsTangent(ISymbolicExpressionTreeNode node) { 149 162 return node.Symbol is Tangent; 150 163 } 164 151 165 // boolean 152 166 private bool IsIfThenElse(ISymbolicExpressionTreeNode node) { 153 167 return node.Symbol is IfThenElse; 154 168 } 169 155 170 private bool IsAnd(ISymbolicExpressionTreeNode node) { 156 171 return node.Symbol is And; 157 172 } 173 158 174 private bool IsOr(ISymbolicExpressionTreeNode node) { 159 175 return node.Symbol is Or; 160 176 } 177 161 178 private bool IsNot(ISymbolicExpressionTreeNode node) { 162 179 return node.Symbol is Not; 163 180 } 181 164 182 // comparison 165 183 private bool IsGreaterThan(ISymbolicExpressionTreeNode node) { 166 184 return node.Symbol is GreaterThan; 167 185 } 186 168 187 private bool IsLessThan(ISymbolicExpressionTreeNode node) { 169 188 return node.Symbol is LessThan; … … 182 201 return node.Symbol is Variable; 183 202 } 203 184 204 private bool IsVariableBase(ISymbolicExpressionTreeNode node) { 185 205 return node is VariableTreeNodeBase; 186 206 } 207 208 private bool IsFactor(ISymbolicExpressionTreeNode node) { 209 return node is FactorVariableTreeNode; 210 } 211 187 212 private bool IsConstant(ISymbolicExpressionTreeNode node) { 188 213 return node.Symbol is Constant; … … 193 218 return node.Symbol is TimeLag; 194 219 } 220 195 221 private bool IsIntegral(ISymbolicExpressionTreeNode node) { 196 222 return node.Symbol is Integral; … … 256 282 } 257 283 258 259 284 #region specific simplification routines 285 260 286 private ISymbolicExpressionTreeNode SimplifyAny(ISymbolicExpressionTreeNode original) { 261 287 // can't simplify this function but simplify all subtrees … … 305 331 var remaining = original.Subtrees.Skip(2); 306 332 return 307 MakeProduct(GetSimplifiedTree(first), Invert(remaining.Aggregate(GetSimplifiedTree(second), (a, b) => MakeProduct(a, GetSimplifiedTree(b))))); 333 MakeProduct(GetSimplifiedTree(first), 334 Invert(remaining.Aggregate(GetSimplifiedTree(second), (a, b) => MakeProduct(a, GetSimplifiedTree(b))))); 308 335 } 309 336 } … … 346 373 return MakeNot(GetSimplifiedTree(original.GetSubtree(0))); 347 374 } 375 348 376 private ISymbolicExpressionTreeNode SimplifyOr(ISymbolicExpressionTreeNode original) { 349 377 return original.Subtrees … … 351 379 .Aggregate(MakeOr); 352 380 } 381 353 382 private ISymbolicExpressionTreeNode SimplifyAnd(ISymbolicExpressionTreeNode original) { 354 383 return original.Subtrees … … 356 385 .Aggregate(MakeAnd); 357 386 } 387 358 388 private ISymbolicExpressionTreeNode SimplifyLessThan(ISymbolicExpressionTreeNode original) { 359 389 return MakeLessThan(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 360 390 } 391 361 392 private ISymbolicExpressionTreeNode SimplifyGreaterThan(ISymbolicExpressionTreeNode original) { 362 393 return MakeGreaterThan(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 363 394 } 395 364 396 private ISymbolicExpressionTreeNode SimplifyIfThenElse(ISymbolicExpressionTreeNode original) { 365 return MakeIfThenElse(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)), GetSimplifiedTree(original.GetSubtree(2))); 366 } 397 return MakeIfThenElse(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1)), 398 GetSimplifiedTree(original.GetSubtree(2))); 399 } 400 367 401 private ISymbolicExpressionTreeNode SimplifyTangent(ISymbolicExpressionTreeNode original) { 368 402 return MakeTangent(GetSimplifiedTree(original.GetSubtree(0))); 369 403 } 404 370 405 private ISymbolicExpressionTreeNode SimplifyCosine(ISymbolicExpressionTreeNode original) { 371 406 return MakeCosine(GetSimplifiedTree(original.GetSubtree(0))); 372 407 } 408 373 409 private ISymbolicExpressionTreeNode SimplifySine(ISymbolicExpressionTreeNode original) { 374 410 return MakeSine(GetSimplifiedTree(original.GetSubtree(0))); 375 411 } 412 376 413 private ISymbolicExpressionTreeNode SimplifyExp(ISymbolicExpressionTreeNode original) { 377 414 return MakeExp(GetSimplifiedTree(original.GetSubtree(0))); 378 415 } 416 379 417 private ISymbolicExpressionTreeNode SimplifySquare(ISymbolicExpressionTreeNode original) { 380 418 return MakeSquare(GetSimplifiedTree(original.GetSubtree(0))); 381 419 } 420 382 421 private ISymbolicExpressionTreeNode SimplifySquareRoot(ISymbolicExpressionTreeNode original) { 383 422 return MakeSquareRoot(GetSimplifiedTree(original.GetSubtree(0))); … … 387 426 return MakeLog(GetSimplifiedTree(original.GetSubtree(0))); 388 427 } 428 389 429 private ISymbolicExpressionTreeNode SimplifyRoot(ISymbolicExpressionTreeNode original) { 390 430 return MakeRoot(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); … … 394 434 return MakePower(GetSimplifiedTree(original.GetSubtree(0)), GetSimplifiedTree(original.GetSubtree(1))); 395 435 } 436 396 437 private ISymbolicExpressionTreeNode SimplifyTimeLag(ISymbolicExpressionTreeNode original) { 397 438 var laggedTreeNode = original as ILaggedTreeNode; … … 403 444 } 404 445 } 446 405 447 private ISymbolicExpressionTreeNode SimplifyIntegral(ISymbolicExpressionTreeNode original) { 406 448 var laggedTreeNode = original as ILaggedTreeNode; … … 416 458 417 459 #region low level tree restructuring 460 418 461 private ISymbolicExpressionTreeNode MakeTimeLag(ISymbolicExpressionTreeNode subtree, int lag) { 419 462 if (lag == 0) return subtree; … … 446 489 } else if (!IsBoolean(t)) { 447 490 var gtNode = gtSymbol.CreateTreeNode(); 448 gtNode.AddSubtree(t); gtNode.AddSubtree(MakeConstant(0.0)); 491 gtNode.AddSubtree(t); 492 gtNode.AddSubtree(MakeConstant(0.0)); 449 493 var notNode = notSymbol.CreateTreeNode(); 450 494 notNode.AddSubtree(gtNode); … … 486 530 } 487 531 } 532 488 533 private ISymbolicExpressionTreeNode MakeAnd(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 489 534 if (IsConstant(a) && IsConstant(b)) { … … 515 560 } 516 561 } 517 private ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide, ISymbolicExpressionTreeNode rightSide) { 562 563 private ISymbolicExpressionTreeNode MakeLessThan(ISymbolicExpressionTreeNode leftSide, 564 ISymbolicExpressionTreeNode rightSide) { 518 565 if (IsConstant(leftSide) && IsConstant(rightSide)) { 519 566 var lsConst = leftSide as ConstantTreeNode; … … 528 575 } 529 576 } 530 private ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide, ISymbolicExpressionTreeNode rightSide) { 577 578 private ISymbolicExpressionTreeNode MakeGreaterThan(ISymbolicExpressionTreeNode leftSide, 579 ISymbolicExpressionTreeNode rightSide) { 531 580 if (IsConstant(leftSide) && IsConstant(rightSide)) { 532 581 var lsConst = leftSide as ConstantTreeNode; … … 541 590 } 542 591 } 543 private ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition, ISymbolicExpressionTreeNode trueBranch, ISymbolicExpressionTreeNode falseBranch) { 592 593 private ISymbolicExpressionTreeNode MakeIfThenElse(ISymbolicExpressionTreeNode condition, 594 ISymbolicExpressionTreeNode trueBranch, ISymbolicExpressionTreeNode falseBranch) { 544 595 if (IsConstant(condition)) { 545 596 var constT = condition as ConstantTreeNode; … … 552 603 } else { 553 604 var gtNode = gtSymbol.CreateTreeNode(); 554 gtNode.AddSubtree(condition); gtNode.AddSubtree(MakeConstant(0.0)); 605 gtNode.AddSubtree(condition); 606 gtNode.AddSubtree(MakeConstant(0.0)); 555 607 ifNode.AddSubtree(gtNode); 556 608 } … … 571 623 } 572 624 } 625 573 626 private ISymbolicExpressionTreeNode MakeTangent(ISymbolicExpressionTreeNode node) { 574 627 if (IsConstant(node)) { … … 581 634 } 582 635 } 636 583 637 private ISymbolicExpressionTreeNode MakeCosine(ISymbolicExpressionTreeNode node) { 584 638 if (IsConstant(node)) { … … 591 645 } 592 646 } 647 593 648 private ISymbolicExpressionTreeNode MakeExp(ISymbolicExpressionTreeNode node) { 594 649 if (IsConstant(node)) { 595 650 var constT = node as ConstantTreeNode; 596 651 return MakeConstant(Math.Exp(constT.Value)); 652 } else if (IsFactor(node)) { 653 var factNode = node as FactorVariableTreeNode; 654 for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = Math.Exp(factNode.Weights[i]); 655 return factNode; 597 656 } else if (IsLog(node)) { 598 657 return node.GetSubtree(0); … … 612 671 var constT = node as ConstantTreeNode; 613 672 return MakeConstant(constT.Value * constT.Value); 673 } else if (IsFactor(node)) { 674 var factNode = node as FactorVariableTreeNode; 675 for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = factNode.Weights[i] * factNode.Weights[i]; 676 return factNode; 614 677 } else if (IsSquareRoot(node)) { 615 678 return node.GetSubtree(0); … … 620 683 } 621 684 } 685 622 686 private ISymbolicExpressionTreeNode MakeSquareRoot(ISymbolicExpressionTreeNode node) { 623 687 if (IsConstant(node)) { 624 688 var constT = node as ConstantTreeNode; 625 689 return MakeConstant(Math.Sqrt(constT.Value)); 690 } else if (IsFactor(node)) { 691 var factNode = node as FactorVariableTreeNode; 692 for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = Math.Sqrt(factNode.Weights[i]); 693 return factNode; 626 694 } else if (IsSquare(node)) { 627 695 return node.GetSubtree(0); … … 637 705 var constT = node as ConstantTreeNode; 638 706 return MakeConstant(Math.Log(constT.Value)); 707 } else if (IsFactor(node)) { 708 var factNode = node as FactorVariableTreeNode; 709 for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = Math.Log(factNode.Weights[i]); 710 return factNode; 639 711 } else if (IsExp(node)) { 640 712 return node.GetSubtree(0); … … 647 719 } 648 720 } 721 649 722 private ISymbolicExpressionTreeNode MakeRoot(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 650 723 if (IsConstant(a) && IsConstant(b)) { … … 652 725 var constB = b as ConstantTreeNode; 653 726 return MakeConstant(Math.Pow(constA.Value, 1.0 / Math.Round(constB.Value))); 727 } else if (IsFactor(a) && IsConstant(b)) { 728 var factNode = a as FactorVariableTreeNode; 729 var constNode = b as ConstantTreeNode; 730 for (int i = 0; i < factNode.Weights.Length; i++) 731 factNode.Weights[i] = Math.Pow(factNode.Weights[i], 1.0 / Math.Round(constNode.Value)); 732 return factNode; 733 } else if (IsConstant(a) && IsFactor(b)) { 734 var constNode = a as ConstantTreeNode; 735 var factNode = b as FactorVariableTreeNode; 736 for (int i = 0; i < factNode.Weights.Length; i++) 737 factNode.Weights[i] = Math.Pow(constNode.Value, 1.0 / Math.Round(factNode.Weights[i])); 738 return factNode; 739 } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) { 740 var node0 = a as FactorVariableTreeNode; 741 var node1 = b as FactorVariableTreeNode; 742 for (int i = 0; i < node0.Weights.Length; i++) 743 node0.Weights[i] = Math.Pow(node0.Weights[i], 1.0 / Math.Round(node1.Weights[i])); 744 return node0; 654 745 } else if (IsConstant(b)) { 655 746 var constB = b as ConstantTreeNode; … … 679 770 } 680 771 } 772 681 773 private ISymbolicExpressionTreeNode MakePower(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b) { 682 774 if (IsConstant(a) && IsConstant(b)) { … … 684 776 var constB = b as ConstantTreeNode; 685 777 return MakeConstant(Math.Pow(constA.Value, Math.Round(constB.Value))); 778 } else if (IsFactor(a) && IsConstant(b)) { 779 var factNode = a as FactorVariableTreeNode; 780 var constNode = b as ConstantTreeNode; 781 for (int i = 0; i < factNode.Weights.Length; i++) 782 factNode.Weights[i] = Math.Pow(factNode.Weights[i], Math.Round(constNode.Value)); 783 return factNode; 784 } else if (IsConstant(a) && IsFactor(b)) { 785 var constNode = a as ConstantTreeNode; 786 var factNode = b as FactorVariableTreeNode; 787 for (int i = 0; i < factNode.Weights.Length; i++) 788 factNode.Weights[i] = Math.Pow(constNode.Value, Math.Round(factNode.Weights[i])); 789 return factNode; 790 } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) { 791 var node0 = a as FactorVariableTreeNode; 792 var node1 = b as FactorVariableTreeNode; 793 for (int i = 0; i < node0.Weights.Length; i++) 794 node0.Weights[i] = Math.Pow(node0.Weights[i], Math.Round(node1.Weights[i])); 795 return node0; 686 796 } else if (IsConstant(b)) { 687 797 var constB = b as ConstantTreeNode; … … 718 828 // fold constants 719 829 return MakeConstant(((ConstantTreeNode)a).Value / ((ConstantTreeNode)b).Value); 720 } if (IsConstant(a) && !((ConstantTreeNode)a).Value.IsAlmost(1.0)) {830 } else if ((IsConstant(a) && !((ConstantTreeNode)a).Value.IsAlmost(1.0))) { 721 831 return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a))); 722 832 } else if (IsVariableBase(a) && IsConstant(b)) { … … 725 835 ((VariableTreeNodeBase)a).Weight /= constB; 726 836 return a; 837 } else if (IsFactor(a) && IsConstant(b)) { 838 var factNode = a as FactorVariableTreeNode; 839 var constNode = b as ConstantTreeNode; 840 for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = factNode.Weights[i] / constNode.Value; 841 return factNode; 842 } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) { 843 var node0 = a as FactorVariableTreeNode; 844 var node1 = b as FactorVariableTreeNode; 845 for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] / node1.Weights[i]; 846 return node0; 847 } else if (IsFactor(a)) { 848 return MakeFraction(MakeConstant(1.0), MakeProduct(b, Invert(a))); 727 849 } else if (IsVariableBase(a) && IsVariableBase(b) && AreSameVariable(a, b)) { 728 850 // cancel variables … … 733 855 return a.Subtrees 734 856 .Select(x => GetSimplifiedTree(x)) 735 .Select(x => MakeFraction(x, b))736 .Aggregate((c, d) => MakeSum(c, d));857 .Select(x => MakeFraction(x, b)) 858 .Aggregate((c, d) => MakeSum(c, d)); 737 859 } else if (IsMultiplication(a) && IsConstant(b)) { 738 860 return MakeProduct(a, Invert(b)); … … 769 891 // x + 0 => x 770 892 return a; 893 } else if (IsFactor(a) && IsConstant(b)) { 894 var factNode = a as FactorVariableTreeNode; 895 var constNode = b as ConstantTreeNode; 896 for (int i = 0; i < factNode.Weights.Length; i++) factNode.Weights[i] = factNode.Weights[i] + constNode.Value; 897 return factNode; 898 } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) { 899 var node0 = a as FactorVariableTreeNode; 900 var node1 = b as FactorVariableTreeNode; 901 for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] + node1.Weights[i]; 902 return node0; 771 903 } else if (IsAddition(a) && IsAddition(b)) { 772 904 // merge additions … … 835 967 var subtrees = new List<ISymbolicExpressionTreeNode>(sum.Subtrees); 836 968 while (sum.Subtrees.Any()) sum.RemoveSubtree(0); 837 var groupedVarNodes = from node in subtrees.OfType<VariableTreeNodeBase>() 969 var groupedVarNodes = from node in subtrees.OfType<IVariableTreeNode>() 970 where node.SubtreeCount == 0 971 // only consider terminal nodes 838 972 let lag = (node is LaggedVariableTreeNode) ? ((LaggedVariableTreeNode)node).Lag : 0 839 let cat = (node is BinaryFactorVariableTreeNode) ? ((BinaryFactorVariableTreeNode)node).VariableValue : string.Empty 840 group node by node.VariableName + cat + lag into g 973 let cat = 974 (node is BinaryFactorVariableTreeNode) ? ((BinaryFactorVariableTreeNode)node).VariableValue : string.Empty 975 group node by node.VariableName + cat + lag 976 into g 841 977 select g; 842 var unchangedSubtrees = subtrees.Where(t => !(t is VariableTreeNodeBase)); 978 var constant = (from node in subtrees.OfType<ConstantTreeNode>() 979 select node.Value).DefaultIfEmpty(0.0).Sum(); 980 var unchangedSubtrees = subtrees.Where(t => t.SubtreeCount > 0 || !(t is IVariableTreeNode) && !(t is ConstantTreeNode)); 843 981 844 982 foreach (var variableNodeGroup in groupedVarNodes) { 845 var weightSum = variableNodeGroup.Select(t => t.Weight).Sum(); 846 var representative = variableNodeGroup.First(); 847 representative.Weight = weightSum; 848 sum.AddSubtree(representative); 983 var firstNode = variableNodeGroup.First(); 984 if (firstNode is VariableTreeNodeBase) { 985 var representative = firstNode as VariableTreeNodeBase; 986 var weightSum = variableNodeGroup.Cast<VariableTreeNodeBase>().Select(t => t.Weight).Sum(); 987 representative.Weight = weightSum; 988 sum.AddSubtree(representative); 989 } else if (firstNode is FactorVariableTreeNode) { 990 var representative = firstNode as FactorVariableTreeNode; 991 foreach (var node in variableNodeGroup.Skip(1).Cast<FactorVariableTreeNode>()) { 992 for (int j = 0; j < representative.Weights.Length; j++) { 993 representative.Weights[j] += node.Weights[j]; 994 } 995 } 996 for (int j = 0; j < representative.Weights.Length; j++) { 997 representative.Weights[j] += constant; 998 } 999 sum.AddSubtree(representative); 1000 } 849 1001 } 850 1002 foreach (var unchangedSubtree in unchangedSubtrees) 851 1003 sum.AddSubtree(unchangedSubtree); 1004 if (!constant.IsAlmost(0.0)) { 1005 sum.AddSubtree(MakeConstant(constant)); 1006 } 852 1007 } 853 1008 … … 861 1016 // a * $ => $ * a 862 1017 return MakeProduct(b, a); 1018 } else if (IsFactor(a) && IsFactor(b) && AreSameVariable(a, b)) { 1019 var node0 = a as FactorVariableTreeNode; 1020 var node1 = b as FactorVariableTreeNode; 1021 for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] * node1.Weights[i]; 1022 return node0; 1023 } else if (IsFactor(a) && IsConstant(b)) { 1024 var node0 = a as FactorVariableTreeNode; 1025 var node1 = b as ConstantTreeNode; 1026 for (int i = 0; i < node0.Weights.Length; i++) node0.Weights[i] = node0.Weights[i] * node1.Value; 1027 return node0; 863 1028 } else if (IsConstant(b) && ((ConstantTreeNode)b).Value.IsAlmost(1.0)) { 864 1029 // $ * 1.0 => $ … … 868 1033 ((VariableTreeNodeBase)a).Weight *= ((ConstantTreeNode)b).Value; 869 1034 return a; 870 } else if (IsConstant(b) && IsAddition(a)) { 1035 } else if (IsConstant(b) && IsAddition(a) || 1036 IsFactor(a) && IsAddition(b) || 1037 IsAddition(b) && IsFactor(a)) { 871 1038 // multiply constants into additions 872 1039 return a.Subtrees.Select(x => MakeProduct(x, b)).Aggregate((c, d) => MakeSum(c, d)); … … 902 1069 } 903 1070 } 1071 904 1072 #endregion 905 1073 906 907 1074 #region helper functions 1075 908 1076 private bool ContainsVariableCondition(ISymbolicExpressionTreeNode node) { 909 1077 if (node.Symbol is VariableCondition) return true; … … 940 1108 if (aLaggedVar != null && bLaggedVar != null) { 941 1109 return aLaggedVar.VariableName == bLaggedVar.VariableName && 942 aLaggedVar.Lag == bLaggedVar.Lag;1110 aLaggedVar.Lag == bLaggedVar.Lag; 943 1111 } 944 1112 var aVar = a as VariableTreeNode; … … 947 1115 return aVar.VariableName == bVar.VariableName; 948 1116 } 949 var aFactor = a as BinaryFactorVariableTreeNode;950 var bFactor = b as BinaryFactorVariableTreeNode;1117 var aFactor = a as FactorVariableTreeNode; 1118 var bFactor = b as FactorVariableTreeNode; 951 1119 if (aFactor != null && bFactor != null) { 952 return aFactor.VariableName == bFactor.VariableName && 953 aFactor.VariableValue == bFactor.VariableValue; 954 } 955 1120 return aFactor.VariableName == bFactor.VariableName; 1121 } 1122 var aBinFactor = a as BinaryFactorVariableTreeNode; 1123 var bBinFactor = b as BinaryFactorVariableTreeNode; 1124 if (aBinFactor != null && bBinFactor != null) { 1125 return aBinFactor.VariableName == bBinFactor.VariableName && 1126 aBinFactor.VariableValue == bBinFactor.VariableValue; 1127 } 956 1128 return false; 957 1129 } … … 961 1133 var subtrees = new List<ISymbolicExpressionTreeNode>(prod.Subtrees); 962 1134 while (prod.Subtrees.Any()) prod.RemoveSubtree(0); 963 var groupedVarNodes = from node in subtrees.OfType<VariableTreeNodeBase>() 1135 var groupedVarNodes = from node in subtrees.OfType<IVariableTreeNode>() 1136 where node.SubtreeCount == 0 964 1137 let lag = (node is LaggedVariableTreeNode) ? ((LaggedVariableTreeNode)node).Lag : 0 965 group node by node.VariableName + lag into g 1138 let cat = 1139 (node is BinaryFactorVariableTreeNode) ? ((BinaryFactorVariableTreeNode)node).VariableValue : string.Empty 1140 group node by node.VariableName + cat + lag 1141 into g 966 1142 orderby g.Count() 967 1143 select g; 968 1144 var constantProduct = (from node in subtrees.OfType<VariableTreeNodeBase>() 969 1145 select node.Weight) 970 971 972 973 1146 .Concat(from node in subtrees.OfType<ConstantTreeNode>() 1147 select node.Value) 1148 .DefaultIfEmpty(1.0) 1149 .Aggregate((c1, c2) => c1 * c2); 974 1150 975 1151 var unchangedSubtrees = from tree in subtrees 976 where !(tree is VariableTreeNodeBase) 977 where !(tree is ConstantTreeNode) 1152 where tree.SubtreeCount > 0 || !(tree is IVariableTreeNode) && !(tree is ConstantTreeNode) 978 1153 select tree; 979 1154 980 1155 foreach (var variableNodeGroup in groupedVarNodes) { 981 var representative = variableNodeGroup.First(); 982 representative.Weight = 1.0; 983 if (variableNodeGroup.Count() > 1) { 984 var poly = mulSymbol.CreateTreeNode(); 985 for (int p = 0; p < variableNodeGroup.Count(); p++) { 986 poly.AddSubtree((ISymbolicExpressionTreeNode)representative.Clone()); 1156 var firstNode = variableNodeGroup.First(); 1157 if (firstNode is VariableTreeNodeBase) { 1158 var representative = (VariableTreeNodeBase)firstNode; 1159 representative.Weight = 1.0; 1160 if (variableNodeGroup.Count() > 1) { 1161 var poly = mulSymbol.CreateTreeNode(); 1162 for (int p = 0; p < variableNodeGroup.Count(); p++) { 1163 poly.AddSubtree((ISymbolicExpressionTreeNode)representative.Clone()); 1164 } 1165 prod.AddSubtree(poly); 1166 } else { 1167 prod.AddSubtree(representative); 987 1168 } 988 prod.AddSubtree(poly); 989 } else { 1169 } else if (firstNode is FactorVariableTreeNode) { 1170 var representative = (FactorVariableTreeNode)firstNode; 1171 foreach (var node in variableNodeGroup.Skip(1).Cast<FactorVariableTreeNode>()) { 1172 for (int j = 0; j < representative.Weights.Length; j++) { 1173 representative.Weights[j] *= node.Weights[j]; 1174 } 1175 } 1176 for (int j = 0; j < representative.Weights.Length; j++) { 1177 representative.Weights[j] *= constantProduct; 1178 } 1179 constantProduct = 1.0; 1180 // if the product already contains a factor it is not necessary to multiply a constant below 990 1181 prod.AddSubtree(representative); 991 1182 } … … 1013 1204 var variableTree = (VariableTreeNodeBase)x; 1014 1205 variableTree.Weight *= -1.0; 1206 } else if (IsFactor(x)) { 1207 var factorNode = (FactorVariableTreeNode)x; 1208 for (int i = 0; i < factorNode.Weights.Length; i++) factorNode.Weights[i] *= -1; 1015 1209 } else if (IsAddition(x)) { 1016 1210 // (x0 + x1 + .. + xn) * -1 => (-x0 + -x1 + .. + -xn) … … 1041 1235 if (IsConstant(x)) { 1042 1236 return MakeConstant(1.0 / ((ConstantTreeNode)x).Value); 1237 } else if (IsFactor(x)) { 1238 var factorNode = (FactorVariableTreeNode)x; 1239 for (int i = 0; i < factorNode.Weights.Length; i++) factorNode.Weights[i] = 1.0 / factorNode.Weights[i]; 1240 return factorNode; 1043 1241 } else if (IsDivision(x)) { 1044 1242 return MakeFraction(x.GetSubtree(1), x.GetSubtree(0)); … … 1061 1259 return tree; 1062 1260 } 1261 1063 1262 #endregion 1064 1263 } -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Symbols/FactorVariableTreeNode.cs
r14249 r14251 114 114 115 115 public override string ToString() { 116 return VariableName + " (factor)";116 return VariableName + " (factor)"; 117 117 } 118 118 } -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/FactorGradientChart.Designer.cs
r14248 r14251 25 25 private void InitializeComponent() { 26 26 this.components = new System.ComponentModel.Container(); 27 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FactorGradientChart));28 27 System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation verticalLineAnnotation1 = new System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation(); 29 28 System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); … … 46 45 // 47 46 this.calculationPendingLabel.BackColor = System.Drawing.Color.White; 48 this.calculationPendingLabel.Image = ((System.Drawing.Image)(resources.GetObject("calculationPendingLabel.Image")));47 this.calculationPendingLabel.Image = HeuristicLab.Common.Resources.VSImageLibrary.Timer; 49 48 this.calculationPendingLabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; 50 49 this.calculationPendingLabel.Location = new System.Drawing.Point(3, 3); -
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/GradientChart.Designer.cs
r14158 r14251 25 25 private void InitializeComponent() { 26 26 this.components = new System.ComponentModel.Container(); 27 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GradientChart));28 27 System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation verticalLineAnnotation1 = new System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation(); 29 28 System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
Note: See TracChangeset
for help on using the changeset viewer.