- Timestamp:
- 08/08/13 11:48:11 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r9828 r9871 118 118 for (int i = code.Length - 1; i >= 0; --i) { 119 119 if (code[i].skip) continue; 120 #region opcode switch120 #region opcode if 121 121 var instr = code[i]; 122 switch (instr.opCode) { 123 case OpCodes.Variable: { 124 if (row < 0 || row >= dataset.Rows) instr.value = double.NaN; 125 var variableTreeNode = (VariableTreeNode)instr.dynamicNode; 126 instr.value = ((IList<double>)instr.data)[row] * variableTreeNode.Weight; 127 } 128 break; 129 case OpCodes.LagVariable: { 130 var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode; 131 int actualRow = row + laggedVariableTreeNode.Lag; 132 if (actualRow < 0 || actualRow >= dataset.Rows) 133 instr.value = double.NaN; 134 else 135 instr.value = ((IList<double>)instr.data)[actualRow] * laggedVariableTreeNode.Weight; 136 } 137 break; 138 case OpCodes.VariableCondition: { 139 if (row < 0 || row >= dataset.Rows) instr.value = double.NaN; 140 var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode; 141 double variableValue = ((IList<double>)instr.data)[row]; 142 double x = variableValue - variableConditionTreeNode.Threshold; 143 double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x)); 144 145 double trueBranch = code[instr.childIndex].value; 146 double falseBranch = code[instr.childIndex + 1].value; 147 148 instr.value = trueBranch * p + falseBranch * (1 - p); 149 } 150 break; 151 case OpCodes.Add: { 152 double s = code[instr.childIndex].value; 153 for (int j = 1; j != instr.nArguments; ++j) { 154 s += code[instr.childIndex + j].value; 155 } 156 instr.value = s; 157 } 158 break; 159 case OpCodes.Sub: { 160 double s = code[instr.childIndex].value; 161 for (int j = 1; j != instr.nArguments; ++j) { 162 s -= code[instr.childIndex + j].value; 163 } 164 if (instr.nArguments == 1) s = -s; 165 instr.value = s; 166 } 167 break; 168 case OpCodes.Mul: { 169 double p = code[instr.childIndex].value; 170 for (int j = 1; j != instr.nArguments; ++j) { 171 p *= code[instr.childIndex + j].value; 172 } 173 instr.value = p; 174 } 175 break; 176 case OpCodes.Div: { 177 double p = code[instr.childIndex].value; 178 for (int j = 1; j != instr.nArguments; ++j) { 179 p /= code[instr.childIndex + j].value; 180 } 181 if (instr.nArguments == 1) p = 1.0 / p; 182 instr.value = p; 183 } 184 break; 185 case OpCodes.Average: { 186 double s = code[instr.childIndex].value; 187 for (int j = 1; j != instr.nArguments; ++j) { 188 s += code[instr.childIndex + j].value; 189 } 190 instr.value = s / instr.nArguments; 191 } 192 break; 193 case OpCodes.Cos: { 194 instr.value = Math.Cos(code[instr.childIndex].value); 195 } 196 break; 197 case OpCodes.Sin: { 198 instr.value = Math.Sin(code[instr.childIndex].value); 199 } 200 break; 201 case OpCodes.Tan: { 202 instr.value = Math.Tan(code[instr.childIndex].value); 203 } 204 break; 205 case OpCodes.Square: { 206 instr.value = Math.Pow(code[instr.childIndex].value, 2); 207 } 208 break; 209 case OpCodes.Power: { 210 double x = code[instr.childIndex].value; 211 double y = Math.Round(code[instr.childIndex + 1].value); 212 instr.value = Math.Pow(x, y); 213 } 214 break; 215 case OpCodes.SquareRoot: { 216 instr.value = Math.Sqrt(code[instr.childIndex].value); 217 } 218 break; 219 case OpCodes.Root: { 220 double x = code[instr.childIndex].value; 221 double y = code[instr.childIndex + 1].value; 222 instr.value = Math.Pow(x, 1 / y); 223 } 224 break; 225 case OpCodes.Exp: { 226 instr.value = Math.Exp(code[instr.childIndex].value); 227 } 228 break; 229 case OpCodes.Log: { 230 instr.value = Math.Log(code[instr.childIndex].value); 231 } 232 break; 233 case OpCodes.Gamma: { 234 var x = code[instr.childIndex].value; 235 instr.value = double.IsNaN(x) ? double.NaN : alglib.gammafunction(x); 236 } 237 break; 238 case OpCodes.Psi: { 239 var x = code[instr.childIndex].value; 240 if (double.IsNaN(x)) instr.value = double.NaN; 241 else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) instr.value = double.NaN; 242 else instr.value = alglib.psi(x); 243 } 244 break; 245 case OpCodes.Dawson: { 246 var x = code[instr.childIndex].value; 247 instr.value = double.IsNaN(x) ? double.NaN : alglib.dawsonintegral(x); 248 } 249 break; 250 case OpCodes.ExponentialIntegralEi: { 251 var x = code[instr.childIndex].value; 252 instr.value = double.IsNaN(x) ? double.NaN : alglib.exponentialintegralei(x); 253 } 254 break; 255 case OpCodes.SineIntegral: { 256 double si, ci; 257 var x = code[instr.childIndex].value; 258 if (double.IsNaN(x)) instr.value = double.NaN; 259 else { 260 alglib.sinecosineintegrals(x, out si, out ci); 261 instr.value = si; 262 } 263 } 264 break; 265 case OpCodes.CosineIntegral: { 266 double si, ci; 267 var x = code[instr.childIndex].value; 268 if (double.IsNaN(x)) instr.value = double.NaN; 269 else { 270 alglib.sinecosineintegrals(x, out si, out ci); 271 instr.value = ci; 272 } 273 } 274 break; 275 case OpCodes.HyperbolicSineIntegral: { 276 double shi, chi; 277 var x = code[instr.childIndex].value; 278 if (double.IsNaN(x)) instr.value = double.NaN; 279 else { 280 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi); 281 instr.value = shi; 282 } 283 } 284 break; 285 case OpCodes.HyperbolicCosineIntegral: { 286 double shi, chi; 287 var x = code[instr.childIndex].value; 288 if (double.IsNaN(x)) instr.value = double.NaN; 289 else { 290 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi); 291 instr.value = chi; 292 } 293 } 294 break; 295 case OpCodes.FresnelCosineIntegral: { 296 double c = 0, s = 0; 297 var x = code[instr.childIndex].value; 298 if (double.IsNaN(x)) instr.value = double.NaN; 299 else { 300 alglib.fresnelintegral(x, ref c, ref s); 301 instr.value = c; 302 } 303 } 304 break; 305 case OpCodes.FresnelSineIntegral: { 306 double c = 0, s = 0; 307 var x = code[instr.childIndex].value; 308 if (double.IsNaN(x)) instr.value = double.NaN; 309 else { 310 alglib.fresnelintegral(x, ref c, ref s); 311 instr.value = s; 312 } 313 } 314 break; 315 case OpCodes.AiryA: { 316 double ai, aip, bi, bip; 317 var x = code[instr.childIndex].value; 318 if (double.IsNaN(x)) instr.value = double.NaN; 319 else { 320 alglib.airy(x, out ai, out aip, out bi, out bip); 321 instr.value = ai; 322 } 323 } 324 break; 325 case OpCodes.AiryB: { 326 double ai, aip, bi, bip; 327 var x = code[instr.childIndex].value; 328 if (double.IsNaN(x)) instr.value = double.NaN; 329 else { 330 alglib.airy(x, out ai, out aip, out bi, out bip); 331 instr.value = bi; 332 } 333 } 334 break; 335 case OpCodes.Norm: { 336 var x = code[instr.childIndex].value; 337 if (double.IsNaN(x)) instr.value = double.NaN; 338 else instr.value = alglib.normaldistribution(x); 339 } 340 break; 341 case OpCodes.Erf: { 342 var x = code[instr.childIndex].value; 343 if (double.IsNaN(x)) instr.value = double.NaN; 344 else instr.value = alglib.errorfunction(x); 345 } 346 break; 347 case OpCodes.Bessel: { 348 var x = code[instr.childIndex].value; 349 if (double.IsNaN(x)) instr.value = double.NaN; 350 else instr.value = alglib.besseli0(x); 351 } 352 break; 353 case OpCodes.IfThenElse: { 354 double condition = code[instr.childIndex].value; 355 double result; 356 if (condition > 0.0) { 357 result = code[instr.childIndex + 1].value; 358 } else { 359 result = code[instr.childIndex + 2].value; 360 } 361 instr.value = result; 362 } 363 break; 364 case OpCodes.AND: { 365 double result = code[instr.childIndex].value; 366 for (int j = 1; j < instr.nArguments; j++) { 367 if (result > 0.0) result = code[instr.childIndex + j].value; 368 else break; 369 } 370 instr.value = result > 0.0 ? 1.0 : -1.0; 371 } 372 break; 373 case OpCodes.OR: { 374 double result = code[instr.childIndex].value; 375 for (int j = 1; j < instr.nArguments; j++) { 376 if (result <= 0.0) result = code[instr.childIndex + j].value; 377 else break; 378 } 379 instr.value = result > 0.0 ? 1.0 : -1.0; 380 } 381 break; 382 case OpCodes.NOT: { 383 instr.value = code[instr.childIndex].value > 0.0 ? -1.0 : 1.0; 384 } 385 break; 386 case OpCodes.GT: { 387 double x = code[instr.childIndex].value; 388 double y = code[instr.childIndex + 1].value; 389 instr.value = x > y ? 1.0 : -1.0; 390 } 391 break; 392 case OpCodes.LT: { 393 double x = code[instr.childIndex].value; 394 double y = code[instr.childIndex + 1].value; 395 instr.value = x < y ? 1.0 : -1.0; 396 } 397 break; 398 case OpCodes.TimeLag: 399 case OpCodes.Integral: 400 case OpCodes.Derivative: { 401 var state = (InterpreterState)instr.data; 402 state.Reset(); 403 instr.value = interpreter.Evaluate(dataset, ref row, state); 404 } 405 break; 406 default: 407 var errorText = string.Format("The {0} symbol is not supported by the linear interpreter. To support this symbol, please use the SymbolicDataAnalysisExpressionTreeInterpreter.", instr.dynamicNode.Symbol.Name); 408 throw new NotSupportedException(errorText); 122 if (instr.opCode == OpCodes.Variable) { 123 if (row < 0 || row >= dataset.Rows) instr.value = double.NaN; 124 var variableTreeNode = (VariableTreeNode)instr.dynamicNode; 125 instr.value = ((IList<double>)instr.data)[row] * variableTreeNode.Weight; 126 } else if (instr.opCode == OpCodes.LagVariable) { 127 var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode; 128 int actualRow = row + laggedVariableTreeNode.Lag; 129 if (actualRow < 0 || actualRow >= dataset.Rows) 130 instr.value = double.NaN; 131 else 132 instr.value = ((IList<double>)instr.data)[actualRow] * laggedVariableTreeNode.Weight; 133 } else if (instr.opCode == OpCodes.VariableCondition) { 134 if (row < 0 || row >= dataset.Rows) instr.value = double.NaN; 135 var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode; 136 double variableValue = ((IList<double>)instr.data)[row]; 137 double x = variableValue - variableConditionTreeNode.Threshold; 138 double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x)); 139 140 double trueBranch = code[instr.childIndex].value; 141 double falseBranch = code[instr.childIndex + 1].value; 142 143 instr.value = trueBranch * p + falseBranch * (1 - p); 144 } else if (instr.opCode == OpCodes.Add) { 145 double s = code[instr.childIndex].value; 146 for (int j = 1; j != instr.nArguments; ++j) { 147 s += code[instr.childIndex + j].value; 148 } 149 instr.value = s; 150 } else if (instr.opCode == OpCodes.Sub) { 151 double s = code[instr.childIndex].value; 152 for (int j = 1; j != instr.nArguments; ++j) { 153 s -= code[instr.childIndex + j].value; 154 } 155 if (instr.nArguments == 1) s = -s; 156 instr.value = s; 157 } else if (instr.opCode == OpCodes.Mul) { 158 double p = code[instr.childIndex].value; 159 for (int j = 1; j != instr.nArguments; ++j) { 160 p *= code[instr.childIndex + j].value; 161 } 162 instr.value = p; 163 } else if (instr.opCode == OpCodes.Div) { 164 double p = code[instr.childIndex].value; 165 for (int j = 1; j != instr.nArguments; ++j) { 166 p /= code[instr.childIndex + j].value; 167 } 168 if (instr.nArguments == 1) p = 1.0 / p; 169 instr.value = p; 170 } else if (instr.opCode == OpCodes.Average) { 171 double s = code[instr.childIndex].value; 172 for (int j = 1; j != instr.nArguments; ++j) { 173 s += code[instr.childIndex + j].value; 174 } 175 instr.value = s / instr.nArguments; 176 } else if (instr.opCode == OpCodes.Cos) { 177 instr.value = Math.Cos(code[instr.childIndex].value); 178 } else if (instr.opCode == OpCodes.Sin) { 179 instr.value = Math.Sin(code[instr.childIndex].value); 180 } else if (instr.opCode == OpCodes.Tan) { 181 instr.value = Math.Tan(code[instr.childIndex].value); 182 } else if (instr.opCode == OpCodes.Square) { 183 instr.value = Math.Pow(code[instr.childIndex].value, 2); 184 } else if (instr.opCode == OpCodes.Power) { 185 double x = code[instr.childIndex].value; 186 double y = Math.Round(code[instr.childIndex + 1].value); 187 instr.value = Math.Pow(x, y); 188 } else if (instr.opCode == OpCodes.SquareRoot) { 189 instr.value = Math.Sqrt(code[instr.childIndex].value); 190 } else if (instr.opCode == OpCodes.Root) { 191 double x = code[instr.childIndex].value; 192 double y = code[instr.childIndex + 1].value; 193 instr.value = Math.Pow(x, 1 / y); 194 } else if (instr.opCode == OpCodes.Exp) { 195 instr.value = Math.Exp(code[instr.childIndex].value); 196 } else if (instr.opCode == OpCodes.Log) { 197 instr.value = Math.Log(code[instr.childIndex].value); 198 } else if (instr.opCode == OpCodes.Gamma) { 199 var x = code[instr.childIndex].value; 200 instr.value = double.IsNaN(x) ? double.NaN : alglib.gammafunction(x); 201 } else if (instr.opCode == OpCodes.Psi) { 202 var x = code[instr.childIndex].value; 203 if (double.IsNaN(x)) instr.value = double.NaN; 204 else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) instr.value = double.NaN; 205 else instr.value = alglib.psi(x); 206 } else if (instr.opCode == OpCodes.Dawson) { 207 var x = code[instr.childIndex].value; 208 instr.value = double.IsNaN(x) ? double.NaN : alglib.dawsonintegral(x); 209 } else if (instr.opCode == OpCodes.ExponentialIntegralEi) { 210 var x = code[instr.childIndex].value; 211 instr.value = double.IsNaN(x) ? double.NaN : alglib.exponentialintegralei(x); 212 } else if (instr.opCode == OpCodes.SineIntegral) { 213 double si, ci; 214 var x = code[instr.childIndex].value; 215 if (double.IsNaN(x)) instr.value = double.NaN; 216 else { 217 alglib.sinecosineintegrals(x, out si, out ci); 218 instr.value = si; 219 } 220 } else if (instr.opCode == OpCodes.CosineIntegral) { 221 double si, ci; 222 var x = code[instr.childIndex].value; 223 if (double.IsNaN(x)) instr.value = double.NaN; 224 else { 225 alglib.sinecosineintegrals(x, out si, out ci); 226 instr.value = ci; 227 } 228 } else if (instr.opCode == OpCodes.HyperbolicSineIntegral) { 229 double shi, chi; 230 var x = code[instr.childIndex].value; 231 if (double.IsNaN(x)) instr.value = double.NaN; 232 else { 233 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi); 234 instr.value = shi; 235 } 236 } else if (instr.opCode == OpCodes.HyperbolicCosineIntegral) { 237 double shi, chi; 238 var x = code[instr.childIndex].value; 239 if (double.IsNaN(x)) instr.value = double.NaN; 240 else { 241 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi); 242 instr.value = chi; 243 } 244 } else if (instr.opCode == OpCodes.FresnelCosineIntegral) { 245 double c = 0, s = 0; 246 var x = code[instr.childIndex].value; 247 if (double.IsNaN(x)) instr.value = double.NaN; 248 else { 249 alglib.fresnelintegral(x, ref c, ref s); 250 instr.value = c; 251 } 252 } else if (instr.opCode == OpCodes.FresnelSineIntegral) { 253 double c = 0, s = 0; 254 var x = code[instr.childIndex].value; 255 if (double.IsNaN(x)) instr.value = double.NaN; 256 else { 257 alglib.fresnelintegral(x, ref c, ref s); 258 instr.value = s; 259 } 260 } else if (instr.opCode == OpCodes.AiryA) { 261 double ai, aip, bi, bip; 262 var x = code[instr.childIndex].value; 263 if (double.IsNaN(x)) instr.value = double.NaN; 264 else { 265 alglib.airy(x, out ai, out aip, out bi, out bip); 266 instr.value = ai; 267 } 268 } else if (instr.opCode == OpCodes.AiryB) { 269 double ai, aip, bi, bip; 270 var x = code[instr.childIndex].value; 271 if (double.IsNaN(x)) instr.value = double.NaN; 272 else { 273 alglib.airy(x, out ai, out aip, out bi, out bip); 274 instr.value = bi; 275 } 276 } else if (instr.opCode == OpCodes.Norm) { 277 var x = code[instr.childIndex].value; 278 if (double.IsNaN(x)) instr.value = double.NaN; 279 else instr.value = alglib.normaldistribution(x); 280 } else if (instr.opCode == OpCodes.Erf) { 281 var x = code[instr.childIndex].value; 282 if (double.IsNaN(x)) instr.value = double.NaN; 283 else instr.value = alglib.errorfunction(x); 284 } else if (instr.opCode == OpCodes.Bessel) { 285 var x = code[instr.childIndex].value; 286 if (double.IsNaN(x)) instr.value = double.NaN; 287 else instr.value = alglib.besseli0(x); 288 } else if (instr.opCode == OpCodes.IfThenElse) { 289 double condition = code[instr.childIndex].value; 290 double result; 291 if (condition > 0.0) { 292 result = code[instr.childIndex + 1].value; 293 } else { 294 result = code[instr.childIndex + 2].value; 295 } 296 instr.value = result; 297 } else if (instr.opCode == OpCodes.AND) { 298 double result = code[instr.childIndex].value; 299 for (int j = 1; j < instr.nArguments; j++) { 300 if (result > 0.0) result = code[instr.childIndex + j].value; 301 else break; 302 } 303 instr.value = result > 0.0 ? 1.0 : -1.0; 304 } else if (instr.opCode == OpCodes.OR) { 305 double result = code[instr.childIndex].value; 306 for (int j = 1; j < instr.nArguments; j++) { 307 if (result <= 0.0) result = code[instr.childIndex + j].value; 308 else break; 309 } 310 instr.value = result > 0.0 ? 1.0 : -1.0; 311 } else if (instr.opCode == OpCodes.NOT) { 312 instr.value = code[instr.childIndex].value > 0.0 ? -1.0 : 1.0; 313 } else if (instr.opCode == OpCodes.GT) { 314 double x = code[instr.childIndex].value; 315 double y = code[instr.childIndex + 1].value; 316 instr.value = x > y ? 1.0 : -1.0; 317 } else if (instr.opCode == OpCodes.LT) { 318 double x = code[instr.childIndex].value; 319 double y = code[instr.childIndex + 1].value; 320 instr.value = x < y ? 1.0 : -1.0; 321 } else if (instr.opCode == OpCodes.TimeLag || instr.opCode == OpCodes.Derivative || instr.opCode == OpCodes.Integral) { 322 var state = (InterpreterState)instr.data; 323 state.Reset(); 324 instr.value = interpreter.Evaluate(dataset, ref row, state); 325 } else { 326 var errorText = string.Format("The {0} symbol is not supported by the linear interpreter. To support this symbol, please use the SymbolicDataAnalysisExpressionTreeInterpreter.", instr.dynamicNode.Symbol.Name); 327 throw new NotSupportedException(errorText); 409 328 } 410 329 #endregion
Note: See TracChangeset
for help on using the changeset viewer.