├── .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 | [](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&ASIN=1449370780&Format=_SL160_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&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&ASIN=144933072X&Format=_SL160_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&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&ASIN=1491907339&Format=_SL160_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&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&ASIN=1449314635&Format=_SL160_&ID=AsinImage&MarketPlace=US&ServiceVersion=20070822&WS=1&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&camp=1789&creative=9325&creativeASIN=1491938455&linkCode=as2&tag=greenteapre01-20&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 | --------------------------------------------------------------------------------