Changeset 14534
- Timestamp:
- 12/30/16 19:35:15 (8 years ago)
- Location:
- branches/symbreg-factors-2650
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/symbreg-factors-2650/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Importer/SymbolicExpressionImporter.cs
r14185 r14534 35 35 private const string INVOKESTART = "CALL"; 36 36 private const string TIMELAGSTART = "LAG"; 37 private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>() 37 private Dictionary<string, Symbol> knownSymbols = new Dictionary<string, Symbol>() 38 38 { 39 39 {"+", new Addition()}, … … 45 45 {"POW", new Power()}, 46 46 {"ROOT", new Root()}, 47 {"SQR", new Square()}, 48 {"SQRT", new SquareRoot()}, 47 49 {"SIN",new Sine()}, 48 50 {"COS", new Cosine()}, … … 74 76 {"PROG", new ProgramRootSymbol()}, 75 77 {"MAIN", new StartSymbol()}, 78 {"FACTOR", new FactorVariable() }, 79 {"BINARYFACTOR", new BinaryFactorVariable()} 76 80 }; 77 81 … … 82 86 TimeLag timeLag = new TimeLag(); 83 87 Integral integral = new Integral(); 88 FactorVariable factorVar = new FactorVariable(); 89 BinaryFactorVariable binFactorVar = new BinaryFactorVariable(); 84 90 85 91 ProgramRootSymbol programRootSymbol = new ProgramRootSymbol(); … … 91 97 ISymbolicExpressionTreeNode start = startSymbol.CreateTreeNode(); 92 98 ISymbolicExpressionTreeNode mainBranch = ParseSexp(new Queue<Token>(GetTokenStream(str))); 93 if 99 if(mainBranch.Symbol is ProgramRootSymbol) { 94 100 // when a root symbol was parsed => use main branch as root 95 101 root = mainBranch; … … 111 117 112 118 private ISymbolicExpressionTreeNode ParseSexp(Queue<Token> tokens) { 113 if 119 if(tokens.Peek().Symbol == TokenSymbol.LPAR) { 114 120 ISymbolicExpressionTreeNode tree; 115 121 Expect(Token.LPAR, tokens); 116 if 122 if(tokens.Peek().StringValue.StartsWith(VARSTART)) { 117 123 tree = ParseVariable(tokens); 118 } else if 124 } else if(tokens.Peek().StringValue.StartsWith(LAGGEDVARSTART)) { 119 125 tree = ParseLaggedVariable(tokens); 120 } else if 126 } else if(tokens.Peek().StringValue.StartsWith(TIMELAGSTART)) { 121 127 tree = ParseTimeLag(tokens); 122 128 tree.AddSubtree(ParseSexp(tokens)); 123 } else if 129 } else if(tokens.Peek().StringValue.StartsWith(INTEGRALSTART)) { 124 130 tree = ParseIntegral(tokens); 125 131 tree.AddSubtree(ParseSexp(tokens)); 126 } else if 132 } else if(tokens.Peek().StringValue.StartsWith(DEFUNSTART)) { 127 133 tree = ParseDefun(tokens); 128 while 134 while(!tokens.Peek().Equals(Token.RPAR)) { 129 135 tree.AddSubtree(ParseSexp(tokens)); 130 136 } 131 } else if 137 } else if(tokens.Peek().StringValue.StartsWith(ARGSTART)) { 132 138 tree = ParseArgument(tokens); 133 } else if 139 } else if(tokens.Peek().StringValue.StartsWith(INVOKESTART)) { 134 140 tree = ParseInvoke(tokens); 135 while 141 while(!tokens.Peek().Equals(Token.RPAR)) { 136 142 tree.AddSubtree(ParseSexp(tokens)); 137 143 } 144 } else if(tokens.Peek().StringValue.StartsWith("FACTOR")) { 145 tree = ParseFactor(tokens); 146 } else if(tokens.Peek().StringValue.StartsWith("BINARYFACTOR")) { 147 tree = ParseBinaryFactor(tokens); 138 148 } else { 139 149 Token curToken = tokens.Dequeue(); 140 150 tree = CreateTree(curToken); 141 while 151 while(!tokens.Peek().Equals(Token.RPAR)) { 142 152 tree.AddSubtree(ParseSexp(tokens)); 143 153 } … … 145 155 Expect(Token.RPAR, tokens); 146 156 return tree; 147 } else if 157 } else if(tokens.Peek().Symbol == TokenSymbol.NUMBER) { 148 158 ConstantTreeNode t = (ConstantTreeNode)constant.CreateTreeNode(); 149 159 t.Value = tokens.Dequeue().DoubleValue; … … 201 211 } 202 212 213 private ISymbolicExpressionTreeNode ParseFactor(Queue<Token> tokens) { 214 Token tok = tokens.Dequeue(); 215 Debug.Assert(tok.StringValue == "FACTOR"); 216 FactorVariableTreeNode t = (FactorVariableTreeNode)(new FactorVariable()).CreateTreeNode(); // create a new symbol each time on purpose 217 var varNameTok = tokens.Dequeue(); 218 Debug.Assert(tok.Symbol == TokenSymbol.SYMB); 219 t.VariableName = varNameTok.StringValue; 220 221 var weights = new List<double>(); 222 while(tokens.Peek().Symbol == TokenSymbol.NUMBER) { 223 weights.Add(tokens.Dequeue().DoubleValue); 224 } 225 226 t.Weights = weights.ToArray(); 227 228 // create a set of (virtual) values to match the number of weights 229 t.Symbol.VariableNames = new string[] { t.VariableName }; 230 t.Symbol.VariableValues = new KeyValuePair<string, List<string>>[] { new KeyValuePair<string, List<string>>(t.VariableName, weights.Select((_, i) => "x" + i).ToList()) }; 231 return t; 232 } 233 234 private ISymbolicExpressionTreeNode ParseBinaryFactor(Queue<Token> tokens) { 235 Token tok = tokens.Dequeue(); 236 Debug.Assert(tok.StringValue == "BINFACTOR"); 237 var t = (BinaryFactorVariableTreeNode)binFactorVar.CreateTreeNode(); 238 var varNameTok = tokens.Dequeue(); 239 Debug.Assert(tok.Symbol == TokenSymbol.SYMB); 240 t.VariableName = varNameTok.StringValue; 241 242 var varValTok = tokens.Dequeue(); 243 Debug.Assert(tok.Symbol == TokenSymbol.SYMB); 244 t.VariableValue = varNameTok.StringValue; 245 246 var weightTok = tokens.Dequeue(); 247 Debug.Assert(tok.Symbol == TokenSymbol.NUMBER); 248 t.Weight = weightTok.DoubleValue; 249 250 return t; 251 } 252 253 203 254 private ISymbolicExpressionTreeNode ParseLaggedVariable(Queue<Token> tokens) { 204 255 Token varTok = tokens.Dequeue(); … … 212 263 213 264 private ISymbolicExpressionTreeNode CreateTree(Token token) { 214 if 265 if(token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue); 215 266 return knownSymbols[token.StringValue].CreateTreeNode(); 216 267 } … … 218 269 private void Expect(Token token, Queue<Token> tokens) { 219 270 Token cur = tokens.Dequeue(); 220 if 271 if(!token.Equals(cur)) throw new FormatException("Expected: " + token.StringValue + ", but got: " + cur.StringValue); 221 272 } 222 273 } -
branches/symbreg-factors-2650/HeuristicLab.Tests/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4/SymbolicDataAnalysisExpressionTreeSimplifierTest.cs
r14185 r14534 19 19 */ 20 20 #endregion 21 22 21 using System; 23 using System. Collections.Generic;22 using System.Globalization; 24 23 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding; 25 using HeuristicLab.Problems.DataAnalysis.Symbolic;26 24 using Microsoft.VisualStudio.TestTools.UnitTesting; 27 25 … … 39 37 SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter(); 40 38 #region single argument arithmetics 41 { 42 var actualTree = simplifier.Simplify(importer.Import("(+ 1.0)")); 43 var expectedTree = importer.Import("1.0"); 44 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 45 } 46 { 47 var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a))")); 48 var expectedTree = importer.Import("(variable 2.0 a)"); 49 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 50 } 51 { 52 var actualTree = simplifier.Simplify(importer.Import("(- 1.0)")); 53 var expectedTree = importer.Import("-1.0"); 54 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 55 } 56 { 57 var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a))")); 58 var expectedTree = importer.Import("(variable -2.0 a)"); 59 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 60 } 61 { 62 var actualTree = simplifier.Simplify(importer.Import("(* 2.0)")); 63 var expectedTree = importer.Import("2.0"); 64 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 65 } 66 { 67 var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a))")); 68 var expectedTree = importer.Import("(variable 2.0 a)"); 69 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 70 } 71 { 72 var actualTree = simplifier.Simplify(importer.Import("(/ 2.0)")); 73 var expectedTree = importer.Import("0.5"); 74 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 75 } 76 { 77 var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a))")); 78 var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))"); 79 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 80 } 81 #endregion 39 40 AssertEqualAfterSimplification("(+ 1.0)", "1.0"); 41 AssertEqualAfterSimplification("(- 1.0)", "-1.0"); 42 AssertEqualAfterSimplification("(- (variable 2.0 a))", "(variable -2.0 a)"); 43 AssertEqualAfterSimplification("(* 2.0)", "2.0"); 44 AssertEqualAfterSimplification("(* (variable 2.0 a))", "(variable 2.0 a)"); 45 AssertEqualAfterSimplification("(/ 2.0)", "0.5"); 46 AssertEqualAfterSimplification("(/ (variable 2.0 a))", "(/ 1.0 (variable 2.0 a))"); 47 #endregion 48 82 49 #region aggregation of constants into factors 83 { 84 var actualTree = simplifier.Simplify(importer.Import("(* 2.0 (variable 2.0 a))")); 85 var expectedTree = importer.Import("(variable 4.0 a)"); 86 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 87 } 88 { 89 var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) 2.0)")); 90 var expectedTree = importer.Import("(variable 1.0 a)"); 91 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 92 } 93 { 94 var actualTree = simplifier.Simplify(importer.Import("(/ (variable 2.0 a) (* 2.0 2.0))")); 95 var expectedTree = importer.Import("(variable 0.5 a)"); 96 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 97 } 98 #endregion 50 AssertEqualAfterSimplification("(* 2.0 (variable 2.0 a))", "(variable 4.0 a)"); 51 AssertEqualAfterSimplification("(/ (variable 2.0 a) 2.0)", "(variable 1.0 a)"); 52 AssertEqualAfterSimplification("(/ (variable 2.0 a) (* 2.0 2.0))", "(variable 0.5 a)"); 53 #endregion 54 99 55 #region constant and variable folding 100 { 101 var actualTree = simplifier.Simplify(importer.Import("(+ 1.0 2.0)")); 102 var expectedTree = importer.Import("3.0"); 103 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 104 } 105 { 106 var actualTree = simplifier.Simplify(importer.Import("(+ (variable 2.0 a) (variable 2.0 a))")); 107 var expectedTree = importer.Import("(variable 4.0 a)"); 108 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 109 } 110 { 111 var actualTree = simplifier.Simplify(importer.Import("(- (variable 2.0 a) (variable 1.0 a))")); 112 var expectedTree = importer.Import("(variable 1.0 a)"); 113 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 114 } 115 { 116 var actualTree = simplifier.Simplify(importer.Import("(* (variable 2.0 a) (variable 2.0 a))")); 117 var expectedTree = importer.Import("(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)"); 118 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 119 } 120 { 121 var actualTree = simplifier.Simplify(importer.Import("(/ (variable 1.0 a) (variable 2.0 a))")); 122 var expectedTree = importer.Import("0.5"); 123 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 124 } 125 #endregion 56 AssertEqualAfterSimplification("(+ 1.0 2.0)", "3.0"); 57 AssertEqualAfterSimplification("(+ (variable 2.0 a) (variable 2.0 a))", "(variable 4.0 a)"); 58 AssertEqualAfterSimplification("(- (variable 2.0 a) (variable 1.0 a))", "(variable 1.0 a)"); 59 AssertEqualAfterSimplification("(* (variable 2.0 a) (variable 2.0 a))", "(* (* (variable 1.0 a) (variable 1.0 a)) 4.0)"); 60 AssertEqualAfterSimplification("(/ (variable 1.0 a) (variable 2.0 a))", "0.5"); 61 #endregion 62 126 63 #region logarithm rules 127 { 128 // cancellation 129 var actualTree = simplifier.Simplify(importer.Import("(log (exp (variable 2.0 a)))")); 130 var expectedTree = importer.Import("(variable 2.0 a)"); 131 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 132 } 133 { 134 // must not transform logs in this way as we do not know wether both variables are positive 135 var actualTree = simplifier.Simplify(importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))")); 136 var expectedTree = importer.Import("(log (* (variable 1.0 a) (variable 1.0 b)))"); 137 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 138 } 139 { 140 // must not transform logs in this way as we do not know wether both variables are positive 141 var actualTree = simplifier.Simplify(importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))")); 142 var expectedTree = importer.Import("(log (/ (variable 1.0 a) (variable 1.0 b)))"); 143 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 144 } 145 #endregion 64 65 // cancellation 66 AssertEqualAfterSimplification("(log (exp (variable 2.0 a)))", "(variable 2.0 a)"); 67 // must not transform logs in this way as we do not know wether both variables are positive 68 AssertEqualAfterSimplification("(log (* (variable 1.0 a) (variable 1.0 b)))", "(log (* (variable 1.0 a) (variable 1.0 b)))"); 69 // must not transform logs in this way as we do not know wether both variables are positive 70 AssertEqualAfterSimplification("(log (/ (variable 1.0 a) (variable 1.0 b)))", "(log (/ (variable 1.0 a) (variable 1.0 b)))"); 71 #endregion 72 146 73 #region exponentiation rules 147 { 148 // cancellation 149 var actualTree = simplifier.Simplify(importer.Import("(exp (log (variable 2.0 a)))")); 150 var expectedTree = importer.Import("(variable 2.0 a)"); 151 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 152 } 153 { 154 // exp transformation 155 var actualTree = simplifier.Simplify(importer.Import("(exp (+ (variable 2.0 a) (variable 3.0 b)))")); 156 var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))"); 157 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 158 } 159 { 160 // exp transformation 161 var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (variable 3.0 b)))")); 162 var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))"); 163 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 164 } 165 { 166 // exp transformation 167 var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))")); 168 var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))"); 169 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 170 } 171 { 172 // exp transformation 173 var actualTree = simplifier.Simplify(importer.Import("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))")); 174 var expectedTree = importer.Import("(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))"); 175 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 176 } 177 #endregion 74 // cancellation 75 AssertEqualAfterSimplification("(exp (log (variable 2.0 a)))", "(variable 2.0 a)"); 76 // exp transformation 77 AssertEqualAfterSimplification("(exp (+ (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable 3.0 b)))"); 78 // exp transformation 79 AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (variable 3.0 b)))", "(* (exp (variable 2.0 a)) (exp (variable -3.0 b)))"); 80 // exp transformation 81 AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (variable 4.0 c))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (variable 1.0 c) -12.0)))"); 82 // exp transformation 83 AssertEqualAfterSimplification("(exp (- (variable 2.0 a) (* (variable 3.0 b) (cos (variable 4.0 c)))))", "(* (exp (variable 2.0 a)) (exp (* (variable 1.0 b) (cos (variable 4.0 c)) -3.0)))"); 84 #endregion 85 178 86 #region power rules 179 { 180 // cancellation 181 var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 0.0)")); 182 var expectedTree = importer.Import("1.0"); 183 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 184 } 185 { 186 // fixed point 187 var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) 1.0)")); 188 var expectedTree = importer.Import("(variable 2.0 a)"); 189 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 190 } 191 { 192 // inversion fixed point 193 var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -1.0)")); 194 var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))"); 195 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 196 } 197 { 198 // inversion 199 var actualTree = simplifier.Simplify(importer.Import("(pow (variable 2.0 a) -2.0)")); 200 var expectedTree = importer.Import("(/ 1.0 (pow (variable 2.0 a) 2.0))"); 201 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 202 } 203 { 204 // constant folding 205 var actualTree = simplifier.Simplify(importer.Import("(pow 3.0 2.0)")); 206 var expectedTree = importer.Import("9.0"); 207 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 208 } 209 #endregion 87 88 // cancellation 89 AssertEqualAfterSimplification("(pow (variable 2.0 a) 0.0)", "1.0"); 90 // fixed point 91 AssertEqualAfterSimplification("(pow (variable 2.0 a) 1.0)", "(variable 2.0 a)"); 92 // inversion fixed point 93 AssertEqualAfterSimplification("(pow (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))"); 94 // inversion 95 AssertEqualAfterSimplification("(pow (variable 2.0 a) -2.0)", "(/ 1.0 (pow (variable 2.0 a) 2.0))"); 96 // constant folding 97 AssertEqualAfterSimplification("(pow 3.0 2.0)", "9.0"); 98 #endregion 99 210 100 #region root rules 211 { 212 // cancellation 213 var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 0.0)")); 214 var expectedTree = importer.Import("1.0"); 215 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 216 } 217 { 218 // fixed point 219 var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) 1.0)")); 220 var expectedTree = importer.Import("(variable 2.0 a)"); 221 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 222 } 223 { 224 // inversion fixed point 225 var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -1.0)")); 226 var expectedTree = importer.Import("(/ 1.0 (variable 2.0 a))"); 227 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 228 } 229 { 230 // inversion 231 var actualTree = simplifier.Simplify(importer.Import("(root (variable 2.0 a) -2.0)")); 232 var expectedTree = importer.Import("(/ 1.0 (root (variable 2.0 a) 2.0))"); 233 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 234 } 235 { 236 // constant folding 237 var actualTree = simplifier.Simplify(importer.Import("(root 9.0 2.0)")); 238 var expectedTree = importer.Import("3.0"); 239 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 240 } 241 #endregion 101 // cancellation 102 AssertEqualAfterSimplification("(root (variable 2.0 a) 0.0)", "1.0"); 103 // fixed point 104 AssertEqualAfterSimplification("(root (variable 2.0 a) 1.0)", "(variable 2.0 a)"); 105 // inversion fixed point 106 AssertEqualAfterSimplification("(root (variable 2.0 a) -1.0)", "(/ 1.0 (variable 2.0 a))"); 107 // inversion 108 AssertEqualAfterSimplification("(root (variable 2.0 a) -2.0)", "(/ 1.0 (root (variable 2.0 a) 2.0))"); 109 // constant folding 110 AssertEqualAfterSimplification("(root 9.0 2.0)", "3.0"); 111 #endregion 112 242 113 #region boolean operations 243 { 244 // always true and 245 var actualTree = simplifier.Simplify(importer.Import("(and 1.0 2.0)")); 246 var expectedTree = importer.Import("1.0"); 247 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 248 } 249 { 250 // always false and 251 var actualTree = simplifier.Simplify(importer.Import("(and 1.0 -2.0)")); 252 var expectedTree = importer.Import("-1.0"); 253 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 254 } 255 { 256 // always true or 257 var actualTree = simplifier.Simplify(importer.Import("(or -1.0 2.0)")); 258 var expectedTree = importer.Import("1.0"); 259 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 260 } 261 { 262 // always false or 263 var actualTree = simplifier.Simplify(importer.Import("(or -1.0 -2.0)")); 264 var expectedTree = importer.Import("-1.0"); 265 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 266 } 267 { 268 // constant not 269 var actualTree = simplifier.Simplify(importer.Import("(not -2.0)")); 270 var expectedTree = importer.Import("1.0"); 271 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 272 } 273 { 274 // constant not 275 var actualTree = simplifier.Simplify(importer.Import("(not 2.0)")); 276 var expectedTree = importer.Import("-1.0"); 277 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 278 } 279 { 280 // constant not 281 var actualTree = simplifier.Simplify(importer.Import("(not 0.0)")); 282 var expectedTree = importer.Import("1.0"); 283 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 284 } 285 { 286 // nested nots 287 var actualTree = simplifier.Simplify(importer.Import("(not (not 1.0))")); 288 var expectedTree = importer.Import("1.0"); 289 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 290 } 291 { 292 // not of non-Boolean argument 293 var actualTree = simplifier.Simplify(importer.Import("(not (variable 1.0 a))")); 294 var expectedTree = importer.Import("(not (> (variable 1.0 a) 0.0))"); 295 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 296 } 297 { 298 // not Boolean argument 299 var actualTree = simplifier.Simplify(importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))")); 300 var expectedTree = importer.Import("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))"); 301 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 302 } 303 #endregion 114 // always true and 115 AssertEqualAfterSimplification("(and 1.0 2.0)", "1.0"); 116 // always false and 117 AssertEqualAfterSimplification("(and 1.0 -2.0)", "-1.0"); 118 // always true or 119 AssertEqualAfterSimplification("(or -1.0 2.0)", "1.0"); 120 // always false or 121 AssertEqualAfterSimplification("(or -1.0 -2.0)", "-1.0"); 122 // constant not 123 AssertEqualAfterSimplification("(not -2.0)", "1.0"); 124 // constant not 125 AssertEqualAfterSimplification("(not 2.0)", "-1.0"); 126 // constant not 127 AssertEqualAfterSimplification("(not 0.0)", "1.0"); 128 // nested nots 129 AssertEqualAfterSimplification("(not (not 1.0))", "1.0"); 130 // not of non-Boolean argument 131 AssertEqualAfterSimplification("(not (variable 1.0 a))", "(not (> (variable 1.0 a) 0.0))"); 132 // not Boolean argument 133 AssertEqualAfterSimplification("(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))", "(not (and (> (variable 1.0 a) 0.0) (> (variable 1.0 a) 0.0)))"); 134 #endregion 135 304 136 #region conditionals 305 { 306 // always false 307 var actualTree = simplifier.Simplify(importer.Import("(if -1.0 (variable 2.0 a) (variable 3.0 a))")); 308 var expectedTree = importer.Import("(variable 3.0 a)"); 309 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 310 } 311 { 312 // always true 313 var actualTree = simplifier.Simplify(importer.Import("(if 1.0 (variable 2.0 a) (variable 3.0 a))")); 314 var expectedTree = importer.Import("(variable 2.0 a)"); 315 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 316 } 317 { 318 // always false (0.0) 319 var actualTree = simplifier.Simplify(importer.Import("(if 0.0 (variable 2.0 a) (variable 3.0 a))")); 320 var expectedTree = importer.Import("(variable 3.0 a)"); 321 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 322 } 323 { 324 // complex constant condition (always false) 325 var actualTree = simplifier.Simplify(importer.Import("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))")); 326 var expectedTree = importer.Import("(variable 3.0 a)"); 327 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 328 } 329 { 330 // complex constant condition (always false) 331 var actualTree = simplifier.Simplify(importer.Import("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))")); 332 var expectedTree = importer.Import("(variable 3.0 a)"); 333 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 334 } 335 { 336 // insertion of relational operator 337 var actualTree = simplifier.Simplify(importer.Import("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))")); 338 var expectedTree = importer.Import("(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))"); 339 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 340 } 137 // always false 138 AssertEqualAfterSimplification("(if -1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)"); 139 // always true 140 AssertEqualAfterSimplification("(if 1.0 (variable 2.0 a) (variable 3.0 a))", "(variable 2.0 a)"); 141 // always false (0.0) 142 AssertEqualAfterSimplification("(if 0.0 (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)"); 143 // complex constant condition (always false) 144 AssertEqualAfterSimplification("(if (* 1.0 -2.0) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)"); 145 // complex constant condition (always false) 146 AssertEqualAfterSimplification("(if (/ (variable 1.0 a) (variable -2.0 a)) (variable 2.0 a) (variable 3.0 a))", "(variable 3.0 a)"); 147 // insertion of relational operator 148 AssertEqualAfterSimplification("(if (variable 1.0 a) (variable 2.0 a) (variable 3.0 a))", "(if (> (variable 1.0 a) 0.0) (variable 2.0 a) (variable 3.0 a))"); 149 #endregion 150 151 #region factor variables 152 AssertEqualAfterSimplification("(factor a 1.0)", "(factor a 1.0)"); 153 // factor folding 154 AssertEqualAfterSimplification("(+ (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a 3.0 4.0)"); 155 AssertEqualAfterSimplification("(- (factor a 1.0 1.0) (factor a 2.0 3.0))", "(factor a -1.0 -2.0)"); 156 AssertEqualAfterSimplification("(* (factor a 2.0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 6.0)"); 157 AssertEqualAfterSimplification("(/ (factor a 2.0 5.0))", "(factor a 0.5 0.2)"); 158 AssertEqualAfterSimplification("(/ (factor a 4.0 6.0) (factor a 2.0 3.0))", "(factor a 2.0 2.0)"); 159 AssertEqualAfterSimplification("(+ 3.0 (factor a 4.0 6.0))", "(factor a 7.0 9.0)"); 160 AssertEqualAfterSimplification("(+ (factor a 4.0 6.0) 3.0)", "(factor a 7.0 9.0)"); 161 AssertEqualAfterSimplification("(* 2.0 (factor a 4.0 6.0))", "(factor a 8.0 12.0)"); 162 AssertEqualAfterSimplification("(* (factor a 4.0 6.0) 2.0)", "(factor a 8.0 12.0)"); 163 AssertEqualAfterSimplification("(* (factor a 4.0 6.0) (variable 2.0 a))", "(* (factor a 4.0 6.0) (variable 2.0 a))"); // not possible 164 AssertEqualAfterSimplification( 165 "(log (factor a 10.0 100.0))", 166 string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Log(10.0), Math.Log(100.0))); 167 AssertEqualAfterSimplification( 168 "(exp (factor a 2.0 3.0))", 169 string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1})", Math.Exp(2.0), Math.Exp(3.0))); 170 AssertEqualAfterSimplification("(sqrt (factor a 9.0 16.0))", "(factor a 3.0 4.0))"); 171 AssertEqualAfterSimplification("(sqr (factor a 2.0 3.0))", "(factor a 4.0 9.0))"); 172 AssertEqualAfterSimplification("(root (factor a 8.0 27.0) 3)", "(factor a 2.0 3.0))"); 173 AssertEqualAfterSimplification("(power (factor a 2.0 3.0) 3)", "(factor a 8.0 27.0))"); 174 175 AssertEqualAfterSimplification("(sin (factor a 1.0 2.0) )", 176 string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Sin(1.0), Math.Sin(2.0))); 177 AssertEqualAfterSimplification("(cos (factor a 1.0 2.0) )", 178 string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Cos(1.0), Math.Cos(2.0))); 179 AssertEqualAfterSimplification("(tan (factor a 1.0 2.0) )", 180 string.Format(CultureInfo.InvariantCulture, "(factor a {0} {1}))", Math.Tan(1.0), Math.Tan(2.0))); 181 182 183 AssertEqualAfterSimplification("(binfactor a val 1.0)", "(binfactor a val 1.0)"); 184 // binfactor folding 185 AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val 3.0)"); 186 AssertEqualAfterSimplification("(+ (binfactor a val0 1.0) (binfactor a val1 2.0))", "(+ (binfactor a val0 1.0) (binfactor a val1 2.0))"); // cannot be simplified (different vals) 187 AssertEqualAfterSimplification("(+ (binfactor a val 1.0) (binfactor b val 2.0))", "(+ (binfactor a val 1.0) (binfactor b val 2.0))"); // cannot be simplified (different vars) 188 AssertEqualAfterSimplification("(- (binfactor a val 1.0) (binfactor a val 2.0))", "(binfactor a val -1.0)"); 189 AssertEqualAfterSimplification("(* (binfactor a val 2.0) (binfactor a val 3.0))", "(binfactor a val 6.0)"); 190 AssertEqualAfterSimplification("(/ (binfactor a val 6.0) (binfactor a val 3.0))", "(binfactor a val 2.0)"); 191 AssertEqualAfterSimplification("(/ (binfactor a val 4.0))", "(binfactor a val 0.25)"); 192 193 AssertEqualAfterSimplification("(+ 3.0 (binfactor a val 4.0 ))", "(binfactor a val 7.0 )"); 194 AssertEqualAfterSimplification("(+ (binfactor a val 4.0 ) 3.0)", "(binfactor a val 7.0 )"); 195 AssertEqualAfterSimplification("(* 2.0 (binfactor a val 4.0))", "(binfactor a val 8.0 )"); 196 AssertEqualAfterSimplification("(* (binfactor a val 4.0) 2.0)", "(binfactor a val 8.0 )"); 197 198 // TODO same set of functions as for factor symbols 199 200 // combination of factor and binfactor 201 // TODO: should we support this? 202 AssertEqualAfterSimplification("(+ (binfactor a x0 2.0) (factor a 2.0 3.0))", "(factor a 4.0 3.0)"); 341 203 #endregion 342 204 } 343 205 344 private void AssertEqualEnumerations(IEnumerable<double> expected, IEnumerable<double> actual) { 345 var expectedEnumerator = expected.GetEnumerator(); 346 var actualEnumerator = actual.GetEnumerator(); 347 while (expectedEnumerator.MoveNext() & actualEnumerator.MoveNext()) { 348 Assert.AreEqual(expectedEnumerator.Current, actualEnumerator.Current, Math.Abs(1E-6 * expectedEnumerator.Current)); 349 } 350 if (expectedEnumerator.MoveNext() | actualEnumerator.MoveNext()) 351 Assert.Fail("Number of elements in enumerations do not match"); 206 207 private void AssertEqualAfterSimplification(string original, string expected) { 208 var simplifier = new SymbolicDataAnalysisExpressionTreeSimplifier(); 209 var formatter = new SymbolicExpressionTreeStringFormatter(); 210 var importer = new SymbolicExpressionImporter(); 211 var actualTree = simplifier.Simplify(importer.Import(original)); 212 var expectedTree = importer.Import(expected); 213 Assert.AreEqual(formatter.Format(expectedTree), formatter.Format(actualTree)); 214 352 215 } 353 216 } 354 217 } 218
Note: See TracChangeset
for help on using the changeset viewer.