Differences between revisions 5 and 45 (spanning 40 versions)
Revision 5 as of 2008-08-12 19:25:28
Size: 4273
Editor: was
Comment:
Revision 45 as of 2020-06-02 02:16:48
Size: 12942
Editor: kcrisman
Comment:
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
goto [:interact:interact main page]


[[TableOfContents]]
goto [[interact|interact main page]]


<<TableOfContents>>

== Hearing a trigonometric identity ==
by Marshall Hampton. When the two frequencies are well separated, we hear the right hand side of the identity. When they start getting close, we hear the higher-pitched factor in the left-hand side modulated by the lower-pitched envelope.

{{{#!sagecell
import wave

class SoundFile:
   def __init__(self, signal,lab=''):
       self.file = wave.open('./test' + lab + '.wav', 'wb')
       self.signal = signal
       self.sr = int(4100)

   def write(self):
       self.file.setparams((1, 2, self.sr, 44100*4, 'NONE', 'noncompressed'))
       self.file.writeframes(self.signal)
       self.file.close()

mypi = float(pi)
from math import sin

@interact
def sinsound(freq_ratio = slider(1/144,1,1/144,1/12)):
    hz1 = 440.0
    hz2 = float(440.0*2^freq_ratio)
    html(r'$\cos(\omega t) - \cos(\omega_0 t) = 2 \sin(\\frac{\omega + \omega_0}{2}t) \sin(\frac{\omega - \omega_0}{2}t)$')
    s2 = [sin(hz1*x*mypi*2)+sin(hz2*x*mypi*2) for x in srange(0,4,1/44100.0)]
    s2m = max(s2)
    s2f = [16384*x/s2m for x in s2]
    s2str = b''.join(wave.struct.pack('f',x) for x in s2f)
    lab="%1.2f"%float(freq_ratio)
    f = SoundFile(s2str,lab=lab)
    f.write()
    pnum = 1500+int(500/freq_ratio)
    show(list_plot(s2[0:pnum],plotjoined=True))
    pretty_print(html(r'<embed src="cell://test'+ lab +'.wav" width="200" height="100"></embed>'))
    pretty_print(html(r'Frequencies: $\omega_0 = {} $, $\omega = {}$'.format(str(hz1),latex(hz2))))
}}}
{{attachment:sinsound.png}}

== Karplus-Strong algorithm for plucked and percussive sound generation ==
by Marshall Hampton

{{{#!sagecell
import wave

class SoundFile:
   def __init__(self, signal,lab=''):
       self.file = wave.open('./test' + lab + '.wav', 'wb')
       self.signal = signal
       self.sr = int(44100)

   def write(self):
       self.file.setparams((1, 2, self.sr, 44100*4, 'NONE', 'noncompressed'))
       self.file.writeframes(self.signal)
       self.file.close()

mypi = float(pi)
from math import sin

def ks(delay,length,blend = 0,filler=None,stretch=0):
    if filler == None:
        filler = [randint(-16383,16383) for q in range(delay+1)]
    outsig = filler[:]
    index = len(filler)
    while len(outsig) < length:
        s = random()
        if s > stretch:
            b = random()
            if b < 1-blend:
                newvalue = (outsig[index-delay]+outsig[index-delay-1])*.5
            else:
                newvalue = -(outsig[index-delay]+outsig[index-delay-1])*.5
        else:
            newvalue = outsig[index-delay]
        outsig.append(newvalue)
        index += 1
    return [int(round(x)) for x in outsig]

@interact
def sinsound(delay = slider([int(2^i) for i in range(2,10)], default=100, label="initial delay"), blend=slider(srange(0,1,.01,include_endpoint=True),default=0,label="blend factor"), stretch=slider(srange(0,1,.01,include_endpoint=True),default=0,label="stretch factor")):
    s2f = ks(delay,int(44100*(1/2)),blend=blend,stretch=stretch)
    for i in range(12):
        s2f = s2f + ks(int(2^((12+i)/12.0)*delay),int(44100*(1/2)),blend=blend, stretch=stretch)
    pretty_print(html("Karplus-Strong algorithm with blending and delay stretching"))
    pretty_print(html("<br>K. Karplus and A. Strong, <em>Digital synthesis of plucked string and drum timbres</em>, \nComputer Music Journal 7 (2) (1983), 43–55.<br>"))
    pretty_print(html("Initial waveform:"))
    show(list_plot(s2f[0:2000],plotjoined=True), figsize = [7,3.5])
    pretty_print(html("Waveform after stabilization:"))
    show(list_plot(s2f[20000:22000],plotjoined=True), figsize = [7,3.5])
    s2str = b''.join(wave.struct.pack('f',x) for x in s2f)
    lab=""
    f = SoundFile(s2str,lab=lab)
    f.write()
    pretty_print(html('<embed src="cell://test'+ lab +'.wav" width="200" height="100"></embed>'))
}}}

{{attachment:KarplusStrong.png}}
Line 9: Line 107:
{{{ {{{#!sagecell
Line 20: Line 118:
    XY = X.intersection(Y)
    XZ = X.intersection(Z)
    YZ = Y.intersection(Z)
    XYZ = XY.intersection(Z)
    XY = X & Y
    XZ = X & Z
    YZ = Y & Z
    XYZ = XY & Z
Line 25: Line 123:
    html("$X \cap Y$ = %s"%f(XY))
    html("$X \cap Z$ = %s"%f(XZ))
    html("$Y \cap Z$ = %s"%f(YZ))
    html("$X \cap Y \cap Z$ = %s"%f(XYZ))
    html("$X \\cap Y$ = {}".format(f(XY)))
    html("$X \\cap Z$ = {}".format(f(XZ)))
    html("$Y \\cap Z$ = {}".format(f(YZ)))
    html("$X \\cap Y \\cap Z$ = {}".format(f(XYZ)))
Line 50: Line 148:
        Z = set(S[i]).intersection(S[(i+1)%3]).difference(set(XYZ))         Z = (set(S[i]) & S[(i+1)%3]) - set(XYZ)
Line 59: Line 157:
}}

attachment:veng.png
}}}

{{attachment:veng.png}}
Line 65: Line 163:
{{{ {{{#!sagecell
Line 68: Line 166:
    print (lambda f:f(0,f))(     print((lambda f:f(0,f))(
Line 73: Line 171:
    )
}}}
attachment:unreadable.png
    ))
}}}
{{attachment:unreadable.png}}
Line 79: Line 177:
{{{ {{{#!sagecell
Line 86: Line 184:
    print "<html>" # trick to avoid word wrap
Line 88: Line 185:
        cProfile.run(cmd)         cProfile.runctx(cmd,globals(), locals())
Line 90: Line 187:
        profile.run(cmd)
   print "</html>"
}}}
attachment:profile.png
        profile.runctx(cmd,globals(), locals())
}}}
{{attachment:profile.png}}
Line 99: Line 195:
{{{ {{{#!sagecell
Line 102: Line 198:
    print globals()[system].eval(code)
}}}

attachment:evalsys.png

== A Random Walk ==

by William Stein

{{{
html('<h1>A Random Walk</h1>')
vv = []; nn = 0
@interact
def foo(pts = checkbox(True, "Show points"),
        refresh = checkbox(False, "New random walk every time"),
        steps = (50,(10..500))):
    # We cache the walk in the global variable vv, so that
    # checking or unchecking the points checkbox doesn't change
    # the random walk.
    html("<h2>%s steps</h2>"%steps)
    global vv
    if refresh or len(vv) == 0:
        s = 0; v = [(0,0)]
        for i in range(steps):
             s += random() - 0.5
             v.append((i, s))
        vv = v
    elif len(vv) != steps:
        # Add or subtract some points
        s = vv[-1][1]; j = len(vv)
        for i in range(steps - len(vv)):
            s += random() - 0.5
            vv.append((i+j,s))
        v = vv[:steps]
    print(globals()[system].eval(code))
}}}

{{attachment:evalsys.png}}


== Minkowski Sum ==
by Marshall Hampton
{{{#!sagecell
def minkdemo(list1, list2):
    '''
    Return the Minkowski sum of two lists.
    '''
    output = []
    for stuff1 in list1:
        for stuff2 in list2:
            output.append([a + b for a, b in zip(stuff1, stuff2)])
    return output

@interact
def minksumvis(x1tri=slider(-1,1,1/10,0, label='Triangle point x coord.'), yb=slider(1,4,1/10,2, label='Blue point y coord.')):
    t_list = [[1,0], [x1tri,1], [0,0]]
    kite_list = [[3, 0], [1, 0], [0, 1], [1, yb]]
    triangle = polygon([[q[0]-6,q[1]] for q in t_list], alpha = .5, rgbcolor = (1,0,0))
    t_vert = point([x1tri-6,1], rgbcolor = (1,0,0))
    b_vert = point([kite_list[3][0]-4,yb], rgbcolor = (0,0,1))
    kite = polygon([[q[0]-4,q[1]] for q in kite_list], alpha = .5,rgbcolor = (0,0,1))
    p12 = minkdemo(t_list, kite_list)
    p12 = [[q[0],q[1]] for q in p12]
    p12poly = Polyhedron(p12)
    edge_lines = Graphics()
    verts = p12poly.vertices()
    for v0, v1 in p12poly.graph().edges(False):
       edge_lines += line([v0, v1])
    triangle_sum = Graphics()
    for vert in kite_list:
        temp_list = []
        for q in t_list:
            temp_list.append([q[i] + vert[i] for i in range(len(t_list[0]))])
        triangle_sum += polygon(temp_list, alpha = .5, rgbcolor = (1,0,0))
    kite_sum = Graphics()
    for vert in t_list:
        temp_list = []
        for q in kite_list:
            temp_list.append([q[i] + vert[i] for i in range(len(t_list[0]))])
        kite_sum += polygon(temp_list, alpha = .3,rgbcolor = (0,0,1))
    labels = text('+', (-4.3,.5), rgbcolor = (0,0,0))
    labels += text('=', (-.2,.5), rgbcolor = (0,0,0))
    show(labels + t_vert + b_vert+ triangle + kite + triangle_sum + kite_sum + edge_lines, axes=False, figsize = [11.0*.7, 4*.7], xmin = -6, ymin = 0, ymax = 4)
}}}
{{attachment:minksum.png}}

== Cellular Automata ==
by Pablo Angulo, Eviatar Bach

{{{#!sagecell
from numpy import zeros
from random import randint

def cellular(rule, N, initial='Single-cell'):
    '''Yields a matrix showing the evolution of a Wolfram's cellular automaton
    
    rule: determines how a cell's value is updated, depending on its neighbors
    N: number of iterations
    initial: starting condition; can be either single-cell or a random binary row
    '''
    M=zeros( (N,2*N+2), dtype=int)
    if initial=='Single-cell':
        M[0,N]=1
Line 137: Line 268:
        v = vv
    L = line(v, rgbcolor='#4a8de2')
    if pts: L += points(v, pointsize=10, rgbcolor='red')
    show(L, xmin=0, figsize=[8,3])
}}}
attachment:randomwalk.png

== 3D Random Walk ==
{{{
@interact
def rwalk3d(n=(50,1000), frame=True):
    pnt = [0,0,0]
    v = [copy(pnt)]
    for i in range(n):
        pnt[0] += random()-0.5
        pnt[1] += random()-0.5
        pnt[2] += random()-0.5
        v.append(copy(pnt))
    show(line3d(v,color='black'),aspect_ratio=[1,1,1],frame=frame)
}}}
attachment:randomwalk3d.png
        M[0]=[randint(0,1) for a in range(2*N+2)]
    
    for j in range(1,N):
        for k in range(2*N):
            l = 4*M[j-1,k-1] + 2*M[j-1,k] + M[j-1,k+1]
            M[j,k]=rule[ l ]
    return M[:,:-1]
    
def num2rule(number):
    if not 0 <= number <= 255:
        raise Exception('Invalid rule number')
    binary_digits = number.digits(base=2)
    return binary_digits + [0]*(8-len(binary_digits))

@interact
def _( initial=selector(['Single-cell', 'Random'], label='Starting condition'), N=input_box(label='Number of iterations',default=100),
       rule_number=input_box(label='Rule number',default=110),
       size = slider(1, 11, label= 'Size', step_size=1, default=6 ), auto_update=False):
    rule = num2rule(rule_number)
    M = cellular(rule, N, initial)
    plot_M = matrix_plot(M, cmap='binary')
    plot_M.show( figsize=[size,size])
}}}
{{attachment:cellular2.png}}

== Another Interactive Venn Diagram ==
by Jane Long (adapted from http://wiki.sagemath.org/interact/misc)

This interact models a problem in which a certain number of people are surveyed to see if they participate in three different activities (running, biking, and swimming). Users can indicate the numbers of people in each category, from 0 to 100. Returns a graphic of a labeled Venn diagram with the number of people in each region. Returns an explanatory error message if user input is inconsistent.

{{{#!sagecell
@interact
def _(T=slider([0..100],default=100,label='People surveyed'),X=slider([0..100],default=28,label='Run'), Y=slider([0..100],default=33,label='Bike'), Z=slider([0..100],default=59,label='Swim'),XY=slider([0..100],default=16,label='Run and Bike'),XZ=slider([0..100],default=13,label='Run and Swim'),YZ=slider([0..100],default=12,label='Bike and Swim'),XYZ=slider([0..100],default=7,label='Run, Bike, and Swim')):
   
    centers = [(cos(n*2*pi/3), sin(n*2*pi/3)) for n in [0,1,2]]
    scale = 1.7
    clr = ['yellow', 'blue', 'green']
    G = Graphics()
    for i in range(3):
        G += circle(centers[i], scale, rgbcolor=clr[i],
             fill=True, alpha=0.3)
    for i in range(3):
        G += circle(centers[i], scale, rgbcolor='black')
   
    # Label sets
    G += text('Run',(3,0),rgbcolor='black')
    G += text('Bike',(-1,3),rgbcolor='black')
    G += text('Swim',(-1,-3),rgbcolor='black')
   
    # Plot pairs of intersections
    ZX=XZ-XYZ
    G += text(ZX, (1.3*cos(2*2*pi/3 + pi/3), 1.3*sin(2*2*pi/3 + pi/3)), rgbcolor='black')
    YX=XY-XYZ
    G += text(YX, (1.3*cos(0*2*pi/3 + pi/3), 1.3*sin(0*2*pi/3 + pi/3)), rgbcolor='black')
    ZY=YZ-XYZ
    G += text(ZY, (1.3*cos(1*2*pi/3 + pi/3), 1.3*sin(1*2*pi/3 + pi/3)), rgbcolor='black')
  
    # Plot what is in one but neither other
    XX=X-ZX-YX-XYZ
    G += text(XX, (1.5*centers[0][0],1.7*centers[0][1]), rgbcolor='black')
    YY=Y-ZY-YX-XYZ
    G += text(YY, (1.5*centers[1][0],1.7*centers[1][1]), rgbcolor='black')
    ZZ=Z-ZY-ZX-XYZ
    G += text(ZZ, (1.5*centers[2][0],1.7*centers[2][1]), rgbcolor='black')
 
    # Plot intersection of all three
    G += text(XYZ, (0,0), rgbcolor='black')
   
    # Indicate number not in X, in Y, or in Z
    C = T-XX-YY-ZZ-ZX-ZY-YX-XYZ
    G += text(C,(3,-3),rgbcolor='black')
    
    # Check reasonableness before displaying result
    if XYZ>XY or XYZ>XZ or XYZ>YZ or XY>X or XY>Y or XZ>X or XZ>Z or YZ>Y or YZ>Z or C<0 or XYZ<0 or XZ<0 or YZ<0 or XY<0 or X<0 or Y<0 or Z<0:
        print('This situation is impossible! (Why?)')
    else:
        G.show(aspect_ratio=1, axes=False)
}}}
{{attachment:vennjhl.png}}

Sage Interactions - Miscellaneous

goto interact main page

Hearing a trigonometric identity

by Marshall Hampton. When the two frequencies are well separated, we hear the right hand side of the identity. When they start getting close, we hear the higher-pitched factor in the left-hand side modulated by the lower-pitched envelope.

sinsound.png

Karplus-Strong algorithm for plucked and percussive sound generation

by Marshall Hampton

KarplusStrong.png

An Interactive Venn Diagram

veng.png

Unreadable code

by Igor Tolkov

unreadable.png

Profile a snippet of code

profile.png

Evaluate a bit of code in a given system

by William Stein (there is no way yet to make the text box big):

evalsys.png

Minkowski Sum

by Marshall Hampton

minksum.png

Cellular Automata

by Pablo Angulo, Eviatar Bach

cellular2.png

Another Interactive Venn Diagram

by Jane Long (adapted from http://wiki.sagemath.org/interact/misc)

This interact models a problem in which a certain number of people are surveyed to see if they participate in three different activities (running, biking, and swimming). Users can indicate the numbers of people in each category, from 0 to 100. Returns a graphic of a labeled Venn diagram with the number of people in each region. Returns an explanatory error message if user input is inconsistent.

vennjhl.png

interact/misc (last edited 2020-06-05 20:32:41 by mathzeta2)