Notebook template

Notes:

  • \(\LaTeX\): It renders correctly from the markdown file. The \(\LaTeX\) within the notebook markdown cells renders the equations, but not the inline math. TODO: fix this
  • When you reference a single cell, you can't say cells[4], you have to write cells[4:5].
  • The numbers in cells[m:n] don't refer to the "input numbers" you see in the notebook. The markdown cells are counted too. This makes it a bit of a pain to locate particular cells within a larger notebook.

Here I am selecting a cell from the notebook.

In [4]:
a = 0
b = 1
print(fib(a, b, 10))

a = 5
b = 6
print(fib(a, b, 10))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[5, 6, 11, 17, 28, 45, 73, 118, 191, 309]

Now I am displaying the whole notebook.

This is an example jupyter notebook.

Demo some things for reference:

  • make sure imports work
  • test plotting: %inline vs %notebook
  • import the whole notebook OR just selected pieces
  • does the notebook Markdown look OK when called into the webpage?
  • do the Markdown calls depend on the order of execution? or just the order in the notebook?

As a test project, we'll look at the Fibonacci numbers and make some plots of their ratios.

In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

Which versions of these packages will be found?

This notebook won't be running live on the website, so this will just depend on how I execute the cells locally. One question is whether or not this will be impacted by the virtual environment (that I am typically in when working on the site).

You can see below that it is independent of the virtual environment.

In [2]:
print(np.__version__)
print(np.__file__)

# This is something I know my site venv imports as an old version.
import nbconvert
print(nbconvert.__version__)
print(nbconvert.__file__)
1.19.5
/usr/local/lib/python3.8/site-packages/numpy/__init__.py
6.0.7
/usr/local/lib/python3.8/site-packages/nbconvert/__init__.py

Now let's do some example coding and plotting.

In [3]:
def fib(a, b, n):
    """Using `a` and `b` as seeds, return the n'th Fibonacci number.
    
    Example:
    a = 2, b = 5, n = 6
    
    Compute like this:
    (2, 5, 2 + 5 = 7, 5 + 7 = 12, 7 + 12 = 19, 12 + 19 = 31)
    """
    
    seq = [a, b]
    for i in range(n-2):
        seq.append(seq[-1] + seq[-2])
    return seq

Let's test this function.

In [4]:
a = 0
b = 1
print(fib(a, b, 10))

a = 5
b = 6
print(fib(a, b, 10))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[5, 6, 11, 17, 28, 45, 73, 118, 191, 309]

Let's look at the ratio of successive Fibonacci numbers for various choices of the seeds.

In [5]:
def ratio_plot(seq, ax=None):
    
    seq = np.array(seq)
    
    if ax is None:
        fig = plt.figure()
        ax = fig.gca()
    plt.plot(seq[1:] / seq[:-1], 'o-')

Plot one sequence of ratios.

In [6]:
a = 0
b = 1
seq = fib(a, b, 10)

ratio_plot(seq)
<ipython-input-5-9e1244002184>:8: RuntimeWarning: divide by zero encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')

Notice that the ratio seems to be stabilizing around 1.6 or so.

Now let's do this for many seed combinations.

In [7]:
fig = plt.figure()
ax = fig.gca()

n = 10

for a in range(4):
    for b in range(4):
        seq = fib(a, b, n)
        ratio_plot(seq, ax=ax)
<ipython-input-5-9e1244002184>:8: RuntimeWarning: invalid value encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')
<ipython-input-5-9e1244002184>:8: RuntimeWarning: divide by zero encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')
<ipython-input-5-9e1244002184>:8: RuntimeWarning: divide by zero encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')
<ipython-input-5-9e1244002184>:8: RuntimeWarning: divide by zero encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')
<ipython-input-5-9e1244002184>:8: RuntimeWarning: divide by zero encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')
<ipython-input-5-9e1244002184>:8: RuntimeWarning: divide by zero encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')
<ipython-input-5-9e1244002184>:8: RuntimeWarning: divide by zero encountered in true_divide
  plt.plot(seq[1:] / seq[:-1], 'o-')

Observations:

  • Ratios of successive Fibonacci numbers approach some constant value.
  • The constant value appears to be roughly 1.6 independent of the seeds.

Can we derive this value?

Let's see what the $ \LaTeX $ rendering looks like..

Assume there is some value $a$ that is the limit of this sequence of ratios.

Consider three adjacent values in the sequence $(x, y, x + y)$ near to the limit (making use of the physicist lemma).

Then the two ratios will be the same.

$$ \frac{y}{x} = \frac{x + y}{y} $$

We can scale the entire sequence so $x = 1$.

$$ \frac{y}{1} = \frac{1 + y}{y} $$

And rearrange.

$$ y^2 - y - 1 = 0 $$

Solving for the roots we find:

$$ y_+ = \frac{1 + \sqrt{5}}{2} , y_- = \frac{1 - \sqrt{5}}{2} $$$$ y_+ \simeq 1.618 , y_- \simeq -0.618 $$

Congrats! We uncovered the "golden ratio" $\phi = 1.618...$.

Armed with this information we are ready to build famous buildings, write magnificent symphonies, and film epic Hollywood movies.

Fewer have explored the lesser-known "ochre ratio" $ \theta = -0.618... $.

In [8]:
a = 1
ochre = (1 - 5**0.5)/2
seq = fib(a, ochre, 10)

ratio_plot(seq)
plt.ylim(-2, 2)
Out[8]:
(-2.0, 2.0)

This ratio has been important in things such as ultra-flat tables, horizon-design, and the limiting behavior of EEGs.

In [ ]:
 
Go Top