|
11 | 11 | import org.matheclipse.core.convert.VariablesSet;
|
12 | 12 | import org.matheclipse.core.eval.Errors;
|
13 | 13 | import org.matheclipse.core.eval.EvalEngine;
|
| 14 | +import org.matheclipse.core.eval.exception.LimitException; |
14 | 15 | import org.matheclipse.core.eval.exception.ValidateException;
|
15 | 16 | import org.matheclipse.core.eval.interfaces.AbstractFunctionEvaluator;
|
16 | 17 | import org.matheclipse.core.eval.util.IAssumptions;
|
@@ -308,176 +309,184 @@ private IExpr tryTransformations(IExpr expr) {
|
308 | 309 | if (!expr.isAST()) {
|
309 | 310 | return F.NIL;
|
310 | 311 | }
|
311 |
| - // try ExpandAll, Together, Apart, Factor to reduce the expression |
312 |
| - SimplifiedResult simplifiedResult = new SimplifiedResult(expr, fComplexityFunction); |
313 |
| - IExpr temp; |
314 |
| - long expandAllCounter = 0; |
315 |
| - if (expr.isTimes()) { |
316 |
| - temp = tryTimesLog((IAST) expr); |
317 |
| - if (temp.isPresent()) { |
318 |
| - simplifiedResult.checkLessEqual(temp); |
319 |
| - } |
320 |
| - } else if (expr.isPlus()) { |
321 |
| - temp = Algebra.factorTermsPlus((IAST) expr, EvalEngine.get()); |
322 |
| - if (temp.isPresent()) { |
323 |
| - simplifiedResult.checkLessEqual(temp); |
| 312 | + try { |
| 313 | + // try ExpandAll, Together, Apart, Factor to reduce the expression |
| 314 | + SimplifiedResult simplifiedResult = new SimplifiedResult(expr, fComplexityFunction); |
| 315 | + IExpr temp; |
| 316 | + long expandAllCounter = 0; |
| 317 | + if (expr.isTimes()) { |
| 318 | + temp = tryTimesLog((IAST) expr); |
| 319 | + if (temp.isPresent()) { |
| 320 | + simplifiedResult.checkLessEqual(temp); |
| 321 | + } |
| 322 | + } else if (expr.isPlus()) { |
| 323 | + temp = Algebra.factorTermsPlus((IAST) expr, EvalEngine.get()); |
| 324 | + if (temp.isPresent()) { |
| 325 | + simplifiedResult.checkLessEqual(temp); |
| 326 | + } |
| 327 | + |
| 328 | + Optional<IExpr[]> commonFactors = |
| 329 | + Algebra.InternalFindCommonFactorPlus.findCommonFactors((IAST) expr, true); |
| 330 | + if (commonFactors.isPresent()) { |
| 331 | + temp = eval(F.Times(commonFactors.get()[0], commonFactors.get()[1])); |
| 332 | + simplifiedResult.checkLessEqual(temp); |
| 333 | + } |
| 334 | + |
| 335 | + if (simplifiedResult.result.isPlus()) { |
| 336 | + temp = tryPlusLog((IAST) simplifiedResult.result); |
| 337 | + } else { |
| 338 | + temp = tryPlusLog((IAST) expr); |
| 339 | + } |
| 340 | + if (temp.isPresent()) { |
| 341 | + temp = eval(temp); |
| 342 | + simplifiedResult.checkLessEqual(temp); |
| 343 | + } |
| 344 | + // } else if (expr.isExp() && expr.second().isTimes()) { |
| 345 | + // IAST times = (IAST) expr.second(); |
| 346 | + // IExpr i = Times.of(times, F.CNI, F.Power(F.Pi, F.CN1)); |
| 347 | + // if (i.isRational()) { |
| 348 | + // IRational rat = (IRational) i; |
| 349 | + // if (rat.isGT(F.C1) || rat.isLE(F.CN1)) { |
| 350 | + // IInteger t = rat.trunc(); |
| 351 | + // t = t.add(t.mod(F.C2)); |
| 352 | + // // exp(I*(i - t)*Pi) |
| 353 | + // return F.Exp.of(F.Times(F.CI, F.Pi, F.Subtract(i, t))); |
| 354 | + // } else { |
| 355 | + // IRational t1 = rat.multiply(F.C6).normalize(); |
| 356 | + // IRational t2 = rat.multiply(F.C4).normalize(); |
| 357 | + // if (t1.isInteger() || t2.isInteger()) { |
| 358 | + // // Cos(- I*times) + I*Sin(- I*times) |
| 359 | + // return F.Plus.of(F.Cos(F.Times(F.CNI, times)), |
| 360 | + // F.Times(F.CI, F.Sin(F.Times(F.CNI, times)))); |
| 361 | + // } |
| 362 | + // } |
| 363 | + // } |
324 | 364 | }
|
325 | 365 |
|
326 |
| - Optional<IExpr[]> commonFactors = |
327 |
| - Algebra.InternalFindCommonFactorPlus.findCommonFactors((IAST) expr, true); |
328 |
| - if (commonFactors.isPresent()) { |
329 |
| - temp = eval(F.Times(commonFactors.get()[0], commonFactors.get()[1])); |
330 |
| - simplifiedResult.checkLessEqual(temp); |
| 366 | + if (simplifiedResult.result.isAST()) { |
| 367 | + expr = simplifiedResult.result; |
331 | 368 | }
|
332 | 369 |
|
333 |
| - if (simplifiedResult.result.isPlus()) { |
334 |
| - temp = tryPlusLog((IAST) simplifiedResult.result); |
335 |
| - } else { |
336 |
| - temp = tryPlusLog((IAST) expr); |
| 370 | + try { |
| 371 | + temp = F.evalExpandAll(expr); |
| 372 | + expandAllCounter = fComplexityFunction.apply(temp); |
| 373 | + simplifiedResult.checkLess(temp); |
| 374 | + } catch (RuntimeException rex) { |
| 375 | + // |
337 | 376 | }
|
338 |
| - if (temp.isPresent()) { |
339 |
| - temp = eval(temp); |
340 |
| - simplifiedResult.checkLessEqual(temp); |
| 377 | + |
| 378 | + if (simplifiedResult.result.isAST()) { |
| 379 | + expr = simplifiedResult.result; |
341 | 380 | }
|
342 |
| - // } else if (expr.isExp() && expr.second().isTimes()) { |
343 |
| - // IAST times = (IAST) expr.second(); |
344 |
| - // IExpr i = Times.of(times, F.CNI, F.Power(F.Pi, F.CN1)); |
345 |
| - // if (i.isRational()) { |
346 |
| - // IRational rat = (IRational) i; |
347 |
| - // if (rat.isGT(F.C1) || rat.isLE(F.CN1)) { |
348 |
| - // IInteger t = rat.trunc(); |
349 |
| - // t = t.add(t.mod(F.C2)); |
350 |
| - // // exp(I*(i - t)*Pi) |
351 |
| - // return F.Exp.of(F.Times(F.CI, F.Pi, F.Subtract(i, t))); |
352 |
| - // } else { |
353 |
| - // IRational t1 = rat.multiply(F.C6).normalize(); |
354 |
| - // IRational t2 = rat.multiply(F.C4).normalize(); |
355 |
| - // if (t1.isInteger() || t2.isInteger()) { |
356 |
| - // // Cos(- I*times) + I*Sin(- I*times) |
357 |
| - // return F.Plus.of(F.Cos(F.Times(F.CNI, times)), |
358 |
| - // F.Times(F.CI, F.Sin(F.Times(F.CNI, times)))); |
359 |
| - // } |
360 |
| - // } |
361 |
| - // } |
362 |
| - } |
363 | 381 |
|
364 |
| - if (simplifiedResult.result.isAST()) { |
365 |
| - expr = simplifiedResult.result; |
366 |
| - } |
| 382 | + if (((IAST) expr).hasTrigonometricFunction()) { |
367 | 383 |
|
368 |
| - try { |
369 |
| - temp = F.evalExpandAll(expr); |
370 |
| - expandAllCounter = fComplexityFunction.apply(temp); |
371 |
| - simplifiedResult.checkLess(temp); |
372 |
| - } catch (RuntimeException rex) { |
373 |
| - // |
374 |
| - } |
| 384 | + try { |
| 385 | + temp = eval(F.TrigExpand(expr)); |
| 386 | + simplifiedResult.checkLess(temp); |
| 387 | + } catch (ValidateException ve) { |
| 388 | + // |
| 389 | + } |
375 | 390 |
|
376 |
| - if (simplifiedResult.result.isAST()) { |
377 |
| - expr = simplifiedResult.result; |
378 |
| - } |
| 391 | + try { |
| 392 | + temp = eval(F.TrigToExp(expr)); |
| 393 | + if (!simplifiedResult.checkLess(temp)) { |
| 394 | + if (fFullSimplify) { |
| 395 | + temp = eval(F.Factor(temp)); |
| 396 | + simplifiedResult.checkLess(temp); |
| 397 | + } |
| 398 | + } |
| 399 | + } catch (ValidateException ve) { |
| 400 | + // |
| 401 | + } |
379 | 402 |
|
380 |
| - if (((IAST) expr).hasTrigonometricFunction()) { |
| 403 | + try { |
| 404 | + temp = eval(F.TrigReduce(expr)); |
| 405 | + simplifiedResult.checkLess(temp); |
| 406 | + } catch (ValidateException ve) { |
| 407 | + // |
| 408 | + } |
| 409 | + } |
381 | 410 |
|
382 | 411 | try {
|
383 |
| - temp = eval(F.TrigExpand(expr)); |
| 412 | + temp = eval(F.ExpToTrig(expr)); |
384 | 413 | simplifiedResult.checkLess(temp);
|
385 | 414 | } catch (ValidateException ve) {
|
386 | 415 | //
|
387 | 416 | }
|
388 | 417 |
|
389 | 418 | try {
|
390 |
| - temp = eval(F.TrigToExp(expr)); |
391 |
| - if (!simplifiedResult.checkLess(temp)) { |
392 |
| - if (fFullSimplify) { |
393 |
| - temp = eval(F.Factor(temp)); |
394 |
| - simplifiedResult.checkLess(temp); |
| 419 | + IExpr together = expr; |
| 420 | + if (simplifiedResult.minCounter < Config.MAX_SIMPLIFY_TOGETHER_LEAFCOUNT) { |
| 421 | + together = eval(F.Together(expr)); |
| 422 | + simplifiedResult.checkLess(together); |
| 423 | + } |
| 424 | + |
| 425 | + if (fFullSimplify) { |
| 426 | + if (together.isTimes()) { |
| 427 | + IExpr[] parts = |
| 428 | + Algebra.numeratorDenominator((IAST) together, true, EvalEngine.get()); |
| 429 | + IExpr numerator = parts[0]; |
| 430 | + IExpr denominator = parts[1]; |
| 431 | + // common factors in numerator, denominator may be canceled here, so check if we |
| 432 | + // have |
| 433 | + // a new minimal expression |
| 434 | + IExpr divide = F.Divide(parts[0], parts[1]); |
| 435 | + simplifiedResult.checkLess(divide); |
| 436 | + |
| 437 | + if (!numerator.isOne() && // |
| 438 | + !denominator.isOne()) { |
| 439 | + tryPolynomialQuotientRemainder(numerator, denominator, simplifiedResult); |
| 440 | + } |
395 | 441 | }
|
396 | 442 | }
|
397 |
| - } catch (ValidateException ve) { |
| 443 | + |
| 444 | + } catch (ValidateException wat) { |
398 | 445 | //
|
399 | 446 | }
|
400 | 447 |
|
401 | 448 | try {
|
402 |
| - temp = eval(F.TrigReduce(expr)); |
403 |
| - simplifiedResult.checkLess(temp); |
| 449 | + // TODO: Factor is not fast enough for large expressions! |
| 450 | + // Maybe restricting factoring to smaller expressions is necessary here |
| 451 | + temp = F.NIL; |
| 452 | + if (fFullSimplify && expandAllCounter < 50) { // Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT) { |
| 453 | + temp = eval(F.Factor(expr)); |
| 454 | + simplifiedResult.checkLess(temp); |
| 455 | + } |
| 456 | + // if (fFullSimplify |
| 457 | + // && (minCounter >= Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT || !temp.equals(expr))) { |
| 458 | + // if (expandAllCounter < (Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT / 2) && !fFullSimplify) |
| 459 | + // { |
| 460 | + // temp = eval(F.Factor(expr)); |
| 461 | + // count = fComplexityFunction.apply(temp); |
| 462 | + // if (count < minCounter) { |
| 463 | + // minCounter = count; |
| 464 | + // result = temp; |
| 465 | + // } |
| 466 | + // } else |
| 467 | + if (expandAllCounter < Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT) { |
| 468 | + temp = eval(F.FactorSquareFree(expr)); |
| 469 | + simplifiedResult.checkLess(temp); |
| 470 | + } |
| 471 | + |
404 | 472 | } catch (ValidateException ve) {
|
405 | 473 | //
|
406 | 474 | }
|
407 |
| - } |
408 |
| - |
409 |
| - try { |
410 |
| - temp = eval(F.ExpToTrig(expr)); |
411 |
| - simplifiedResult.checkLess(temp); |
412 |
| - } catch (ValidateException ve) { |
413 |
| - // |
414 |
| - } |
415 | 475 |
|
416 |
| - try { |
417 |
| - IExpr together = expr; |
418 |
| - if (simplifiedResult.minCounter < Config.MAX_SIMPLIFY_TOGETHER_LEAFCOUNT) { |
419 |
| - together = eval(F.Together(expr)); |
420 |
| - simplifiedResult.checkLess(together); |
421 |
| - } |
422 |
| - |
423 |
| - if (fFullSimplify) { |
424 |
| - if (together.isTimes()) { |
425 |
| - IExpr[] parts = Algebra.numeratorDenominator((IAST) together, true, EvalEngine.get()); |
426 |
| - IExpr numerator = parts[0]; |
427 |
| - IExpr denominator = parts[1]; |
428 |
| - // common factors in numerator, denominator may be canceled here, so check if we have |
429 |
| - // a new minimal expression |
430 |
| - IExpr divide = F.Divide(parts[0], parts[1]); |
431 |
| - simplifiedResult.checkLess(divide); |
432 |
| - |
433 |
| - if (!numerator.isOne() && // |
434 |
| - !denominator.isOne()) { |
435 |
| - tryPolynomialQuotientRemainder(numerator, denominator, simplifiedResult); |
436 |
| - } |
| 476 | + try { |
| 477 | + if (!fNoApart // |
| 478 | + && simplifiedResult.minCounter < Config.MAX_SIMPLIFY_APART_LEAFCOUNT) { |
| 479 | + temp = eval(F.Apart(expr)); |
| 480 | + simplifiedResult.checkLess(temp); |
437 | 481 | }
|
| 482 | + } catch (ValidateException ve) { |
| 483 | + // |
438 | 484 | }
|
439 |
| - |
440 |
| - } catch (ValidateException wat) { |
441 |
| - // |
442 |
| - } |
443 |
| - |
444 |
| - try { |
445 |
| - // TODO: Factor is not fast enough for large expressions! |
446 |
| - // Maybe restricting factoring to smaller expressions is necessary here |
447 |
| - temp = F.NIL; |
448 |
| - if (fFullSimplify && expandAllCounter < 50) { // Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT) { |
449 |
| - temp = eval(F.Factor(expr)); |
450 |
| - simplifiedResult.checkLess(temp); |
451 |
| - } |
452 |
| - // if (fFullSimplify |
453 |
| - // && (minCounter >= Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT || !temp.equals(expr))) { |
454 |
| - // if (expandAllCounter < (Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT / 2) && !fFullSimplify) { |
455 |
| - // temp = eval(F.Factor(expr)); |
456 |
| - // count = fComplexityFunction.apply(temp); |
457 |
| - // if (count < minCounter) { |
458 |
| - // minCounter = count; |
459 |
| - // result = temp; |
460 |
| - // } |
461 |
| - // } else |
462 |
| - if (expandAllCounter < Config.MAX_SIMPLIFY_FACTOR_LEAFCOUNT) { |
463 |
| - temp = eval(F.FactorSquareFree(expr)); |
464 |
| - simplifiedResult.checkLess(temp); |
465 |
| - } |
466 |
| - |
467 |
| - } catch (ValidateException ve) { |
468 |
| - // |
469 |
| - } |
470 |
| - |
471 |
| - try { |
472 |
| - if (!fNoApart // |
473 |
| - && simplifiedResult.minCounter < Config.MAX_SIMPLIFY_APART_LEAFCOUNT) { |
474 |
| - temp = eval(F.Apart(expr)); |
475 |
| - simplifiedResult.checkLess(temp); |
476 |
| - } |
477 |
| - } catch (ValidateException ve) { |
| 485 | + return simplifiedResult.result; |
| 486 | + } catch (LimitException aele) { |
478 | 487 | //
|
479 | 488 | }
|
480 |
| - return simplifiedResult.result; |
| 489 | + return F.NIL; |
481 | 490 | }
|
482 | 491 |
|
483 | 492 | /**
|
|
0 commit comments