Ticket #9623: trac_9623-rebase-v3.patch

File trac_9623-rebase-v3.patch, 69.5 KB (added by kcrisman, 10 years ago)

Based to 4.6.2.alpha0, should apply ok

  • module_list.py

    # HG changeset patch
    # User Karl-Dieter Crisman <kcrisman@gmail.com>
    # Date 1295155082 18000
    # Node ID 6511ebf30f3035d0c45721dd4796f7ec956c10d4
    # Parent  4a9f7b41ae22e247c2a6675c7854e419f7340d09
    Trac #9623 - include interacts from wiki and high school project
    
    Many originate with master's work of Lauri Ruotsalainen.
    Most others are from the http://wiki.sagemath.org/interacts.
    Several stem from work of Robert Marik.
    Original patch from Harald Schilly, extensively reworked by Robert Marik.
    Rebased and importing improved by Marshall Hampton.
    
    For further information, see the individual interacts.
    
    diff -r 4a9f7b41ae22 -r 6511ebf30f30 module_list.py
    a b  
    494494
    495495    ################################
    496496    ##
     497    ## sage.interacts
     498    ##
     499    ################################
     500
     501    Extension('sage.interacts.library_cython',
     502              sources = ['sage/interacts/library_cython.pyx'],
     503              libraries = []),
     504
     505    ################################
     506    ##
    497507    ## sage.libs
    498508    ##
    499509    ################################
  • sage/all.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/all.py
    a b  
    131131
    132132import sage.finance.all  as finance
    133133
    134 import sage.interacts as interacts
     134import sage.interacts.all as interacts
    135135
    136136from sage.parallel.all   import *
    137137
  • sage/interacts/__init__.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/__init__.py
    a b  
    1 """
    2 Interacts included with sage
    3 """
    4 import calculus
    5 import library
     1
     2
  • new file sage/interacts/algebra.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/algebra.py
    - +  
     1"""
     2Interacts for Algebra and Number Theory
     3
     4"""
     5
     6
     7#*****************************************************************************
     8#     Copyright (C) 2010 Harald Schilly <harald.schilly@gmail.com>
     9#
     10#  Distributed under the terms of the GNU General Public License (GPL)
     11#                  http://www.gnu.org/licenses/
     12#*****************************************************************************
     13
     14from library import polar_prime_spiral
  • new file sage/interacts/all.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/all.py
    - +  
     1"""
     2Interacts included with sage
     3"""
     4import calculus
     5import geometry
     6import statistics
     7import fractals
     8import algebra
     9from library import demo
  • sage/interacts/calculus.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/calculus.py
    a b  
     1"""
     2Interacts for Calculus
     3
     4"""
     5
     6
     7#*****************************************************************************
     8#     Copyright (C) 2010 Harald Schilly <harald.schilly@gmail.com>
     9#
     10#  Distributed under the terms of the GNU General Public License (GPL)
     11#                  http://www.gnu.org/licenses/
     12#*****************************************************************************
     13
    114from library import taylor_polynomial
     15from library import definite_integral
     16from library import function_derivative, difference_quotient, quadratic_equation
     17from library import trigonometric_properties_triangle
     18from library import secant_method, newton_method, trapezoid_integration, simpson_integration, bisection_method
     19from library import riemann_sum
     20from library import function_tool
  • new file sage/interacts/fractals.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/fractals.py
    - +  
     1"""
     2Interacts for Fractals
     3
     4"""
     5
     6
     7#*****************************************************************************
     8#     Copyright (C) 2010 Harald Schilly <harald.schilly@gmail.com>
     9#
     10#  Distributed under the terms of the GNU General Public License (GPL)
     11#                  http://www.gnu.org/licenses/
     12#*****************************************************************************
     13
     14from library import mandelbrot, julia, cellular_automaton
  • new file sage/interacts/geometry.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/geometry.py
    - +  
     1"""
     2Interacts for Geometry
     3
     4"""
     5
     6
     7#*****************************************************************************
     8#     Copyright (C) 2010 Harald Schilly <harald.schilly@gmail.com>
     9#
     10#  Distributed under the terms of the GNU General Public License (GPL)
     11#                  http://www.gnu.org/licenses/
     12#*****************************************************************************
     13
     14from library import unit_circle
     15from library import trigonometric_properties_triangle, special_points
  • sage/interacts/library.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/library.py
    a b  
    11"""
    2 A library of interacts
     2Sage Interacts
     3
     4Sage interacts are applications of the `@interact decorator <../../sagenb/notebook/interact.html>`_.
     5They are conveniently accessible in the Sage Notebook via ``interacts.[TAB].[TAB]()``.
     6The first ``[TAB]`` lists categories and the second ``[TAB]`` reveals the interact examples.
     7
     8EXAMPLE:
     9
     10Invoked in the notebook, the following command will produce the fully formatted
     11interactive mathlet.  In the command line, it will simply return the underlying
     12HTML and Sage code which creates the mathlet::
     13
     14    sage: interacts.calculus.taylor_polynomial()
     15    <html>...</html>
     16
    317"""
    418
    5 from sagenb.notebook.interact import interact, slider, range_slider, input_box
    6 from sage.all import sin, plot, point, html, show, latex, SR,exp
     19
     20#*****************************************************************************
     21#        Copyright (C) 2009 William Stein <wstein@gmail.com>
     22#     Copyright (C) 2010 Harald Schilly <harald.schilly@gmail.com>
     23#
     24#  Distributed under the terms of the GNU General Public License (GPL)
     25#                  http://www.gnu.org/licenses/
     26#*****************************************************************************
     27
     28from sage.all import *
     29# this is not imported in sage.all, so we have to import it
     30from sage.ext.fast_callable import fast_callable
    731x=SR.var('x')
    832
    9 from sage.misc.decorators import sage_wraps
    10 from sage.misc.html import html
    11 
    1233def library_interact(f):
    1334    """
    1435    This is a decorator for using interacts in the Sage library.
    1536
    1637    EXAMPLES::
    1738
    18         sage: @interacts.library.library_interact
     39        sage: import sage.interacts.library as library
     40        sage: @library.library_interact
    1941        ... def f(n=5): print n
    2042        ...   
    21         sage: f()  # an interact appears
     43        sage: f()  # an interact appears, if using the notebook, else code
    2244        <html>...</html>
    2345    """
    2446    @sage_wraps(f)
     
    3759   
    3860    INPUT:
    3961       
    40         - `n` -- integer slider
    41         - `m` -- integer slider
     62        - ``n`` -- integer slider
     63        - ``m`` -- integer slider
    4264
    43     EXAMPLES::
     65    EXAMPLES:
     66
     67    Invoked in the notebook, the following command will produce
     68    the fully formatted interactive mathlet.  In the command line,
     69    it will simply return the underlying HTML and Sage code which
     70    creates the mathlet::
    4471     
    45         sage: interacts.library.demo()
     72        sage: interacts.demo()
    4673        <html>...</html>
    4774    """
    4875    print n+m
    4976
    50 
    51 
    5277@library_interact
    53 def taylor_polynomial(f=input_box(sin(x)*exp(-x)), order=slider(range(1,13))):
     78def taylor_polynomial(   
     79    title = text_control('<h2>Taylor polynomial</h2>'),
     80    f=input_box(sin(x)*exp(-x),label="$f(x)=$"), order=slider(range(1,13))):
    5481    """
    5582    An interact which illustrates the Taylor polynomial approximation
    5683    of various orders around `x=0`.
    5784
    58         - `f` -- function expression
    59         - ``order`` -- integer slider
     85        - ``f`` -- function expression
     86        - ```order``` -- integer slider
    6087
    61     EXAMPLES::
     88    EXAMPLES:
     89
     90    Invoked in the notebook, the following command will produce
     91    the fully formatted interactive mathlet.  In the command line,
     92    it will simply return the underlying HTML and Sage code which
     93    creates the mathlet::
    6294     
    6395        sage: interacts.calculus.taylor_polynomial()
    6496        <html>...</html>
     
    71103    html('$f(x)\;=\;%s$'%latex(f))
    72104    html('$\hat{f}(x;%s)\;=\;%s+\mathcal{O}(x^{%s})$'%(x0,latex(ft),order+1))
    73105    show(dot + p + pt, ymin = -.5, ymax = 1)
     106
     107@library_interact
     108def definite_integral(
     109    title = text_control('<h2>Definite integral</h2>'),
     110    f = input_box(default = "3*x", label = '$f(x)=$'),
     111    g = input_box(default = "x^2", label = '$g(x)=$'),
     112    interval = range_slider(-10,10,default=(0,3), label="Interval"),
     113    x_range = range_slider(-10,10,default=(0,3), label = "plot range (x)"),
     114    selection = selector(["f", "g", "f and g", "f - g"], default="f and g", label="Select")):
     115    """
     116    This is a demo interact for plotting the definite integral of a function
     117    based on work by Lauri Ruotsalainen, 2010.
     118
     119    INPUT:
     120
     121        - ``function`` -- input box, function in x
     122        - ``interval`` -- interval for the definite integral
     123        - ``x_range`` -- range slider for plotting range
     124        - ``selection`` -- selector on how to visualize the integrals
     125
     126    EXAMPLES:
     127
     128    Invoked in the notebook, the following command will produce
     129    the fully formatted interactive mathlet.  In the command line,
     130    it will simply return the underlying HTML and Sage code which
     131    creates the mathlet::
     132
     133        sage: interacts.calculus.definite_integral()
     134        <html>...</html>
     135    """
     136    x = SR.var('x')
     137    f = symbolic_expression(f).function(x)
     138    g = symbolic_expression(g).function(x)
     139    f_plot = Graphics(); g_plot = Graphics(); h_plot = Graphics();
     140    text = ""
     141
     142    # Plot function f.
     143    if selection != "g":   
     144        f_plot = plot(f(x), x, x_range, color="blue", thickness=1.5)
     145           
     146    # Color and calculate the area between f and the horizontal axis. 
     147    if selection == "f" or selection == "f and g":
     148        f_plot += plot(f(x), x, interval, color="blue", fill=True, fillcolor="blue", fillalpha=0.15)
     149        text += r"$\int_{%.2f}^{%.2f}(\color{Blue}{f(x)})\,\mathrm{d}x=\int_{%.2f}^{%.2f}(%s)\,\mathrm{d}x=%.2f$" % (
     150            interval[0], interval[1],
     151            interval[0], interval[1],
     152            latex(f(x)),
     153            f(x).nintegrate(x, interval[0], interval[1])[0]
     154        )
     155
     156    if selection == "f and g":
     157        text += r"<br/>"
     158
     159    # Plot function g. Also color and calculate the area between g and the horizontal axis.   
     160    if selection == "g" or selection == "f and g":
     161        g_plot = plot(g(x), x, x_range, color="green", thickness=1.5)
     162        g_plot += plot(g(x), x, interval, color="green", fill=True, fillcolor="yellow", fillalpha=0.5)
     163        text += r"$\int_{%.2f}^{%.2f}(\color{Green}{g(x)})\,\mathrm{d}x=\int_{%.2f}^{%.2f}(%s)\,\mathrm{d}x=%.2f$" % (
     164            interval[0], interval[1],
     165            interval[0], interval[1],
     166            latex(g(x)),
     167            g(x).nintegrate(x, interval[0], interval[1])[0]
     168        )     
     169         
     170    # Plot function f-g. Also color and calculate the area between f-g and the horizontal axis.
     171    if selection == "f - g":
     172        g_plot = plot(g(x), x, x_range, color="green", thickness=1.5)
     173        g_plot += plot(g(x), x, interval, color="green", fill=f(x), fillcolor="red", fillalpha=0.15)
     174        h_plot = plot(f(x)-g(x), x, interval, color="red", thickness=1.5, fill=True, fillcolor="red", fillalpha=0.15)
     175        text = r"$\int_{%.2f}^{%.2f}(\color{Red}{f(x)-g(x)})\,\mathrm{d}x=\int_{%.2f}^{%.2f}(%s)\,\mathrm{d}x=%.2f$" % (
     176            interval[0], interval[1],
     177            interval[0], interval[1],
     178            latex(f(x)-g(x)),
     179            (f(x)-g(x)).nintegrate(x, interval[0], interval[1])[0]
     180        )
     181               
     182    show(f_plot + g_plot + h_plot, gridlines=True)
     183    html(text)
     184
     185@library_interact
     186def function_derivative(
     187    title = text_control('<h2>Derivative grapher</h2>'),
     188    function = input_box(default="x^5-3*x^3+1", label="Function:"),
     189    x_range  = range_slider(-15,15,0.1, default=(-2,2), label="Range (x)"),
     190    y_range  = range_slider(-15,15,0.1, default=(-8,6), label="Range (y)")):
     191    """
     192    This is a demo interact for plotting derivatives of a function based on work by
     193    Lauri Ruotsalainen, 2010.
     194
     195    INPUT:
     196
     197        - ``function`` -- input box, function in x
     198        - ``x_range`` -- range slider for plotting range
     199        - ``y_range`` -- range slider for plotting range
     200
     201    EXAMPLES:
     202
     203    Invoked in the notebook, the following command will produce
     204    the fully formatted interactive mathlet.  In the command line,
     205    it will simply return the underlying HTML and Sage code which
     206    creates the mathlet::
     207
     208        sage: interacts.calculus.function_derivative()
     209        <html>...</html>
     210    """
     211    x = SR.var('x')
     212    f = symbolic_expression(function).function(x)
     213    df = derivative(f, x)
     214    ddf = derivative(df, x)
     215    plots = plot(f(x), x_range, thickness=1.5) + plot(df(x), x_range, color="green") + plot(ddf(x), x_range, color="red")
     216    if y_range == (0,0):
     217        show(plots, xmin=x_range[0], xmax=x_range[1])
     218    else:
     219        show(plots, xmin=x_range[0], xmax=x_range[1], ymin=y_range[0], ymax=y_range[1])
     220
     221    html("<center>$\color{Blue}{f(x) = %s}$</center>"%latex(f(x)))
     222    html("<center>$\color{Green}{f'(x) = %s}$</center>"%latex(df(x)))
     223    html("<center>$\color{Red}{f''(x) = %s}$</center>"%latex(ddf(x)))
     224
     225@library_interact
     226def difference_quotient(
     227    title = text_control('<h2>Difference quotient</h2>'),
     228    f = input_box(default="sin(x)", label='f(x)'),
     229    interval= range_slider(0, 10, 0.1, default=(0.0,10.0), label="Range"),
     230    a = slider(0, 10, None, 5.5, label = '$a$'),
     231    x0 = slider(0, 10, None, 2.5, label = '$x_0$ (start point)')):
     232    """
     233    This is a demo interact for difference quotient based on work by
     234    Lauri Ruotsalainen, 2010.
     235
     236    INPUT:
     237
     238        - ``f`` -- input box, function in `x`
     239        - ``interval`` -- range slider for plotting
     240        - ``a`` -- slider for `a`
     241        - ``x0`` -- slider for starting point `x_0`
     242
     243    EXAMPLES:
     244
     245    Invoked in the notebook, the following command will produce
     246    the fully formatted interactive mathlet.  In the command line,
     247    it will simply return the underlying HTML and Sage code which
     248    creates the mathlet::
     249
     250        sage: interacts.calculus.difference_quotient()
     251        <html>...</html>
     252    """
     253    html('<h2>Difference Quotient</h2>')
     254    html('<div style="white-space: normal;">\
     255         <a href="http://en.wikipedia.org/wiki/Difference_quotient" target="_blank">\
     256         Wikipedia article about difference quotient</a></div>'
     257         )
     258
     259    x = SR.var('x')
     260    f = symbolic_expression(f).function(x)
     261    fmax = f.find_maximum_on_interval(interval[0], interval[1])[0]
     262    fmin = f.find_minimum_on_interval(interval[0], interval[1])[0]
     263    f_height = fmax - fmin
     264    measure_y = fmin - 0.1*f_height
     265
     266    measure_0 = line2d([(x0, measure_y), (a, measure_y)], rgbcolor="black")
     267    measure_1 = line2d([(x0, measure_y + 0.02*f_height), (x0, measure_y-0.02*f_height)], rgbcolor="black")
     268    measure_2 = line2d([(a, measure_y + 0.02*f_height), (a, measure_y-0.02*f_height)], rgbcolor="black")
     269    text_x0 = text("x0", (x0, measure_y - 0.05*f_height), rgbcolor="black")
     270    text_a = text("a", (a, measure_y - 0.05*f_height), rgbcolor="black")
     271    measure = measure_0 + measure_1 + measure_2 + text_x0 + text_a
     272
     273    tanf = symbolic_expression((f(x0)-f(a))*(x-a)/(x0-a)+f(a)).function(x)
     274
     275    fplot = plot(f(x), x, interval[0], interval[1])
     276    tanplot = plot(tanf(x), x, interval[0], interval[1], rgbcolor="#FF0000")
     277    points = point([(x0, f(x0)), (a, f(a))], pointsize=20, rgbcolor="#005500")
     278    dashline = line2d([(x0, f(x0)), (x0, f(a)), (a, f(a))], rgbcolor="#005500", linestyle="--")
     279    html('<h2>Difference Quotient</h2>')
     280    show(fplot + tanplot + points + dashline + measure, xmin=interval[0], xmax=interval[1], ymin=fmin-0.2*f_height, ymax=fmax)
     281    html(r"<br>$\text{Line's equation:}$")
     282    html(r"$y = %s$<br>"%tanf(x))
     283    html(r"$\text{Slope:}$")
     284    html(r"$k = \frac{f(x_0)-f(a)}{x_0-a} = %s$<br>" % (N(derivative(tanf(x), x), digits=5)))
     285
     286@library_interact
     287def quadratic_equation(A = slider(-7, 7, 1, 1), B = slider(-7, 7, 1, 1), C = slider(-7, 7, 1, -2)):
     288    """
     289    This is a demo interact for solving quadratic equations based on work by
     290    Lauri Ruotsalainen, 2010.
     291
     292    INPUT:
     293
     294        - ``A`` -- integer slider
     295        - ``B`` -- integer slider
     296        - ``C`` -- integer slider
     297
     298    EXAMPLES:
     299
     300    Invoked in the notebook, the following command will produce
     301    the fully formatted interactive mathlet.  In the command line,
     302    it will simply return the underlying HTML and Sage code which
     303    creates the mathlet::
     304
     305        sage: interacts.calculus.quadratic_equation()
     306        <html>...</html>
     307    """
     308    x = SR.var('x')
     309    f = symbolic_expression(A*x**2 + B*x + C).function(x)
     310    html('<h2>The Solutions of the Quadratic Equation</h2>')
     311    html("$%s = 0$" % f(x))
     312   
     313    show(plot(f(x), x, (-10, 10), ymin=-10, ymax=10), aspect_ratio=1, figsize=4)
     314
     315    d = B**2 - 4*A*C
     316
     317    if d < 0:
     318        color = "Red"
     319        sol = r"\text{solution} \in \mathbb{C}"
     320    elif d == 0:
     321        color = "Blue"
     322        sol = -B/(2*A)
     323    else:
     324        color = "Green"
     325        a = (-B+sqrt(B**2-4*A*C))/(2*A)
     326        b = (-B-sqrt(B**2-4*A*C))/(2*A)
     327        sol = r"\begin{cases}%s\\%s\end{cases}" % (latex(a), latex(b))
     328
     329    if B < 0:
     330        dis1 = "(%s)^2-4*%s*%s" % (B, A, C)
     331    else:
     332        dis1 = "%s^2-4*%s*%s" % (B, A, C)       
     333    dis2 = r"\color{%s}{%s}" % (color, d)
     334
     335    html("$Ax^2 + Bx + C = 0$")
     336    calc = r"$x = \frac{-B\pm\sqrt{B^2-4AC}}{2A} = " + \
     337           r"\frac{-%s\pm\sqrt{%s}}{2*%s} = " + \
     338           r"\frac{-%s\pm\sqrt{%s}}{%s} = %s$"
     339    html(calc % (B, dis1, A, B, dis2, (2*A), sol))
     340
     341@library_interact
     342def trigonometric_properties_triangle(
     343    a0 = slider(0, 360, 1, 30, label="A"),
     344    a1 = slider(0, 360, 1, 180, label="B"),
     345    a2 = slider(0, 360, 1, 300, label="C")):
     346    """
     347    This is an interact for demonstrating trigonometric properties
     348    in a triangle based on work by Lauri Ruotsalainen, 2010.
     349
     350    INPUT:
     351
     352        - ``a0`` -- angle
     353        - ``a1`` -- angle
     354        - ``a2`` -- angle
     355
     356    EXAMPLES:
     357
     358    Invoked in the notebook, the following command will produce
     359    the fully formatted interactive mathlet.  In the command line,
     360    it will simply return the underlying HTML and Sage code which
     361    creates the mathlet::
     362
     363        sage: interacts.geometry.trigonometric_properties_triangle()
     364        <html>...</html>
     365    """
     366    import math
     367
     368    # Returns the distance between points (x1,y1) and (x2,y2)
     369    def distance((x1, y1), (x2, y2)):
     370        return sqrt((x2-x1)**2 + (y2-y1)**2)
     371   
     372    # Returns an angle (in radians) when sides a and b
     373    # are adjacent and the side c is opposite to the angle
     374    def angle(a, b, c):
     375        a,b,c = map(float,[a,b,c])
     376        return acos((b**2 + c**2 - a**2)/(2.0*b*c))
     377   
     378    # Returns the area of a triangle when an angle alpha
     379    # and adjacent sides a and b are known
     380    def area(alpha, a, b):
     381        return 1.0/2.0*a*b*sin(alpha)
     382   
     383    xy = [0]*3
     384    html('<h2>Trigonometric Properties of a Triangle</h2>')
     385    # Coordinates of the angles
     386    a = map(lambda x : math.radians(float(x)), [a0, a1, a2])
     387    for i in range(3):
     388        xy[i] = (cos(a[i]), sin(a[i]))
     389
     390    # Side lengths (bc, ca, ab) corresponding to triangle vertices (a, b, c)
     391    al = [distance(xy[1], xy[2]), distance(xy[2], xy[0]), distance(xy[0], xy[1])]
     392
     393    # The angles (a, b, c) in radians
     394    ak = [angle(al[0], al[1], al[2]), angle(al[1], al[2], al[0]), angle(al[2], al[0], al[1])]
     395
     396    # The area of the triangle
     397    A = area(ak[0], al[1], al[2])
     398
     399    unit_circle = circle((0, 0), 1, aspect_ratio=1)
     400
     401    # Triangle
     402    triangle = line([xy[0], xy[1], xy[2], xy[0]], rgbcolor="black")
     403    triangle_points = point(xy, pointsize=30)
     404
     405    # Labels of the angles drawn in a distance from points
     406    a_label = text("A", (xy[0][0]*1.07, xy[0][1]*1.07))
     407    b_label = text("B", (xy[1][0]*1.07, xy[1][1]*1.07))
     408    c_label = text("C", (xy[2][0]*1.07, xy[2][1]*1.07))
     409    labels = a_label + b_label + c_label
     410
     411    show(unit_circle + triangle + triangle_points + labels, figsize=[5, 5], xmin=-1, xmax=1, ymin=-1, ymax=1)
     412    angl_txt = r"$\angle A = {%s}^{\circ},$ $\angle B = {%s}^{\circ},$ $\angle C = {%s}^{\circ}$" % (
     413            math.degrees(ak[0]),
     414            math.degrees(ak[1]),
     415            math.degrees(ak[2])
     416        )
     417    html(angl_txt)
     418    html(r"$AB = %s,$  $BC = %s,$  $CA = %s$"%(al[2], al[0], al[1]))
     419    html(r"Area of triangle $ABC = %s$"%A)
     420
     421@library_interact
     422def unit_circle(
     423    function = selector([(0, sin(x)), (1, cos(x)), (2, tan(x))]),
     424    x = slider(0,2*pi, 0.005*pi, 0)):
     425    """
     426    This is an interact for Sin, Cos and Tan in the Unit Circle
     427    based on work by Lauri Ruotsalainen, 2010.
     428
     429    INPUT:
     430
     431        - ``function`` -- select Sin, Cos or Tan
     432        - ``x`` -- slider to select angle in unit circle
     433
     434    EXAMPLES:
     435
     436    Invoked in the notebook, the following command will produce
     437    the fully formatted interactive mathlet.  In the command line,
     438    it will simply return the underlying HTML and Sage code which
     439    creates the mathlet::
     440
     441        sage: interacts.geometry.unit_circle()
     442        <html>...</html>
     443    """
     444    xy = (cos(x), sin(x))
     445    t = SR.var('t')
     446    html('<div style="white-space: normal;">Lines of the same color have\
     447         the same length</div>')
     448
     449    # Unit Circle
     450    C = circle((0, 0), 1, figsize=[5, 5], aspect_ratio=1)
     451    C_line = line([(0, 0), (xy[0], xy[1])], rgbcolor="black")
     452    C_point = point((xy[0], xy[1]), pointsize=40, rgbcolor="green")
     453    C_inner = parametric_plot((cos(t), sin(t)), (t, 0, x + 0.001), color="green", thickness=3)
     454    C_outer = parametric_plot((0.1 * cos(t), 0.1 * sin(t)), (t, 0, x + 0.001), color="black")
     455    C_graph = C + C_line + C_point + C_inner + C_outer
     456
     457    # Graphics related to the graph of the function
     458    G_line = line([(0, 0), (x, 0)], rgbcolor="green", thickness=3)
     459    G_point = point((x, 0), pointsize=30, rgbcolor="green")
     460    G_graph = G_line + G_point
     461
     462    # Sine
     463    if function == 0:
     464        Gf = plot(sin(t), t, 0, 2*pi, axes_labels=("x", "sin(x)"))
     465        Gf_point = point((x, sin(x)), pointsize=30, rgbcolor="red")
     466        Gf_line = line([(x, 0),(x, sin(x))], rgbcolor="red")
     467        Cf_point = point((0, xy[1]), pointsize=40, rgbcolor="red")
     468        Cf_line1 = line([(0, 0), (0, xy[1])], rgbcolor="red", thickness=3)
     469        Cf_line2 = line([(0, xy[1]), (xy[0], xy[1])], rgbcolor="purple", linestyle="--")
     470    # Cosine
     471    elif function == 1:
     472        Gf = plot(cos(t), t, 0, 2*pi, axes_labels=("x", "cos(x)"))
     473        Gf_point = point((x, cos(x)), pointsize=30, rgbcolor="red")
     474        Gf_line = line([(x, 0), (x, cos(x))], rgbcolor="red")
     475        Cf_point = point((xy[0], 0), pointsize=40, rgbcolor="red")
     476        Cf_line1 = line([(0, 0), (xy[0], 0)], rgbcolor="red", thickness=3)
     477        Cf_line2 = line([(xy[0], 0), (xy[0], xy[1])], rgbcolor="purple", linestyle="--")
     478    # Tangent
     479    else:
     480        Gf = plot(tan(t), t, 0, 2*pi, ymin=-8, ymax=8, axes_labels=("x", "tan(x)"))
     481        Gf_point = point((x, tan(x)), pointsize=30, rgbcolor="red")
     482        Gf_line = line([(x, 0), (x, tan(x))], rgbcolor="red")
     483        Cf_point = point((1, tan(x)), pointsize=40, rgbcolor="red")
     484        Cf_line1 = line([(1, 0), (1, tan(x))], rgbcolor="red", thickness=3)
     485        Cf_line2 = line([(xy[0], xy[1]), (1, tan(x))], rgbcolor="purple", linestyle="--")
     486
     487    C_graph += Cf_point + Cf_line1 + Cf_line2
     488    G_graph += Gf + Gf_point + Gf_line
     489
     490    html.table([[r"$\text{Unit Circle}$",r"$\text{Function}$"], [C_graph, G_graph]], header=True)
     491
     492@library_interact
     493def special_points(
     494    title = text_control('<h2>Special points in triangle</h2>'),
     495    a0 = slider(0, 360, 1, 30, label="A"),
     496    a1 = slider(0, 360, 1, 180, label="B"),
     497    a2 = slider(0, 360, 1, 300, label="C"),
     498    show_median = checkbox(False, label="Medians"),
     499    show_pb = checkbox(False, label="Perpendicular Bisectors"),
     500    show_alt = checkbox(False, label="Altitudes"),
     501    show_ab = checkbox(False, label="Angle Bisectors"),
     502    show_incircle = checkbox(False, label="Incircle"),
     503    show_euler = checkbox(False, label="Euler's Line")):
     504    """
     505    This interact demo shows special points in a triangle
     506    based on work by Lauri Ruotsalainen, 2010.
     507
     508    INPUT:
     509
     510        - ``a0`` -- angle
     511        - ``a1`` -- angle
     512        - ``a2`` -- angle
     513        - ``show_median`` -- checkbox
     514        - ``show_pb`` -- checkbox to show perpendicular bisectors
     515        - ``show_alt`` -- checkbox to show altitudes
     516        - ``show_ab`` -- checkbox to show angle bisectors
     517        - ``show_incircle`` -- checkbox to show incircle
     518        - ``show_euler`` -- checkbox to show euler's line
     519
     520    EXAMPLES:
     521
     522    Invoked in the notebook, the following command will produce
     523    the fully formatted interactive mathlet.  In the command line,
     524    it will simply return the underlying HTML and Sage code which
     525    creates the mathlet::
     526
     527        sage: interacts.geometry.special_points()
     528        <html>...</html>
     529    """
     530    import math
     531    # Return the intersection point of the bisector of the angle <(A[a],A[c],A[b]) and the unit circle. Angles given in radians.
     532    def half(A, a, b, c):
     533        if (A[a] < A[b] and (A[c] < A[a] or A[c] > A[b])) or (A[a] > A[b] and (A[c] > A[a] or A[c] < A[b])):
     534            p = A[a] + (A[b] - A[a]) / 2.0
     535        else:
     536            p = A[b] + (2*pi - (A[b]-A[a])) / 2.0
     537        return (math.cos(p), math.sin(p))
     538   
     539    # Returns the distance between points (x1,y1) and (x2,y2)
     540    def distance((x1, y1), (x2, y2)):
     541        return math.sqrt((x2-x1)**2 + (y2-y1)**2)
     542   
     543    # Returns the line (graph) going through points (x1,y1) and (x2,y2)
     544    def line_to_points((x1, y1), (x2, y2), **plot_kwargs):
     545        return plot((y2-y1) / (x2-x1) * (x-x1) + y1, (x,-3,3), **plot_kwargs)
     546
     547    # Coordinates of the angles
     548    a = map(lambda x : math.radians(float(x)), [a0, a1, a2])
     549    xy = [(math.cos(a[i]), math.sin(a[i])) for i in range(3)]
     550
     551    # Labels of the angles drawn in a distance from points
     552    a_label = text("A", (xy[0][0]*1.07, xy[0][1]*1.07))
     553    b_label = text("B", (xy[1][0]*1.07, xy[1][1]*1.07))
     554    c_label = text("C", (xy[2][0]*1.07, xy[2][1]*1.07))
     555    labels = a_label + b_label + c_label
     556
     557    C = circle((0, 0), 1, aspect_ratio=1)
     558
     559    # Triangle
     560    triangle = line([xy[0], xy[1], xy[2], xy[0]], rgbcolor="black")
     561    triangle_points = point(xy, pointsize=30)
     562
     563    # Side lengths (bc, ca, ab) corresponding to triangle vertices (a, b, c)
     564    ad = [distance(xy[1], xy[2]), distance(xy[2], xy[0]), distance(xy[0], xy[1])]
     565
     566    # Midpoints of edges (bc, ca, ab)
     567    a_middle = [
     568        ((xy[1][0] + xy[2][0])/2.0, (xy[1][1] + xy[2][1])/2.0),
     569        ((xy[2][0] + xy[0][0])/2.0, (xy[2][1] + xy[0][1])/2.0),
     570        ((xy[0][0] + xy[1][0])/2.0, (xy[0][1] + xy[1][1])/2.0)
     571    ]
     572
     573    # Incircle
     574    perimeter = float(ad[0] + ad[1] + ad[2])
     575    incircle_center = (
     576        (ad[0]*xy[0][0] + ad[1]*xy[1][0] + ad[2]*xy[2][0]) / perimeter,
     577        (ad[0]*xy[0][1] + ad[1]*xy[1][1] + ad[2]*xy[2][1]) / perimeter
     578    )
     579
     580    if show_incircle:
     581        s = perimeter/2.0
     582        incircle_r = math.sqrt((s - ad[0]) * (s - ad[1]) * (s - ad[2]) / s)
     583        incircle_graph = circle(incircle_center, incircle_r) + point(incircle_center)
     584    else:
     585        incircle_graph = Graphics()
     586
     587    # Angle Bisectors
     588    if show_ab:
     589        a_ab = line([xy[0], half(a, 1, 2, 0)], rgbcolor="blue", alpha=0.6)
     590        b_ab = line([xy[1], half(a, 2, 0, 1)], rgbcolor="blue", alpha=0.6)
     591        c_ab = line([xy[2], half(a, 0, 1, 2)], rgbcolor="blue", alpha=0.6)
     592        ab_point = point(incircle_center, rgbcolor="blue", pointsize=28)
     593        ab_graph = a_ab + b_ab + c_ab + ab_point
     594    else:
     595        ab_graph = Graphics()
     596
     597    # Medians
     598    if show_median:
     599        a_median = line([xy[0], a_middle[0]], rgbcolor="green", alpha=0.6)
     600        b_median = line([xy[1], a_middle[1]], rgbcolor="green", alpha=0.6)
     601        c_median = line([xy[2], a_middle[2]], rgbcolor="green", alpha=0.6)
     602        median_point = point(
     603            (
     604                (xy[0][0]+xy[1][0]+xy[2][0])/3.0,
     605                (xy[0][1]+xy[1][1]+xy[2][1])/3.0
     606            ), rgbcolor="green", pointsize=28)
     607        median_graph = a_median + b_median + c_median + median_point
     608    else:
     609        median_graph = Graphics()
     610
     611    # Perpendicular Bisectors
     612    if show_pb:
     613        a_pb = line_to_points(a_middle[0], half(a, 1, 2, 0), rgbcolor="red", alpha=0.6)
     614        b_pb = line_to_points(a_middle[1], half(a, 2, 0, 1), rgbcolor="red", alpha=0.6)
     615        c_pb = line_to_points(a_middle[2], half(a, 0, 1, 2), rgbcolor="red", alpha=0.6)
     616        pb_point = point((0, 0), rgbcolor="red", pointsize=28)
     617        pb_graph = a_pb + b_pb + c_pb + pb_point
     618    else:
     619        pb_graph = Graphics()
     620
     621    # Altitudes
     622    if show_alt:
     623        xA, xB, xC = xy[0][0], xy[1][0], xy[2][0]
     624        yA, yB, yC = xy[0][1], xy[1][1], xy[2][1]
     625        a_alt = plot(((xC-xB)*x+(xB-xC)*xA)/(yB-yC)+yA, (x,-3,3), rgbcolor="brown", alpha=0.6)
     626        b_alt = plot(((xA-xC)*x+(xC-xA)*xB)/(yC-yA)+yB, (x,-3,3), rgbcolor="brown", alpha=0.6)
     627        c_alt = plot(((xB-xA)*x+(xA-xB)*xC)/(yA-yB)+yC, (x,-3,3), rgbcolor="brown", alpha=0.6)
     628        alt_lx = (xA*xB*(yA-yB)+xB*xC*(yB-yC)+xC*xA*(yC-yA)-(yA-yB)*(yB-yC)*(yC-yA))/(xC*yB-xB*yC+xA*yC-xC*yA+xB*yA-xA*yB)
     629        alt_ly = (yA*yB*(xA-xB)+yB*yC*(xB-xC)+yC*yA*(xC-xA)-(xA-xB)*(xB-xC)*(xC-xA))/(yC*xB-yB*xC+yA*xC-yC*xA+yB*xA-yA*xB)
     630        alt_intersection = point((alt_lx, alt_ly), rgbcolor="brown", pointsize=28)
     631        alt_graph = a_alt + b_alt + c_alt + alt_intersection
     632    else:
     633        alt_graph = Graphics()
     634
     635    # Euler's Line
     636    if show_euler:
     637        euler_graph = line_to_points(
     638            (0, 0),
     639            (
     640                (xy[0][0]+xy[1][0]+xy[2][0])/3.0,
     641                (xy[0][1]+xy[1][1]+xy[2][1])/3.0
     642            ),
     643            rgbcolor="purple",
     644            thickness=2,
     645            alpha=0.7
     646        )
     647    else:
     648        euler_graph = Graphics()
     649
     650    show(
     651        C + triangle + triangle_points + labels + ab_graph + median_graph +
     652        pb_graph + alt_graph + incircle_graph + euler_graph,
     653        figsize=[5,5], xmin=-1, xmax=1, ymin=-1, ymax=1
     654    )
     655
     656
     657@library_interact
     658def coin(n = slider(2,10000, 100, default=1000, label="Number of Tosses"), interval = range_slider(0, 1, default=(0.45, 0.55), label="Plotting range (y)")):
     659    """
     660    This interact demo simulates repeated tosses of a coin,
     661    based on work by Lauri Ruotsalainen, 2010.
     662
     663    The points give the cumulative percentage of tosses which
     664    are heads in a given run of the simulation, so that the
     665    point `(x,y)` gives the percentage of the first `x` tosses
     666    that were heads; this proportion should approach .5, of
     667    course, if we are simulating a fair coin.
     668
     669    INPUT:
     670
     671      - ``n`` -- number of tosses
     672      - ``interval`` -- plot range along
     673        vertical axis
     674
     675    EXAMPLES:
     676
     677    Invoked in the notebook, the following command will produce
     678    the fully formatted interactive mathlet.  In the command line,
     679    it will simply return the underlying HTML and Sage code which
     680    creates the mathlet::
     681
     682        sage: interacts.statistics.coin()
     683        <html>...</html>
     684    """
     685    from random import random
     686    c = []
     687    k = 0.0
     688    for i in range(1, n + 1):
     689        k += random()
     690        c.append((i, k/i))
     691    show(point(c[1:], gridlines=[None, [0.5]], pointsize=1), ymin=interval[0], ymax=interval[1])
     692
     693
     694@library_interact
     695def bisection_method(
     696    title = text_control('<h2>Bisection method</h2>'),
     697    f = input_box("x^2-2", label='f(x)'),
     698    interval = range_slider(-5,5,default=(0, 4), label="range"),
     699    d = slider(1, 8, 1, 3, label="$10^{-d}$ precision"),
     700    maxn = slider(0,50,1,10, label="max iterations")):
     701    """
     702    Interact explaining the bisection method, based on similar interact
     703    explaining secant method and Wiliam Stein's example from wiki.
     704
     705    INPUT:
     706
     707      - ``f`` -- function
     708      - ``interval`` -- range slider for the search interval
     709      - ``d`` -- slider for the precision (`10^{-d}`)
     710      - ``maxn`` -- max number of iterations
     711
     712    EXAMPLES:
     713
     714    Invoked in the notebook, the following command will produce
     715    the fully formatted interactive mathlet.  In the command line,
     716    it will simply return the underlying HTML and Sage code which
     717    creates the mathlet::
     718
     719        sage: interacts.calculus.secant_method()
     720        <html>...</html>
     721    """
     722    def _bisection_method(f, a, b, maxn, eps):
     723        intervals = [(a,b)]
     724        round = 1
     725        two = float(2)
     726        while True:
     727            c = (b+a)/two
     728            if abs(f(c)) < h or round >= maxn:
     729                break
     730            fa = f(a); fb = f(b); fc = f(c)
     731            if abs(fc) < eps:
     732                return c, intervals
     733            if fa*fc < 0:
     734                a, b = a, c
     735            elif fc*fb < 0:
     736                a, b = c, b
     737            else:
     738                raise ValueError, "f must have a sign change in the interval (%s,%s)"%(a,b)
     739            intervals.append((a,b))
     740            round += 1
     741        return c, intervals
     742
     743    x = SR.var('x')
     744    f = symbolic_expression(f).function(x)
     745    a, b = interval
     746    h = 10**(-d)
     747    try:
     748        c, intervals = _bisection_method(f, float(a), float(b), maxn, h)
     749    except ValueError:
     750        print "f must have opposite sign at the endpoints of the interval"
     751        show(plot(f, a, b, color='red'), xmin=a, xmax=b)
     752    else:
     753        html(r"$\text{Precision }h = 10^{-d}=10^{-%s}=%.5f$"%(d, float(h)))
     754        html(r"${c = }%s$"%latex(c))
     755        html(r"${f(c) = }%s"%latex(f(c)))
     756        html(r"$%s \text{ iterations}"%len(intervals))
     757        P = plot(f, a, b, color='red')
     758        k = (P.ymax() - P.ymin())/ (1.5*len(intervals))
     759        L = sum(line([(c,k*i), (d,k*i)]) for i, (c,d) in enumerate(intervals) )
     760        L += sum(line([(c,k*i-k/4), (c,k*i+k/4)]) for i, (c,d) in enumerate(intervals) )
     761        L += sum(line([(d,k*i-k/4), (d,k*i+k/4)]) for i, (c,d) in enumerate(intervals) )
     762        show(P + L, xmin=a, xmax=b)
     763
     764@library_interact
     765def secant_method(
     766    title = text_control('<h2>Secant method for numerical root finding</h2>'),
     767    f = input_box("x^2-2", label='f(x)'),
     768    interval = range_slider(-5,5,default=(0, 4), label="range"),
     769    d = slider(1, 16, 1, 3, label="10^-d precision"),
     770    maxn = slider(0,15,1,10, label="max iterations")):
     771    """
     772    Interact explaining the secant method, based on work by
     773    Lauri Ruotsalainen, 2010.
     774    Originally this is based on work by William Stein.
     775
     776    INPUT:
     777
     778      - ``f`` -- function
     779      - ``interval`` -- range slider for the search interval
     780      - ``d`` -- slider for the precision (10^-d)
     781      - ``maxn`` -- max number of iterations
     782
     783    EXAMPLES:
     784
     785    Invoked in the notebook, the following command will produce
     786    the fully formatted interactive mathlet.  In the command line,
     787    it will simply return the underlying HTML and Sage code which
     788    creates the mathlet::
     789
     790        sage: interacts.calculus.secant_method()
     791        <html>...</html>
     792    """
     793    def _secant_method(f, a, b, maxn, h):
     794        intervals = [(a,b)]
     795        round = 1
     796        while True:
     797            c = b-(b-a)*f(b)/(f(b)-f(a))
     798            if abs(f(c)) < h or round >= maxn:
     799                break
     800            a, b = b, c
     801            intervals.append((a,b))
     802            round += 1
     803        return c, intervals
     804
     805    x = SR.var('x')
     806    f = symbolic_expression(f).function(x)
     807    a, b = interval
     808    h = 10**(-d)
     809    if float(f(a)*f(b)) > 0:
     810        print "f must have opposite sign at the endpoints of the interval"
     811        show(plot(f, a, b, color='red'), xmin=a, xmax=b)
     812    else:
     813        c, intervals = _secant_method(f, float(a), float(b), maxn, h)
     814        html(r"$\text{Precision }h = 10^{-d}=10^{-%s}=%.5f$"%(d, float(h)))
     815        html(r"${c = }%s$"%latex(c))
     816        html(r"${f(c) = }%s"%latex(f(c)))
     817        html(r"$%s \text{ iterations}"%len(intervals))
     818        P = plot(f, a, b, color='red')
     819        k = (P.ymax() - P.ymin())/ (1.5*len(intervals))
     820        L = sum(line([(c,k*i), (d,k*i)]) for i, (c,d) in enumerate(intervals) )
     821        L += sum(line([(c,k*i-k/4), (c,k*i+k/4)]) for i, (c,d) in enumerate(intervals) )
     822        L += sum(line([(d,k*i-k/4), (d,k*i+k/4)]) for i, (c,d) in enumerate(intervals) )
     823        S = sum(line([(c,f(c)), (d,f(d)), (d-(d-c)*f(d)/(f(d)-f(c)), 0)], color="green") for  (c,d) in intervals)
     824        show(P + L + S, xmin=a, xmax=b)
     825
     826@library_interact
     827def newton_method(
     828    title = text_control('<h2>Newton method</h2>'),
     829    f = input_box("x^2 - 2"),
     830    c = slider(-10,10, default=6, label='Start ($x$)'),
     831    d = slider(1, 16, 1, 3, label="$10^{-d}$ precision"),
     832    maxn = slider(0, 15, 1, 10, label="max iterations"),
     833    interval = range_slider(-10,10, default = (0,6), label="Interval"),
     834    list_steps = checkbox(default=False, label="List steps")):
     835    """
     836    Interact explaining the newton method, based on work by
     837    Lauri Ruotsalainen, 2010.
     838    Originally this is based on work by William Stein.
     839
     840    INPUT:
     841
     842      - ``f`` -- function
     843      - ``c`` -- starting position (`x`)
     844      - ``d`` -- slider for the precision (`10^{-d}`)
     845      - ``maxn`` -- max number of iterations
     846      - ``interval`` -- range slider for the search interval
     847      - ``list_steps`` -- checkbox, if true shows the steps numerically
     848
     849    EXAMPLES:
     850
     851    Invoked in the notebook, the following command will produce
     852    the fully formatted interactive mathlet.  In the command line,
     853    it will simply return the underlying HTML and Sage code which
     854    creates the mathlet::
     855
     856        sage: interacts.calculus.newton_method()
     857        <html>...</html>
     858    """
     859    def _newton_method(f, c, maxn, h):
     860        midpoints = [c]
     861        round = 1
     862        while True:
     863            c = c-f(c)/f.derivative(x)(x=c)
     864            midpoints.append(c)
     865            if f(c-h)*f(c+h) < 0 or round == maxn:
     866                break
     867            round += 1
     868        return c, midpoints
     869
     870    x = SR.var('x')
     871    f = symbolic_expression(f).function(x)
     872    a, b = interval
     873    h = 10**(-d)
     874    c, midpoints = _newton_method(f, float(c), maxn, h/2.0)
     875    html(r"$\text{Precision } 2h = %s$"%latex(float(h)))
     876    html(r"${c = }%s$"%c)
     877    html(r"${f(c) = }%s"%latex(f(c)))
     878    html(r"$%s \text{ iterations}"%len(midpoints))
     879    if list_steps:
     880        s = [["$n$","$x_n$","$f(x_n)$", "$f(x_n-h)\,f(x_n+h)$"]]
     881        for i, c in enumerate(midpoints):
     882            s.append([i+1, c, f(c), (c-h)*f(c+h)])
     883        html.table(s,header=True)
     884    else:
     885        P = plot(f, x, interval, color="blue")
     886        L = sum(line([(c, 0), (c, f(c))], color="green") for c in midpoints[:-1])
     887        for i in range(len(midpoints) - 1):
     888            L += line([(midpoints[i], f(midpoints[i])), (midpoints[i+1], 0)], color="red")
     889        show(P + L, xmin=interval[0], xmax=interval[1], ymin=P.ymin(), ymax=P.ymax())
     890
     891@library_interact
     892def trapezoid_integration(
     893    title = text_control('<h2>Trapezoid integration</h2>'),
     894    f = input_box(default = "x^2-5*x + 10", label='$f(x)=$'),
     895    n = slider(1,100,1,5, label='# divisions'),
     896    interval_input = selector(['from slider','from keyboard'], label='Integration interval', buttons=True),
     897    interval_s = range_slider(-10,10,default=(0,8), label="slider: "),
     898    interval_g = input_grid(1,2,default=[[0,8]], label="keyboard: "),
     899    output_form = selector(['traditional','table','none'], label='Computations form', buttons=True)
     900    ):
     901    """
     902    Interact explaining the trapezoid method for definite integrals, based on work by
     903    Lauri Ruotsalainen, 2010 (based on the application "Numerical integrals with various rules"
     904    by Marshall Hampton and Nick Alexander)
     905
     906    INPUT:
     907   
     908      - ``f`` -- function of variable x to integrate
     909      - ``n`` -- number of divisions
     910      - ``interval_input`` -- swithes the input for interval between slider and keyboard
     911      - ``interval_s`` -- slider for interval to integrate
     912      - ``interval_g`` -- input grid for interval to integrate
     913      - ``output_form`` -- the computation is formatted in a traditional form, in a table or missing
     914
     915    EXAMPLES:
     916
     917    Invoked in the notebook, the following command will produce
     918    the fully formatted interactive mathlet.  In the command line,
     919    it will simply return the underlying HTML and Sage code which
     920    creates the mathlet::
     921
     922        sage: interacts.calculus.trapezoid_integration()
     923        <html>...</html>
     924    """
     925    xs = []
     926    ys = []
     927    if interval_input == 'from slider':
     928        interval = interval_s
     929    else:
     930        interval = interval_g[0]
     931    h = float(interval[1]-interval[0])/n
     932    x = SR.var('x')
     933    f = symbolic_expression(f).function(x)
     934
     935    trapezoids = Graphics()
     936   
     937    for i in range(n):
     938        xi = interval[0] + i*h
     939        yi = f(xi)
     940        trapezoids += line([[xi, 0], [xi, yi], [xi + h, f(xi + h)],[xi + h, 0],[xi, 0]], rgbcolor = (1,0,0))
     941        xs.append(xi)
     942        ys.append(yi)
     943    xs.append(xi + h)
     944    ys.append(f(xi + h))
     945
     946    html(r'Function $f(x)=%s$'%latex(f(x)))
     947    show(plot(f, interval[0], interval[1]) + trapezoids, xmin = interval[0], xmax = interval[1])
     948   
     949    numeric_value = integral_numerical(f, interval[0], interval[1])[0]
     950    approx = h *(ys[0]/2 + sum([ys[i] for i in range(1,n)]) + ys[n]/2)
     951
     952    html(r'Integral value to seven decimal places is: $\displaystyle\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x} = %.6f$'%(           
     953            interval[0], interval[1], N(numeric_value, digits=7))
     954         )
     955
     956    if output_form == 'traditional':
     957        sum_formula_html = r"\frac {d}{2} \cdot \left[f(x_0) + %s + f(x_{%s})\right]" % (
     958            ' + '.join([ "2 f(x_{%s})"%i for i in range(1,n)]),
     959            n
     960            )
     961        sum_placement_html = r"\frac{%.2f}{2} \cdot \left[f(%.2f) + %s + f(%.2f)\right]" % (
     962            h,
     963            N(xs[0], digits=5),
     964            ' + '.join([ "2 f(%.2f)" %N(i, digits=5) for i in xs[1:-1]]),
     965            N(xs[n], digits=5)
     966            )
     967        sum_values_html = r"\frac{%.2f}{2} \cdot \left[%.2f + %s + %.2f\right]" % (
     968            h,
     969            N(ys[0], digits=5),
     970            ' + '.join([ "2\cdot %.2f" % N(i, digits=5) for i in ys[1:-1]]),
     971            N(ys[n], digits=5)
     972            )
     973
     974        html(r'''
     975            <div class="math">
     976            \begin{align*}
     977            \int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x}
     978                & \approx %s \\
     979                & = %s \\
     980                & = %s \\
     981                & = %s
     982            \end{align*}
     983            </div>
     984        ''' % (
     985                interval[0], interval[1],
     986                sum_formula_html, sum_placement_html, sum_values_html,
     987                N(approx, digits=7)
     988        ))
     989    elif output_form == 'table':
     990        s = [['$i$','$x_i$','$f(x_i)$','$m$','$m\cdot f(x_i)$']]
     991        for i in range(0,n+1):
     992            if i==0 or i==n:
     993                j = 1
     994            else:
     995                j = 2
     996            s.append([i, xs[i], ys[i],j,N(j*ys[i])])
     997        html.table(s,header=True)
     998
     999@library_interact
     1000def simpson_integration(
     1001    title = text_control('<h2>Simpson integration</h2>'),
     1002    f = input_box(default = 'x*sin(x)+x+1', label='$f(x)=$'),
     1003    n = slider(2,100,2,6, label='# divisions'),
     1004    interval_input = selector(['from slider','from keyboard'], label='Integration interval', buttons=True),
     1005    interval_s = range_slider(-10,10,default=(0,10), label="slider: "),
     1006    interval_g = input_grid(1,2,default=[[0,10]], label="keyboard: "),
     1007    output_form = selector(['traditional','table','none'], label='Computations form', buttons=True)):
     1008    """
     1009    Interact explaining the simpson method for definite integrals, based on work by
     1010    Lauri Ruotsalainen, 2010 (based on the application "Numerical integrals with various rules"
     1011    by Marshall Hampton and Nick Alexander)
     1012
     1013    INPUT:
     1014   
     1015      - ``f`` -- function of variable x to integrate
     1016      - ``n`` -- number of divisions (mult. of 2)
     1017      - ``interval_input`` -- swithes the input for interval between slider and keyboard
     1018      - ``interval_s`` -- slider for interval to integrate
     1019      - ``interval_g`` -- input grid for interval to integrate
     1020      - ``output_form`` -- the computation is formatted in a traditional form, in a table or missing
     1021
     1022    EXAMPLES:
     1023
     1024    Invoked in the notebook, the following command will produce
     1025    the fully formatted interactive mathlet.  In the command line,
     1026    it will simply return the underlying HTML and Sage code which
     1027    creates the mathlet::
     1028
     1029        sage: interacts.calculus.simpson_integration()
     1030        <html>...</html>
     1031    """
     1032    x = SR.var('x')
     1033    f = symbolic_expression(f).function(x)
     1034    if interval_input == 'from slider':
     1035        interval = interval_s
     1036    else:
     1037        interval = interval_g[0]
     1038    def parabola(a, b, c):
     1039        from sage.all import solve
     1040        A, B, C = SR.var("A, B, C")
     1041        K = solve([A*a[0]**2+B*a[0]+C==a[1], A*b[0]**2+B*b[0]+C==b[1], A*c[0]**2+B*c[0]+C==c[1]], [A, B, C], solution_dict=True)[0]
     1042        f = K[A]*x**2+K[B]*x+K[C]
     1043        return f
     1044    xs = []; ys = []
     1045    dx = float(interval[1]-interval[0])/n
     1046   
     1047    for i in range(n+1):
     1048        xs.append(interval[0] + i*dx)
     1049        ys.append(f(x=xs[-1]))
     1050
     1051    parabolas = Graphics()
     1052    lines = Graphics()
     1053   
     1054    for i in range(0, n-1, 2):
     1055        p = parabola((xs[i],ys[i]),(xs[i+1],ys[i+1]),(xs[i+2],ys[i+2]))
     1056        parabolas += plot(p(x=x), (x, xs[i], xs[i+2]), color="red")
     1057        lines += line([(xs[i],ys[i]), (xs[i],0), (xs[i+2],0)],color="red")
     1058        lines += line([(xs[i+1],ys[i+1]), (xs[i+1],0)], linestyle="-.", color="red")
     1059       
     1060    lines += line([(xs[-1],ys[-1]), (xs[-1],0)], color="red")
     1061   
     1062    html(r'Function $f(x)=%s$'%latex(f(x)))
     1063
     1064    show(plot(f(x),x,interval[0],interval[1]) + parabolas + lines, xmin = interval[0], xmax = interval[1])
     1065   
     1066    numeric_value = integral_numerical(f,interval[0],interval[1])[0]
     1067    approx = dx/3 *(ys[0] + sum([4*ys[i] for i in range(1,n,2)]) + sum([2*ys[i] for i in range(2,n,2)]) + ys[n])
     1068   
     1069    html(r'Integral value to seven decimal places is: $\displaystyle\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x} = %.6f$'%
     1070         (interval[0],interval[1],
     1071         N(numeric_value,digits=7)))
     1072
     1073    if output_form == 'traditional':
     1074        sum_formula_html = r"\frac{d}{3} \cdot \left[ f(x_0) + %s + f(x_{%s})\right]" % (
     1075            ' + '.join([ r"%s \cdot f(x_{%s})" %(i%2*(-2)+4, i+1) for i in range(0,n-1)]),
     1076            n
     1077            )
     1078   
     1079        sum_placement_html = r"\frac{%.2f}{3} \cdot \left[ f(%.2f) +  %s + f(%.2f)\right]" % (
     1080            dx,
     1081            N(xs[0],digits=5),
     1082            ' + '.join([ r"%s \cdot f(%.2f)" %(i%2*(-2)+4, N(xk, digits=5)) for i, xk in enumerate(xs[1:-1])]),
     1083            N(xs[n],digits=5)
     1084            )
     1085   
     1086        sum_values_html = r"\frac{%.2f}{3} \cdot \left[ %s %s %s\right]" %(
     1087            dx,
     1088            "%.2f + "%N(ys[0],digits=5),
     1089            ' + '.join([ r"%s \cdot %.2f" %(i%2*(-2)+4, N(yk, digits=5)) for i, yk in enumerate(ys[1:-1])]),
     1090            " + %.2f"%N(ys[n],digits=5)
     1091            )
     1092       
     1093        html(r'''
     1094        <div class="math">
     1095        \begin{align*}
     1096        \int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x}
     1097            & \approx %s \\
     1098            & = %s \\
     1099            & = %s \\
     1100            & = %.6f
     1101        \end{align*}
     1102        </div>
     1103        ''' % (
     1104                interval[0], interval[1],
     1105                sum_formula_html, sum_placement_html, sum_values_html,
     1106                N(approx,digits=7)
     1107                ))
     1108    elif output_form == 'table':
     1109        s = [['$i$','$x_i$','$f(x_i)$','$m$','$m\cdot f(x_i)$']]
     1110        for i in range(0,n+1):
     1111            if i==0 or i==n:
     1112                j = 1
     1113            else:
     1114                j = (i+1)%2*(-2)+4
     1115            s.append([i, xs[i], ys[i],j,N(j*ys[i])])
     1116        s.append(['','','','$\sum$','$%s$'%latex(3/dx*approx)])
     1117        html.table(s,header=True)
     1118        html(r'$\int_{%.2f}^{%.2f} {f(x) \, \mathrm{d}x}\approx\frac {%.2f}{3}\cdot %s=%s$'%
     1119             (interval[0], interval[1],dx,latex(3/dx*approx),latex(approx)))
     1120       
     1121@library_interact
     1122def riemann_sum(
     1123    title = text_control('<h2>Riemann integral with random sampling</h2>'),
     1124    f = input_box("x^2+1", label = "$f(x)=$", width=40),
     1125    n = slider(1,30,1,5, label='# divisions'),
     1126    hr1 = text_control('<hr>'),
     1127    interval_input = selector(['from slider','from keyboard'], label='Integration interval', buttons=True),
     1128    interval_s = range_slider(-5,10,default=(0,2), label="slider: "),
     1129    interval_g = input_grid(1,2,default=[[0,2]], label="keyboard: "),
     1130    hr2 = text_control('<hr>'),
     1131    list_table = checkbox(default=False, label="List table"),   
     1132    auto_update = False):
     1133    """
     1134    Interact explaining the definition of Riemann integral
     1135
     1136    INPUT:
     1137   
     1138    - ``f`` -- function of variable x to integrate
     1139    - ``n`` -- number of divisions
     1140      - ``interval_input`` -- swithes the input for interval between slider and keyboard
     1141      - ``interval_s`` -- slider for interval to integrate
     1142      - ``interval_g`` -- input grid for interval to integrate
     1143    - ``list_table`` -- print table with values of the function
     1144
     1145    EXAMPLES:
     1146
     1147    Invoked in the notebook, the following command will produce
     1148    the fully formatted interactive mathlet.  In the command line,
     1149    it will simply return the underlying HTML and Sage code which
     1150    creates the mathlet::
     1151
     1152        sage: interacts.calculus.riemann_sum()
     1153        <html>...</html>
     1154
     1155    AUTHORS:
     1156
     1157    - Robert Marik (08-2010)
     1158    """
     1159    x = SR.var('x')
     1160    from random import random
     1161    if interval_input == 'from slider':
     1162        a = interval_s[0]
     1163        b = interval_s[1]
     1164    else:
     1165        a = interval_g[0][0]
     1166        b = interval_g[0][1]
     1167    func = symbolic_expression(f).function(x)
     1168    division = [a]+[a+random()*(b-a) for i in range(n-1)]+[b]
     1169    division = [i for i in division]
     1170    division.sort()
     1171    xs = [division[i]+random()*(division[i+1]-division[i]) for i in range(n)]
     1172    ys = [func(x_val) for x_val in xs]
     1173    rects = Graphics()
     1174    for i in range(n):
     1175        body=[[division[i],0],[division[i],ys[i]],[division[i+1],ys[i]],[division[i+1],0]]
     1176        if ys[i].n()>0:
     1177            color_rect='green'
     1178        else:
     1179            color_rect='red'
     1180        rects = rects +polygon2d(body, rgbcolor = color_rect,alpha=0.1)\
     1181         + point((xs[i],ys[i]), rgbcolor = (1,0,0))\
     1182         + line(body,rgbcolor='black',zorder=-1)
     1183    html('<small>Adjust your data and click Update button. Click repeatedly for another random values.</small>')
     1184   
     1185    show(plot(func(x),(x,a,b),zorder=5) + rects)
     1186    delka_intervalu=[division[i+1]-division[i] for i in range(n)]
     1187    if list_table:
     1188        html.table([["$i$","$[x_{i-1},x_i]$","$\eta_i$","$f(\eta_i)$","$x_{i}-x_{i-1}$"]]\
     1189        +[[i+1,[division[i],division[i+1]],xs[i],ys[i],delka_intervalu[i]] for i in range(n)],\
     1190        header=True)
     1191
     1192    html('Riemann sum: $\displaystyle\sum_{i=1}^{%s} f(\eta_i)(x_i-x_{i-1})=%s$ '%
     1193         (latex(n),latex(sum([ys[i]*delka_intervalu[i] for i in range(n)]))))       
     1194    html('Exact value of the integral $\displaystyle\int_{%s}^{%s}%s\,\mathrm{d}x=%s$'%
     1195         (latex(a),latex(b),latex(func(x)),latex(integral_numerical(func(x),a,b)[0])))
     1196
     1197
     1198x = SR.var('x')
     1199@library_interact
     1200def function_tool(f=sin(x), g=cos(x), xrange=range_slider(-3,3,default=(0,1),label='x-range'),
     1201      yrange='auto',
     1202      a=1,
     1203      action=selector(['f', 'df/dx', 'int f', 'num f', 'den f', '1/f', 'finv',
     1204                       'f+a', 'f-a', 'f*a', 'f/a', 'f^a', 'f(x+a)', 'f(x*a)',
     1205                       'f+g', 'f-g', 'f*g', 'f/g', 'f(g)'],
     1206             width=15, nrows=5, label="h = "),
     1207      do_plot = ("Draw Plots", True)):
     1208    """
     1209    `Function Plotting Tool <http://wiki.sagemath.org/interact/calculus#Functiontool>`_
     1210    (by William Stein (?))
     1211
     1212    INPUT:
     1213   
     1214      - ``f`` -- function f(x)
     1215      - ``g`` -- function g(x)
     1216      - ``xrange`` -- range for plotting (x)
     1217      - ``yrange`` -- range for plotting ('auto' is default, otherwise a tuple)
     1218      - ``a`` -- factor ``a``
     1219      - ``action`` -- select given operation on or combination of functions
     1220      - ``do_plot`` -- if true, a plot is drawn
     1221
     1222    EXAMPLE:
     1223
     1224    Invoked in the notebook, the following command will produce
     1225    the fully formatted interactive mathlet.  In the command line,
     1226    it will simply return the underlying HTML and Sage code which
     1227    creates the mathlet::
     1228
     1229        sage: interacts.calculus.function_tool()
     1230        <html>...</html>
     1231    """
     1232    x = SR.var('x')
     1233    try:
     1234        f = SR(f); g = SR(g); a = SR(a)
     1235    except TypeError, msg:
     1236        print msg[-200:]
     1237        print "Unable to make sense of f,g, or a as symbolic expressions in single variable x."
     1238        return
     1239    if not (isinstance(xrange, tuple) and len(xrange) == 2):
     1240          xrange = (0,1)
     1241    h = 0; lbl = ''
     1242    if action == 'f':
     1243        h = f
     1244        lbl = 'f'
     1245    elif action == 'df/dx':
     1246        h = f.derivative(x)
     1247        lbl = r'\frac{\mathrm{d}f}{\mathrm{d}x}'
     1248    elif action == 'int f':
     1249        h = f.integrate(x)
     1250        lbl = r'\int f \,\mathrm{d}x'
     1251    elif action == 'num f':
     1252        h = f.numerator()
     1253        lbl = r'\text{numer(f)}'
     1254    elif action == 'den f':
     1255        h = f.denominator()
     1256        lbl = r'\text{denom(f)}'
     1257    elif action == '1/f':
     1258        h = 1/f
     1259        lbl = r'\frac{1}{f}'
     1260    elif action == 'finv':
     1261        h = solve(f == var('y'), x)[0].rhs()
     1262        lbl = 'f^{-1}(y)'
     1263    elif action == 'f+a':
     1264        h = f+a
     1265        lbl = 'f + a'
     1266    elif action == 'f-a':
     1267        h = f-a
     1268        lbl = 'f - a'
     1269    elif action == 'f*a':
     1270        h = f*a
     1271        lbl = r'f \times a'
     1272    elif action == 'f/a':
     1273        h = f/a
     1274        lbl = r'\frac{f}{a}'
     1275    elif action == 'f^a':
     1276        h = f**a
     1277        lbl = 'f^a'
     1278    elif action == 'f^a':
     1279        h = f**a
     1280        lbl = 'f^a'
     1281    elif action == 'f(x+a)':
     1282        h = f.subs(x=x+a)
     1283        lbl = 'f(x+a)'
     1284    elif action == 'f(x*a)':
     1285        h = f.subs(x=x*a)
     1286        lbl = 'f(xa)'
     1287    elif action == 'f+g':
     1288        h = f+g
     1289        lbl = 'f + g'
     1290    elif action == 'f-g':
     1291        h = f-g
     1292        lbl = 'f - g'
     1293    elif action == 'f*g':
     1294        h = f*g
     1295        lbl = r'f \times g'
     1296    elif action == 'f/g':
     1297        h = f/g
     1298        lbl = r'\frac{f}{g}'
     1299    elif action == 'f(g)':
     1300        h = f(g)
     1301        lbl = 'f(g)'
     1302    html('<center><font color="red">$f = %s$</font></center>'%latex(f))
     1303    html('<center><font color="green">$g = %s$</font></center>'%latex(g))
     1304    html('<center><font color="blue"><b>$h = %s = %s$</b></font></center>'%(lbl, latex(h)))
     1305    if do_plot:
     1306        P = plot(f, xrange, color='red', thickness=2) +  \
     1307            plot(g, xrange, color='green', thickness=2) + \
     1308            plot(h, xrange, color='blue', thickness=2)
     1309        if yrange == 'auto':
     1310            show(P, xmin=xrange[0], xmax=xrange[1])
     1311        else:
     1312            yrange = sage_eval(yrange)
     1313            show(P, xmin=xrange[0], xmax=xrange[1], ymin=yrange[0], ymax=yrange[1])
     1314
     1315@library_interact
     1316def julia(expo = slider(-10,10,0.1,2),
     1317    c_real = slider(-2,2,0.01,0.5, label='real part const.'),
     1318    c_imag = slider(-2,2,0.01,0.5, label='imag part const.'),
     1319    iterations=slider(1,100,1,20, label='# iterations'),
     1320    zoom_x = range_slider(-2,2,0.01,(-1.5,1.5), label='Zoom X'),
     1321    zoom_y = range_slider(-2,2,0.01,(-1.5,1.5), label='Zoom Y'),
     1322    plot_points = slider(20,400,20, default=150, label='plot points'),
     1323    dpi = slider(20, 200, 10, default=80, label='dpi')):
     1324    """
     1325    Julia Fractal, based on
     1326    `Julia by Harald Schilly <http://wiki.sagemath.org/interact/fractal#Julia>`_.
     1327
     1328    INPUT:
     1329   
     1330        - ``exponent`` -- exponent ``e`` in `z^e+c`
     1331        - ``c_real`` -- real part of the constant ``c``
     1332        - ``c_imag`` -- imaginary part of the constant ``c``
     1333        - ``iterations`` -- number of iterations
     1334        - ``zoom_x`` -- range slider for zoom in x direction
     1335        - ``zoom_y`` -- range slider for zoom in y direction
     1336        - ``plot_points`` -- number of points to plot
     1337        - ``dpi`` -- dots-per-inch parameter for the plot
     1338
     1339    EXAMPLE:
     1340
     1341    Invoked in the notebook, the following command will produce
     1342    the fully formatted interactive mathlet.  In the command line,
     1343    it will simply return the underlying HTML and Sage code which
     1344    creates the mathlet::
     1345
     1346        sage: interacts.fractals.julia()
     1347        <html>...</html>
     1348    """
     1349    z = SR.var('z')
     1350    I = CDF.gen()   
     1351    f = symbolic_expression(z**expo + c_real + c_imag*I).function(z)
     1352    ff_j = fast_callable(f, vars=[z], domain=CDF)
     1353
     1354    from sage.interacts.library_cython import julia
     1355
     1356    html('<h2>Julia Fractal</h2>')
     1357    html(r'Recursive Formula: $z \leftarrow z^{%.2f} + (%.2f+%.2f*\mathbb{I})$' % (expo, c_real, c_imag))
     1358    complex_plot(lambda z: julia(ff_j, z, iterations), zoom_x, zoom_y, plot_points=plot_points, dpi=dpi).show(frame=True, aspect_ratio=1)
     1359
     1360@library_interact
     1361def mandelbrot(expo = slider(-10,10,0.1,2),
     1362    iterations=slider(1,100,1,20, label='# iterations'),
     1363    zoom_x = range_slider(-2,2,0.01,(-2,1), label='Zoom X'),
     1364    zoom_y = range_slider(-2,2,0.01,(-1.5,1.5), label='Zoom Y'),
     1365    plot_points = slider(20,400,20, default=150, label='plot points'),
     1366    dpi = slider(20, 200, 10, default=80, label='dpi')):
     1367    """
     1368    Mandelbrot Fractal, based on
     1369    `Mandelbrot by Harald Schilly <http://wiki.sagemath.org/interact/fractal#Mandelbrot>`_.
     1370
     1371    INPUT:
     1372   
     1373        - ``exponent`` -- exponent ``e`` in `z^e+c`
     1374        - ``iterations`` -- number of iterations
     1375        - ``zoom_x`` -- range slider for zoom in x direction
     1376        - ``zoom_y`` -- range slider for zoom in y direction
     1377        - ``plot_points`` -- number of points to plot
     1378        - ``dpi`` -- dots-per-inch parameter for the plot
     1379
     1380    EXAMPLE:
     1381
     1382    Invoked in the notebook, the following command will produce
     1383    the fully formatted interactive mathlet.  In the command line,
     1384    it will simply return the underlying HTML and Sage code which
     1385    creates the mathlet::
     1386
     1387        sage: interacts.fractals.mandelbrot()
     1388        <html>...</html>
     1389    """
     1390    x, z, c = SR.var('x, z, c')
     1391    f = symbolic_expression(z**expo + c).function(z, c)
     1392    ff_m = fast_callable(f, vars=[z,c], domain=CDF)
     1393
     1394    from sage.interacts.library_cython import mandel
     1395
     1396    html('<h2>Mandelbrot Fractal</h2>')
     1397    html(r'Recursive Formula: $z \leftarrow z^{%.2f} + c$ for $c \in \mathbb{C}$' % expo)
     1398    complex_plot(lambda z: mandel(ff_m, z, iterations), zoom_x, zoom_y, plot_points=plot_points, dpi=dpi).show(frame=True, aspect_ratio=1)
     1399
     1400
     1401@library_interact
     1402def cellular_automaton(
     1403    N=slider(1,500,1,label='Number of iterations',default=100),
     1404    rule_number=slider(0, 255, 1, default=110, label='Rule number'),
     1405    size = slider(1, 11, step_size=1, default=6, label='size of graphic')):
     1406    """
     1407    Yields a matrix showing the evolution of a
     1408    `Wolfram's cellular automaton <http://mathworld.wolfram.com/CellularAutomaton.html>`_.
     1409
     1410    `Based on work by Pablo Angulo <http://wiki.sagemath.org/interact/misc#CellularAutomata>`_.
     1411
     1412    INPUT:
     1413
     1414        - ``N`` -- iterations
     1415        - ``rule_number`` -- rule number (0 to 255)
     1416        - ``size`` -- size of the shown picture
     1417
     1418    EXAMPLE:
     1419
     1420    Invoked in the notebook, the following command will produce
     1421    the fully formatted interactive mathlet.  In the command line,
     1422    it will simply return the underlying HTML and Sage code which
     1423    creates the mathlet::
     1424
     1425        sage: interacts.fractals.cellular_automaton()
     1426        <html>...</html>
     1427    """
     1428    from sage.all import Integer
     1429    if not 0 <= rule_number <= 255:
     1430        raise Exception('Invalid rule number')
     1431    binary_digits = Integer(rule_number).digits(base=2)
     1432    rule = binary_digits + [0]*(8-len(binary_digits))
     1433
     1434    html('<h2>Cellular Automaton</h2>'+
     1435         '<div style="white-space: normal;">"A cellular automaton is a collection of "colored" cells \
     1436         on a grid of specified shape that evolves through a number of \
     1437         discrete time steps according to a set of rules based on the \
     1438         states of neighboring cells." &mdash; \
     1439         <a target="_blank" href="http://mathworld.wolfram.com/CellularAutomaton.html">Mathworld,\
     1440         Cellular Automaton</a></div>\
     1441         <div>Rule %s expands to %s</div>' % (rule_number, ''.join(map(str,rule)))
     1442        )
     1443
     1444    from sage.interacts.library_cython import cellular
     1445    M = cellular(rule, N)
     1446    plot_M = matrix_plot(M)
     1447    plot_M.show(figsize=[size,size])
     1448
     1449
     1450@library_interact
     1451def polar_prime_spiral(
     1452    interval = range_slider(1, 4000, 10, default=(1, 1000), label="range"),
     1453    show_factors = True,
     1454    highlight_primes = True,
     1455    show_curves = True,
     1456    n = slider(1,200, 1, default=89, label="number $n$"),
     1457    dpi = slider(10,300, 10, default=100, label="dpi")):
     1458    """
     1459    Polar Prime Spiral interact, based on work by David Runde.
     1460
     1461    For more information about the factors in the spiral,
     1462    `visit John Williamson's website <http://www.dcs.gla.ac.uk/~jhw/spirals/index.html>`_.
     1463
     1464    INPUT:
     1465
     1466        - ``interval`` -- range slider to specify start and end
     1467        - ``show_factors`` -- if true, show factors
     1468        - ``highlight_primes`` -- if true, prime numbers are highlighted
     1469        - ``show_curves`` -- if true, curves are plotted
     1470        - ``n`` -- number `n`
     1471        - ``dpi`` -- dots per inch resolution for plotting
     1472
     1473    EXAMPLE:
     1474
     1475    Invoked in the notebook, the following command will produce
     1476    the fully formatted interactive mathlet.  In the command line,
     1477    it will simply return the underlying HTML and Sage code which
     1478    creates the mathlet::
     1479
     1480        sage: sage.interacts.algebra.polar_prime_spiral()
     1481        <html>...</html>
     1482
     1483    """
     1484
     1485    html('<h2>Polar Prime Spiral</h2> \
     1486          <div style="white-space: normal;">\
     1487          For more information about the factors in the spiral, visit \
     1488          <a href="http://www.dcs.gla.ac.uk/~jhw/spirals/index.html" target="_blank">\
     1489          Number Spirals by John Williamson</a>.</div>'
     1490        )
     1491
     1492    start, end = interval
     1493    from sage.ext.fast_eval import fast_float
     1494    from math import floor, ceil
     1495    from sage.plot.colors import hue
     1496
     1497    if start < 1 or end <= start:
     1498        print "invalid start or end value"
     1499        return
     1500    if n > end:
     1501        print "WARNING: n is greater than end value"
     1502        return
     1503    if n < start:
     1504        print "n < start value"
     1505        return
     1506    nn = SR.var('nn')
     1507    f1 = fast_float(sqrt(nn)*cos(2*pi*sqrt(nn)), 'nn')
     1508    f2 = fast_float(sqrt(nn)*sin(2*pi*sqrt(nn)), 'nn')
     1509    f = lambda x: (f1(x), f2(x))
     1510   
     1511    list =[]
     1512    list2=[]
     1513    if show_factors == False:
     1514        for i in srange(start, end, include_endpoint = True):
     1515            if Integer(i).is_pseudoprime(): list.append(f(i-start+1)) #Primes list
     1516            else: list2.append(f(i-start+1)) #Composites list
     1517        P = points(list)
     1518        R = points(list2, alpha = .1) #Faded Composites
     1519    else:
     1520        for i in srange(start, end, include_endpoint = True):
     1521            list.append(disk((f(i-start+1)),0.05*pow(2,len(factor(i))-1), (0,2*pi))) #resizes each of the dots depending of the number of factors of each number
     1522            if Integer(i).is_pseudoprime() and highlight_primes: list2.append(f(i-start+1))
     1523        P = plot(list)
     1524        p_size = 5 #the orange dot size of the prime markers
     1525        if not highlight_primes: list2 = [(f(n-start+1))]
     1526        R = points(list2, hue = .1, pointsize = p_size)
     1527   
     1528    if n > 0:
     1529        html('$n = %s$' % factor(n))
     1530       
     1531        p = 1
     1532    #The X which marks the given n
     1533        W1 = disk((f(n-start+1)), p, (pi/6, 2*pi/6))
     1534        W2 = disk((f(n-start+1)), p, (4*pi/6, 5*pi/6))
     1535        W3 = disk((f(n-start+1)), p, (7*pi/6, 8*pi/6))
     1536        W4 = disk((f(n-start+1)), p, (10*pi/6, 11*pi/6))
     1537        Q = plot(W1 + W2 + W3 + W4, alpha = .1)         
     1538
     1539        n = n - start +1        #offsets the n for different start values to ensure accurate plotting
     1540        if show_curves:
     1541            begin_curve = 0
     1542            t = SR.var('t')
     1543            a=1.0
     1544            b=0.0
     1545            if n > (floor(sqrt(n)))**2 and n <= (floor(sqrt(n)))**2 + floor(sqrt(n)):
     1546                c = -((floor(sqrt(n)))**2 - n)
     1547                c2= -((floor(sqrt(n)))**2 + floor(sqrt(n)) - n)
     1548            else:
     1549                c = -((ceil(sqrt(n)))**2 - n)
     1550                c2= -((floor(sqrt(n)))**2 + floor(sqrt(n)) - n)
     1551            html('Pink Curve:  $n^2 + %s$' % c)
     1552            html('Green Curve: $n^2 + n + %s$' % c2)
     1553            m = SR.var('m')
     1554            g = symbolic_expression(a*m**2+b*m+c).function(m)
     1555            r = symbolic_expression(sqrt(g(m))).function(m)
     1556            theta = symbolic_expression(r(m)- m*sqrt(a)).function(m)
     1557            S1 = parametric_plot(((r(t))*cos(2*pi*(theta(t))),(r(t))*sin(2*pi*(theta(t)))),
     1558                 (begin_curve, ceil(sqrt(end-start))), color=hue(0.8), thickness = .3) #Pink Line
     1559
     1560            b = 1
     1561            c = c2;
     1562            g = symbolic_expression(a*m**2+b*m+c).function(m)
     1563            r = symbolic_expression(sqrt(g(m))).function(m)
     1564            theta = symbolic_expression(r(m)- m*sqrt(a)).function(m)
     1565            S2 = parametric_plot(((r(t))*cos(2*pi*(theta(t))),(r(t))*sin(2*pi*(theta(t)))),
     1566                 (begin_curve, ceil(sqrt(end-start))), color=hue(0.6), thickness = .3) #Green Line
     1567
     1568            show(R+P+S1+S2+Q, aspect_ratio = 1, axes = False, dpi = dpi)
     1569        else: show(R+P+Q, aspect_ratio = 1, axes = False, dpi = dpi)
     1570    else: show(R+P, aspect_ratio = 1, axes = False, dpi = dpi)
     1571
     1572
     1573
  • new file sage/interacts/library_cython.pyx

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/library_cython.pyx
    - +  
     1r"""
     2Library of cythonized methods
     3"""
     4
     5#*****************************************************************************
     6#       Copyright (C) 2010 Harald Schilly <harald.schilly@gmail.com>
     7#
     8# Distributed  under  the  terms  of  the  GNU  General  Public  License (GPL)
     9#                         http://www.gnu.org/licenses/
     10#*****************************************************************************
     11
     12from sage.misc.misc import prod
     13
     14include '../ext/interrupt.pxi'
     15include '../ext/cdefs.pxi'
     16include "../ext/stdsage.pxi"
     17
     18cpdef julia(ff_j, z, int iterations):
     19    """
     20    Helper function for the Julia Fractal interact example.
     21
     22    INPUT:
     23
     24        - `ff_j` -- fast callable for the inner iteration
     25        - `z` -- complex number
     26        - `iterations` -- number of loops
     27
     28    TESTS::
     29
     30        sage: from sage.interacts.library_cython import julia
     31        sage: z = var('z')
     32        sage: c_real, c_imag = 1, 1
     33        sage: f = symbolic_expression(z**2 + c_real + c_imag * CDF.gen()).function(z)
     34        sage: ff_m = fast_callable(f, vars=[z], domain=CDF)
     35        sage: julia(ff_m, CDF(1,1), 3)
     36        1.0 + 3.0*I
     37    """
     38    for i in range(iterations):
     39         z = ff_j(z)
     40         if z.abs() > 2: break
     41    return z
     42
     43cpdef mandel(ff_m, z, int iterations):
     44    """
     45    Helper function for the Mandelbrot Fractal interact example.
     46
     47    INPUT:
     48
     49        - `ff_m` -- fast callable for the inner iteration
     50        - `z` -- complex number
     51        - `iterations` -- number of loops
     52
     53    TESTS::
     54
     55        sage: from sage.interacts.library_cython import mandel
     56        sage: z, c = var('z, c')
     57        sage: f = symbolic_expression(z**2 + c).function(z,c)
     58        sage: ff_m = fast_callable(f, vars=[z,c], domain=CDF)
     59        sage: mandel(ff_m, CDF(1,1), 3)
     60        1.0 + 3.0*I
     61
     62    """
     63    c = z
     64    for i in range(iterations):
     65        z = ff_m(z, c)
     66        if z.abs() > 2: break
     67    return z
     68
     69
     70cpdef cellular(rule, int N):
     71    '''
     72    Cythonized helper function for the callular_automata fractal.
     73    Yields a matrix showing the evolution of a Wolfram's cellular automaton.
     74    Based on work by Pablo Angulo.
     75    http://wiki.sagemath.org/interact/misc#CellularAutomata
     76   
     77    INPUT:
     78
     79        - `rule` -- determines how a cell's value is updated, depending on its neighbors
     80        - `N` -- number of iterations
     81
     82    TESTS::
     83
     84        sage: from sage.interacts.library_cython import cellular
     85        sage: rule = [1, 0, 1, 0, 0, 1, 1, 0]
     86        sage: N = 3
     87        sage: print cellular(rule, 3)
     88
     89    '''
     90    from numpy import zeros
     91    cdef int j, k, l
     92    M=zeros((N, 2*N+1), dtype=int)
     93    M[0,N]=1 
     94   
     95    for j in range(1, N):
     96        for k in range(N-j, N+j+1):
     97            l = 4 * M[j-1, k-1] + 2 * M[j-1, k] + M[j-1, k+1]
     98            M[j,k] = rule[l]
     99    return M
  • new file sage/interacts/statistics.py

    diff -r 4a9f7b41ae22 -r 6511ebf30f30 sage/interacts/statistics.py
    - +  
     1"""
     2Interacts for Statistics
     3
     4"""
     5
     6
     7#*****************************************************************************
     8#     Copyright (C) 2010 Harald Schilly <harald.schilly@gmail.com>
     9#
     10#  Distributed under the terms of the GNU General Public License (GPL)
     11#                  http://www.gnu.org/licenses/
     12#*****************************************************************************
     13
     14from library import coin