```python
import ipywidgets as widgets
```

# Inductive Reasoning and Deductive Reasoning

There are two forms of reasoning that that are useful when investigating a piece of mathematics.

* `Inductive reasoning` involves looking for __patterns__ in evidence in order to come up with conjectures (i.e. things that are likely to be true). This sort of reasoning will __not__ tell you whether or not something actually _is_ true but it is still very useful for making connections and figuring out what to investigate next.

* `Deductive reasoning` involves starting with what you __know__ and logically figuring out if some conjecture __must__ also be true (and why). While deductive reasoning is stronger than inductive reasoning, it can also be more difficult to use.

In practice, one will often use `inductive reasoning` to make conjectures and `deductive reasoning` to verify them. In some cases producing a conjecture will require a mix of inductive and deductive reasoning.

In this notebook we will go over some example problems to help illustrate how one would go about using `inductive` and `deductive` reasoning in problem solving while avoiding pitfalls. Being able to apply these skills will make you a more effective problem solver. Being able to distinguish between the two will help you maintain a clear understanding of what you're doing, why you're doing it, and avoid mistakes in the processs.

## A Flawed Application of Inductive Reasoning

In this problem a circle is partitioned into regions by adding dots to the edges and drawing chords connecting them. The circle on the top left has only a single dot and a single region. The next one has two dots and two regions.

Before we can apply inductive reasoning we need some examples. To that end I've counted the number of regions for the first five cases:

$$1, 2, 4, 8, 16.$$

It looks like there is a pattern here. Inductive reasoning might suggest that the circle with $n$ dots will have $2^{n-1}$ regions, is that true?

Try counting the number of regions in the sixth case.

Unfortunately, as it turns out the sixth circle will break down into $31$ regions (the last one is contained in the intersection at the center, almost inexistent because of how I drew it), not $32$. This is an example where inductive reasoning can lead you astray. Fortunately for us we managed to find a counterexample right away but there are conjectures where the first counterexample took decades to find and required numbers so large that it's virtually impossible for people to find them by hand. So we should always be very skeptical about the things inductive thinking may lead us to believe.

## Some Flawed Applications of Deductive Reasoning

Deductive reasoning can also fail us if we are not careful. It is possible to get caught up manipulating equations and not realize there's an underlying logical problem.

Here are two flawed proofs. Try and find the problem in each one!

### A Classic Flawed Proof

There are a few variations of this proof (with the same flaw) floating around. Every so often a student rediscovers it and thinks they've broken math.

Let $a=b$.

Then it follows that $b^2=ab$.

$$
\begin{align*}
    a^2 - b^2 &= a^2 - b^2\\
    a^2 - b^2 &= a^2 - ab \tag{Since $b^2=ab$}\\
    (a+b)(a-b) &= (a)(a-b) \tag{Factoring}\\
    a+b &= a \tag{Divide by sides by $a-b$}\\
    2a &= a \tag{Since $a=b$}\\
    2 &= 1 \tag{Divide both sides by $a$}
\end{align*}
$$

Hint: The problem involves division.

The problem is introduced when both sides are divided by $a-b$ because $a-b=0$ and division by zero is not allowed (for reasons like this).

### A Flawed Proof Involving Radicals

This one is somewhat less common but still interesting.

$$
\begin{align*}
    -1
    &= i^2 \\
    &= (i)(i) \\
    &= \sqrt{-1}\sqrt{-1} \\
    &= \sqrt{(-1)(-1)} \\
    &= \sqrt{1} \\
    &= 1
\end{align*}
$$

So $-1=1$.

Hint: The problem involves distributing roots.

The problem occurs because $\sqrt{ab}=\sqrt{a}\sqrt{b}$ only holds when $a$ and $b$ are both greater than or equal to $0$ (neither $a$ nor $b$ are allowed to be negative).

## Some Applications of Inductive Reasoning

### Sum of the first n odd numbers

Suppose you need to compute the sum of the first $100$ odd numbers. You could do this directly but that likely wouldn't be very fun or interesting. Let's instead try applying inductive reasoning to try to come up with a better way to do it.

Before we can start looking for patterns we'll first need to generate some examples (so that we can use them as evidence later). Let's do that in Python:

```python
# Create a list of odd numbers from 1 to 20 (incrementing by 2 each time).
oddNumbers = range(1,20,2)

# Print a nice heading.
print('|  n | Odd | S(n)|')
print('------------------')

# For each odd number print the step, the number, and the sum of all odd numbers so far.
step = 0
oddSum = 0
for odd in oddNumbers:
    step = step + 1
    oddSum = oddSum + odd
    print('|{:3d} | {:3d} | {:3d} |'.format(step, odd, oddSum))
```

    |  n | Odd | S(n)|
    ------------------
    |  1 |   1 |   1 |
    |  2 |   3 |   4 |
    |  3 |   5 |   9 |
    |  4 |   7 |  16 |
    |  5 |   9 |  25 |
    |  6 |  11 |  36 |
    |  7 |  13 |  49 |
    |  8 |  15 |  64 |
    |  9 |  17 |  81 |
    | 10 |  19 | 100 |

For brevity we'll use $S(n)$ to refer to the __sum of the first $n$ odd numbers__.

The code above gives us a list of the first $10$ odd numbers as well as $S(n)$ for each one (eg. for $n=3$, the $3$rd odd is $5$ and $S(3) = 1 + 3 + 5 = 9$).

Now look closely at the data and try to see if there is a pattern there. Maybe consider changing the 20 in `range(1,20,2)` to a larger value to obtain more examples.

Hint: $1+3+5=3^2$.

A good conjecture might be that

$$S(n)=n^2.$$

Here is a slider that tests our conjecture against a larger range of values:

```python
num = widgets.IntSlider(description='n:', min=1)
def oddCompare(num):
    oddNumbers = range(1, num*2, 2)
    oddSum = sum(list(oddNumbers))
    print('S(n): {}'.format(oddSum))
    print('n^2: {}'.format((num*num)))

out = widgets.interactive_output(oddCompare, {'num': num})
widgets.VBox([num, out])
```

Failed to display Jupyter Widget of type VBox.

  If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean
  that the widgets JavaScript is still loading. If this message persists, it
  likely means that the widgets JavaScript library is either not installed or
  not enabled. See the Jupyter
  Widgets Documentation for setup instructions.

  If you're reading this message in another frontend (for example, a static
  rendering on GitHub or NBViewer),
  it may mean that your frontend doesn't currently support widgets.

Now that we have a conjecture it is typically very helpful if we're able to take it further and come up with some guesses about __why__ the conjecture holds. In this case the trick is to realize that we can compute the sum of the first $n$ odd numbers by taking the sum of the first $n-1$ odd numbers and adding the $n$'th odd. In other words:

$$S(n+1)=S(n) + (n+1)^{\text{th}} \text{ odd number}.$$

For instance, $S(5) = 1 + 3 + 5 + 7 + 9 = S(4) + 9$.

Then combining this insight with the fact that we can represent square numbers as squares yields this visualization:

Unfortunately as convincing as this visual representation may be, it isn't strong enough to prove that $S(n)=n^2$ for all numbers $n$. In order to prove that it holds for all $n$ we require a more advanced proof technique that we don't currently have access to. So we must grit our teeth and accept the fact that _as far as we know_ there could exist some number out there for which this fails.

### Triangular numbers

There is famous story about the mathematician Carl Friedrich Gauss who as a child in primary school was tasked with computing the sum of the first 100 numbers as a way to keep him busy. As the story goes, Gauss quickly realized a pattern and wrote down the answer of 5050 within a few seconds.

For brevity we'll use $T(n)$ to refer to the __sum of the first $n$ numbers__.

The trick to seeing the pattern in this problem isn't as straightforward as the last one. As before we'll need to generate some examples to analyze first.

```python
# Create a list of the first 10 numbers.
numbers = range(1,11)

# Print a nice heading.
print('|  n  | T(n)|')
print('-------------')

# For each odd number print the number and the sum of all numbers so far.
tSum = 0
for num in numbers:
    tSum = tSum + num
    print('| {:3d} | {:3d} |'.format(num, tSum))
```

    |  n  | T(n)|
    -------------
    |   1 |   1 |
    |   2 |   3 |
    |   3 |   6 |
    |   4 |  10 |
    |   5 |  15 |
    |   6 |  21 |
    |   7 |  28 |
    |   8 |  36 |
    |   9 |  45 |
    |  10 |  55 |

Unfortunately this didn't turn out to be very insightful.

Another approach we can take is to try to represent the sum differently. Taking a cue from the previous section we'll draw the sum visually:

It is because of this representation that the sum of the first $n$ numbers is often referred to as a $n$'th `triangle number`. The value of our sum is represented by the 'area' of its triangular representation. Now, while it may not be easy to compute the area of such a triangle it is easy to compute the area of a rectangle and we can produce one by setting two triangles face to face:

This representation suggests a good conjecture for computing the $n$'th triangle number:
$$T(n)=\frac{(n)(n+1)}{2}.$$

Unfortunately we once again lack the advanced proof technique we need to prove (using deductive thinking) that this is true for all numbers $n$. So like before we've managed to obtain a really good conjecture through inductive thinking but are not able to confirm with certainty whether or not it's true.

### One Weird Trick

From time to time neat computational tricks like this will go viral on social media. Unfortunately the people presenting them will typically only show a few flashy examples and leave the readers feeling completely mystified about __why__ the trick works (or worse, feeling betrayed when it fails).

Before we start lets first rephrase what the picture is saying:

To compute $(97)(96)$:
1. For each of our values, compute their difference from $100$:
  - $3=100-97$
  - $4=100-96$
2. Multiply the differences to compute the first two digits of the result:
  - $12=(3)(4)$
3. Add the differences and subtract the result from $100$ to compute the remaining digits of the result:
  - $93=100-(3+4)$
4. Glue the two results together to get the final result:
  - $(97)(96)=9312$

It looks like step 3 could be simplified a bit to $93 = 97 - 4$ or $93 = 96 - 3$

In general it looks like the algorithm may be something like this:

To compute $(a)(b)$:
1. For each of our values, compute their difference from $100$:
  - $a'=100-a$
  - $b'=100-b$
2. Multiply the differences to compute the first two digits of the result:
  - $D=(a')(b')$
3. Add the differences and subtract the result from $100$ to compute the remaining digits of the result:
  - $C=a-b'$
4. Glue the two results together to get the final result:
  - $(a)(b)=C\text{ appended with }D$

Next lets have the computer generate some more examples for us so that we can get a better sense of the problem through `inductive reasoning`. The two sliders below let us choose some inputs and present the result created by the algorithm as well as the actual result with a message saying `Success!` if the algorithm gave the correct answer and `Fail!` if it gave the incorrect answer.

```python
a = widgets.IntSlider(description='a:', min=85, max=115, value=100)
b = widgets.IntSlider(description='b:', min=85, max=115, value=100)

def multiply(a,b):
    aDiff = 100-a
    bDiff = 100-b

    firstTwo = aDiff*bDiff
    lastTwo = a - bDiff

    result = str(lastTwo).lstrip('0') + str(firstTwo).zfill(2)
    print('Result: {}'.format(result))
    print('Actual product: {}'.format((a*b)))
    if (result == str(a*b)):
        print('Success!')
    else:
        print('Fail!')

out = widgets.interactive_output(multiply, {'a': a, 'b':b})
widgets.VBox([a,b, out])
```

Failed to display Jupyter Widget of type VBox.

  If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean
  that the widgets JavaScript is still loading. If this message persists, it
  likely means that the widgets JavaScript library is either not installed or
  not enabled. See the Jupyter
  Widgets Documentation for setup instructions.

  If you're reading this message in another frontend (for example, a static
  rendering on GitHub or NBViewer),
  it may mean that your frontend doesn't currently support widgets.

Playing around with the sliders it seems that the algorithm fails in two cases:
1. Where the first digits in the result are greater than $100$.
    * for instance, for $(101)(99)$ it gives `100-1` instead of `9999`
2. Where the first digits in the result are negative.
    * For instance, for $(110)(110)$ it gives `120120` instead of `12100`

Can you see a pattern in the way the numbers fail, maybe a way to fix it?

It seems like both instances can be fixed by carrying values. Perhaps, instead of gluing values together like strings we're actually supposed to be multiplying the last digits by $100$ and adding the first digits! For instance, instead of saying $$9312 = 93\text{ appended with }12$$ we would say $$9312=(93)(100)+12.$$

Lets update the algorithm with this change:

To compute $(a)(b)$:
1. For each of our values, compute their difference from $100$:
  - $a'=100-a$
  - $b'=100-b$
2. Multiply the differences to compute the first two digits of the result:
  - $D=(a')(b')$
3. Add the differences and subtract the result from $100$ to compute the remaining digits of the result:
  - $C=a - b'$
4. Combine the two results together to get the final result:
  - $(a)(b)=(C)(100) + D$

In other words: $$ab = [a-(100-b)](100) + (100-b)(100-a).$$

Next let's create a new version of the sliders:

```python
a = widgets.IntSlider(description='a:', min=85, max=115, value=100)
b = widgets.IntSlider(description='b:', min=85, max=115, value=100)

def multiply(a,b):
    aDiff = 100-a
    bDiff = 100-b

    firstTwo = aDiff*bDiff
    lastTwo = 100 - (aDiff + bDiff)

    result = lastTwo*100 + firstTwo
    print('Result: {}'.format(result))
    print('Actual product: {}'.format((a*b)))
    if (result == a*b):
        print('Success!')
    else:
        print('Fail!')

out = widgets.interactive_output(multiply, {'a': a, 'b':b})
widgets.VBox([a,b, out])
```

Failed to display Jupyter Widget of type VBox.

  If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean
  that the widgets JavaScript is still loading. If this message persists, it
  likely means that the widgets JavaScript library is either not installed or
  not enabled. See the Jupyter
  Widgets Documentation for setup instructions.

  If you're reading this message in another frontend (for example, a static
  rendering on GitHub or NBViewer),
  it may mean that your frontend doesn't currently support widgets.

For the two failing examples mentioned above we now get:
* For $(101)(99)$ we get `9999` which is correct!
* For $(110)(110)$ we get `12100` which is correct!

Now that we have a conjecture let's getting a better sense of why it works. One thing we can do is to take our equation from above:
$$
\begin{align}
ab &= [a-(100-b)](100) + (100-b)(100-a) \\
&= (a)(100) - (100-b)(100) + (100-b)(100-a)
\end{align}
$$

We can visualize this:

Note: This visualization assumes that $a$ and $b$ are between $0$ and $100$ (though in our conjecture we also allow them be greater than $100$).

In general these sorts of techniques where one performs a computation by manipulating the digits of a value is called an 'algorism' (not to be confused with algorithm). They're not really used very much these days (except for fast mental math gimicks).

This particular algorism has a lot of generalizations for dealing with larger numbers but the reasoning behind them gets quite convoluted and in the end the most important part isn't proving that a algorism works for all numbers but that it works for all the numbers for which a mental computation is fast. In this case we can be satisfied by saying that this algorism works for numbers between $91$ and $109$ since those values are the easiest to use in practice.

## Some Applications of Deductive Reasoning

### Fractions

Fractions can be difficult to manipulate. Perhaps we can use deductive reasoning to come up with some easier ways to manipulate them.

First some observations:
1. Every number $a$ can be written in fraction form: $$ a=\frac{a}{1}. $$
2. For every number $a$, except in the case where $a=0$, we can write: $$ 1=\frac{a}{a}. $$
3. Multiplying two fractions just multiplies the numerators and denominators: $$ \left( \frac{a}{b}\right) \left( \frac{c}{d} \right) = \frac{ac}{bd}. $$

The first thing to note is that observation (3) gives us a way to factor any fraction: $$ \frac{a}{b} = \left( \frac{a}{1}\right) \left( \frac{1}{b} \right). $$

Cancellation follows from these observations as well: $$ (b) \left(\frac{a}{b}\right) = \left(\frac{b}{1}\right) \left(\frac{a}{1}\right)\left(\frac{1}{b}\right) = \left(\frac{b}{b}\right) \left(\frac{a}{1}\right) = (1)(a) = a$$

Let's use these to manipulate some complicated fractions.

$$
\begin{align*}
    \frac{a}{\frac{1}{c}}
    & = \left( \frac{a}{\frac{1}{c}}\right) (1) \tag{Multiply by $1$}\\
    & = \left( \frac{a}{\frac{1}{c}}\right) \left(\frac{c}{c} \right) \tag{By observation 2}\\
    & = \frac{ac}{\left( \frac{1}{c}\right) (c)} \tag{By observation 3}\\
    & = \frac{ac}{1} \tag{By canceling}\\
    & = ac \tag{By observation 1}
\end{align*}
$$

Another more complicated example:
$$
\begin{align*}
    \frac{\frac{a}{b}}{\frac{d}{c}}
    & = \left( \frac{\frac{a}{b}}{\frac{d}{c}} \right) (1)(1) \tag{Multiply by $1$}\\
    & = \left( \frac{\frac{a}{b}}{\frac{d}{c}} \right) \left(\frac{b}{b} \right)\left(\frac{c}{c} \right) \tag{By observation 2}\\
    & = \frac{\left( \frac{a}{b} \right) (b)(c)}{\left(\frac{d}{c} \right) (b)(c)} \tag{By observation 3}\\
    & = \frac{ac}{db} \tag{By canceling}
\end{align*}
$$

We can manipulate even the most complicated fractions by __cleverly multiplying by 1__ in this way.

### Distributive Property

The distributive property is extremely useful in simplifying expressions and performing computations. In fact, every multiplication algorithm you encounter will at some level boil down to some clever application of the distributive property. Simply put the distributive property tells us how addition and multiplication interact: $$(a+b)c = ac + bc.$$

Since multiplication is commutative this statement is equivalent: $$a(c+d) = ac + ad.$$

The FOIL mnemonic is just a special case of the distributive property:
$$ (a+b)(c+d) = (a+b)c + (a+b)d = ac + bc + ad + bd. $$

It is important to remember that the distributive property can be read two ways. In one sense it tells us how to distribute multiplication accross addition but in another sense it tells us how to undo that distribution. For example, suppose you have something like $6x + 10xy$. If we notice that both $6x$ and $10xy$ have $2x$ as a factor then we can rewrite that as $6x + 10xy = 2x(3 + 5y)$. This technique is an extremely useful application of deductive reasoning.

### Mentally Computing Simple Percentages

There are many occasions where one might be asked to compute a percentage of some value on the spot (eg. tipping at a restaurant). Fortunately there's a trick to doing it quickly.

First notice that computing $10\%$ is as easy as moving the decimal point one digit to the left (eg. $10\%$ of $25.3$ is $2.53$). Similarly, $1\%$ can be computed by moving the decimal point two digits to the left.

From there on it's just a matter of adding, subtracting, and/or multiplying these percentages to get to the desired percentage. For instance, $18\%$ can be computed by first computing $10\%$, doubling the value to get $20\%$, moving the decimal over one more time to get $2\%$ and then subtracting the $2\%$ value from the $20\%$ value. It's easier than it sounds.

This is an application of deductive reasoning because we reached all of the assertions here logically, not by looking at any patterns and conjecturing.


# RAW-CAPTURE on Aspen-8

In this we are going to show how to access "raw" measurement data with Quilt.

```python
from pyquil import Program, get_qc

qc = get_qc('Aspen-8')
```

```python
cals = qc.compiler.calibration_program
```

## Peeking at a MEASURE calibration
We first take a peek at how a measurement operation is specified. We can dot his by looking at the corresponding calibration. Below we consider the calibration for `MEASURE 0`.

```python
from pyquil.quilatom import Qubit, Frame
from pyquil.quilbase import Pulse, Capture, DefMeasureCalibration

qubit = Qubit(0)

measure_defn = next(defn for defn in cals.calibrations
                    if isinstance(defn, DefMeasureCalibration) and defn.qubit == qubit)

print(measure_defn)
```

    DEFCAL MEASURE 0 addr:
        FENCE 0
        DECLARE q0_unclassified REAL[2]
        NONBLOCKING PULSE 0 "ro_tx" flat(duration: 1.68e-06, iq: 1.0, scale: 0.04466835921509615, phase: 0.0, detuning: 0.0)
        NONBLOCKING CAPTURE 0 "ro_rx" boxcar_kernel(duration: 1.68e-06, scale: 1.0, phase: 2.6571617075901393, detuning: 0.0) q0_unclassified[0]
        PRAGMA FILTER-NODE q0_unclassified "{'module':'lodgepole.filters.io','filter_type':'DataBuffer','source':'q0_ro_rx/filter','publish':true,'params':{},'_type':'FilterNode'}"
        PRAGMA LOAD-MEMORY q0_unclassified "q0_unclassified[0]"
        PRAGMA FILTER-NODE q0_classified "{'module':'lodgepole.filters.classifiers','filter_type':'SingleQLinear','source':'q0_ro_rx/filter','publish':false,'params':{'a':[1.0,0.0],'threshold':0.000241237408735565},'_type':'FilterNode'}"
        PRAGMA FILTER-NODE q0 "{'module':'lodgepole.filters.io','filter_type':'DataBuffer','source':'q0_classified','publish':true,'params':{},'_type':'FilterNode'}"
        PRAGMA LOAD-MEMORY q0 "addr"
        FENCE 0

There are a few things note about the above:

1. The basic structure of `MEASURE 0 addr` is to apply a pulse on the `"ro_tx"` frame, and then perform a capture on the corresponding `"ro_rx"` frame.
2. Although the user may perform `MEASURE 0 ro`, the memory location required for this is a bit. Under the hood, `CAPTURE` writes a complex IQ value to the `REAL[2]` region `q0_unclassified`.
3. The wrangling in order to map from `q0_unclassified` to `addr` is controlled through `PRAGMA` operations. These are important for downstream processing and execution of the Quil program. Tamper with them at your own risk!

## RAW-CAPTURE experiments

The value stored in `q0_unclassified` has already been processed on hardware: in particular, it is produced by demodulating a passband signal and then integrating against the `CAPTURE` waveform. What `RAW-CAPTURE` does is give you, the user, access to the raw values of that passband signal. In the following, execute programs with `RAW-CAPTURE`, and plot their results.

Before we begin, it will be useful to get some data associated with the above `MEASURE` calibration. In particular, the `PULSE` and `CAPTURE` operations, as well as the frame definition for `0 "ro_rx"`.

```python
pulse = next(i for i in measure_defn.instrs if isinstance(i, Pulse))
print(pulse, "\n")
capture = next(i for i in measure_defn.instrs if isinstance(i, Capture))
print(capture, "\n")
frame = Frame([qubit], "ro_rx")
frame_defn = cals.frames[frame]
print(frame_defn)
```

    NONBLOCKING PULSE 0 "ro_tx" flat(duration: 1.68e-06, iq: 1.0, scale: 0.04466835921509615, phase: 0.0, detuning: 0.0)

    NONBLOCKING CAPTURE 0 "ro_rx" boxcar_kernel(duration: 1.68e-06, scale: 1.0, phase: 2.6571617075901393, detuning: 0.0) q0_unclassified[0]

    DEFFRAME 0 "ro_rx":
        DIRECTION: "rx"
        INITIAL-FREQUENCY: 7262459787.78838
        HARDWARE-OBJECT: "q0_ro_rx"
        SAMPLE-RATE: 2000000000.0

### An almost-trivial example

First, let's just run a `RAW-CAPTURE` instruction. We will apply this to the above `CAPTURE` frame, i.e. `0 "ro_rx"`, and for the same duration the `CAPTURE`. The principal difference is that rather than read-out to a memory region of length 2, we will need many more. It is easy to compute the size $n$ of the output, namely
\begin{equation}
n = \left \lceil{t \cdot f_s}\right \rceil ,
\end{equation}
where $t$ is the duration in seconds, $f_s$ is the sample rate in Hz (which is part of the frame definition), and $ \left \lceil x \right \rceil $ denotes the smallest integer not less than $x$.

```python
from math import ceil

duration = capture.kernel.duration
sample_rate = frame_defn.sample_rate
memory_length = ceil(duration * sample_rate)

raw_capture_no_pulse = Program(
    f'DECLARE raw REAL[{memory_length}]',
    f'RAW-CAPTURE {frame} {duration} raw'
).wrap_in_numshots_loop(1000)
print(raw_capture_no_pulse)
```

    DECLARE raw REAL[3360]
    RAW-CAPTURE 0 "ro_rx" 1.68e-06 raw[0]

```python
exe = qc.compiler.native_quil_to_executable(raw_capture_no_pulse)
qc.run(exe)
```

```python
raw_results_no_pulse = qc.qam.read_memory(region_name='raw')
```

Raw capture results are by default represented as integers in the interval $[-2^{15}, 2^{15}]$. For many analyses you may prefer to normalize to the range $[-1,1]$.

```python
print("shape", raw_results_no_pulse.shape)
print("data", raw_results_no_pulse)
```

    shape (1000, 3360)
    data [[ 156. -268. -488. ... -152.  -96.  176.]
     [-704.  -68. -588. ...  572.   20.  452.]
     [-304. -412. -784. ...   76.  628.  668.]
     ...
     [-408. -788. -500. ...  -80. -116.  868.]
     [-736. -400. -956. ...  528.  872.  272.]
     [-388. -608. -432. ...  556.  548.  520.]]

```python
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

plt.figure()
plt.gcf().set_size_inches(20.5, 10.5)
plt.plot(np.arange(len(raw_results_no_pulse[0,:]))/sample_rate, raw_results_no_pulse[0,:])
plt.show()
```

```python
avg_results_no_pulse = raw_results_no_pulse.mean(axis=0) / (2**15)
```

```python
plt.psd(avg_results_no_pulse, Fs=sample_rate)
plt.show()
```

### Applying a `PULSE` before `RAW-CAPTURE`

Recall how measurements are usually done: first there is a pulse on the `"ro_tx"` frame, and then a capture on the `"ro_rx"` frame. We modify our above program by including the `PULSE` operation associated with the vanilla measurement.

```python
raw_capture_pulse = Program(
    f'DECLARE raw REAL[{memory_length}]',
    pulse,
    f'RAW-CAPTURE {frame} {duration} raw'
).wrap_in_numshots_loop(1000)
print(raw_capture_pulse)
```

    DECLARE raw REAL[3360]
    NONBLOCKING PULSE 0 "ro_tx" flat(duration: 1.68e-06, iq: 1.0, scale: 0.04466835921509615, phase: 0.0, detuning: 0.0)
    RAW-CAPTURE 0 "ro_rx" 1.68e-06 raw[0]

```python
exe = qc.compiler.native_quil_to_executable(raw_capture_pulse)
qc.run(exe)

raw_results_pulse = qc.qam.read_memory(region_name='raw')
avg_results_pulse = raw_results_pulse.mean(axis=0) / 2**15
```

```python
plt.psd(avg_results_pulse, Fs=sample_rate)
plt.show()
```

### Capturing an excited qubit

Finally, we extend the above by first exciting the qubit, by applying a `RX(pi)` gate.

```python
raw_capture_excited = Program(
    f'DECLARE raw REAL[{memory_length}]',
    f'RX(pi) {qubit}',
    pulse,
    f'RAW-CAPTURE {frame} {duration} raw'
).wrap_in_numshots_loop(1000)
print(raw_capture_excited)
```

    DECLARE raw REAL[3360]
    RX(pi) 0
    NONBLOCKING PULSE 0 "ro_tx" flat(duration: 1.68e-06, iq: 1.0, scale: 0.04466835921509615, phase: 0.0, detuning: 0.0)
    RAW-CAPTURE 0 "ro_rx" 1.68e-06 raw[0]

```python
exe = qc.compiler.native_quil_to_executable(raw_capture_excited)
qc.run(exe)

raw_results_excited = qc.qam.read_memory(region_name='raw')
avg_results_excited = raw_results_excited.mean(axis=0) / 2**15
```

```python
plt.psd(avg_results_excited, Fs=sample_rate)
plt.show()
```

### TODO

Discuss readout classification.

## Some Restrictions May Apply

Performing a `RAW-CAPTURE` operation places a number of demands on the underlying hardware, and thus comes with a few constraints. We demonstrate these here.

### Capture duration exceeds maximum length

A `RAW-CAPTURE` operation can capture at most 8192 samples per shot, which puts a limit of $\frac{8192}{f_s}$ seconds for the duration, where $f_s$ is the frame's sample rate.

```python
duration = 5e-6
samples = ceil(sample_rate*duration)
rrr = Program(
    f'DECLARE raw REAL[{samples}]',
    f'RAW-CAPTURE 0 "ro_rx" {duration} raw'
).wrap_in_numshots_loop(1)

try:
    exe = qc.compiler.native_quil_to_executable(rrr)
except Exception as e:
    print(e)
```

    ERROR: QPU Compiler native_quilt_to_binary failed: RAW-CAPTURE 0 "ro_rx" 5e-06 raw[0] would require 10000 samples, butat most 8192 are allowed. Consider using a duration of < 4.096e-06 seconds.

### Number of samples in a job exceeds maximum

There is a total limit of $2^{24}$ samples per job, i.e. `duration * sample_rate * num_shots` cannot exceed $2^24$.

```python
duration = 1e-06
samples = ceil(sample_rate*duration)
rrr = Program(
    f'DECLARE raw REAL[{samples}]',
    f'RAW-CAPTURE 0 "ro_rx" {duration} raw'
).wrap_in_numshots_loop(100000)

try:
    exe = qc.compiler.native_quil_to_executable(rrr)
except Exception as e:
    print(e)
```

    ERROR: QPU Compiler native_quilt_to_binary failed: RAW-CAPTURE would require DMA buffer of size 381.4697265625 MB but the maximum allowed is 32.0 MB.
    For duration 1e-06 seconds this places a limit of at most 8388 shots.

### `RAW-CAPTURE` precludes the use of other capture operations

Due to the hardware requirements associated with `RAW-CAPTURE`, the following limits are currently imposed:

* there can be at most one `RAW-CAPTURE` operation per program, and
* if a program includes `RAW-CAPTURE`, then it cannot also include `CAPTURE` operations.

```python
duration = 1e-06
samples = ceil(sample_rate*duration)
rrr = Program(
    f'DECLARE raw REAL[{samples}]',
    'DECLARE ro BIT',
    'MEASURE 1 ro',
    f'RAW-CAPTURE 0 "ro_rx" {duration} raw'
)

try:
    exe = qc.compiler.native_quil_to_executable(rrr)
except Exception as e:
    print(e)
```

    ERROR: QPU Compiler native_quilt_to_binary failed: Capture conflict: RAW-CAPTURE 0 "ro_rx" 1e-06 raw[0] precludes the presence of any other capture instructions, but NONBLOCKING CAPTURE 1 "ro_rx" boxcar_kernel(duration: 2.36e-06, scale: 1.0, phase: 1.1499233858972862, detuning: 0.0) q1_unclassified[0] was observed.

```python

```


Copyright 2017 Google LLC.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

# Performance RNN

### ___Ian Simon, Sageev Oore, Curtis Hawthorne___ ([blog](https://magenta.tensorflow.org/performance-rnn)) ([code](https://github.com/tensorflow/magenta/tree/master/magenta/models/performance_rnn))

Performance RNN, an LSTM-based recurrent neural network designed to model polyphonic music with expressive timing and dynamics. This notebook shows you how to generate new performed compositions from a trained model. You'll see how to download a bundle containing a pre-trained model, instantiate and initialize the model and generate new polyphonic performances. The notebook also shows some hyperparameters useful for controlling generation, such as temperature.

___

This colab notebook is self-contained and should run natively on google cloud. The code and checkpoints can be downloaded separately and run locally, which is recommended if you want to train your own model. Details on how to do this can be found in the [GitHub repo](https://github.com/tensorflow/magenta/tree/master/magenta/models/performance_rnn).

# Environment Setup

Includes package installation for sequence synthesis. May take a few minutes.

```
!apt-get update -qq && apt-get install -qq libfluidsynth1 build-essential libasound2-dev libjack-dev
!pip install -U magenta==0.5.0 pyfluidsynth

# Hack to allow python to pick up the newly-installed fluidsynth lib.
import ctypes.util
orig_ctypes_util_find_library = ctypes.util.find_library
def proxy_find_library(lib):
  if lib == 'fluidsynth':
    return 'libfluidsynth.so.1'
  else:
    return orig_ctypes_util_find_library(lib)
ctypes.util.find_library = proxy_find_library

# Download Salamander piano SoundFont.
# Samples by Alexander Holm: https://archive.org/details/SalamanderGrandPianoV3
# Converted to sf2 by John Nebauer: https://sites.google.com/site/soundfonts4u
!gsutil -m cp gs://download.magenta.tensorflow.org/soundfonts/Yamaha-C5-Salamander-JNv5.1.sf2 /tmp/
```

    Selecting previously unselected package libfluidsynth1:amd64.
    (Reading database ... 110842 files and directories currently installed.)
    Preparing to unpack .../libfluidsynth1_1.1.9-1_amd64.deb ...
    Unpacking libfluidsynth1:amd64 (1.1.9-1) ...
    Processing triggers for libc-bin (2.27-3ubuntu1) ...
    Setting up libfluidsynth1:amd64 (1.1.9-1) ...
    Processing triggers for libc-bin (2.27-3ubuntu1) ...
    Collecting magenta==0.5.0
      Downloading https://files.pythonhosted.org/packages/db/fc/3cae201d5141d49f167649d23fd3136f1c180dd0da495a6d06cefffe04c6/magenta-0.5.0-py2.py3-none-any.whl (1.4MB)
        100% |████████████████████████████████| 1.4MB 11.1MB/s
    Collecting pyfluidsynth
      Downloading https://files.pythonhosted.org/packages/43/eb/6b10b586d727a9706b5f2320121defdcb1cb9a2e301104549c7cca4a313e/pyFluidSynth-1.2.5-py2-none-any.whl
    Requirement already satisfied, skipping upgrade: numpy>=1.11.0 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.14.6)
    Requirement already satisfied, skipping upgrade: python-rtmidi in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.1.2)
    Requirement already satisfied, skipping upgrade: scipy>=0.18.1 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.1.0)
    Requirement already satisfied, skipping upgrade: mir-eval>=0.4 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.5)
    Requirement already satisfied, skipping upgrade: tensorflow>=1.12.0 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.12.0)
    Requirement already satisfied, skipping upgrade: pandas>=0.18.1 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.22.0)
    Requirement already satisfied, skipping upgrade: pretty-midi>=0.2.6 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.2.8)
    Requirement already satisfied, skipping upgrade: intervaltree>=2.1.0 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (2.1.0)
    Requirement already satisfied, skipping upgrade: librosa>=0.6.2 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.6.2)
    Collecting apache-beam>=2.8.0; python_version == "2.7" (from magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/d4/3d/90aa15779e884feebae4b0c26cad6f52cd4040397a94deb58dad9c8b7300/apache_beam-2.9.0-cp27-cp27mu-manylinux1_x86_64.whl (2.4MB)
        100% |████████████████████████████████| 2.4MB 8.3MB/s
    Requirement already satisfied, skipping upgrade: backports.tempfile in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.0)
    Requirement already satisfied, skipping upgrade: mido==1.2.6 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.2.6)
    Requirement already satisfied, skipping upgrade: Pillow>=3.4.2 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (4.0.0)
    Requirement already satisfied, skipping upgrade: protobuf in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (3.6.1)
    Requirement already satisfied, skipping upgrade: tensorflow-probability>=0.5.0 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.5.0)
    Requirement already satisfied, skipping upgrade: IPython in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (5.5.0)
    Requirement already satisfied, skipping upgrade: bokeh>=0.12.0 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.0.2)
    Requirement already satisfied, skipping upgrade: matplotlib>=1.5.3 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (2.1.2)
    Requirement already satisfied, skipping upgrade: futures; python_version == "2.7" in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (3.2.0)
    Collecting sonnet (from magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/01/aa/641d5113d301cc67e2efd802bfd566ab5390676ea1117b2b8954ea6d60c1/sonnet-0.1.6.tar.gz
    Requirement already satisfied, skipping upgrade: absl-py in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.6.1)
    Requirement already satisfied, skipping upgrade: wheel in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.32.3)
    Requirement already satisfied, skipping upgrade: joblib>=0.12 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (0.13.0)
    Requirement already satisfied, skipping upgrade: tensor2tensor>=1.10.0 in /usr/local/lib/python2.7/dist-packages (from magenta==0.5.0) (1.11.0)
    Collecting sk-video (from magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/dd/3f/ce848b8b2062ad1ccf1449094a740c775f6c761339f411e44f1e090f23a7/sk_video-1.1.10-py2.py3-none-any.whl (2.3MB)
        100% |████████████████████████████████| 2.3MB 9.0MB/s
    Requirement already satisfied, skipping upgrade: future in /usr/local/lib/python2.7/dist-packages (from pyfluidsynth) (0.16.0)
    Requirement already satisfied, skipping upgrade: six in /usr/local/lib/python2.7/dist-packages (from mir-eval>=0.4->magenta==0.5.0) (1.11.0)
    Requirement already satisfied, skipping upgrade: grpcio>=1.8.6 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (1.15.0)
    Requirement already satisfied, skipping upgrade: mock>=2.0.0 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (2.0.0)
    Requirement already satisfied, skipping upgrade: keras-applications>=1.0.6 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (1.0.6)
    Requirement already satisfied, skipping upgrade: enum34>=1.1.6 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (1.1.6)
    Requirement already satisfied, skipping upgrade: keras-preprocessing>=1.0.5 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (1.0.5)
    Requirement already satisfied, skipping upgrade: gast>=0.2.0 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (0.2.0)
    Requirement already satisfied, skipping upgrade: backports.weakref>=1.0rc1 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (1.0.post1)
    Requirement already satisfied, skipping upgrade: tensorboard<1.13.0,>=1.12.0 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (1.12.1)
    Requirement already satisfied, skipping upgrade: termcolor>=1.1.0 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (1.1.0)
    Requirement already satisfied, skipping upgrade: astor>=0.6.0 in /usr/local/lib/python2.7/dist-packages (from tensorflow>=1.12.0->magenta==0.5.0) (0.7.1)
    Requirement already satisfied, skipping upgrade: pytz>=2011k in /usr/local/lib/python2.7/dist-packages (from pandas>=0.18.1->magenta==0.5.0) (2018.7)
    Requirement already satisfied, skipping upgrade: python-dateutil in /usr/local/lib/python2.7/dist-packages (from pandas>=0.18.1->magenta==0.5.0) (2.5.3)
    Requirement already satisfied, skipping upgrade: sortedcontainers in /usr/local/lib/python2.7/dist-packages (from intervaltree>=2.1.0->magenta==0.5.0) (2.1.0)
    Requirement already satisfied, skipping upgrade: audioread>=2.0.0 in /usr/local/lib/python2.7/dist-packages (from librosa>=0.6.2->magenta==0.5.0) (2.1.6)
    Requirement already satisfied, skipping upgrade: scikit-learn!=0.19.0,>=0.14.0 in /usr/local/lib/python2.7/dist-packages (from librosa>=0.6.2->magenta==0.5.0) (0.20.1)
    Requirement already satisfied, skipping upgrade: decorator>=3.0.0 in /usr/local/lib/python2.7/dist-packages (from librosa>=0.6.2->magenta==0.5.0) (4.3.0)
    Requirement already satisfied, skipping upgrade: resampy>=0.2.0 in /usr/local/lib/python2.7/dist-packages (from librosa>=0.6.2->magenta==0.5.0) (0.2.1)
    Requirement already satisfied, skipping upgrade: numba>=0.38.0 in /usr/local/lib/python2.7/dist-packages (from librosa>=0.6.2->magenta==0.5.0) (0.40.1)
    Requirement already satisfied, skipping upgrade: pyyaml<4.0.0,>=3.12 in /usr/local/lib/python2.7/dist-packages (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (3.13)
    Collecting hdfs<3.0.0,>=2.1.0 (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/96/4e/f82bd349c7893e1595429ecc95233369bc33c9a26e4859991439bfa01c1f/hdfs-2.2.2.tar.gz
    Requirement already satisfied, skipping upgrade: httplib2<=0.11.3,>=0.8 in /usr/local/lib/python2.7/dist-packages (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (0.11.3)
    Requirement already satisfied, skipping upgrade: dill<=0.2.8.2,>=0.2.6 in /usr/local/lib/python2.7/dist-packages (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (0.2.8.2)
    Collecting pyvcf<0.7.0,>=0.6.8 (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/20/b6/36bfb1760f6983788d916096193fc14c83cce512c7787c93380e09458c09/PyVCF-0.6.8.tar.gz
    Collecting fastavro<0.22,>=0.21.4 (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/e6/81/9ecee4b61514da16e6e11b5bfd3cc35112bc9c2846d846ec7cc1cda0b106/fastavro-0.21.16-cp27-cp27mu-manylinux1_x86_64.whl (1.1MB)
        100% |████████████████████████████████| 1.1MB 16.5MB/s
    Requirement already satisfied, skipping upgrade: typing<3.7.0,>=3.6.0; python_version < "3.5.0" in /usr/local/lib/python2.7/dist-packages (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (3.6.6)
    Collecting avro<2.0.0,>=1.8.1 (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/eb/27/143f124a7498f841317a92ced877150c5cb8d28a4109ec39666485925d00/avro-1.8.2.tar.gz (43kB)
        100% |████████████████████████████████| 51kB 21.2MB/s
    Collecting pydot<1.3,>=1.2.0 (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/c3/f1/e61d6dfe6c1768ed2529761a68f70939e2569da043e9f15a8d84bf56cadf/pydot-1.2.4.tar.gz (132kB)
        100% |████████████████████████████████| 133kB 27.5MB/s
    Collecting oauth2client<4,>=2.0.1 (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/c0/7b/bc893e35d6ca46a72faa4b9eaac25c687ce60e1fbe978993fe2de1b0ff0d/oauth2client-3.0.0.tar.gz (77kB)
        100% |████████████████████████████████| 81kB 21.9MB/s
    Requirement already satisfied, skipping upgrade: crcmod<2.0,>=1.7 in /usr/local/lib/python2.7/dist-packages (from apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (1.7)
    Requirement already satisfied, skipping upgrade: olefile in /usr/local/lib/python2.7/dist-packages (from Pillow>=3.4.2->magenta==0.5.0) (0.46)
    Requirement already satisfied, skipping upgrade: setuptools in /usr/local/lib/python2.7/dist-packages (from protobuf->magenta==0.5.0) (40.6.3)
    Requirement already satisfied, skipping upgrade: simplegeneric>0.8 in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (0.8.1)
    Requirement already satisfied, skipping upgrade: pickleshare in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (0.7.5)
    Requirement already satisfied, skipping upgrade: backports.shutil-get-terminal-size; python_version == "2.7" in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (1.0.0)
    Requirement already satisfied, skipping upgrade: pathlib2; python_version == "2.7" or python_version == "3.3" in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (2.3.3)
    Requirement already satisfied, skipping upgrade: pexpect; sys_platform != "win32" in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (4.6.0)
    Requirement already satisfied, skipping upgrade: traitlets>=4.2 in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (4.3.2)
    Requirement already satisfied, skipping upgrade: pygments in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (2.1.3)
    Requirement already satisfied, skipping upgrade: prompt-toolkit<2.0.0,>=1.0.4 in /usr/local/lib/python2.7/dist-packages (from IPython->magenta==0.5.0) (1.0.15)
    Requirement already satisfied, skipping upgrade: Jinja2>=2.7 in /usr/local/lib/python2.7/dist-packages (from bokeh>=0.12.0->magenta==0.5.0) (2.10)
    Requirement already satisfied, skipping upgrade: packaging>=16.8 in /usr/local/lib/python2.7/dist-packages (from bokeh>=0.12.0->magenta==0.5.0) (18.0)
    Requirement already satisfied, skipping upgrade: tornado>=4.3 in /usr/local/lib/python2.7/dist-packages (from bokeh>=0.12.0->magenta==0.5.0) (4.5.3)
    Requirement already satisfied, skipping upgrade: cycler>=0.10 in /usr/local/lib/python2.7/dist-packages (from matplotlib>=1.5.3->magenta==0.5.0) (0.10.0)
    Requirement already satisfied, skipping upgrade: backports.functools-lru-cache in /usr/local/lib/python2.7/dist-packages (from matplotlib>=1.5.3->magenta==0.5.0) (1.5)
    Requirement already satisfied, skipping upgrade: subprocess32 in /usr/local/lib/python2.7/dist-packages (from matplotlib>=1.5.3->magenta==0.5.0) (3.5.3)
    Requirement already satisfied, skipping upgrade: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python2.7/dist-packages (from matplotlib>=1.5.3->magenta==0.5.0) (2.3.0)
    Collecting networkx==1.8.1 (from sonnet->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/1e/ce/c5f0d432ab38b114a18020c1f716e08347b580b6865111ef1314995627a2/networkx-1.8.1.tar.gz (806kB)
        100% |████████████████████████████████| 808kB 18.4MB/s
    Requirement already satisfied, skipping upgrade: requests in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (2.18.4)
    Requirement already satisfied, skipping upgrade: flask in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (1.0.2)
    Requirement already satisfied, skipping upgrade: gunicorn in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (19.9.0)
    Requirement already satisfied, skipping upgrade: mesh-tensorflow in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (0.0.5)
    Requirement already satisfied, skipping upgrade: tfds-nightly in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (0.0.2.dev201812180014)
    Requirement already satisfied, skipping upgrade: google-api-python-client in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (1.6.7)
    Requirement already satisfied, skipping upgrade: tqdm in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (4.28.1)
    Requirement already satisfied, skipping upgrade: bz2file in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (0.98)
    Requirement already satisfied, skipping upgrade: gevent in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (1.3.7)
    Requirement already satisfied, skipping upgrade: sympy in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (1.1.1)
    Requirement already satisfied, skipping upgrade: gym in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (0.10.9)
    Requirement already satisfied, skipping upgrade: h5py in /usr/local/lib/python2.7/dist-packages (from tensor2tensor>=1.10.0->magenta==0.5.0) (2.8.0)
    Requirement already satisfied, skipping upgrade: funcsigs>=1; python_version < "3.3" in /usr/local/lib/python2.7/dist-packages (from mock>=2.0.0->tensorflow>=1.12.0->magenta==0.5.0) (1.0.2)
    Requirement already satisfied, skipping upgrade: pbr>=0.11 in /usr/local/lib/python2.7/dist-packages (from mock>=2.0.0->tensorflow>=1.12.0->magenta==0.5.0) (5.1.1)
    Requirement already satisfied, skipping upgrade: werkzeug>=0.11.10 in /usr/local/lib/python2.7/dist-packages (from tensorboard<1.13.0,>=1.12.0->tensorflow>=1.12.0->magenta==0.5.0) (0.14.1)
    Requirement already satisfied, skipping upgrade: markdown>=2.6.8 in /usr/local/lib/python2.7/dist-packages (from tensorboard<1.13.0,>=1.12.0->tensorflow>=1.12.0->magenta==0.5.0) (3.0.1)
    Requirement already satisfied, skipping upgrade: llvmlite>=0.25.0dev0 in /usr/local/lib/python2.7/dist-packages (from numba>=0.38.0->librosa>=0.6.2->magenta==0.5.0) (0.26.0)
    Requirement already satisfied, skipping upgrade: singledispatch in /usr/local/lib/python2.7/dist-packages (from numba>=0.38.0->librosa>=0.6.2->magenta==0.5.0) (3.4.0.3)
    Collecting docopt (from hdfs<3.0.0,>=2.1.0->apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0)
      Downloading https://files.pythonhosted.org/packages/a2/55/8f8cab2afd404cf578136ef2cc5dfb50baa1761b68c9da1fb1e4eed343c9/docopt-0.6.2.tar.gz
    Requirement already satisfied, skipping upgrade: pyasn1>=0.1.7 in /usr/local/lib/python2.7/dist-packages (from oauth2client<4,>=2.0.1->apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (0.4.4)
    Requirement already satisfied, skipping upgrade: pyasn1-modules>=0.0.5 in /usr/local/lib/python2.7/dist-packages (from oauth2client<4,>=2.0.1->apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (0.2.2)
    Requirement already satisfied, skipping upgrade: rsa>=3.1.4 in /usr/local/lib/python2.7/dist-packages (from oauth2client<4,>=2.0.1->apache-beam>=2.8.0; python_version == "2.7"->magenta==0.5.0) (4.0)
    Requirement already satisfied, skipping upgrade: scandir; python_version < "3.5" in /usr/local/lib/python2.7/dist-packages (from pathlib2; python_version == "2.7" or python_version == "3.3"->IPython->magenta==0.5.0) (1.9.0)
    Requirement already satisfied, skipping upgrade: ptyprocess>=0.5 in /usr/local/lib/python2.7/dist-packages (from pexpect; sys_platform != "win32"->IPython->magenta==0.5.0) (0.6.0)
    Requirement already satisfied, skipping upgrade: ipython-genutils in /usr/local/lib/python2.7/dist-packages (from traitlets>=4.2->IPython->magenta==0.5.0) (0.2.0)
    Requirement already satisfied, skipping upgrade: wcwidth in /usr/local/lib/python2.7/dist-packages (from prompt-toolkit<2.0.0,>=1.0.4->IPython->magenta==0.5.0) (0.1.7)
    Requirement already satisfied, skipping upgrade: MarkupSafe>=0.23 in /usr/local/lib/python2.7/dist-packages (from Jinja2>=2.7->bokeh>=0.12.0->magenta==0.5.0) (1.1.0)
    Requirement already satisfied, skipping upgrade: certifi in /usr/local/lib/python2.7/dist-packages (from tornado>=4.3->bokeh>=0.12.0->magenta==0.5.0) (2018.11.29)
    Requirement already satisfied, skipping upgrade: backports_abc>=0.4 in /usr/local/lib/python2.7/dist-packages (from tornado>=4.3->bokeh>=0.12.0->magenta==0.5.0) (0.5)
    Requirement already satisfied, skipping upgrade: idna<2.7,>=2.5 in /usr/local/lib/python2.7/dist-packages (from requests->tensor2tensor>=1.10.0->magenta==0.5.0) (2.6)
    Requirement already satisfied, skipping upgrade: urllib3<1.23,>=1.21.1 in /usr/local/lib/python2.7/dist-packages (from requests->tensor2tensor>=1.10.0->magenta==0.5.0) (1.22)
    Requirement already satisfied, skipping upgrade: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python2.7/dist-packages (from requests->tensor2tensor>=1.10.0->magenta==0.5.0) (3.0.4)
    Requirement already satisfied, skipping upgrade: click>=5.1 in /usr/local/lib/python2.7/dist-packages (from flask->tensor2tensor>=1.10.0->magenta==0.5.0) (7.0)
    Requirement already satisfied, skipping upgrade: itsdangerous>=0.24 in /usr/local/lib/python2.7/dist-packages (from flask->tensor2tensor>=1.10.0->magenta==0.5.0) (1.1.0)
    Requirement already satisfied, skipping upgrade: wrapt in /usr/local/lib/python2.7/dist-packages (from tfds-nightly->tensor2tensor>=1.10.0->magenta==0.5.0) (1.10.11)
    Requirement already satisfied, skipping upgrade: promise in /usr/local/lib/python2.7/dist-packages (from tfds-nightly->tensor2tensor>=1.10.0->magenta==0.5.0) (2.2.1)
    Requirement already satisfied, skipping upgrade: tensorflow-metadata in /usr/local/lib/python2.7/dist-packages (from tfds-nightly->tensor2tensor>=1.10.0->magenta==0.5.0) (0.9.0)
    Requirement already satisfied, skipping upgrade: functools32 in /usr/local/lib/python2.7/dist-packages (from tfds-nightly->tensor2tensor>=1.10.0->magenta==0.5.0) (3.2.3.post2)
    Requirement already satisfied, skipping upgrade: uritemplate<4dev,>=3.0.0 in /usr/local/lib/python2.7/dist-packages (from google-api-python-client->tensor2tensor>=1.10.0->magenta==0.5.0) (3.0.0)
    Requirement already satisfied, skipping upgrade: greenlet>=0.4.14; platform_python_implementation == "CPython" in /usr/local/lib/python2.7/dist-packages (from gevent->tensor2tensor>=1.10.0->magenta==0.5.0) (0.4.15)
    Requirement already satisfied, skipping upgrade: mpmath>=0.19 in /usr/local/lib/python2.7/dist-packages (from sympy->tensor2tensor>=1.10.0->magenta==0.5.0) (1.1.0)
    Requirement already satisfied, skipping upgrade: pyglet>=1.2.0 in /usr/local/lib/python2.7/dist-packages (from gym->tensor2tensor>=1.10.0->magenta==0.5.0) (1.3.2)
    Requirement already satisfied, skipping upgrade: googleapis-common-protos in /usr/local/lib/python2.7/dist-packages (from tensorflow-metadata->tfds-nightly->tensor2tensor>=1.10.0->magenta==0.5.0) (1.5.5)
    Building wheels for collected packages: sonnet, hdfs, pyvcf, avro, pydot, oauth2client, networkx, docopt
      Running setup.py bdist_wheel for sonnet ... - done
      Stored in directory: /root/.cache/pip/wheels/c9/eb/cf/78638749d5a9065ef666af154431cff8f2e82bd2d9dc0d96b2
      Running setup.py bdist_wheel for hdfs ... - done
      Stored in directory: /root/.cache/pip/wheels/99/3f/b2/a09631bd4e2220031fa88949f4acc010cc48cc29011cb25922
      Running setup.py bdist_wheel for pyvcf ... - \ | / done
      Stored in directory: /root/.cache/pip/wheels/81/91/41/3272543c0b9c61da9c525f24ee35bae6fe8f60d4858c66805d
      Running setup.py bdist_wheel for avro ... - done
      Stored in directory: /root/.cache/pip/wheels/bf/0b/75/1b3517b7d36ddc8ba5d22c0df5eb01e83979f34420066d643e
      Running setup.py bdist_wheel for pydot ... - done
      Stored in directory: /root/.cache/pip/wheels/6a/a5/14/25541ebcdeaf97a37b6d05c7ff15f5bd20f5e91b99d313e5b4
      Running setup.py bdist_wheel for oauth2client ... - done
      Stored in directory: /root/.cache/pip/wheels/48/f7/87/b932f09c6335dbcf45d916937105a372ab14f353a9ca431d7d
      Running setup.py bdist_wheel for networkx ... - \ | / done
      Stored in directory: /root/.cache/pip/wheels/b0/45/7a/70a261dd19bcb094df5e3629f305a81156c9c2f15d47b29c89
      Running setup.py bdist_wheel for docopt ... - done
      Stored in directory: /root/.cache/pip/wheels/9b/04/dd/7daf4150b6d9b12949298737de9431a324d4b797ffd63f526e
    Successfully built sonnet hdfs pyvcf avro pydot oauth2client networkx docopt
    apache-beam 2.9.0 has requirement pytz<=2018.4,>=2018.3, but you'll have pytz 2018.7 which is incompatible.
    Installing collected packages: docopt, hdfs, pyvcf, fastavro, avro, pydot, oauth2client, apache-beam, networkx, sonnet, sk-video, magenta, pyfluidsynth
      Found existing installation: pydot 1.3.0
        Uninstalling pydot-1.3.0:
          Successfully uninstalled pydot-1.3.0
      Found existing installation: oauth2client 4.1.3
        Uninstalling oauth2client-4.1.3:
          Successfully uninstalled oauth2client-4.1.3
      Found existing installation: networkx 2.2
        Uninstalling networkx-2.2:
          Successfully uninstalled networkx-2.2
      Found existing installation: magenta 0.3.19
        Uninstalling magenta-0.3.19:
          Successfully uninstalled magenta-0.3.19
    Successfully installed apache-beam-2.9.0 avro-1.8.2 docopt-0.6.2 fastavro-0.21.16 hdfs-2.2.2 magenta-0.5.0 networkx-1.8.1 oauth2client-3.0.0 pydot-1.2.4 pyfluidsynth-1.2.5 pyvcf-0.6.8 sk-video-1.1.10 sonnet-0.1.6
    Copying gs://download.magenta.tensorflow.org/soundfonts/Yamaha-C5-Salamander-JNv5.1.sf2...
    / [1/1 files][591.9 MiB/591.9 MiB] 100% Done
    Operation completed over 1 objects/591.9 MiB.

```
import os
from magenta.models.performance_rnn import performance_sequence_generator
from magenta.protobuf import generator_pb2
from magenta.protobuf import music_pb2

import magenta.music as mm

# Necessary until pyfluidsynth is updated (>1.2.5).
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

# Constants.
BUNDLE_DIR = '/tmp/'
MODEL_NAME = 'performance_with_dynamics'
BUNDLE_NAME = MODEL_NAME + '.mag'
```

    /usr/local/lib/python2.7/dist-packages/scipy/signal/_max_len_seq.py:8: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._max_len_seq_inner import _max_len_seq_inner
    /usr/local/lib/python2.7/dist-packages/scipy/signal/_upfirdn.py:36: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._upfirdn_apply import _output_len, _apply
    /usr/local/lib/python2.7/dist-packages/scipy/signal/spectral.py:10: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._spectral import _lombscargle
    /usr/local/lib/python2.7/dist-packages/scipy/signal/_peak_finding.py:13: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._peak_finding_utils import (_argmaxima1d, _select_by_peak_distance,
    /usr/local/lib/python2.7/dist-packages/sklearn/linear_model/base.py:35: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ..utils.seq_dataset import ArrayDataset, CSRDataset
    /usr/local/lib/python2.7/dist-packages/sklearn/linear_model/least_angle.py:23: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ..utils import arrayfuncs, as_float_array, check_X_y, deprecated
    /usr/local/lib/python2.7/dist-packages/sklearn/utils/random.py:10: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._random import sample_without_replacement
    /usr/local/lib/python2.7/dist-packages/sklearn/linear_model/coordinate_descent.py:30: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import cd_fast
    /usr/local/lib/python2.7/dist-packages/sklearn/linear_model/__init__.py:22: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .sgd_fast import Hinge, Log, ModifiedHuber, SquaredLoss, Huber
    /usr/local/lib/python2.7/dist-packages/sklearn/linear_model/__init__.py:22: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .sgd_fast import Hinge, Log, ModifiedHuber, SquaredLoss, Huber
    /usr/local/lib/python2.7/dist-packages/sklearn/linear_model/sag.py:12: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .sag_fast import sag
    /usr/local/lib/python2.7/dist-packages/sklearn/svm/base.py:8: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import libsvm, liblinear
    /usr/local/lib/python2.7/dist-packages/sklearn/svm/base.py:8: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import libsvm, liblinear
    /usr/local/lib/python2.7/dist-packages/sklearn/svm/base.py:9: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import libsvm_sparse
    /usr/local/lib/python2.7/dist-packages/sklearn/neighbors/__init__.py:6: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .ball_tree import BallTree
    /usr/local/lib/python2.7/dist-packages/sklearn/neighbors/__init__.py:6: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .ball_tree import BallTree
    /usr/local/lib/python2.7/dist-packages/sklearn/neighbors/__init__.py:6: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .ball_tree import BallTree
    /usr/local/lib/python2.7/dist-packages/sklearn/neighbors/__init__.py:7: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .kd_tree import KDTree
    /usr/local/lib/python2.7/dist-packages/sklearn/decomposition/online_lda.py:28: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._online_lda import (mean_change, _dirichlet_expectation_1d,
    /usr/local/lib/python2.7/dist-packages/sklearn/utils/graph.py:16: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from .graph_shortest_path import graph_shortest_path  # noqa
    /usr/local/lib/python2.7/dist-packages/sklearn/isotonic.py:11: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._isotonic import _inplace_contiguous_isotonic_regression, _make_unique
    /usr/local/lib/python2.7/dist-packages/sklearn/manifold/t_sne.py:26: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import _utils
    /usr/local/lib/python2.7/dist-packages/sklearn/manifold/t_sne.py:27: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import _barnes_hut_tsne
    /usr/local/lib/python2.7/dist-packages/sklearn/manifold/t_sne.py:27: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import _barnes_hut_tsne
    /usr/local/lib/python2.7/dist-packages/sklearn/tree/tree.py:40: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._criterion import Criterion
    /usr/local/lib/python2.7/dist-packages/sklearn/tree/tree.py:40: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._criterion import Criterion
    /usr/local/lib/python2.7/dist-packages/sklearn/tree/tree.py:40: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._criterion import Criterion
    /usr/local/lib/python2.7/dist-packages/sklearn/tree/tree.py:40: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._criterion import Criterion
    /usr/local/lib/python2.7/dist-packages/sklearn/cluster/k_means_.py:37: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import _k_means
    /usr/local/lib/python2.7/dist-packages/sklearn/cluster/k_means_.py:38: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._k_means_elkan import k_means_elkan
    /usr/local/lib/python2.7/dist-packages/sklearn/cluster/hierarchical.py:23: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import _hierarchical
    /usr/local/lib/python2.7/dist-packages/sklearn/cluster/hierarchical.py:23: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from . import _hierarchical
    /usr/local/lib/python2.7/dist-packages/sklearn/cluster/dbscan_.py:20: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._dbscan_inner import dbscan_inner
    /usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/hashing.py:14: RuntimeWarning: numpy.dtype size changed, may indicate binary incompatibility. Expected 96, got 88
      from ._hashing import transform as _hashing_transform

```
mm.notebook_utils.download_bundle(BUNDLE_NAME, BUNDLE_DIR)
```

# Generate a sequence

```
bundle = mm.sequence_generator_bundle.read_bundle_file(os.path.join(BUNDLE_DIR, BUNDLE_NAME))
generator_map = performance_sequence_generator.get_generator_map()
generator = generator_map[MODEL_NAME](checkpoint=None, bundle=bundle)
generator.initialize()
generator_options = generator_pb2.GeneratorOptions()
generator_options.args['temperature'].float_value = 1.0  # Higher is more random; 1.0 is default.
generate_section = generator_options.generate_sections.add(start_time=0, end_time=30)
sequence = generator.generate(music_pb2.NoteSequence(), generator_options)

# Play and view this masterpiece.
mm.plot_sequence(sequence)
mm.play_sequence(sequence, mm.midi_synth.fluidsynth,
                 sf2_path='/tmp/Yamaha-C5-Salamander-JNv5.1.sf2')
```

    WARNING:tensorflow:The saved meta_graph is possibly from an older release:
    'model_variables' collection should be of type 'byte_list', but instead is of type 'node_list'.
    INFO:tensorflow:Restoring parameters from /tmp/tmpVlLvYQ/model.ckpt
    INFO:tensorflow:Need to generate 2899 more steps for this sequence, will try asking for 1740 RNN steps
    INFO:tensorflow:Beam search yields sequence with log-likelihood: -3987.715332

    Loading BokehJS ...

Performance_RNN Midi Music generator.ipynb