Révision 218 pobysoPythonSage/src/sageSLZ/sageSLZ.sage
sageSLZ.sage (revision 218) | ||
---|---|---|
494 | 494 |
# End slz_compute_integer_polynomial_modular_roots_2. |
495 | 495 |
# |
496 | 496 |
def slz_compute_polynomial_and_interval(functionSo, degreeSo, lowerBoundSa, |
497 |
upperBoundSa, approxPrecSa,
|
|
498 |
sollyaPrecSa=None):
|
|
497 |
upperBoundSa, approxAccurSa,
|
|
498 |
precSa=None):
|
|
499 | 499 |
""" |
500 | 500 |
Under the assumptions listed for slz_get_intervals_and_polynomials, compute |
501 | 501 |
a polynomial that approximates the function on a an interval starting |
... | ... | |
511 | 511 |
- an range (an interval, not in the sense of number given as an interval); |
512 | 512 |
- the center of the interval; |
513 | 513 |
- the maximum error in the approximation of the input functionSo by the |
514 |
output polynomial ; this error <= approxPrecSaS.
|
|
514 |
output polynomial ; this error <= approxAccurSaS.
|
|
515 | 515 |
|
516 | 516 |
""" |
517 |
#print"In slz_compute_polynomial_and_interval..." |
|
517 | 518 |
## Superficial argument check. |
518 | 519 |
if lowerBoundSa > upperBoundSa: |
519 | 520 |
return None |
521 |
## Change Sollya precision, if requested. |
|
522 |
sollyaPrecChanged = False |
|
523 |
(sollyaPrecSo, sollyaPrecSa) = pobyso_get_prec_so_so_sa() |
|
524 |
if precSa is None: |
|
525 |
precSa = ceil((RR('1.5') * abs(RR(approxAccurSa).log2())) / 64) * 64 |
|
526 |
#print "Computed internal precision:", precSa |
|
527 |
if precSa < 192: |
|
528 |
precSa = 192 |
|
529 |
if precSa != sollyaPrecSa: |
|
530 |
precSo = pobyso_constant_from_int_sa_so(precSa) |
|
531 |
pobyso_set_prec_so_so(precSo) |
|
532 |
sollya_lib_clear_obj(precSo) |
|
533 |
sollyaPrecChanged = True |
|
520 | 534 |
RRR = lowerBoundSa.parent() |
521 | 535 |
intervalShrinkConstFactorSa = RRR('0.9') |
522 | 536 |
absoluteErrorTypeSo = pobyso_absolute_so_so() |
... | ... | |
531 | 545 |
currentRangeSo, |
532 | 546 |
absoluteErrorTypeSo) |
533 | 547 |
maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
534 |
while maxErrorSa > approxPrecSa:
|
|
548 |
while maxErrorSa > approxAccurSa:
|
|
535 | 549 |
print "++Approximation error:", maxErrorSa.n() |
536 | 550 |
sollya_lib_clear_obj(polySo) |
537 | 551 |
sollya_lib_clear_obj(intervalCenterSo) |
538 | 552 |
sollya_lib_clear_obj(maxErrorSo) |
539 | 553 |
# Very empirical shrinking factor. |
540 |
shrinkFactorSa = 1 / (maxErrorSa/approxPrecSa).log2().abs()
|
|
554 |
shrinkFactorSa = 1 / (maxErrorSa/approxAccurSa).log2().abs()
|
|
541 | 555 |
print "Shrink factor:", \ |
542 | 556 |
shrinkFactorSa.n(), \ |
543 | 557 |
intervalShrinkConstFactorSa |
544 | 558 |
|
545 |
#errorRatioSa = approxPrecSa/maxErrorSa
|
|
559 |
#errorRatioSa = approxAccurSa/maxErrorSa
|
|
546 | 560 |
#print "Error ratio: ", errorRatioSa |
547 | 561 |
# Make sure interval shrinks. |
548 | 562 |
if shrinkFactorSa > intervalShrinkConstFactorSa: |
... | ... | |
566 | 580 |
print "Use either or both a higher polynomial degree or a higher", |
567 | 581 |
print "internal precision." |
568 | 582 |
print "Aborting!" |
569 |
return (None, None, None, None) |
|
583 |
if sollyaPrecChanged: |
|
584 |
pobyso_set_prec_so_so(sollyaPrecSo) |
|
585 |
sollya_lib_clear_obj(sollyaPrecSo) |
|
586 |
return None |
|
570 | 587 |
currentRangeSo = pobyso_bounds_to_range_sa_so(currentLowerBoundSa, |
571 | 588 |
currentUpperBoundSa) |
572 | 589 |
# print "New interval:", |
... | ... | |
583 | 600 |
#print "Max errorSa:", maxErrorSa |
584 | 601 |
#print "Sollya prec:", |
585 | 602 |
#pobyso_autoprint(sollya_lib_get_prec(None)) |
603 |
# End while |
|
586 | 604 |
sollya_lib_clear_obj(absoluteErrorTypeSo) |
605 |
if sollyaPrecChanged: |
|
606 |
pobyso_set_prec_so_so(sollyaPrecSo) |
|
607 |
sollya_lib_clear_obj(sollyaPrecSo) |
|
587 | 608 |
return (polySo, currentRangeSo, intervalCenterSo, maxErrorSo) |
588 | 609 |
# End slz_compute_polynomial_and_interval |
610 |
|
|
611 |
def slz_compute_polynomial_and_interval_01(functionSo, degreeSo, lowerBoundSa, |
|
612 |
upperBoundSa, approxAccurSa, |
|
613 |
sollyaPrecSa=None): |
|
614 |
""" |
|
615 |
Under the assumptions listed for slz_get_intervals_and_polynomials, compute |
|
616 |
a polynomial that approximates the function on a an interval starting |
|
617 |
at lowerBoundSa and finishing at a value that guarantees that the polynomial |
|
618 |
approximates with the expected precision. |
|
619 |
The interval upper bound is lowered until the expected approximation |
|
620 |
precision is reached. |
|
621 |
The polynomial, the bounds, the center of the interval and the error |
|
622 |
are returned. |
|
623 |
OUTPUT: |
|
624 |
A tuple made of 4 Sollya objects: |
|
625 |
- a polynomial; |
|
626 |
- an range (an interval, not in the sense of number given as an interval); |
|
627 |
- the center of the interval; |
|
628 |
- the maximum error in the approximation of the input functionSo by the |
|
629 |
output polynomial ; this error <= approxAccurSaS. |
|
630 |
|
|
631 |
""" |
|
632 |
print"In slz_compute_polynomial_and_interval..." |
|
633 |
## Superficial argument check. |
|
634 |
if lowerBoundSa > upperBoundSa: |
|
635 |
return None |
|
636 |
## Change Sollya precision, if requested. |
|
637 |
if not sollyaPrecSa is None: |
|
638 |
sollyaPrecSo = pobyso_get_prec_so() |
|
639 |
pobyso_set_prec_sa_so(sollyaPrecSa) |
|
640 |
else: |
|
641 |
sollyaPrecSa = pobyso_get_prec_so_sa() |
|
642 |
sollyaPrecSo = None |
|
643 |
RRR = lowerBoundSa.parent() |
|
644 |
intervalShrinkConstFactorSa = RRR('0.9') |
|
645 |
absoluteErrorTypeSo = pobyso_absolute_so_so() |
|
646 |
currentRangeSo = pobyso_bounds_to_range_sa_so(lowerBoundSa, upperBoundSa) |
|
647 |
currentUpperBoundSa = upperBoundSa |
|
648 |
currentLowerBoundSa = lowerBoundSa |
|
649 |
# What we want here is the polynomial without the variable change, |
|
650 |
# since our actual variable will be x-intervalCenter defined over the |
|
651 |
# domain [lowerBound-intervalCenter , upperBound-intervalCenter]. |
|
652 |
(polySo, intervalCenterSo, maxErrorSo) = \ |
|
653 |
pobyso_taylor_expansion_no_change_var_so_so(functionSo, degreeSo, |
|
654 |
currentRangeSo, |
|
655 |
absoluteErrorTypeSo) |
|
656 |
maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
657 |
while maxErrorSa > approxAccurSa: |
|
658 |
print "++Approximation error:", maxErrorSa.n() |
|
659 |
sollya_lib_clear_obj(polySo) |
|
660 |
sollya_lib_clear_obj(intervalCenterSo) |
|
661 |
sollya_lib_clear_obj(maxErrorSo) |
|
662 |
# Very empirical shrinking factor. |
|
663 |
shrinkFactorSa = 1 / (maxErrorSa/approxAccurSa).log2().abs() |
|
664 |
print "Shrink factor:", \ |
|
665 |
shrinkFactorSa.n(), \ |
|
666 |
intervalShrinkConstFactorSa |
|
667 |
|
|
668 |
#errorRatioSa = approxAccurSa/maxErrorSa |
|
669 |
#print "Error ratio: ", errorRatioSa |
|
670 |
# Make sure interval shrinks. |
|
671 |
if shrinkFactorSa > intervalShrinkConstFactorSa: |
|
672 |
actualShrinkFactorSa = intervalShrinkConstFactorSa |
|
673 |
#print "Fixed" |
|
674 |
else: |
|
675 |
actualShrinkFactorSa = shrinkFactorSa |
|
676 |
#print "Computed",shrinkFactorSa,maxErrorSa |
|
677 |
#print shrinkFactorSa, maxErrorSa |
|
678 |
#print "Shrink factor", actualShrinkFactorSa |
|
679 |
currentUpperBoundSa = currentLowerBoundSa + \ |
|
680 |
(currentUpperBoundSa - currentLowerBoundSa) * \ |
|
681 |
actualShrinkFactorSa |
|
682 |
#print "Current upper bound:", currentUpperBoundSa |
|
683 |
sollya_lib_clear_obj(currentRangeSo) |
|
684 |
# Check what is left with the bounds. |
|
685 |
if currentUpperBoundSa <= currentLowerBoundSa or \ |
|
686 |
currentUpperBoundSa == currentLowerBoundSa.nextabove(): |
|
687 |
sollya_lib_clear_obj(absoluteErrorTypeSo) |
|
688 |
print "Can't find an interval." |
|
689 |
print "Use either or both a higher polynomial degree or a higher", |
|
690 |
print "internal precision." |
|
691 |
print "Aborting!" |
|
692 |
if not sollyaPrecSo is None: |
|
693 |
pobyso_set_prec_so_so(sollyaPrecSo) |
|
694 |
sollya_lib_clear_obj(sollyaPrecSo) |
|
695 |
return None |
|
696 |
currentRangeSo = pobyso_bounds_to_range_sa_so(currentLowerBoundSa, |
|
697 |
currentUpperBoundSa) |
|
698 |
# print "New interval:", |
|
699 |
# pobyso_autoprint(currentRangeSo) |
|
700 |
#print "Second Taylor expansion call." |
|
701 |
(polySo, intervalCenterSo, maxErrorSo) = \ |
|
702 |
pobyso_taylor_expansion_no_change_var_so_so(functionSo, degreeSo, |
|
703 |
currentRangeSo, |
|
704 |
absoluteErrorTypeSo) |
|
705 |
#maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo, RRR) |
|
706 |
#print "Max errorSo:", |
|
707 |
#pobyso_autoprint(maxErrorSo) |
|
708 |
maxErrorSa = pobyso_get_constant_as_rn_with_rf_so_sa(maxErrorSo) |
|
709 |
#print "Max errorSa:", maxErrorSa |
|
710 |
#print "Sollya prec:", |
|
711 |
#pobyso_autoprint(sollya_lib_get_prec(None)) |
|
712 |
# End while |
|
713 |
sollya_lib_clear_obj(absoluteErrorTypeSo) |
|
714 |
itpSo = pobyso_constant_from_int_sa_so(floor(sollyaPrecSa/3)) |
|
715 |
ftpSo = pobyso_constant_from_int_sa_so(floor(2*sollyaPrecSa/3)) |
|
716 |
maxPrecSo = pobyso_constant_from_int_sa_so(sollyaPrecSa) |
|
717 |
approxAccurSo = pobyso_constant_sa_so(RR(approxAccurSa)) |
|
718 |
print "About to call polynomial rounding with:" |
|
719 |
print "polySo: ", ; pobyso_autoprint(polySo) |
|
720 |
print "functionSo: ", ; pobyso_autoprint(functionSo) |
|
721 |
print "intervalCenterSo: ", ; pobyso_autoprint(intervalCenterSo) |
|
722 |
print "currentRangeSo: ", ; pobyso_autoprint(currentRangeSo) |
|
723 |
print "itpSo: ", ; pobyso_autoprint(itpSo) |
|
724 |
print "ftpSo: ", ; pobyso_autoprint(ftpSo) |
|
725 |
print "maxPrecSo: ", ; pobyso_autoprint(maxPrecSo) |
|
726 |
print "approxAccurSo: ", ; pobyso_autoprint(approxAccurSo) |
|
727 |
(roundedPolySo, roundedPolyMaxErrSo) = \ |
|
728 |
pobyso_polynomial_coefficients_progressive_round_so_so(polySo, |
|
729 |
functionSo, |
|
730 |
intervalCenterSo, |
|
731 |
currentRangeSo, |
|
732 |
itpSo, |
|
733 |
ftpSo, |
|
734 |
maxPrecSo, |
|
735 |
approxAccurSo) |
|
736 |
|
|
737 |
sollya_lib_clear_obj(polySo) |
|
738 |
sollya_lib_clear_obj(maxErrorSo) |
|
739 |
sollya_lib_clear_obj(itpSo) |
|
740 |
sollya_lib_clear_obj(ftpSo) |
|
741 |
sollya_lib_clear_obj(approxAccurSo) |
|
742 |
if not sollyaPrecSo is None: |
|
743 |
pobyso_set_prec_so_so(sollyaPrecSo) |
|
744 |
sollya_lib_clear_obj(sollyaPrecSo) |
|
745 |
print "1: ", ; pobyso_autoprint(roundedPolySo) |
|
746 |
print "2: ", ; pobyso_autoprint(currentRangeSo) |
|
747 |
print "3: ", ; pobyso_autoprint(intervalCenterSo) |
|
748 |
print "4: ", ; pobyso_autoprint(roundedPolyMaxErrSo) |
|
749 |
return (roundedPolySo, currentRangeSo, intervalCenterSo, roundedPolyMaxErrSo) |
|
750 |
# End slz_compute_polynomial_and_interval_01 |
|
751 |
|
|
589 | 752 |
def slz_compute_reduced_polynomial(matrixRow, |
590 | 753 |
knownMonomials, |
591 | 754 |
var1, |
... | ... | |
996 | 1159 |
scaledLowerBoundSa, scaledUpperBoundSa = \ |
997 | 1160 |
scaledUpperBoundSa, scaledLowerBoundSa |
998 | 1161 |
#print "Switching!" |
999 |
print "Approximation precision: ", RR(approxPrecSa)
|
|
1162 |
print "Approximation accuracy: ", RR(approxAccurSa)
|
|
1000 | 1163 |
# Prepare the arguments for the Taylor expansion computation with Sollya. |
1001 | 1164 |
functionSo = \ |
1002 | 1165 |
pobyso_parse_string_sa_so(fff._assume_str().replace('_SAGE_VAR_', '')) |
... | ... | |
1015 | 1178 |
slz_compute_polynomial_and_interval(functionSo, degreeSo, |
1016 | 1179 |
currentScaledLowerBoundSa, |
1017 | 1180 |
currentScaledUpperBoundSa, |
1018 |
approxPrecSa, internalSollyaPrecSa)
|
|
1181 |
approxAccurSa, internalSollyaPrecSa)
|
|
1019 | 1182 |
print "...done." |
1020 | 1183 |
## If slz_compute_polynomial_and_interval fails, it returns None. |
1021 | 1184 |
# This value goes to the first variable: polySo. Other variables are |
... | ... | |
1046 | 1209 |
print "Computed approximation error:", errorSa.n(digits=10) |
1047 | 1210 |
# If the error and interval are OK a the first try, just return. |
1048 | 1211 |
if (boundsSa.endpoints()[1] >= scaledUpperBoundSa) and \ |
1049 |
(errorSa <= approxPrecSa):
|
|
1212 |
(errorSa <= approxAccurSa):
|
|
1050 | 1213 |
if precChangedSa: |
1051 | 1214 |
pobyso_set_prec_sa_so(currentSollyaPrecSa) |
1052 | 1215 |
sollya_lib_clear_obj(currentSollyaPrecSo) |
... | ... | |
1059 | 1222 |
# upper bound: compute the next upper bound. |
1060 | 1223 |
## The following ratio is always >= 1. If errorSa, we may want to |
1061 | 1224 |
# enlarge the interval |
1062 |
currentErrorRatio = approxPrecSa / errorSa
|
|
1225 |
currentErrorRatio = approxAccurSa / errorSa
|
|
1063 | 1226 |
## --|--------------------------------------------------------------|-- |
1064 | 1227 |
# --|--------------------|-------------------------------------------- |
1065 | 1228 |
# --|----------------------------|------------------------------------ |
... | ... | |
1223 | 1386 |
- [3]: the interval center; |
1224 | 1387 |
- [4]: the approximation error. |
1225 | 1388 |
|
1226 |
The function return a 5 elements tuple: formed with all the |
|
1389 |
The function returns a 5 elements tuple: formed with all the
|
|
1227 | 1390 |
input elements converted into their Sollya counterpart. |
1228 | 1391 |
""" |
1229 |
polynomialSa = pobyso_get_poly_so_sa(polyRangeCenterErrorSo[0]) |
|
1230 |
polynomialChangedVarSa = pobyso_get_poly_so_sa(polyRangeCenterErrorSo[1]) |
|
1392 |
polynomialSa = pobyso_float_poly_so_sa(polyRangeCenterErrorSo[0]) |
|
1393 |
#print "Polynomial after first conversion: ", pobyso_autoprint(polyRangeCenterErrorSo[1]) |
|
1394 |
polynomialChangedVarSa = pobyso_float_poly_so_sa(polyRangeCenterErrorSo[1]) |
|
1231 | 1395 |
intervalSa = \ |
1232 | 1396 |
pobyso_get_interval_from_range_so_sa(polyRangeCenterErrorSo[2]) |
1233 | 1397 |
centerSa = \ |
Formats disponibles : Unified diff