Ticket #3813: trac_3813-review.patch

File trac_3813-review.patch, 6.6 kB (added by saliola, 5 months ago)

reviewers changes

  • a/sage/plot/plot.py

    old new  
    34143414 
    34153415    PLOT OPTIONS: 
    34163416    The plot options are 
    3417         plot_points -- the number of points to initially plot before 
    3418                        doing adaptive refinement 
    3419         adaptive_recursion -- how many levels of recursion to go before 
    3420                               giving up when doing adaptive refinement 
    3421                               Setting this to 0 disables adaptive refinement 
     3417        plot_points -- (default: 200) the number of points to initially plot 
     3418                       before the adaptive refinement. 
     3419        adaptive_recursion -- (default: 10) how many levels of recursion to go  
     3420                              before giving up when doing adaptive refinement. 
     3421                              Setting this to 0 disables adaptive refinement. 
    34223422        adaptive_tolerance -- how large a difference should be before the 
    34233423                              adaptive refinement code considers it significant. 
    34243424                              This depends on the interval you use by default. 
     
    35113511        sage: p += text('D', (0.53, 0.18), rgbcolor='red') 
    35123512        sage: p 
    35133513     
    3514     You have the function (in blue) its approximation (in green) passing by the 
    3515     points A and B.  The algorithm find the middle point in x of A and B, which 
    3516     is C.  It then computes the distance in y between C and D  and adds D  
    3517     to the curve points if it exceeds some treshold. 
    3518      
    3519     If D was added, it recursivly applies the same algorithm between A and D, 
    3520     and D and B.  It does this up to 10 levels deep by default. 
    3521  
     3514    You have the function (in blue) and its approximation (in green) passing 
     3515    through the points A and B. The algorithm finds the midpoint C of AB and 
     3516    computes the distance between C and D. The point D is added the curve if 
     3517    it exceeds the (nonzero) adaptive_tolerance threshold. If D is added to 
     3518    the curve, then the algorithm is applied recursively to the points A and D, 
     3519    and D and B. It is repeated adaptive_recursion times (10, by default). 
    35223520 
    35233521    The actual sample points are slightly randomized, so the above 
    35243522    plots may look slightly different each time you draw them. 
     
    35623560    def _reset(self): 
    35633561        o = self.options 
    35643562        o['plot_points'] = 200 
    3565         o['adaptive_recursion'] = 10       
     3563        o['adaptive_recursion'] = 10 
    35663564        o['rgbcolor'] = (0,0,1)    
    35673565 
    35683566    def __repr__(self): 
     
    36303628        plot_points = int(options['plot_points']) 
    36313629        del options['plot_points'] 
    36323630        x, data = var_and_list_of_values(xrange, plot_points) 
    3633         data = list(data) 
    36343631        xmin = data[0] 
    36353632        xmax = data[-1] 
    36363633 
     
    36803677        adaptive_recursion = int(options['adaptive_recursion']) 
    36813678        del options['adaptive_recursion'] 
    36823679         
    3683         def refine(f, p1, p2, level=0): 
    3684             if level >= adaptive_recursion: 
    3685                 return [] 
    3686             x = float((p1[0] + p2[0])/2) 
    3687             try: 
    3688                 y = float(f(x)) 
    3689             except (ZeroDivisionError, TypeError, ValueError), msg: 
    3690                 sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, x), 1) 
    3691                 # give up for this branch 
    3692                 return [] 
    3693             # this distance calculation is not perfect. 
    3694             if abs((p1[1] + p2[1])/2 - y) > adaptive_tolerance: 
    3695                 return refine(f, p1, (x, y), level+1) + [(x, y)] +\ 
    3696                         refine(f, (x, y), p2, level+1) 
    3697             else: 
    3698                 return [] 
    3699          
    37003680        while i < len(data) - 1: 
    3701             for p in refine(f, data[i], data[i+1]): 
     3681            for p in adaptive_refinement(f, data[i], data[i+1],  
     3682                            adaptive_tolerance, adaptive_recursion): 
    37023683                data.insert(i+1, p) 
    37033684                i += 1 
    37043685            i += 1 
     
    44794460                g.append(fast_float(f, str(xvar), str(yvar))) 
    44804461             
    44814462    return g, xstep, ystep, xrange, yrange 
     4463 
     4464def adaptive_refinement(f, p1, p2, adaptive_tolerance=0.01, adaptive_recursion=10, level=0): 
     4465    r""" 
     4466    The adaptive refinement algorithm for plotting a function f. See the 
     4467    docstring for plot or PlotFactory for a description of the algorithm. 
     4468 
     4469    INPUT: 
     4470        f -- a function of one variable 
     4471        p1, p2 -- two points to compare 
     4472        adaptive_recursion -- (default: 10) how many levels of recursion to go  
     4473                              before giving up when doing adaptive refinement. 
     4474                              Setting this to 0 disables adaptive refinement. 
     4475        adaptive_tolerance -- how large a difference should be before the 
     4476                              adaptive refinement code considers it significant. 
     4477                              This depends on the interval you use by default. 
     4478 
     4479    TESTS: 
     4480        sage: from sage.plot.plot import adaptive_refinement 
     4481        sage: adaptive_refinement(sin, (0,0), (pi,0), 0.01, level=10) 
     4482        [] 
     4483        sage: adaptive_refinement(sin, (0,0), (pi,0), 0.01) 
     4484        [(pi/8, 0.38268343236508978), (3*pi/16, 0.55557023301960218), (pi/4, 0.70710678118654746), (5*pi/16, 0.83146961230254524), (3*pi/8, 0.92387953251128674), (7*pi/16, 0.98078528040323043), (pi/2, 1.0), (9*pi/16, 0.98078528040323043), (5*pi/8, 0.92387953251128674), (11*pi/16, 0.83146961230254546), (3*pi/4, 0.70710678118654757), (13*pi/16, 0.55557023301960218), (7*pi/8, 0.38268343236508989)] 
     4485    """ 
     4486    if level >= adaptive_recursion: 
     4487        return [] 
     4488    x = (p1[0] + p2[0])/2 
     4489    try: 
     4490        y = float(f(x)) 
     4491    except (ZeroDivisionError, TypeError, ValueError), msg: 
     4492        sage.misc.misc.verbose("%s\nUnable to compute f(%s)"%(msg, x), 1) 
     4493        # give up for this branch 
     4494        return [] 
     4495    # this distance calculation is not perfect. 
     4496    if abs((p1[1] + p2[1])/2 - y) > adaptive_tolerance: 
     4497        return adaptive_refinement(f, p1, (x, y),  
     4498                        adaptive_tolerance=adaptive_tolerance, 
     4499                        adaptive_recursion=adaptive_recursion, 
     4500                        level=level+1) \ 
     4501               + [(x, y)] + \ 
     4502               adaptive_refinement(f, (x, y), p2, 
     4503                        adaptive_tolerance=adaptive_tolerance, 
     4504                        adaptive_recursion=adaptive_recursion, 
     4505                        level=level+1) 
     4506    else: 
     4507        return []