Ticket #9623: 9623-interact-examples.patch

File 9623-interact-examples.patch, 57.9 KB (added by schilly, 11 years ago)
  • doc/en/reference/index.rst

    # HG changeset patch
    # User Harald Schilly <harald.schilly@gmail.com>
    # Date 1280582452 -7200
    # Node ID dd9d78f1125180d10b04844cabf58d7d4aa3cefa
    # Parent  cb1ad1ee5bd452850fde04d47f9618dec4c3e997
    #9623 interacts for high school level education by Lauri Ruotsalainen and selected interact examples from wiki.sagemath.org/interacts
    
    diff -r cb1ad1ee5bd4 -r dd9d78f11251 doc/en/reference/index.rst
    a b  
    4545   calculus
    4646   plotting
    4747   plot3d
     48   interacts
    4849   games
    4950   graphs
    5051   constants
  • module_list.py

    diff -r cb1ad1ee5bd4 -r dd9d78f11251 module_list.py
    a b  
    451451
    452452    ################################
    453453    ##
     454    ## sage.interacts
     455    ##
     456    ################################
     457
     458    Extension('sage.interacts.library_cython',
     459              sources = ['sage/interacts/library_cython.pyx'],
     460              libraries = []),
     461
     462    ################################
     463    ##
    454464    ## sage.libs
    455465    ##
    456466    ################################
  • sage/interacts/__init__.py

    diff -r cb1ad1ee5bd4 -r dd9d78f11251 sage/interacts/__init__.py
    a b  
    22Interacts included with sage
    33"""
    44import calculus
    5 import library
     5import geometry
     6import statistics
     7import fractals
     8import algebra
  • new file sage/interacts/algebra.py

    diff -r cb1ad1ee5bd4 -r dd9d78f11251 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
  • sage/interacts/calculus.py

    diff -r cb1ad1ee5bd4 -r dd9d78f11251 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 practice_differentiating_polynomials, trigonometric_properties_triangle
     18from library import secant_method, newton_method, trapezoid_integration, simpson_integration
     19from library import function_tool
  • new file sage/interacts/fractals.py

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

    diff -r cb1ad1ee5bd4 -r dd9d78f11251 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 cb1ad1ee5bd4 -r dd9d78f11251 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