Ticket #9623: trac_9623_rebase_and_import_change_v2.patch

File trac_9623_rebase_and_import_change_v2.patch, 64.9 KB (added by mhampton, 10 years ago)

Apply only this patch; using Jason's idea from #10622

  • module_list.py

    # HG changeset patch
    # User Marshall Hampton <hamptonio@gmail.com>
    # Date 1294873282 21600
    # Node ID 8a3cf6e1592a06861d4e27a04cc5b57b4233f63a
    # Parent  9067e00885fed8c35d14e8ff160c291cd8045cf8
    Trac #9623: rebasing and minor restructuring.
    
    diff -r 9067e00885fe -r 8a3cf6e1592a module_list.py
    a b  
    489489
    490490    ################################
    491491    ##
     492    ## sage.interacts
     493    ##
     494    ################################
     495
     496    Extension('sage.interacts.library_cython',
     497              sources = ['sage/interacts/library_cython.pyx'],
     498              libraries = []),
     499
     500    ################################
     501    ##
    492502    ## sage.libs
    493503    ##
    494504    ################################
  • sage/all.py

    diff -r 9067e00885fe -r 8a3cf6e1592a sage/all.py
    a b  
    132132
    133133import sage.finance.all  as finance
    134134
    135 import sage.interacts as interacts
     135import sage.interacts.all as interacts
    136136
    137137from sage.parallel.all   import *
    138138
  • sage/interacts/__init__.py

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

    diff -r 9067e00885fe -r 8a3cf6e1592a 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 9067e00885fe -r 8a3cf6e1592a 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