Ticket #9623: trac_9623_rebase_and_import_change.patch

File trac_9623_rebase_and_import_change.patch, 65.3 KB (added by mhampton, 10 years ago)

Rebases all previous patches against 4.6.1 and makes minor import changes

  • module_list.py

    # HG changeset patch
    # User Marshall Hampton <hamptonio@gmail.com>
    # Date 1294873282 21600
    # Node ID f711e2a0e1d559f83ba72655b703f8b7cc9d0548
    # Parent  c58f82863c75b2e53662e08cd550bb398653174c
    Trac #9623: rebasing and minor restructuring.
    
    diff -r c58f82863c75 -r f711e2a0e1d5 module_list.py
    a b  
    482482
    483483    ################################
    484484    ##
     485    ## sage.interacts
     486    ##
     487    ################################
     488
     489    Extension('sage.interacts.library_cython',
     490              sources = ['sage/interacts/library_cython.pyx'],
     491              libraries = []),
     492
     493    ################################
     494    ##
    485495    ## sage.libs
    486496    ##
    487497    ################################
  • sage/all.py

    diff -r c58f82863c75 -r f711e2a0e1d5 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
  • deleted file sage/interacts/__init__.py

    diff -r c58f82863c75 -r f711e2a0e1d5 sage/interacts/__init__.py
    + -  
    1 """
    2 Interacts included with sage
    3 """
    4 import calculus
    5 import library
  • new file sage/interacts/algebra.py

    diff -r c58f82863c75 -r f711e2a0e1d5 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 c58f82863c75 -r f711e2a0e1d5 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 c58f82863c75 -r f711e2a0e1d5 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 c58f82863c75 -r f711e2a0e1d5 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 c58f82863c75 -r f711e2a0e1d5 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, cube_hemisphere
     15from library import trigonometric_properties_triangle, special_points
  • sage/interacts/library.py

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

    diff -r c58f82863c75 -r f711e2a0e1d5 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 c58f82863c75 -r f711e2a0e1d5 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