Changeset 9292
- Timestamp:
- 03/07/13 14:49:11 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.DataAnalysis.Symbolic.LinearInterpreter/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeLinearInterpreter.cs
r9290 r9292 124 124 } 125 125 126 double[] values = new double[code.Length];127 128 126 foreach (var rowEnum in rows) { 129 127 int row = rowEnum; 130 yield return Evaluate(dataset, ref row, code , values);128 yield return Evaluate(dataset, ref row, code); 131 129 } 132 130 } 133 131 134 protected virtual double Evaluate(Dataset dataset, ref int row, Instruction[] code , double[] values) {132 protected virtual double Evaluate(Dataset dataset, ref int row, Instruction[] code) { 135 133 int count = 0; 136 134 for (int j = 0; j != code.Length; ++j) { 137 135 Instruction currentInstr = code[j]; 138 139 #region switch 136 int narg = currentInstr.nArguments; 137 140 138 switch (currentInstr.opCode) { 141 139 case OpCodes.Add: { 142 double s = values[j - currentInstr.nArguments];143 for (int i = j - currentInstr.nArguments+ 1; i < j; i++) {144 s += values[i];145 } 146 values[j]= s;140 double s = code[j - narg].value; 141 for (int i = j - narg + 1; i < j; i++) { 142 s += code[i].value; 143 } 144 currentInstr.value = s; 147 145 } 148 146 break; 149 147 case OpCodes.Sub: { 150 double s = values[j - currentInstr.nArguments];151 for (int i = j - currentInstr.nArguments+ 1; i < j; i++) {152 s -= values[i];153 } 154 if ( currentInstr.nArguments== 1) s = -s;155 values[j]= s;148 double s = code[j - narg].value; 149 for (int i = j - narg + 1; i < j; i++) { 150 s -= code[i].value; 151 } 152 if (narg == 1) s = -s; 153 currentInstr.value = s; 156 154 } 157 155 break; 158 156 case OpCodes.Mul: { 159 double p = values[j - currentInstr.nArguments];160 for (int i = j - currentInstr.nArguments+ 1; i < j; i++) {161 p *= values[i];162 } 163 values[j]= p;157 double p = code[j - narg].value; 158 for (int i = j - narg + 1; i < j; i++) { 159 p *= code[i].value; 160 } 161 currentInstr.value = p; 164 162 } 165 163 break; 166 164 case OpCodes.Div: { 167 double p = values[j - currentInstr.nArguments];168 for (int i = j - currentInstr.nArguments+ 1; i < j; i++) {169 p /= values[i];170 } 171 if ( currentInstr.nArguments== 1) p = 1.0 / p;172 values[j]= p;165 double p = code[j - narg].value; 166 for (int i = j - narg + 1; i < j; i++) { 167 p /= code[i].value; 168 } 169 if (narg == 1) p = 1.0 / p; 170 currentInstr.value = p; 173 171 } 174 172 break; 175 173 case OpCodes.Average: { 176 double sum = values[j - currentInstr.nArguments];177 for (int i = j - currentInstr.nArguments+ 1; i < j; i++) {178 sum += values[i];179 } 180 values[j] = sum / currentInstr.nArguments;174 double sum = code[j - narg].value; 175 for (int i = j - narg + 1; i < j; i++) { 176 sum += code[i].value; 177 } 178 currentInstr.value = sum / narg; 181 179 } 182 180 break; 183 181 case OpCodes.Cos: { 184 values[j] = Math.Cos(values[j - currentInstr.nArguments]);182 currentInstr.value = Math.Cos(code[j - 1].value); 185 183 } 186 184 break; 187 185 case OpCodes.Sin: { 188 values[j] = Math.Sin(values[j - currentInstr.nArguments]);186 currentInstr.value = Math.Sin(code[j - 1].value); 189 187 break; 190 188 } 191 189 case OpCodes.Tan: { 192 values[j] = Math.Tan(values[j - currentInstr.nArguments]);190 currentInstr.value = Math.Tan(code[j - 1].value); 193 191 } 194 192 break; 195 193 case OpCodes.Square: { 196 values[j] = Math.Pow(values[j - currentInstr.nArguments], 2);194 currentInstr.value = Math.Pow(code[j - 1].value, 2); 197 195 } 198 196 break; 199 197 case OpCodes.Power: { 200 double x = values[j - currentInstr.nArguments];201 double y = Math.Round( values[j - currentInstr.nArguments + 1]);202 values[j]= Math.Pow(x, y);198 double x = code[j - 2].value; 199 double y = Math.Round(code[j - 1].value); 200 currentInstr.value = Math.Pow(x, y); 203 201 } 204 202 break; 205 203 case OpCodes.SquareRoot: { 206 values[j] = Math.Sqrt(values[j - currentInstr.nArguments]);204 currentInstr.value = Math.Sqrt(code[j - 1].value); 207 205 } 208 206 break; 209 207 case OpCodes.Root: { 210 double x = values[j - currentInstr.nArguments];211 double y = Math.Round( values[j - currentInstr.nArguments + 1]);212 values[j]= Math.Pow(x, 1 / y);208 double x = code[j - 2].value; 209 double y = Math.Round(code[j - 1].value); 210 currentInstr.value = Math.Pow(x, 1 / y); 213 211 } 214 212 break; 215 213 case OpCodes.Exp: { 216 values[j] = Math.Exp(values[j - currentInstr.nArguments]);214 currentInstr.value = Math.Exp(code[j - 1].value); 217 215 } 218 216 break; 219 217 case OpCodes.Log: { 220 values[j] = Math.Log(values[j - currentInstr.nArguments]);218 currentInstr.value = Math.Log(code[j - 1].value); 221 219 } 222 220 break; 223 221 case OpCodes.Gamma: { 224 values[j] = double.IsNaN(values[j - currentInstr.nArguments]) ? double.NaN : alglib.gammafunction(values[j - currentInstr.nArguments]);222 currentInstr.value = double.IsNaN(code[j - 1].value) ? double.NaN : alglib.gammafunction(code[j - 1].value); 225 223 } 226 224 break; 227 225 case OpCodes.Psi: { 228 var x = values[j - currentInstr.nArguments];229 if (double.IsNaN(x)) values[j]= double.NaN;230 else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) values[j]= double.NaN;231 else values[j]= alglib.psi(x);226 var x = code[j - 1].value; 227 if (double.IsNaN(x)) currentInstr.value = double.NaN; 228 else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) currentInstr.value = double.NaN; 229 else currentInstr.value = alglib.psi(x); 232 230 } 233 231 break; 234 232 case OpCodes.Dawson: { 235 var x = values[j - currentInstr.nArguments];236 values[j]= double.IsNaN(x) ? double.NaN : alglib.dawsonintegral(x);233 var x = code[j - 1].value; 234 currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.dawsonintegral(x); 237 235 } 238 236 break; 239 237 case OpCodes.ExponentialIntegralEi: { 240 var x = values[j - currentInstr.nArguments];241 values[j]= double.IsNaN(x) ? double.NaN : alglib.exponentialintegralei(x);238 var x = code[j - 1].value; 239 currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.exponentialintegralei(x); 242 240 } 243 241 break; 244 242 case OpCodes.SineIntegral: { 245 243 double si, ci; 246 var x = values[j - currentInstr.nArguments];247 if (double.IsNaN(x)) values[j]= double.NaN;244 var x = code[j - 1].value; 245 if (double.IsNaN(x)) currentInstr.value = double.NaN; 248 246 else { 249 247 alglib.sinecosineintegrals(x, out si, out ci); 250 values[j]= si;248 currentInstr.value = si; 251 249 } 252 250 } … … 254 252 case OpCodes.CosineIntegral: { 255 253 double si, ci; 256 var x = values[j - currentInstr.nArguments];257 if (double.IsNaN(x)) values[j]= double.NaN;254 var x = code[j - 1].value; 255 if (double.IsNaN(x)) currentInstr.value = double.NaN; 258 256 else { 259 257 alglib.sinecosineintegrals(x, out si, out ci); 260 values[j]= ci;258 currentInstr.value = ci; 261 259 } 262 260 } … … 264 262 case OpCodes.HyperbolicSineIntegral: { 265 263 double shi, chi; 266 var x = values[j - currentInstr.nArguments];267 if (double.IsNaN(x)) values[j]= double.NaN;264 var x = code[j - 1].value; 265 if (double.IsNaN(x)) currentInstr.value = double.NaN; 268 266 else { 269 267 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi); 270 values[j]= shi;268 currentInstr.value = shi; 271 269 } 272 270 } … … 274 272 case OpCodes.HyperbolicCosineIntegral: { 275 273 double shi, chi; 276 var x = values[j - currentInstr.nArguments];277 if (double.IsNaN(x)) values[j]= double.NaN;274 var x = code[j - 1].value; 275 if (double.IsNaN(x)) currentInstr.value = double.NaN; 278 276 else { 279 277 alglib.hyperbolicsinecosineintegrals(x, out shi, out chi); 280 values[j]= chi;278 currentInstr.value = chi; 281 279 } 282 280 } … … 284 282 case OpCodes.FresnelCosineIntegral: { 285 283 double c = 0, s = 0; 286 var x = values[j - currentInstr.nArguments];287 if (double.IsNaN(x)) values[j]= double.NaN;284 var x = code[j - 1].value; 285 if (double.IsNaN(x)) currentInstr.value = double.NaN; 288 286 else { 289 287 alglib.fresnelintegral(x, ref c, ref s); 290 values[j]= c;288 currentInstr.value = c; 291 289 } 292 290 } … … 294 292 case OpCodes.FresnelSineIntegral: { 295 293 double c = 0, s = 0; 296 var x = values[j - currentInstr.nArguments];297 if (double.IsNaN(x)) values[j]= double.NaN;294 var x = code[j - 1].value; 295 if (double.IsNaN(x)) currentInstr.value = double.NaN; 298 296 else { 299 297 alglib.fresnelintegral(x, ref c, ref s); 300 values[j]= s;298 currentInstr.value = s; 301 299 } 302 300 } … … 304 302 case OpCodes.AiryA: { 305 303 double ai, aip, bi, bip; 306 var x = values[j - currentInstr.nArguments];307 if (double.IsNaN(x)) values[j]= double.NaN;304 var x = code[j - 1].value; 305 if (double.IsNaN(x)) currentInstr.value = double.NaN; 308 306 else { 309 307 alglib.airy(x, out ai, out aip, out bi, out bip); 310 values[j]= ai;308 currentInstr.value = ai; 311 309 } 312 310 } … … 314 312 case OpCodes.AiryB: { 315 313 double ai, aip, bi, bip; 316 var x = values[j - currentInstr.nArguments];317 if (double.IsNaN(x)) values[j]= double.NaN;314 var x = code[j - 1].value; 315 if (double.IsNaN(x)) currentInstr.value = double.NaN; 318 316 else { 319 317 alglib.airy(x, out ai, out aip, out bi, out bip); 320 values[j]= bi;318 currentInstr.value = bi; 321 319 } 322 320 } 323 321 break; 324 322 case OpCodes.Norm: { 325 var x = values[j - currentInstr.nArguments];326 values[j]= double.IsNaN(x) ? double.NaN : alglib.normaldistribution(x);323 var x = code[j - 1].value; 324 currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.normaldistribution(x); 327 325 } 328 326 break; 329 327 case OpCodes.Erf: { 330 var x = values[j - currentInstr.nArguments];331 values[j]= double.IsNaN(x) ? double.NaN : alglib.errorfunction(x);328 var x = code[j - 1].value; 329 currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.errorfunction(x); 332 330 } 333 331 break; 334 332 case OpCodes.Bessel: { 335 var x = values[j - currentInstr.nArguments];336 values[j]= double.IsNaN(x) ? double.NaN : alglib.besseli0(x);333 var x = code[j - 1].value; 334 currentInstr.value = double.IsNaN(x) ? double.NaN : alglib.besseli0(x); 337 335 } 338 336 break; 339 337 case OpCodes.IfThenElse: { 340 double condition = values[j - currentInstr.nArguments];341 double result = condition > 0.0 ? values[j - currentInstr.nArguments] : values[j - currentInstr.nArguments + 1];342 values[j]= result;338 double condition = code[j - narg].value; 339 double result = condition > 0.0 ? code[j - 2].value : code[j - 1].value; 340 currentInstr.value = result; 343 341 } 344 342 break; 345 343 case OpCodes.AND: { 346 double result = values[j - currentInstr.nArguments];347 for (int i = j - currentInstr.nArguments+ 1; i < j; i++) {348 if (result > 0.0) result = values[i];349 } 350 values[j]= result > 0.0 ? 1.0 : -1.0;344 double result = code[j - narg].value; 345 for (int i = j - narg + 1; i < j; i++) { 346 if (result > 0.0) result = code[i].value; 347 } 348 currentInstr.value = result > 0.0 ? 1.0 : -1.0; 351 349 } 352 350 break; 353 351 case OpCodes.OR: { 354 double result = values[j - currentInstr.nArguments];355 for (int i = 1; i < currentInstr.nArguments; i++) {356 if (result <= 0.0) result = values[i]; ;357 } 358 values[j]= result > 0.0 ? 1.0 : -1.0;352 double result = code[j - narg].value; 353 for (int i = j - narg + 1; i < j; i++) { 354 if (result <= 0.0) result = code[i].value; ; 355 } 356 currentInstr.value = result > 0.0 ? 1.0 : -1.0; 359 357 } 360 358 break; 361 359 case OpCodes.NOT: { 362 values[j] = values[j - currentInstr.nArguments]> 0.0 ? -1.0 : 1.0;360 currentInstr.value = code[j - 1].value > 0.0 ? -1.0 : 1.0; 363 361 } 364 362 break; 365 363 case OpCodes.GT: { 366 double x = values[j - currentInstr.nArguments];367 double y = values[j - currentInstr.nArguments + 1];368 values[j]= x > y ? 1.0 : -1.0;364 double x = code[j - 2].value; 365 double y = code[j - 1].value; 366 currentInstr.value = x > y ? 1.0 : -1.0; 369 367 } 370 368 break; 371 369 case OpCodes.LT: { 372 double x = values[j - currentInstr.nArguments];373 double y = values[j - currentInstr.nArguments + 1];374 values[j]= x < y ? 1.0 : -1.0;370 double x = code[j - 2].value; 371 double y = code[j - 1].value; 372 currentInstr.value = x < y ? 1.0 : -1.0; 375 373 } 376 374 break; … … 396 394 } 397 395 case OpCodes.Variable: { 398 if (row < 0 || row >= dataset.Rows) values[j]= double.NaN;396 if (row < 0 || row >= dataset.Rows) currentInstr.value = double.NaN; 399 397 else { 400 398 var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode; 401 values[j]= ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;399 currentInstr.value = ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight; 402 400 } 403 401 } … … 406 404 var laggedVariableTreeNode = (LaggedVariableTreeNode)currentInstr.dynamicNode; 407 405 int actualRow = row + laggedVariableTreeNode.Lag; 408 if (actualRow < 0 || actualRow >= dataset.Rows) values[j]= double.NaN;409 else { 410 values[j]= ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;406 if (actualRow < 0 || actualRow >= dataset.Rows) currentInstr.value = double.NaN; 407 else { 408 currentInstr.value = ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight; 411 409 } 412 410 } … … 414 412 case OpCodes.Constant: { 415 413 var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode; 416 values[j]= constTreeNode.Value;414 currentInstr.value = constTreeNode.Value; 417 415 } 418 416 break; … … 421 419 //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function 422 420 case OpCodes.VariableCondition: { 423 if (row < 0 || row >= dataset.Rows) values[j]= double.NaN;421 if (row < 0 || row >= dataset.Rows) currentInstr.value = double.NaN; 424 422 else { 425 423 var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode; … … 428 426 double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x)); 429 427 430 double trueBranch = values[j - currentInstr.nArguments];431 double falseBranch = values[j - currentInstr.nArguments + 1];432 433 values[j]= trueBranch * p + falseBranch * (1 - p);428 double trueBranch = code[j - narg].value; 429 double falseBranch = code[j - narg + 1].value; 430 431 currentInstr.value = trueBranch * p + falseBranch * (1 - p); 434 432 } 435 433 } … … 438 436 throw new NotSupportedException(); 439 437 } 440 #endregion441 442 // book-keeping in order to keep all the values correct443 int narg = currentInstr.nArguments;444 438 445 439 // we count the values before the next function is encountered … … 448 442 if (count > narg) { 449 443 for (int i = 1; i <= count - narg; ++i) 450 values[j - i] = values[j - i - narg];444 code[j - i].value = code[j - i - narg].value; 451 445 } 452 446 … … 454 448 } 455 449 456 return values[values.Length - 1];450 return code[code.Length - 1].value; 457 451 } 458 452 }
Note: See TracChangeset
for help on using the changeset viewer.