# メモ
colab で latex を勉強するためのノートブックです。

colab で開いてください。

https://colab.research.google.com/github/kalz2q/mycolabnotebooks/blob/master/learnlatex.ipynb

colab でテキストセル内で $ マークを使うと数式を latex で処理して美しく表示できる。
$$ \int f(x)dx $$

これを latex でどう書いているかは、セルをダブルクリックするかセルを選択して Ctrl+Enter を押して、編集モードにすることで見ることができる。

もっと明示的にコードセルで `%%latex` マジックを使って書くことができる。

この場合はコードセルをセルの左側の丸に右向き三角の実行ボタンを押すか、Ctrl+Enter で実行して出力としてレンダリングされた表示を見ることになる。

colab の latex は完全な latex ではない。 mathjax ベースのサブセットである。 数式を書くのに便利。

このノートブックではテキストセルで表示して同じことを、コードセルで実行できるようにすることで、いちいち編集モードに入らずに読み進められるようにしたい。

```python
# 例
%%latex
\int f(x)dx
```

\int f(x)dx

# 参考サイト

TeX入門 ( http://www.comp.tmu.ac.jp/tsakai/lectures/intro_tex.html )
TeX入門Wiki ( https://texwiki.texjp.org/)
Learn LaTeX in 30 minutes ( https://www.overleaf.com/learn/latex/
Learn_LaTeX_in_30_minutes )
MathJax ( https://docs.mathjax.org/en/v2.5-latest/tex.html )
MathJaxの使い方(
http://www.eng.niigata-u.ac.jp/~nomoto/download/mathjax.pdf)

# 数式記号一覧

The Comprehensive LaTeX Symbol List - The CTAN archive ( http://tug.ctan.org/info/symbols/comprehensive/symbols-a4.pdf )

Short Math Guide for LaTeX ( https://ftp.yz.yamagata-u.ac.jp/pub/CTAN/info/short-math-guide/short-math-guide.pdf )

ギリシャ文字, ドイツ文字, 花文字, 筆記体の TeX 表記をまとめておいた ( https://phasetr.com/blog/2013/04/14/ギリシャ文字-ドイツ文字-筆記体の-tex-表記を/ )

# はじめに ～ 実験学習

マークダウンでテキストの中に latex を入れることができる。
インラインで入れることもできるし $x = 3$ とか。

$$
x = 3
$$

とか。

テキストセルでは数式を $ マークで囲むとインライン、$$ で囲むと段落を変えて表示する。

表示された数式の latex での表記はセルを編集モードにすると見ることができる。

編集モードにするにはセルを選択してダブルクリックするか Enter キーを押す。

```python
# コードセルで %%latex で表示する
# 編集モードにしなくても latex 表記ができるので latex の学習には便利
# コードセルを実行しないと数式表記にならない。
# コードセルの実行はセルの左の実行ボタン(右向き三角)を押すか、Ctrl+Enter を押す。
# x = 3 の数字を変えて実行してみよう
%%latex
x = 3
```

x = 3

```python
# 実験 python プログラムで表示することもできる。このノートブックでは学習対象としない。
from sympy import *
from IPython.display import Markdown
display(Markdown("実験学習 $x = 3$ と書く"))
x = symbols('x')
display(Eq(x,3))
```

実験学習 $x = 3$ と書く

$\displaystyle x = 3$

# マークダウンと %%latex の違い (参考)
1. コードセルに %%latex と書くとその行以降 mathjax のルールが適用される。
1. %%latex以降にバックスラッシュ \ でエスケープされていない \$ マークがあると latex で解釈せずに入力のまま出力する。
1. % 記号はコメント記号なので文法上は許されるが、% 記号以降が出力されないのでバックスラッシュ \ でエスケープする必要がある。
1. バックスラッシュ \ 自体は \backslash と書く。 波記号 チルダ tilde ~ は \tilde{}、キャレット、ハット記号、サーカムフレックス、circumflex ^ は \hat{} になる。
1. 地の文、テキストも数式として解釈されるので、英文字はフォントが変わる。普通の文字にしたい場合は \text{} で括る。
1. 改行はマークダウンではスペース 2 個だが、%%latex では バックスラッシュ \ を2個 \\\\ になる。
1. その他マークダウン上の便利な機能。箇条書きの自動ナンバリングなどは使えない。

```python
# 実験
%%latex
this is a pen. \\
\text{this is a pen} \\
\backslash \\
\tilde{x}\\
\tilde{} \quad x\\
\hat{x} \\
\hat{} \quad  x \\
x^3 \\
```

this is a pen. \\
\text{this is a pen} \\
\backslash \\
\tilde{x}\\
\tilde{} \quad x\\
\hat{x} \\
\hat{} \quad  x \\
x^3 \\

同じことをマークダウンでやってみる。

$this is a pen.$
$\text{this is a pen}$
$\backslash$
$\tilde{x}$
$\tilde{} \quad x$
$\hat{x} $
$\hat{} \quad  x $
$x^3 $

```python
# これはコメント
%%latex
y = 5 \\
% これはコメント
x = 3
```

y = 5 \\
% これはコメント
x = 3

# 簡単な数式

```latex
%%latex
E = mc^2
```

E = mc^2

マークダウンでドルサインで囲むと latex(mathjax) になる。 2 個のドルサインで囲むと行替えされ、センタリングされた数式になる。

$$ E=mc^2$$

ここで $c$ は光速を表し、値は次の通り。

$$ c = 299{,}792{,}458 \, \mathrm{m/s} $$

いわゆる光速は 30 万キロ/秒というやつね!!!!

地球 7 周り半。

```latex
%%latex
E =mc^2 \\[0.8em]
c = 299{,}792{,}458 \, \mathrm{m/s}
```

E =mc^2 \\[0.8em]
c = 299{,}792{,}458 \, \mathrm{m/s}

数字のカンマは `{,}` として入れる。 波括弧 brace で囲む。

# ドル`$`マーク ドルサインをエスケープするには

この本は\$35.40。これはマークダウン。

この本は $\$35.40$ 。これは latex。

ドルサインは latex (mathjax) 対応のマークダウンでは mathjax の begin, end の記号なので、エスケープする必要がある。

colab 環境ではバックスラッシュ `\` でエスケープできる。

ドルサイン自体を HTML文字参照で書く、という方法もある。

`$ `
`$`
`$`

HTML文字参照は latex の中では使えない。

同一セル内でペアになっていないと表示される。

$

$$

# 水平方向の空白

```python
# 水平方向の空白の実験
# \+セミコロン、スペース、チルダが標準的な 1 文字スペースのようである
# とりあえずセミコロンがわかりやすいので \; とする
%%latex
a\;b\;c\;d\;e\;f\;g\; セミコロン\\
a\ b\ c\ d\ e\ f\ g\  スペース\\
a~b~c~d~e~f~g~ tilde\\
a\,b\,c\,d\,e\,f\,g\, カンマ\\
a~~b~~c~~d~~e~~f~~g~~ tilde2\\
a\quad b\quad c\quad d\quad e\quad f\quad g\quad  quad\\
```

a\;b\;c\;d\;e\;f\;g\; セミコロン\\
a\ b\ c\ d\ e\ f\ g\  スペース\\
a~b~c~d~e~f~g~ tilde\\
a\,b\,c\,d\,e\,f\,g\, カンマ\\
a~~b~~c~~d~~e~~f~~g~~ tilde2\\
a\quad b\quad c\quad d\quad e\quad f\quad g\quad  quad\\

# 改行と空行

マークダウン中の latex の中での改行は無視される。

結合されて、1 つの文になる。

改行は `\` を行末に2個入れる。

行間をあける (空白行を入れる) のはけっこうむずかしい。

\{\}+\\\\
`{}\\`

とか。

#インテグラル 積分
$$
\frac{\pi}{2} =
\left( \int_{0}^{\infty} \frac{\sin x}{\sqrt{x}} dx \right)^2 =
\sum_{k=0}^{\infty} \frac{(2k)!}{2^{2k}(k!)^2} \frac{1}{2k+1} =
\prod_{k=1}^{\infty} \frac{4k^2}{4k^2 - 1}
$$

```python
# インテグラル 積分記号
# latex では \int , sympy では Integral
%%latex
\displaystyle
\frac{\pi}{2}
=
\left( \int_{0}^{\infty} \frac{\sin x}{\sqrt{x}} dx \right)^2
=
\sum_{k=0}^{\infty} \frac{(2k)!}{2^{2k}(k!)^2} \frac{1}{2k+1}
=
\prod_{k=1}^{\infty} \frac{4k^2}{4k^2 - 1}
```

\displaystyle
\frac{\pi}{2}
=
\left( \int_{0}^{\infty} \frac{\sin x}{\sqrt{x}} dx \right)^2
=
\sum_{k=0}^{\infty} \frac{(2k)!}{2^{2k}(k!)^2} \frac{1}{2k+1}
=
\prod_{k=1}^{\infty} \frac{4k^2}{4k^2 - 1}

`\displaystyle`としないと、インラインスタイルでフォントが小さくなってしまう。

# フォントの実験

マークダウンで英文字は
abcdefABC
となるが、ドルサインで囲って latex にすると、数学用のフォントになる。
$abcdefABC$
この latex のなかで text とすると数学フォントではなくなる。
$\text{This is a text}$

* latex -> $abcdefABC$ $\quad$ 通常の数式書体
* \mathrm -> $\mathrm{abcdefABC}$   $\quad$ sin, cos など数式
*\boldsymbol -> $\boldsymbol{abcdefABC}$ $\quad$ ベクトルに使う
* \mathbf -> $\mathbf{abcdefABC}$ $\quad$ $\mathbf{NZRC}$
* \mathbb -> $\mathbb{abcdefABC}$ $\quad$ $\mathbb{NZRC}$
* \mathcal -> $\mathcal{abcdefABC}$   $\quad$
* \mathfrak -> $\mathfrak{abcdefABC}$   $\quad$

数学のテキストでのアルファベットの使い分けは通常はイタリックで、座標とかはセリフ付きのローマン体の大文字が使われている。 ベクトルを小文字で表すときに上矢印をつけずにボールド体を使うことがある。

手書きで部分白抜きを真似た mathbb というのもあって、これで書かれたテキストもある。

# 行列 matrix

$
A =\begin{pmatrix}
    a_{11} & \ldots & a_{1n} \\
    \vdots & \ddots & \vdots \\
    a_{m1} & \ldots & a_{mn}
\end{pmatrix}$

```latex
%%latex
\displaystyle
A =\begin{pmatrix}
    a_{11} & \ldots & a_{1n} \\
    \vdots & \ddots & \vdots \\
    a_{m1} & \ldots & a_{mn}
\end{pmatrix} \quad
A =\begin{bmatrix}
    a_{11} & \ldots & a_{1n} \\
    \vdots & \ddots & \vdots \\
    a_{m1} & \ldots & a_{mn}
\end{bmatrix}
```

\displaystyle
A =\begin{pmatrix}
    a_{11} & \ldots & a_{1n} \\
    \vdots & \ddots & \vdots \\
    a_{m1} & \ldots & a_{mn}
\end{pmatrix} \quad
A =\begin{bmatrix}
    a_{11} & \ldots & a_{1n} \\
    \vdots & \ddots & \vdots \\
    a_{m1} & \ldots & a_{mn}
\end{bmatrix}

直交行列
実対称行列 $A$ は直交行列 $P$ によって
$D = P^{-1} A P$
と対角行列 $D$ に対角化される。

```python
# 直交行列
%%latex
D = P^{-1} A P
```

D = P^{-1} A P

数列の合計シグマ、無限、階乗
$$
\sin x = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n+1)!} x^{2n+1}
$$

```latex
%%latex
\displaystyle
\sin x = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n+1)!} x^{2n+1}
```

\displaystyle
\sin x = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n+1)!} x^{2n+1}

# 積分記号、イプシロン、極限
$$
\int_{0}^{1} \log x \,dx
= \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x \,dx
= \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1}
= -1
$$

```python
# \int, Integral, \lim,
%%latex
\displaystyle
\int_{0}^{1} \log x \,dx
= \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x \,dx
= \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1}
= -1
```

\displaystyle
\int_{0}^{1} \log x \,dx
= \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x \,dx
= \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1}
= -1

# array, eqnarray, align, cases
それぞれ違いがあるが、汎用的なのは array だろう。
$$
\begin{array}{lcl}
    \displaystyle \int_{0}^{1} \log x dx
     & = \quad & \displaystyle  \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x dx \\
     & = & \displaystyle \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1} \\
     & = & -1
\end{array}
$$

$$
\begin{eqnarray}
    \int_{0}^{1} \log x dx
     & = & \displaystyle \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x dx \\
     & = & \displaystyle \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1} \\
     & = & -1
\end{eqnarray}
$$

$$
\begin{align}
    \int_{0}^{1} \log x dx
     & = & \displaystyle \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x dx \\
     & = & \displaystyle \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1} \\
     & = & -1
\end{align}
$$

$$
\begin{align}
\int_1^x \{ye^{-t^2}\}'dt &=&\int_1^x e^{-t^2}tdt \\
\left[ye^{-t^2}\right]_1^x &=& \left[-{1\over 2}e^{-t^2}\right]_1^x \\
ye^{-x^2}-2e^{-1} &=& -{1\over 2}e^{-x^2}+{1\over 2}e^{-1} \\
ye^{-x^2} &=& -{1\over 2}e^{-x^2}+{5\over 2}e^{-1}
\end{align}
$$

```latex
%%latex
\begin{array}{lcl}
    \displaystyle
    \int_{0}^{1} \log x dx
     & = & \displaystyle \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x dx \\
     & = & \displaystyle \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1} \\
     & = & -1
\end{array}
```

\begin{array}{lcl}
    \displaystyle
    \int_{0}^{1} \log x dx
     & = & \displaystyle \lim_{\epsilon \to +0} \int_{\epsilon}^{1} \log x dx \\
     & = & \displaystyle \lim_{\epsilon \to +0} [x \log x - x]_{\epsilon}^{1} \\
     & = & -1
\end{array}

```python
# \begin{array} の使い方。
%%latex
\displaystyle
\begin{array}
    lkj;lkj & = & jk          \\
            & = & kj;ljk;jk;j
\end{array}
```

\displaystyle
\begin{array}
    lkj;lkj & = & jk          \\
            & = & kj;ljk;jk;j
\end{array}

# array で行間が狭いとき
array で行間が狭いときには \\ のあとに [0.3em] とか入れる

$$
\displaystyle
\begin{array}{lcl}
    \sin(\alpha \pm \beta) & = & \sin \alpha \cos \beta \pm \cos \alpha \sin \beta               \\
    \cos(\alpha \pm \beta) & = & \cos \alpha \cos \beta \mp \sin \alpha \sin \beta               \\[0.5em]
    \tan(\alpha \pm \beta) & = & \displaystyle \frac{\tan \alpha \pm \tan \beta}{1 \mp \tan \alpha \tan \beta}
\end{array}
$$

```python
# 行間がきついときには \\ のあとに [0.3em] とか入れる
%%latex
\displaystyle
\begin{array}{lcl}
    \sin(\alpha \pm \beta) & = & \sin \alpha \cos \beta \pm \cos \alpha \sin \beta               \\
    \cos(\alpha \pm \beta) & = & \cos \alpha \cos \beta \mp \sin \alpha \sin \beta               \\[0.3em]
    \tan(\alpha \pm \beta) & = & \displaystyle \frac{\tan \alpha \pm \tan \beta}{1 \mp \tan \alpha \tan \beta}
\end{array}
```

\displaystyle
\begin{array}{lcl}
    \sin(\alpha \pm \beta) & = & \sin \alpha \cos \beta \pm \cos \alpha \sin \beta               \\
    \cos(\alpha \pm \beta) & = & \cos \alpha \cos \beta \mp \sin \alpha \sin \beta               \\[0.3em]
    \tan(\alpha \pm \beta) & = & \displaystyle \frac{\tan \alpha \pm \tan \beta}{1 \mp \tan \alpha \tan \beta}
\end{array}

```python
# 括弧のいろいろ 丸括弧 波括弧 角括弧 絶対値
%%latex
[ (x) ] \\
\{ x \}\\
\| x \| \\
| x | \\
\langle x \rangle
```

[ (x) ] \\
\{ x \}\\
\| x \| \\
| x | \\
\langle x \rangle

```latex
%%latex
\displaystyle
\Bigg( \bigg[ \Big\{ \big\| \langle x \rangle \big\| \Big\} \bigg] \Bigg)
```

\displaystyle
\Bigg( \bigg[ \Big\{ \big\| \langle x \rangle \big\| \Big\} \bigg] \Bigg)

左右の括弧に`\left`、`\right`をつけると自動で可変になる。 大きくなる。
\left`、`\right`はかならずペアで、片方だけ使うときはピリオド `.` をつける。
$$
\displaystyle
\left( \frac{a}{b} \right)
\left( \int_a^\infty x \, dx \right)
$$

左寄せ、センタリング、右寄せ

$$
\begin{array}{lcr}
111 & 222 & 333 \\
44  & 55  & 66 \\
7   & 8   & 9
\end{array}
$$

```latex
%%latex

\begin{array}{lcr}
111 & 222 & 333 \\
44  & 55  & 66 \\
7   & 8   & 9
\end{array}
```

\begin{array}{lcr}
111 & 222 & 333 \\
44  & 55  & 66 \\
7   & 8   & 9
\end{array}

# 括弧のいろいろ 丸括弧 波括弧 角括弧 絶対値 大括弧 可変括弧 片括弧 山括弧
$$
[ (x) ] \\
\{ x \}\\
\| x \| \\
| x | \\
\langle x \rangle
$$

左右の括弧に`\left`、`\right`をつけると自動で可変になる。 大きくなる。
`\left`、`\right`はかならずペアで、片方だけ使うときはピリオド `.` をつける。

$$
\left( \frac{a}{b} \right)
\left( \int_a^\infty x \, dx \right)
$$

```python
# 左右の括弧に`\left`、`\right`をつけると自動で可変になる。 大きくなる。
# `\left`、`\right`はかならずペアで、片方だけ使うときはピリオド `.` をつける。
%%latex
\displaystyle
\left( \frac{a}{b} \right)
\left( \int_a^\infty x \, dx \right)
```

\displaystyle
\left( \frac{a}{b} \right)
\left( \int_a^\infty x \, dx \right)

# 片括弧
$$
\displaystyle
\left\{ \frac{a}{b} \right.
$$

$$
\left\{
\begin{array}{lcl}
    \sin(\alpha \pm \beta) & = & \sin \alpha \cos \beta \pm \cos \alpha \sin \beta               \\
    \cos(\alpha \pm \beta) & = & \cos \alpha \cos \beta \mp \sin \alpha \sin \beta               \\[0.3em]
    \tan(\alpha \pm \beta) & = & \displaystyle \frac{\tan \alpha \pm \tan \beta}{1 \mp \tan \alpha \tan \beta}
\end{array}
\right.
$$

```python
# 括弧を片方だけつかってみる
%%latex
\displaystyle
\left\{ \frac{a}{b} \right.
```

\displaystyle
\left\{ \frac{a}{b} \right.

```python
# 括弧を片方だけつかってみる
%%latex
\displaystyle
\left\{
\begin{array}{lcl}
    \sin(\alpha \pm \beta) & = & \sin \alpha \cos \beta \pm \cos \alpha \sin \beta               \\
    \cos(\alpha \pm \beta) & = & \cos \alpha \cos \beta \mp \sin \alpha \sin \beta               \\[0.3em]
    \tan(\alpha \pm \beta) & = & \displaystyle \frac{\tan \alpha \pm \tan \beta}{1 \mp \tan \alpha \tan \beta}
\end{array}
\right.
```

\displaystyle
\left\{
\begin{array}{lcl}
    \sin(\alpha \pm \beta) & = & \sin \alpha \cos \beta \pm \cos \alpha \sin \beta               \\
    \cos(\alpha \pm \beta) & = & \cos \alpha \cos \beta \mp \sin \alpha \sin \beta               \\[0.3em]
    \tan(\alpha \pm \beta) & = & \displaystyle \frac{\tan \alpha \pm \tan \beta}{1 \mp \tan \alpha \tan \beta}
\end{array}
\right.

行列を括弧で囲むには array ではなく pmatrix を使う。
\left(,\right) を使うこともできる
$$
%%latex
\begin{pmatrix}
    111 & 222 & 333 \\
    44  & 55  & 66  \\
    7   & 8   & 9
\end{pmatrix}
$$
$$
\left(
\begin{array}{rrr}
    111 & 222 & 333 \\
    44  & 55  & 66  \\
    7   & 8   & 9
\end{array}
\right)
$$

```python
# 行列を括弧で囲むには array ではなく pmatrix を使う。
# \left(,\right) を使うこともできる
%%latex
\begin{pmatrix}
    111 & 222 & 333 \\
    44  & 55  & 66  \\
    7   & 8   & 9
\end{pmatrix}
{}\\
\left(
\begin{array}{rrr}
    111 & 222 & 333 \\
    44  & 55  & 66  \\
    7   & 8   & 9
\end{array}
\right)
```

\begin{pmatrix}
    111 & 222 & 333 \\
    44  & 55  & 66  \\
    7   & 8   & 9
\end{pmatrix}
{}\\
\left(
\begin{array}{rrr}
    111 & 222 & 333 \\
    44  & 55  & 66  \\
    7   & 8   & 9
\end{array}
\right)

pmatrix は array のように item の位置指定ができない。

$$
\begin{pmatrix}
a & longitem \\
128 & 3.1419
\end{pmatrix}
$$

```python
# pmatrix は array のように item の位置を指定することはできないみたい
%%latex
\displaystyle
\begin{pmatrix}
a & longitem \\
128 & 3.1419
\end{pmatrix}
```

\displaystyle
\begin{pmatrix}
a & longitem \\
128 & 3.1419
\end{pmatrix}

# 複素関数

**複素関数**
$$
f(z) = f(x + i y ) = u (x, y) + iv(x, y) \\
$$
が点 \\
$$
z_0 = x_0 + iy_0
$$

において正則であるための必要十分条件は、
$ z_0 $
のある
$ \varepsilon $
近傍
$\Delta (z_0, \varepsilon) $
においてコーシー・リーマン方程式

$$
\begin {array}{ccc}
    \displaystyle \frac{\partial u}{\partial x} &=& \displaystyle \frac{\partial v}{\partial y} \\
    \displaystyle \frac{\partial u}{\partial y} &=& \displaystyle - \frac{\partial v}{\partial x}
\end {array}
$$

を満たすことである。

```latex
%%latex
複素関数   \\
f(z) = f(x + i y ) = u (x, y) + iv(x, y) \\
が点 \\
z_0 = x_0 + iy_0 \\
において正則であるための必要十分条件は、 \\
z_0
のある
\varepsilon
近傍 \\
\Delta (z_0, \varepsilon) \\
においてコーシー・リーマン方程式 \\

\begin {array}{ccc}
    \displaystyle \frac{\partial u}{\partial x} &=& \displaystyle \frac{\partial v}{\partial y} \\
    \displaystyle \frac{\partial u}{\partial y} &=& \displaystyle - \frac{\partial v}{\partial x}
\end {array}
\\
を満たすことである。
```

複素関数   \\
f(z) = f(x + i y ) = u (x, y) + iv(x, y) \\
が点 \\
z_0 = x_0 + iy_0 \\
において正則であるための必要十分条件は、 \\
z_0
のある
\varepsilon
近傍 \\
\Delta (z_0, \varepsilon) \\
においてコーシー・リーマン方程式 \\

\begin {array}{ccc}
    \displaystyle \frac{\partial u}{\partial x} &=& \displaystyle \frac{\partial v}{\partial y} \\
    \displaystyle \frac{\partial u}{\partial y} &=& \displaystyle - \frac{\partial v}{\partial x}
\end {array}
\\
を満たすことである。

# 空間曲線

**空間曲線**
$$
c(t) = (x (t), y(t), z(t)) $$

によって与えられる空間曲線 c の $
c(0)$ を始点として $c(t)$ までの弧長を $s(t)$ とすると

$$
s(t) = \displaystyle \int_0^t \sqrt { (\frac {dx}{dt})^2
       + (\frac {dy}{dt})^2 + (\frac {dz}{dt})^2}
$$
と表される。

```latex
%%latex
c(t) = (x (t), y(t), z(t)) \\
によって与えられる空間曲線 c の \\
c(0) を始点として c(t) までの弧長を s(t) とすると \\

s(t) = \displaystyle \int_0^t \sqrt { (\frac {dx}{dt})^2
       + (\frac {dy}{dt})^2 + (\frac {dz}{dt})^2}
\\
と表される。
```

c(t) = (x (t), y(t), z(t)) \\
によって与えられる空間曲線 c の \\
c(0) を始点として c(t) までの弧長を s(t) とすると \\

s(t) = \displaystyle \int_0^t \sqrt { (\frac {dx}{dt})^2
       + (\frac {dy}{dt})^2 + (\frac {dz}{dt})^2}
\\
と表される。

# 微分可能

**微分可能**

関数 $f$ が開区間 $I$ 上で $n$ 回微分可能であるとする。
このとき、$a, b \in I$ に対し、

$$
f(b) = \displaystyle f(a)+ \frac{f'(a)}{1!} (b - a)
    + \frac{f''(a)}{2!} (b - a)^2 + \cdots
    + \frac{f^{(n - 1)}(a)}{(n - 1)!} (b - a)^{(n - 1)} + R_n(c)
$$

を満たす $c$ が $a$ と $b$ の間に存在する。

```python
# 微分可能
%%latex
関数 f が開区間 I 上で n 回微分可能であるとする。 \\
このとき、a, b \in I に対し、\\

f(b) = \displaystyle f(a)+ \frac{f'(a)}{1!} (b - a)
    + \frac{f''(a)}{2!} (b - a)^2 + \cdots
    + \frac{f^{(n - 1)}(a)}{(n - 1)!} (b - a)^{(n - 1)} + R_n(c)
\\
を満たす c が a と b の間に存在する。

```

関数 f が開区間 I 上で n 回微分可能であるとする。 \\
このとき、a, b \in I に対し、\\

f(b) = \displaystyle f(a)+ \frac{f'(a)}{1!} (b - a)
    + \frac{f''(a)}{2!} (b - a)^2 + \cdots
    + \frac{f^{(n - 1)}(a)}{(n - 1)!} (b - a)^{(n - 1)} + R_n(c)
\\
を満たす c が a と b の間に存在する。

# $n$ 次正方行列

**$n$ 次正方行列**
$$
J (\alpha, m) = \begin {bmatrix}
                    \alpha & 1 & 0 & \ldots & 0 \\
                    0 & \alpha & 1 & \ddots & \vdots \\
                    \vdots & \ddots & \ddots & \ddots & 0 \\
                    \vdots &  & \ddots & \ddots & 1 \\
                    0 & \ldots & \ldots & 0 & \alpha
                \end {bmatrix}
$$

を Jordan 細胞と呼ぶ。 正方行列 $A$ が正則行列 $P$ によって

$$
\begin {array} {lcl}
P^{-1} A P &=& J(\alpha_1, m_1) \oplus J(\alpha_2, m_2) \oplus \cdots \oplus J(\alpha_k, m_k)  \\
&=& \begin {bmatrix}
        J(\alpha_1, m_1) & & & \\
        & J(\alpha_2, m_2) & & \\
        & & \ddots & \\
        & & & j(\alpha_k, m_k)
    \end {bmatrix}
\end {array} \\
$$

と Jordan 細胞の直和になるとき、これを $A$ の Jordan 標準形と呼ぶ。

```python
# n次正方行列
%%latex
J (\alpha, m) = \begin {bmatrix}
                    \alpha & 1 & 0 & \ldots & 0 \\
                    0 & \alpha & 1 & \ddots & \vdots \\
                    \vdots & \ddots & \ddots & \ddots & 0 \\
                    \vdots &  & \ddots & \ddots & 1 \\
                    0 & \ldots & \ldots & 0 & \alpha
                \end {bmatrix} \\
を Jordan 細胞と呼ぶ。 正方行列 A が正則行列 P によって \\
\begin {array} {lcl}
P^{-1} A P &=& J(\alpha_1, m_1) \oplus J(\alpha_2, m_2) \oplus \cdots \oplus J(\alpha_k, m_k)  \\
&=& \begin {bmatrix}
        J(\alpha_1, m_1) & & & \\
        & J(\alpha_2, m_2) & & \\
        & & \ddots & \\
        & & & j(\alpha_k, m_k)
    \end {bmatrix}
\end {array} \\
と Jordan 細胞の直和になるとき、これを A の Jordan 標準形と呼ぶ。

```

J (\alpha, m) = \begin {bmatrix}
                    \alpha & 1 & 0 & \ldots & 0 \\
                    0 & \alpha & 1 & \ddots & \vdots \\
                    \vdots & \ddots & \ddots & \ddots & 0 \\
                    \vdots &  & \ddots & \ddots & 1 \\
                    0 & \ldots & \ldots & 0 & \alpha
                \end {bmatrix} \\
を Jordan 細胞と呼ぶ。 正方行列 A が正則行列 P によって \\
\begin {array} {lcl}
P^{-1} A P &=& J(\alpha_1, m_1) \oplus J(\alpha_2, m_2) \oplus \cdots \oplus J(\alpha_k, m_k)  \\
&=& \begin {bmatrix}
        J(\alpha_1, m_1) & & & \\
        & J(\alpha_2, m_2) & & \\
        & & \ddots & \\
        & & & j(\alpha_k, m_k)
    \end {bmatrix}
\end {array} \\
と Jordan 細胞の直和になるとき、これを A の Jordan 標準形と呼ぶ。

# 二項関係

**定義 1** 集合 $X$ 上の二項関係 $\rho$ について、次の性質を考える。

1. すべての $x \in X$ について、$x \;\rho\; x$ が成り立つ。(反射律)

1. $x, y \in X$ について、$x \;\rho\; y$ ならば $y \;\rho\; x$ が成り立つ。(対称律)

1. $x, y, z \in X$ について、$x \;\rho\; y$ かつ $y \;\rho\; z$ ならば $x \;\rho\; z$ が成り立つ。(推移律)

1. $x, y \in X$ について、$x \;\rho\; y$ かつ $y \;\rho\; x$ ならば $x = y$ が成り立つ。(反対称律)

性質 $\it{1, 2, 3}$ を満たす二項関係を**同値関係**と呼び、性質 $\it{1, 3, 4}$ を満たす二項関係を**順序関係**と呼ぶ。

* reflexive law 反射律
* transitive law 推移律
* symmetric law 対称律
* antisymmetric law 反対称律

```latex
%%latex
定義 1 集合 X 上の二項関係 \;\rho\; について、次の性質を考える。\\

1. すべての x \in X について、x \;\rho\; x が成り立つ。(反射律) \\
2. x, y \in X について、x \;\rho\; y ならば y \;\rho\; x が成り立つ。(対称律) \\
3. x, y, z \in X について、x \;\rho\; y かつ y \;\rho\; z ならば x \;\rho\; z が成り立つ。(推移律) \\
4. x, y \in X について、x \;\rho\; y かつ y \;\rho\; x ならば x = y が成り立つ。(反対称律) \\
性質 \it{1, 2, 3} を満たす二項関係を同値関係と呼び、性質 \it{1, 3, 4} を満たす二項関係を順序関係と呼ぶ。 \\
```

定義 1 集合 X 上の二項関係 \;\rho\; について、次の性質を考える。\\

1. すべての x \in X について、x \;\rho\; x が成り立つ。(反射律) \\
2. x, y \in X について、x \;\rho\; y ならば y \;\rho\; x が成り立つ。(対称律) \\
3. x, y, z \in X について、x \;\rho\; y かつ y \;\rho\; z ならば x \;\rho\; z が成り立つ。(推移律) \\
4. x, y \in X について、x \;\rho\; y かつ y \;\rho\; x ならば x = y が成り立つ。(反対称律) \\
性質 \it{1, 2, 3} を満たす二項関係を同値関係と呼び、性質 \it{1, 3, 4} を満たす二項関係を順序関係と呼ぶ。 \\

# 集合の内包表記 set comprehension

参考 集合で習う集合の内包表記は数式で次の様に書く。

$
S= \{2x \mid x \in  \mathbb{N}, \ x \leq 10 \}
$

プログラミングでは list comprehension と言うと思うが。

```python
# 参考 集合で習う集合の内包表記は数式で次の様に書く。
%%latex

S= \{2x \mid x \in  \mathbb{N}, \ x \leq 10 \}

```

S= \{2x \mid x \in  \mathbb{N}, \ x \leq 10 \}

# 練習問題

---
2 次方程式
$$ ax^{2}+bx+c=0 $$
の解は
$$ x = \frac{-b\pm\sqrt{b^{2}-4ac}}{2a} \tag{1}$$
である。

---
総和記号 シグマ はこんな感じ。

$$\sum_{k=1}^{n} a_{k} = a_{1} + a_{2} + \dots + a_{n}$$

---
ガウス積分

$$
\int_{-\infty}^{\infty} e^{-x^{2}} \, dx = \sqrt{\pi}
$$

---
関数 $f(x)$ の導関数は
$$
f’(x) = \lim_{\varDelta x \to 0} \frac{ f(x+\varDelta x) - f(x) }{\varDelta x}$$
である。

---
三角関数の積分

$$\int \tan\theta \, d\theta = \int \frac{\sin\theta}{\cos\theta} \, d\theta= -\log |\cos\theta| + C$$

---
式の変形
$$
\begin{align}\cos 2\theta &= \cos^{2} \theta - \sin^{2} \theta \\&= 2\cos^{2} \theta - 1 \\&= 1 - 2\sin^{2} \theta\end{align}
$$

---
片括弧、大括弧、大波括弧、cases

$$
|x| =
\begin{cases}
fx  & x \ge 0のとき\\
-x & x \lt 0のとき
\end{cases}\
$$

---
行列 $n \times n$ 行列

$$A =\begin{pmatrix}
a_{11} & a_{12} & \ldots & a_{1n} \\
a_{21} & a_{22} & \ldots & a_{2n} \\
\vdots & \vdots & \ddots & \vdots \\
a_{n1} & a_{n2} & \ldots & a_{nn}
\end{pmatrix} $$

が逆行列 $A^{-1}$ をもつための必要十分条件は、$ \det A \neq 0 $ である。

---
行列を囲む括弧のいろいろ

丸括弧、角括弧、波括弧、縦棒、 二重の縦棒括弧なし

$$
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix},\;
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix},\;
\begin{Bmatrix}
a & b \\
c & d
\end{Bmatrix},\;
\begin{vmatrix}
a & b \\
c & d
\end{vmatrix},\;
\begin{Vmatrix}
a & b \\
c & d
\end{Vmatrix},\;
\begin{matrix}
a & b \\
c & d
\end{matrix}
$$

---
$$

# マクロの定義
$$
\def\RR{{\mathbb R}}
\def\bol#1{{\bf #1}}
\RR \\
\bol {crazy\;rich\;tycoon}\\
\def \x {\times}
3 \x 3 = 9\\
\def\dd#1#2{\frac{\partial #1}{\partial #2}}
\dd{x}{y}
$$

```latex
%%latex
\def\RR{{\mathbb R}}
\def\bol#1{{\bf #1}}
\RR \\
\bol {crazy\;rich\;tycoon}\\
\def \x {\times}
3 \x 3 = 9\\
\def\dd#1#2{\frac{\partial #1}{\partial #2}}
\dd{x}{y}
```

\def\RR{{\mathbb R}}
\def\bol#1{{\bf #1}}
\RR \\
\bol {crazy\;rich\;tycoon}\\
\def \x {\times}
3 \x 3 = 9\\
\def\dd#1#2{\frac{\partial #1}{\partial #2}}
\dd{x}{y}

---
ベクトル場 $\boldsymbol B (x,y,z)$ が

$$
\def \x {\times}
\boldsymbol B = \nabla \x\boldsymbol A \tag{1.1}
$$

という形に書ける時、その発散

$$
\def\dd#1#2{\frac{\partial #1}{\partial #2}}
\nabla \cdot\boldsymbol{B} = \dd{B_{x}}{x} + \dd{B_{y}}{y} + \dd{B_{z}}{z} \tag{1.2}
$$

は $0$ になる。 式 (1.1) に現れる $\boldsymbol{A,B}$ をベクトルポテンシャルと言う。

# 演習問題

---
オイラーの公式

$$
e^{i\theta}=\cos \theta + i \sin \theta
$$

---
テイラー展開

$$
f(x) = \sum^\infty_{n=0}\frac{f^{(n)}(a)}{n !} (x-a)^n
$$

---
正規分布

$$
f(x)=\frac 1 {\sqrt{2\pi \sigma^2}}\exp\left (-\frac{(x-\mu)^2}{2\sigma^2}\right)
$$

---
ニュートンの運動方程式

$$
m \frac{d^2 \overrightarrow r}{d t^2}=\overrightarrow F
$$

---
ラグランジュの運動方程式

$$
\frac d {dt}\left(\frac{\partial \mathcal L}{\partial \dot q} \right) - \frac{\partial \mathcal L}{\partial q} = 0
$$

---
フーリエ変換

$$
\hat f (\xi) = \int_{\mathbb R ^n} f(x) e ^{-2 \pi i x \cdot \xi} dx
$$

---
コーシーの積分方程式

$$
f(\alpha)=\frac 1 {2\pi i} \oint_C \frac{f(z)}{z - \alpha} d z
$$

---
ガウスの定理

$$
\iiint_V \nabla \cdot\boldsymbol A \; dV = \iint_{\partial V}\boldsymbol A \cdot\boldsymbol n \; dS
$$

---
シュレーディンガー方程式

$$
i \hbar \frac \partial {\partial t} \psi (r,t) = \left (-\frac{\hbar}{2m}\nabla^2+V(r,t) \right)\psi(r,t)
$$

---
メモ $\quad$ 上記では `\left (, \right )` を使ったが、
* \bigl,\Bigl,\biggl,\Biggl
* \bigr,\Bigr,\biggr,\Biggr
* \bigm,\Bigm,\biggm,\Biggm \\
という体系もある。

---
熱化学方程式

$$
\mathrm{H_2(g) + {1 \over 2} O_2(g) \rightarrow H_2O(l)} \quad \varDelta H^\circ = -286\mathrm{kJ}
$$

集合記号・内包表記 list comprehension

$$
A \cap B = \{x \;|\; x \in A \land x \in B\}
$$

---
メモ
* \\{ , \\}： $\{$, $\}$ 波括弧だけでは表示されない
* \cap, \cup, \wedge, \land, \lor, \vee：$\cap, \cup, \wedge, \land, \lor, \vee$
* \in, \ni, \notin, \subset, \supset：$\in, \ni, \notin, \subset, \supset$
* \emptyset, \forall, \exists, \neg：$\emptyset, \forall, \exists, \neg$

---
二項係数

$$
{}_n C_r = \binom n r = \frac{n!}{r! (n-r)!}
$$

---
マクスウェル方程式

$$
\begin{array}{ll}
\displaystyle
\nabla \cdot E = \frac \rho {\varepsilon_0},
&\qquad
\displaystyle
\nabla \cdot E = - \frac {\partial B}{\partial t}\\
\nabla \cdot B = 0,
&\qquad
\nabla \cdot B = \mu_0 i + \displaystyle \frac 1 {c^2} \frac {\partial E}{\partial t}
\end{array}
$$


# Python Basics
© Explore Data Science Academy

## Learning Objectives:
By the end of this train, you should be able to:
* Perform basic print functions and string manipulation; and
* Create basic Python functions.

## Outline
In this train we will:
* Introduce print statements;
* Perform basic string manipulation; and
* Breakdown the different aspects of Python Functions.

## Print Statements and Strings

The standard introduction into any programming language is the ''Hello world!'' program. This is a computer program that outputs "Hello world!" to your console window. In Python, this program can be implemented using the **print** built-in function as follows:

```python
print("Hello world!")
```

    Hello world!

The **print** function "prints" the value stored in Python variables/objects as a **string** to the console, or other standard output devices. A **string** is a data type used to represent text, i.e. a sequence of characters. In the Python programming language, strings can be specified by encasing a sequence of characters within single or double-quotes.

```python
String_1 = "This is a string."
String_2 = ' This is also a string :)'

print(String_1)
print(String_2)
```

    This is a string.
     This is also a string :)

Sometimes, strings will also contain quotation marks or other special characters. To avoid syntax errors in such cases, we need to use the escape character or backslash ```"\"```.  Prefixing a special character with ```"\"``` turns it into an ordinary character. Additionally, the backslash ```"\"``` can be used to specify special characters such as the newline ```"\n"```, tab ```"\t"```, carriage return ```"\r"```, etc.

```python
String_3 = 'This shouldn't work.'
```

```python
String_3 = 'This shouldn\'t break.'
print(String_3)
```

    This shouldn't break.

The escape character can also be used to specify characters using unicodes.

```python
print("Grinning face: \U0001f600")
print("Squinting face: \U0001F606")
print("ROFL face: \U0001F923")
```

    Grinning face: 😀
    Squinting face: 😆
    ROFL face: 🤣

As you might have noticed, the print function appends a newline character ```"\n"``` to its output. This forces consecutive print calls to start on a new line. We can avoid this by assigning the 'end'  argument in the print function to an empty string.

```python
print(String_1, end='')
print(String_2)
```

    This is a string. This is also a string :)

We can achieve the same effect by using string concatenation. This operation allows us to combine two or more strings together.

```python
print(String_1 + String_2)
```

    This is a string. This is also a string :)

We can also concatenate strings with other data types by first converting them into strings using the **str()** in-built function.

```python
num_chars = len(String_1)
print("String_1 is "+str(num_chars)+" characters long")
```

    String_1 is 17 characters long

Alternatively, this concatenation can be performed by passing a list of comma-separated inputs into the print function.

```python
print("String_1 is",num_chars,"characters long")
```

    String_1 is 17 characters long

Notice that we didn't need to add extra spacing around the first and last strings and didn't need to convert the num_chars integer into a string.

The **print** function can be extremely useful for debugging purposes. For example, printing out the value of the variable before or after mathematical operations to ensure the correct operation occurred.

```python
a = 3
b = a%2
c = b**2
d = a/(c*5) + b

print(d)
```

    1.6

## Functions

A function is a block of organised, reusable code that is used to perform an action.

The image above points out all the components of a function in Python.

### def

We can define a function using the `def` keyword. This `def` keyword is then followed by a name for the function and two brackets (we'll get back to this later). It is important to note that everything inside the function must be indented by one tab deeper than `def`.

```python
def name_of_your_function(a, b, c):
    some_result = do_something_with(a and b and c)
    return some_result
```

Here is a simple example.

```python
def monthly_expenses(rent, food):
    total_expenses = rent + food
    return total_expenses
```

Now lets consider the following function.

```python
def print_something():
    print('SoMeThInG')
```

We can run this function by writing the name of the function, followed by two brackets:

```python
print_something()
```

    SoMeThInG

### return

In the above example, we printed something in the function.  But, more often than not, we would want to **return** something from the function. It's useful (at least at the start) to think of **return** as the function passing something back to whoever ran it.

```python
def return_something():
    return 'SoMeThInG'
```

```python
return_something()
```

    'SoMeThInG'

We notice ``return_something`` returns a string. This is different from `print_something` which won't give us any result **out**, but merely *print it*:

```python
print_something()
```

    SoMeThInG

### Arguments

Let's say we want to write a function that returns the result of the future value equation:

$(1 + i)^n$

where $i$, and $n$ are both numbers. We can pass in the values of i and n into the function, by defining it as follows.

```python
def future_value(i, n):
    result = (1 + i)**n
    return result
```

We can then call our function with any values of i and n.

```python
future_value(0.05, 20)
```

    2.653297705144422

The `i` and the `n` inside `equation(i, n)` are called **arguments** to the function. Function arguments allow us to make generic functions that can be used with infinitely many variations.

```python
future_value(0.1, 20)
```

    6.727499949325611

```python
future_value(0.15, 20)
```

    16.36653739294609

## Scope of Variables

Variable scope refers to how accessible a variable is to different parts of the program. The scope of a variable can be **local** or **global**, we illustrate the difference in the example below.

```python
y = 10
def my_function():
    x = 2
    print("Inside function, x =",x)
    print("Inside function, y =",y)

    return

my_function()
print("Outside function, y =",y)
print("Outside function, x =",x)

```

**Local variables** only exist within a context, in the above example, this refers to the body of the function. Furthermore, they can only be accessed within this context. On the other hand, **global variables** can be accessed from anywhere in the code. ```x``` is a local variable and only exists within ```my_function``` and attempting to access if outside the function, results in an error. ```y``` however, is a global variable and can be accessed both inside and outside of the function.

To declare global variables within a context, we can use the ```global``` keyword as follows:

```python
y = 9
def my_other_function():
    global x
    x = 3
    print("Inside function, x =",x)
    print("Inside function, y =",y)

    return

my_other_function()
print("Outside function, y =",y)
print("Outside function, x =",x)
```

    Inside function, x = 3
    Inside function, y = 9
    Outside function, y = 9
    Outside function, x = 3

## Exercises
### Exercise 1: Interest rates

You just turned 20 and you want to buy a new pair of shoes to wear at your party. The shoes cost R1000.
You're broke right now, but you know that in a year's time - when you turn 21 - you will get a lot of money from your relatives for your 21st birthday.

FedBank is willing to lend you R1000, at 20% interest per year.

Assuming that you take the loan - how much will you have to pay back in one year?

***
Loan summary:

*   $PV$:     **R1000**
*   $n$:      **1 year**
*   $i$:      **20% interest** per annum, compounded annually

Given a present value loan amount, PV, the formula for a future repayment (FV) is given by:

\begin{equation}
FV = PV(1 + i)^n
\end{equation}

***

In Python we'd calculate this value as follows:

```python
# Present Value of the Loan amount:
PV = 1000

# Interest rate, i:
i = 20 / 100

# Term in years, n:
n = 1

#Calculate the Future Value, FV:
PV*(1 + i)**n
```

    1200.0

So, if you decide to go ahead with the purchase, you'll need to pay an extra R200 to FedBank after 1 year.

### Exercise 2: Future Value Formula

Now, perform the exact same calculation, just using a function! Create a function called `future_value`, that takes the following arguments: present value $PV$, interest rate $i$, and a term $n$, and returns the future repayment value ($FV$) of that loan.

```python
def future_value_of(PV, i, n):
    # YOUR CODE HERE:
    # FV = some formula
    return FV
```

```python
future_value_of(500, 0.15, 10)
```

Your code should give the following results:

*   `future_value(100, 0.1, 20) = 672.7499949325611`
*   `future_value(500, 0.15, 10) = 2022.7788678539534`

## Conclusion

In this train, you learned to perform basic operations using print statements and strings, as well as the basic aspects of Python functions and the scope of variables. The reader is expected to complete the exercises before moving forward to ensure familiarity with these concepts.

## Appendix

- [Print Statement](https://www.w3schools.com/python/ref_func_print.asp)

- [Functions](https://www.w3schools.com/python/python_functions.asp)


# Lambda School Data Science Module 143

## Introduction to Bayesian Inference

!['Detector! What would the Bayesian statistician say if I asked him whether the--' [roll] 'I AM A NEUTRINO DETECTOR, NOT A LABYRINTH GUARD. SERIOUSLY, DID YOUR BRAIN FALL OUT?' [roll] '... yes.'](https://imgs.xkcd.com/comics/frequentists_vs_bayesians.png)

*[XKCD 1132](https://www.xkcd.com/1132/)*

## Prepare - Bayes' Theorem and the Bayesian mindset

Bayes' theorem possesses a near-mythical quality - a bit of math that somehow magically evaluates a situation. But this mythicalness has more to do with its reputation and advanced applications than the actual core of it - deriving it is actually remarkably straightforward.

### The Law of Total Probability

By definition, the total probability of all outcomes (events) if some variable (event space) $A$ is 1. That is:

$$P(A) = \sum_n P(A_n) = 1$$

The law of total probability takes this further, considering two variables ($A$ and $B$) and relating their marginal probabilities (their likelihoods considered independently, without reference to one another) and their conditional probabilities (their likelihoods considered jointly). A marginal probability is simply notated as e.g. $P(A)$, while a conditional probability is notated $P(A|B)$, which reads "probability of $A$ *given* $B$".

The law of total probability states:

$$P(A) = \sum_n P(A | B_n) P(B_n)$$

In words - the total probability of $A$ is equal to the sum of the conditional probability of $A$ on any given event $B_n$ times the probability of that event $B_n$, and summed over all possible events in $B$.

### The Law of Conditional Probability

What's the probability of something conditioned on something else? To determine this we have to go back to set theory and think about the intersection of sets:

The formula for actual calculation:

$$P(A|B) = \frac{P(A \cap B)}{P(B)}$$

Think of the overall rectangle as the whole probability space, $A$ as the left circle, $B$ as the right circle, and their intersection as the red area. Try to visualize the ratio being described in the above formula, and how it is different from just the $P(A)$ (not conditioned on $B$).

We can see how this relates back to the law of total probability - multiply both sides by $P(B)$ and you get $P(A|B)P(B) = P(A \cap B)$ - replaced back into the law of total probability we get $P(A) = \sum_n P(A \cap B_n)$.

This may not seem like an improvement at first, but try to relate it back to the above picture - if you think of sets as physical objects, we're saying that the total probability of $A$ given $B$ is all the little pieces of it intersected with $B$, added together. The conditional probability is then just that again, but divided by the probability of $B$ itself happening in the first place.

\begin{align}
P(A|B) &= \frac{P(A \cap B)}{P(B)}\\
\Rightarrow P(A|B)P(B) &= P(A \cap B)\\
P(B|A) &= \frac{P(B \cap A)}{P(A)}\\
\Rightarrow P(B|A)P(A) &= P(B \cap A)\\
\Rightarrow P(A|B)P(B) &= P(B|A)P(A) \\
P(A \cap B) &= P(B \cap A)\\
P(A|B) &= \frac{P(B|A) \times P(A)}{P(B)}
\end{align}

### Bayes Theorem

Here is is, the seemingly magic tool:

$$P(A|B) = \frac{P(B|A)P(A)}{P(B)}$$

In words - the probability of $A$ conditioned on $B$ is the probability of $B$ conditioned on $A$, times the probability of $A$ and divided by the probability of $B$. These unconditioned probabilities are referred to as "prior beliefs", and the conditioned probabilities as "updated."

Why is this important? Scroll back up to the XKCD example - the Bayesian statistician draws a less absurd conclusion because their prior belief in the likelihood that the sun will go nova is extremely low. So, even when updated based on evidence from a detector that is $35/36 = 0.972$ accurate, the prior belief doesn't shift enough to change their overall opinion.

There's many examples of Bayes' theorem - one less absurd example is to apply to [breathalyzer tests](https://www.bayestheorem.net/breathalyzer-example/). You may think that a breathalyzer test that is 100% accurate for true positives (detecting somebody who is drunk) is pretty good, but what if it also has 8% false positives (indicating somebody is drunk when they're not)? And furthermore, the rate of drunk driving (and thus our prior belief)  is 1/1000.

What is the likelihood somebody really is drunk if they test positive? Some may guess it's 92% - the difference between the true positives and the false positives. But we have a prior belief of the background/true rate of drunk driving. Sounds like a job for Bayes' theorem!

$$
\begin{aligned}
P(Drunk | Positive) &= \frac{P(Positive | Drunk)P(Drunk)}{P(Positive)} \\
&= \frac{1 \times 0.001}{0.08} \\
&= 0.0125
\end{aligned}
$$

In other words, the likelihood that somebody is drunk given they tested positive with a breathalyzer in this situation is only 1.25% - probably much lower than you'd guess. This is why, in practice, it's important to have a repeated test to confirm (the probability of two false positives in a row is $0.08 * 0.08 = 0.0064$, much lower), and Bayes' theorem has been relevant in court cases where proper consideration of evidence was important.

Source: <https://en.wikipedia.org/wiki/Bayes%27_theorem>

## Live Lecture - Deriving Bayes' Theorem, Calculating Bayesian Confidence

Notice that $P(A|B)$ appears in the above laws - in Bayesian terms, this is the belief in $A$ updated for the evidence $B$. So all we need to do is solve for this term to derive Bayes' theorem. Let's do it together!

```
# Activity 2 - Use SciPy to calculate Bayesian confidence intervals
# https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.bayes_mvs.html#scipy.stats.bayes_mvs
```

```
from scipy import stats
import numpy as np

np.random.seed(seed=42)

coinflips = np.random.binomial(n=1, p=.5, size=100)
print(coinflips)
```

    [0 1 1 1 0 0 0 1 1 1 0 1 1 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 1 0 1 0 0 1 1 1 0
     0 1 0 0 0 0 1 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 1 1 0 0 1
     1 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 1 1 1 1 0 1 0 0 0]

```
def confidence_interval(data, confidence=.95):
  n = len(data)
  mean = sum(data)/n
  data = np.array(data)
  stderr = stats.sem(data)
  interval = stderr * stats.t.ppf((1 + confidence) / 2.0, n-1)
  return (mean , mean-interval, mean+interval)
```

```
confidence_interval(coinflips, confidence=.95)
```

    (0.47, 0.3704689875017368, 0.5695310124982632)

```
mean_CI, _, _ = stats.bayes_mvs(coinflips, alpha=.95)

mean_CI
```

    Mean(statistic=0.47, minmax=(0.37046898750173674, 0.5695310124982632))

```
??stats.bayes_mvs
```

```
coinflips_mean_dist, _, _ = stats.mvsdist(coinflips)
coinflips_mean_dist
```

    <scipy.stats._distn_infrastructure.rv_frozen at 0x7f7a8c320b38>

```
coinflips_mean_dist.rvs(1000)
```

    array([0.47447628, 0.51541425, 0.54722018, 0.4589882 , 0.51501386,
           0.53819192, 0.43382292, 0.53546659, 0.47026173, 0.44967562,
           0.4621107 , 0.42691904, 0.37324325, 0.47531437, 0.46052277,
           0.48711257, 0.52456771, 0.43332181, 0.49545882, 0.44671454,
           0.47520117, 0.47047251, 0.41828918, 0.50159477, 0.42965501,
           0.45273383, 0.48045849, 0.45342529, 0.48238344, 0.53966291,
           0.48230241, 0.48073422, 0.48553525, 0.47962228, 0.41274185,
           0.42892633, 0.5170948 , 0.42678096, 0.42249309, 0.51499109,
           0.47059199, 0.39903942, 0.41790336, 0.46406817, 0.42232382,
           0.42163269, 0.47848227, 0.48232842, 0.4731858 , 0.51077244,
           0.3957508 , 0.48504646, 0.49014295, 0.53252732, 0.45495376,
           0.47883978, 0.60393033, 0.4492549 , 0.44797902, 0.54782121,
           0.43380002, 0.5760073 , 0.36941266, 0.44467418, 0.4939245 ,
           0.45278835, 0.55635162, 0.48695459, 0.39080983, 0.45948606,
           0.2941779 , 0.35950718, 0.44805696, 0.4725126 , 0.42218381,
           0.45985418, 0.47545393, 0.44317753, 0.46267013, 0.4458753 ,
           0.44204707, 0.51334913, 0.50914181, 0.49923748, 0.46895674,
           0.43892798, 0.45984946, 0.44984632, 0.53560791, 0.45865723,
           0.48646824, 0.55937503, 0.41464303, 0.50701457, 0.46934196,
           0.37681534, 0.42748113, 0.49812825, 0.48278895, 0.4964763 ,
           0.3891381 , 0.43956744, 0.48413544, 0.45477873, 0.48725027,
           0.49464113, 0.50575373, 0.47327346, 0.47520013, 0.58130199,
           0.5845843 , 0.46478398, 0.4258629 , 0.52948199, 0.48513203,
           0.49687534, 0.41137211, 0.46621924, 0.3914774 , 0.48360179,
           0.38619449, 0.48277886, 0.47026304, 0.45226139, 0.47583911,
           0.51800201, 0.48765985, 0.47519588, 0.56197092, 0.41764152,
           0.49955199, 0.4476301 , 0.53072591, 0.51503605, 0.54521753,
           0.51825987, 0.38392617, 0.46969675, 0.40735953, 0.41644585,
           0.46704857, 0.44673322, 0.44172829, 0.39682358, 0.56863866,
           0.49382431, 0.46425614, 0.43441607, 0.45352793, 0.43280667,
           0.49838641, 0.42134069, 0.39030482, 0.46056071, 0.43477593,
           0.48030697, 0.46963763, 0.58135074, 0.41707759, 0.54735952,
           0.40234266, 0.44587394, 0.43824819, 0.34994202, 0.45715098,
           0.48171551, 0.49707708, 0.56201387, 0.43796178, 0.48736057,
           0.48396275, 0.4137432 , 0.43730294, 0.44127354, 0.49414193,
           0.37391405, 0.48951459, 0.49203495, 0.48750347, 0.4535989 ,
           0.4826649 , 0.45727017, 0.35957717, 0.52627891, 0.48671508,
           0.5146115 , 0.40126273, 0.49351532, 0.47899387, 0.41170621,
           0.47372827, 0.45349404, 0.45541059, 0.44761163, 0.50985422,
           0.38946749, 0.38924167, 0.477608  , 0.47523283, 0.48057958,
           0.55631265, 0.47918939, 0.41974198, 0.59314567, 0.46179892,
           0.52111564, 0.39858206, 0.39293582, 0.45738699, 0.51094648,
           0.55605523, 0.42063349, 0.4553239 , 0.47003479, 0.47070228,
           0.46428309, 0.46828548, 0.55559626, 0.54327956, 0.48485723,
           0.39503943, 0.45169487, 0.51312502, 0.43261878, 0.44449548,
           0.45205734, 0.50467902, 0.55919291, 0.50052268, 0.39552378,
           0.44554284, 0.54545754, 0.41285254, 0.37820216, 0.4433361 ,
           0.51902109, 0.45162443, 0.57347586, 0.47871392, 0.40561444,
           0.48058706, 0.56598937, 0.48203328, 0.42126387, 0.368201  ,
           0.45272922, 0.43585457, 0.54199909, 0.42996167, 0.474737  ,
           0.44127776, 0.39061556, 0.46844006, 0.38929335, 0.49974341,
           0.38804905, 0.46641358, 0.52312717, 0.49613505, 0.44815583,
           0.49130684, 0.51080517, 0.41943377, 0.52715474, 0.51901749,
           0.40173031, 0.48157307, 0.45698766, 0.54181905, 0.5128087 ,
           0.4738456 , 0.53469041, 0.58876563, 0.37350851, 0.44841936,
           0.41531469, 0.46828303, 0.41863695, 0.52030773, 0.59197971,
           0.47809192, 0.39139708, 0.43735205, 0.44473506, 0.54450722,
           0.4877697 , 0.48142576, 0.4282081 , 0.43828492, 0.49536959,
           0.46056192, 0.51769419, 0.44435832, 0.2833451 , 0.44709257,
           0.39013597, 0.49752388, 0.48941684, 0.51950258, 0.43841402,
           0.461676  , 0.4364845 , 0.47132422, 0.5159512 , 0.40504394,
           0.54411978, 0.48126155, 0.53768622, 0.44783793, 0.45195711,
           0.53732665, 0.48919172, 0.54916543, 0.38184422, 0.3839936 ,
           0.50047602, 0.4827814 , 0.45782355, 0.57051467, 0.51586565,
           0.41297865, 0.49549503, 0.4867028 , 0.49218095, 0.47941133,
           0.4179382 , 0.43990307, 0.43267506, 0.51435874, 0.45603811,
           0.44264597, 0.5258102 , 0.42116497, 0.59109176, 0.45889992,
           0.42601209, 0.41855971, 0.51763858, 0.53603004, 0.55891986,
           0.51308977, 0.47539497, 0.57980186, 0.45166958, 0.4360487 ,
           0.4160565 , 0.46894016, 0.42544503, 0.4718965 , 0.44509759,
           0.4553363 , 0.51417409, 0.40125374, 0.40141203, 0.52444062,
           0.38433692, 0.53755945, 0.49124436, 0.44092107, 0.48664193,
           0.49809931, 0.35939896, 0.45019818, 0.51452836, 0.44702996,
           0.39014382, 0.4742493 , 0.45802077, 0.54117637, 0.50917065,
           0.48864846, 0.45513837, 0.46638664, 0.46289285, 0.474597  ,
           0.47679289, 0.53272938, 0.4273865 , 0.53018322, 0.48459184,
           0.46054965, 0.46864369, 0.47940797, 0.47963348, 0.50495819,
           0.43197032, 0.46684607, 0.48552696, 0.45851019, 0.52062144,
           0.45638092, 0.4765386 , 0.40863058, 0.42996211, 0.43454883,
           0.47898572, 0.44026601, 0.47275271, 0.39097285, 0.58139265,
           0.49820118, 0.45762952, 0.43127976, 0.42291755, 0.47822454,
           0.54221029, 0.41974753, 0.42307496, 0.4404098 , 0.54071199,
           0.47650072, 0.52908201, 0.43292955, 0.52911544, 0.40416927,
           0.51208142, 0.43676583, 0.59252479, 0.50098008, 0.52513111,
           0.43895871, 0.48582562, 0.43385598, 0.51551279, 0.49560729,
           0.4116628 , 0.47181415, 0.44020566, 0.48571059, 0.40538225,
           0.55172833, 0.47509918, 0.49899901, 0.42421471, 0.43601874,
           0.44018693, 0.5304447 , 0.43289087, 0.476795  , 0.41250698,
           0.38083118, 0.58788278, 0.46971184, 0.45125409, 0.47414778,
           0.4974292 , 0.46069729, 0.42235771, 0.52285515, 0.59676334,
           0.4705739 , 0.44988487, 0.47274685, 0.37493384, 0.42223226,
           0.49987446, 0.46030573, 0.44077887, 0.43844871, 0.47083241,
           0.49024836, 0.49153355, 0.40008594, 0.53218928, 0.43465945,
           0.51603003, 0.39652748, 0.41985494, 0.53091204, 0.40977991,
           0.46225922, 0.41771646, 0.43867606, 0.38712168, 0.58344414,
           0.48316133, 0.47170139, 0.47396495, 0.45185247, 0.43308114,
           0.53336288, 0.44655484, 0.52674401, 0.49790806, 0.45346429,
           0.49966867, 0.43964157, 0.5347767 , 0.49514565, 0.49845113,
           0.40907362, 0.4988595 , 0.45864058, 0.40669431, 0.46175527,
           0.5317036 , 0.50075453, 0.48638633, 0.49108861, 0.471713  ,
           0.48383151, 0.37494445, 0.50690883, 0.43971337, 0.45880774,
           0.48454783, 0.41166892, 0.48265585, 0.43225349, 0.39086731,
           0.50734673, 0.42186418, 0.48059622, 0.55935268, 0.39964071,
           0.47968735, 0.44197047, 0.5523577 , 0.5194387 , 0.46967629,
           0.46114995, 0.51547562, 0.41173477, 0.42714514, 0.54287129,
           0.47917532, 0.52899054, 0.52902622, 0.55529675, 0.39260093,
           0.47808929, 0.5227214 , 0.49686402, 0.41385472, 0.46877338,
           0.51290447, 0.42081246, 0.48763814, 0.46488503, 0.48815416,
           0.51874676, 0.44349542, 0.35529184, 0.48235864, 0.38829235,
           0.41629837, 0.49353573, 0.42837918, 0.43078333, 0.51282674,
           0.49055841, 0.48687382, 0.4024712 , 0.45031963, 0.49709223,
           0.54003902, 0.43554303, 0.53183842, 0.486558  , 0.45249906,
           0.51469574, 0.42098649, 0.45018556, 0.37915825, 0.55746338,
           0.50905594, 0.49594724, 0.51327984, 0.4526535 , 0.48421933,
           0.58224419, 0.47947599, 0.46611747, 0.52237733, 0.46120613,
           0.47167891, 0.49850872, 0.4311296 , 0.47774032, 0.45230789,
           0.35840294, 0.44659314, 0.51071187, 0.44069454, 0.55320876,
           0.39988476, 0.49035529, 0.48985295, 0.44694677, 0.45049715,
           0.51842605, 0.37342115, 0.49553783, 0.504753  , 0.49098663,
           0.4218805 , 0.52620235, 0.4827884 , 0.44288146, 0.45916104,
           0.49631062, 0.51646158, 0.48630302, 0.37307539, 0.41265663,
           0.49024564, 0.46467903, 0.47432696, 0.47325263, 0.48613461,
           0.51737977, 0.49745443, 0.43226223, 0.51386209, 0.54409309,
           0.42166633, 0.45683158, 0.49113578, 0.47195372, 0.46461796,
           0.43912749, 0.4570565 , 0.3981925 , 0.45969044, 0.45356353,
           0.49012313, 0.46231133, 0.42623662, 0.52407443, 0.4489394 ,
           0.36793671, 0.50496954, 0.4459393 , 0.47762308, 0.45557782,
           0.42430219, 0.46342973, 0.49607806, 0.42021132, 0.47986594,
           0.43995321, 0.47310004, 0.46830237, 0.6095986 , 0.47867353,
           0.50938602, 0.44119682, 0.41853036, 0.54135276, 0.3737122 ,
           0.54427806, 0.4251556 , 0.41348475, 0.41993261, 0.52989098,
           0.462017  , 0.51346035, 0.56842082, 0.44612654, 0.4650062 ,
           0.46543262, 0.37686614, 0.50593036, 0.38350366, 0.41051578,
           0.5477685 , 0.37572632, 0.40238182, 0.37546585, 0.46061846,
           0.34000573, 0.48379551, 0.4102443 , 0.46841925, 0.48235662,
           0.4521498 , 0.50212742, 0.46316433, 0.52688369, 0.39250788,
           0.44273506, 0.60936845, 0.46729244, 0.48883352, 0.45995963,
           0.52954227, 0.50744425, 0.5702215 , 0.4322026 , 0.52990493,
           0.51626873, 0.4946539 , 0.5082119 , 0.49850001, 0.46857659,
           0.37680806, 0.42922449, 0.4714559 , 0.47006439, 0.46103295,
           0.38448095, 0.51598495, 0.51233212, 0.39171157, 0.47295778,
           0.42799097, 0.31999544, 0.43777493, 0.51361593, 0.48083238,
           0.49048985, 0.37754081, 0.44390605, 0.43851769, 0.45367766,
           0.43004286, 0.39810176, 0.52425887, 0.5132496 , 0.46711766,
           0.5371266 , 0.49789306, 0.47440018, 0.48044375, 0.46275003,
           0.32760769, 0.43969128, 0.53361144, 0.50404316, 0.45660878,
           0.39614646, 0.5306167 , 0.41652062, 0.47978152, 0.44229313,
           0.38296985, 0.4576275 , 0.51705712, 0.46901214, 0.57001682,
           0.50423767, 0.45819868, 0.47460827, 0.52497238, 0.47857488,
           0.34748446, 0.46412874, 0.43491473, 0.47103418, 0.45914633,
           0.4506799 , 0.48795458, 0.49316724, 0.41450339, 0.45860263,
           0.48590433, 0.43353272, 0.47182887, 0.57180098, 0.51429135,
           0.36982541, 0.45893858, 0.44927164, 0.47235794, 0.58265714,
           0.478167  , 0.49140614, 0.46531855, 0.50984351, 0.4827639 ,
           0.45424265, 0.5015955 , 0.40968418, 0.49247972, 0.44791535,
           0.43087735, 0.5079453 , 0.39380662, 0.38242163, 0.49299987,
           0.41208436, 0.39335919, 0.45047663, 0.40227791, 0.55079414,
           0.51004866, 0.46107434, 0.44619307, 0.40856549, 0.45213558,
           0.34076475, 0.44746926, 0.50151825, 0.47512069, 0.44447584,
           0.51219988, 0.41074984, 0.52785383, 0.37876592, 0.51172916,
           0.51014685, 0.5534993 , 0.4745541 , 0.49519006, 0.50658855,
           0.51617094, 0.55167752, 0.52080632, 0.48118055, 0.4497149 ,
           0.43954218, 0.51988854, 0.46973126, 0.49375973, 0.45512846,
           0.4670614 , 0.51303675, 0.56130338, 0.49572266, 0.41883276,
           0.44433704, 0.48790926, 0.50805016, 0.47367689, 0.41275913,
           0.53529189, 0.4393815 , 0.44798915, 0.47777408, 0.41248419,
           0.44957019, 0.44111031, 0.47174419, 0.54963872, 0.37056181,
           0.42624852, 0.42007032, 0.47428632, 0.44194326, 0.53917971,
           0.51442597, 0.39569021, 0.52024419, 0.45939336, 0.51860329,
           0.4722443 , 0.49892044, 0.45117057, 0.4687997 , 0.48571876,
           0.44523495, 0.47080056, 0.40803152, 0.4873699 , 0.42852689,
           0.5576894 , 0.44129667, 0.48988382, 0.47362904, 0.53799032,
           0.43168666, 0.47733785, 0.42619853, 0.52326113, 0.40582344,
           0.3752876 , 0.44395294, 0.43526222, 0.44753265, 0.4335338 ,
           0.50883482, 0.43585868, 0.41200332, 0.36602514, 0.49333628,
           0.40624739, 0.45769445, 0.39957451, 0.51484301, 0.45243127,
           0.49550451, 0.42045661, 0.51606437, 0.45627401, 0.45883254,
           0.40159611, 0.39777387, 0.47548967, 0.37814115, 0.52078691,
           0.33737182, 0.49376712, 0.42425788, 0.49313496, 0.51393986,
           0.33733477, 0.61310296, 0.4179583 , 0.48252206, 0.48776153,
           0.52774351, 0.48715976, 0.42955008, 0.45700497, 0.43991845,
           0.45648164, 0.37957614, 0.39961823, 0.43406117, 0.53066173,
           0.505644  , 0.48217836, 0.49081739, 0.50618318, 0.4919582 ,
           0.4350554 , 0.48444719, 0.49467042, 0.4789851 , 0.46491457,
           0.42527415, 0.42989511, 0.47073809, 0.48158046, 0.49392888,
           0.52054431, 0.47831854, 0.42700402, 0.49578621, 0.52062022,
           0.43633741, 0.42671723, 0.48976181, 0.41265183, 0.45424771,
           0.44743247, 0.50648504, 0.46491952, 0.46800249, 0.3828106 ,
           0.49856068, 0.51699582, 0.48166775, 0.56224234, 0.49789532,
           0.46000952, 0.49959486, 0.46650966, 0.42187689, 0.47007628,
           0.51639958, 0.49191647, 0.50020547, 0.51637026, 0.54369003,
           0.42976058, 0.48321571, 0.47720863, 0.44630105, 0.42892523,
           0.41553131, 0.46174644, 0.51717268, 0.48445115, 0.44363908,
           0.486894  , 0.45906175, 0.43506012, 0.44476889, 0.38141848,
           0.40464606, 0.44997479, 0.44733676, 0.45134756, 0.46831684,
           0.53670241, 0.47772302, 0.40203076, 0.46568984, 0.39886807,
           0.55712779, 0.45029969, 0.45676884, 0.55615739, 0.53303594,
           0.45722586, 0.55022421, 0.48445879, 0.58295224, 0.3706536 ,
           0.48182352, 0.42183159, 0.44396719, 0.473292  , 0.53361495,
           0.47621795, 0.44416008, 0.43392763, 0.42497657, 0.48451716])

## Assignment - Code it up!

Most of the above was pure math - now write Python code to reproduce the results! This is purposefully open ended - you'll have to think about how you should represent probabilities and events. You can and should look things up, and as a stretch goal - refactor your code into helpful reusable functions!

Specific goals/targets:

1. Write a function `def prob_drunk_given_positive(prob_drunk_prior, prob_positive, prob_positive_drunk)` that reproduces the example from lecture, and use it to calculate and visualize a range of situations
2. Explore `scipy.stats.bayes_mvs` - read its documentation, and experiment with it on data you've tested in other ways earlier this week
3. Create a visualization comparing the results of a Bayesian approach to a traditional/frequentist approach
4. In your own words, summarize the difference between Bayesian and Frequentist statistics

If you're unsure where to start, check out [this blog post of Bayes theorem with Python](https://dataconomy.com/2015/02/introduction-to-bayes-theorem-with-python/) - you could and should create something similar!

Stretch goals:

- Apply a Bayesian technique to a problem you previously worked (in an assignment or project work) on from a frequentist (standard) perspective
- Check out [PyMC3](https://docs.pymc.io/) (note this goes beyond hypothesis tests into modeling) - read the guides and work through some examples
- Take PyMC3 further - see if you can build something with it!

### Imports

```
from scipy import stats
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
```

### Bayes' Theorem Definition

```
def prob_drunk_given_positive(prob_drunk_prior, prob_positive, prob_positive_drunk):
  return((prob_positive_drunk*prob_drunk_prior) / prob_positive)
```

```
# Let's check it

prob_drunk_prior = 1/1000
prob_positive = 8/100
prob_positive_drunk = 1
```

```
prob_drunk_given_positive(prob_drunk_prior, prob_positive, prob_positive_drunk)
```

    0.0125

### Likelihood over Ranges of `prob_drunk_prior` and `prob_positive`

```
df = pd.DataFrame()
```

```
drunk_list = list(range(1, 51))
positive_list = list(range(1, 10, 1))

drunk_list = [i/100 for i in drunk_list]
positive_list = [i/100 for i in positive_list]
```

```
drunk = []
positive = []
likelihood = []
```

```
for x in drunk_list:
  for y in positive_list:
    drunk.append(x)
    positive.append(y)
    likelihood.append(prob_drunk_given_positive(x, y, 1))
```

```
df['prob_drunk'] = drunk
df['prob_positive'] = positive
df['likelihood'] = likelihood
```

```
fig = plt.figure(figsize=(10, 10))

ax = df.plot.scatter('prob_drunk', 'prob_positive', c='likelihood')

# Title
ax.text(x=-.05, y=.11, s="Likelihood the Breathylyzer is Correct", fontsize=14, fontweight='bold');

# Set x-axis label
plt.xlabel(x=.5, y=-.1, xlabel="The proporion of citizens drunk at any given time", fontsize=12, fontweight="bold", labelpad=15);
plt.xticks([.1, .2, .3, .4, .5], labels=['.1', '.2', '.3', '.4', '.5']);

# Set y-axis label
plt.ylabel(x=1, y=.5, ylabel="False Positive Rate", fontsize=12, fontweight="bold", labelpad=15);
plt.yticks([0, .02, .04, .06, .08, .1]);
```

### Recursive Definition

```
i = 1
df = pd.DataFrame()
result = []
ind = []
post_list = []
```

```
def prob_drunk_given_positive_recur(prob_drunk_prior, prob_positive, prob_positive_drunk, n):
 global result
 global i

 post_prob = (prob_positive_drunk*prob_drunk_prior) / (prob_positive + prob_drunk_prior)
 ind.append(int(i))
 post_list.append(post_prob)
 #print(i, post_prob)
 i += 1
 while i < n:
   prob_drunk_given_positive_recur(post_prob, prob_positive, prob_positive_drunk, n)
 return(result)
```

```
prob_drunk_given_positive_recur(prob_drunk_prior, prob_positive, prob_positive_drunk, 20);
```

```
df['index'] = ind
df['post_prob'] = post_list
```

```
df.plot.scatter('index', 'post_prob')
```

Running the test over and over again will cause the posterior probability to converge to 1 - (False Positive Rate) as we would expect.

```
df.head()
```

      index
      post_prob

      0
      1
      0.012346

      1
      2
      0.133690

      2
      3
      0.625626

      3
      4
      0.886625

### Frequentist vs. Bayesian Statistics

Frequentist and Bayesian Statistics are two sides of the same coin, with fundamentally different philosophies. Frequentists are primarily concerned with the frequency with which events happen, and Bayesians are concerned with our own uncertainty of events.

Bayesian approaches factor in our own observations and perceptions of events more naturally than Frequentist approaches.

## Resources

- [Worked example of Bayes rule calculation](https://en.wikipedia.org/wiki/Bayes'_theorem#Examples) (helpful as it fully breaks out the denominator)
- [Source code for mvsdist in scipy](https://github.com/scipy/scipy/blob/90534919e139d2a81c24bf08341734ff41a3db12/scipy/stats/morestats.py#L139)

```
def prob_drunk_given_positive_recur(prob_drunk_prior, prob_positive, prob_positive_drunk, n):
   global result
   post_prob = (prob_positive_drunk*prob_drunk_prior) / (prob_positive + prob_drunk_prior)
   global i
   i += 1
   while i < n:
     result.append(prob_drunk_given_positive_recur(post_prob, prob_positive, prob_positive_drunk, n))

   return(i, result) # This will give x, y.
```

```
pd.DataFrame(columns=[x, y])
```


# [ATM 623: Climate Modeling](../index.ipynb)

[Brian E. J. Rose](http://www.atmos.albany.edu/facstaff/brose/index.html), University at Albany

# Lecture 6: Elementary greenhouse models

### About these notes:

This document uses the interactive [`Jupyter notebook`](https://jupyter.org) format. The notes can be accessed in several different ways:

- The interactive notebooks are hosted on `github` at https://github.com/brian-rose/ClimateModeling_courseware
- The latest versions can be viewed as static web pages [rendered on nbviewer](http://nbviewer.ipython.org/github/brian-rose/ClimateModeling_courseware/blob/master/index.ipynb)
- A complete snapshot of the notes as of May 2017 (end of spring semester) are [available on Brian's website](http://www.atmos.albany.edu/facstaff/brose/classes/ATM623_Spring2017/Notes/index.html).

[Also here is a legacy version from 2015](http://www.atmos.albany.edu/facstaff/brose/classes/ATM623_Spring2015/Notes/index.html).

Many of these notes make use of the `climlab` package, available at https://github.com/brian-rose/climlab

```python
#  Ensure compatibility with Python 2 and 3
from __future__ import print_function, division
```

## Contents

1. [A single layer atmosphere](#section1)
2. [Introducing the two-layer grey gas model](#section2)
3. [Tuning the grey gas model to observations](#section3)
4. [Level of emission](#section4)
5. [Radiative forcing in the 2-layer grey gas model](#section5)
6. [Radiative equilibrium in the 2-layer grey gas model](#section6)
7. [Summary](#section7)

____________

## 1. A single layer atmosphere
____________

We will make our first attempt at quantifying the greenhouse effect in the simplest possible greenhouse model: a single layer of atmosphere that is able to absorb and emit longwave radiation.

### Assumptions

- Atmosphere is a single layer of air at temperature $T_a$
- Atmosphere is **completely transparent to shortwave** solar radiation.
- The **surface** absorbs shortwave radiation $(1-\alpha) Q$
- Atmosphere is **completely opaque to infrared** radiation
- Both surface and atmosphere emit radiation as **blackbodies** ($\sigma T_s^4, \sigma T_a^4$)
- Atmosphere radiates **equally up and down** ($\sigma T_a^4$)
- There are no other heat transfer mechanisms

We can now use the concept of energy balance to ask what the temperature need to be in order to balance the energy budgets at the surface and the atmosphere, i.e. the **radiative equilibrium temperatures**.

### Energy balance at the surface

\begin{align}
\text{energy in} &= \text{energy out} \\
(1-\alpha) Q + \sigma T_a^4 &= \sigma T_s^4 \\
\end{align}

The presence of the atmosphere above means there is an additional source term: downwelling infrared radiation from the atmosphere.

We call this the **back radiation**.

### Energy balance for the atmosphere

\begin{align}
\text{energy in} &= \text{energy out} \\
\sigma T_s^4 &= A\uparrow + A\downarrow = 2 \sigma T_a^4 \\
\end{align}

which means that
$$ T_s = 2^\frac{1}{4} T_a \approx 1.2 T_a $$

So we have just determined that, in order to have a purely **radiative equilibrium**, we must have $T_s > T_a$.

*The surface must be warmer than the atmosphere.*

### Solve for the radiative equilibrium surface temperature

Now plug this into the surface equation to find

$$ \frac{1}{2} \sigma T_s^4 = (1-\alpha) Q  $$

and use the definition of the emission temperature $T_e$ to write

$$ (1-\alpha) Q = \sigma T_e^4 $$

*In fact, in this model, $T_e$ is identical to the atmospheric temperature $T_a$, since all the OLR originates from this layer.*

Solve for the surface temperature:
$$ T_s = 2^\frac{1}{4} T_e $$

Putting in observed numbers, $T_e = 255$ K gives a surface temperature of
$$T_s = 303 ~\text{K}$$

This model is one small step closer to reality: surface is warmer than atmosphere, emissions to space generated in the atmosphere, atmosphere heated from below and helping to keep surface warm.

BUT our model now overpredicts the surface temperature by about 15ºC (or K).

Ideas about why?

Basically we just need to read our **list of assumptions** above and realize that none of them are very good approximations:

- Atmosphere absorbs some solar radiation.
- Atmosphere is NOT a perfect absorber of longwave radiation
- Absorption and emission varies strongly with wavelength *(atmosphere does not behave like a blackbody)*.
- Emissions are not determined by a single temperature $T_a$ but by the detailed *vertical profile* of air temperture.
- Energy is redistributed in the vertical by a variety of dynamical transport mechanisms (e.g. convection and boundary layer turbulence).

____________

## 2. Introducing the two-layer grey gas model
____________

Let's generalize the above model just a little bit to build a slighly more realistic model of longwave radiative transfer.

We will address two shortcomings of our single-layer model:
1. No vertical structure
2. 100% longwave opacity

Relaxing these two assumptions gives us what turns out to be a very useful prototype model for **understanding how the greenhouse effect works**.

### Assumptions

- The atmosphere is **transparent to shortwave radiation** (still)
- Divide the atmosphere up into **two layers of equal mass** (the dividing line is thus at 500 hPa pressure level)
- Each layer **absorbs only a fraction $\epsilon$ ** of whatever longwave radiation is incident upon it.
- We will call the fraction $\epsilon$ the **absorptivity** of the layer.
- Assume $\epsilon$ is the same in each layer

This is called the **grey gas** model, where grey here means the emission and absorption have no spectral dependence.

We can think of this model informally as a "leaky greenhouse".

Note that the assumption that $\epsilon$ is the same in each layer is appropriate if the absorption is actually carried out by a gas that is **well-mixed** in the atmosphere.

Out of our two most important absorbers:

- CO$_2$ is well mixed
- H$_2$O is not (mostly confined to lower troposphere due to strong temperature dependence of the saturation vapor pressure).

But we will ignore this aspect of reality for now.

In order to build our model, we need to introduce one additional piece of physics known as **Kirchoff's Law**:

$$ \text{absorptivity} = \text{emissivity} $$

So if a layer of atmosphere at temperature $T$ absorbs a fraction $\epsilon$ of incident longwave radiation, it must emit

$$ \epsilon ~\sigma ~T^4 $$

both up and down.

### A sketch of the radiative fluxes in the 2-layer atmosphere

- Surface temperature is $T_s$
- Atm. temperatures are $T_0, T_1$ where $T_0$ is closest to the surface.
- absorptivity of atm layers is $\epsilon$
- Surface emission is $\sigma T_s^4$
- Atm emission is $\epsilon \sigma T_0^4, \epsilon \sigma T_1^4$ (up and down)
- Absorptivity = emissivity for atmospheric layers
- a fraction $(1-\epsilon)$ of the longwave beam is **transmitted** through each layer

### A fun aside: symbolic math with the `sympy` package

This two-layer grey gas model is simple enough that we can work out all the details algebraically. There are three temperatures to keep track of $(T_s, T_0, T_1)$, so we will have 3x3 matrix equations.

We all know how to work these things out with pencil and paper. But it can be tedious and error-prone.

Symbolic math software lets us use the computer to automate a lot of tedious algebra.

The [sympy](http://www.sympy.org/en/index.html) package is a powerful open-source symbolic math library that is well-integrated into the scientific Python ecosystem.

```python
import sympy
#  Allow sympy to produce nice looking equations as output
sympy.init_printing()
#  Define some symbols for mathematical quantities
#  Assume all quantities are positive (which will help simplify some expressions)
epsilon, T_e, T_s, T_0, T_1, sigma = \
    sympy.symbols('epsilon, T_e, T_s, T_0, T_1, sigma', positive=True)
#  So far we have just defined some symbols, e.g.
T_s
```

```python
#  We have hard-coded the assumption that the temperature is positive
sympy.ask(T_s>0)
```

    True

### Longwave emissions

Let's denote the emissions from each layer as
\begin{align}
E_s &= \sigma T_s^4 \\
E_0 &= \epsilon \sigma T_0^4 \\
E_1 &= \epsilon \sigma T_1^4
\end{align}

recognizing that $E_0$ and $E_1$ contribute to **both** the upwelling and downwelling beams.

```python
#  Define these operations as sympy symbols
#  And display as a column vector:
E_s = sigma*T_s**4
E_0 = epsilon*sigma*T_0**4
E_1 = epsilon*sigma*T_1**4
E = sympy.Matrix([E_s, E_0, E_1])
E
```

### Shortwave radiation
Since we have assumed the atmosphere is transparent to shortwave, the incident beam $Q$ passes unchanged from the top to the surface, where a fraction $\alpha$ is reflected upward out to space.

```python
#  Define some new symbols for shortwave radiation
Q, alpha = sympy.symbols('Q, alpha', positive=True)
#  Create a dictionary to hold our numerical values
tuned = {}
tuned[Q] = 341.3  #  global mean insolation in W/m2
tuned[alpha] = 101.9/Q.subs(tuned)  #  observed planetary albedo
tuned[sigma] = 5.67E-8  #  Stefan-Boltzmann constant in W/m2/K4
tuned
#  Numerical value for emission temperature
#T_e.subs(tuned)
```

### Upwelling beam

Let $U$ be the upwelling flux of longwave radiation.

The upward flux from the surface to layer 0 is
$$ U_0 = E_s $$
(just the emission from the suface).

```python
U_0 = E_s
U_0
```

Following this beam upward, we can write the upward flux from layer 0 to layer 1 as the sum of the transmitted component that originated below layer 0 and the new emissions from layer 0:

$$ U_1 = (1-\epsilon) U_0 + E_0 $$

```python
U_1 = (1-epsilon)*U_0 + E_0
U_1
```

Continuing to follow the same beam, the upwelling flux above layer 1 is
$$ U_2 = (1-\epsilon) U_1 + E_1 $$

```python
U_2 = (1-epsilon) * U_1 + E_1
```

Since there is no more atmosphere above layer 1, this upwelling flux is our Outgoing Longwave Radiation for this model:

$$ OLR = U_2 $$

```python
U_2
```

The three terms in the above expression represent the **contributions to the total OLR that originate from each of the three levels**.

Let's code this up explicitly for future reference:

```python
#  Define the contributions to OLR originating from each level
OLR_s = (1-epsilon)**2 *sigma*T_s**4
OLR_0 = epsilon*(1-epsilon)*sigma*T_0**4
OLR_1 = epsilon*sigma*T_1**4

OLR = OLR_s + OLR_0 + OLR_1

print( 'The expression for OLR is')
OLR
```

### Downwelling beam

Let $D$ be the downwelling longwave beam. Since there is no longwave radiation coming in from space, we begin with

```python
fromspace = 0
D_2 = fromspace
```

Between layer 1 and layer 0 the beam contains emissions from layer 1:

$$ D_1 = (1-\epsilon)D_2 + E_1 = E_1 $$

```python
D_1 = (1-epsilon)*D_2 + E_1
D_1
```

Finally between layer 0 and the surface the beam contains a transmitted component and the emissions from layer 0:

$$ D_0 = (1-\epsilon) D_1 + E_0 = \epsilon(1-\epsilon) \sigma T_1^4 + \epsilon \sigma T_0^4$$

```python
D_0 = (1-epsilon)*D_1 + E_0
D_0
```

This $D_0$ is what we call the **back radiation**, i.e. the longwave radiation from the atmosphere to the surface.

____________

## 3. Tuning the grey gas model to observations
____________

In building our new model we have introduced exactly one parameter, the absorptivity $\epsilon$. We need to choose a value for $\epsilon$.

We will tune our model so that it **reproduces the observed global mean OLR** given **observed global mean temperatures**.

To get appropriate temperatures for $T_s, T_0, T_1$, let's revisit the [global, annual mean lapse rate plot from NCEP Reanalysis data](Lecture05 -- Radiation.ipynb) from the previous lecture.

### Temperatures

First, we set
$$T_s = 288 \text{ K}  $$

From the lapse rate plot, an average temperature for the layer between 1000 and 500 hPa is

$$ T_0 = 275 \text{ K}$$

Defining an average temperature for the layer between 500 and 0 hPa is more ambiguous because of the lapse rate reversal at the tropopause. We will choose

$$ T_1 = 230 \text{ K}$$

From the graph, this is approximately the observed global mean temperature at 275 hPa or about 10 km.

```python
#  add to our dictionary of values:
tuned[T_s] = 288.
tuned[T_0] = 275.
tuned[T_1] = 230.
tuned
```

### OLR

From the [observed global energy budget](Lecture01 -- Planetary energy budget.ipynb) we set

$$ OLR = 238.5 \text{ W m}^{-2} $$

### Solving for $\epsilon$

We wrote down the expression for OLR as a function of temperatures and absorptivity in our model above.

We just need to equate this to the observed value and solve a **quadratic equation** for $\epsilon$.

This is where the real power of the symbolic math toolkit comes in.

Subsitute in the numerical values we are interested in:

```python
# the .subs() method for a sympy symbol means
#  substitute values in the expression using the supplied dictionary
#  Here we use observed values of Ts, T0, T1
OLR2 = OLR.subs(tuned)
OLR2
```

We have a quadratic equation for $\epsilon$.

Now use the `sympy.solve` function to solve the quadratic:

```python
#  The sympy.solve method takes an expression equal to zero
#  So in this case we subtract the tuned value of OLR from our expression
eps_solution = sympy.solve(OLR2 - 238.5, epsilon)
eps_solution
```

There are two roots, but the second one is unphysical since we must have $0 < \epsilon < 1$.

Just for fun, here is a simple of example of *filtering a list* using powerful Python *list comprehension* syntax:

```python
# Give me only the roots that are between zero and 1!
list_result = [eps for eps in eps_solution if 0<eps<1]
print( list_result)
# The result is a list with a single element.
#  We need to slice the list to get just the number:
eps_tuned = list_result[0]
print( eps_tuned)
```

    [0.586041150248834]
    0.586041150248834

We conclude that our tuned value is

$$ \epsilon = 0.586 $$

This is the absorptivity that guarantees that our model reproduces the observed OLR given the observed tempertures.

```python
tuned[epsilon] = eps_tuned
tuned
```

____________

## 4. Level of emission
____________

Even in this very simple greenhouse model, there is **no single level** at which the OLR is generated.

The three terms in our formula for OLR tell us the contributions from each level.

```python
OLRterms = sympy.Matrix([OLR_s, OLR_0, OLR_1])
OLRterms
```

Now evaluate these expressions for our tuned temperature and absorptivity:

```python
OLRtuned = OLRterms.subs(tuned)
OLRtuned
```

So we are getting about 67 W m$^{-2}$ from the surface, 79 W m$^{-2}$ from layer 0, and 93 W m$^{-2}$ from the top layer.

In terms of fractional contributions to the total OLR, we have (limiting the output to two decimal places):

```python
sympy.N(OLRtuned / 239., 2)
```

Notice that the largest single contribution is coming from the top layer. This is in spite of the fact that the emissions from this layer are weak, because it is so cold.

Comparing to observations, the actual contribution to OLR from the surface is about 22 W m$^{-2}$ (or about 9% of the total), not 67 W m$^{-2}$. So we certainly don't have all the details worked out yet!

As we will see later, to really understand what sets that observed 22 W m$^{-2}$, we will need to start thinking about the spectral dependence of the longwave absorptivity.

____________

## 5. Radiative forcing in the 2-layer grey gas model
____________

Adding some extra greenhouse absorbers will mean that a greater fraction of incident longwave radiation is absorbed in each layer.

Thus **$\epsilon$ must increase** as we add greenhouse gases.

Suppose we have $\epsilon$ initially, and the absorptivity increases to $\epsilon_2 = \epsilon + \delta_\epsilon$.

Suppose further that this increase happens **abruptly** so that there is no time for the temperatures to respond to this change. **We hold the temperatures fixed** in the column and ask how the radiative fluxes change.

**Do you expect the OLR to increase or decrease?**

Let's use our two-layer leaky greenhouse model to investigate the answer.

The components of the OLR before the perturbation are

```python
OLRterms
```

After the perturbation we have

```python
delta_epsilon = sympy.symbols('delta_epsilon')
OLRterms_pert = OLRterms.subs(epsilon, epsilon+delta_epsilon)
OLRterms_pert
```

Let's take the difference

```python
deltaOLR = OLRterms_pert - OLRterms
deltaOLR
```

To make things simpler, we will neglect the terms in $\delta_\epsilon^2$. This is perfectly reasonably because we are dealing with **small perturbations** where $\delta_\epsilon << \epsilon$.

Telling `sympy` to set the quadratic terms to zero gives us

```python
deltaOLR_linear = sympy.expand(deltaOLR).subs(delta_epsilon**2, 0)
deltaOLR_linear
```

Recall that the three terms are the contributions to the OLR from the three different levels. In this case, the **changes** in those contributions after adding more absorbers.

Now let's divide through by $\delta_\epsilon$ to get the normalized change in OLR per unit change in absorptivity:

```python
deltaOLR_per_deltaepsilon = \
    sympy.simplify(deltaOLR_linear / delta_epsilon)
deltaOLR_per_deltaepsilon
```

Now look at the **sign** of each term. Recall that $0 < \epsilon < 1$. **Which terms in the OLR go up and which go down?**

**THIS IS VERY IMPORTANT, SO STOP AND THINK ABOUT IT.**

The contribution from the **surface** must **decrease**, while the contribution from the **top layer** must **increase**.

**When we add absorbers, the average level of emission goes up!**

### "Radiative forcing" is the change in radiative flux at TOA after adding absorbers

In this model, only the longwave flux can change, so we define the radiative forcing as

$$ R = - \delta OLR $$

(with the minus sign so that $R$ is positive when the climate system is gaining extra energy).

We just worked out that whenever we add some extra absorbers, the emissions to space (on average) will originate from higher levels in the atmosphere.

What does this mean for OLR? Will it increase or decrease?

To get the answer, we just have to sum up the three contributions we wrote above:

```python
R = -sum(deltaOLR_per_deltaepsilon)
R
```

Is this a positive or negative number? The key point is this:

**It depends on the temperatures, i.e. on the lapse rate.**

### Greenhouse effect for an isothermal atmosphere

Stop and think about this question:

If the **surface and atmosphere are all at the same temperature**, does the OLR go up or down when $\epsilon$ increases (i.e. we add more absorbers)?

Understanding this question is key to understanding how the greenhouse effect works.

#### Let's solve the isothermal case

We will just set $T_s = T_0 = T_1$ in the above expression for the radiative forcing.

```python
R.subs([(T_0, T_s), (T_1, T_s)])
```

which then simplifies to

```python
sympy.simplify(R.subs([(T_0, T_s), (T_1, T_s)]))
```

#### The answer is zero

For an isothermal atmosphere, there is **no change** in OLR when we add extra greenhouse absorbers. Hence, no radiative forcing and no greenhouse effect.

Why?

The level of emission still must go up. But since the temperature at the upper level is the **same** as everywhere else, the emissions are exactly the same.

### The radiative forcing (change in OLR) depends on the lapse rate!

For a more realistic example of radiative forcing due to an increase in greenhouse absorbers, we can substitute in our tuned values for temperature and $\epsilon$.

We'll express the answer in W m$^{-2}$ for a 1% increase in $\epsilon$.

The three components of the OLR change are

```python
deltaOLR_per_deltaepsilon.subs(tuned) * 0.01
```

And the net radiative forcing is

```python
R.subs(tuned) * 0.01
```

So in our example, **the OLR decreases by 2.2 W m$^{-2}$**, or equivalently, the radiative forcing is +2.2 W m$^{-2}$.

What we have just calculated is this:

*Given the observed lapse rates, a small increase in absorbers will cause a small decrease in OLR.*

The greenhouse effect thus gets stronger, and energy will begin to accumulate in the system -- which will eventually cause temperatures to increase as the system adjusts to a new equilibrium.

____________

## 6. Radiative equilibrium in the 2-layer grey gas model
____________

In the previous section we:

- made no assumptions about the processes that actually set the temperatures.
- used the model to calculate radiative fluxes, **given observed temperatures**.
- stressed the importance of knowing the lapse rates in order to know how an increase in emission level would affect the OLR, and thus determine the radiative forcing.

A key question in climate dynamics is therefore this:

**What sets the lapse rate?**

It turns out that lots of different physical processes contribute to setting the lapse rate.

Understanding how these processes acts together and how they change as the climate changes is one of the key reasons for which we need more complex climate models.

For now, we will use our prototype greenhouse model to do the most basic lapse rate calculation: the **radiative equilibrium temperature**.

We assume that

- the only exchange of energy between layers is longwave radiation
- equilibrium is achieved when the **net radiative flux convergence** in each layer is zero.

### Compute the radiative flux convergence

First, the **net upwelling flux** is just the difference between flux up and flux down:

```python
#  Upwelling and downwelling beams as matrices
U = sympy.Matrix([U_0, U_1, U_2])
D = sympy.Matrix([D_0, D_1, D_2])
# Net flux, positive up
F = U-D
F
```

####  Net absorption is the flux convergence in each layer

(difference between what's coming in the bottom and what's going out the top of each layer)

```python
# define a vector of absorbed radiation -- same size as emissions
A = E.copy()

#  absorbed radiation at surface
A[0] = F[0]
# Compute the convergence
for n in range(2):
    A[n+1] = -(F[n+1]-F[n])

A
```

#### Radiative equilibrium means net absorption is ZERO in the atmosphere

The only other heat source is the **shortwave heating** at the **surface**.

In matrix form, here is the system of equations to be solved:

```python
radeq = sympy.Equality(A, sympy.Matrix([(1-alpha)*Q, 0, 0]))
radeq
```

Just as we did for the 1-layer model, it is helpful to rewrite this system using the definition of the **emission temperture** $T_e$

$$ (1-\alpha) Q = \sigma T_e^4 $$

```python
radeq2 = radeq.subs([((1-alpha)*Q, sigma*T_e**4)])
radeq2
```

In this form we can see that we actually have a **linear system** of equations for a set of variables $T_s^4, T_0^4, T_1^4$.

We can solve this matrix problem to get these as functions of $T_e^4$.

```python
# Solve for radiative equilibrium
fourthpower = sympy.solve(radeq2, [T_s**4, T_1**4, T_0**4])
fourthpower
```

This produces a dictionary of solutions for the fourth power of the temperatures!

A little manipulation gets us the solutions for temperatures that we want:

```python
# need the symbolic fourth root operation
from sympy.simplify.simplify import nthroot

fourthpower_list = [fourthpower[key] for key in [T_s**4, T_0**4, T_1**4]]
solution = sympy.Matrix([nthroot(item,4) for item in fourthpower_list])
#  Display result as matrix equation!
T = sympy.Matrix([T_s, T_0, T_1])
sympy.Equality(T, solution)
```

In more familiar notation, the radiative equilibrium solution is thus

\begin{align}
T_s &= T_e \left( \frac{2+\epsilon}{2-\epsilon} \right)^{1/4} \\
T_0 &= T_e \left( \frac{1+\epsilon}{2-\epsilon} \right)^{1/4} \\
T_1 &= T_e \left( \frac{ 1}{2 - \epsilon} \right)^{1/4}
\end{align}

Plugging in the tuned value $\epsilon = 0.586$ gives

```python
Tsolution = solution.subs(tuned)
#  Display result as matrix equation!
sympy.Equality(T, Tsolution)
```

Now we just need to know the Earth's emission temperature $T_e$!

(Which we already know is about 255 K)

```python
# Here's how to calculate T_e from the observed values
sympy.solve(((1-alpha)*Q - sigma*T_e**4).subs(tuned), T_e)
```

```python
# Need to unpack the list
Te_value = sympy.solve(((1-alpha)*Q - sigma*T_e**4).subs(tuned), T_e)[0]
Te_value
```

#### Now we finally get our solution for radiative equilibrium

```python
#  Output 4 significant digits
Trad = sympy.N(Tsolution.subs([(T_e, Te_value)]), 4)
sympy.Equality(T, Trad)
```

Compare these to the values we derived from the **observed lapse rates**:

```python
sympy.Equality(T, T.subs(tuned))
```

The **radiative equilibrium** solution is substantially **warmer at the surface** and **colder in the lower troposphere** than reality.

This is a very general feature of radiative equilibrium, and we will see it again very soon in this course.

____________

## 7. Summary
____________

## Key physical lessons

- Putting a **layer of longwave absorbers** above the surface keeps the **surface substantially warmer**, because of the **backradiation** from the atmosphere (greenhouse effect).
- The **grey gas** model assumes that each layer absorbs and emits a fraction $\epsilon$ of its blackbody value, independent of wavelength.

- With **incomplete absorption** ($\epsilon < 1$), there are contributions to the OLR from every level and the surface (there is no single **level of emission**)
- Adding more absorbers means that **contributions to the OLR** from **upper levels** go **up**, while contributions from the surface go **down**.
- This upward shift in the weighting of different levels is what we mean when we say the **level of emission goes up**.

- The **radiative forcing** caused by an increase in absorbers **depends on the lapse rate**.
- For an **isothermal atmosphere** the radiative forcing is zero and there is **no greenhouse effect**
- The radiative forcing is positive for our atmosphere **because tropospheric temperatures tends to decrease with height**.
- Pure **radiative equilibrium** produces a **warm surface** and **cold lower troposphere**.
- This is unrealistic, and suggests that crucial heat transfer mechanisms are missing from our model.

### And on the Python side...

Did we need `sympy` to work all this out? No, of course not. We could have solved the 3x3 matrix problems by hand. But computer algebra can be very useful and save you a lot of time and error, so it's good to invest some effort into learning how to use it.

Hopefully these notes provide a useful starting point.

### A follow-up assignment

You are now ready to tackle [Assignment 5](../Assignments/Assignment05 -- Radiative forcing in a grey radiation atmosphere.ipynb), where you are asked to extend this grey-gas analysis to many layers.

For more than a few layers, the analytical approach we used here is no longer very useful. You will code up a numerical solution to calculate OLR given temperatures and absorptivity, and look at how the lapse rate determines radiative forcing for a given increase in absorptivity.

[Back to ATM 623 notebook home](../index.ipynb)

____________
## Version information
____________

```python
%load_ext version_information
%version_information sympy
```

Software	Version

Python	3.6.2 64bit [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]

IPython	6.1.0

OS	Darwin 17.7.0 x86_64 i386 64bit

sympy	1.1.1

Tue Jan 15 13:50:53 2019 EST

____________

## Credits

The author of this notebook is [Brian E. J. Rose](http://www.atmos.albany.edu/facstaff/brose/index.html), University at Albany.

It was developed in support of [ATM 623: Climate Modeling](http://www.atmos.albany.edu/facstaff/brose/classes/ATM623_Spring2015/), a graduate-level course in the [Department of Atmospheric and Envionmental Sciences](http://www.albany.edu/atmos/index.php)

Development of these notes and the [climlab software](https://github.com/brian-rose/climlab) is partially supported by the National Science Foundation under award AGS-1455071 to Brian Rose. Any opinions, findings, conclusions or recommendations expressed here are mine and do not necessarily reflect the views of the National Science Foundation.
____________

```python

```

Lectures/Lecture07 -- Elementary greenhouse models.ipynb