The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .devcontainer
    ├── Dockerfile
    ├── devcontainer.json
    └── noop.txt
├── .github
    └── workflows
    │   └── tests.yml
├── .gitignore
├── Makefile
├── README.md
├── _config.yml
├── book
    ├── Makefile
    ├── back.png
    ├── book.tex
    ├── diagram.tex
    ├── diagram2.tex
    ├── figs
    │   ├── MP86F77F.pdf
    │   ├── aliasing-3.eps
    │   ├── aliasing-3.pdf
    │   ├── aliasing1.eps
    │   ├── aliasing1.pdf
    │   ├── autocorr1.eps
    │   ├── autocorr1.pdf
    │   ├── autocorr2.eps
    │   ├── autocorr2.pdf
    │   ├── autocorr3.eps
    │   ├── autocorr3.pdf
    │   ├── autocorr4.eps
    │   ├── autocorr4.pdf
    │   ├── autocorr5.eps
    │   ├── autocorr5.pdf
    │   ├── autocorr6.eps
    │   ├── autocorr6.pdf
    │   ├── autocorr7.eps
    │   ├── autocorr7.pdf
    │   ├── autocorr8.eps
    │   ├── autocorr8.pdf
    │   ├── autocorr9.eps
    │   ├── autocorr9.pdf
    │   ├── brfss_weight_log.eps
    │   ├── brfss_weight_log.pdf
    │   ├── chirp1.eps
    │   ├── chirp1.pdf
    │   ├── chirp2.eps
    │   ├── chirp2.pdf
    │   ├── chirp3.eps
    │   ├── chirp3.pdf
    │   ├── convolution1.eps
    │   ├── convolution1.pdf
    │   ├── convolution10.eps
    │   ├── convolution10.pdf
    │   ├── convolution2.eps
    │   ├── convolution2.pdf
    │   ├── convolution4.eps
    │   ├── convolution4.pdf
    │   ├── convolution5.eps
    │   ├── convolution5.pdf
    │   ├── convolution6.eps
    │   ├── convolution6.pdf
    │   ├── convolution7.eps
    │   ├── convolution7.pdf
    │   ├── convolution8.eps
    │   ├── convolution8.pdf
    │   ├── convolution9.eps
    │   ├── convolution9.pdf
    │   ├── dct1.eps
    │   ├── dct1.pdf
    │   ├── dft1.eps
    │   ├── dft1.pdf
    │   ├── dft2.eps
    │   ├── dft2.pdf
    │   ├── dft3.eps
    │   ├── dft3.pdf
    │   ├── diagram.pdf
    │   ├── diagram1.eps
    │   ├── diagram1.pdf
    │   ├── diagram2.eps
    │   ├── diagram2.pdf
    │   ├── diff_int1.eps
    │   ├── diff_int1.pdf
    │   ├── diff_int2.eps
    │   ├── diff_int2.pdf
    │   ├── diff_int3.eps
    │   ├── diff_int3.pdf
    │   ├── diff_int4.eps
    │   ├── diff_int4.pdf
    │   ├── diff_int5.eps
    │   ├── diff_int5.pdf
    │   ├── diff_int6.eps
    │   ├── diff_int6.pdf
    │   ├── diff_int7.eps
    │   ├── diff_int7.pdf
    │   ├── diff_int8.eps
    │   ├── diff_int8.pdf
    │   ├── diff_int9.eps
    │   ├── diff_int9.pdf
    │   ├── example1.eps
    │   ├── example1.pdf
    │   ├── example_cdf.eps
    │   ├── example_cdf.pdf
    │   ├── expo_cdf.eps
    │   ├── expo_cdf.pdf
    │   ├── interarrivals.eps
    │   ├── interarrivals.pdf
    │   ├── interarrivals_logy.eps
    │   ├── interarrivals_logy.pdf
    │   ├── noise-triple.eps
    │   ├── noise-triple.pdf
    │   ├── noise0.eps
    │   ├── noise0.pdf
    │   ├── noise1.eps
    │   ├── noise1.pdf
    │   ├── noise2.eps
    │   ├── noise2.pdf
    │   ├── noise3.eps
    │   ├── noise3.pdf
    │   ├── normal_cdf.eps
    │   ├── normal_cdf.pdf
    │   ├── nsfg_birthwgt_model.eps
    │   ├── nsfg_birthwgt_model.pdf
    │   ├── nsfg_birthwgt_normal.eps
    │   ├── nsfg_birthwgt_normal.pdf
    │   ├── pareto_cdf.eps
    │   ├── pareto_cdf.pdf
    │   ├── pinknoise0.eps
    │   ├── pinknoise0.pdf
    │   ├── pinknoise1.eps
    │   ├── pinknoise1.pdf
    │   ├── pinknoise2.eps
    │   ├── pinknoise2.pdf
    │   ├── pinknoise3.eps
    │   ├── pinknoise3.pdf
    │   ├── pinknoise4.eps
    │   ├── pinknoise4.pdf
    │   ├── pinknoise5.eps
    │   ├── pinknoise5.pdf
    │   ├── rednoise0.eps
    │   ├── rednoise0.pdf
    │   ├── rednoise1.eps
    │   ├── rednoise1.pdf
    │   ├── rednoise2.eps
    │   ├── rednoise2.pdf
    │   ├── rednoise3.eps
    │   ├── rednoise3.pdf
    │   ├── rednoise4.eps
    │   ├── rednoise4.pdf
    │   ├── rednoise5.eps
    │   ├── rednoise5.pdf
    │   ├── sampling1.eps
    │   ├── sampling1.pdf
    │   ├── sampling2.eps
    │   ├── sampling2.pdf
    │   ├── sampling3.eps
    │   ├── sampling3.pdf
    │   ├── sampling4.eps
    │   ├── sampling4.pdf
    │   ├── sampling5.eps
    │   ├── sampling5.pdf
    │   ├── sampling6.eps
    │   ├── sampling6.pdf
    │   ├── sampling7.eps
    │   ├── sampling7.pdf
    │   ├── sampling8.eps
    │   ├── sampling8.pdf
    │   ├── sampling9.eps
    │   ├── sampling9.pdf
    │   ├── sinusoid1.eps
    │   ├── sinusoid1.pdf
    │   ├── sounds1.eps
    │   ├── sounds1.pdf
    │   ├── sounds2.eps
    │   ├── sounds2.pdf
    │   ├── sounds3.eps
    │   ├── sounds3.pdf
    │   ├── sounds4.eps
    │   ├── sounds4.pdf
    │   ├── square-100-1.eps
    │   ├── square-100-1.pdf
    │   ├── square-100-2.eps
    │   ├── square-100-2.pdf
    │   ├── systems1.eps
    │   ├── systems1.pdf
    │   ├── systems2.eps
    │   ├── systems2.pdf
    │   ├── systems3.eps
    │   ├── systems3.pdf
    │   ├── systems4.eps
    │   ├── systems4.pdf
    │   ├── systems5.eps
    │   ├── systems5.pdf
    │   ├── systems6.eps
    │   ├── systems6.pdf
    │   ├── systems7.eps
    │   ├── systems7.pdf
    │   ├── systems8.eps
    │   ├── systems8.pdf
    │   ├── triangle-1100-1.eps
    │   ├── triangle-1100-1.pdf
    │   ├── triangle-1100-2.eps
    │   ├── triangle-1100-2.pdf
    │   ├── triangle-200-1.eps
    │   ├── triangle-200-1.pdf
    │   ├── triangle-200-2.eps
    │   ├── triangle-200-2.pdf
    │   ├── tuning1.eps
    │   ├── tuning1.pdf
    │   ├── uml_diagram1.eps
    │   ├── uml_diagram1.pdf
    │   ├── violin1.eps
    │   ├── violin1.pdf
    │   ├── violin2.eps
    │   ├── violin2.pdf
    │   ├── whitenoise0.eps
    │   ├── whitenoise0.pdf
    │   ├── whitenoise1.eps
    │   ├── whitenoise1.pdf
    │   ├── whitenoise2.eps
    │   ├── whitenoise2.pdf
    │   ├── whitenoise3.eps
    │   ├── whitenoise3.pdf
    │   ├── whitenoise4.eps
    │   ├── whitenoise4.pdf
    │   ├── whitenoise5.eps
    │   ├── whitenoise5.pdf
    │   ├── windowing1.eps
    │   ├── windowing1.pdf
    │   ├── windowing2.eps
    │   ├── windowing2.pdf
    │   ├── windowing3.eps
    │   └── windowing3.pdf
    ├── footer.html
    ├── header.html
    ├── hevea.sty
    ├── htmlonly
    ├── latexonly
    ├── localdef.py
    ├── next.png
    └── up.png
├── code
    ├── 100475__iluppai__saxophone-weep.wav
    ├── 105977__wcfl10__favorite-station.wav
    ├── 120994__thirsk__120-oboe.wav
    ├── 132736__ciccarelli__ocean-waves.wav
    ├── 170255__dublie__trumpet.wav
    ├── 180929__docquesting__crowd-noise.wav
    ├── 180960__kleeb__gunshot.wav
    ├── 181934__landub__applause2.wav
    ├── 18871__zippi1__sound-bell-440hz.wav
    ├── 253887__themusicalnomad__positive-beeps.wav
    ├── 263868__kevcio__amen-break-a-160-bpm.wav
    ├── 28042__bcjordan__voicedownbew.wav
    ├── 328878__tzurkan__guitar-phrase-tzu.wav
    ├── 72475__rockwehrmann__glissup02.wav
    ├── 87778__marcgascon7__vocals.wav
    ├── 92002__jcveliz__violin-origional.wav
    ├── BTC_USD_2013-10-01_2020-03-26-CoinDesk.csv
    ├── FB_2.csv
    ├── GardnerFractalMusic.pdf
    ├── Makefile
    ├── aliasing.py
    ├── autocorr.py
    ├── cacophony.ipynb
    ├── chap01.ipynb
    ├── chap01preview.ipynb
    ├── chap01soln.ipynb
    ├── chap02.ipynb
    ├── chap02soln.ipynb
    ├── chap03.ipynb
    ├── chap03soln.ipynb
    ├── chap04.ipynb
    ├── chap04soln.ipynb
    ├── chap05.ipynb
    ├── chap05soln.ipynb
    ├── chap06.ipynb
    ├── chap06soln.ipynb
    ├── chap07.ipynb
    ├── chap07soln.ipynb
    ├── chap08.ipynb
    ├── chap08soln.ipynb
    ├── chap09.ipynb
    ├── chap09soln.ipynb
    ├── chap10.ipynb
    ├── chap10preview.ipynb
    ├── chap10soln.ipynb
    ├── chap11.ipynb
    ├── chap11soln.ipynb
    ├── chirp.py
    ├── convolution.py
    ├── dct.py
    ├── dft.py
    ├── dft_example.ipynb
    ├── diff_int.py
    ├── fb_1.csv
    ├── fourth_wave.ipynb
    ├── fourth_wave.png
    ├── noise.py
    ├── phase.ipynb
    ├── sampling.py
    ├── saxophone.ipynb
    ├── scipy2015_demo.ipynb
    ├── sounds.py
    ├── stalbans_a_mono.wav
    ├── systems.py
    ├── thinkdsp.py
    ├── thinkdsp_test.py
    ├── thinkplot.py
    ├── thinkstats2.py
    ├── tos-redalert.wav
    └── voss.ipynb
├── environment.yml
├── pyproject.toml
├── requirements-dev.txt
└── requirements.txt


/.devcontainer/Dockerfile:
--------------------------------------------------------------------------------
 1 | FROM mcr.microsoft.com/devcontainers/miniconda
 2 | 
 3 | # Copy environment.yml (if found) to a temp location so we update the environment. Also
 4 | # copy "noop.txt" so the COPY instruction does not fail if no environment.yml exists.
 5 | COPY environment.yml* .devcontainer/noop.txt /tmp/conda-tmp/
 6 | RUN if [ -f "/tmp/conda-tmp/environment.yml" ]; then umask 0002 && /opt/conda/bin/conda env update -n base -f /tmp/conda-tmp/environment.yml; fi \
 7 |     && rm -rf /tmp/conda-tmp
 8 | 
 9 | # Install python 3.6
10 | RUN conda install -y python=3.6 \
11 |     && pip install --no-cache-dir pipx \
12 |     && pipx reinstall-all
13 | 
14 | # [Optional] Uncomment this section to install additional OS packages.
15 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
16 | #     && apt-get -y install --no-install-recommends <your-package-list-here>
17 | 


--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the
 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/miniconda
 3 | {
 4 | 	"name": "Miniconda (Python 3)",
 5 | 	"build": { 
 6 | 		"context": "..",
 7 | 		"dockerfile": "Dockerfile"
 8 | 	}
 9 | 
10 | 	// Features to add to the dev container. More info: https://containers.dev/features.
11 | 	// "features": {},
12 | 
13 | 	// Use 'forwardPorts' to make a list of ports inside the container available locally.
14 | 	// "forwardPorts": [],
15 | 
16 | 	// Use 'postCreateCommand' to run commands after the container is created.
17 | 	// "postCreateCommand": "python --version",
18 | 
19 | 	// Configure tool-specific properties.
20 | 	// "customizations": {},
21 | 
22 | 	// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
23 | 	// "remoteUser": "root"
24 | }
25 | 


--------------------------------------------------------------------------------
/.devcontainer/noop.txt:
--------------------------------------------------------------------------------
1 | This file is copied into the container along with environment.yml* from the
2 | parent folder. This is done to prevent the Dockerfile COPY instruction from 
3 | failing if no environment.yml is found.


--------------------------------------------------------------------------------
/.github/workflows/tests.yml:
--------------------------------------------------------------------------------
 1 | name: tests
 2 | 
 3 | on:
 4 |   push:
 5 |     branches: [master]
 6 |   pull_request:
 7 |   schedule:
 8 |     # https://cron.help/#0_0_1_*_*
 9 |     # min hour day-of-month month day-of-week
10 |     - cron: "0 0 1 * *"
11 |   workflow_dispatch:
12 | 
13 | jobs:
14 |   tests:
15 |     name: Tests (${{ matrix.os }}, Python ${{ matrix.python-version }})
16 |     runs-on: ${{ matrix.os }}
17 |     strategy:
18 |       matrix:
19 |         os: [ubuntu-latest, macos-latest, windows-latest]
20 |         python-version: ["3.10"]
21 | 
22 |     steps:
23 |       - uses: actions/checkout@v2
24 | 
25 |       - name: Set up Python ${{ matrix.python-version }}
26 |         uses: actions/setup-python@v2
27 |         with:
28 |           python-version: ${{ matrix.python-version }}
29 | 
30 |       - name: Install dependencies
31 |         run: |
32 |           python -m pip install --upgrade pip
33 |           pip install -r requirements-dev.txt
34 | 
35 |       - name: Run tests
36 |         run: |
37 |           make tests
38 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .ipynb_checkpoints/
2 | 


--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
 1 | PROJECT_NAME = ThinkDSP
 2 | PYTHON_VERSION = 3.10
 3 | PYTHON_INTERPRETER = python
 4 | 
 5 | 
 6 | 
 7 | ## Set up Python environment
 8 | create_environment:
 9 | 	conda create -y --name $(PROJECT_NAME) python=$(PYTHON_VERSION)
10 | 	@echo ">>> conda env created. Activate with:\nconda activate $(PROJECT_NAME)"
11 | 
12 | 
13 | ## Install dependencies
14 | requirements:
15 | 	$(PYTHON_INTERPRETER) -m pip install -U pip setuptools wheel
16 | 	$(PYTHON_INTERPRETER) -m pip install -r requirements-dev.txt
17 | 
18 | 
19 | tests:
20 | 	# looks like we can't test chapters with interactives
21 | 	cd code; pytest --nbmake chap0[2346789].ipynb
22 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
  1 | # ThinkDSP
  2 | 
  3 | *Think DSP* is an introduction to Digital Signal Processing in Python.
  4 | 
  5 | [Order *Think DSP* from Amazon.com](http://amzn.to/1naaUCN).
  6 | 
  7 | [Download *Think DSP* in PDF](http://greenteapress.com/thinkdsp/thinkdsp.pdf).
  8 | 
  9 | [Read *Think DSP* in HTML](http://greenteapress.com/thinkdsp/html/index.html).
 10 | 
 11 | The premise of this book (and the other books in the Think X series) is that if you know how to program, you can use that skill to learn other things. I am writing this book because I think the conventional approach to digital signal processing is backward: most books (and the classes that use them) present the material bottom-up, starting with mathematical abstractions like phasors.
 12 | 
 13 | With a programming-based approach, I can go top-down, which means I can present the most important ideas right away. By the end of the first chapter, you can decompose a sound into its harmonics, modify the harmonics, and generate new sounds.
 14 | 
 15 | Think DSP is a Free Book. It is available under the [Creative Commons Attribution-NonCommercial 3.0 Unported License](https://creativecommons.org/licenses/by-nc/3.0/), which means that you are free to copy, distribute, and modify it, as long as you attribute the work and don't use it for commercial purposes.
 16 | 
 17 | Here's a notebook that previews what you will see in Chapter 1:
 18 | 
 19 | * [chap01preview.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap01preview.ipynb)
 20 | 
 21 | And if you want to see where we are headed, here's a preview of Chapter 10:
 22 | 
 23 | * [chap10preview.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap10preview.ipynb)
 24 | 
 25 | 
 26 | ## Running the code
 27 | 
 28 | Most of the code for this book is in Jupyter notebooks.
 29 | If you are not familiar with Jupyter, you can run a tutorial by [clicking here](https://jupyter.org/try).  Then select "Try Classic Notebook".  It will open a notebook with instructions for getting started.
 30 | 
 31 | To run the ThinkDSP code, you have several options:
 32 | 
 33 | Option 1: Run the notebooks on Google Colab.
 34 | 
 35 | Option 2: Run the notebooks on Binder.
 36 | 
 37 | Option 3: Use Conda to install the libraries you need and run the notebooks on your computer.
 38 | 
 39 | Option 4: Use poetry to install the libraries you need and run the notebooks on your computer.
 40 | 
 41 | The following sections explain these options in detail.
 42 | 
 43 | Note: I have heard from a few people who tried to run the code in Spyder.  Apparently there were problems, so I don't recommend it.
 44 | 
 45 | ### Option 1: Run on Colab
 46 | 
 47 | I have recently updated most of the notebooks in this repository so they run on Colab.
 48 | 
 49 | You can open any of them by clicking on the links below.  If you want to modify and save any of them, you can use Colab to save a copy in a Google Drive or your own GitHub repo, or on your computer.
 50 | 
 51 | * [chap01.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap01.ipynb)
 52 | * [chap01soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap01soln.ipynb)
 53 | * [chap02.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap02.ipynb)
 54 | * [chap02soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap02soln.ipynb)
 55 | * [chap03.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap03.ipynb)
 56 | * [chap03soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap03soln.ipynb)
 57 | * [chap04.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap04.ipynb)
 58 | * [chap04soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap04soln.ipynb)
 59 | * [chap05.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap05.ipynb)
 60 | * [chap05soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap05soln.ipynb)
 61 | * [chap06.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap06.ipynb)
 62 | * [chap06soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap06soln.ipynb)
 63 | * [chap07.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap07.ipynb)
 64 | * [chap07soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap07soln.ipynb)
 65 | * [chap08.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap08.ipynb)
 66 | * [chap08soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap08soln.ipynb)
 67 | * [chap09.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap09.ipynb)
 68 | * [chap09soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap09soln.ipynb)
 69 | * [chap10.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap10.ipynb)
 70 | * [chap10soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap10soln.ipynb)
 71 | * [chap11.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap11.ipynb)
 72 | * [chap11soln.ipynb](https://colab.research.google.com/github/AllenDowney/ThinkDSP/blob/master/code/chap11soln.ipynb)
 73 | 
 74 | 
 75 | ### Option 2: Run on Binder
 76 | 
 77 | To run the code for this book on Binder, press this button:
 78 | 
 79 | [![Binder](http://mybinder.org/badge.svg)](http://mybinder.org/repo/AllenDowney/ThinkDSP)
 80 | 
 81 | It takes a minute or so to start up, but then you should see the Jupyter home page with a list of files.  Click on `code` to open the folder with the notebooks, then click on one of the notebooks (with the .ipynb extension).
 82 | 
 83 | 
 84 | ### Option 3: Install Python+Jupyter
 85 | 
 86 | First, download the files from this repository.  If you are a Git user, you can run
 87 | 
 88 | ```
 89 | git clone --depth 1 https://github.com/AllenDowney/ThinkDSP.git
 90 | ```
 91 | 
 92 | Otherwise you can [download this Zip file](https://github.com/AllenDowney/ThinkDSP/archive/master.zip) and unzip it.
 93 | Either way, you should end up with a directory called `ThinkDSP`.
 94 | 
 95 | Now, if you don't already have Jupyter, I highly recommend installing Anaconda, which is a Python distribution that contains everything you need to run the ThinkDSP code.  It is easy to install on Windows, Mac, and Linux, and because it does a
 96 | user-level install, it will not interfere with other Python installations.
 97 | 
 98 | [Information about installing Anaconda is here](https://www.anaconda.com/distribution/).
 99 | 
100 | If you have the choice of Python 2 or 3, choose Python 3.
101 | 
102 | There are two ways to get the packages you need for ThinkDSP.  You can install them by hand or create a Conda environment.
103 | 
104 | To install them by hand run
105 | 
106 | ```
107 | conda install jupyter numpy scipy pandas matplotlib seaborn
108 | ```
109 | 
110 | Or, to create a conda environment, run
111 | 
112 | ```
113 | cd ThinkDSP
114 | conda env create -f environment.yml
115 | conda activate ThinkDSP
116 | ```
117 | 
118 | 
119 | ### Option 4: Use poetry to manage the project on your computer or notebook locally.
120 | 
121 | First, download the files from this repository.  If you are a Git user, you can run
122 | 
123 | ```
124 | git clone --depth 1 https://github.com/AllenDowney/ThinkDSP.git
125 | ```
126 | 
127 | Then, assuming you have [poetry](https://python-poetry.org) installed on your machine, run
128 | 
129 | ```
130 | cd ThinkDSP
131 | poetry install
132 | ```
133 | 
134 | to install the libraries you need in a virtual environment.  To activate the environment, run
135 | 
136 | ```
137 | poetry shell
138 | ```
139 | 
140 | Then you can run Jupyter.
141 | 
142 | 
143 | ## Run Jupyter 
144 | 
145 | To start Jupyter, run:
146 | 
147 | ```
148 | jupyter notebook
149 | ```
150 | 
151 | Jupyter should launch your default browser or open a tab in an existing browser window.
152 | If not, the Jupyter server should print a URL you can use.  For example, when I launch Jupyter, I get
153 | 
154 | ```
155 | ~/ThinkComplexity2$ jupyter notebook
156 | [I 10:03:20.115 NotebookApp] Serving notebooks from local directory: /home/downey/ThinkDSP
157 | [I 10:03:20.115 NotebookApp] 0 active kernels
158 | [I 10:03:20.115 NotebookApp] The Jupyter Notebook is running at: http://localhost:8888/
159 | [I 10:03:20.115 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
160 | ```
161 | 
162 | In this case, the URL is [http://localhost:8888](http://localhost:8888).
163 | When you start your server, you might get a different URL.
164 | Whatever it is, if you paste it into a browser, you should see a home page with a list of directories.
165 | 
166 | Click on `code` to open the folder with the notebooks, then click on one of the notebooks (with the .ipynb extension).
167 | 
168 | Select the cell with the import statements and press "Shift-Enter" to run the code in the cell.
169 | If it works and you get no error messages, **you are all set**.
170 | 
171 | If you get error messages about missing packages, you can install the packages you need using your
172 | package manager, or install Anaconda.
173 | 
174 | If you run into problems with these instructions, let me know and I will make corrections.  Good luck!
175 | 
176 | 
177 | 
178 | ## Freesound
179 | 
180 | Special thanks to Freesound (http://freesound.org), which is the source of many of the
181 | sound samples I use in this book, and to the Freesound users who
182 | uploaded those sounds.  I include some of their wave files in
183 | the GitHub repository for this book, using the original file
184 | names, so it should be easy to find their sources.
185 | 
186 | Unfortunately, most Freesound users don't make their real names
187 | available, so I can only thank them using their user names.  Samples
188 | used in this book were contributed by Freesound users: iluppai,
189 | wcfl10, thirsk, docquesting, kleeb, landup, zippi1, themusicalnomad,
190 | bcjordan, rockwehrmann, marchascon7, jcveliz.  Thank you all!
191 | 
192 | Here are links to the sources:
193 | 
194 | http://www.freesound.org/people/iluppai/sounds/100475/
195 | 
196 | http://www.freesound.org/people/wcfl10/sounds/105977/
197 | 
198 | http://www.freesound.org/people/Thirsk/sounds/120994/
199 | 
200 | http://www.freesound.org/people/ciccarelli/sounds/132736/
201 | 
202 | http://www.freesound.org/people/Kleeb/sounds/180960/
203 | 
204 | http://www.freesound.org/people/zippi1/sounds/18871/
205 | 
206 | http://www.freesound.org/people/themusicalnomad/sounds/253887/
207 | 
208 | http://www.freesound.org/people/bcjordan/sounds/28042/
209 | 
210 | http://www.freesound.org/people/rockwehrmann/sounds/72475/
211 | 
212 | http://www.freesound.org/people/marcgascon7/sounds/87778/
213 | 
214 | http://www.freesound.org/people/jcveliz/sounds/92002/
215 | 


--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal


--------------------------------------------------------------------------------
/book/Makefile:
--------------------------------------------------------------------------------
 1 | # instructions
 2 | 
 3 | # Currently the staging area for greenteapress.com is on bob at
 4 | # /home/downey/web/greenteapress
 5 | 
 6 | # To build and sync a new release:
 7 | # make
 8 | # make hevea
 9 | # make distrib
10 | 
11 | PDFFLAGS = -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress \
12 |            -dCompressPages=true -dUseFlateCompression=true  \
13 |            -dEmbedAllFonts=true -dSubsetFonts=true -dMaxSubsetPct=100
14 | 
15 | 
16 | all:	book.tex
17 | 	pdflatex book
18 | 	makeindex book.idx
19 | 	pdflatex book
20 | 	mv book.pdf thinkdsp.pdf
21 | 	evince thinkdsp.pdf
22 | 
23 | HEVEABUILDLOG=build.log
24 | 
25 | hevea:
26 | 	sed 's/\(figs\/[^.]*\).\(pdf\|png\)/\1.eps/' book.tex > thinkdsp.tex
27 | 	rm -rf html
28 | 	mkdir html
29 | 	hevea macros.hva -O -e latexonly htmlonly thinkdsp 2>&1 | tee ${HEVEABUILDLOG}
30 | # the following greps are a kludge to prevent imagen from seeing
31 | # the definitions in latexonly, and to avoid headers on the images
32 | 	grep -v latexonly thinkdsp.image.tex > a; mv a thinkdsp.image.tex
33 | 	sed s/\\\\usepackage{fancyhdr}// < thinkdsp.image.tex > a; mv a thinkdsp.image.tex
34 | 	imagen -png thinkdsp
35 | 	hacha thinkdsp.html
36 | 	cp up.png next.png back.png html
37 | 	cp custom.css thinkdsp.css
38 | 	mv index.html thinkdsp.css thinkdsp*.html thinkdsp*.png *motif.gif html
39 | 
40 | DEST = /home/downey/web/greenteapress/thinkdsp
41 | 
42 | distrib:
43 | 	rm -rf dist
44 | 	mkdir dist
45 | 	rsync -a thinkdsp.pdf html dist
46 | 	rsync -a dist/* $(DEST)
47 | 	chmod -R o+r $(DEST)/*
48 | 	cd $(DEST)/..; sh back
49 | 
50 | plastex:
51 | 	# Before running plastex, we need the current directory in PYTHONPATH
52 | 	# export PYTHONPATH=$PYTHONPATH:.
53 | 	rm -rf /home/downey/thinkdsp/trunk/book/.svn
54 | 	plastex --renderer=DocBook --theme=book --image-resolution=300 --filename=book.xml book.tex
55 | 	rm -rf /home/downey/thinkdsp/trunk/book/.svn
56 | 
57 | xxe:
58 | 	xmlcopyeditor ~/ThinkDSP/book/book/book.xml &
59 | 
60 | lint:
61 | 	xmllint -noout book/book.xml
62 | 
63 | OREILLY = atlas
64 | 
65 | oreilly:
66 | 	rsync -a book/ $(OREILLY)
67 | 	rsync -a figs/* $(OREILLY)/figs/
68 | 	cd $(OREILLY); git add .
69 | 	cd $(OREILLY); git commit -m "Automated check in."
70 | 	cd $(OREILLY); git push
71 | 
72 | clean:
73 | 	rm -f *~ *.aux *.log *.dvi *.idx *.ilg *.ind *.toc
74 | 
75 | 
76 | pdfpextr = \
77 |     gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dSAFER \
78 |        -dFirstPage=$(1) \
79 |        -dLastPage=$(2) \
80 |        -sOutputFile=$(4) \
81 |        $(3)
82 | 
83 | split:
84 | 	$(call pdfpextr,5,7,thinkos.pdf,chap00.pdf)
85 | 	$(call pdfpextr,13,20,thinkos.pdf,chap01.pdf)
86 | 	$(call pdfpextr,21,26,thinkos.pdf,chap02.pdf)
87 | 	$(call pdfpextr,27,34,thinkos.pdf,chap03.pdf)
88 | 	$(call pdfpextr,35,42,thinkos.pdf,chap04.pdf)
89 | 	$(call pdfpextr,43,50,thinkos.pdf,chap05.pdf)
90 | 	$(call pdfpextr,51,56,thinkos.pdf,chap06.pdf)
91 | 	$(call pdfpextr,57,68,thinkos.pdf,chap07.pdf)
92 | 	$(call pdfpextr,69,74,thinkos.pdf,chap08.pdf)
93 | 	$(call pdfpextr,75,82,thinkos.pdf,chap09.pdf)
94 | 	$(call pdfpextr,83,94,thinkos.pdf,chap10.pdf)
95 | 	$(call pdfpextr,95,101,thinkos.pdf,chap11.pdf)
96 | 


--------------------------------------------------------------------------------
/book/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/back.png


--------------------------------------------------------------------------------
/book/diagram.tex:
--------------------------------------------------------------------------------
 1 | % LaTeX source for ``Think DSP: Digital Signal Processing for Programmers''
 2 | % Copyright 2013  Allen B. Downey.
 3 | 
 4 | % License: Creative Commons Attribution-NonCommercial 3.0 Unported License.
 5 | % http://creativecommons.org/licenses/by-nc/3.0/
 6 | %
 7 | 
 8 | \[ 
 9 | \begin{matrix}
10 | & {\large \mathtt{M}} &
11 |  \begin{bmatrix} 
12 | 0.6 \\
13 | 0.25 \\
14 | 0.1 \\
15 | 0.05 \\
16 | \end{bmatrix}
17 | = \mathtt{amps}
18 | \\
19 | \\
20 | \begin{matrix} 
21 | &.& \\
22 | &.& \\
23 | &t_n& \\
24 | &.& \\
25 | &.& \\
26 | \end{matrix}
27 | &
28 | \begin{bmatrix} 
29 | . & . & . & . \\
30 | . & . & . & . \\
31 | a & b & c & d \\
32 | . & . & . & . \\
33 | . & . & . & . \\
34 | \end{bmatrix} 
35 | &
36 | \begin{bmatrix} 
37 | &.& \\
38 | &.& \\
39 | &e& \\
40 | &.& \\
41 | &.& \\
42 | \end{bmatrix} = \mathtt{ys}
43 | \\
44 | \\
45 | &
46 | \begin{matrix}
47 | . & f_k & . & . \\
48 | \end{matrix}
49 | &
50 | \\
51 | \end{matrix}
52 | \]
53 | 
54 | 
55 |  
56 | 


--------------------------------------------------------------------------------
/book/diagram2.tex:
--------------------------------------------------------------------------------
 1 | % LaTeX source for ``Think DSP: Digital Signal Processing for Programmers''
 2 | % Copyright 2013  Allen B. Downey.
 3 | 
 4 | % License: Creative Commons Attribution-NonCommercial 3.0 Unported License.
 5 | % http://creativecommons.org/licenses/by-nc/3.0/
 6 | %
 7 | 
 8 | \[ 
 9 | \begin{matrix}
10 | f[0]     & [ & g[0] & g[1] & g[2] & ... &     &    & ] \\
11 | f[1]     & [ &     & g[0] & g[1] & g[2] & ... &    & ] \\   
12 | f[2]     & [ &     &     & g[0] & g[1] & g[2] & ...& ] \\ 
13 | \noalign{\vskip 2mm}
14 | \hline
15 | \noalign{\vskip 2mm}
16 |         & [ &     &     & h[2] &     &    &    & ] \\
17 | \end{matrix}
18 | \]
19 | 
20 | 
21 |  
22 | 


--------------------------------------------------------------------------------
/book/figs/MP86F77F.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/MP86F77F.pdf


--------------------------------------------------------------------------------
/book/figs/aliasing-3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/aliasing-3.pdf


--------------------------------------------------------------------------------
/book/figs/aliasing1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/aliasing1.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr1.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr2.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr3.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr4.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr5.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr6.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr7.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr8.pdf


--------------------------------------------------------------------------------
/book/figs/autocorr9.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/autocorr9.pdf


--------------------------------------------------------------------------------
/book/figs/brfss_weight_log.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/brfss_weight_log.pdf


--------------------------------------------------------------------------------
/book/figs/chirp1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/chirp1.pdf


--------------------------------------------------------------------------------
/book/figs/chirp2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/chirp2.pdf


--------------------------------------------------------------------------------
/book/figs/chirp3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/chirp3.pdf


--------------------------------------------------------------------------------
/book/figs/convolution1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution1.pdf


--------------------------------------------------------------------------------
/book/figs/convolution10.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution10.pdf


--------------------------------------------------------------------------------
/book/figs/convolution2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution2.pdf


--------------------------------------------------------------------------------
/book/figs/convolution4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution4.pdf


--------------------------------------------------------------------------------
/book/figs/convolution5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution5.pdf


--------------------------------------------------------------------------------
/book/figs/convolution6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution6.pdf


--------------------------------------------------------------------------------
/book/figs/convolution7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution7.pdf


--------------------------------------------------------------------------------
/book/figs/convolution8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution8.pdf


--------------------------------------------------------------------------------
/book/figs/convolution9.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/convolution9.pdf


--------------------------------------------------------------------------------
/book/figs/dct1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/dct1.pdf


--------------------------------------------------------------------------------
/book/figs/dft1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/dft1.pdf


--------------------------------------------------------------------------------
/book/figs/dft2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/dft2.pdf


--------------------------------------------------------------------------------
/book/figs/dft3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/dft3.pdf


--------------------------------------------------------------------------------
/book/figs/diagram.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diagram.pdf


--------------------------------------------------------------------------------
/book/figs/diagram1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diagram1.pdf


--------------------------------------------------------------------------------
/book/figs/diagram2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diagram2.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int1.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int2.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int3.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int4.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int5.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int6.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int7.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int8.pdf


--------------------------------------------------------------------------------
/book/figs/diff_int9.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/diff_int9.pdf


--------------------------------------------------------------------------------
/book/figs/example1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/example1.pdf


--------------------------------------------------------------------------------
/book/figs/example_cdf.eps:
--------------------------------------------------------------------------------
  1 | %!PS-Adobe-3.0 EPSF-3.0
  2 | %%Title: example_cdf.eps
  3 | %%Creator: matplotlib version 0.99.0, http://matplotlib.sourceforge.net/
  4 | %%CreationDate: Wed May  4 13:22:36 2011
  5 | %%Orientation: portrait
  6 | %%BoundingBox: 18 180 594 612
  7 | %%EndComments
  8 | %%BeginProlog
  9 | /mpldict 8 dict def
 10 | mpldict begin
 11 | /m { moveto } bind def
 12 | /l { lineto } bind def
 13 | /r { rlineto } bind def
 14 | /c { curveto } bind def
 15 | /cl { closepath } bind def
 16 | /box {
 17 | m
 18 | 1 index 0 r
 19 | 0 exch r
 20 | neg 0 r
 21 | cl
 22 | } bind def
 23 | /clipbox {
 24 | box
 25 | clip
 26 | newpath
 27 | } bind def
 28 | %!PS-Adobe-3.0 Resource-Font
 29 | %%Title: DejaVu Sans
 30 | %%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain 
 31 | %%Creator: Converted from TrueType by PPR
 32 | 25 dict begin
 33 | /_d{bind def}bind def
 34 | /_m{moveto}_d
 35 | /_l{lineto}_d
 36 | /_cl{closepath eofill}_d
 37 | /_c{curveto}_d
 38 | /_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d
 39 | /_e{exec}_d
 40 | /FontName /DejaVuSans def
 41 | /PaintType 0 def
 42 | /FontMatrix[.001 0 0 .001 0 0]def
 43 | /FontBBox[-1020 -349 1681 1167]def
 44 | /FontType 3 def
 45 | /Encoding StandardEncoding def
 46 | /FontInfo 10 dict dup begin
 47 | /FamilyName (DejaVu Sans) def
 48 | /FullName (DejaVu Sans) def
 49 | /Notice (Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain ) def
 50 | /Weight (Book) def
 51 | /Version (Version 2.29) def
 52 | /ItalicAngle 0.0 def
 53 | /isFixedPitch false def
 54 | /UnderlinePosition -130 def
 55 | /UnderlineThickness 90 def
 56 | end readonly def
 57 | /CharStrings 15 dict dup begin
 58 | /parenleft{390 0 86 -131 310 759 _sc
 59 | 310 759 _m
 60 | 266 683 234 609 213 536 _c
 61 | 191 463 181 389 181 314 _c
 62 | 181 238 191 164 213 91 _c
 63 | 234 17 266 -56 310 -131 _c
 64 | 232 -131 _l
 65 | 183 -54 146 20 122 94 _c
 66 | 98 168 86 241 86 314 _c
 67 | 86 386 98 459 122 533 _c
 68 | 146 607 182 682 232 759 _c
 69 | 310 759 _l
 70 | _cl}_d
 71 | /parenright{390 0 80 -131 304 759 _sc
 72 | 80 759 _m
 73 | 158 759 _l
 74 | 206 682 243 607 267 533 _c
 75 | 291 459 304 386 304 314 _c
 76 | 304 241 291 168 267 94 _c
 77 | 243 20 206 -54 158 -131 _c
 78 | 80 -131 _l
 79 | 123 -56 155 17 177 91 _c
 80 | 198 164 209 238 209 314 _c
 81 | 209 389 198 463 177 536 _c
 82 | 155 609 123 683 80 759 _c
 83 | _cl}_d
 84 | /period{318 0 107 0 210 124 _sc
 85 | 107 124 _m
 86 | 210 124 _l
 87 | 210 0 _l
 88 | 107 0 _l
 89 | 107 124 _l
 90 | _cl}_d
 91 | /zero{636 0 66 -13 570 742 _sc
 92 | 318 664 _m
 93 | 267 664 229 639 203 589 _c
 94 | 177 539 165 464 165 364 _c
 95 | 165 264 177 189 203 139 _c
 96 | 229 89 267 64 318 64 _c
 97 | 369 64 407 89 433 139 _c
 98 | 458 189 471 264 471 364 _c
 99 | 471 464 458 539 433 589 _c
100 | 407 639 369 664 318 664 _c
101 | 318 742 _m
102 | 399 742 461 709 505 645 _c
103 | 548 580 570 486 570 364 _c
104 | 570 241 548 147 505 83 _c
105 | 461 19 399 -13 318 -13 _c
106 | 236 -13 173 19 130 83 _c
107 | 87 147 66 241 66 364 _c
108 | 66 486 87 580 130 645 _c
109 | 173 709 236 742 318 742 _c
110 | _cl}_d
111 | /one{636 0 110 0 544 729 _sc
112 | 124 83 _m
113 | 285 83 _l
114 | 285 639 _l
115 | 110 604 _l
116 | 110 694 _l
117 | 284 729 _l
118 | 383 729 _l
119 | 383 83 _l
120 | 544 83 _l
121 | 544 0 _l
122 | 124 0 _l
123 | 124 83 _l
124 | _cl}_d
125 | /two{{636 0 73 0 536 742 _sc
126 | 192 83 _m
127 | 536 83 _l
128 | 536 0 _l
129 | 73 0 _l
130 | 73 83 _l
131 | 110 121 161 173 226 239 _c
132 | 290 304 331 346 348 365 _c
133 | 380 400 402 430 414 455 _c
134 | 426 479 433 504 433 528 _c
135 | 433 566 419 598 392 622 _c
136 | 365 646 330 659 286 659 _c
137 | 255 659 222 653 188 643 _c
138 | 154 632 117 616 78 594 _c
139 | 78 694 _l
140 | 118 710 155 722 189 730 _c
141 | 223 738 255 742 284 742 _c
142 | 359 742 419 723 464 685 _c
143 | 509 647 532 597 532 534 _c
144 | 532 504 526 475 515 449 _c
145 | 504 422 484 390 454 354 _c
146 | 446 344 420 317 376 272 _c
147 | 332 227 271 164 192 83 _c
148 | _cl}_e}_d
149 | /three{{636 0 76 -13 556 742 _sc
150 | 406 393 _m
151 | 453 383 490 362 516 330 _c
152 | 542 298 556 258 556 212 _c
153 | 556 140 531 84 482 45 _c
154 | 432 6 362 -13 271 -13 _c
155 | 240 -13 208 -10 176 -4 _c
156 | 144 1 110 10 76 22 _c
157 | 76 117 _l
158 | 103 101 133 89 166 81 _c
159 | 198 73 232 69 268 69 _c
160 | 330 69 377 81 409 105 _c
161 | 441 129 458 165 458 212 _c
162 | 458 254 443 288 413 312 _c
163 | 383 336 341 349 287 349 _c
164 | 202 349 _l
165 | 202 430 _l
166 | 291 430 _l
167 | 339 430 376 439 402 459 _c
168 | 428 478 441 506 441 543 _c
169 | 441 580 427 609 401 629 _c
170 | 374 649 336 659 287 659 _c
171 | 260 659 231 656 200 650 _c
172 | 169 644 135 635 98 623 _c
173 | 98 711 _l
174 | 135 721 170 729 203 734 _c
175 | 235 739 266 742 296 742 _c
176 | }_e{370 742 429 725 473 691 _c
177 | 517 657 539 611 539 553 _c
178 | 539 513 527 479 504 451 _c
179 | 481 423 448 403 406 393 _c
180 | _cl}_e}_d
181 | /four{636 0 49 0 580 729 _sc
182 | 378 643 _m
183 | 129 254 _l
184 | 378 254 _l
185 | 378 643 _l
186 | 352 729 _m
187 | 476 729 _l
188 | 476 254 _l
189 | 580 254 _l
190 | 580 172 _l
191 | 476 172 _l
192 | 476 0 _l
193 | 378 0 _l
194 | 378 172 _l
195 | 49 172 _l
196 | 49 267 _l
197 | 352 729 _l
198 | _cl}_d
199 | /five{{636 0 77 -13 549 729 _sc
200 | 108 729 _m
201 | 495 729 _l
202 | 495 646 _l
203 | 198 646 _l
204 | 198 467 _l
205 | 212 472 227 476 241 478 _c
206 | 255 480 270 482 284 482 _c
207 | 365 482 429 459 477 415 _c
208 | 525 370 549 310 549 234 _c
209 | 549 155 524 94 475 51 _c
210 | 426 8 357 -13 269 -13 _c
211 | 238 -13 207 -10 175 -6 _c
212 | 143 -1 111 6 77 17 _c
213 | 77 116 _l
214 | 106 100 136 88 168 80 _c
215 | 199 72 232 69 267 69 _c
216 | 323 69 368 83 401 113 _c
217 | 433 143 450 183 450 234 _c
218 | 450 284 433 324 401 354 _c
219 | 368 384 323 399 267 399 _c
220 | 241 399 214 396 188 390 _c
221 | 162 384 135 375 108 363 _c
222 | 108 729 _l
223 | _cl}_e}_d
224 | /six{{636 0 70 -13 573 742 _sc
225 | 330 404 _m
226 | 286 404 251 388 225 358 _c
227 | 199 328 186 286 186 234 _c
228 | 186 181 199 139 225 109 _c
229 | 251 79 286 64 330 64 _c
230 | 374 64 409 79 435 109 _c
231 | 461 139 474 181 474 234 _c
232 | 474 286 461 328 435 358 _c
233 | 409 388 374 404 330 404 _c
234 | 526 713 _m
235 | 526 623 _l
236 | 501 635 476 644 451 650 _c
237 | 425 656 400 659 376 659 _c
238 | 310 659 260 637 226 593 _c
239 | 192 549 172 482 168 394 _c
240 | 187 422 211 444 240 459 _c
241 | 269 474 301 482 336 482 _c
242 | 409 482 467 459 509 415 _c
243 | 551 371 573 310 573 234 _c
244 | 573 159 550 99 506 54 _c
245 | 462 9 403 -13 330 -13 _c
246 | 246 -13 181 19 137 83 _c
247 | 92 147 70 241 70 364 _c
248 | 70 479 97 571 152 639 _c
249 | 206 707 280 742 372 742 _c
250 | }_e{396 742 421 739 447 735 _c
251 | 472 730 498 723 526 713 _c
252 | _cl}_e}_d
253 | /eight{{636 0 68 -13 568 742 _sc
254 | 318 346 _m
255 | 271 346 234 333 207 308 _c
256 | 180 283 167 249 167 205 _c
257 | 167 161 180 126 207 101 _c
258 | 234 76 271 64 318 64 _c
259 | 364 64 401 76 428 102 _c
260 | 455 127 469 161 469 205 _c
261 | 469 249 455 283 429 308 _c
262 | 402 333 365 346 318 346 _c
263 | 219 388 _m
264 | 177 398 144 418 120 447 _c
265 | 96 476 85 511 85 553 _c
266 | 85 611 105 657 147 691 _c
267 | 188 725 245 742 318 742 _c
268 | 390 742 447 725 489 691 _c
269 | 530 657 551 611 551 553 _c
270 | 551 511 539 476 515 447 _c
271 | 491 418 459 398 417 388 _c
272 | 464 377 501 355 528 323 _c
273 | 554 291 568 251 568 205 _c
274 | 568 134 546 80 503 43 _c
275 | 459 5 398 -13 318 -13 _c
276 | 237 -13 175 5 132 43 _c
277 | 89 80 68 134 68 205 _c
278 | 68 251 81 291 108 323 _c
279 | 134 355 171 377 219 388 _c
280 | }_e{183 544 _m
281 | 183 506 194 476 218 455 _c
282 | 242 434 275 424 318 424 _c
283 | 360 424 393 434 417 455 _c
284 | 441 476 453 506 453 544 _c
285 | 453 582 441 611 417 632 _c
286 | 393 653 360 664 318 664 _c
287 | 275 664 242 653 218 632 _c
288 | 194 611 183 582 183 544 _c
289 | _cl}_e}_d
290 | /C{{698 0 56 -13 644 742 _sc
291 | 644 673 _m
292 | 644 569 _l
293 | 610 599 575 622 537 638 _c
294 | 499 653 460 661 418 661 _c
295 | 334 661 270 635 226 584 _c
296 | 182 533 160 460 160 364 _c
297 | 160 268 182 194 226 143 _c
298 | 270 92 334 67 418 67 _c
299 | 460 67 499 74 537 90 _c
300 | 575 105 610 128 644 159 _c
301 | 644 56 _l
302 | 609 32 572 15 534 4 _c
303 | 496 -7 455 -13 412 -13 _c
304 | 302 -13 215 20 151 87 _c
305 | 87 154 56 246 56 364 _c
306 | 56 481 87 573 151 641 _c
307 | 215 708 302 742 412 742 _c
308 | 456 742 497 736 535 725 _c
309 | 573 713 610 696 644 673 _c
310 | _cl}_e}_d
311 | /D{770 0 98 0 711 729 _sc
312 | 197 648 _m
313 | 197 81 _l
314 | 316 81 _l
315 | 416 81 490 103 537 149 _c
316 | 583 195 607 267 607 365 _c
317 | 607 463 583 534 537 580 _c
318 | 490 625 416 648 316 648 _c
319 | 197 648 _l
320 | 98 729 _m
321 | 301 729 _l
322 | 442 729 546 699 612 641 _c
323 | 678 582 711 490 711 365 _c
324 | 711 239 677 147 611 88 _c
325 | 545 29 441 0 301 0 _c
326 | 98 0 _l
327 | 98 729 _l
328 | _cl}_d
329 | /F{575 0 98 0 517 729 _sc
330 | 98 729 _m
331 | 517 729 _l
332 | 517 646 _l
333 | 197 646 _l
334 | 197 431 _l
335 | 486 431 _l
336 | 486 348 _l
337 | 197 348 _l
338 | 197 0 _l
339 | 98 0 _l
340 | 98 729 _l
341 | _cl}_d
342 | /x{592 0 29 0 559 547 _sc
343 | 549 547 _m
344 | 351 281 _l
345 | 559 0 _l
346 | 453 0 _l
347 | 294 215 _l
348 | 135 0 _l
349 | 29 0 _l
350 | 241 286 _l
351 | 47 547 _l
352 | 153 547 _l
353 | 298 352 _l
354 | 443 547 _l
355 | 549 547 _l
356 | _cl}_d
357 | end readonly def
358 | 
359 | /BuildGlyph
360 |  {exch begin
361 |  CharStrings exch
362 |  2 copy known not{pop /.notdef}if
363 |  true 3 1 roll get exec
364 |  end}_d
365 | 
366 | /BuildChar {
367 |  1 index /Encoding get exch get
368 |  1 index /BuildGlyph get exec
369 | }_d
370 | 
371 | FontName currentdict end definefont pop
372 | end
373 | %%EndProlog
374 | mpldict begin
375 | 18 180 translate
376 | 576 432 0 0 clipbox
377 | 1.000 setlinewidth
378 | 1 setlinejoin
379 | 2 setlinecap
380 | [] 0 setdash
381 | 1.000 setgray
382 | gsave
383 | 0 0 m
384 | 576 0 l
385 | 576 432 l
386 | 0 432 l
387 | 0 0 l
388 | gsave
389 | fill
390 | grestore
391 | stroke
392 | grestore
393 | gsave
394 | 72 43.2 m
395 | 518.4 43.2 l
396 | 518.4 388.8 l
397 | 72 388.8 l
398 | 72 43.2 l
399 | fill
400 | grestore
401 | 0.000 0.000 1.000 setrgbcolor
402 | gsave
403 | 446.4 345.6 72 43.2 clipbox
404 | 146.4 43.2 m
405 | 146.4 112.32 l
406 | 220.8 112.32 l
407 | 220.8 250.56 l
408 | 295.2 250.56 l
409 | 295.2 319.68 l
410 | 444 319.68 l
411 | 444 388.8 l
412 | stroke
413 | grestore
414 | 0.500 setlinewidth
415 | 0 setlinecap
416 | 0.000 setgray
417 | gsave
418 | /o {
419 | gsave
420 | newpath
421 | translate
422 | 0 0 m
423 | 0 4 l
424 | stroke
425 | grestore
426 | } bind def
427 | 72 43.2 o
428 | grestore
429 | gsave
430 | /o {
431 | gsave
432 | newpath
433 | translate
434 | 0 0 m
435 | 0 -4 l
436 | stroke
437 | grestore
438 | } bind def
439 | 72 388.8 o
440 | grestore
441 | /DejaVuSans findfont
442 | 18.000 scalefont
443 | setfont
444 | gsave
445 | 67.460938 25.590625 translate
446 | 0.000000 rotate
447 | 0.000000 0.250000 m /zero glyphshow
448 | grestore
449 | gsave
450 | /o {
451 | gsave
452 | newpath
453 | translate
454 | 0 0 m
455 | 0 4 l
456 | stroke
457 | grestore
458 | } bind def
459 | 146.4 43.2 o
460 | grestore
461 | gsave
462 | /o {
463 | gsave
464 | newpath
465 | translate
466 | 0 0 m
467 | 0 -4 l
468 | stroke
469 | grestore
470 | } bind def
471 | 146.4 388.8 o
472 | grestore
473 | gsave
474 | 142.493750 26.075000 translate
475 | 0.000000 rotate
476 | 0.000000 0.000000 m /one glyphshow
477 | grestore
478 | gsave
479 | /o {
480 | gsave
481 | newpath
482 | translate
483 | 0 0 m
484 | 0 4 l
485 | stroke
486 | grestore
487 | } bind def
488 | 220.8 43.2 o
489 | grestore
490 | gsave
491 | /o {
492 | gsave
493 | newpath
494 | translate
495 | 0 0 m
496 | 0 -4 l
497 | stroke
498 | grestore
499 | } bind def
500 | 220.8 388.8 o
501 | grestore
502 | gsave
503 | 216.628125 25.840625 translate
504 | 0.000000 rotate
505 | 0.000000 0.000000 m /two glyphshow
506 | grestore
507 | gsave
508 | /o {
509 | gsave
510 | newpath
511 | translate
512 | 0 0 m
513 | 0 4 l
514 | stroke
515 | grestore
516 | } bind def
517 | 295.2 43.2 o
518 | grestore
519 | gsave
520 | /o {
521 | gsave
522 | newpath
523 | translate
524 | 0 0 m
525 | 0 -4 l
526 | stroke
527 | grestore
528 | } bind def
529 | 295.2 388.8 o
530 | grestore
531 | gsave
532 | 290.879687 25.590625 translate
533 | 0.000000 rotate
534 | 0.000000 0.250000 m /three glyphshow
535 | grestore
536 | gsave
537 | /o {
538 | gsave
539 | newpath
540 | translate
541 | 0 0 m
542 | 0 4 l
543 | stroke
544 | grestore
545 | } bind def
546 | 369.6 43.2 o
547 | grestore
548 | gsave
549 | /o {
550 | gsave
551 | newpath
552 | translate
553 | 0 0 m
554 | 0 -4 l
555 | stroke
556 | grestore
557 | } bind def
558 | 369.6 388.8 o
559 | grestore
560 | gsave
561 | 364.818750 26.075000 translate
562 | 0.000000 rotate
563 | 0.000000 0.000000 m /four glyphshow
564 | grestore
565 | gsave
566 | /o {
567 | gsave
568 | newpath
569 | translate
570 | 0 0 m
571 | 0 4 l
572 | stroke
573 | grestore
574 | } bind def
575 | 444 43.2 o
576 | grestore
577 | gsave
578 | /o {
579 | gsave
580 | newpath
581 | translate
582 | 0 0 m
583 | 0 -4 l
584 | stroke
585 | grestore
586 | } bind def
587 | 444 388.8 o
588 | grestore
589 | gsave
590 | 439.757812 25.825000 translate
591 | 0.000000 rotate
592 | 0.000000 0.250000 m /five glyphshow
593 | grestore
594 | gsave
595 | /o {
596 | gsave
597 | newpath
598 | translate
599 | 0 0 m
600 | 0 4 l
601 | stroke
602 | grestore
603 | } bind def
604 | 518.4 43.2 o
605 | grestore
606 | gsave
607 | /o {
608 | gsave
609 | newpath
610 | translate
611 | 0 0 m
612 | 0 -4 l
613 | stroke
614 | grestore
615 | } bind def
616 | 518.4 388.8 o
617 | grestore
618 | gsave
619 | 513.876562 25.590625 translate
620 | 0.000000 rotate
621 | 0.000000 0.250000 m /six glyphshow
622 | grestore
623 | 290.427 10.747 m
624 | (x) show
625 | gsave
626 | /o {
627 | gsave
628 | newpath
629 | translate
630 | 0 0 m
631 | 4 0 l
632 | stroke
633 | grestore
634 | } bind def
635 | 72 43.2 o
636 | grestore
637 | gsave
638 | /o {
639 | gsave
640 | newpath
641 | translate
642 | 0 0 m
643 | -4 0 l
644 | stroke
645 | grestore
646 | } bind def
647 | 518.4 43.2 o
648 | grestore
649 | gsave
650 | 41.750000 36.395312 translate
651 | 0.000000 rotate
652 | 0.000000 0.250000 m /zero glyphshow
653 | 11.452148 0.250000 m /period glyphshow
654 | 17.173828 0.250000 m /zero glyphshow
655 | grestore
656 | gsave
657 | /o {
658 | gsave
659 | newpath
660 | translate
661 | 0 0 m
662 | 4 0 l
663 | stroke
664 | grestore
665 | } bind def
666 | 72 112.32 o
667 | grestore
668 | gsave
669 | /o {
670 | gsave
671 | newpath
672 | translate
673 | 0 0 m
674 | -4 0 l
675 | stroke
676 | grestore
677 | } bind def
678 | 518.4 112.32 o
679 | grestore
680 | gsave
681 | 42.359375 105.515312 translate
682 | 0.000000 rotate
683 | 0.000000 0.250000 m /zero glyphshow
684 | 11.452148 0.250000 m /period glyphshow
685 | 17.173828 0.250000 m /two glyphshow
686 | grestore
687 | gsave
688 | /o {
689 | gsave
690 | newpath
691 | translate
692 | 0 0 m
693 | 4 0 l
694 | stroke
695 | grestore
696 | } bind def
697 | 72 181.44 o
698 | grestore
699 | gsave
700 | /o {
701 | gsave
702 | newpath
703 | translate
704 | 0 0 m
705 | -4 0 l
706 | stroke
707 | grestore
708 | } bind def
709 | 518.4 181.44 o
710 | grestore
711 | gsave
712 | 41.578125 174.635312 translate
713 | 0.000000 rotate
714 | 0.000000 0.250000 m /zero glyphshow
715 | 11.452148 0.250000 m /period glyphshow
716 | 17.173828 0.250000 m /four glyphshow
717 | grestore
718 | gsave
719 | /o {
720 | gsave
721 | newpath
722 | translate
723 | 0 0 m
724 | 4 0 l
725 | stroke
726 | grestore
727 | } bind def
728 | 72 250.56 o
729 | grestore
730 | gsave
731 | /o {
732 | gsave
733 | newpath
734 | translate
735 | 0 0 m
736 | -4 0 l
737 | stroke
738 | grestore
739 | } bind def
740 | 518.4 250.56 o
741 | grestore
742 | gsave
743 | 41.703125 243.755313 translate
744 | 0.000000 rotate
745 | 0.000000 0.250000 m /zero glyphshow
746 | 11.452148 0.250000 m /period glyphshow
747 | 17.173828 0.250000 m /six glyphshow
748 | grestore
749 | gsave
750 | /o {
751 | gsave
752 | newpath
753 | translate
754 | 0 0 m
755 | 4 0 l
756 | stroke
757 | grestore
758 | } bind def
759 | 72 319.68 o
760 | grestore
761 | gsave
762 | /o {
763 | gsave
764 | newpath
765 | translate
766 | 0 0 m
767 | -4 0 l
768 | stroke
769 | grestore
770 | } bind def
771 | 518.4 319.68 o
772 | grestore
773 | gsave
774 | 41.796875 312.875313 translate
775 | 0.000000 rotate
776 | 0.000000 0.250000 m /zero glyphshow
777 | 11.452148 0.250000 m /period glyphshow
778 | 17.173828 0.250000 m /eight glyphshow
779 | grestore
780 | gsave
781 | /o {
782 | gsave
783 | newpath
784 | translate
785 | 0 0 m
786 | 4 0 l
787 | stroke
788 | grestore
789 | } bind def
790 | 72 388.8 o
791 | grestore
792 | gsave
793 | /o {
794 | gsave
795 | newpath
796 | translate
797 | 0 0 m
798 | -4 0 l
799 | stroke
800 | grestore
801 | } bind def
802 | 518.4 388.8 o
803 | grestore
804 | gsave
805 | 42.546875 381.995313 translate
806 | 0.000000 rotate
807 | 0.000000 0.250000 m /one glyphshow
808 | 11.452148 0.250000 m /period glyphshow
809 | 17.173828 0.250000 m /zero glyphshow
810 | grestore
811 | 36.578 186.531 m
812 | gsave
813 | 90 rotate
814 | 0 2.375 rmoveto
815 | (CDF\(x\)) show
816 | grestore
817 | 1.000 setlinewidth
818 | 2 setlinecap
819 | gsave
820 | 72 388.8 m
821 | 518.4 388.8 l
822 | stroke
823 | grestore
824 | gsave
825 | 518.4 43.2 m
826 | 518.4 388.8 l
827 | stroke
828 | grestore
829 | gsave
830 | 72 43.2 m
831 | 518.4 43.2 l
832 | stroke
833 | grestore
834 | gsave
835 | 72 43.2 m
836 | 72 388.8 l
837 | stroke
838 | grestore
839 | /DejaVuSans findfont
840 | 21.600 scalefont
841 | setfont
842 | 274.341 393.8 m
843 | 0 0.312 rmoveto
844 | (CDF) show
845 | 
846 | end
847 | showpage
848 | 


--------------------------------------------------------------------------------
/book/figs/example_cdf.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/example_cdf.pdf


--------------------------------------------------------------------------------
/book/figs/expo_cdf.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/expo_cdf.pdf


--------------------------------------------------------------------------------
/book/figs/interarrivals.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/interarrivals.pdf


--------------------------------------------------------------------------------
/book/figs/interarrivals_logy.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/interarrivals_logy.pdf


--------------------------------------------------------------------------------
/book/figs/noise-triple.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/noise-triple.pdf


--------------------------------------------------------------------------------
/book/figs/noise0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/noise0.pdf


--------------------------------------------------------------------------------
/book/figs/noise1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/noise1.pdf


--------------------------------------------------------------------------------
/book/figs/noise2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/noise2.pdf


--------------------------------------------------------------------------------
/book/figs/noise3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/noise3.pdf


--------------------------------------------------------------------------------
/book/figs/normal_cdf.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/normal_cdf.pdf


--------------------------------------------------------------------------------
/book/figs/nsfg_birthwgt_model.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/nsfg_birthwgt_model.pdf


--------------------------------------------------------------------------------
/book/figs/nsfg_birthwgt_normal.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/nsfg_birthwgt_normal.pdf


--------------------------------------------------------------------------------
/book/figs/pareto_cdf.eps:
--------------------------------------------------------------------------------
  1 | %!PS-Adobe-3.0 EPSF-3.0
  2 | %%Title: pareto_cdf.eps
  3 | %%Creator: matplotlib version 0.99.0, http://matplotlib.sourceforge.net/
  4 | %%CreationDate: Wed May  4 13:23:51 2011
  5 | %%Orientation: portrait
  6 | %%BoundingBox: 18 180 594 612
  7 | %%EndComments
  8 | %%BeginProlog
  9 | /mpldict 8 dict def
 10 | mpldict begin
 11 | /m { moveto } bind def
 12 | /l { lineto } bind def
 13 | /r { rlineto } bind def
 14 | /c { curveto } bind def
 15 | /cl { closepath } bind def
 16 | /box {
 17 | m
 18 | 1 index 0 r
 19 | 0 exch r
 20 | neg 0 r
 21 | cl
 22 | } bind def
 23 | /clipbox {
 24 | box
 25 | clip
 26 | newpath
 27 | } bind def
 28 | %!PS-Adobe-3.0 Resource-Font
 29 | %%Title: DejaVu Sans
 30 | %%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain 
 31 | %%Creator: Converted from TrueType by PPR
 32 | 25 dict begin
 33 | /_d{bind def}bind def
 34 | /_m{moveto}_d
 35 | /_l{lineto}_d
 36 | /_cl{closepath eofill}_d
 37 | /_c{curveto}_d
 38 | /_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d
 39 | /_e{exec}_d
 40 | /FontName /DejaVuSans def
 41 | /PaintType 0 def
 42 | /FontMatrix[.001 0 0 .001 0 0]def
 43 | /FontBBox[-1020 -349 1681 1167]def
 44 | /FontType 3 def
 45 | /Encoding StandardEncoding def
 46 | /FontInfo 10 dict dup begin
 47 | /FamilyName (DejaVu Sans) def
 48 | /FullName (DejaVu Sans) def
 49 | /Notice (Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. DejaVu changes are in public domain ) def
 50 | /Weight (Book) def
 51 | /Version (Version 2.29) def
 52 | /ItalicAngle 0.0 def
 53 | /isFixedPitch false def
 54 | /UnderlinePosition -130 def
 55 | /UnderlineThickness 90 def
 56 | end readonly def
 57 | /CharStrings 18 dict dup begin
 58 | /space{318 0 0 0 0 0 _sc
 59 | }_d
 60 | /period{318 0 107 0 210 124 _sc
 61 | 107 124 _m
 62 | 210 124 _l
 63 | 210 0 _l
 64 | 107 0 _l
 65 | 107 124 _l
 66 | _cl}_d
 67 | /zero{636 0 66 -13 570 742 _sc
 68 | 318 664 _m
 69 | 267 664 229 639 203 589 _c
 70 | 177 539 165 464 165 364 _c
 71 | 165 264 177 189 203 139 _c
 72 | 229 89 267 64 318 64 _c
 73 | 369 64 407 89 433 139 _c
 74 | 458 189 471 264 471 364 _c
 75 | 471 464 458 539 433 589 _c
 76 | 407 639 369 664 318 664 _c
 77 | 318 742 _m
 78 | 399 742 461 709 505 645 _c
 79 | 548 580 570 486 570 364 _c
 80 | 570 241 548 147 505 83 _c
 81 | 461 19 399 -13 318 -13 _c
 82 | 236 -13 173 19 130 83 _c
 83 | 87 147 66 241 66 364 _c
 84 | 66 486 87 580 130 645 _c
 85 | 173 709 236 742 318 742 _c
 86 | _cl}_d
 87 | /one{636 0 110 0 544 729 _sc
 88 | 124 83 _m
 89 | 285 83 _l
 90 | 285 639 _l
 91 | 110 604 _l
 92 | 110 694 _l
 93 | 284 729 _l
 94 | 383 729 _l
 95 | 383 83 _l
 96 | 544 83 _l
 97 | 544 0 _l
 98 | 124 0 _l
 99 | 124 83 _l
100 | _cl}_d
101 | /two{{636 0 73 0 536 742 _sc
102 | 192 83 _m
103 | 536 83 _l
104 | 536 0 _l
105 | 73 0 _l
106 | 73 83 _l
107 | 110 121 161 173 226 239 _c
108 | 290 304 331 346 348 365 _c
109 | 380 400 402 430 414 455 _c
110 | 426 479 433 504 433 528 _c
111 | 433 566 419 598 392 622 _c
112 | 365 646 330 659 286 659 _c
113 | 255 659 222 653 188 643 _c
114 | 154 632 117 616 78 594 _c
115 | 78 694 _l
116 | 118 710 155 722 189 730 _c
117 | 223 738 255 742 284 742 _c
118 | 359 742 419 723 464 685 _c
119 | 509 647 532 597 532 534 _c
120 | 532 504 526 475 515 449 _c
121 | 504 422 484 390 454 354 _c
122 | 446 344 420 317 376 272 _c
123 | 332 227 271 164 192 83 _c
124 | _cl}_e}_d
125 | /four{636 0 49 0 580 729 _sc
126 | 378 643 _m
127 | 129 254 _l
128 | 378 254 _l
129 | 378 643 _l
130 | 352 729 _m
131 | 476 729 _l
132 | 476 254 _l
133 | 580 254 _l
134 | 580 172 _l
135 | 476 172 _l
136 | 476 0 _l
137 | 378 0 _l
138 | 378 172 _l
139 | 49 172 _l
140 | 49 267 _l
141 | 352 729 _l
142 | _cl}_d
143 | /six{{636 0 70 -13 573 742 _sc
144 | 330 404 _m
145 | 286 404 251 388 225 358 _c
146 | 199 328 186 286 186 234 _c
147 | 186 181 199 139 225 109 _c
148 | 251 79 286 64 330 64 _c
149 | 374 64 409 79 435 109 _c
150 | 461 139 474 181 474 234 _c
151 | 474 286 461 328 435 358 _c
152 | 409 388 374 404 330 404 _c
153 | 526 713 _m
154 | 526 623 _l
155 | 501 635 476 644 451 650 _c
156 | 425 656 400 659 376 659 _c
157 | 310 659 260 637 226 593 _c
158 | 192 549 172 482 168 394 _c
159 | 187 422 211 444 240 459 _c
160 | 269 474 301 482 336 482 _c
161 | 409 482 467 459 509 415 _c
162 | 551 371 573 310 573 234 _c
163 | 573 159 550 99 506 54 _c
164 | 462 9 403 -13 330 -13 _c
165 | 246 -13 181 19 137 83 _c
166 | 92 147 70 241 70 364 _c
167 | 70 479 97 571 152 639 _c
168 | 206 707 280 742 372 742 _c
169 | }_e{396 742 421 739 447 735 _c
170 | 472 730 498 723 526 713 _c
171 | _cl}_e}_d
172 | /eight{{636 0 68 -13 568 742 _sc
173 | 318 346 _m
174 | 271 346 234 333 207 308 _c
175 | 180 283 167 249 167 205 _c
176 | 167 161 180 126 207 101 _c
177 | 234 76 271 64 318 64 _c
178 | 364 64 401 76 428 102 _c
179 | 455 127 469 161 469 205 _c
180 | 469 249 455 283 429 308 _c
181 | 402 333 365 346 318 346 _c
182 | 219 388 _m
183 | 177 398 144 418 120 447 _c
184 | 96 476 85 511 85 553 _c
185 | 85 611 105 657 147 691 _c
186 | 188 725 245 742 318 742 _c
187 | 390 742 447 725 489 691 _c
188 | 530 657 551 611 551 553 _c
189 | 551 511 539 476 515 447 _c
190 | 491 418 459 398 417 388 _c
191 | 464 377 501 355 528 323 _c
192 | 554 291 568 251 568 205 _c
193 | 568 134 546 80 503 43 _c
194 | 459 5 398 -13 318 -13 _c
195 | 237 -13 175 5 132 43 _c
196 | 89 80 68 134 68 205 _c
197 | 68 251 81 291 108 323 _c
198 | 134 355 171 377 219 388 _c
199 | }_e{183 544 _m
200 | 183 506 194 476 218 455 _c
201 | 242 434 275 424 318 424 _c
202 | 360 424 393 434 417 455 _c
203 | 441 476 453 506 453 544 _c
204 | 453 582 441 611 417 632 _c
205 | 393 653 360 664 318 664 _c
206 | 275 664 242 653 218 632 _c
207 | 194 611 183 582 183 544 _c
208 | _cl}_e}_d
209 | /C{{698 0 56 -13 644 742 _sc
210 | 644 673 _m
211 | 644 569 _l
212 | 610 599 575 622 537 638 _c
213 | 499 653 460 661 418 661 _c
214 | 334 661 270 635 226 584 _c
215 | 182 533 160 460 160 364 _c
216 | 160 268 182 194 226 143 _c
217 | 270 92 334 67 418 67 _c
218 | 460 67 499 74 537 90 _c
219 | 575 105 610 128 644 159 _c
220 | 644 56 _l
221 | 609 32 572 15 534 4 _c
222 | 496 -7 455 -13 412 -13 _c
223 | 302 -13 215 20 151 87 _c
224 | 87 154 56 246 56 364 _c
225 | 56 481 87 573 151 641 _c
226 | 215 708 302 742 412 742 _c
227 | 456 742 497 736 535 725 _c
228 | 573 713 610 696 644 673 _c
229 | _cl}_e}_d
230 | /D{770 0 98 0 711 729 _sc
231 | 197 648 _m
232 | 197 81 _l
233 | 316 81 _l
234 | 416 81 490 103 537 149 _c
235 | 583 195 607 267 607 365 _c
236 | 607 463 583 534 537 580 _c
237 | 490 625 416 648 316 648 _c
238 | 197 648 _l
239 | 98 729 _m
240 | 301 729 _l
241 | 442 729 546 699 612 641 _c
242 | 678 582 711 490 711 365 _c
243 | 711 239 677 147 611 88 _c
244 | 545 29 441 0 301 0 _c
245 | 98 0 _l
246 | 98 729 _l
247 | _cl}_d
248 | /F{575 0 98 0 517 729 _sc
249 | 98 729 _m
250 | 517 729 _l
251 | 517 646 _l
252 | 197 646 _l
253 | 197 431 _l
254 | 486 431 _l
255 | 486 348 _l
256 | 197 348 _l
257 | 197 0 _l
258 | 98 0 _l
259 | 98 729 _l
260 | _cl}_d
261 | /P{603 0 98 0 569 729 _sc
262 | 197 648 _m
263 | 197 374 _l
264 | 321 374 _l
265 | 367 374 402 385 427 409 _c
266 | 452 433 465 467 465 511 _c
267 | 465 555 452 588 427 612 _c
268 | 402 636 367 648 321 648 _c
269 | 197 648 _l
270 | 98 729 _m
271 | 321 729 _l
272 | 402 729 464 710 506 673 _c
273 | 548 636 569 582 569 511 _c
274 | 569 439 548 384 506 348 _c
275 | 464 311 402 293 321 293 _c
276 | 197 293 _l
277 | 197 0 _l
278 | 98 0 _l
279 | 98 729 _l
280 | _cl}_d
281 | /a{{613 0 60 -13 522 560 _sc
282 | 343 275 _m
283 | 270 275 220 266 192 250 _c
284 | 164 233 150 205 150 165 _c
285 | 150 133 160 107 181 89 _c
286 | 202 70 231 61 267 61 _c
287 | 317 61 357 78 387 114 _c
288 | 417 149 432 196 432 255 _c
289 | 432 275 _l
290 | 343 275 _l
291 | 522 312 _m
292 | 522 0 _l
293 | 432 0 _l
294 | 432 83 _l
295 | 411 49 385 25 355 10 _c
296 | 325 -5 287 -13 243 -13 _c
297 | 187 -13 142 2 109 33 _c
298 | 76 64 60 106 60 159 _c
299 | 60 220 80 266 122 298 _c
300 | 163 329 224 345 306 345 _c
301 | 432 345 _l
302 | 432 354 _l
303 | 432 395 418 427 391 450 _c
304 | 364 472 326 484 277 484 _c
305 | 245 484 215 480 185 472 _c
306 | 155 464 127 453 100 439 _c
307 | 100 522 _l
308 | }_e{132 534 164 544 195 550 _c
309 | 226 556 256 560 286 560 _c
310 | 365 560 424 539 463 498 _c
311 | 502 457 522 395 522 312 _c
312 | _cl}_e}_d
313 | /e{{615 0 55 -13 562 560 _sc
314 | 562 296 _m
315 | 562 252 _l
316 | 149 252 _l
317 | 153 190 171 142 205 110 _c
318 | 238 78 284 62 344 62 _c
319 | 378 62 412 66 444 74 _c
320 | 476 82 509 95 541 113 _c
321 | 541 28 _l
322 | 509 14 476 3 442 -3 _c
323 | 408 -9 373 -13 339 -13 _c
324 | 251 -13 182 12 131 62 _c
325 | 80 112 55 181 55 268 _c
326 | 55 357 79 428 127 481 _c
327 | 175 533 241 560 323 560 _c
328 | 397 560 455 536 498 489 _c
329 | 540 441 562 377 562 296 _c
330 | 472 322 _m
331 | 471 371 457 410 431 440 _c
332 | 404 469 368 484 324 484 _c
333 | 274 484 234 469 204 441 _c
334 | 174 413 156 373 152 322 _c
335 | 472 322 _l
336 | _cl}_e}_d
337 | /o{612 0 55 -13 557 560 _sc
338 | 306 484 _m
339 | 258 484 220 465 192 427 _c
340 | 164 389 150 338 150 273 _c
341 | 150 207 163 156 191 118 _c
342 | 219 80 257 62 306 62 _c
343 | 354 62 392 80 420 118 _c
344 | 448 156 462 207 462 273 _c
345 | 462 337 448 389 420 427 _c
346 | 392 465 354 484 306 484 _c
347 | 306 560 _m
348 | 384 560 445 534 490 484 _c
349 | 534 433 557 363 557 273 _c
350 | 557 183 534 113 490 63 _c
351 | 445 12 384 -13 306 -13 _c
352 | 227 -13 165 12 121 63 _c
353 | 77 113 55 183 55 273 _c
354 | 55 363 77 433 121 484 _c
355 | 165 534 227 560 306 560 _c
356 | _cl}_d
357 | /r{411 0 91 0 411 560 _sc
358 | 411 463 _m
359 | 401 469 390 473 378 476 _c
360 | 366 478 353 480 339 480 _c
361 | 288 480 249 463 222 430 _c
362 | 194 397 181 350 181 288 _c
363 | 181 0 _l
364 | 91 0 _l
365 | 91 547 _l
366 | 181 547 _l
367 | 181 462 _l
368 | 199 495 224 520 254 536 _c
369 | 284 552 321 560 365 560 _c
370 | 371 560 378 559 386 559 _c
371 | 393 558 401 557 411 555 _c
372 | 411 463 _l
373 | _cl}_d
374 | /t{392 0 27 0 368 702 _sc
375 | 183 702 _m
376 | 183 547 _l
377 | 368 547 _l
378 | 368 477 _l
379 | 183 477 _l
380 | 183 180 _l
381 | 183 135 189 106 201 94 _c
382 | 213 81 238 75 276 75 _c
383 | 368 75 _l
384 | 368 0 _l
385 | 276 0 _l
386 | 206 0 158 13 132 39 _c
387 | 106 65 93 112 93 180 _c
388 | 93 477 _l
389 | 27 477 _l
390 | 27 547 _l
391 | 93 547 _l
392 | 93 702 _l
393 | 183 702 _l
394 | _cl}_d
395 | /x{592 0 29 0 559 547 _sc
396 | 549 547 _m
397 | 351 281 _l
398 | 559 0 _l
399 | 453 0 _l
400 | 294 215 _l
401 | 135 0 _l
402 | 29 0 _l
403 | 241 286 _l
404 | 47 547 _l
405 | 153 547 _l
406 | 298 352 _l
407 | 443 547 _l
408 | 549 547 _l
409 | _cl}_d
410 | end readonly def
411 | 
412 | /BuildGlyph
413 |  {exch begin
414 |  CharStrings exch
415 |  2 copy known not{pop /.notdef}if
416 |  true 3 1 roll get exec
417 |  end}_d
418 | 
419 | /BuildChar {
420 |  1 index /Encoding get exch get
421 |  1 index /BuildGlyph get exec
422 | }_d
423 | 
424 | FontName currentdict end definefont pop
425 | end
426 | %%EndProlog
427 | mpldict begin
428 | 18 180 translate
429 | 576 432 0 0 clipbox
430 | 1.000 setlinewidth
431 | 1 setlinejoin
432 | 2 setlinecap
433 | [] 0 setdash
434 | 1.000 setgray
435 | gsave
436 | 0 0 m
437 | 576 0 l
438 | 576 432 l
439 | 0 432 l
440 | 0 0 l
441 | gsave
442 | fill
443 | grestore
444 | stroke
445 | grestore
446 | gsave
447 | 72 43.2 m
448 | 518.4 43.2 l
449 | 518.4 388.8 l
450 | 72 388.8 l
451 | 72 43.2 l
452 | fill
453 | grestore
454 | 0.000 0.000 1.000 setrgbcolor
455 | gsave
456 | 446.4 345.6 72 43.2 clipbox
457 | 72 43.2 m
458 | 80.928 43.2 l
459 | 89.856 43.2 l
460 | 98.784 100.8 l
461 | 107.712 172.8 l
462 | 116.64 216 l
463 | 125.568 244.8 l
464 | 134.496 265.371 l
465 | 143.424 280.8 l
466 | 152.352 292.8 l
467 | 161.28 302.4 l
468 | 170.208 310.255 l
469 | 179.136 316.8 l
470 | 188.064 322.338 l
471 | 196.992 327.086 l
472 | 205.92 331.2 l
473 | 214.848 334.8 l
474 | 223.776 337.976 l
475 | 232.704 340.8 l
476 | 241.632 343.326 l
477 | 250.56 345.6 l
478 | 259.488 347.657 l
479 | 268.416 349.527 l
480 | 277.344 351.235 l
481 | 286.272 352.8 l
482 | 295.2 354.24 l
483 | 304.128 355.569 l
484 | 313.056 356.8 l
485 | 321.984 357.943 l
486 | 330.912 359.007 l
487 | 339.84 360 l
488 | 348.768 360.929 l
489 | 357.696 361.8 l
490 | 366.624 362.618 l
491 | 375.552 363.388 l
492 | 384.48 364.114 l
493 | 393.408 364.8 l
494 | 402.336 365.449 l
495 | 411.264 366.063 l
496 | 420.192 366.646 l
497 | 429.12 367.2 l
498 | 438.048 367.727 l
499 | 446.976 368.229 l
500 | 455.904 368.707 l
501 | 464.832 369.164 l
502 | 473.76 369.6 l
503 | 482.688 370.017 l
504 | 491.616 370.417 l
505 | 500.544 370.8 l
506 | 509.472 371.167 l
507 | stroke
508 | grestore
509 | 0.500 setlinewidth
510 | 0 setlinecap
511 | 0.000 setgray
512 | gsave
513 | /o {
514 | gsave
515 | newpath
516 | translate
517 | 0 0 m
518 | 0 4 l
519 | stroke
520 | grestore
521 | } bind def
522 | 72 43.2 o
523 | grestore
524 | gsave
525 | /o {
526 | gsave
527 | newpath
528 | translate
529 | 0 0 m
530 | 0 -4 l
531 | stroke
532 | grestore
533 | } bind def
534 | 72 388.8 o
535 | grestore
536 | /DejaVuSans findfont
537 | 18.000 scalefont
538 | setfont
539 | gsave
540 | 67.460938 25.590625 translate
541 | 0.000000 rotate
542 | 0.000000 0.250000 m /zero glyphshow
543 | grestore
544 | gsave
545 | /o {
546 | gsave
547 | newpath
548 | translate
549 | 0 0 m
550 | 0 4 l
551 | stroke
552 | grestore
553 | } bind def
554 | 161.28 43.2 o
555 | grestore
556 | gsave
557 | /o {
558 | gsave
559 | newpath
560 | translate
561 | 0 0 m
562 | 0 -4 l
563 | stroke
564 | grestore
565 | } bind def
566 | 161.28 388.8 o
567 | grestore
568 | gsave
569 | 157.108125 25.840625 translate
570 | 0.000000 rotate
571 | 0.000000 0.000000 m /two glyphshow
572 | grestore
573 | gsave
574 | /o {
575 | gsave
576 | newpath
577 | translate
578 | 0 0 m
579 | 0 4 l
580 | stroke
581 | grestore
582 | } bind def
583 | 250.56 43.2 o
584 | grestore
585 | gsave
586 | /o {
587 | gsave
588 | newpath
589 | translate
590 | 0 0 m
591 | 0 -4 l
592 | stroke
593 | grestore
594 | } bind def
595 | 250.56 388.8 o
596 | grestore
597 | gsave
598 | 245.778750 26.075000 translate
599 | 0.000000 rotate
600 | 0.000000 0.000000 m /four glyphshow
601 | grestore
602 | gsave
603 | /o {
604 | gsave
605 | newpath
606 | translate
607 | 0 0 m
608 | 0 4 l
609 | stroke
610 | grestore
611 | } bind def
612 | 339.84 43.2 o
613 | grestore
614 | gsave
615 | /o {
616 | gsave
617 | newpath
618 | translate
619 | 0 0 m
620 | 0 -4 l
621 | stroke
622 | grestore
623 | } bind def
624 | 339.84 388.8 o
625 | grestore
626 | gsave
627 | 335.316563 25.590625 translate
628 | 0.000000 rotate
629 | 0.000000 0.250000 m /six glyphshow
630 | grestore
631 | gsave
632 | /o {
633 | gsave
634 | newpath
635 | translate
636 | 0 0 m
637 | 0 4 l
638 | stroke
639 | grestore
640 | } bind def
641 | 429.12 43.2 o
642 | grestore
643 | gsave
644 | /o {
645 | gsave
646 | newpath
647 | translate
648 | 0 0 m
649 | 0 -4 l
650 | stroke
651 | grestore
652 | } bind def
653 | 429.12 388.8 o
654 | grestore
655 | gsave
656 | 424.620000 25.590625 translate
657 | 0.000000 rotate
658 | 0.000000 0.250000 m /eight glyphshow
659 | grestore
660 | gsave
661 | /o {
662 | gsave
663 | newpath
664 | translate
665 | 0 0 m
666 | 0 4 l
667 | stroke
668 | grestore
669 | } bind def
670 | 518.4 43.2 o
671 | grestore
672 | gsave
673 | /o {
674 | gsave
675 | newpath
676 | translate
677 | 0 0 m
678 | 0 -4 l
679 | stroke
680 | grestore
681 | } bind def
682 | 518.4 388.8 o
683 | grestore
684 | gsave
685 | 508.532812 25.590625 translate
686 | 0.000000 rotate
687 | 0.000000 0.250000 m /one glyphshow
688 | 11.452148 0.250000 m /zero glyphshow
689 | grestore
690 | 290.427 10.747 m
691 | (x) show
692 | gsave
693 | /o {
694 | gsave
695 | newpath
696 | translate
697 | 0 0 m
698 | 4 0 l
699 | stroke
700 | grestore
701 | } bind def
702 | 72 43.2 o
703 | grestore
704 | gsave
705 | /o {
706 | gsave
707 | newpath
708 | translate
709 | 0 0 m
710 | -4 0 l
711 | stroke
712 | grestore
713 | } bind def
714 | 518.4 43.2 o
715 | grestore
716 | gsave
717 | 41.750000 36.395312 translate
718 | 0.000000 rotate
719 | 0.000000 0.250000 m /zero glyphshow
720 | 11.452148 0.250000 m /period glyphshow
721 | 17.173828 0.250000 m /zero glyphshow
722 | grestore
723 | gsave
724 | /o {
725 | gsave
726 | newpath
727 | translate
728 | 0 0 m
729 | 4 0 l
730 | stroke
731 | grestore
732 | } bind def
733 | 72 112.32 o
734 | grestore
735 | gsave
736 | /o {
737 | gsave
738 | newpath
739 | translate
740 | 0 0 m
741 | -4 0 l
742 | stroke
743 | grestore
744 | } bind def
745 | 518.4 112.32 o
746 | grestore
747 | gsave
748 | 42.359375 105.515312 translate
749 | 0.000000 rotate
750 | 0.000000 0.250000 m /zero glyphshow
751 | 11.452148 0.250000 m /period glyphshow
752 | 17.173828 0.250000 m /two glyphshow
753 | grestore
754 | gsave
755 | /o {
756 | gsave
757 | newpath
758 | translate
759 | 0 0 m
760 | 4 0 l
761 | stroke
762 | grestore
763 | } bind def
764 | 72 181.44 o
765 | grestore
766 | gsave
767 | /o {
768 | gsave
769 | newpath
770 | translate
771 | 0 0 m
772 | -4 0 l
773 | stroke
774 | grestore
775 | } bind def
776 | 518.4 181.44 o
777 | grestore
778 | gsave
779 | 41.578125 174.635312 translate
780 | 0.000000 rotate
781 | 0.000000 0.250000 m /zero glyphshow
782 | 11.452148 0.250000 m /period glyphshow
783 | 17.173828 0.250000 m /four glyphshow
784 | grestore
785 | gsave
786 | /o {
787 | gsave
788 | newpath
789 | translate
790 | 0 0 m
791 | 4 0 l
792 | stroke
793 | grestore
794 | } bind def
795 | 72 250.56 o
796 | grestore
797 | gsave
798 | /o {
799 | gsave
800 | newpath
801 | translate
802 | 0 0 m
803 | -4 0 l
804 | stroke
805 | grestore
806 | } bind def
807 | 518.4 250.56 o
808 | grestore
809 | gsave
810 | 41.703125 243.755313 translate
811 | 0.000000 rotate
812 | 0.000000 0.250000 m /zero glyphshow
813 | 11.452148 0.250000 m /period glyphshow
814 | 17.173828 0.250000 m /six glyphshow
815 | grestore
816 | gsave
817 | /o {
818 | gsave
819 | newpath
820 | translate
821 | 0 0 m
822 | 4 0 l
823 | stroke
824 | grestore
825 | } bind def
826 | 72 319.68 o
827 | grestore
828 | gsave
829 | /o {
830 | gsave
831 | newpath
832 | translate
833 | 0 0 m
834 | -4 0 l
835 | stroke
836 | grestore
837 | } bind def
838 | 518.4 319.68 o
839 | grestore
840 | gsave
841 | 41.796875 312.875313 translate
842 | 0.000000 rotate
843 | 0.000000 0.250000 m /zero glyphshow
844 | 11.452148 0.250000 m /period glyphshow
845 | 17.173828 0.250000 m /eight glyphshow
846 | grestore
847 | gsave
848 | /o {
849 | gsave
850 | newpath
851 | translate
852 | 0 0 m
853 | 4 0 l
854 | stroke
855 | grestore
856 | } bind def
857 | 72 388.8 o
858 | grestore
859 | gsave
860 | /o {
861 | gsave
862 | newpath
863 | translate
864 | 0 0 m
865 | -4 0 l
866 | stroke
867 | grestore
868 | } bind def
869 | 518.4 388.8 o
870 | grestore
871 | gsave
872 | 42.546875 381.995313 translate
873 | 0.000000 rotate
874 | 0.000000 0.250000 m /one glyphshow
875 | 11.452148 0.250000 m /period glyphshow
876 | 17.173828 0.250000 m /zero glyphshow
877 | grestore
878 | 36.578 198.641 m
879 | gsave
880 | 90 rotate
881 | 0 0.25 rmoveto
882 | (CDF) show
883 | grestore
884 | 1.000 setlinewidth
885 | 2 setlinecap
886 | gsave
887 | 72 388.8 m
888 | 518.4 388.8 l
889 | stroke
890 | grestore
891 | gsave
892 | 518.4 43.2 m
893 | 518.4 388.8 l
894 | stroke
895 | grestore
896 | gsave
897 | 72 43.2 m
898 | 518.4 43.2 l
899 | stroke
900 | grestore
901 | gsave
902 | 72 43.2 m
903 | 72 388.8 l
904 | stroke
905 | grestore
906 | /DejaVuSans findfont
907 | 21.600 scalefont
908 | setfont
909 | 235.934 393.8 m
910 | 0 0.312 rmoveto
911 | (Pareto CDF) show
912 | 
913 | end
914 | showpage
915 | 


--------------------------------------------------------------------------------
/book/figs/pareto_cdf.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/pareto_cdf.pdf


--------------------------------------------------------------------------------
/book/figs/pinknoise0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/pinknoise0.pdf


--------------------------------------------------------------------------------
/book/figs/pinknoise1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/pinknoise1.pdf


--------------------------------------------------------------------------------
/book/figs/pinknoise2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/pinknoise2.pdf


--------------------------------------------------------------------------------
/book/figs/pinknoise3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/pinknoise3.pdf


--------------------------------------------------------------------------------
/book/figs/pinknoise4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/pinknoise4.pdf


--------------------------------------------------------------------------------
/book/figs/pinknoise5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/pinknoise5.pdf


--------------------------------------------------------------------------------
/book/figs/rednoise0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/rednoise0.pdf


--------------------------------------------------------------------------------
/book/figs/rednoise1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/rednoise1.pdf


--------------------------------------------------------------------------------
/book/figs/rednoise2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/rednoise2.pdf


--------------------------------------------------------------------------------
/book/figs/rednoise3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/rednoise3.pdf


--------------------------------------------------------------------------------
/book/figs/rednoise4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/rednoise4.pdf


--------------------------------------------------------------------------------
/book/figs/rednoise5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/rednoise5.pdf


--------------------------------------------------------------------------------
/book/figs/sampling1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling1.pdf


--------------------------------------------------------------------------------
/book/figs/sampling2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling2.pdf


--------------------------------------------------------------------------------
/book/figs/sampling3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling3.pdf


--------------------------------------------------------------------------------
/book/figs/sampling4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling4.pdf


--------------------------------------------------------------------------------
/book/figs/sampling5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling5.pdf


--------------------------------------------------------------------------------
/book/figs/sampling6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling6.pdf


--------------------------------------------------------------------------------
/book/figs/sampling7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling7.pdf


--------------------------------------------------------------------------------
/book/figs/sampling8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling8.pdf


--------------------------------------------------------------------------------
/book/figs/sampling9.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sampling9.pdf


--------------------------------------------------------------------------------
/book/figs/sinusoid1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sinusoid1.pdf


--------------------------------------------------------------------------------
/book/figs/sounds1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sounds1.pdf


--------------------------------------------------------------------------------
/book/figs/sounds2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sounds2.pdf


--------------------------------------------------------------------------------
/book/figs/sounds3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sounds3.pdf


--------------------------------------------------------------------------------
/book/figs/sounds4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/sounds4.pdf


--------------------------------------------------------------------------------
/book/figs/square-100-1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/square-100-1.pdf


--------------------------------------------------------------------------------
/book/figs/square-100-2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/square-100-2.pdf


--------------------------------------------------------------------------------
/book/figs/systems1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems1.pdf


--------------------------------------------------------------------------------
/book/figs/systems2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems2.pdf


--------------------------------------------------------------------------------
/book/figs/systems3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems3.pdf


--------------------------------------------------------------------------------
/book/figs/systems4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems4.pdf


--------------------------------------------------------------------------------
/book/figs/systems5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems5.pdf


--------------------------------------------------------------------------------
/book/figs/systems6.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems6.pdf


--------------------------------------------------------------------------------
/book/figs/systems7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems7.pdf


--------------------------------------------------------------------------------
/book/figs/systems8.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/systems8.pdf


--------------------------------------------------------------------------------
/book/figs/triangle-1100-1.eps:
--------------------------------------------------------------------------------
  1 | %!PS-Adobe-3.0 EPSF-3.0
  2 | %%Title: triangle-1100-1.eps
  3 | %%Creator: matplotlib version 1.5.1, http://matplotlib.org/
  4 | %%CreationDate: Thu May  5 10:23:44 2016
  5 | %%Orientation: portrait
  6 | %%BoundingBox: 18 180 594 612
  7 | %%EndComments
  8 | %%BeginProlog
  9 | /mpldict 8 dict def
 10 | mpldict begin
 11 | /m { moveto } bind def
 12 | /l { lineto } bind def
 13 | /r { rlineto } bind def
 14 | /c { curveto } bind def
 15 | /cl { closepath } bind def
 16 | /box {
 17 | m
 18 | 1 index 0 r
 19 | 0 exch r
 20 | neg 0 r
 21 | cl
 22 | } bind def
 23 | /clipbox {
 24 | box
 25 | clip
 26 | newpath
 27 | } bind def
 28 | %!PS-Adobe-3.0 Resource-Font
 29 | %%Title: Bitstream Vera Sans
 30 | %%Copyright: Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.
 31 | %%Creator: Converted from TrueType to type 3 by PPR
 32 | 25 dict begin
 33 | /_d{bind def}bind def
 34 | /_m{moveto}_d
 35 | /_l{lineto}_d
 36 | /_cl{closepath eofill}_d
 37 | /_c{curveto}_d
 38 | /_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d
 39 | /_e{exec}_d
 40 | /FontName /BitstreamVeraSans-Roman def
 41 | /PaintType 0 def
 42 | /FontMatrix[.001 0 0 .001 0 0]def
 43 | /FontBBox[-183 -236 1287 928]def
 44 | /FontType 3 def
 45 | /Encoding [ /space /parenleft /parenright /period /zero /one /two /five /T /e /i /m /s /minus ] def
 46 | /FontInfo 10 dict dup begin
 47 | /FamilyName (Bitstream Vera Sans) def
 48 | /FullName (Bitstream Vera Sans) def
 49 | /Notice (Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a trademark of Bitstream, Inc.) def
 50 | /Weight (Roman) def
 51 | /Version (Release 1.10) def
 52 | /ItalicAngle 0.0 def
 53 | /isFixedPitch false def
 54 | /UnderlinePosition -213 def
 55 | /UnderlineThickness 143 def
 56 | end readonly def
 57 | /CharStrings 14 dict dup begin
 58 | /space{318 0 0 0 0 0 _sc
 59 | }_d
 60 | /parenleft{390 0 86 -131 310 759 _sc
 61 | 310 759 _m
 62 | 266 683 234 609 213 536 _c
 63 | 191 463 181 389 181 314 _c
 64 | 181 238 191 164 213 91 _c
 65 | 234 17 266 -56 310 -131 _c
 66 | 232 -131 _l
 67 | 183 -54 146 20 122 94 _c
 68 | 98 168 86 241 86 314 _c
 69 | 86 386 98 459 122 533 _c
 70 | 146 607 182 682 232 759 _c
 71 | 310 759 _l
 72 | _cl}_d
 73 | /parenright{390 0 80 -131 304 759 _sc
 74 | 80 759 _m
 75 | 158 759 _l
 76 | 206 682 243 607 267 533 _c
 77 | 291 459 304 386 304 314 _c
 78 | 304 241 291 168 267 94 _c
 79 | 243 20 206 -54 158 -131 _c
 80 | 80 -131 _l
 81 | 123 -56 155 17 177 91 _c
 82 | 198 164 209 238 209 314 _c
 83 | 209 389 198 463 177 536 _c
 84 | 155 609 123 683 80 759 _c
 85 | _cl}_d
 86 | /period{318 0 107 0 210 124 _sc
 87 | 107 124 _m
 88 | 210 124 _l
 89 | 210 0 _l
 90 | 107 0 _l
 91 | 107 124 _l
 92 | _cl}_d
 93 | /zero{636 0 66 -13 570 742 _sc
 94 | 318 664 _m
 95 | 267 664 229 639 203 589 _c
 96 | 177 539 165 464 165 364 _c
 97 | 165 264 177 189 203 139 _c
 98 | 229 89 267 64 318 64 _c
 99 | 369 64 407 89 433 139 _c
100 | 458 189 471 264 471 364 _c
101 | 471 464 458 539 433 589 _c
102 | 407 639 369 664 318 664 _c
103 | 318 742 _m
104 | 399 742 461 709 505 645 _c
105 | 548 580 570 486 570 364 _c
106 | 570 241 548 147 505 83 _c
107 | 461 19 399 -13 318 -13 _c
108 | 236 -13 173 19 130 83 _c
109 | 87 147 66 241 66 364 _c
110 | 66 486 87 580 130 645 _c
111 | 173 709 236 742 318 742 _c
112 | _cl}_d
113 | /one{636 0 110 0 544 729 _sc
114 | 124 83 _m
115 | 285 83 _l
116 | 285 639 _l
117 | 110 604 _l
118 | 110 694 _l
119 | 284 729 _l
120 | 383 729 _l
121 | 383 83 _l
122 | 544 83 _l
123 | 544 0 _l
124 | 124 0 _l
125 | 124 83 _l
126 | _cl}_d
127 | /two{{636 0 73 0 536 742 _sc
128 | 192 83 _m
129 | 536 83 _l
130 | 536 0 _l
131 | 73 0 _l
132 | 73 83 _l
133 | 110 121 161 173 226 239 _c
134 | 290 304 331 346 348 365 _c
135 | 380 400 402 430 414 455 _c
136 | 426 479 433 504 433 528 _c
137 | 433 566 419 598 392 622 _c
138 | 365 646 330 659 286 659 _c
139 | 255 659 222 653 188 643 _c
140 | 154 632 117 616 78 594 _c
141 | 78 694 _l
142 | 118 710 155 722 189 730 _c
143 | 223 738 255 742 284 742 _c
144 | }_e{359 742 419 723 464 685 _c
145 | 509 647 532 597 532 534 _c
146 | 532 504 526 475 515 449 _c
147 | 504 422 484 390 454 354 _c
148 | 446 344 420 317 376 272 _c
149 | 332 227 271 164 192 83 _c
150 | _cl}_e}_d
151 | /five{{636 0 77 -13 549 729 _sc
152 | 108 729 _m
153 | 495 729 _l
154 | 495 646 _l
155 | 198 646 _l
156 | 198 467 _l
157 | 212 472 227 476 241 478 _c
158 | 255 480 270 482 284 482 _c
159 | 365 482 429 459 477 415 _c
160 | 525 370 549 310 549 234 _c
161 | 549 155 524 94 475 51 _c
162 | 426 8 357 -13 269 -13 _c
163 | 238 -13 207 -10 175 -6 _c
164 | 143 -1 111 6 77 17 _c
165 | 77 116 _l
166 | 106 100 136 88 168 80 _c
167 | 199 72 232 69 267 69 _c
168 | }_e{323 69 368 83 401 113 _c
169 | 433 143 450 183 450 234 _c
170 | 450 284 433 324 401 354 _c
171 | 368 384 323 399 267 399 _c
172 | 241 399 214 396 188 390 _c
173 | 162 384 135 375 108 363 _c
174 | 108 729 _l
175 | _cl}_e}_d
176 | /T{611 0 -2 0 614 729 _sc
177 | -2 729 _m
178 | 614 729 _l
179 | 614 646 _l
180 | 355 646 _l
181 | 355 0 _l
182 | 256 0 _l
183 | 256 646 _l
184 | -2 646 _l
185 | -2 729 _l
186 | _cl}_d
187 | /e{{615 0 55 -13 562 560 _sc
188 | 562 296 _m
189 | 562 252 _l
190 | 149 252 _l
191 | 153 190 171 142 205 110 _c
192 | 238 78 284 62 344 62 _c
193 | 378 62 412 66 444 74 _c
194 | 476 82 509 95 541 113 _c
195 | 541 28 _l
196 | 509 14 476 3 442 -3 _c
197 | 408 -9 373 -13 339 -13 _c
198 | 251 -13 182 12 131 62 _c
199 | 80 112 55 181 55 268 _c
200 | 55 357 79 428 127 481 _c
201 | 175 533 241 560 323 560 _c
202 | 397 560 455 536 498 489 _c
203 | }_e{540 441 562 377 562 296 _c
204 | 472 322 _m
205 | 471 371 457 410 431 440 _c
206 | 404 469 368 484 324 484 _c
207 | 274 484 234 469 204 441 _c
208 | 174 413 156 373 152 322 _c
209 | 472 322 _l
210 | _cl}_e}_d
211 | /i{278 0 94 0 184 760 _sc
212 | 94 547 _m
213 | 184 547 _l
214 | 184 0 _l
215 | 94 0 _l
216 | 94 547 _l
217 | 94 760 _m
218 | 184 760 _l
219 | 184 646 _l
220 | 94 646 _l
221 | 94 760 _l
222 | _cl}_d
223 | /m{{974 0 91 0 889 560 _sc
224 | 520 442 _m
225 | 542 482 569 511 600 531 _c
226 | 631 550 668 560 711 560 _c
227 | 767 560 811 540 842 500 _c
228 | 873 460 889 403 889 330 _c
229 | 889 0 _l
230 | 799 0 _l
231 | 799 327 _l
232 | 799 379 789 418 771 444 _c
233 | 752 469 724 482 686 482 _c
234 | 639 482 602 466 575 435 _c
235 | 548 404 535 362 535 309 _c
236 | 535 0 _l
237 | 445 0 _l
238 | 445 327 _l
239 | 445 379 435 418 417 444 _c
240 | 398 469 369 482 331 482 _c
241 | }_e{285 482 248 466 221 435 _c
242 | 194 404 181 362 181 309 _c
243 | 181 0 _l
244 | 91 0 _l
245 | 91 547 _l
246 | 181 547 _l
247 | 181 462 _l
248 | 201 495 226 520 255 536 _c
249 | 283 552 317 560 357 560 _c
250 | 397 560 430 550 458 530 _c
251 | 486 510 506 480 520 442 _c
252 | _cl}_e}_d
253 | /s{{521 0 54 -13 472 560 _sc
254 | 443 531 _m
255 | 443 446 _l
256 | 417 458 391 468 364 475 _c
257 | 336 481 308 485 279 485 _c
258 | 234 485 200 478 178 464 _c
259 | 156 450 145 430 145 403 _c
260 | 145 382 153 366 169 354 _c
261 | 185 342 217 330 265 320 _c
262 | 296 313 _l
263 | 360 299 405 279 432 255 _c
264 | 458 230 472 195 472 151 _c
265 | 472 100 452 60 412 31 _c
266 | 372 1 316 -13 246 -13 _c
267 | 216 -13 186 -10 154 -5 _c
268 | }_e{122 0 89 8 54 20 _c
269 | 54 113 _l
270 | 87 95 120 82 152 74 _c
271 | 184 65 216 61 248 61 _c
272 | 290 61 323 68 346 82 _c
273 | 368 96 380 117 380 144 _c
274 | 380 168 371 187 355 200 _c
275 | 339 213 303 226 247 238 _c
276 | 216 245 _l
277 | 160 257 119 275 95 299 _c
278 | 70 323 58 356 58 399 _c
279 | 58 450 76 490 112 518 _c
280 | 148 546 200 560 268 560 _c
281 | 301 560 332 557 362 552 _c
282 | 391 547 418 540 443 531 _c
283 | }_e{_cl}_e}_d
284 | /minus{838 0 106 272 732 355 _sc
285 | 106 355 _m
286 | 732 355 _l
287 | 732 272 _l
288 | 106 272 _l
289 | 106 355 _l
290 | _cl}_d
291 | end readonly def
292 | 
293 | /BuildGlyph
294 |  {exch begin
295 |  CharStrings exch
296 |  2 copy known not{pop /.notdef}if
297 |  true 3 1 roll get exec
298 |  end}_d
299 | 
300 | /BuildChar {
301 |  1 index /Encoding get exch get
302 |  1 index /BuildGlyph get exec
303 | }_d
304 | 
305 | FontName currentdict end definefont pop
306 | end
307 | %%EndProlog
308 | mpldict begin
309 | 18 180 translate
310 | 576 432 0 0 clipbox
311 | 100000 setmiterlimit
312 | gsave
313 | 0 0 m
314 | 576 0 l
315 | 576 432 l
316 | 0 432 l
317 | cl
318 | 1.000 setgray
319 | fill
320 | grestore
321 | gsave
322 | 72 43.2 m
323 | 518.4 43.2 l
324 | 518.4 388.8 l
325 | 72 388.8 l
326 | cl
327 | 1.000 setgray
328 | fill
329 | grestore
330 | 3.000 setlinewidth
331 | 1 setlinejoin
332 | 2 setlinecap
333 | [] 0 setdash
334 | 0.031 0.188 0.420 setrgbcolor
335 | gsave
336 | 446.4 345.6 72 43.2 clipbox
337 | 72 380.571429 m
338 | 88.368 308.16 l
339 | 104.736 235.748571 l
340 | 121.104 163.337143 l
341 | 137.472 90.925714 l
342 | 153.84 84.342857 l
343 | 170.208 156.754286 l
344 | 186.576 229.165714 l
345 | 202.944 301.577143 l
346 | 219.312 373.988571 l
347 | 235.68 314.742857 l
348 | 252.048 242.331429 l
349 | 268.416 169.92 l
350 | 284.784 97.508571 l
351 | 301.152 77.76 l
352 | 317.52 150.171429 l
353 | 333.888 222.582857 l
354 | 350.256 294.994286 l
355 | 366.624 367.405714 l
356 | 382.992 321.325714 l
357 | 399.36 248.914286 l
358 | 415.728 176.502857 l
359 | 432.096 104.091429 l
360 | 448.464 71.177143 l
361 | 464.832 143.588571 l
362 | 481.2 216 l
363 | 497.568 288.411429 l
364 | stroke
365 | grestore
366 | 1.000 setlinewidth
367 | 0 setlinejoin
368 | 0.000 setgray
369 | gsave
370 | 72 388.8 m
371 | 518.4 388.8 l
372 | stroke
373 | grestore
374 | gsave
375 | 72 43.2 m
376 | 518.4 43.2 l
377 | stroke
378 | grestore
379 | gsave
380 | 72 43.2 m
381 | 72 388.8 l
382 | stroke
383 | grestore
384 | gsave
385 | 518.4 43.2 m
386 | 518.4 388.8 l
387 | stroke
388 | grestore
389 | 0.500 setlinewidth
390 | 1 setlinejoin
391 | 0 setlinecap
392 | gsave
393 | /o {
394 | gsave
395 | newpath
396 | translate
397 | 0.5 setlinewidth
398 | 1 setlinejoin
399 | 0 setlinecap
400 | 0 0 m
401 | 0 4 l
402 | 
403 | gsave
404 | 0.000 setgray
405 | fill
406 | grestore
407 | stroke
408 | grestore
409 | } bind def
410 | 72 43.2 o
411 | grestore
412 | gsave
413 | /o {
414 | gsave
415 | newpath
416 | translate
417 | 0.5 setlinewidth
418 | 1 setlinejoin
419 | 0 setlinecap
420 | 0 0 m
421 | 0 -4 l
422 | 
423 | gsave
424 | 0.000 setgray
425 | fill
426 | grestore
427 | stroke
428 | grestore
429 | } bind def
430 | 72 388.8 o
431 | grestore
432 | /BitstreamVeraSans-Roman findfont
433 | 12.000 scalefont
434 | setfont
435 | gsave
436 | 50.992188 30.075000 translate
437 | 0.000000 rotate
438 | 0.000000 0.000000 m /zero glyphshow
439 | 7.634766 0.000000 m /period glyphshow
440 | 11.449219 0.000000 m /zero glyphshow
441 | 19.083984 0.000000 m /zero glyphshow
442 | 26.718750 0.000000 m /zero glyphshow
443 | 34.353516 0.000000 m /zero glyphshow
444 | grestore
445 | gsave
446 | /o {
447 | gsave
448 | newpath
449 | translate
450 | 0.5 setlinewidth
451 | 1 setlinejoin
452 | 0 setlinecap
453 | 0 0 m
454 | 0 4 l
455 | 
456 | gsave
457 | 0.000 setgray
458 | fill
459 | grestore
460 | stroke
461 | grestore
462 | } bind def
463 | 153.84 43.2 o
464 | grestore
465 | gsave
466 | /o {
467 | gsave
468 | newpath
469 | translate
470 | 0.5 setlinewidth
471 | 1 setlinejoin
472 | 0 setlinecap
473 | 0 0 m
474 | 0 -4 l
475 | 
476 | gsave
477 | 0.000 setgray
478 | fill
479 | grestore
480 | stroke
481 | grestore
482 | } bind def
483 | 153.84 388.8 o
484 | grestore
485 | gsave
486 | 132.832187 30.075000 translate
487 | 0.000000 rotate
488 | 0.000000 0.000000 m /zero glyphshow
489 | 7.634766 0.000000 m /period glyphshow
490 | 11.449219 0.000000 m /zero glyphshow
491 | 19.083984 0.000000 m /zero glyphshow
492 | 26.718750 0.000000 m /zero glyphshow
493 | 34.353516 0.000000 m /five glyphshow
494 | grestore
495 | gsave
496 | /o {
497 | gsave
498 | newpath
499 | translate
500 | 0.5 setlinewidth
501 | 1 setlinejoin
502 | 0 setlinecap
503 | 0 0 m
504 | 0 4 l
505 | 
506 | gsave
507 | 0.000 setgray
508 | fill
509 | grestore
510 | stroke
511 | grestore
512 | } bind def
513 | 235.68 43.2 o
514 | grestore
515 | gsave
516 | /o {
517 | gsave
518 | newpath
519 | translate
520 | 0.5 setlinewidth
521 | 1 setlinejoin
522 | 0 setlinecap
523 | 0 0 m
524 | 0 -4 l
525 | 
526 | gsave
527 | 0.000 setgray
528 | fill
529 | grestore
530 | stroke
531 | grestore
532 | } bind def
533 | 235.68 388.8 o
534 | grestore
535 | gsave
536 | 214.672187 30.075000 translate
537 | 0.000000 rotate
538 | 0.000000 0.000000 m /zero glyphshow
539 | 7.634766 0.000000 m /period glyphshow
540 | 11.449219 0.000000 m /zero glyphshow
541 | 19.083984 0.000000 m /zero glyphshow
542 | 26.718750 0.000000 m /one glyphshow
543 | 34.353516 0.000000 m /zero glyphshow
544 | grestore
545 | gsave
546 | /o {
547 | gsave
548 | newpath
549 | translate
550 | 0.5 setlinewidth
551 | 1 setlinejoin
552 | 0 setlinecap
553 | 0 0 m
554 | 0 4 l
555 | 
556 | gsave
557 | 0.000 setgray
558 | fill
559 | grestore
560 | stroke
561 | grestore
562 | } bind def
563 | 317.52 43.2 o
564 | grestore
565 | gsave
566 | /o {
567 | gsave
568 | newpath
569 | translate
570 | 0.5 setlinewidth
571 | 1 setlinejoin
572 | 0 setlinecap
573 | 0 0 m
574 | 0 -4 l
575 | 
576 | gsave
577 | 0.000 setgray
578 | fill
579 | grestore
580 | stroke
581 | grestore
582 | } bind def
583 | 317.52 388.8 o
584 | grestore
585 | gsave
586 | 296.512187 30.075000 translate
587 | 0.000000 rotate
588 | 0.000000 0.000000 m /zero glyphshow
589 | 7.634766 0.000000 m /period glyphshow
590 | 11.449219 0.000000 m /zero glyphshow
591 | 19.083984 0.000000 m /zero glyphshow
592 | 26.718750 0.000000 m /one glyphshow
593 | 34.353516 0.000000 m /five glyphshow
594 | grestore
595 | gsave
596 | /o {
597 | gsave
598 | newpath
599 | translate
600 | 0.5 setlinewidth
601 | 1 setlinejoin
602 | 0 setlinecap
603 | 0 0 m
604 | 0 4 l
605 | 
606 | gsave
607 | 0.000 setgray
608 | fill
609 | grestore
610 | stroke
611 | grestore
612 | } bind def
613 | 399.36 43.2 o
614 | grestore
615 | gsave
616 | /o {
617 | gsave
618 | newpath
619 | translate
620 | 0.5 setlinewidth
621 | 1 setlinejoin
622 | 0 setlinecap
623 | 0 0 m
624 | 0 -4 l
625 | 
626 | gsave
627 | 0.000 setgray
628 | fill
629 | grestore
630 | stroke
631 | grestore
632 | } bind def
633 | 399.36 388.8 o
634 | grestore
635 | gsave
636 | 378.352187 30.075000 translate
637 | 0.000000 rotate
638 | 0.000000 0.000000 m /zero glyphshow
639 | 7.634766 0.000000 m /period glyphshow
640 | 11.449219 0.000000 m /zero glyphshow
641 | 19.083984 0.000000 m /zero glyphshow
642 | 26.718750 0.000000 m /two glyphshow
643 | 34.353516 0.000000 m /zero glyphshow
644 | grestore
645 | gsave
646 | /o {
647 | gsave
648 | newpath
649 | translate
650 | 0.5 setlinewidth
651 | 1 setlinejoin
652 | 0 setlinecap
653 | 0 0 m
654 | 0 4 l
655 | 
656 | gsave
657 | 0.000 setgray
658 | fill
659 | grestore
660 | stroke
661 | grestore
662 | } bind def
663 | 481.2 43.2 o
664 | grestore
665 | gsave
666 | /o {
667 | gsave
668 | newpath
669 | translate
670 | 0.5 setlinewidth
671 | 1 setlinejoin
672 | 0 setlinecap
673 | 0 0 m
674 | 0 -4 l
675 | 
676 | gsave
677 | 0.000 setgray
678 | fill
679 | grestore
680 | stroke
681 | grestore
682 | } bind def
683 | 481.2 388.8 o
684 | grestore
685 | gsave
686 | 460.192187 30.075000 translate
687 | 0.000000 rotate
688 | 0.000000 0.000000 m /zero glyphshow
689 | 7.634766 0.000000 m /period glyphshow
690 | 11.449219 0.000000 m /zero glyphshow
691 | 19.083984 0.000000 m /zero glyphshow
692 | 26.718750 0.000000 m /two glyphshow
693 | 34.353516 0.000000 m /five glyphshow
694 | grestore
695 | gsave
696 | 270.614062 13.450000 translate
697 | 0.000000 rotate
698 | 0.000000 0.000000 m /T glyphshow
699 | 7.330078 0.000000 m /i glyphshow
700 | 10.664062 0.000000 m /m glyphshow
701 | 22.353516 0.000000 m /e glyphshow
702 | 29.736328 0.000000 m /space glyphshow
703 | 33.550781 0.000000 m /parenleft glyphshow
704 | 38.232422 0.000000 m /s glyphshow
705 | 44.484375 0.000000 m /parenright glyphshow
706 | grestore
707 | gsave
708 | /o {
709 | gsave
710 | newpath
711 | translate
712 | 0.5 setlinewidth
713 | 1 setlinejoin
714 | 0 setlinecap
715 | 0 0 m
716 | 4 0 l
717 | 
718 | gsave
719 | 0.000 setgray
720 | fill
721 | grestore
722 | stroke
723 | grestore
724 | } bind def
725 | 72 51.4286 o
726 | grestore
727 | gsave
728 | /o {
729 | gsave
730 | newpath
731 | translate
732 | 0.5 setlinewidth
733 | 1 setlinejoin
734 | 0 setlinecap
735 | 0 0 m
736 | -4 0 l
737 | 
738 | gsave
739 | 0.000 setgray
740 | fill
741 | grestore
742 | stroke
743 | grestore
744 | } bind def
745 | 518.4 51.4286 o
746 | grestore
747 | gsave
748 | 38.843750 48.116071 translate
749 | 0.000000 rotate
750 | 0.000000 0.000000 m /minus glyphshow
751 | 10.054688 0.000000 m /one glyphshow
752 | 17.689453 0.000000 m /period glyphshow
753 | 21.503906 0.000000 m /zero glyphshow
754 | grestore
755 | gsave
756 | /o {
757 | gsave
758 | newpath
759 | translate
760 | 0.5 setlinewidth
761 | 1 setlinejoin
762 | 0 setlinecap
763 | 0 0 m
764 | 4 0 l
765 | 
766 | gsave
767 | 0.000 setgray
768 | fill
769 | grestore
770 | stroke
771 | grestore
772 | } bind def
773 | 72 133.714 o
774 | grestore
775 | gsave
776 | /o {
777 | gsave
778 | newpath
779 | translate
780 | 0.5 setlinewidth
781 | 1 setlinejoin
782 | 0 setlinecap
783 | 0 0 m
784 | -4 0 l
785 | 
786 | gsave
787 | 0.000 setgray
788 | fill
789 | grestore
790 | stroke
791 | grestore
792 | } bind def
793 | 518.4 133.714 o
794 | grestore
795 | gsave
796 | 38.843750 130.401786 translate
797 | 0.000000 rotate
798 | 0.000000 0.000000 m /minus glyphshow
799 | 10.054688 0.000000 m /zero glyphshow
800 | 17.689453 0.000000 m /period glyphshow
801 | 21.503906 0.000000 m /five glyphshow
802 | grestore
803 | gsave
804 | /o {
805 | gsave
806 | newpath
807 | translate
808 | 0.5 setlinewidth
809 | 1 setlinejoin
810 | 0 setlinecap
811 | 0 0 m
812 | 4 0 l
813 | 
814 | gsave
815 | 0.000 setgray
816 | fill
817 | grestore
818 | stroke
819 | grestore
820 | } bind def
821 | 72 216 o
822 | grestore
823 | gsave
824 | /o {
825 | gsave
826 | newpath
827 | translate
828 | 0.5 setlinewidth
829 | 1 setlinejoin
830 | 0 setlinecap
831 | 0 0 m
832 | -4 0 l
833 | 
834 | gsave
835 | 0.000 setgray
836 | fill
837 | grestore
838 | stroke
839 | grestore
840 | } bind def
841 | 518.4 216 o
842 | grestore
843 | gsave
844 | 48.906250 212.687500 translate
845 | 0.000000 rotate
846 | 0.000000 0.000000 m /zero glyphshow
847 | 7.634766 0.000000 m /period glyphshow
848 | 11.449219 0.000000 m /zero glyphshow
849 | grestore
850 | gsave
851 | /o {
852 | gsave
853 | newpath
854 | translate
855 | 0.5 setlinewidth
856 | 1 setlinejoin
857 | 0 setlinecap
858 | 0 0 m
859 | 4 0 l
860 | 
861 | gsave
862 | 0.000 setgray
863 | fill
864 | grestore
865 | stroke
866 | grestore
867 | } bind def
868 | 72 298.286 o
869 | grestore
870 | gsave
871 | /o {
872 | gsave
873 | newpath
874 | translate
875 | 0.5 setlinewidth
876 | 1 setlinejoin
877 | 0 setlinecap
878 | 0 0 m
879 | -4 0 l
880 | 
881 | gsave
882 | 0.000 setgray
883 | fill
884 | grestore
885 | stroke
886 | grestore
887 | } bind def
888 | 518.4 298.286 o
889 | grestore
890 | gsave
891 | 48.906250 294.973214 translate
892 | 0.000000 rotate
893 | 0.000000 0.000000 m /zero glyphshow
894 | 7.634766 0.000000 m /period glyphshow
895 | 11.449219 0.000000 m /five glyphshow
896 | grestore
897 | gsave
898 | /o {
899 | gsave
900 | newpath
901 | translate
902 | 0.5 setlinewidth
903 | 1 setlinejoin
904 | 0 setlinecap
905 | 0 0 m
906 | 4 0 l
907 | 
908 | gsave
909 | 0.000 setgray
910 | fill
911 | grestore
912 | stroke
913 | grestore
914 | } bind def
915 | 72 380.571 o
916 | grestore
917 | gsave
918 | /o {
919 | gsave
920 | newpath
921 | translate
922 | 0.5 setlinewidth
923 | 1 setlinejoin
924 | 0 setlinecap
925 | 0 0 m
926 | -4 0 l
927 | 
928 | gsave
929 | 0.000 setgray
930 | fill
931 | grestore
932 | stroke
933 | grestore
934 | } bind def
935 | 518.4 380.571 o
936 | grestore
937 | gsave
938 | 48.906250 377.258929 translate
939 | 0.000000 rotate
940 | 0.000000 0.000000 m /one glyphshow
941 | 7.634766 0.000000 m /period glyphshow
942 | 11.449219 0.000000 m /zero glyphshow
943 | grestore
944 | 
945 | end
946 | showpage
947 | 


--------------------------------------------------------------------------------
/book/figs/triangle-1100-1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/triangle-1100-1.pdf


--------------------------------------------------------------------------------
/book/figs/triangle-1100-2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/triangle-1100-2.pdf


--------------------------------------------------------------------------------
/book/figs/triangle-200-1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/triangle-200-1.pdf


--------------------------------------------------------------------------------
/book/figs/triangle-200-2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/triangle-200-2.pdf


--------------------------------------------------------------------------------
/book/figs/tuning1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/tuning1.pdf


--------------------------------------------------------------------------------
/book/figs/uml_diagram1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/uml_diagram1.pdf


--------------------------------------------------------------------------------
/book/figs/violin1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/violin1.pdf


--------------------------------------------------------------------------------
/book/figs/violin2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/violin2.pdf


--------------------------------------------------------------------------------
/book/figs/whitenoise0.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/whitenoise0.pdf


--------------------------------------------------------------------------------
/book/figs/whitenoise1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/whitenoise1.pdf


--------------------------------------------------------------------------------
/book/figs/whitenoise2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/whitenoise2.pdf


--------------------------------------------------------------------------------
/book/figs/whitenoise3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/whitenoise3.pdf


--------------------------------------------------------------------------------
/book/figs/whitenoise4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/whitenoise4.pdf


--------------------------------------------------------------------------------
/book/figs/whitenoise5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/whitenoise5.pdf


--------------------------------------------------------------------------------
/book/figs/windowing1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/windowing1.pdf


--------------------------------------------------------------------------------
/book/figs/windowing2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/windowing2.pdf


--------------------------------------------------------------------------------
/book/figs/windowing3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/figs/windowing3.pdf


--------------------------------------------------------------------------------
/book/footer.html:
--------------------------------------------------------------------------------
 1 | </div>
 2 | 
 3 | <div id="sidebar">
 4 | 
 5 | <p>
 6 | <h4>Are you using one of our books in a class?</h4>  We'd like to know
 7 | about it.  Please consider filling out <a href="http://spreadsheets.google.com/viewform?formkey=dC0tNUZkMjBEdXVoRGljNm9FRmlTMHc6MA" onClick="javascript: pageTracker._trackPageview('/outbound/survey');">this short survey</a>.
 8 | 
 9 | <p>
10 | <br>
11 | 
12 | <p>
13 | <a href="http://www.amazon.com/gp/product/1449370780/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1449370780&linkCode=as2&tag=greenteapre01-20">Think Bayes</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=1449370780" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
14 | 
15 | <p>
16 | <a href="http://www.amazon.com/gp/product/1449370780/ref=as_li_qf_sp_asin_il?ie=UTF8&camp=1789&creative=9325&creativeASIN=1449370780&linkCode=as2&tag=greenteapre01-20"><img border="0" src="http://ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;ASIN=1449370780&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=US&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=greenteapre01-20" onerror="this.style.display='none'" /></a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=1449370780" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
17 | 
18 | <p>
19 | <a href="http://www.amazon.com/gp/product/144933072X/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=144933072X&linkCode=as2&tag=greenteapre01-20">Think Python</a><img src="http://www.assoc-amazon.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=144933072X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
20 | 
21 | <p>
22 | <a href="http://www.amazon.com/gp/product/144933072X/ref=as_li_tf_il?ie=UTF8&camp=1789&creative=9325&creativeASIN=144933072X&linkCode=as2&tag=greenteapre01-20"><img border="0" src="http://ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;ASIN=144933072X&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=US&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=greenteapre01-20" onerror="this.style.display='none'" /></a><img src="http://www.assoc-amazon.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=144933072X" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
23 | 
24 | <p>
25 | <a href="http://www.amazon.com/gp/product/1491907339/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1491907339&linkCode=as2&tag=greenteapre01-20&linkId=O7WYM6H6YBYUFNWU">Think Stats</a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=1491907339" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
26 | 
27 | <p>
28 | <a href="http://www.amazon.com/gp/product/1491907339/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1491907339&linkCode=as2&tag=greenteapre01-20&linkId=JVSYKQHYSUIEYRHL"><img border="0" src="http://ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;ASIN=1491907339&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=US&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=greenteapre01-20" onerror="this.style.display='none'" /></a><img src="http://ir-na.amazon-adsystem.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=1491907339" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
29 | 
30 | <p>
31 | <a href="http://www.amazon.com/gp/product/1449314635/ref=as_li_tf_tl?ie=UTF8&tag=greenteapre01-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1449314635">Think Complexity</a><img src="http://www.assoc-amazon.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=1449314635" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
32 | 
33 | <p>
34 | <a href="http://www.amazon.com/gp/product/1449314635/ref=as_li_tf_il?ie=UTF8&camp=1789&creative=9325&creativeASIN=1449314635&linkCode=as2&tag=greenteapre01-20"><img border="0" src="http://ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;ASIN=1449314635&amp;Format=_SL160_&amp;ID=AsinImage&amp;MarketPlace=US&amp;ServiceVersion=20070822&amp;WS=1&amp;tag=greenteapre01-20" onerror="this.style.display='none'" /></a><img src="http://www.assoc-amazon.com/e/ir?t=greenteapre01-20&l=as2&o=1&a=1449314635" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
35 | 
36 | 
37 | </div>
38 | </div>
39 | </body>
40 | 


--------------------------------------------------------------------------------
/book/header.html:
--------------------------------------------------------------------------------
 1 | <div id="main">
 2 | <div id="colorbar"></div>
 3 | <div id="content">
 4 | 
 5 | <div class="notice">
 6 | <p>This HTML version of <it>Think DSP</it> is provided for convenience, but it
 7 | is not the best format for the book.  In particular, some of the
 8 | math symbols are not rendered correctly.
 9 | 
10 | <p style="margin-bottom:0">You might prefer to read
11 | the <a href="https://greenteapress.com/thinkdsp/thinkdsp.pdf">PDF version</a>, or
12 | you can buy a hard copy from
13 | <a href="http://www.amazon.com/gp/product/1491938455/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1491938455&amp;linkCode=as2&amp;tag=greenteapre01-20&amp;linkId=2JJH4SWCAVVYSQHO">Amazon</a>.
14 | </div>
15 | 


--------------------------------------------------------------------------------
/book/hevea.sty:
--------------------------------------------------------------------------------
 1 | % hevea  : hevea.sty
 2 | % This is a very basic style file for latex document to be processed
 3 | % with hevea. It contains definitions of LaTeX environment which are
 4 | % processed in a special way by the translator. 
 5 | %  Mostly :
 6 | %     - latexonly, not processed by hevea, processed by latex.
 7 | %     - htmlonly , the reverse.
 8 | %     - rawhtml,  to include raw HTML in hevea output.
 9 | %     - toimage, to send text to the image file.
10 | % The package also provides hevea logos, html related commands (ahref
11 | % etc.), void cutting and image commands.
12 | \NeedsTeXFormat{LaTeX2e}
13 | \ProvidesPackage{hevea}[2002/01/11]
14 | \RequirePackage{comment}
15 | \newif\ifhevea\heveafalse
16 | \@ifundefined{ifimagen}{\newif\ifimagen\imagenfalse}
17 | \makeatletter%
18 | \newcommand{\heveasmup}[2]{%
19 | \raise #1\hbox{$\m@th$%
20 |   \csname S@\f@size\endcsname
21 |   \fontsize\sf@size 0%
22 |   \math@fontsfalse\selectfont
23 | #2%
24 | }}%
25 | \DeclareRobustCommand{\hevea}{H\kern-.15em\heveasmup{.2ex}{E}\kern-.15emV\kern-.15em\heveasmup{.2ex}{E}\kern-.15emA}%
26 | \DeclareRobustCommand{\hacha}{H\kern-.15em\heveasmup{.2ex}{A}\kern-.15emC\kern-.1em\heveasmup{.2ex}{H}\kern-.15emA}%
27 | \DeclareRobustCommand{\html}{\protect\heveasmup{0.ex}{HTML}}
28 | %%%%%%%%% Hyperlinks hevea style
29 | \newcommand{\ahref}[2]{{#2}}
30 | \newcommand{\ahrefloc}[2]{{#2}}
31 | \newcommand{\aname}[2]{{#2}}
32 | \newcommand{\ahrefurl}[1]{\texttt{#1}}
33 | \newcommand{\footahref}[2]{#2\footnote{\texttt{#1}}}
34 | \newcommand{\mailto}[1]{\texttt{#1}}
35 | \newcommand{\imgsrc}[2][]{}
36 | \newcommand{\home}[1]{\protect\raisebox{-.75ex}{\char126}#1}
37 | \AtBeginDocument
38 | {\@ifundefined{url}
39 | {%url package is not loaded
40 | \let\url\ahref\let\oneurl\ahrefurl\let\footurl\footahref}
41 | {}}
42 | %% Void cutting instructions
43 | \newcounter{cuttingdepth}
44 | \newcommand{\tocnumber}{}
45 | \newcommand{\notocnumber}{}
46 | \newcommand{\cuttingunit}{}
47 | \newcommand{\cutdef}[2][]{}
48 | \newcommand{\cuthere}[2]{}
49 | \newcommand{\cutend}{}
50 | \newcommand{\htmlhead}[1]{}
51 | \newcommand{\htmlfoot}[1]{}
52 | \newcommand{\htmlprefix}[1]{}
53 | \newenvironment{cutflow}[1]{}{}
54 | \newcommand{\cutname}[1]{}
55 | \newcommand{\toplinks}[3]{}
56 | \newcommand{\setlinkstext}[3]{}
57 | \newcommand{\flushdef}[1]{}
58 | \newcommand{\footnoteflush}[1]{}
59 | %%%% Html only
60 | \excludecomment{rawhtml}
61 | \newcommand{\rawhtmlinput}[1]{}
62 | \excludecomment{htmlonly}
63 | %%%% Latex only
64 | \newenvironment{latexonly}{}{}
65 | \newenvironment{verblatex}{}{}
66 | %%%% Image file stuff
67 | \def\toimage{\endgroup}
68 | \def\endtoimage{\begingroup\def\@currenvir{toimage}}
69 | \def\verbimage{\endgroup}
70 | \def\endverbimage{\begingroup\def\@currenvir{verbimage}}
71 | \newcommand{\imageflush}[1][]{}
72 | %%% Bgcolor definition
73 | \newsavebox{\@bgcolorbin}
74 | \newenvironment{bgcolor}[2][]
75 |   {\newcommand{\@mycolor}{#2}\begin{lrbox}{\@bgcolorbin}\vbox\bgroup}
76 |   {\egroup\end{lrbox}%
77 |    \begin{flushleft}%
78 |    \colorbox{\@mycolor}{\usebox{\@bgcolorbin}}%
79 |    \end{flushleft}}
80 | %%% Style sheets macros, defined as no-ops
81 | \newcommand{\newstyle}[2]{}
82 | \newcommand{\addstyle}[1]{}
83 | \newcommand{\setenvclass}[2]{}
84 | \newcommand{\getenvclass}[1]{}
85 | \newcommand{\loadcssfile}[1]{}
86 | \newenvironment{divstyle}[1]{}{}
87 | \newenvironment{cellstyle}[2]{}{}
88 | \newif\ifexternalcss
89 | %%% Postlude
90 | \makeatother
91 | 


--------------------------------------------------------------------------------
/book/htmlonly:
--------------------------------------------------------------------------------
 1 | % put commands here that should be used for the HTML
 2 | % version of the book but not Postscript or PDF
 3 | 
 4 | \newcommand{\beforefig}{}
 5 | \newcommand{\afterfig}{}
 6 | 
 7 | \newcommand{\beforeverb}{\blue \large}
 8 | \newcommand{\afterverb}{\black \normalsize}
 9 | 
10 | \newcommand{\adjustpage}[1]{}
11 | 
12 | \newcommand{\clearemptydoublepage}{}
13 | \newcommand{\blankpage}{}
14 | 
15 | \newcommand{\spacing}{}
16 | \newcommand{\endspacing}{}
17 | 
18 | \newcommand{\frontmatter}{}
19 | \newcommand{\mainmatter}{}
20 | 
21 | \newcommand{\theoremstyle}[1]{}
22 | \newcommand{\newtheoremstyle}[1]{}
23 | 
24 | \newcommand{\vfill}{}
25 | 
26 | \htmlhead{\rawhtmlinput{header.html}}
27 | 
28 | \htmlfoot{\rawhtmlinput{footer.html}}


--------------------------------------------------------------------------------
/book/latexonly:
--------------------------------------------------------------------------------
  1 | \sloppy
  2 | %\setlength{\topmargin}{-0.375in}
  3 | %\setlength{\oddsidemargin}{0.0in}
  4 | %\setlength{\evensidemargin}{0.0in}
  5 | 
  6 | % Uncomment these to center on 8.5 x 11
  7 | %\setlength{\topmargin}{0.625in}
  8 | %\setlength{\oddsidemargin}{0.875in}
  9 | %\setlength{\evensidemargin}{0.875in}
 10 | 
 11 | %\setlength{\textheight}{7.2in}
 12 | 
 13 | \setlength{\headsep}{3ex}
 14 | \setlength{\parindent}{0.0in}
 15 | \setlength{\parskip}{1.7ex plus 0.5ex minus 0.5ex}
 16 | \renewcommand{\baselinestretch}{1.02}
 17 | 
 18 | % see LaTeX Companion page 62
 19 | \setlength{\topsep}{-0.0\parskip}
 20 | \setlength{\partopsep}{-0.5\parskip}
 21 | \setlength{\itemindent}{0.0in}
 22 | \setlength{\listparindent}{0.0in}
 23 | 
 24 | % see LaTeX Companion page 26
 25 | % these are copied from /usr/local/teTeX/share/texmf/tex/latex/base/book.cls
 26 | % all I changed is afterskip
 27 | 
 28 | \makeatletter
 29 | 
 30 | \renewcommand{\section}{\@startsection 
 31 |     {section} {1} {0mm}%
 32 |     {-3.5ex \@plus -1ex \@minus -.2ex}%
 33 |     {0.7ex \@plus.2ex}%
 34 |     {\normalfont\Large\bfseries}}
 35 | \renewcommand\subsection{\@startsection {subsection}{2}{0mm}%
 36 |     {-3.25ex\@plus -1ex \@minus -.2ex}%
 37 |     {0.3ex \@plus .2ex}%
 38 |     {\normalfont\large\bfseries}}
 39 | \renewcommand\subsubsection{\@startsection {subsubsection}{3}{0mm}%
 40 |     {-3.25ex\@plus -1ex \@minus -.2ex}%
 41 |     {0.3ex \@plus .2ex}%
 42 |     {\normalfont\normalsize\bfseries}}
 43 | 
 44 | % The following line adds a little extra space to the column
 45 | % in which the Section numbers appear in the table of contents
 46 | \renewcommand{\l@section}{\@dottedtocline{1}{1.5em}{3.0em}}
 47 | \setcounter{tocdepth}{1}
 48 | 
 49 | \makeatother
 50 | 
 51 | \newcommand{\beforefig}{\vspace{1.3\parskip}}
 52 | \newcommand{\afterfig}{\vspace{-0.2\parskip}}
 53 | 
 54 | \newcommand{\beforeverb}{\vspace{0.6\parskip}}
 55 | \newcommand{\afterverb}{\vspace{0.6\parskip}}
 56 | 
 57 | \newcommand{\adjustpage}[1]{\enlargethispage{#1\baselineskip}}
 58 | 
 59 | 
 60 | % Note: the following command seems to cause problems for Acroreader
 61 | % on Windows, so for now I am overriding it.
 62 | %\newcommand{\clearemptydoublepage}{
 63 | %            \newpage{\pagestyle{empty}\cleardoublepage}}
 64 | \newcommand{\clearemptydoublepage}{\cleardoublepage}
 65 | 
 66 | %\newcommand{\blankpage}{\pagestyle{empty}\vspace*{1in}\newpage}
 67 | \newcommand{\blankpage}{\vspace*{1in}\newpage}
 68 | 
 69 | % HEADERS
 70 | 
 71 | \renewcommand{\chaptermark}[1]{\markboth{#1}{}}
 72 | \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}{}}
 73 | 
 74 | \lhead[\fancyplain{}{\bfseries\thepage}]%
 75 |       {\fancyplain{}{\bfseries\rightmark}}
 76 | \rhead[\fancyplain{}{\bfseries\leftmark}]%
 77 |       {\fancyplain{}{\bfseries\thepage}}
 78 | \cfoot{}
 79 | 
 80 | \pagestyle{fancyplain}
 81 | 
 82 | 
 83 | % turn off the rule under the header
 84 | %\setlength{\headrulewidth}{0pt}
 85 | 
 86 | % the following is a brute-force way to prevent the headers
 87 | % from getting transformed into all-caps
 88 | \renewcommand\MakeUppercase{}
 89 | 
 90 | % Exercise environment
 91 | \newtheoremstyle{myex}% name
 92 |      {9pt}%      Space above
 93 |      {9pt}%      Space below
 94 |      {}%         Body font
 95 |      {}%         Indent amount (empty = no indent, \parindent = para indent)
 96 |      {\bfseries}% Thm head font
 97 |      {}%        Punctuation after thm head
 98 |      {0.5em}%     Space after thm head: " " = normal interword space;
 99 |            %       \newline = linebreak
100 |      {}%         Thm head spec (can be left empty, meaning `normal')
101 | 
102 | \theoremstyle{myex}
103 | 


--------------------------------------------------------------------------------
/book/localdef.py:
--------------------------------------------------------------------------------
 1 | import plasTeX.Base as Base
 2 | 
 3 | def idgen():
 4 |     """ Generate a unique ID """
 5 |     i = 1
 6 |     while 1:
 7 |         yield 'a%.10d' % i
 8 |         i += 1
 9 | 
10 | idgen = idgen()
11 | 
12 | class Eqn(Base.Command):
13 |     args = 'self'
14 | 
15 | class Anchor(Base.Command):
16 |     args = 'label:str'
17 |     def invoke(self, tex):
18 |         Base.Command.invoke(self, tex)
19 |         self.ownerDocument.context.label(self.attributes['label'], self)
20 | 
21 | class exercise(Base.Environment):
22 |     counter = 'exercise'
23 | 
24 | class index(Base.Command):
25 |     args = 'termstring'
26 | 
27 |     def setEntry(self, s, seetype=0):
28 |     #    TYPE_NORMAL = 0
29 |     #    TYPE_SEE = 1
30 |     #    TYPE_SEEALSO = 2
31 |         if type(s) != type(''):
32 |             s = s.textContent
33 |         if s.count('!'):
34 |             priterm, secterm = s.split('!')
35 |             if priterm.count('@'):
36 |                 prisort, primary = priterm.split('@')
37 |             else:
38 |                 prisort, primary = None, priterm
39 |             if secterm.count('@'):
40 |                 secsort, secondary = secterm.split('@')
41 |             else:
42 |                 secsort, secondary = None, secterm
43 |         elif s.count('@'):
44 |             prisort, primary = s.split('@')
45 |             secsort, secondary = None, None
46 |         else:
47 |             prisort, primary = None, s
48 |             secsort, secondary = None, None
49 | 
50 | #        if secondary:
51 | #            self.ownerDocument.userdata.setdefault('index', []).append(\
52 | #                Base.IndexEntry([primary, secondary], self, [prisort, secsort], None, type=seetype))
53 | #        else:
54 | #            self.ownerDocument.userdata.setdefault('index', []).append(\
55 | #                Base.IndexEntry([primary], self, [prisort], None, type=seetype))
56 |         return prisort, primary, secsort, secondary
57 | 
58 |     def invoke(self, tex):
59 |         Base.Command.invoke(self, tex)
60 |         self.ownerDocument.context.label(idgen.next(), self)
61 |         p0,p1,s0,s1 = self.setEntry(self.attributes['termstring'])
62 |         if p0:
63 |             self.prisort = '%s' % p0
64 |         if p1:
65 |             self.primary = '%s' % p1
66 |         if s0:
67 |             self.secsort = '%s' % s0
68 |         if s1:
69 |             self.secondary = '%s' % s1
70 | 
71 | class scriptN(Base.Command):
72 |        unicode = u'\U0001D4A9'
73 | 
74 | class uxbar(Base.Command): pass
75 | class uybar(Base.Command): pass
76 | class unhat(Base.Command): pass
77 | class ule(Base.Command): pass
78 | class minus(Base.Command): pass
79 | class lowast(Base.Command): pass
80 | class Erdos(Base.Command): pass
81 | 
82 | 


--------------------------------------------------------------------------------
/book/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/next.png


--------------------------------------------------------------------------------
/book/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/book/up.png


--------------------------------------------------------------------------------
/code/100475__iluppai__saxophone-weep.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/100475__iluppai__saxophone-weep.wav


--------------------------------------------------------------------------------
/code/105977__wcfl10__favorite-station.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/105977__wcfl10__favorite-station.wav


--------------------------------------------------------------------------------
/code/120994__thirsk__120-oboe.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/120994__thirsk__120-oboe.wav


--------------------------------------------------------------------------------
/code/132736__ciccarelli__ocean-waves.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/132736__ciccarelli__ocean-waves.wav


--------------------------------------------------------------------------------
/code/170255__dublie__trumpet.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/170255__dublie__trumpet.wav


--------------------------------------------------------------------------------
/code/180929__docquesting__crowd-noise.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/180929__docquesting__crowd-noise.wav


--------------------------------------------------------------------------------
/code/180960__kleeb__gunshot.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/180960__kleeb__gunshot.wav


--------------------------------------------------------------------------------
/code/181934__landub__applause2.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/181934__landub__applause2.wav


--------------------------------------------------------------------------------
/code/18871__zippi1__sound-bell-440hz.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/18871__zippi1__sound-bell-440hz.wav


--------------------------------------------------------------------------------
/code/253887__themusicalnomad__positive-beeps.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/253887__themusicalnomad__positive-beeps.wav


--------------------------------------------------------------------------------
/code/263868__kevcio__amen-break-a-160-bpm.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/263868__kevcio__amen-break-a-160-bpm.wav


--------------------------------------------------------------------------------
/code/28042__bcjordan__voicedownbew.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/28042__bcjordan__voicedownbew.wav


--------------------------------------------------------------------------------
/code/328878__tzurkan__guitar-phrase-tzu.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/328878__tzurkan__guitar-phrase-tzu.wav


--------------------------------------------------------------------------------
/code/72475__rockwehrmann__glissup02.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/72475__rockwehrmann__glissup02.wav


--------------------------------------------------------------------------------
/code/87778__marcgascon7__vocals.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/87778__marcgascon7__vocals.wav


--------------------------------------------------------------------------------
/code/92002__jcveliz__violin-origional.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/92002__jcveliz__violin-origional.wav


--------------------------------------------------------------------------------
/code/GardnerFractalMusic.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/GardnerFractalMusic.pdf


--------------------------------------------------------------------------------
/code/Makefile:
--------------------------------------------------------------------------------
  1 | DEST = /home/downey/web/greenteapress
  2 | 
  3 | FIGS = \
  4 | sounds1.pdf sounds1.eps  \
  5 | sounds2.pdf sounds2.eps  \
  6 | sounds3.pdf sounds3.eps  \
  7 | sounds4.pdf sounds4.eps  \
  8 | aliasing1.eps  square-100-1.eps  triangle-1100-1.eps  triangle-200-1.eps \
  9 | aliasing1.pdf  square-100-1.pdf  triangle-1100-1.pdf  triangle-200-1.pdf \
 10 | square-100-2.eps  triangle-1100-2.eps  triangle-200-2.eps \
 11 | square-100-2.pdf  triangle-1100-2.pdf  triangle-200-2.pdf \
 12 | chirp1.pdf chirp1.eps \
 13 | chirp2.pdf chirp2.eps \
 14 | chirp3.pdf chirp3.eps \
 15 | windowing1.pdf windowing1.eps \
 16 | windowing2.pdf windowing2.eps \
 17 | windowing3.pdf windowing3.eps \
 18 | whitenoise0.pdf whitenoise0.eps \
 19 | whitenoise1.pdf whitenoise1.eps \
 20 | whitenoise2.pdf whitenoise2.eps \
 21 | rednoise0.pdf rednoise0.eps \
 22 | rednoise3.pdf rednoise3.eps \
 23 | pinknoise0.pdf pinknoise0.eps \
 24 | noise-triple.pdf noise-triple.eps \
 25 | noise1.pdf noise1.eps \
 26 | autocorr1.pdf autocorr1.eps \
 27 | autocorr2.pdf autocorr2.eps \
 28 | autocorr3.pdf autocorr3.eps \
 29 | autocorr4.pdf autocorr4.eps \
 30 | autocorr5.pdf autocorr5.eps \
 31 | autocorr6.pdf autocorr6.eps \
 32 | autocorr7.pdf autocorr7.eps \
 33 | autocorr8.pdf autocorr8.eps \
 34 | autocorr9.pdf autocorr9.eps \
 35 | dct1.pdf dct1.eps \
 36 | dft1.pdf dft1.eps \
 37 | dft2.pdf dft2.eps \
 38 | dft3.pdf dft3.eps \
 39 | convolution1.pdf convolution1.eps \
 40 | convolution2.pdf convolution2.eps \
 41 | convolution4.pdf convolution4.eps \
 42 | convolution5.pdf convolution5.eps \
 43 | convolution6.pdf convolution6.eps \
 44 | convolution7.pdf convolution7.eps \
 45 | convolution8.pdf convolution8.eps \
 46 | convolution9.pdf convolution9.eps \
 47 | diff_int1.pdf diff_int1.eps \
 48 | diff_int2.pdf diff_int2.eps \
 49 | diff_int3.pdf diff_int3.eps \
 50 | diff_int4.pdf diff_int4.eps \
 51 | diff_int5.pdf diff_int5.eps \
 52 | diff_int6.pdf diff_int6.eps \
 53 | diff_int7.pdf diff_int7.eps \
 54 | diff_int8.pdf diff_int8.eps \
 55 | diff_int9.pdf diff_int9.eps \
 56 | systems1.pdf systems1.eps \
 57 | systems6.pdf systems6.eps \
 58 | systems7.pdf systems7.eps \
 59 | systems8.pdf systems8.eps \
 60 | sampling1.pdf sampling1.eps \
 61 | sampling2.pdf sampling2.eps \
 62 | sampling3.pdf sampling3.eps \
 63 | sampling4.pdf sampling4.eps \
 64 | sampling5.pdf sampling5.eps \
 65 | sampling6.pdf sampling6.eps \
 66 | sampling7.pdf sampling7.eps \
 67 | sampling8.pdf sampling8.eps \
 68 | sampling9.pdf sampling9.eps \
 69 | 
 70 | FIGDEST = ../book/figs
 71 | 
 72 | figs:
 73 | 	rsync -a $(FIGS) $(FIGDEST)
 74 | 
 75 | 
 76 | .PHONY: docs
 77 | 
 78 | docs:
 79 | 	pydoc -w thinkdsp
 80 | 	rsync -a thinkdsp.html $(DEST)/thinkdsp
 81 | 	#cd $(DEST); sh back
 82 | 
 83 | $(DOCPY):
 84 | 
 85 | 
 86 | 
 87 | NOTEBOOKS = \
 88 | cacophony.ipynb \
 89 | chap01.ipynb \
 90 | chap01preview.ipynb \
 91 | chap01soln.ipynb \
 92 | chap02.ipynb \
 93 | chap02soln.ipynb \
 94 | chap03.ipynb \
 95 | chap03soln.ipynb \
 96 | chap04.ipynb \
 97 | chap04soln.ipynb \
 98 | chap05.ipynb \
 99 | chap05soln.ipynb \
100 | chap06.ipynb \
101 | chap06soln.ipynb \
102 | chap07.ipynb \
103 | chap07soln.ipynb \
104 | chap08.ipynb \
105 | chap08soln.ipynb \
106 | chap09.ipynb \
107 | chap09soln.ipynb \
108 | chap10.ipynb \
109 | chap10preview.ipynb \
110 | chap10soln.ipynb \
111 | chap11.ipynb \
112 | chap11soln.ipynb \
113 | cumsum_example.ipynb \
114 | dft_example.ipynb \
115 | diff_int.ipynb \
116 | phase.ipynb \
117 | saxophone.ipynb \
118 | scipy2015_demo.ipynb \
119 | voss.ipynb \
120 | 
121 | SCRIPTS = $(NOTEBOOKS:ipynb=py)
122 | 
123 | make_scripts:
124 | 	for notebook in $(NOTEBOOKS) ; do \
125 | 		jupyter nbconvert --to script $notebook ; \
126 | 	done
127 | 
128 | clean_scripts:
129 | 	# remove magic command and help functions so scripts
130 | 	# can run without interaction
131 | 	for script in $(SCRIPTS) ; do \
132 | 		grep -v "'matplotlib'" $script > temp ; \
133 | 		mv temp $script ; \
134 | 		sed -i s/get_ipython/\#get_ipython/ $script ; \
135 | 		sed -i s/\^help/\#help/ $script ; \
136 | 		sed -i s/\#\ In/from\ clf\ import\ clf\;clf\(\)\#\ In/ $script ; \
137 | 	done
138 | 
139 | 
140 | run_scripts:
141 | 	# remove magic command and help functions so scripts
142 | 	# can run without interaction
143 | 	for script in $(SCRIPTS) ; do \
144 | 	    echo $script ; \
145 | 		ipython $script ; \
146 | 	done
147 | 


--------------------------------------------------------------------------------
/code/aliasing.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2013 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import thinkdsp
 11 | import thinkplot
 12 | 
 13 | FORMATS = ['pdf', 'png']
 14 | 
 15 | def triangle_example(freq):
 16 |     """Makes a figure showing a triangle wave.
 17 | 
 18 |     freq: frequency in Hz
 19 |     """
 20 |     framerate = 10000
 21 |     signal = thinkdsp.TriangleSignal(freq)
 22 | 
 23 |     duration = signal.period*3
 24 |     segment = signal.make_wave(duration, framerate=framerate)
 25 |     segment.plot()
 26 |     thinkplot.save(root='triangle-%d-1' % freq,
 27 |                    xlabel='Time (s)',
 28 |                    axis=[0, duration, -1.05, 1.05])
 29 | 
 30 |     wave = signal.make_wave(duration=0.5, framerate=framerate)
 31 |     spectrum = wave.make_spectrum()
 32 | 
 33 |     thinkplot.preplot(cols=2)
 34 |     spectrum.plot()
 35 |     thinkplot.config(xlabel='Frequency (Hz)',
 36 |                      ylabel='Amplitude')
 37 | 
 38 |     thinkplot.subplot(2)
 39 |     spectrum.plot()
 40 |     thinkplot.config(ylim=[0, 500],
 41 |                      xlabel='Frequency (Hz)')
 42 |     
 43 |     thinkplot.save(root='triangle-%d-2' % freq)
 44 | 
 45 | 
 46 | def square_example(freq):
 47 |     """Makes a figure showing a square wave.
 48 | 
 49 |     freq: frequency in Hz
 50 |     """
 51 |     framerate = 10000
 52 |     signal = thinkdsp.SquareSignal(freq)
 53 | 
 54 |     duration = signal.period*3
 55 |     segment = signal.make_wave(duration, framerate=framerate)
 56 |     segment.plot()
 57 |     thinkplot.save(root='square-%d-1' % freq,
 58 |                    xlabel='Time (s)',
 59 |                    axis=[0, duration, -1.05, 1.05])
 60 | 
 61 |     wave = signal.make_wave(duration=0.5, framerate=framerate)
 62 |     spectrum = wave.make_spectrum()
 63 |     spectrum.plot()
 64 |     thinkplot.save(root='square-%d-2' % freq,
 65 |                    xlabel='Frequency (Hz)',
 66 |                    ylabel='Amplitude')
 67 | 
 68 | 
 69 | def aliasing_example(offset=0.000003):
 70 |     """Makes a figure showing the effect of aliasing.
 71 |     """
 72 |     framerate = 10000
 73 | 
 74 |     def plot_segment(freq):
 75 |         signal = thinkdsp.CosSignal(freq)
 76 |         duration = signal.period*4
 77 |         thinkplot.Hlines(0, 0, duration, color='gray')
 78 |         segment = signal.make_wave(duration, framerate=framerate*10)
 79 |         segment.plot(linewidth=0.5, color='gray')
 80 |         segment = signal.make_wave(duration, framerate=framerate)
 81 |         segment.plot_vlines(label=freq, linewidth=4)
 82 | 
 83 |     thinkplot.preplot(rows=2)
 84 |     plot_segment(4500)
 85 |     thinkplot.config(axis=[-0.00002, 0.0007, -1.05, 1.05])
 86 | 
 87 |     thinkplot.subplot(2)
 88 |     plot_segment(5500)
 89 |     thinkplot.config(axis=[-0.00002, 0.0007, -1.05, 1.05])
 90 | 
 91 |     thinkplot.save(root='aliasing1',
 92 |                    xlabel='Time (s)',
 93 |                    formats=FORMATS)
 94 | 
 95 | 
 96 | def main():
 97 |     triangle_example(freq=200)
 98 |     triangle_example(freq=1100)
 99 |     square_example(freq=100)
100 |     aliasing_example()
101 | 
102 | 
103 | if __name__ == '__main__':
104 |     main()
105 | 


--------------------------------------------------------------------------------
/code/autocorr.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import thinkdsp
 11 | import thinkplot
 12 | import thinkstats2
 13 | import numpy as np
 14 | 
 15 | PI2 = 2 * np.pi
 16 | 
 17 | 
 18 | def make_sine(offset):
 19 |     """Makes a 440 Hz sine wave with the given phase offset.
 20 | 
 21 |     offset: phase offset in radians
 22 | 
 23 |     returns: Wave objects
 24 |     """
 25 |     signal = thinkdsp.SinSignal(freq=440, offset=offset)
 26 |     wave = signal.make_wave(duration=0.5, framerate=10000)
 27 |     return wave
 28 | 
 29 | 
 30 | def corrcoef(xs, ys):
 31 |     """Coefficient of correlation.
 32 | 
 33 |     ddof=0 indicates that we should normalize by N, not N-1.
 34 | 
 35 |     xs: sequence
 36 |     ys: sequence
 37 | 
 38 |     returns: float
 39 |     """
 40 |     return np.corrcoef(xs, ys)[0, 1]
 41 | 
 42 | 
 43 | def plot_sines():
 44 |     """Makes figures showing correlation of sine waves with offsets.
 45 |     """
 46 |     wave1 = make_sine(0)
 47 |     wave2 = make_sine(offset=1)
 48 | 
 49 |     thinkplot.preplot(2)
 50 |     wave1.segment(duration=0.01).plot(label='wave1')
 51 |     wave2.segment(duration=0.01).plot(label='wave2')
 52 | 
 53 |     corr_matrix = np.corrcoef(wave1.ys, wave2.ys, ddof=0)
 54 |     print(corr_matrix)
 55 | 
 56 |     thinkplot.save(root='autocorr1',
 57 |                    xlabel='Time (s)',
 58 |                    ylim=[-1.05, 1.05])
 59 | 
 60 |     offsets = np.linspace(0, PI2, 101)
 61 | 
 62 |     corrs = []
 63 |     for offset in offsets:
 64 |         wave2 = make_sine(offset)
 65 |         corr = corrcoef(wave1.ys, wave2.ys)
 66 |         corrs.append(corr)
 67 | 
 68 |     thinkplot.plot(offsets, corrs)
 69 |     thinkplot.save(root='autocorr2',
 70 |                    xlabel='Offset (radians)',
 71 |                    ylabel='Correlation',
 72 |                    xlim=[0, PI2],
 73 |                    ylim=[-1.05, 1.05])
 74 | 
 75 | 
 76 | def plot_shifted(wave, offset=0.002, start=0.2):
 77 |     """Plots two segments of a wave with different start times.
 78 | 
 79 |     wave: Wave
 80 |     offset: difference in start time (seconds)
 81 |     start: start time in seconds
 82 |     """
 83 |     thinkplot.preplot(num=2)
 84 |     segment1 = wave.segment(start=start, duration=0.01)
 85 |     segment1.plot(linewidth=2, alpha=0.8)
 86 | 
 87 |     segment2 = wave.segment(start=start-offset, duration=0.01)
 88 |     segment2.shift(offset)
 89 |     segment2.plot(linewidth=2, alpha=0.4)
 90 | 
 91 |     corr = segment1.corr(segment2)
 92 |     text = r'$\rho =$ %.2g' % corr
 93 |     thinkplot.text(start+0.0005, -0.8, text)
 94 |     thinkplot.config(xlabel='Time (s)', ylim=[-1.05, 1.05])
 95 | 
 96 | 
 97 | def serial_corr(wave, lag=1):
 98 |     """Computes serial correlation with given lag.
 99 | 
100 |     wave: Wave
101 |     lag: integer, how much to shift the wave
102 | 
103 |     returns: float correlation coefficient
104 |     """
105 |     n = len(wave)
106 |     y1 = wave.ys[lag:]
107 |     y2 = wave.ys[:n-lag]
108 |     corr = corrcoef(y1, y2)
109 |     return corr
110 | 
111 | 
112 | def plot_serial_corr():
113 |     """Makes a plot showing serial correlation for pink noise.
114 |     """
115 |     np.random.seed(19)
116 | 
117 |     betas = np.linspace(0, 2, 21)
118 |     corrs = []
119 | 
120 |     for beta in betas:
121 |         signal = thinkdsp.PinkNoise(beta=beta)
122 |         wave = signal.make_wave(duration=1.0, framerate=11025)
123 |         corr = serial_corr(wave)
124 |         corrs.append(corr)
125 | 
126 |     thinkplot.plot(betas, corrs)
127 |     thinkplot.config(xlabel=r'Pink noise parameter, $\beta
#39;,
128 |                      ylabel='Serial correlation',
129 |                      ylim=[0, 1.05])
130 |     thinkplot.save(root='autocorr3')
131 | 
132 | 
133 | def autocorr(wave):
134 |     """Computes and plots the autocorrelation function.
135 | 
136 |     wave: Wave
137 |     """
138 |     lags = range(len(wave.ys)//2)
139 |     corrs = [serial_corr(wave, lag) for lag in lags]
140 |     return lags, corrs
141 | 
142 | 
143 | def plot_pink_autocorr(beta, label):
144 |     """Makes a plot showing autocorrelation for pink noise.
145 | 
146 |     beta: parameter of pink noise
147 |     label: string label for the plot
148 |     """
149 |     signal = thinkdsp.PinkNoise(beta=beta)
150 |     wave = signal.make_wave(duration=1.0, framerate=11025)
151 |     lags, corrs = autocorr(wave)
152 |     thinkplot.plot(lags, corrs, label=label)
153 | 
154 | 
155 | def plot_autocorr():
156 |     """Plots autocorrelation for pink noise with different parameters
157 |     """
158 |     np.random.seed(19)
159 |     thinkplot.preplot(3)
160 | 
161 |     for beta in [1.7, 1.0, 0.3]:
162 |         label = r'$\beta$ = %.1f' % beta
163 |         plot_pink_autocorr(beta, label)
164 | 
165 |     thinkplot.config(xlabel='Lag',
166 |                      ylabel='Correlation',
167 |                      xlim=[-5, 1000],
168 |                      ylim=[-0.05, 1.05])
169 |     thinkplot.save(root='autocorr4')
170 | 
171 | 
172 | def plot_singing_chirp():
173 |     """Makes a spectrogram of the vocal chirp recording.
174 |     """
175 |     wave = thinkdsp.read_wave('28042__bcjordan__voicedownbew.wav')
176 |     wave.normalize()
177 | 
178 |     duration = 0.01
179 |     segment = wave.segment(start=0.2, duration=duration)
180 | 
181 |     # plot two copies of the wave with a shift
182 |     plot_shifted(wave, start=0.2, offset=0.0023)
183 |     thinkplot.save(root='autocorr7')
184 | 
185 |     # plot the autocorrelation function
186 |     lags, corrs = autocorr(segment)
187 |     thinkplot.plot(lags, corrs)
188 |     thinkplot.config(xlabel='Lag (index)',
189 |                      ylabel='Correlation',
190 |                      ylim=[-1.05, 1.05],
191 |                      xlim=[0, 225])
192 |     thinkplot.save(root='autocorr8')
193 | 
194 |     # plot the spectrogram
195 |     gram = wave.make_spectrogram(seg_length=1024)
196 |     gram.plot(high=4200)
197 | 
198 |     thinkplot.config(xlabel='Time (s)',
199 |                      ylabel='Frequency (Hz)',
200 |                      xlim=[0, 1.4],
201 |                      ylim=[0, 4200])
202 |     thinkplot.save(root='autocorr5')
203 | 
204 |     # plot the spectrum of one segment
205 |     spectrum = segment.make_spectrum()
206 |     spectrum.plot(high=1000)
207 |     thinkplot.config(xlabel='Frequency (Hz)', ylabel='Amplitude')
208 |     thinkplot.save(root='autocorr6')
209 | 
210 | 
211 | def plot_correlate():
212 |     """Plots the autocorrelation function computed by np.
213 |     """
214 |     wave = thinkdsp.read_wave('28042__bcjordan__voicedownbew.wav')
215 |     wave.normalize()
216 |     segment = wave.segment(start=0.2, duration=0.01)
217 | 
218 |     lags, corrs = autocorr(segment)
219 | 
220 |     N = len(segment)
221 |     corrs2 = np.correlate(segment.ys, segment.ys, mode='same')
222 |     lags = np.arange(-N//2, N//2)
223 |     thinkplot.plot(lags, corrs2)
224 |     thinkplot.config(xlabel='Lag',
225 |                      ylabel='Correlation',
226 |                      xlim=[-N//2, N//2])
227 |     thinkplot.save(root='autocorr9')
228 | 
229 | 
230 | def main():
231 |     plot_sines()
232 |     plot_serial_corr()
233 |     plot_autocorr()
234 |     plot_singing_chirp()
235 |     plot_correlate()
236 | 
237 | 
238 | if __name__ == '__main__':
239 |     main()
240 | 


--------------------------------------------------------------------------------
/code/chap07soln.ipynb:
--------------------------------------------------------------------------------
  1 | {
  2 |  "cells": [
  3 |   {
  4 |    "cell_type": "markdown",
  5 |    "metadata": {},
  6 |    "source": [
  7 |     "## ThinkDSP\n",
  8 |     "\n",
  9 |     "This notebook contains solutions to exercises in Chapter 7: Discrete Fourier Transform\n",
 10 |     "\n",
 11 |     "Copyright 2015 Allen Downey\n",
 12 |     "\n",
 13 |     "License: [Creative Commons Attribution 4.0 International](http://creativecommons.org/licenses/by/4.0/)"
 14 |    ]
 15 |   },
 16 |   {
 17 |    "cell_type": "code",
 18 |    "execution_count": 1,
 19 |    "metadata": {},
 20 |    "outputs": [],
 21 |    "source": [
 22 |     "import numpy as np\n",
 23 |     "PI2 = 2 * np.pi"
 24 |    ]
 25 |   },
 26 |   {
 27 |    "cell_type": "markdown",
 28 |    "metadata": {},
 29 |    "source": [
 30 |     "## Exercise 1\n",
 31 |     "\n",
 32 |     "In this chapter, I showed how we can express the DFT and inverse DFT\n",
 33 |     "as matrix multiplications.  These operations take time proportional to\n",
 34 |     "$N^2$, where $N$ is the length of the wave array.  That is fast enough\n",
 35 |     "for many applications, but there is a faster\n",
 36 |     "algorithm, the Fast Fourier Transform (FFT), which takes time\n",
 37 |     "proportional to $N \\log N$.\n",
 38 |     "\n",
 39 |     "The key to the FFT is the Danielson-Lanczos lemma:\n",
 40 |     "\n",
 41 |     "$DFT(y)[n] = DFT(e)[n] + \\exp(-2 \\pi i n / N) DFT(o)[n]$\n",
 42 |     "\n",
 43 |     "Where $ DFT(y)[n]$ is the $n$th element of the DFT of $y$; $e$ is the even elements of $y$, and $o$ is the odd elements of $y$.\n",
 44 |     "\n",
 45 |     "This lemma suggests a recursive algorithm for the DFT:\n",
 46 |     "\n",
 47 |     "1. Given a wave array, $y$, split it into its even elements, $e$, and its odd elements, $o$.\n",
 48 |     "\n",
 49 |     "2. Compute the DFT of $e$ and $o$ by making recursive calls.\n",
 50 |     "\n",
 51 |     "3. Compute $DFT(y)$ for each value of $n$ using the Danielson-Lanczos lemma.\n",
 52 |     "\n",
 53 |     "For the base case of this recursion, you could wait until the length\n",
 54 |     "of $y$ is 1.  In that case, $DFT(y) = y$.  Or if the length of $y$\n",
 55 |     "is sufficiently small, you could compute its DFT by matrix multiplication,\n",
 56 |     "possibly using a precomputed matrix.\n",
 57 |     "\n",
 58 |     "Hint: I suggest you implement this algorithm incrementally by starting\n",
 59 |     "with a version that is not truly recursive.  In Step 2, instead of\n",
 60 |     "making a recursive call, use `dft` or `np.fft.fft`.  Get Step 3 working,\n",
 61 |     "and confirm that the results are consistent with the other\n",
 62 |     "implementations.  Then add a base case and confirm that it works.\n",
 63 |     "Finally, replace Step 2 with recursive calls.\n",
 64 |     "\n",
 65 |     "One more hint: Remember that the DFT is periodic; you might find `np.tile` useful.\n",
 66 |     "\n",
 67 |     "You can read more about the FFT at https://en.wikipedia.org/wiki/Fast_Fourier_transform."
 68 |    ]
 69 |   },
 70 |   {
 71 |    "cell_type": "markdown",
 72 |    "metadata": {},
 73 |    "source": [
 74 |     "As the test case, I'll start with a small real signal and compute its FFT:"
 75 |    ]
 76 |   },
 77 |   {
 78 |    "cell_type": "code",
 79 |    "execution_count": 2,
 80 |    "metadata": {
 81 |     "jupyter": {
 82 |      "outputs_hidden": false
 83 |     }
 84 |    },
 85 |    "outputs": [
 86 |     {
 87 |      "name": "stdout",
 88 |      "output_type": "stream",
 89 |      "text": [
 90 |       "[ 0.2+0.j  -1.2-0.2j  0.2+0.j  -1.2+0.2j]\n"
 91 |      ]
 92 |     }
 93 |    ],
 94 |    "source": [
 95 |     "ys = [-0.5, 0.1, 0.7, -0.1]\n",
 96 |     "hs = np.fft.fft(ys)\n",
 97 |     "print(hs)"
 98 |    ]
 99 |   },
100 |   {
101 |    "cell_type": "markdown",
102 |    "metadata": {},
103 |    "source": [
104 |     "Here's my implementation of DFT from the book:"
105 |    ]
106 |   },
107 |   {
108 |    "cell_type": "code",
109 |    "execution_count": 3,
110 |    "metadata": {
111 |     "jupyter": {
112 |      "outputs_hidden": false
113 |     }
114 |    },
115 |    "outputs": [],
116 |    "source": [
117 |     "def dft(ys):\n",
118 |     "    N = len(ys)\n",
119 |     "    ts = np.arange(N) / N\n",
120 |     "    freqs = np.arange(N)\n",
121 |     "    args = np.outer(ts, freqs)\n",
122 |     "    M = np.exp(1j * PI2 * args)\n",
123 |     "    amps = M.conj().transpose().dot(ys)\n",
124 |     "    return amps"
125 |    ]
126 |   },
127 |   {
128 |    "cell_type": "markdown",
129 |    "metadata": {},
130 |    "source": [
131 |     "We can confirm that this implementation gets the same result."
132 |    ]
133 |   },
134 |   {
135 |    "cell_type": "code",
136 |    "execution_count": 4,
137 |    "metadata": {
138 |     "jupyter": {
139 |      "outputs_hidden": false
140 |     }
141 |    },
142 |    "outputs": [
143 |     {
144 |      "data": {
145 |       "text/plain": [
146 |        "5.864775846765962e-16"
147 |       ]
148 |      },
149 |      "execution_count": 4,
150 |      "metadata": {},
151 |      "output_type": "execute_result"
152 |     }
153 |    ],
154 |    "source": [
155 |     "hs2 = dft(ys)\n",
156 |     "np.sum(np.abs(hs - hs2))"
157 |    ]
158 |   },
159 |   {
160 |    "cell_type": "markdown",
161 |    "metadata": {},
162 |    "source": [
163 |     "As a step toward making a recursive FFT, I'll start with a version that splits the input array and uses np.fft.fft to compute the FFT of the halves."
164 |    ]
165 |   },
166 |   {
167 |    "cell_type": "code",
168 |    "execution_count": 5,
169 |    "metadata": {
170 |     "jupyter": {
171 |      "outputs_hidden": false
172 |     }
173 |    },
174 |    "outputs": [],
175 |    "source": [
176 |     "def fft_norec(ys):\n",
177 |     "    N = len(ys)\n",
178 |     "    He = np.fft.fft(ys[::2])\n",
179 |     "    Ho = np.fft.fft(ys[1::2])\n",
180 |     "    \n",
181 |     "    ns = np.arange(N)\n",
182 |     "    W = np.exp(-1j * PI2 * ns / N)\n",
183 |     "    \n",
184 |     "    return np.tile(He, 2) + W * np.tile(Ho, 2)"
185 |    ]
186 |   },
187 |   {
188 |    "cell_type": "markdown",
189 |    "metadata": {},
190 |    "source": [
191 |     "And we get the same results:"
192 |    ]
193 |   },
194 |   {
195 |    "cell_type": "code",
196 |    "execution_count": 6,
197 |    "metadata": {
198 |     "jupyter": {
199 |      "outputs_hidden": false
200 |     }
201 |    },
202 |    "outputs": [
203 |     {
204 |      "data": {
205 |       "text/plain": [
206 |        "0.0"
207 |       ]
208 |      },
209 |      "execution_count": 6,
210 |      "metadata": {},
211 |      "output_type": "execute_result"
212 |     }
213 |    ],
214 |    "source": [
215 |     "hs3 = fft_norec(ys)\n",
216 |     "np.sum(np.abs(hs - hs3))"
217 |    ]
218 |   },
219 |   {
220 |    "cell_type": "markdown",
221 |    "metadata": {},
222 |    "source": [
223 |     "Finally, we can replace `np.fft.fft` with recursive calls, and add a base case:"
224 |    ]
225 |   },
226 |   {
227 |    "cell_type": "code",
228 |    "execution_count": 7,
229 |    "metadata": {
230 |     "jupyter": {
231 |      "outputs_hidden": false
232 |     }
233 |    },
234 |    "outputs": [],
235 |    "source": [
236 |     "def fft(ys):\n",
237 |     "    N = len(ys)\n",
238 |     "    if N == 1:\n",
239 |     "        return ys\n",
240 |     "    \n",
241 |     "    He = fft(ys[::2])\n",
242 |     "    Ho = fft(ys[1::2])\n",
243 |     "    \n",
244 |     "    ns = np.arange(N)\n",
245 |     "    W = np.exp(-1j * PI2 * ns / N)\n",
246 |     "    \n",
247 |     "    return np.tile(He, 2) + W * np.tile(Ho, 2)"
248 |    ]
249 |   },
250 |   {
251 |    "cell_type": "markdown",
252 |    "metadata": {},
253 |    "source": [
254 |     "And we get the same results:"
255 |    ]
256 |   },
257 |   {
258 |    "cell_type": "code",
259 |    "execution_count": 8,
260 |    "metadata": {
261 |     "jupyter": {
262 |      "outputs_hidden": false
263 |     }
264 |    },
265 |    "outputs": [
266 |     {
267 |      "data": {
268 |       "text/plain": [
269 |        "1.6653345369377348e-16"
270 |       ]
271 |      },
272 |      "execution_count": 8,
273 |      "metadata": {},
274 |      "output_type": "execute_result"
275 |     }
276 |    ],
277 |    "source": [
278 |     "hs4 = fft(ys)\n",
279 |     "np.sum(np.abs(hs - hs4))"
280 |    ]
281 |   },
282 |   {
283 |    "cell_type": "markdown",
284 |    "metadata": {},
285 |    "source": [
286 |     "This implementation of FFT takes time proportional to $n \\log n$.  It also takes space proportional to $n \\log n$, and it wastes some time making and copying arrays.  It can be improved to run \"in place\"; in that case, it requires no additional space, and spends less time on overhead."
287 |    ]
288 |   },
289 |   {
290 |    "cell_type": "code",
291 |    "execution_count": null,
292 |    "metadata": {
293 |     "collapsed": true,
294 |     "jupyter": {
295 |      "outputs_hidden": true
296 |     }
297 |    },
298 |    "outputs": [],
299 |    "source": []
300 |   }
301 |  ],
302 |  "metadata": {
303 |   "kernelspec": {
304 |    "display_name": "Python 3",
305 |    "language": "python",
306 |    "name": "python3"
307 |   },
308 |   "language_info": {
309 |    "codemirror_mode": {
310 |     "name": "ipython",
311 |     "version": 3
312 |    },
313 |    "file_extension": ".py",
314 |    "mimetype": "text/x-python",
315 |    "name": "python",
316 |    "nbconvert_exporter": "python",
317 |    "pygments_lexer": "ipython3",
318 |    "version": "3.8.5"
319 |   }
320 |  },
321 |  "nbformat": 4,
322 |  "nbformat_minor": 4
323 | }
324 | 


--------------------------------------------------------------------------------
/code/chirp.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2015 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import math
 11 | import numpy as np
 12 | 
 13 | import thinkdsp
 14 | import thinkplot
 15 | 
 16 | import matplotlib.pyplot as pyplot
 17 | 
 18 | import warnings
 19 | warnings.filterwarnings('ignore')
 20 | 
 21 | PI2 = np.pi * 2
 22 | 
 23 | 
 24 | def linear_chirp_evaluate(ts, low=440, high=880, amp=1.0):
 25 |     """Computes the waveform of a linear chirp and prints intermediate values.
 26 | 
 27 |     low: starting frequency
 28 |     high: ending frequency
 29 |     amp: amplitude
 30 |     """
 31 |     print('ts', ts)
 32 | 
 33 |     freqs = np.linspace(low, high, len(ts)-1)
 34 |     print('freqs', freqs)
 35 | 
 36 |     dts = np.diff(ts)
 37 |     print('dts', dts)
 38 | 
 39 |     dphis = np.insert(PI2 * freqs * dts, 0, 0)
 40 |     print('dphis', dphis)
 41 | 
 42 |     phases = np.cumsum(dphis)
 43 |     print('phases', phases)
 44 | 
 45 |     ys = amp * np.cos(phases)
 46 |     print('ys', ys)
 47 | 
 48 |     return ys
 49 | 
 50 | 
 51 | def discontinuity(num_periods=30, hamming=False):
 52 |     """Plots the spectrum of a sinusoid with/without windowing.
 53 | 
 54 |     num_periods: how many periods to compute
 55 |     hamming: boolean whether to apply Hamming window
 56 |     """
 57 |     signal = thinkdsp.SinSignal(freq=440)
 58 |     duration = signal.period * num_periods
 59 |     wave = signal.make_wave(duration)
 60 | 
 61 |     if hamming:
 62 |         wave.hamming()
 63 | 
 64 |     print(len(wave.ys), wave.ys[0], wave.ys[-1])
 65 |     spectrum = wave.make_spectrum()
 66 |     spectrum.plot(high=880)
 67 | 
 68 | 
 69 | def three_spectrums():    
 70 |     """Makes a plot showing three spectrums for a sinusoid.
 71 |     """
 72 |     thinkplot.preplot(rows=1, cols=3)
 73 | 
 74 |     pyplot.subplots_adjust(wspace=0.3, hspace=0.4, 
 75 |                            right=0.95, left=0.1,
 76 |                            top=0.95, bottom=0.1)
 77 | 
 78 |     xticks = range(0, 900, 200)
 79 | 
 80 |     thinkplot.subplot(1)
 81 |     thinkplot.config(xticks=xticks)
 82 |     discontinuity(num_periods=30, hamming=False)
 83 | 
 84 |     thinkplot.subplot(2)
 85 |     thinkplot.config(xticks=xticks, xlabel='Frequency (Hz)')
 86 |     discontinuity(num_periods=30.25, hamming=False)
 87 | 
 88 |     thinkplot.subplot(3)
 89 |     thinkplot.config(xticks=xticks)
 90 |     discontinuity(num_periods=30.25, hamming=True)
 91 | 
 92 |     thinkplot.save(root='windowing1')
 93 | 
 94 | 
 95 | def window_plot():
 96 |     """Makes a plot showing a sinusoid, hamming window, and their product.
 97 |     """
 98 |     signal = thinkdsp.SinSignal(freq=440)
 99 |     duration = signal.period * 10.25
100 |     wave1 = signal.make_wave(duration)
101 |     wave2 = signal.make_wave(duration)
102 | 
103 |     ys = np.hamming(len(wave1.ys))
104 |     ts = wave1.ts
105 |     window = thinkdsp.Wave(ys, ts, wave1.framerate)
106 | 
107 |     wave2.hamming()
108 | 
109 |     thinkplot.preplot(rows=3, cols=1)
110 | 
111 |     pyplot.subplots_adjust(wspace=0.3, hspace=0.3, 
112 |                            right=0.95, left=0.1,
113 |                            top=0.95, bottom=0.05)
114 | 
115 |     thinkplot.subplot(1)
116 |     wave1.plot()
117 |     thinkplot.config(axis=[0, duration, -1.07, 1.07])
118 | 
119 |     thinkplot.subplot(2)
120 |     window.plot()
121 |     thinkplot.config(axis=[0, duration, -1.07, 1.07])
122 | 
123 |     thinkplot.subplot(3)
124 |     wave2.plot()
125 |     thinkplot.config(axis=[0, duration, -1.07, 1.07],
126 |                      xlabel='Time (s)')
127 | 
128 |     thinkplot.save(root='windowing2')
129 | 
130 | 
131 | def chirp_spectrum():
132 |     """Plots the spectrum of a one-second one-octave linear chirp.
133 |     """
134 |     signal = thinkdsp.Chirp(start=220, end=440)
135 |     wave = signal.make_wave(duration=1)
136 | 
137 |     thinkplot.preplot(3, cols=3)
138 |     duration = 0.01
139 |     wave.segment(0, duration).plot(xfactor=1000)
140 |     thinkplot.config(ylim=[-1.05, 1.05])
141 | 
142 |     thinkplot.subplot(2)
143 |     wave.segment(0.5, duration).plot(xfactor=1000)
144 |     thinkplot.config(yticklabels='invisible',
145 |                      xlabel='Time (ms)')
146 | 
147 |     thinkplot.subplot(3)
148 |     wave.segment(0.9, duration).plot(xfactor=1000)
149 |     thinkplot.config(yticklabels='invisible')
150 | 
151 |     thinkplot.save('chirp3')
152 | 
153 | 
154 |     spectrum = wave.make_spectrum()
155 |     spectrum.plot(high=700)
156 |     thinkplot.save('chirp1',
157 |                    xlabel='Frequency (Hz)',
158 |                    ylabel='Amplitude')
159 |     
160 | 
161 | def chirp_spectrogram():
162 |     """Makes a spectrogram of a one-second one-octave linear chirp.
163 |     """
164 |     signal = thinkdsp.Chirp(start=220, end=440)
165 |     wave = signal.make_wave(duration=1, framerate=11025)
166 |     spectrogram = wave.make_spectrogram(seg_length=512)
167 | 
168 |     print('time res', spectrogram.time_res)
169 |     print('freq res', spectrogram.freq_res)
170 |     print('product', spectrogram.time_res * spectrogram.freq_res)
171 | 
172 |     spectrogram.plot(high=700)
173 | 
174 |     thinkplot.save('chirp2',
175 |                    xlabel='Time (s)',
176 |                    ylabel='Frequency (Hz)')
177 |     
178 |     
179 | def overlapping_windows():
180 |     """Makes a figure showing overlapping hamming windows.
181 |     """
182 |     n = 256
183 |     window = np.hamming(n)
184 | 
185 |     thinkplot.preplot(num=5)
186 |     start = 0
187 |     for i in range(5):
188 |         xs = np.arange(start, start+n)
189 |         thinkplot.plot(xs, window)
190 | 
191 |         start += n/2
192 | 
193 |     thinkplot.save(root='windowing3',
194 |                    xlabel='Index',
195 |                    axis=[0, 800, 0, 1.05])
196 | 
197 | 
198 | def invert_spectrogram():
199 |     """Tests Spectrogram.make_wave.
200 |     """
201 |     signal = thinkdsp.Chirp(start=220, end=440)
202 |     wave = signal.make_wave(duration=1, framerate=11025)
203 |     spectrogram = wave.make_spectrogram(seg_length=512)
204 | 
205 |     wave2 = spectrogram.make_wave()
206 | 
207 |     for i, (y1, y2) in enumerate(zip(wave.ys, wave2.ys)):
208 |         if abs(y1 - y2) > 1e-14:
209 |             print(i, y1, y2)
210 | 
211 |     
212 | def main():
213 |     chirp_spectrum()
214 |     chirp_spectrogram()
215 |     overlapping_windows()
216 |     window_plot()
217 |     three_spectrums()
218 | 
219 | 
220 | if __name__ == '__main__':
221 |     main()
222 | 


--------------------------------------------------------------------------------
/code/convolution.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import thinkdsp
 11 | import thinkplot
 12 | 
 13 | import numpy as np
 14 | import pandas as pd
 15 | 
 16 | import scipy.signal
 17 | 
 18 | PI2 = np.pi * 2
 19 | 
 20 | 
 21 | def plot_bitcoin():
 22 |     """Plot BitCoin prices and a smoothed time series.
 23 |     """
 24 |     nrows = 1625
 25 |     df = pandas.read_csv('coindesk-bpi-USD-close.csv', 
 26 |                          nrows=nrows, parse_dates=[0])
 27 |     ys = df.Close.values
 28 | 
 29 |     window = np.ones(30)
 30 |     window /= sum(window)
 31 |     smoothed = np.convolve(ys, window, mode='valid')
 32 | 
 33 |     N = len(window)
 34 |     smoothed = thinkdsp.shift_right(smoothed, N//2)
 35 | 
 36 |     thinkplot.plot(ys, color='0.7', label='daily')
 37 |     thinkplot.plot(smoothed, label='30 day average')
 38 |     thinkplot.config(xlabel='time (days)', 
 39 |                      ylabel='price',
 40 |                      xlim=[0, nrows],
 41 |                      loc='lower right')
 42 |     thinkplot.save(root='convolution1')
 43 | 
 44 | 
 45 | GRAY = "0.7"
 46 | 
 47 | def plot_facebook():
 48 |     """Plot Facebook prices and a smoothed time series.
 49 |     """
 50 |     names = ['date', 'open', 'high', 'low', 'close', 'volume']
 51 |     df = pd.read_csv('fb_1.csv', header=0, names=names, parse_dates=[0])
 52 |     close = df.close.values[::-1]
 53 |     dates = df.date.values[::-1]
 54 |     days = (dates - dates[0]) / np.timedelta64(1,'D')
 55 | 
 56 |     M = 30
 57 |     window = np.ones(M)
 58 |     window /= sum(window)
 59 |     smoothed = np.convolve(close, window, mode='valid')
 60 |     smoothed_days = days[M//2: len(smoothed) + M//2]
 61 |     
 62 |     thinkplot.plot(days, close, color=GRAY, label='daily close')
 63 |     thinkplot.plot(smoothed_days, smoothed, label='30 day average')
 64 |     
 65 |     last = days[-1]
 66 |     thinkplot.config(xlabel='Time (days)', 
 67 |                      ylabel='Price ($)',
 68 |                      xlim=[-7, last+7],
 69 |                      legend=True,
 70 |                      loc='lower right')
 71 |     thinkplot.save(root='convolution1')
 72 | 
 73 | 
 74 | def plot_boxcar():
 75 |     """Makes a plot showing the effect of convolution with a boxcar window.
 76 |     """
 77 |     # start with a square signal
 78 |     signal = thinkdsp.SquareSignal(freq=440)
 79 |     wave = signal.make_wave(duration=1, framerate=44100)
 80 | 
 81 |     # and a boxcar window
 82 |     window = np.ones(11)
 83 |     window /= sum(window)
 84 | 
 85 |     # select a short segment of the wave
 86 |     segment = wave.segment(duration=0.01)
 87 | 
 88 |     # and pad with window out to the length of the array
 89 |     N = len(segment)
 90 |     padded = thinkdsp.zero_pad(window, N)
 91 | 
 92 |     # compute the first element of the smoothed signal
 93 |     prod = padded * segment.ys
 94 |     print(sum(prod))
 95 | 
 96 |     # compute the rest of the smoothed signal
 97 |     smoothed = np.zeros(N)
 98 |     rolled = padded
 99 |     for i in range(N):
100 |         smoothed[i] = sum(rolled * segment.ys)
101 |         rolled = np.roll(rolled, 1)
102 | 
103 |     # plot the results
104 |     segment.plot(color=GRAY)
105 |     smooth = thinkdsp.Wave(smoothed, framerate=wave.framerate)
106 |     smooth.plot()
107 |     thinkplot.config(xlabel='Time(s)', ylim=[-1.05, 1.05])
108 |     thinkplot.save(root='convolution2')
109 | 
110 |     # compute the same thing using np.convolve
111 |     segment.plot(color=GRAY)
112 |     ys = np.convolve(segment.ys, window, mode='valid')
113 |     smooth2 = thinkdsp.Wave(ys, framerate=wave.framerate)
114 |     smooth2.plot()
115 |     thinkplot.config(xlabel='Time(s)', ylim=[-1.05, 1.05])
116 |     thinkplot.save(root='convolution3')
117 | 
118 |     # plot the spectrum before and after smoothing
119 |     spectrum = wave.make_spectrum()
120 |     spectrum.plot(color=GRAY)
121 | 
122 |     ys = np.convolve(wave.ys, window, mode='same')
123 |     smooth = thinkdsp.Wave(ys, framerate=wave.framerate)
124 |     spectrum2 = smooth.make_spectrum()
125 |     spectrum2.plot()
126 |     thinkplot.config(xlabel='Frequency (Hz)',
127 |                      ylabel='Amplitude',
128 |                      xlim=[0, 22050])
129 |     thinkplot.save(root='convolution4')
130 | 
131 |     # plot the ratio of the original and smoothed spectrum
132 |     amps = spectrum.amps
133 |     amps2 = spectrum2.amps
134 |     ratio = amps2 / amps    
135 |     ratio[amps<560] = 0
136 |     thinkplot.plot(ratio)
137 | 
138 |     thinkplot.config(xlabel='Frequency (Hz)',
139 |                      ylabel='Amplitude ratio',
140 |                      xlim=[0, 22050])
141 |     thinkplot.save(root='convolution5')
142 | 
143 | 
144 |     # plot the same ratio along with the FFT of the window
145 |     padded = thinkdsp.zero_pad(window, len(wave))
146 |     dft_window = np.fft.rfft(padded)
147 | 
148 |     thinkplot.plot(abs(dft_window), color=GRAY, label='DFT(window)')
149 |     thinkplot.plot(ratio, label='amplitude ratio')
150 | 
151 |     thinkplot.config(xlabel='Frequency (Hz)',
152 |                      ylabel='Amplitude ratio',
153 |                      xlim=[0, 22050])
154 |     thinkplot.save(root='convolution6')
155 | 
156 |     
157 | def plot_gaussian():
158 |     """Makes a plot showing the effect of convolution with a boxcar window.
159 |     """
160 |     # start with a square signal
161 |     signal = thinkdsp.SquareSignal(freq=440)
162 |     wave = signal.make_wave(duration=1, framerate=44100)
163 |     spectrum = wave.make_spectrum()
164 | 
165 |     # and a boxcar window
166 |     boxcar = np.ones(11)
167 |     boxcar /= sum(boxcar)
168 | 
169 |     # and a gaussian window
170 |     gaussian = scipy.signal.gaussian(M=11, std=2)
171 |     gaussian /= sum(gaussian)
172 | 
173 |     thinkplot.preplot(2)
174 |     thinkplot.plot(boxcar, label='boxcar')
175 |     thinkplot.plot(gaussian, label='Gaussian')
176 |     thinkplot.config(xlabel='Index', legend=True)
177 |     thinkplot.save(root='convolution7')
178 | 
179 |     ys = np.convolve(wave.ys, gaussian, mode='same')
180 |     smooth = thinkdsp.Wave(ys, framerate=wave.framerate)
181 |     spectrum2 = smooth.make_spectrum()
182 | 
183 |     # plot the ratio of the original and smoothed spectrum
184 |     amps = spectrum.amps
185 |     amps2 = spectrum2.amps
186 |     ratio = amps2 / amps    
187 |     ratio[amps<560] = 0
188 | 
189 |     # plot the same ratio along with the FFT of the window
190 |     padded = thinkdsp.zero_pad(gaussian, len(wave))
191 |     dft_gaussian = np.fft.rfft(padded)
192 | 
193 |     thinkplot.plot(abs(dft_gaussian), color=GRAY, label='Gaussian filter')
194 |     thinkplot.plot(ratio, label='amplitude ratio')
195 | 
196 |     thinkplot.config(xlabel='Frequency (Hz)',
197 |                      ylabel='Amplitude ratio',
198 |                      xlim=[0, 22050])
199 |     thinkplot.save(root='convolution8')
200 | 
201 | 
202 | def fft_convolve(signal, window):
203 |     """Computes convolution using FFT.
204 |     """
205 |     fft_signal = np.fft.fft(signal)
206 |     fft_window = np.fft.fft(window)
207 |     return np.fft.ifft(fft_signal * fft_window)
208 | 
209 | 
210 | def fft_autocorr(signal):
211 |     """Computes the autocorrelation function using FFT.
212 |     """
213 |     N = len(signal)
214 |     signal = thinkdsp.zero_pad(signal, 2*N)
215 |     window = np.flipud(signal)
216 | 
217 |     corrs = fft_convolve(signal, window)
218 |     corrs = np.roll(corrs, N//2+1)[:N]
219 |     return corrs
220 | 
221 | 
222 | def plot_fft_convolve():
223 |     """Makes a plot showing that FFT-based convolution works.
224 |     """
225 |     names = ['date', 'open', 'high', 'low', 'close', 'volume']
226 |     df = pd.read_csv('fb_1.csv',
227 |                      header=0, names=names, parse_dates=[0])
228 |     close = df.close.values[::-1]
229 | 
230 |     # compute a 30-day average using np.convolve
231 |     window = scipy.signal.gaussian(M=30, std=6)
232 |     window /= window.sum()
233 |     smoothed = np.convolve(close, window, mode='valid')
234 | 
235 |     # compute the same thing using fft_convolve
236 |     N = len(close)
237 |     padded = thinkdsp.zero_pad(window, N)
238 | 
239 |     M = len(window)
240 |     smoothed4 = fft_convolve(close, padded)[M-1:]
241 | 
242 |     # check for the biggest difference
243 |     diff = smoothed - smoothed4
244 |     print(max(abs(diff)))
245 | 
246 |     # compute autocorrelation using np.correlate
247 |     corrs = np.correlate(close, close, mode='same')
248 |     corrs2 = fft_autocorr(close)
249 | 
250 |     # check for the biggest difference
251 |     diff = corrs - corrs2
252 |     print(max(abs(diff)))
253 | 
254 |     # plot the results
255 |     lags = np.arange(N) - N//2
256 |     thinkplot.plot(lags, corrs, color=GRAY, linewidth=7, label='np.convolve')
257 |     thinkplot.plot(lags, corrs2.real, linewidth=2, label='fft_convolve')
258 |     thinkplot.config(xlabel='Lag', 
259 |                      ylabel='Correlation', 
260 |                      xlim=[-N//2, N//2])
261 |     thinkplot.save(root='convolution9')
262 | 
263 | 
264 | def main():
265 |     plot_facebook()
266 |     plot_boxcar()
267 |     plot_gaussian()
268 |     plot_fft_convolve()
269 |     #plot_bitcoin()
270 | 
271 | 
272 | if __name__ == '__main__':
273 |     main()
274 | 


--------------------------------------------------------------------------------
/code/dct.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import numpy as np
 11 | 
 12 | import thinkdsp
 13 | import thinkplot
 14 | 
 15 | PI2 = np.pi * 2
 16 | 
 17 | 
 18 | def synthesize1(amps, fs, ts):
 19 |     """Synthesize a mixture of cosines with given amps and fs.
 20 | 
 21 |     amps: amplitudes
 22 |     fs: frequencies in Hz
 23 |     ts: times to evaluate the signal
 24 | 
 25 |     returns: wave array
 26 |     """
 27 |     components = [thinkdsp.CosSignal(freq, amp)
 28 |                   for amp, freq in zip(amps, fs)]
 29 |     signal = thinkdsp.SumSignal(*components)
 30 | 
 31 |     ys = signal.evaluate(ts)
 32 |     return ys
 33 | 
 34 | 
 35 | def synthesize2(amps, fs, ts):
 36 |     """Synthesize a mixture of cosines with given amps and fs.
 37 | 
 38 |     amps: amplitudes
 39 |     fs: frequencies in Hz
 40 |     ts: times to evaluate the signal
 41 | 
 42 |     returns: wave array
 43 |     """
 44 |     args = np.outer(ts, fs)
 45 |     M = np.cos(PI2 * args)
 46 |     ys = np.dot(M, amps)
 47 |     return ys
 48 | 
 49 | 
 50 | def analyze1(ys, fs, ts):
 51 |     """Analyze a mixture of cosines and return amplitudes.
 52 | 
 53 |     Works for the general case where M is not orthogonal.
 54 | 
 55 |     ys: wave array
 56 |     fs: frequencies in Hz
 57 |     ts: times where the signal was evaluated    
 58 | 
 59 |     returns: vector of amplitudes
 60 |     """
 61 |     args = np.outer(ts, fs)
 62 |     M = np.cos(PI2 * args)
 63 |     amps = np.linalg.solve(M, ys)
 64 |     return amps
 65 | 
 66 | 
 67 | def analyze2(ys, fs, ts):
 68 |     """Analyze a mixture of cosines and return amplitudes.
 69 | 
 70 |     Assumes that fs and ts are chosen so that M is orthogonal.
 71 | 
 72 |     ys: wave array
 73 |     fs: frequencies in Hz
 74 |     ts: times where the signal was evaluated    
 75 | 
 76 |     returns: vector of amplitudes
 77 |     """
 78 |     args = np.outer(ts, fs)
 79 |     M = np.cos(PI2 * args)
 80 |     amps = np.dot(M, ys) / 2
 81 |     return amps
 82 | 
 83 | 
 84 | def dct_iv(ys):
 85 |     """Computes DCT-IV.
 86 | 
 87 |     ys: wave array
 88 | 
 89 |     returns: vector of amplitudes
 90 |     """
 91 |     N = len(ys)
 92 |     ts = (0.5 + np.arange(N)) / N
 93 |     fs = (0.5 + np.arange(N)) / 2
 94 |     args = np.outer(ts, fs)
 95 |     M = np.cos(PI2 * args)
 96 |     amps = np.dot(M, ys) / 2
 97 |     return amps
 98 | 
 99 | 
100 | def synthesize_example():
101 |     """Synthesizes a sum of sinusoids and plays it.
102 |     """
103 |     amps = np.array([0.6, 0.25, 0.1, 0.05])
104 |     fs = [100, 200, 300, 400]
105 | 
106 |     framerate = 11025
107 |     ts = np.linspace(0, 1, 11025)
108 |     ys = synthesize2(amps, fs, ts)
109 |     wave = thinkdsp.Wave(ys, framerate)
110 |     wave.normalize()
111 |     wave.apodize()
112 |     wave.play()
113 | 
114 |     n = len(fs)
115 |     amps2 = analyze1(ys[:n], fs, ts[:n])
116 |     print(amps)
117 |     print(amps2)
118 | 
119 | 
120 | def test1():
121 |     amps = np.array([0.6, 0.25, 0.1, 0.05])
122 |     N = 4.0
123 |     time_unit = 0.001
124 |     ts = np.arange(N) / N * time_unit
125 |     max_freq = N / time_unit / 2
126 |     fs = np.arange(N) / N * max_freq
127 |     args = np.outer(ts, fs)
128 |     M = np.cos(PI2 * args)
129 |     return M
130 | 
131 | 
132 | def test2():
133 |     """
134 |     """
135 |     amps = np.array([0.6, 0.25, 0.1, 0.05])
136 |     N = 4.0
137 |     ts = (0.5 + np.arange(N)) / N
138 |     fs = (0.5 + np.arange(N)) / 2
139 |     print('amps', amps)
140 |     print('ts', ts)
141 |     print('fs', fs)
142 |     ys = synthesize2(amps, fs, ts)
143 |     amps2 = analyze2(ys, fs, ts)
144 |     print('amps', amps)
145 |     print('amps2', amps2)
146 | 
147 | 
148 | def test_dct():
149 |     """
150 |     """
151 |     amps = np.array([0.6, 0.25, 0.1, 0.05])
152 |     N = 4.0
153 |     ts = (0.5 + np.arange(N)) / N
154 |     fs = (0.5 + np.arange(N)) / 2
155 |     ys = synthesize2(amps, fs, ts)
156 | 
157 |     amps2 = dct_iv(ys)
158 |     print('amps', amps)
159 |     print('amps2', amps2)
160 | 
161 | 
162 | def dct_plot():
163 |     signal = thinkdsp.TriangleSignal(freq=400)
164 |     wave = signal.make_wave(duration=1.0, framerate=10000)
165 |     dct = wave.make_dct()
166 |     dct.plot()
167 |     thinkplot.config(xlabel='Frequency (Hz)', ylabel='DCT')
168 |     thinkplot.save(root='dct1',
169 |                    formats=['pdf', 'eps'])
170 | 
171 | 
172 | def main():
173 |     np.set_printoptions(precision=3, suppress=True)
174 | 
175 |     test1()
176 |     test2()
177 |     dct_plot()
178 | 
179 | 
180 | if __name__ == '__main__':
181 |     main()
182 | 


--------------------------------------------------------------------------------
/code/dft.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import math
 11 | import numpy
 12 | 
 13 | import thinkdsp
 14 | import thinkplot
 15 | 
 16 | PI2 = np.pi * 2
 17 | 
 18 | 
 19 | def synthesize1(amps, freqs, ts):
 20 |     """Synthesize a mixture of complex sinusoids with given amps and freqs.
 21 | 
 22 |     amps: amplitudes
 23 |     freqs: frequencies in Hz
 24 |     ts: times to evaluate the signal
 25 | 
 26 |     returns: wave array
 27 |     """
 28 |     components = [thinkdsp.ComplexSinusoid(freq, amp)
 29 |                   for amp, freq in zip(amps, freqs)]
 30 |     signal = thinkdsp.SumSignal(*components)
 31 | 
 32 |     ys = signal.evaluate(ts)
 33 |     return ys
 34 | 
 35 | 
 36 | def synthesize2(amps, freqs, ts):
 37 |     """Synthesize a mixture of cosines with given amps and freqs.
 38 | 
 39 |     amps: amplitudes
 40 |     freqs: frequencies in Hz
 41 |     ts: times to evaluate the signal
 42 | 
 43 |     returns: wave array
 44 |     """
 45 |     i = complex(0, 1)
 46 |     args = numpy.outer(ts, freqs)
 47 |     M = numpy.exp(i * PI2 * args)
 48 |     ys = numpy.dot(M, amps)
 49 |     return ys
 50 | 
 51 | 
 52 | def analyze1(ys, freqs, ts):
 53 |     """Analyze a mixture of cosines and return amplitudes.
 54 | 
 55 |     Works for the general case where M is not orthogonal.
 56 | 
 57 |     ys: wave array
 58 |     freqs: frequencies in Hz
 59 |     ts: times where the signal was evaluated    
 60 | 
 61 |     returns: vector of amplitudes
 62 |     """
 63 |     args = numpy.outer(ts, freqs)
 64 |     M = numpy.exp(i * PI2 * args)
 65 |     amps = numpy.linalg.solve(M, ys)
 66 |     return amps
 67 | 
 68 | 
 69 | def analyze2(ys, freqs, ts):
 70 |     """Analyze a mixture of cosines and return amplitudes.
 71 | 
 72 |     Assumes that freqs and ts are chosen so that M is orthogonal.
 73 | 
 74 |     ys: wave array
 75 |     freqs: frequencies in Hz
 76 |     ts: times where the signal was evaluated    
 77 | 
 78 |     returns: vector of amplitudes
 79 |     """
 80 | 
 81 | def analyze2(ys, freqs, ts):
 82 |     args = numpy.outer(ts, freqs)
 83 |     M = numpy.exp(i * PI2 * args)
 84 |     amps = M.conj().transpose().dot(ys) / N
 85 |     return amps
 86 | 
 87 | 
 88 | def dft(ys):
 89 |     i = complex(0, 1)
 90 |     N = len(ys)
 91 |     ts = numpy.arange(N) / N
 92 |     freqs = numpy.arange(N)
 93 |     args = numpy.outer(ts, freqs)
 94 |     M = numpy.exp(i * PI2 * args)
 95 |     amps = M.conj().transpose().dot(ys)
 96 |     return amps
 97 | 
 98 | 
 99 | def idft(amps):
100 |     ys = dft(amps) / N
101 |     return ys
102 | 
103 | 
104 | def make_figures():
105 |     """Makes figures showing complex signals.
106 |     """
107 |     amps = numpy.array([0.6, 0.25, 0.1, 0.05])
108 |     freqs = [100, 200, 300, 400]
109 |     framerate = 11025
110 | 
111 |     ts = numpy.linspace(0, 1, framerate)
112 |     ys = synthesize1(amps, freqs, ts)
113 |     print(ys)
114 |     
115 |     thinkplot.preplot(2)
116 |     n = framerate / 25
117 |     thinkplot.plot(ts[:n], ys[:n].real, label='real')
118 |     thinkplot.plot(ts[:n], ys[:n].imag, label='imag')
119 |     thinkplot.save(root='dft1',
120 |                    xlabel='Time (s)',
121 |                    ylim=[-1.05, 1.05],
122 |                    loc='lower right')
123 | 
124 |     ys = synthesize2(amps, freqs, ts)
125 | 
126 |     amps2 = amps * numpy.exp(1.5j)
127 |     ys2 = synthesize2(amps2, freqs, ts)
128 | 
129 |     thinkplot.preplot(2)
130 |     thinkplot.plot(ts[:n], ys.real[:n], label=r'$\phi_0 = 0
#39;)
131 |     thinkplot.plot(ts[:n], ys2.real[:n], label=r'$\phi_0 = 1.5
#39;)
132 |     thinkplot.save(root='dft2',
133 |                    xlabel='Time (s)', 
134 |                    ylim=[-1.05, 1.05],
135 |                    loc='lower right')
136 | 
137 | 
138 |     framerate = 10000
139 |     signal = thinkdsp.SawtoothSignal(freq=500)
140 |     wave = signal.make_wave(duration=0.1, framerate=framerate)
141 |     hs = dft(wave.ys)
142 |     amps = numpy.absolute(hs)
143 | 
144 |     N = len(hs)
145 |     fs = numpy.arange(N) * framerate / N
146 |     thinkplot.plot(fs, amps)
147 |     thinkplot.save(root='dft3',
148 |                    xlabel='Frequency (Hz)', 
149 |                    ylabel='Amplitude',
150 |                    legend=False)
151 | 
152 | 
153 | 
154 | def main():
155 |     numpy.set_printoptions(precision=3, suppress=True)
156 |     make_figures()
157 | 
158 | 
159 | if __name__ == '__main__':
160 |     main()
161 | 


--------------------------------------------------------------------------------
/code/dft_example.ipynb:
--------------------------------------------------------------------------------
  1 | {
  2 |  "cells": [
  3 |   {
  4 |    "cell_type": "markdown",
  5 |    "metadata": {},
  6 |    "source": [
  7 |     "# Implementing DFT\n",
  8 |     "\n",
  9 |     "Copyright 2019 Allen Downey, [MIT License](http://opensource.org/licenses/MIT)"
 10 |    ]
 11 |   },
 12 |   {
 13 |    "cell_type": "code",
 14 |    "execution_count": 1,
 15 |    "metadata": {},
 16 |    "outputs": [],
 17 |    "source": [
 18 |     "import numpy as np"
 19 |    ]
 20 |   },
 21 |   {
 22 |    "cell_type": "markdown",
 23 |    "metadata": {},
 24 |    "source": [
 25 |     "Let's start with a known result.  The DFT of an impulse is a constant."
 26 |    ]
 27 |   },
 28 |   {
 29 |    "cell_type": "code",
 30 |    "execution_count": 2,
 31 |    "metadata": {},
 32 |    "outputs": [],
 33 |    "source": [
 34 |     "N = 4\n",
 35 |     "x = [1, 0, 0, 0]"
 36 |    ]
 37 |   },
 38 |   {
 39 |    "cell_type": "code",
 40 |    "execution_count": 3,
 41 |    "metadata": {},
 42 |    "outputs": [
 43 |     {
 44 |      "data": {
 45 |       "text/plain": [
 46 |        "array([1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j])"
 47 |       ]
 48 |      },
 49 |      "execution_count": 3,
 50 |      "metadata": {},
 51 |      "output_type": "execute_result"
 52 |     }
 53 |    ],
 54 |    "source": [
 55 |     "np.fft.fft(x)"
 56 |    ]
 57 |   },
 58 |   {
 59 |    "cell_type": "markdown",
 60 |    "metadata": {},
 61 |    "source": [
 62 |     "### Literal translation\n",
 63 |     "\n",
 64 |     "The usual way the DFT is expressed is as a summation.  Following the notation on [Wikipedia](https://en.wikipedia.org/wiki/Discrete_Fourier_transform):\n",
 65 |     "\n",
 66 |     "$ X_k = \\sum_{n=0}^N x_n \\cdot e^{-2 \\pi i n k / N} $\n",
 67 |     "\n",
 68 |     "Here's a straightforward translation of that formula into Python."
 69 |    ]
 70 |   },
 71 |   {
 72 |    "cell_type": "code",
 73 |    "execution_count": 4,
 74 |    "metadata": {},
 75 |    "outputs": [],
 76 |    "source": [
 77 |     "pi = np.pi\n",
 78 |     "exp = np.exp"
 79 |    ]
 80 |   },
 81 |   {
 82 |    "cell_type": "code",
 83 |    "execution_count": 5,
 84 |    "metadata": {},
 85 |    "outputs": [
 86 |     {
 87 |      "data": {
 88 |       "text/plain": [
 89 |        "(1+0j)"
 90 |       ]
 91 |      },
 92 |      "execution_count": 5,
 93 |      "metadata": {},
 94 |      "output_type": "execute_result"
 95 |     }
 96 |    ],
 97 |    "source": [
 98 |     "k = 0\n",
 99 |     "sum(x[n] * exp(-2j * pi * k * n / N) for n in range(N))"
100 |    ]
101 |   },
102 |   {
103 |    "cell_type": "markdown",
104 |    "metadata": {},
105 |    "source": [
106 |     "Wrapping this code in a function makes the roles of `k` and `n` clearer, where `k` is a free parameter and `n` is the bound variable of the summation."
107 |    ]
108 |   },
109 |   {
110 |    "cell_type": "code",
111 |    "execution_count": 6,
112 |    "metadata": {},
113 |    "outputs": [],
114 |    "source": [
115 |     "def dft_k(x, k):\n",
116 |     "    return sum(x[n] * exp(-2j * pi * k * n / N) for n in range(N))"
117 |    ]
118 |   },
119 |   {
120 |    "cell_type": "markdown",
121 |    "metadata": {},
122 |    "source": [
123 |     "Of course, we usually we compute $X$ all at once, so we can wrap this function in another function:"
124 |    ]
125 |   },
126 |   {
127 |    "cell_type": "code",
128 |    "execution_count": 7,
129 |    "metadata": {},
130 |    "outputs": [],
131 |    "source": [
132 |     "def dft(x):\n",
133 |     "    N = len(x)\n",
134 |     "    X = [dft_k(x, k) for k in range(N)]\n",
135 |     "    return X"
136 |    ]
137 |   },
138 |   {
139 |    "cell_type": "code",
140 |    "execution_count": 8,
141 |    "metadata": {},
142 |    "outputs": [
143 |     {
144 |      "data": {
145 |       "text/plain": [
146 |        "[(1+0j), (1+0j), (1+0j), (1+0j)]"
147 |       ]
148 |      },
149 |      "execution_count": 8,
150 |      "metadata": {},
151 |      "output_type": "execute_result"
152 |     }
153 |    ],
154 |    "source": [
155 |     "dft(x)"
156 |    ]
157 |   },
158 |   {
159 |    "cell_type": "markdown",
160 |    "metadata": {},
161 |    "source": [
162 |     "And the results check out."
163 |    ]
164 |   },
165 |   {
166 |    "cell_type": "markdown",
167 |    "metadata": {},
168 |    "source": [
169 |     "### DFT as a matrix operation\n",
170 |     "\n",
171 |     "It is also common to express the DFT as a [matrix operation](https://en.wikipedia.org/wiki/DFT_matrix):\n",
172 |     "\n",
173 |     "$ X = W x $\n",
174 |     "\n",
175 |     "with \n",
176 |     "\n",
177 |     "$ W_{j, k} = \\omega^{j k} $\n",
178 |     "\n",
179 |     "and\n",
180 |     "\n",
181 |     "$ \\omega = e^{-2 \\pi i / N}$\n",
182 |     "\n",
183 |     "If we recognize the construction of $W$ as an outer product, we can use `np.outer` to compute it.\n",
184 |     "\n",
185 |     "Here's an implementation of DFT using outer product to construct the DFT matrix, and dot product to compute the DFT."
186 |    ]
187 |   },
188 |   {
189 |    "cell_type": "code",
190 |    "execution_count": 9,
191 |    "metadata": {},
192 |    "outputs": [],
193 |    "source": [
194 |     "def dft(x):\n",
195 |     "    N = len(x)\n",
196 |     "    ks = range(N)\n",
197 |     "    args = -2j * pi * np.outer(ks, ks) / N\n",
198 |     "    W = exp(args)\n",
199 |     "    X = W.dot(x)\n",
200 |     "    return X"
201 |    ]
202 |   },
203 |   {
204 |    "cell_type": "markdown",
205 |    "metadata": {},
206 |    "source": [
207 |     "And the results check out."
208 |    ]
209 |   },
210 |   {
211 |    "cell_type": "code",
212 |    "execution_count": 10,
213 |    "metadata": {
214 |     "scrolled": true
215 |    },
216 |    "outputs": [
217 |     {
218 |      "data": {
219 |       "text/plain": [
220 |        "array([1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j])"
221 |       ]
222 |      },
223 |      "execution_count": 10,
224 |      "metadata": {},
225 |      "output_type": "execute_result"
226 |     }
227 |    ],
228 |    "source": [
229 |     "dft(x)"
230 |    ]
231 |   },
232 |   {
233 |    "cell_type": "markdown",
234 |    "metadata": {},
235 |    "source": [
236 |     "### Implementing FFT\n",
237 |     "\n",
238 |     "Finally, we can implement the FFT by translating from math notation:\n",
239 |     "\n",
240 |     "$ X_k = E_k + e^{-2 \\pi i k / N} O_k $\n",
241 |     "\n",
242 |     "Where $E$ is the FFT of the even elements of $x$ and $O$ is the DFT of the odd elements of $x$.\n",
243 |     "\n",
244 |     "Here's what that looks like in code."
245 |    ]
246 |   },
247 |   {
248 |    "cell_type": "code",
249 |    "execution_count": 11,
250 |    "metadata": {},
251 |    "outputs": [],
252 |    "source": [
253 |     "def fft(x):\n",
254 |     "    N = len(x)\n",
255 |     "    if N == 1:\n",
256 |     "        return x\n",
257 |     "    \n",
258 |     "    E = fft(x[::2])\n",
259 |     "    O = fft(x[1::2])\n",
260 |     "    \n",
261 |     "    ks = np.arange(N)\n",
262 |     "    args = -2j * pi * ks / N\n",
263 |     "    W = np.exp(args)\n",
264 |     "    \n",
265 |     "    return np.tile(E, 2) + W * np.tile(O, 2)"
266 |    ]
267 |   },
268 |   {
269 |    "cell_type": "markdown",
270 |    "metadata": {},
271 |    "source": [
272 |     "The length of $E$ and $O$ is half the length of $W$, so I use `np.tile` to double them up.\n",
273 |     "\n",
274 |     "And the results check out."
275 |    ]
276 |   },
277 |   {
278 |    "cell_type": "code",
279 |    "execution_count": 12,
280 |    "metadata": {},
281 |    "outputs": [
282 |     {
283 |      "data": {
284 |       "text/plain": [
285 |        "array([1.+0.j, 1.+0.j, 1.+0.j, 1.+0.j])"
286 |       ]
287 |      },
288 |      "execution_count": 12,
289 |      "metadata": {},
290 |      "output_type": "execute_result"
291 |     }
292 |    ],
293 |    "source": [
294 |     "fft(x)"
295 |    ]
296 |   },
297 |   {
298 |    "cell_type": "code",
299 |    "execution_count": null,
300 |    "metadata": {},
301 |    "outputs": [],
302 |    "source": []
303 |   }
304 |  ],
305 |  "metadata": {
306 |   "anaconda-cloud": {},
307 |   "kernelspec": {
308 |    "display_name": "Python 3",
309 |    "language": "python",
310 |    "name": "python3"
311 |   },
312 |   "language_info": {
313 |    "codemirror_mode": {
314 |     "name": "ipython",
315 |     "version": 3
316 |    },
317 |    "file_extension": ".py",
318 |    "mimetype": "text/x-python",
319 |    "name": "python",
320 |    "nbconvert_exporter": "python",
321 |    "pygments_lexer": "ipython3",
322 |    "version": "3.6.10"
323 |   }
324 |  },
325 |  "nbformat": 4,
326 |  "nbformat_minor": 4
327 | }
328 | 


--------------------------------------------------------------------------------
/code/diff_int.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import numpy as np
 11 | import pandas as pd
 12 | 
 13 | import thinkdsp
 14 | import thinkplot
 15 | 
 16 | PI2 = np.pi * 2
 17 | GRAY = '0.7'
 18 | 
 19 | 
 20 | def plot_wave_and_spectrum(wave, root):
 21 |     """Makes a plot showing a wave and its spectrum.
 22 | 
 23 |     wave: Wave object
 24 |     root: string used to generate filenames
 25 |     """
 26 |     thinkplot.preplot(cols=2)
 27 |     wave.plot()
 28 |     thinkplot.config(xlabel='Time (days)',
 29 |                      ylabel='Price ($)')
 30 | 
 31 |     thinkplot.subplot(2)
 32 |     spectrum = wave.make_spectrum()
 33 |     print(spectrum.estimate_slope())
 34 |     spectrum.plot()
 35 |     thinkplot.config(xlabel='Frequency (1/days)',
 36 |                      ylabel='Amplitude',
 37 |                      xlim=[0, spectrum.fs[-1]],
 38 |                      xscale='log',
 39 |                      yscale='log')
 40 | 
 41 |     thinkplot.save(root=root)
 42 | 
 43 | 
 44 | def plot_sawtooth_and_spectrum(wave, root):
 45 |     """Makes a plot showing a sawtoothwave and its spectrum.
 46 |     """
 47 |     thinkplot.preplot(cols=2)
 48 |     wave.plot()
 49 |     thinkplot.config(xlabel='Time (s)')
 50 | 
 51 |     thinkplot.subplot(2)
 52 |     spectrum = wave.make_spectrum()
 53 |     spectrum.plot()
 54 |     thinkplot.config(xlabel='Frequency (Hz)',
 55 |                      #ylabel='Amplitude',
 56 |                      xlim=[0, spectrum.fs[-1]])
 57 | 
 58 |     thinkplot.save(root)
 59 | 
 60 | 
 61 | def make_filter(window, wave):
 62 |     """Computes the filter that corresponds to a window.
 63 |     
 64 |     window: NumPy array
 65 |     wave: wave used to choose the length and framerate
 66 |     
 67 |     returns: new Spectrum
 68 |     """
 69 |     padded = thinkdsp.zero_pad(window, len(wave))
 70 |     window_wave = thinkdsp.Wave(padded, framerate=wave.framerate)
 71 |     window_spectrum = window_wave.make_spectrum()
 72 |     return window_spectrum
 73 | 
 74 | 
 75 | def plot_filters(close):
 76 |     """Plots the filter that corresponds to diff, deriv, and integral.
 77 |     """
 78 |     thinkplot.preplot(3, cols=2)
 79 | 
 80 |     diff_window = np.array([1.0, -1.0])
 81 |     diff_filter = make_filter(diff_window, close)
 82 |     diff_filter.plot(label='diff')
 83 | 
 84 |     deriv_filter = close.make_spectrum()
 85 |     deriv_filter.hs = PI2 * 1j * deriv_filter.fs
 86 |     deriv_filter.plot(label='derivative')
 87 | 
 88 |     thinkplot.config(xlabel='Frequency (1/day)',
 89 |                      ylabel='Amplitude ratio',
 90 |                      loc='upper left')
 91 | 
 92 |     thinkplot.subplot(2)
 93 |     integ_filter = deriv_filter.copy()
 94 |     integ_filter.hs = 1 / (PI2 * 1j * integ_filter.fs)
 95 | 
 96 |     integ_filter.plot(label='integral')
 97 |     thinkplot.config(xlabel='Frequency (1/day)',
 98 |                      ylabel='Amplitude ratio', 
 99 |                      yscale='log')
100 |     thinkplot.save('diff_int3')
101 | 
102 | 
103 | def plot_diff_deriv(close):
104 |     change = thinkdsp.Wave(np.diff(close.ys), framerate=1)
105 | 
106 |     deriv_spectrum = close.make_spectrum().differentiate()
107 |     deriv = deriv_spectrum.make_wave()
108 | 
109 |     low, high = 0, 50
110 |     thinkplot.preplot(2)
111 |     thinkplot.plot(change.ys[low:high], label='diff')
112 |     thinkplot.plot(deriv.ys[low:high], label='derivative')
113 | 
114 |     thinkplot.config(xlabel='Time (day)', ylabel='Price change ($)')
115 |     thinkplot.save('diff_int4')
116 | 
117 |     
118 | def plot_integral(close):
119 | 
120 |     deriv_spectrum = close.make_spectrum().differentiate()
121 | 
122 |     integ_spectrum = deriv_spectrum.integrate()
123 |     print(integ_spectrum.hs[0])
124 |     integ_spectrum.hs[0] = 0
125 |     
126 |     thinkplot.preplot(2)
127 |     integ_wave = integ_spectrum.make_wave()
128 |     close.plot(label='closing prices')
129 |     integ_wave.plot(label='integrated derivative')
130 |     thinkplot.config(xlabel='Time (day)', ylabel='Price ($)', 
131 |                      legend=True, loc='upper left')
132 | 
133 |     thinkplot.save('diff_int5')
134 | 
135 |     
136 | def plot_ratios(in_wave, out_wave):
137 | 
138 |     # compare filters for cumsum and integration
139 |     diff_window = np.array([1.0, -1.0])
140 |     padded = thinkdsp.zero_pad(diff_window, len(in_wave))
141 |     diff_wave = thinkdsp.Wave(padded, framerate=in_wave.framerate)
142 |     diff_filter = diff_wave.make_spectrum()
143 |     
144 |     cumsum_filter = diff_filter.copy()
145 |     cumsum_filter.hs = 1 / cumsum_filter.hs
146 |     cumsum_filter.plot(label='cumsum filter', color=GRAY, linewidth=7)
147 |     
148 |     integ_filter = cumsum_filter.copy()
149 |     integ_filter.hs = integ_filter.framerate / (PI2 * 1j * integ_filter.fs)
150 |     integ_filter.plot(label='integral filter')
151 | 
152 |     thinkplot.config(xlim=[0, integ_filter.max_freq],
153 |                      yscale='log', legend=True)
154 |     thinkplot.save('diff_int8')
155 | 
156 |     # compare cumsum filter to actual ratios
157 |     cumsum_filter.plot(label='cumsum filter', color=GRAY, linewidth=7)
158 |     
159 |     in_spectrum = in_wave.make_spectrum()
160 |     out_spectrum = out_wave.make_spectrum()
161 |     ratio_spectrum = out_spectrum.ratio(in_spectrum, thresh=1)
162 |     ratio_spectrum.plot(label='ratio', style='.', markersize=4)
163 | 
164 |     thinkplot.config(xlabel='Frequency (Hz)',
165 |                      ylabel='Amplitude ratio',
166 |                      xlim=[0, integ_filter.max_freq],
167 |                      yscale='log', legend=True)
168 |     thinkplot.save('diff_int9')
169 | 
170 | 
171 | 
172 | def plot_diff_filters(wave):
173 | 
174 |     window1 = np.array([1, -1])
175 |     window2 = np.array([-1, 4, -3]) / 2.0
176 |     window3 = np.array([2, -9, 18, -11]) / 6.0
177 |     window4 = np.array([-3, 16, -36, 48, -25]) / 12.0
178 |     window5 = np.array([12, -75, 200, -300, 300, -137]) / 60.0
179 | 
180 |     thinkplot.preplot(5)
181 |     for i, window in enumerate([window1, window2, window3, window4, window5]):
182 |         padded = thinkdsp.zero_pad(window, len(wave))
183 |         fft_window = np.fft.rfft(padded)
184 |         n = len(fft_window)
185 |         thinkplot.plot(abs(fft_window)[:], label=i+1)
186 | 
187 |     thinkplot.show()
188 | 
189 | 
190 | def main():
191 |     names = ['date', 'open', 'high', 'low', 'close', 'volume']
192 |     df = pd.read_csv('fb_1.csv', header=0, names=names, parse_dates=[0])
193 |     ys = df.close.values[::-1]
194 |     close = thinkdsp.Wave(ys, framerate=1)
195 |     plot_wave_and_spectrum(close, root='diff_int1')
196 | 
197 |     change = thinkdsp.Wave(np.diff(ys), framerate=1)
198 |     plot_wave_and_spectrum(change, root='diff_int2')
199 | 
200 |     plot_filters(close)
201 | 
202 |     plot_diff_deriv(close)
203 | 
204 |     signal = thinkdsp.SawtoothSignal(freq=50)
205 |     in_wave = signal.make_wave(duration=0.1, framerate=44100)
206 |     plot_sawtooth_and_spectrum(in_wave, 'diff_int6')
207 | 
208 |     out_wave = in_wave.cumsum()
209 |     out_wave.unbias()
210 |     plot_sawtooth_and_spectrum(out_wave, 'diff_int7')
211 | 
212 |     plot_integral(close)
213 |     plot_ratios(in_wave, out_wave)
214 | 
215 | 
216 | if __name__ == '__main__':
217 |     main()
218 | 


--------------------------------------------------------------------------------
/code/fourth_wave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/fourth_wave.png


--------------------------------------------------------------------------------
/code/noise.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import numpy
 11 | import thinkstats2
 12 | import thinkdsp
 13 | import thinkplot
 14 | 
 15 | 
 16 | def process_noise(signal, root='white'):
 17 |     """Plots wave and spectrum for noise signals.
 18 | 
 19 |     signal: Signal
 20 |     root: string used to generate file names
 21 |     """
 22 |     framerate = 11025
 23 |     wave = signal.make_wave(duration=0.5, framerate=framerate)
 24 | 
 25 |     # 0: waveform
 26 |     segment = wave.segment(duration=0.1)
 27 |     segment.plot(linewidth=1, alpha=0.5)
 28 |     thinkplot.save(root=root+'noise0',
 29 |                    xlabel='Time (s)',
 30 |                    ylim=[-1.05, 1.05])
 31 | 
 32 |     spectrum = wave.make_spectrum()
 33 | 
 34 |     # 1: spectrum
 35 |     spectrum.plot_power(linewidth=1, alpha=0.5)
 36 |     thinkplot.save(root=root+'noise1',
 37 |                    xlabel='Frequency (Hz)',
 38 |                    ylabel='Power',
 39 |                    xlim=[0, spectrum.fs[-1]])
 40 | 
 41 |     slope, _, _, _, _ = spectrum.estimate_slope()
 42 |     print('estimated slope', slope)
 43 | 
 44 |     # 2: integrated spectrum
 45 |     integ = spectrum.make_integrated_spectrum()
 46 |     integ.plot_power()
 47 |     thinkplot.save(root=root+'noise2',
 48 |                    xlabel='Frequency (Hz)',
 49 |                    ylabel='Cumulative fraction of total power',
 50 |                    xlim=[0, framerate/2])
 51 | 
 52 |     # 3: log-log power spectrum
 53 |     spectrum.hs[0] = 0
 54 |     thinkplot.preplot(cols=2)
 55 |     spectrum.plot_power(linewidth=1, alpha=0.5)
 56 |     thinkplot.config(xlabel='Frequency (Hz)',
 57 |                      ylabel='Power',
 58 |                      xlim=[0, framerate/2])
 59 | 
 60 |     thinkplot.subplot(2)
 61 |     spectrum.plot_power(linewidth=1, alpha=0.5)
 62 |     thinkplot.config(xlabel='Frequency (Hz)',                  
 63 |                    xscale='log',
 64 |                    yscale='log',
 65 |                    xlim=[0, framerate/2])
 66 | 
 67 |     thinkplot.save(root=root+'noise3')
 68 | 
 69 | 
 70 | def plot_gaussian_noise():
 71 |     """Shows the distribution of the spectrum of Gaussian noise.
 72 |     """
 73 |     thinkdsp.random_seed(18)
 74 |     signal = thinkdsp.UncorrelatedGaussianNoise()
 75 |     wave = signal.make_wave(duration=0.5, framerate=11025)
 76 |     spectrum = wave.make_spectrum()
 77 | 
 78 |     thinkplot.preplot(2, cols=2)
 79 |     thinkstats2.NormalProbabilityPlot(spectrum.real, label='real')
 80 |     thinkplot.config(xlabel='Normal sample',
 81 |                      ylabel='Amplitude',
 82 |                      ylim=[-250, 250],
 83 |                      loc='lower right')
 84 | 
 85 |     thinkplot.subplot(2)
 86 |     thinkstats2.NormalProbabilityPlot(spectrum.imag, label='imag')
 87 |     thinkplot.config(xlabel='Normal sample',
 88 |                      ylim=[-250, 250],
 89 |                      loc='lower right')
 90 | 
 91 |     thinkplot.save(root='noise1')
 92 | 
 93 | 
 94 | def plot_pink_noise():
 95 |     """Makes a plot showing power spectrums for pink noise.
 96 |     """
 97 |     thinkdsp.random_seed(20)
 98 | 
 99 |     duration = 1.0
100 |     framerate = 512
101 | 
102 |     def make_spectrum(signal):
103 |         wave = signal.make_wave(duration=duration, framerate=framerate)
104 |         spectrum = wave.make_spectrum()
105 |         spectrum.hs[0] = 0
106 |         return spectrum
107 | 
108 |     signal = thinkdsp.UncorrelatedUniformNoise()
109 |     white = make_spectrum(signal)
110 | 
111 |     signal = thinkdsp.PinkNoise()
112 |     pink = make_spectrum(signal)
113 | 
114 |     signal = thinkdsp.BrownianNoise()
115 |     red = make_spectrum(signal)
116 | 
117 |     linewidth = 2
118 |     # colorbrewer2.org 4-class sequential OrRd
119 |     white.plot_power(label='white', color='#fdcc8a', linewidth=linewidth)
120 |     pink.plot_power(label='pink', color='#fc8d59', linewidth=linewidth)
121 |     red.plot_power(label='red', color='#d7301f', linewidth=linewidth)
122 |     thinkplot.save(root='noise-triple',
123 |                    xlabel='Frequency (Hz)',
124 |                    ylabel='Power',
125 |                    xscale='log',
126 |                    yscale='log',
127 |                    xlim=[1, red.fs[-1]])
128 | 
129 | 
130 | def main():
131 |     thinkdsp.random_seed(17)
132 |     plot_pink_noise()
133 | 
134 |     thinkdsp.random_seed(17)
135 |     plot_gaussian_noise()
136 | 
137 |     thinkdsp.random_seed(20)
138 |     signal = thinkdsp.UncorrelatedUniformNoise()
139 |     process_noise(signal, root='white')
140 | 
141 |     thinkdsp.random_seed(20)
142 |     signal = thinkdsp.PinkNoise(beta=1.0)
143 |     process_noise(signal, root='pink')
144 | 
145 |     thinkdsp.random_seed(17)
146 |     signal = thinkdsp.BrownianNoise()
147 |     process_noise(signal, root='red')
148 | 
149 | 
150 | if __name__ == '__main__':
151 |     main()
152 | 


--------------------------------------------------------------------------------
/code/sampling.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2015 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import thinkdsp
 11 | import thinkplot
 12 | 
 13 | import numpy as np
 14 | import matplotlib.pyplot as plt
 15 | 
 16 | PI2 = 2 * np.pi
 17 | FORMATS = ['pdf', 'eps']
 18 | 
 19 | 
 20 | def plot_beeps():
 21 |     wave = thinkdsp.read_wave('253887__themusicalnomad__positive-beeps.wav')
 22 |     wave.normalize()
 23 | 
 24 |     thinkplot.preplot(3)
 25 | 
 26 |     # top left
 27 |     ax1 = plt.subplot2grid((4, 2), (0, 0), rowspan=2)
 28 |     plt.setp(ax1.get_xticklabels(), visible=False)
 29 | 
 30 |     wave.plot()
 31 |     thinkplot.config(title='Input waves', legend=False)
 32 | 
 33 |     # bottom left
 34 |     imp_sig = thinkdsp.Impulses([0.01, 0.4, 0.8, 1.2], 
 35 |                                 amps=[1, 0.5, 0.25, 0.1])
 36 |     impulses = imp_sig.make_wave(start=0, duration=1.3, 
 37 |                                  framerate=wave.framerate)
 38 | 
 39 |     ax2 = plt.subplot2grid((4, 2), (2, 0), rowspan=2, sharex=ax1)
 40 |     impulses.plot()
 41 |     thinkplot.config(xlabel='Time (s)')
 42 | 
 43 |     # center right
 44 |     convolved = wave.convolve(impulses)
 45 | 
 46 |     ax3 = plt.subplot2grid((4, 2), (1, 1), rowspan=2)
 47 |     plt.title('Convolution')
 48 |     convolved.plot()
 49 |     thinkplot.config(xlabel='Time (s)')
 50 | 
 51 |     thinkplot.save(root='sampling1',
 52 |                    formats=FORMATS,
 53 |                    legend=False)
 54 | 
 55 | XLIM = [-22050, 22050]
 56 | 
 57 | def plot_am():
 58 |     wave = thinkdsp.read_wave('105977__wcfl10__favorite-station.wav')
 59 |     wave.unbias()
 60 |     wave.normalize()
 61 | 
 62 |     # top
 63 |     ax1 = thinkplot.preplot(6, rows=4)
 64 |     spectrum = wave.make_spectrum(full=True)
 65 |     spectrum.plot(label='spectrum')
 66 | 
 67 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
 68 | 
 69 |     #second
 70 |     carrier_sig = thinkdsp.CosSignal(freq=10000)
 71 |     carrier_wave = carrier_sig.make_wave(duration=wave.duration, 
 72 |                                          framerate=wave.framerate)
 73 |     modulated = wave * carrier_wave
 74 | 
 75 |     ax2 = thinkplot.subplot(2, sharey=ax1)
 76 |     modulated.make_spectrum(full=True).plot(label='modulated')
 77 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
 78 | 
 79 |     # third
 80 |     demodulated = modulated * carrier_wave
 81 |     demodulated_spectrum = demodulated.make_spectrum(full=True)
 82 | 
 83 |     ax3 = thinkplot.subplot(3, sharey=ax1)
 84 |     demodulated_spectrum.plot(label='demodulated')
 85 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
 86 | 
 87 |     #fourth
 88 |     ax4 = thinkplot.subplot(4, sharey=ax1)
 89 |     demodulated_spectrum.low_pass(10000)
 90 |     demodulated_spectrum.plot(label='filtered')
 91 |     thinkplot.config(xlim=XLIM, xlabel='Frequency (Hz)')
 92 | 
 93 |     thinkplot.save(root='sampling2',
 94 |                    formats=FORMATS)
 95 | 
 96 |     #carrier_spectrum = carrier_wave.make_spectrum(full=True)
 97 |     #carrier_spectrum.plot()
 98 | 
 99 | 
100 |     #convolved = spectrum.convolve(carrier_spectrum)
101 |     #convolved.plot()
102 | 
103 | 
104 |     #reconvolved = convolved.convolve(carrier_spectrum)
105 |     #reconvolved.plot()
106 | 
107 | 
108 | def sample(wave, factor):
109 |     """Simulates sampling of a wave.
110 |     
111 |     wave: Wave object
112 |     factor: ratio of the new framerate to the original
113 |     """
114 |     ys = np.zeros(len(wave))
115 |     ys[::factor] = wave.ys[::factor]
116 |     ts = wave.ts[:]
117 |     return thinkdsp.Wave(ys, ts, wave.framerate) 
118 | 
119 | 
120 | def make_impulses(wave, factor):
121 |     ys = np.zeros(len(wave))
122 |     ys[::factor] = 1
123 |     ts = np.arange(len(wave)) / wave.framerate
124 |     return thinkdsp.Wave(ys, ts, wave.framerate)
125 | 
126 | 
127 | def plot_segments(original, filtered):
128 |     start = 1
129 |     duration = 0.01
130 |     original.segment(start=start, duration=duration).plot(color='gray')
131 |     filtered.segment(start=start, duration=duration).plot()
132 | 
133 | 
134 | def plot_sampling(wave, root):
135 |     ax1 = thinkplot.preplot(2, rows=2)
136 |     wave.make_spectrum(full=True).plot(label='spectrum')
137 | 
138 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
139 | 
140 |     ax2 = thinkplot.subplot(2)
141 |     sampled = sample(wave, 4)
142 |     sampled.make_spectrum(full=True).plot(label='sampled')
143 |     thinkplot.config(xlim=XLIM, xlabel='Frequency (Hz)')
144 | 
145 |     thinkplot.save(root=root,
146 |                    formats=FORMATS)
147 | 
148 | 
149 | def plot_sampling2(wave, root):
150 |     ax1 = thinkplot.preplot(6, rows=4)
151 |     wave.make_spectrum(full=True).plot(label='spectrum')
152 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
153 | 
154 |     ax2 = thinkplot.subplot(2)
155 |     impulses = make_impulses(wave, 4)
156 |     impulses.make_spectrum(full=True).plot(label='impulses')
157 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
158 | 
159 |     ax3 = thinkplot.subplot(3)
160 |     sampled = wave * impulses
161 |     spectrum = sampled.make_spectrum(full=True)
162 |     spectrum.plot(label='sampled')
163 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
164 | 
165 |     ax4 = thinkplot.subplot(4)
166 |     spectrum.low_pass(5512.5)
167 |     spectrum.plot(label='filtered')
168 |     thinkplot.config(xlim=XLIM, xlabel='Frequency (Hz)')
169 | 
170 |     thinkplot.save(root=root,
171 |                    formats=FORMATS)
172 | 
173 | 
174 | def plot_sampling3(wave, root):
175 |     ax1 = thinkplot.preplot(6, rows=3)
176 |     wave.make_spectrum(full=True).plot(label='spectrum')
177 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
178 | 
179 |     impulses = make_impulses(wave, 4)
180 | 
181 |     ax2 = thinkplot.subplot(2)
182 |     sampled = wave * impulses
183 |     spectrum = sampled.make_spectrum(full=True)
184 |     spectrum.plot(label='sampled')
185 |     thinkplot.config(xlim=XLIM, xticklabels='invisible')
186 | 
187 |     ax3 = thinkplot.subplot(3)
188 |     spectrum.low_pass(5512.5)
189 |     spectrum.plot(label='filtered')
190 |     thinkplot.config(xlim=XLIM, xlabel='Frequency (Hz)')
191 | 
192 |     thinkplot.save(root=root,
193 |                    formats=FORMATS)
194 | 
195 |     #filtered = spectrum.make_wave()
196 |     #plot_segments(wave, filtered)
197 | 
198 | 
199 | def make_boxcar(spectrum, factor):
200 |     """Makes a boxcar filter for the given spectrum.
201 |     
202 |     spectrum: Spectrum to be filtered
203 |     factor: sampling factor
204 |     """
205 |     fs = np.copy(spectrum.fs)
206 |     hs = np.zeros_like(spectrum.hs)
207 |     
208 |     cutoff = spectrum.framerate / 2 / factor
209 |     for i, f in enumerate(fs):
210 |         if abs(f) <= cutoff:
211 |             hs[i] = 1
212 |     return thinkdsp.Spectrum(hs, fs, spectrum.framerate, full=spectrum.full)
213 | 
214 | 
215 | 
216 | def plot_sinc_demo(wave, factor, start=None, duration=None):
217 | 
218 |     def make_sinc(t, i, y):
219 |         """Makes a shifted, scaled copy of the sinc function."""
220 |         sinc = boxcar.make_wave()
221 |         sinc.shift(t)
222 |         sinc.roll(i)
223 |         sinc.scale(y * factor)
224 |         return sinc
225 |  
226 |     def plot_mini_sincs(wave):
227 |         """Plots sinc functions for each sample in wave."""
228 |         t0 = wave.ts[0]
229 |         for i in range(0, len(wave), factor):
230 |             sinc = make_sinc(t0, i, wave.ys[i])
231 |             seg = sinc.segment(start, duration)
232 |             seg.plot(color='green', linewidth=0.5, alpha=0.3)
233 |             if i == 0:
234 |                 total = sinc
235 |             else:
236 |                 total += sinc
237 |             
238 |         seg = total.segment(start, duration)        
239 |         seg.plot(color='blue', alpha=0.5)
240 | 
241 |     sampled = sample(wave, factor)
242 |     spectrum = sampled.make_spectrum()
243 |     boxcar = make_boxcar(spectrum, factor)
244 | 
245 |     start = wave.start if start is None else start
246 |     duration = wave.duration if duration is None else duration
247 |         
248 |     sampled.segment(start, duration).plot_vlines(color='gray')
249 |     wave.segment(start, duration).plot(color='gray')
250 |     plot_mini_sincs(wave)
251 | 
252 | 
253 | def plot_sincs(wave):
254 |     start = 1.0
255 |     duration = 0.01
256 |     factor = 4
257 | 
258 |     short = wave.segment(start=start, duration=duration)
259 |     #short.plot()
260 | 
261 |     sampled = sample(short, factor)
262 |     #sampled.plot_vlines(color='gray')
263 | 
264 |     spectrum = sampled.make_spectrum(full=True)
265 |     boxcar = make_boxcar(spectrum, factor)
266 | 
267 |     sinc = boxcar.make_wave()
268 |     sinc.shift(sampled.ts[0])
269 |     sinc.roll(len(sinc)//2)
270 | 
271 |     thinkplot.preplot(2, cols=2)
272 |     sinc.plot()
273 |     thinkplot.config(xlabel='Time (s)')
274 | 
275 |     thinkplot.subplot(2)
276 |     boxcar.plot()
277 |     thinkplot.config(xlabel='Frequency (Hz)',
278 |                      ylim=[0, 1.05],
279 |                      xlim=[-boxcar.max_freq, boxcar.max_freq])
280 | 
281 |     thinkplot.save(root='sampling6',
282 |                    formats=FORMATS)
283 | 
284 |     return
285 | 
286 |     # CAUTION: don't call plot_sinc_demo with a large wave or it will
287 |     # fill memory and crash
288 |     plot_sinc_demo(short, 4)
289 |     thinkplot.config(xlabel='Time (s)')
290 |     thinkplot.save(root='sampling7',
291 |                    formats=FORMATS)
292 | 
293 |     start = short.start + 0.004
294 |     duration = 0.00061
295 |     plot_sinc_demo(short, 4, start, duration)
296 |     thinkplot.config(xlabel='Time (s)',
297 |                      xlim=[start, start+duration],
298 |                      ylim=[-0.06, 0.17], legend=False)
299 |     thinkplot.save(root='sampling8',
300 |                    formats=FORMATS)
301 | 
302 | 
303 | def kill_yticklabels():
304 |     axis = plt.gca()
305 |     plt.setp(axis.get_yticklabels(), visible=False)
306 | 
307 | 
308 | def show_impulses(wave, factor, i):
309 |     thinkplot.subplot(i)
310 |     thinkplot.preplot(2)
311 |     impulses = make_impulses(wave, factor)
312 |     impulses.segment(0, 0.001).plot_vlines(linewidth=2, xfactor=1000)
313 |     if i == 1:
314 |         thinkplot.config(title='Impulse train',
315 |                          ylim=[0, 1.05])
316 |     else:
317 |         thinkplot.config(xlabel='Time (ms)',
318 |                          ylim=[0, 1.05])
319 |     
320 |     thinkplot.subplot(i+1)
321 |     impulses.make_spectrum(full=True).plot()
322 |     kill_yticklabels()
323 |     if i == 1:
324 |         thinkplot.config(title='DFT of impulse train', 
325 |                          xlim=[-22400, 22400])
326 |     else:
327 |         thinkplot.config(xlabel='Frequency (Hz)',
328 |                          xlim=[-22400, 22400])
329 | 
330 | 
331 | def plot_impulses(wave):
332 |     thinkplot.preplot(rows=2, cols=2)
333 |     show_impulses(wave, 4, 1)
334 |     show_impulses(wave, 8, 3)
335 |     thinkplot.save('sampling9',
336 |                    formats=FORMATS)
337 | 
338 | 
339 | def main():
340 |     wave = thinkdsp.read_wave('328878__tzurkan__guitar-phrase-tzu.wav')
341 |     wave.normalize()
342 | 
343 |     plot_sampling3(wave, 'sampling5')
344 |     plot_sincs(wave)
345 | 
346 |     plot_beeps()
347 |     plot_am()
348 | 
349 |     wave = thinkdsp.read_wave('263868__kevcio__amen-break-a-160-bpm.wav')
350 |     wave.normalize()
351 |     plot_impulses(wave)
352 | 
353 |     plot_sampling(wave, 'sampling3')
354 |     plot_sampling2(wave, 'sampling4')
355 | 
356 | 
357 | if __name__ == '__main__':
358 |     main()
359 | 


--------------------------------------------------------------------------------
/code/sounds.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import thinkdsp
 11 | import thinkplot
 12 | 
 13 | FORMATS = ['pdf', 'eps']
 14 | 
 15 | 
 16 | def plot_tuning(start=7.0, duration=0.006835):
 17 |     """Plots three cycles of a bell playing A4.
 18 | 
 19 |     start: start time in seconds
 20 |     duration: float
 21 |     """
 22 |     period = duration/3
 23 |     freq = 1/period
 24 |     print(period, freq)
 25 |     assert abs(freq - 438.917337235) < 1e-7
 26 | 
 27 |     wave = thinkdsp.read_wave('18871__zippi1__sound-bell-440hz.wav')
 28 | 
 29 |     segment = wave.segment(start, duration)
 30 |     segment.normalize()
 31 | 
 32 |     thinkplot.preplot(1)
 33 |     segment.plot()
 34 |     thinkplot.Save(root='sounds1',
 35 |                    xlabel='Time (s)',
 36 |                    axis=[start, start+duration, -1.05, 1.05],
 37 |                    formats=FORMATS,
 38 |                    legend=False)
 39 | 
 40 | 
 41 | def plot_violin(start=1.30245, duration=0.00683):
 42 |     """Plots three cycles of a violin playing A4.
 43 | 
 44 |     duration: float
 45 |     """
 46 |     period = duration/3
 47 |     freq = 1/period
 48 |     print(period, freq)
 49 |     assert abs(freq - 439.238653001) < 1e-7
 50 | 
 51 |     wave = thinkdsp.read_wave('92002__jcveliz__violin-origional.wav')
 52 | 
 53 |     segment = wave.segment(start, duration)
 54 |     segment.normalize()
 55 | 
 56 |     thinkplot.preplot(1)
 57 |     segment.plot()
 58 |     thinkplot.Save(root='sounds2',
 59 |                    xlabel='Time (s)',
 60 |                    axis=[start, start+duration, -1.05, 1.05],
 61 |                    formats=FORMATS,
 62 |                    legend=False)
 63 | 
 64 | 
 65 | def segment_violin(start=1.2, duration=0.6):
 66 |     """Load a violin recording and plot its spectrum.
 67 | 
 68 |     start: start time of the segment in seconds
 69 |     duration: in seconds
 70 |     """
 71 |     wave = thinkdsp.read_wave('92002__jcveliz__violin-origional.wav')
 72 | 
 73 |     # extract a segment
 74 |     segment = wave.segment(start, duration)
 75 |     segment.normalize()
 76 | 
 77 |     # plot the spectrum
 78 |     spectrum = segment.make_spectrum()
 79 | 
 80 |     thinkplot.preplot(1)
 81 |     spectrum.plot(high=10000)
 82 |     thinkplot.Save(root='sounds3',
 83 |                    xlabel='Frequency (Hz)',
 84 |                    ylabel='Amplitude',
 85 |                    formats=FORMATS,
 86 |                    legend=False)
 87 | 
 88 |     # print the top 5 peaks
 89 |     peaks = spectrum.peaks()
 90 |     for amp, freq in peaks[:10]:
 91 |         print(freq, amp)
 92 |     assert abs(peaks[0][0] - 3762.382899) < 1e-7
 93 | 
 94 | 
 95 | def mix_cosines():
 96 |     """Plots three periods of a mix of cosines.
 97 |     """
 98 | 
 99 |     # create a SumSignal
100 |     cos_sig = thinkdsp.CosSignal(freq=440, amp=1.0, offset=0)
101 |     sin_sig = thinkdsp.SinSignal(freq=880, amp=0.5, offset=0)
102 | 
103 |     mix = sin_sig + cos_sig
104 | 
105 |     # create a wave
106 |     wave = mix.make_wave(duration=1.0, start=0, framerate=11025)
107 |     print('Number of samples', len(wave))
108 |     print('Timestep in ms', 1000 / wave.framerate)
109 |     assert len(wave) == wave.framerate
110 | 
111 |     # select a segment
112 |     period = mix.period
113 |     segment = wave.segment(start=0, duration=period*3)
114 | 
115 |     # plot the segment
116 |     thinkplot.preplot(1)
117 |     segment.plot()
118 |     thinkplot.Save(root='sounds4',
119 |                    xlabel='Time (s)',
120 |                    axis=[0, period*3, -1.55, 1.55],
121 |                    formats=FORMATS,
122 |                    legend=False)
123 | 
124 | 
125 | def main():
126 |     plot_tuning()
127 |     plot_violin()
128 |     segment_violin()
129 |     mix_cosines()
130 | 
131 | 
132 | if __name__ == '__main__':
133 |     main()
134 | 


--------------------------------------------------------------------------------
/code/stalbans_a_mono.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/stalbans_a_mono.wav


--------------------------------------------------------------------------------
/code/systems.py:
--------------------------------------------------------------------------------
  1 | """This file contains code used in "Think DSP",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import thinkdsp
 11 | import thinkplot
 12 | 
 13 | import numpy as np
 14 | 
 15 | 
 16 | def plot_filter():
 17 |     """Plots the filter that corresponds to a 2-element moving average.
 18 |     """
 19 |     impulse = np.zeros(8)
 20 |     impulse[0] = 1
 21 |     wave = thinkdsp.Wave(impulse, framerate=8)
 22 |     
 23 |     impulse_spectrum = wave.make_spectrum(full=True)
 24 |     window_array = np.array([0.5, 0.5, 0, 0, 0, 0, 0, 0,])
 25 |     window = thinkdsp.Wave(window_array, framerate=8)
 26 |     filtr = window.make_spectrum(full=True)
 27 | 
 28 |     filtr.plot()
 29 |     thinkplot.config(xlabel='Frequency', ylabel='Amplitude')
 30 |     thinkplot.save('systems1')
 31 | 
 32 | 
 33 | def read_response():
 34 |     """Reads the impulse response file and removes the initial silence.
 35 |     """
 36 |     response = thinkdsp.read_wave('180960__kleeb__gunshot.wav')
 37 |     start = 0.26
 38 |     response = response.segment(start=start)
 39 |     response.shift(-start)
 40 |     response.normalize()
 41 |     return response
 42 | 
 43 | 
 44 | def plot_response(response):
 45 |     """Plots an input wave and the corresponding output.
 46 |     """
 47 |     thinkplot.preplot(cols=2)
 48 |     response.plot()
 49 |     thinkplot.config(xlabel='Time (s)',
 50 |                      xlim=[0.26, response.end],
 51 |                      ylim=[-1.05, 1.05])
 52 | 
 53 |     thinkplot.subplot(2)
 54 |     transfer = response.make_spectrum()
 55 |     transfer.plot()
 56 |     thinkplot.config(xlabel='Frequency (Hz)',
 57 |                      xlim=[0, 22500],
 58 |                      ylabel='Amplitude')
 59 |     thinkplot.save(root='systems6')
 60 | 
 61 |     violin = thinkdsp.read_wave('92002__jcveliz__violin-origional.wav')
 62 | 
 63 |     start = 0.11
 64 |     violin = violin.segment(start=start)
 65 |     violin.shift(-start)
 66 | 
 67 |     violin.truncate(len(response))
 68 |     violin.normalize()
 69 |     spectrum = violin.make_spectrum()
 70 | 
 71 |     output = (spectrum * transfer).make_wave()
 72 |     output.normalize()
 73 | 
 74 |     thinkplot.preplot(rows=2)
 75 |     violin.plot(label='input')
 76 |     thinkplot.config(xlim=[0, violin.end],
 77 |                      ylim=[-1.05, 1.05])
 78 | 
 79 |     thinkplot.subplot(2)
 80 |     output.plot(label='output')
 81 |     thinkplot.config(xlabel='Time (s)',
 82 |                      xlim=[0, violin.end],
 83 |                      ylim=[-1.05, 1.05])
 84 | 
 85 |     thinkplot.save(root='systems7')
 86 | 
 87 | 
 88 | def shifted_scaled(wave, shift, factor):
 89 |     res = wave.copy()
 90 |     res.shift(shift)
 91 |     res.scale(factor)
 92 |     return res
 93 | 
 94 | 
 95 | def plot_convolution(response):
 96 |     """Plots the impulse response and a shifted, scaled copy.
 97 |     """
 98 |     shift = 1
 99 |     factor = 0.5
100 |     
101 |     gun2 = response + shifted_scaled(response, shift, factor)
102 |     gun2.plot()
103 |     thinkplot.config(xlabel='Time (s)',
104 |                      ylim=[-1.05, 1.05],
105 |                      legend=False)
106 |     thinkplot.save(root='systems8')
107 | 
108 | 
109 | def plot_sawtooth(response):
110 |     signal = thinkdsp.SawtoothSignal(freq=441)
111 |     wave = signal.make_wave(duration=0.1, framerate=response.framerate)
112 | 
113 |     total = 0
114 |     for t, y in zip(wave.ts, wave.ys):
115 |         total += shifted_scaled(response, t, y)
116 | 
117 |     total.normalize()
118 | 
119 |     high = 5000
120 |     wave.make_spectrum().plot(high=high, color='0.7', label='original')
121 |     segment = total.segment(duration=0.2)
122 |     segment.make_spectrum().plot(high=high, label='convolved')
123 |     thinkplot.config(xlabel='Frequency (Hz)', ylabel='Amplitude')
124 |     thinkplot.save(root='systems9')
125 | 
126 | 
127 | def main():
128 |     plot_filter()
129 | 
130 |     response = read_response()
131 |     plot_response(response)
132 |     plot_convolution(response)
133 | 
134 | 
135 | if __name__ == '__main__':
136 |     main()
137 | 


--------------------------------------------------------------------------------
/code/thinkdsp_test.py:
--------------------------------------------------------------------------------
  1 | """This file contains code for use with "Think Stats",
  2 | by Allen B. Downey, available from greenteapress.com
  3 | 
  4 | Copyright 2014 Allen B. Downey
  5 | License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
  6 | """
  7 | 
  8 | from __future__ import print_function, division
  9 | 
 10 | import unittest
 11 | import thinkdsp
 12 | 
 13 | import numpy as np
 14 | 
 15 | 
 16 | class Test(unittest.TestCase):
 17 |     def assertArrayAlmostEqual(self, a, b):
 18 |         total_error = np.sum(np.abs(a-b))
 19 |         self.assertAlmostEqual(total_error, 0)
 20 | 
 21 |     def testMakeSpectrum(self):
 22 |         # rfft with n even
 23 |         ys = np.arange(10)
 24 |         wave = thinkdsp.Wave(ys, framerate=10)
 25 |         spectrum = wave.make_spectrum()
 26 |         self.assertAlmostEqual(spectrum.hs[0], 45)
 27 |         wave2 = spectrum.make_wave()
 28 |         #print(wave2.ys)
 29 |         self.assertArrayAlmostEqual(wave.ys, wave2.ys)
 30 | 
 31 |         # rfft with n odd
 32 |         ys = np.arange(11)
 33 |         wave = thinkdsp.Wave(ys, framerate=10)
 34 |         spectrum = wave.make_spectrum()
 35 |         self.assertAlmostEqual(spectrum.hs[0], 55)
 36 | 
 37 |         # TODO: make rfft invertible when n is odd
 38 |         #wave2 = spectrum.make_wave()
 39 |         #print(wave2.ys)
 40 |         #self.assertArrayAlmostEqual(wave.ys, wave2.ys)
 41 | 
 42 |         # fft with n even
 43 |         ys = np.arange(10)
 44 |         wave = thinkdsp.Wave(ys, framerate=10)
 45 |         spectrum = wave.make_spectrum(full=True)
 46 |         self.assertAlmostEqual(spectrum.hs[0], 45)
 47 |         wave2 = spectrum.make_wave()
 48 |         #print(wave2.ys)
 49 |         self.assertArrayAlmostEqual(wave.ys, wave2.ys)
 50 | 
 51 |         # fft with n odd
 52 |         ys = np.arange(11)
 53 |         wave = thinkdsp.Wave(ys, framerate=10)
 54 |         spectrum = wave.make_spectrum(full=True)
 55 |         self.assertAlmostEqual(spectrum.hs[0], 55)
 56 |         wave2 = spectrum.make_wave()
 57 |         #print(wave2.ys)
 58 |         self.assertArrayAlmostEqual(wave.ys, wave2.ys)
 59 | 
 60 |     def testComplexSinusoid(self):
 61 |         signal = thinkdsp.ComplexSinusoid(440, 0.7, 1.1)
 62 |         result = signal.evaluate(2.1) * complex(-1.5, -0.5)
 63 |         self.assertAlmostEqual(result, -0.164353351475-1.09452637056j)
 64 | 
 65 |     def testChirp(self):
 66 |         signal = thinkdsp.Chirp(100, 200, 0.5)
 67 |         result = signal.evaluate([1.001, 1.002, 1.005])
 68 |         self.assertAlmostEqual(result[0], 0.5)
 69 |         self.assertAlmostEqual(result[2], -0.49384417)
 70 | 
 71 |     def testExpoChirp(self):
 72 |         signal = thinkdsp.ExpoChirp(100, 200, 0.5)
 73 |         result = signal.evaluate([0, 0.001, 0.002])
 74 |         self.assertAlmostEqual(result[0], 0.5)
 75 |         self.assertAlmostEqual(result[2], -0.27167286)
 76 | 
 77 |     def testWaveAdd(self):
 78 |         ys = np.array([1, 2, 3, 4])
 79 |         wave1 = thinkdsp.Wave(ys, framerate=1)
 80 |         wave2 = wave1.copy()
 81 |         wave2.shift(2)
 82 |         wave = wave1 + wave2
 83 | 
 84 |         self.assertEqual(len(wave), 6)
 85 |         self.assertAlmostEqual(sum(wave.ys), 20)
 86 | 
 87 |     def testDct(self):
 88 |         signal = thinkdsp.CosSignal(freq=2)
 89 |         wave = signal.make_wave(duration=1, framerate=8)
 90 |         dct = wave.make_dct()
 91 | 
 92 |         self.assertAlmostEqual(dct.fs[0], 0.25)
 93 | 
 94 |     def testImpulses(self):
 95 |         imp_sig = thinkdsp.Impulses([0.01, 0.4, 0.8, 1.2],
 96 |                                     amps=[1, 0.5, 0.25, 0.1])
 97 |         impulses = imp_sig.make_wave(start=0, duration=1.3,
 98 |                                      framerate=11025)
 99 | 
100 |         self.assertEqual(len(impulses), 14332)
101 | 
102 | 
103 | if __name__ == "__main__":
104 |     unittest.main()
105 | 


--------------------------------------------------------------------------------
/code/tos-redalert.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AllenDowney/ThinkDSP/f1cc15de31f658d5df287332a30659fb16eb41d5/code/tos-redalert.wav


--------------------------------------------------------------------------------
/environment.yml:
--------------------------------------------------------------------------------
 1 | name: ThinkDSP
 2 | 
 3 | dependencies:
 4 |   - python>=3.6
 5 |   - jupyter
 6 |   - numpy>=1.16
 7 |   - matplotlib
 8 |   - seaborn
 9 |   - pandas
10 |   - scipy
11 | 
12 | 


--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
 1 | [tool.poetry]
 2 | name = "thinkdsp"
 3 | version = "0.1.0"
 4 | description = ""
 5 | authors = ["Allen Downey <allen.downey@olin.edu>"]
 6 | 
 7 | [tool.poetry.dependencies]
 8 | python = "^3.8"
 9 | jupyter = "^1.0.0"
10 | numpy = "^1.19.4"
11 | matplotlib = "^3.3.3"
12 | seaborn = "^0.11.0"
13 | pandas = "^1.1.4"
14 | scipy = "^1.5.4"
15 | 
16 | [tool.poetry.dev-dependencies]
17 | 
18 | [build-system]
19 | requires = ["poetry>=0.12"]
20 | build-backend = "poetry.masonry.api"
21 | 


--------------------------------------------------------------------------------
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | -r requirements.txt
2 | black
3 | flake8
4 | nbmake
5 | pytest
6 | 


--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | jupyter
2 | numpy
3 | matplotlib
4 | pandas
5 | scipy
6 | 


--------------------------------------------------------------------------------