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
        print
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
        print
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