# FFM232, Klassisk fysik och vektorfält - Föreläsningsanteckningar

 **[Christian Forssén](http://fy.chalmers.se/subatom/tsp/), Institutionen för fysik, Chalmers, Göteborg, Sverige**

Date: **Sep 9, 2016**

# 3. Integraler
Det mesta av detta material förutsätts vara känt från kursen i flervariabelanalys. Vi kommer att repetera
### Linje- (kurv-) integraler

* t.ex. $\int_C \vec{F} \cdot d\vec{r}$

* eller $\int_C \phi \cdot ds$

* eller ...

* (integral över en sluten kurva betecknas $\oint_C \vec{F} \cdot d\vec{r}$)

### Ytintegraler

* t.ex. $\int_S \vec{F} \cdot d\vec{S}$

* eller ...

* (integral över en sluten yta betecknas $\oint_C \vec{F} \cdot d\vec{S}$)

### Volymintegraler

* $\int_V \vec{F} dV$

## Parametrisering
Integralerna kan i allmänhet lösas genom parametrisering.

### Parametrisering av kurvintegraler:

T.ex. ges en kurva $C$ av $\vec{r}(\tau)$ med $\tau \in [\tau_1,\tau_2]$. Då blir

$$
\begin{equation}
  \int_C \vec{F}\cdot \mbox{d}\vec{r} = \int_{\tau_1}^{\tau_2} \vec{F}
\cdot \frac{\mbox{d}\vec{r}}{\mbox{d}\tau} \mbox{d}\tau,
\end{equation}
$$

och efter att ha beräknat skalärprodukten har vi en helt vanlig endimensionell integral.

[Comment 1: Lägg här märke till att $d\vec{r}/d\tau$ är en tangentvektor till kurvan $C$.  I princip finns det oändligt många parametriseringar till kurvan $C$, och rent matematiskt spelar det ingen roll vilken man väljer, fast vissa parametriseringar ger snällare räkningar än andra!]

Ibland är kurvan $C$ sluten, det vill säga kurvans start- och slutpunkt sammanfaller.

Man skriver då integralen som

$$
\begin{equation}
  \oint_C \vec{F} \cdot \mbox{d}\vec{r}.
\end{equation}
$$

Det finns andra typer av linjeintegraler, till exempel

$$
\begin{equation}
  \int \phi \mbox{d}\vec{r}, \quad \int \phi \mbox{d}s
\end{equation}
$$

där $\phi$ är ett skalärt fält och $\mbox{d}s = | \mbox{d}\vec{r} | $. Samt

$$
\begin{equation}
  \int \vec{F} \times \mbox{d}\vec{r}, \quad \int \vec{F} \mbox{d}s.
\end{equation}
$$

## Studera räkneexempel:
* Kurvintegral, cirkel 1

* Kurvintegral, cirkel 2

## Konservativa fält
Om

$$
\begin{equation}
  \oint_C \vec{F} \cdot\mbox{d}\vec{r} = 0
\end{equation}
$$

för varje sluten kurva $C$, så säges fältet $\vec{F}$ vara konservativt.  För ett konservativt fält $\vec{F}$ gäller att givet en fix startpunkt A och en fix slutpunkt B, så beror integralen

$$
\begin{equation}
  \int_C \vec{F} \cdot\mbox{d}\vec{r}
\end{equation}
$$

inte på valet av kurvan $C$ mellan dessa punkter.  Betrakta två kurvor $C_1$ och $C_2$ mellan A och B.  Då kan vi skapa en sluten kurva $C_0$ genom att först följa kurvan $C_1$ från A till B, och sedan kurvan $C_2$ baklänges, det vill säga i negativ riktning, tillbaka till A. Integralen över $C_0$ måste då vara 0, fast den integralen kan vi också skriva som

$$
\begin{equation}
  \oint_{C_0} \vec{F} \cdot\mbox{d}\vec{r} = \int_{C_1}
\vec{F} \cdot\mbox{d}\vec{r} - \int_{C_2} \vec{F} \cdot\mbox{d}\vec{r} = 0,
\end{equation}
$$

ty integralen byter tecken om vi följer kurvan i *fel* riktning. Nu följer det att

$$
\begin{equation}
  \int_{C_1} \vec{F} \cdot\mbox{d}\vec{r} = \int_{C_2} \vec{F} \cdot\mbox{d}
\vec{r}.
\end{equation}
$$

## Studera räkneexempel:
* Kurvintegral, fältstyrka

### Parametrisering av ytintegraler:

Precis som man kan beräkna linjeintegralerna genom att parametrisera linjen längs vilken man integrerar kan man beräkna ytintegralerna genom att parametrisera ytan längs med vilken man integrerar.  Skillnaden är att genom att ytan är två-dimensionell så behöver man två parametrar. Antag att ortsvektorerna för punkterna på ytan kan skrivas som $\vec{r}(v,w)$ där $v$ och $w$ är våra parametrar.  Vi kan då bilda två tangentvektorer till ytan

$$
\begin{equation}
  \frac{\partial \vec{r}}{\partial v} \quad \mathrm{och} \quad
\frac{\partial \vec{r}}{\partial w}.
\end{equation}
$$

Förutsatt att dessa tangentvektorer inte är parallella, annars måste vi finna en ny parametrisering, kan vi bilda en normalvektor till ytan

$$
\begin{equation}
  \frac{\partial \vec{r}}{\partial v} \times \frac{\partial \vec{r}}{\partial w}.
\end{equation}
$$

Analogt med hur vi tidigare uttryckte linjeintegralen med hjälp av vår parameter kan vi nu skriva ytintegralen som

$$
\begin{equation}
  \int_S \vec{F} \cdot \mbox{d}\vec{S} = \int_S \vec{F} \cdot
\frac{\partial \vec{r}}{\partial v} \times \frac{\partial \vec{r}}{\partial w}
\mbox{d}v \mbox{d}w,
\end{equation}
$$

där $\mbox{d}\vec{S} = \hat{n} \mbox{d}S = \frac{\partial \vec{r}}{\partial v} \times \frac{\partial \vec{r}}{\partial w} \mbox{d}v \mbox{d}w$ är ytan på det parallellogram som spänns upp av de två tangentvektorerna. Normalvektorn uppfyller $|\hat{n}|=1$.

Allmänt skriver man ytintegraler över en yta $S$ (ofta använder man i de här sammanhangen $S$ för att beteckna en yta) som

$$
\begin{equation}
  \int_S \vec{F} \cdot \mbox{d}\vec{S}.
\end{equation}
$$

För att skilja dessa integraler från andra ytintegraler, som emellanåt förekommer, kallar man dem för normalytintegraler.

## Studera räkneexempel:
* Cylinderyta

[Comment 2: För resten av den här kursen kommer det ofta att vara lämpligt att på detta sätt beskriva arean av ett ytelement som en vektor.  En komplikation är förstås att en yta i allmänhet har två motsatta normalvektorer, och man måste därför ange vilken riktning som är positiv. Ytterligare en komplikation är att det finns ytor för vilka man inte kan definiera normalvektorn på ett kontinuerligt sätt över hela ytan, till exempel Möbius-bandet.  Vi skall inte befatta oss med sådana ytor här, utan begränsa oss till orienterbara ytor, ytor som har en insida och en utsida.]

Om ytan $S$ är sluten så skriver man

$$
\begin{equation}
  \oint_S \vec{F} \cdot \mbox{d}\vec{S}.
\end{equation}
$$

För slutna ytor definierar man den positiva riktningen som den som ges av en vektor som pekar ut från den inneslutna volymen.

Det finns också andra former av ytintegraler, vilka emellanåt används:

$$
\begin{equation}
  \int_S \phi dS,
\end{equation}
$$

där $\phi$ är en skalär, och vi i detta fall inte betraktar $S$ som en
vektor.

$$
\begin{equation}
  \int_S \phi d\vec{S}
\end{equation}
$$

Skillnaden mot det första fallet är att $S$ här behandlas som en vektor.

$$
\begin{equation}
  \int_S \vec{v} \times d\vec{S}
\end{equation}
$$

där $\vec{v}$ är en vektorvärd funktion.

### Parametrisering av volymintegraler

Det finns bara två möjliga sätt att volymintegrera ett fält. Med (det skalära) volymelementet $\mbox{d}V$

$$
\begin{equation}
\int_V \phi \mbox{d}V,\quad \int_V \vec{F} \mbox{d}V.
\end{equation}
$$

En parametrisering med $(u,v,w)$ ger att volymselementet blir volymen av parallellepipeden med sidorna $\frac{\partial \vec{r}}{\partial u} \mbox{d}u$, $\frac{\partial \vec{r}}{\partial v} \mbox{d}v$, $\frac{\partial \vec{r}}{\partial w} \mbox{d}w$ (som då måste vara linjärt oberoende). Denna volym är

$$
\begin{equation}
\mbox{d}V = \left| \frac{\partial \vec{r}}{\partial u} \cdot \left( \frac{\partial \vec{r}}{\partial v} \times \frac{\partial \vec{r}}{\partial w} \right) \right| \mbox{d}u \mbox{d}v \mbox{d}w.
\end{equation}
$$

## Integration med ortogonala kroklinjiga koordinater

Från tidigare kapitel har vi

$$
\begin{equation}
d\vec{r} = \hat{e}_1 h_1 du_1 + \hat{e}_2 h_2 du_2 + \hat{e}_3 h_3 du_3
\end{equation}
$$

Vidare ytelementet, t.ex. för en $u_1$-yta (dvs i $u_2 u_3$-planet):

$$
\begin{equation}
\mbox{d} S_1 = h_2 h_3 \mbox{d}u_2 \mbox{d}u_3
\end{equation}
$$

$$
\begin{equation}
\mbox{d} \vec{S}_1 = \pm \hat{e}_1 h_2 h_3 \mbox{d}u_2 \mbox{d}u_3
\end{equation}
$$

vilket man t.ex. ser från

$$
\begin{equation}
\mbox{d} \vec{S}_1 = \frac{d\vec{r}}{du_2} \times \frac{d\vec{r}}{du_3} du_2 du_3
= \hat{e}_1 h_2 h_3 \mbox{d}u_2 \mbox{d}u_3
\end{equation}
$$

Volymelement:

$$
\begin{equation}
\mbox{d} V = h_1 h_2 h_3 \mbox{d}u_1 \mbox{d}u_2 \mbox{d}u_3.
\end{equation}
$$

Med ett vektorfält $\vec{F}$ som tecknas i det kroklinjiga koordinatsystemet $\vec{F} = F_1 \hat{e}_1 + F_2 \hat{e}_2 + F_3 \hat{e}_3$ får vi t.ex.

$$
\begin{equation}
\int_{C_1} \vec{F} \cdot d\vec{r} = \int_{C_1} F_1 h_1 du_1
\end{equation}
$$

$$
\begin{equation}
\int_{S_1} \vec{F} \cdot d\vec{S}_1 = \int_{S_1} F_1 h_2 h_3 du_2 du_3
\end{equation}
$$

$$
\begin{equation}
\int_V \vec{F} dV = \int_V \vec{F} h_1 h_2 h_3 du_a du_2 du_3,
\end{equation}
$$

där $C_1$ är en kurva längs $u_1$-riktningen och $S_1$ är en $u_1$-yta.

## Räkneexempel: Linjeintegraler

### Exempel: Kurvintegral, cirkel 1

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

Beräkna integralen $\oint_C \phi d\vec{r}$ där $\phi = \phi_0$ (konstant) och kurvan $C$ beskriver en cirkel i xy-planet med radie $a$ och centrum i origo som genomlöps medurs.

* Notera att svaret kommer att bli en vektor.

* Parametrisera kurvan (notera riktningen): $\vec{r}(\tau) = x(\tau)\hat{x} + y(\tau)\hat{y} = a \sin\omega\tau \hat{x} + a \cos\omega\tau \hat{y}$ med $\tau \in [0,2\pi/\omega]$.

* Vi inkluderar konstanten $\omega$ för att illustrera att det finns ett oändligt antal parametriseringar och att svaret inte kan bero på detta.

* Förskjutningsvektorn $d\vec{r} = \hat{x} \frac{dx}{d\tau}d\tau + \hat{y} \frac{dy}{d\tau}d\tau$.

Den parametriserade kurvintegralen blir

$$
\begin{equation}
\oint_C \phi d\vec{r} = \phi_0 \oint_0^{2\pi/\omega} \left[
\hat{x} a \omega\cos\omega\tau - \hat{y} a \omega\sin\omega\tau \right] d\tau = 0
\end{equation}
$$

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

### Exempel: Kurvintegral, cirkel 2

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

Beräkna integralen $\oint_C \phi dr$ där $\phi = \phi_0$ (konstant) och kurvan $C$ beskriver en cirkel i xy-planet med radie $a$ och centrum i origo som genomlöps medurs.

* Notera att svaret kommer att bli en skalär.

* Lite eftertanke ger att svaret borde bli $\phi_0 2 \pi a$, dvs den konstanta potentialen gånger omkretsen på cirkeln.

* Bågelementet blir $dr = |d\vec{r}| = \sqrt{\left( \frac{dx}{d\tau} \right)^2 d\tau^2 + \left( \frac{dy}{d\tau} \right)^2 d\tau^2 } = a \omega d\tau$

Den parametriserade kurvintegralen blir

$$
\begin{equation}
\oint_C \phi ds = \phi_0 a \omega \oint_0^{2\pi/\omega}  d\tau = \phi_0 2 \pi a
\end{equation}
$$

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

### Exempel: Kurvintegral, fältstyrka

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

Betrakta kurvintegralen $\int_C \vec{A} \cdot d\vec{r}$ där $\vec{A} = -\nabla \phi$, dvs en fältstyrka.
* Det betyder att $\int_C \vec{A} \cdot d\vec{r} = -\int_C \nabla{\phi} \cdot d\vec{r}$.

* Kom ihåg att $\nabla\phi \cdot d\vec{r} = d\phi$.

* Alltså $\int_C \vec{A} \cdot d\vec{r} = -\int_{\phi_1}^{\phi_2} d{\phi} = \phi_1 - \phi_2$.

Dvs kurvintegralen av en fältstyrka är oberoende av vägen $C$ utan beror bara på potentialens värden i start- och slutpunkterna.

---------------------------------------------
### Exempel: Kraft och arbete

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

En partikel rör sig längs en bana C, som ges av $\vec{r}(t)$, under inverkan av en kraft $\vec{F}(\vec{r})$.  Vi vill då beräkna arbetet som kraften utövar på partikeln.  Mellan punkterna $\vec{r}$ och $\vec{r}+\mbox{d}\vec{r}$ så är arbetet

$$
\begin{equation}
  \mbox{d}W = \vec{F}\cdot \mbox{d}\vec{r}.
\end{equation}
$$

Vi kan då beräkna arbetet längs hela kurvan genom att beräkna integralen

$$
\begin{equation}
  W = \int_C \vec{F}\cdot \mbox{d}\vec{r}.
\end{equation}
$$

Denna integral är ett exempel på en linjeintegral (kurvintegral). Vi kan skriva

$$
\begin{equation}
  W = \int_C \vec{F} \cdot \frac{\mbox{d}\vec{r}}{\mbox{d}t} \mbox{d}t = \int P \mbox{d}t,
\end{equation}
$$

där $P$ är effekten.

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

### Exempel: Konservativ kraft och arbete

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

En elektron rör sig längs banan $y = \frac{x^2}{H}$ från $(0,0)$ till $(L,L^2/H)$ under inverkan av en elektrostatisk kraft $\vec{F} = e E_0\hat{y}$.  Beräkna det arbete som kraften utför på elektronen.

*Lösning 1:*  Arbetet ges av integralen

$$
\begin{equation}
  \int_C eE_0 \hat{y} \cdot \mbox{d}\vec{r},
\end{equation}
$$

där $C$ är den kurva som elektronen följer.  Vi kan nu använda koordinaten $x$ för att parametrisera vår kurva och skriver kurvan som $\vec{r}(x) = (x, x^2/H)$.  Då gäller att

$$
\begin{equation}
  \frac{\mbox{d}\vec{r}}{\mbox{d}x} = \left(1,\frac{2x}{H}\right).
\end{equation}
$$

Vi kan nu beräkna arbetet ur

$$
\begin{equation}
  \int_C eE_0 \hat{y} \cdot \mbox{d}\vec{r} = \int_0^LeE_0 \hat{y} \cdot
\frac{\mbox{d}\vec{r}}{\mbox{d}x} \mbox{d}x = \int_0^LeE_0 \frac{2x}{H}
\mbox{d}x = \frac{eE_0}{H} \left[x^2\right]_0^L = \frac{e E_0 L^2}{H}.
\end{equation}
$$

*Lösning 2:*  Elektrostatiska krafter är konservativa, så vi kan ersätta kurvan med två räta linjer, en $C_1$ som går från $(0,0)$ till $(L,0)$ och är parallell med $x$-axeln, och en kurva $C_2$ som går från $(L,0)$ till $(L,L^2/H)$ och är parallell med $y$-axeln. Arbetet kan nu skrivas som

$$
\begin{equation}
   \int_C eE_0 \hat{y} \cdot \mbox{d}r = \int_{C_1} eE_0
\hat{y} \cdot \mbox{d}r + \int_{C_2} eE_0 \hat{y} \cdot \mbox{d}r.
\end{equation}
$$

Eftersom kraften överallt är ortogonal mot kurvan $C_1$ följer att
integralen längs med $C_1$ måste vara noll, så det återstår bara att beräkna

$$
\begin{equation}
\int_{C_2} eE_0 \hat{y} \cdot \mbox{d} \vec{r} = \int_{C_2}
e E_0 \hat{y} \cdot \hat{y} \mbox{d}r = e E_0 \int_{C_2} \mbox{d}r.
\end{equation}
$$

Den sista integralen ger nu längden på kurvan $C_2$, vilken är $L^2/H$,
så arbetet blir till slut

$$
\begin{equation}
  \frac{e E_0 L^2}{H}.
\end{equation}
$$

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

### Exempel: Parametriserad 3d-kurva

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

Beräkna integralen av $\vec{u} = (xy, z^2, x)$ längs med kurvan

$$
\begin{equation}
\left\{\begin{array}{lcl}
x & = & 1+t\\
y & = & 0\\
z & = & t^2\\
\end{array}\right.
\end{equation}
$$

där $0 \le t \le 3$.

Vi beräknar då först

$$
\begin{equation}
  \frac{\mbox{d}\vec{r}}{\mbox{d}t} = (1, 0, 2t).
\end{equation}
$$

Vektorfältet uttryckt i $t$ är

$$
\begin{equation}
  \vec{u} = \left(\left(1+t\right) \cdot 0, t^4, 1+t\right) =
\left(0,t^4,1+t\right).
\end{equation}
$$

Skalärprodukten mellan vektorerna är

$$
\begin{equation}
  \left(0,t^4,1+t\right) \cdot \left(1,0,2t\right) = 2t + 2t^2.
\end{equation}
$$

Integralen blir

$$
\begin{equation}
  \int_0^3 \left(2t+2t^2\right)\mbox{d}t =
\left[t^2 + \frac{2t^3}{3}\right]_0^3 = 9 + 18 = 27.
\end{equation}
$$

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

## Räkneexempel: Ytintegraler

### Exempel: Flöde genom yta

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

En vätska med densiteten $\rho$ och hastigheten $\vec{u}$ strömmar parallellt genom ett rör med tvärsnittsarean $A$.  Flödet av vätska genom röret (det vill säga kg vätska som per sekund strömmar genom röret är då $\rho u A$.

Vad händer då om vätskans  hastighet $\vec{u}$ beror på avståndet $r$ från rörets symmetriaxel?  I så fall får vi definiera en flödestäthet $\rho u(r)$ så att flödet genom ett ytelement $dS$ blir $\rho u(r)dS$. Om vi tar $dS$ som en ring med centrum i symmetriaxeln och med en tjocklek d$r$ så är d$A = 2\pi r$d$r$ och det totala flödet genom röret blir

$$
\begin{equation}
  \int \rho u( r ) dS = \int_0^R \rho u ( r ) 2 \pi r
dr,
\end{equation}
$$

där $R$ är rörets radie.

För att nu ytterligare komplicera det hela och verkligen blanda in vektorerna så antar vi att vätskan strömmar genom en tvärsnittsarea $dS$, vilken inte är vinkelrät mot vätskans strömningshastighet $\vec{u}$.  Vi antar att vinkeln mellan normalvektorn $\vec{n}$ till ytan $dS$ och vätskans hastighet $\vec{u}$ är $\theta$.  Då blir flödet genom ytan $dS$

$$
\begin{equation}
  \rho u dS \cos \theta.
\end{equation}
$$

Om vi nu väljer att definiera en vektor $d\vec{S}$ för ett ytelement med storleken $dS$ och riktningen $\vec{n}$, så ser vi att vi kan skriva flödet som

$$
\begin{equation}
  \rho \vec{u} \cdot d\vec{S},
\end{equation}
$$

där $\rho \vec{u}$ kan kallas för en massflödestäthet (jämför med en strömtäthet för flöde av elektrisk laddning).

Vi kan nu skriva vätskeflödet genom en godtycklig yta $A$ som

$$
\begin{equation}
  \int_A \rho \vec{u} \cdot d\vec{S},
\end{equation}
$$

vilket är ett typiskt exempel på en ytintegral.

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

### Exempel: Cylinderyta

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

Beräkna ytintegralen av fältet $\vec{u} = (x,z,-y)$ över cylinderytan $x^2 + y^2 = 1$ mellan $z = 0$ och $z = 1$.  Vi kan då beskriva punkterna på ytan genom deras $z$-koordinat och vinkeln $\varphi$ som ortsvektorn bildar med $\hat{x}$-vektorn.  Det vill säga $\vec{r} = (\cos\varphi , \sin\varphi , z)$, och tangentvektorerna blir

$$
\begin{equation}
  \frac{\mbox{d}\vec{r}}{\mbox{d} \varphi} = \left(-\sin\varphi , \cos \varphi ,
0\right)
\end{equation}
$$

och

$$
\begin{equation}
  \frac{\mbox{d}\vec{r}}{\mbox{d}z} = \left(0,0,1\right).
\end{equation}
$$

Normalvektorn blir

$$
\begin{equation}
  \frac{\mbox{d}\vec{r}}{\mbox{d} \varphi} \times
\frac{\mbox{d}\vec{r}}{\mbox{d}z} = \left(\cos\varphi , \sin \varphi, 0\right).
\end{equation}
$$

Vi kan sedan beräkna integralen som

$$
\begin{equation}
  \int_S \vec{u} \cdot \mbox{d}\vec{S} = \int_0^1\int_0^{2\pi} \left(\cos\varphi,
z, -\sin\varphi\right) \cdot \left(\cos\varphi, \sin \varphi, 0\right)
\mbox{d}\varphi \mbox{d}z \nonumber
\end{equation}
$$

$$
\begin{equation}
= \int_0^1\int_0^{2\pi} \left(\cos^2\varphi + z
\sin\varphi\right) \mbox{d}\varphi\mbox{d}z \nonumber
\end{equation}
$$

$$
\begin{equation}
= \int_0^1 \int_0^{2\pi} \left(
\frac{1}{2} + \frac{1}{2}\cos 2\varphi + z\sin\varphi\right) \mbox{d}\varphi
\mbox{d}z \nonumber
\end{equation}
$$

$$
\begin{equation}
= \int_0^1 \left[\frac{1}{2}\varphi + \frac{1}{4}\sin2\varphi - z
\cos\varphi\right]_0^{2\pi} \mbox{d}z = \int_0^1 \pi \mbox{d}z = \pi.
\end{equation}
$$

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


# OpenMP Parallel Performance and Scalability analysis of $n$-body problem
---

Import all the required libraries.

```python
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from IPython.display import display, HTML
```

## System Info
---

```python
base_path = 'data/'

info = pd.read_csv(base_path + 'system_info.txt', ':', names = ["Parameter", "Description"])
info = pd.DataFrame(info, columns = ["Parameter", "Description"])
display(HTML(info.to_html(justify='left',bold_rows=True ,index=False)))
```

## Obtain the data
---

Serial and parallel execution times can be obtained by running the script *run_tests.sh*. The number of processors, $N$, can be specified in the OpenMP parallelization.

> $ ./run_tests simpar

> $ ./run_tests simpar-omp N

The results from each run is stored in a csv file e.g ***parallel_cpu4_results.csv*** where the tests where run for $N=4$.

Read data from csv files and create DataFrame objects for each of the files. Since serial and parallel results for each number of processors are divided in different files, we concatenate the data from all the parallel results.

```python
serial = pd.read_csv(base_path + 'serial_cpu1_results.csv')
serial.insert(0, column='Test Number', value=serial.index)

num_procs = 8
parallel_data = []

for i in range(1, num_procs+1):
    filename = 'parallel_cpu' + str(i) + '_results.csv'

    try:
        parallel_data.append(pd.read_csv(base_path + filename))
    except:
        print('File {0} not found. Try running the test script for {1} threads'.format(filename,i))

parallel = pd.concat(parallel_data, ignore_index=False)
parallel.insert(0, column='Test Number', value=parallel.index)
```

## Display data
---

### Serial algorithm results

```python
display(HTML(serial.to_html(index=False)))
```

### OpenMP algorithm results

```python
display(HTML(parallel.sort_values(by=['Test Number','Processors']).to_html(index=False)))
```

## Calculate performance metrics
---

Performance results for the faculty provided tests, with varying number of particles, $n$, and simulation steps, $t$. The performance metric used to check scalability was the elapsed time, the speedup and efficiency.

```python
# Set indexes for data frames
serial.set_index(['Test Number'], inplace=True)
parallel.set_index(['Test Number','Processors'], inplace=True)
```

### Speedup

The principal measure of parallelization efficiency is the speedup, $S$, defined to be the ratio of the time to execute the computational workload $W$ on a single processor to the time on $N$ processors.

\begin{equation}
    S_N = \frac{T_1}{T_N}
    \quad\text{where}\quad
    T_N = (f + \frac{(1-f)}{N})T_1
\end{equation}

$f$  represents the fraction of the code that cannot be parallelized. The remaining fraction, $1 – f$, is parallelizable. Optimally, if the parallelized code scales linearly with the number of processors once parallelized, then the runtime reduces to $\frac{(1-f)}{N}$.

```python
parallel['Speedup'] = (serial['Real time'] / parallel['Real time'])
```

```python
# Reset indexes in order to calculate the following metrics
serial.reset_index(inplace=True)
parallel.reset_index(inplace=True)
```

### Efficiency

The ratio of the true speedup to the theoretical speedup is the parallelization efficiency, which is a measure of the efficiency of the parallel processor to execute a given parallel algorithm. Any degradation in performance due to parallelization overhead will result in $\epsilon_N$ being less than one.

\begin{equation}
    \epsilon_N = \frac{S_N}{N}
\end{equation}

```python
parallel['Efficiency'] = parallel['Speedup'] / parallel['Processors']
```

## Data analysis
---

```python
aux = parallel[['Test Number','Particles', 'Steps','Processors','Real time','Speedup','Efficiency']]
temp = pd.DataFrame(aux)
temp.set_index(['Test Number','Processors'], inplace=True)
temp.sort_index(inplace=True)

display(HTML(temp.sort_values(by=['Test Number','Processors']).to_html(index=True)))
```

```python
line_labels = []
lines = []

# Create matplotlib figure
fig, ax = plt.subplots(1,2, figsize=(10,4))
plt.tight_layout()
fig.subplots_adjust(wspace=0.18)

# Setup subplots
ax[0].grid()
ax[1].grid()
ax[0].set_xlabel('Processors')
ax[0].set_ylabel('Speedup')
ax[1].set_xlabel('Processors')
ax[1].set_ylabel('Efficiency')

# For each test in range
for i in range(2,6):
    line_labels.append('{0}: n={1}, t={2}'.format(i, int(temp.loc[(i,1)]['Particles']), int(temp.loc[(i,1)]['Steps'])))
    ax[0].plot(temp.loc[i]['Speedup'], marker=".")
    l, = ax[1].plot(temp.loc[i]['Efficiency'], marker=".")
    lines.append(l)

ax[0].plot([1,8],[1,8], linestyle=':', color='black' ,alpha=0.4)
ax[1].plot([1,8],[1,1], linestyle=':', color='black' ,alpha=0.4)

plt.subplots_adjust(right=0.8)

fig.legend(tuple(lines), tuple(line_labels), loc="center right", borderaxespad=0.1, title="# of test", shadow=True)
plt.show()
```


# Latent Factor DBCM Analysis

This example highlights several advanced modeling strategies.

**Dynamic Binary Cascade Model**

The first is a Dynamic Binary Cascade Model (DBCM), which is the combination a Dynamic Count Mixture Model (DCMM) and a binary cascade (Berry et. al. 2020). When modeling sales in a retail setting, the DCMM (Berry and West, 2019) is used to model the number of transactions involving an item, and the binary cascade models the quantity purchased by each customer. The DCMM models the transactions as a mixture of a Bernoulli and Poisson DGLM:

\begin{equation} \label{eqn-dcmm}
z_t \sim Ber(\pi_t) \text{ and } y_t \mid z_t =
\begin{cases}
0, & \text{if } z_t = 0,\\
1 + x_t, \quad x_t \sim Po(\mu_t), & \text{if }z_t = 1
\end{cases}
\end{equation}

where $\pi_t$ and $\mu_t$ vary according to the dynamics of independent Bernoulli and Poisson DGLMs respectively:

\begin{equation*}
\text{logit}(\pi_t) = \mathbf{F}_{ber, t}^{'}\boldsymbol{\theta}_{ber, t} \qquad \text{and} \qquad \text{log}(\mu_t) = \mathbf{F}_{Po, t}^{'} \boldsymbol{\theta}_{Po, t}
\end{equation*}

A DCMM is useful to capture a higher prevalence of $0$ outcomes than in a standard Poisson DGLM.

Transactions are related to sales by modeling the number of units bought in each transaction. Recognizing that sales outliers often occur due to shoppers buying many units of an item, the probability of each quantity is modeled with a binary cascade. Let $n_{r,t}$ be the number of transactions with more than $r$ units. Then $n_{r,t} | n_{r-1, t} \sim Bin(n_{r-1,t}, \pi_{r,t})$ is defined by a binomial DGLM. This cascade of binomial DGLMs represents the sequence of conditional probabilities for purchasing $n$ units or greater, given that the shopper has bought $n-1$. This implies the following expression for sales $y_t$:

\begin{equation}\label{eqn-dbcm}
y_t =
\begin{cases}
0, & \text{if } z_t = 0,\\
\sum_{r=1:d} r(n_{r-1, t} - n_{r,t}) + e_t, & \text{if }z_t = 1,
\end{cases}
\end{equation}
where $d$ is the predefined length of the cascade and $e_t$ represents excess units greater than $d$. The cascade enables modeling of very small probabilities, in the rare cases when shoppers purchase large quantities of an item on a single grocery store trip.

**Latent Factors**

The second strategy in this example is the use of *latent factors* for multiscale modeling. This example features simulated data from a retail sales setting. There is data for an item, and also for total sales at the store. The total sales are smoother and more predictable than the item level sales. A model is fit to the total sales which includes a day-of-week seasonal effect. This seasonal effect is extracted from the model on total sales, and used as a predictor in the item level model.

Modeling effects at different levels of a hierarchy - aka multiscale modeling - can improve forecast accuracy, because the sales of an individual can be very noisy, making it difficult to learn accurate patterns.

**Copula Forecasting**

In this example we are focusing on forecasting retail sales *1* through *14* days into the future. To do this, we will simulate from the joint forecast distribution *1:14* days into the future. This is accomplished in an efficient manner through the use of a Copula, which accounts for dependence in the forecasts across days into the future.

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
```

```python
from pybats.analysis import analysis, analysis_dbcm
from pybats.latent_factor import seas_weekly_lf
from pybats.shared import load_dbcm_latent_factor_example
from pybats.plot import plot_data_forecast
from pybats.point_forecast import median
from pybats.loss_functions import MAD
```

We start by loading the simulated retail sales data.

The dataframe 'totaldata' has the total daily sales in a store, along with a predictor, which represents a measure of average price.

The dataframe 'data' is the sales of a single item, and has two predictors. 'X_transaction' is a measure of price, and will be used in as a predictor in the DCMM. 'X_cascade' is a binary indicator of whether the item is being promoted within the store, and is used as a predictor in the binary cascade within the DBCM.

```python
data = load_dbcm_latent_factor_example()
totaldata, data = data.values()
totaldata['Y'] = np.log(totaldata['Y'] + 1)
```

```python
totaldata.head()
```

      Y
      X

      2014-06-01
      5.746203
      0.793644

      2014-06-02
      5.375278
      -0.762627

      2014-06-03
      5.375278
      -0.752116

      2014-06-04
      5.613128
      -0.791505

      2014-06-05
      5.429346
      -0.496851

```python
data.head()
```

      Sales
      Y_transaction
      X_transaction
      mt1
      mt2
      mt3
      mt4
      X_cascade
      excess

      2014-06-01
      7.0
      6.0
      0.376729
      1.0
      0.0
      0.0
      0.0
      0
      []

      2014-06-02
      3.0
      3.0
      1.797680
      0.0
      0.0
      0.0
      0.0
      1
      []

      2014-06-03
      9.0
      7.0
      -1.687661
      2.0
      0.0
      0.0
      0.0
      1
      []

      2014-06-04
      11.0
      10.0
      -0.188624
      1.0
      0.0
      0.0
      0.0
      0
      []

      2014-06-05
      5.0
      4.0
      0.684483
      1.0
      0.0
      0.0
      0.0
      1
      []

Here we define hyper parameters for the analysis:
-  *rho* is a discount factor which calibrates the forecast distribution. A value of *rho* less than $1$ increases the forecast variance.

- *k* is the number of days ahead to forecast.

- *nsamps* is the number of forecast samples to draw.

- *prior_length* is the number of days of data to use when defining the priors for model coefficients.

```python
#Define hyper parameters
rho = .2  # rho must be greater than 0, and is typically < 1. A smaller rho widens the forecast distribution.
k = 14 # Number of days ahead that we will forecast
nsamps = 200
prior_length = 21
```

Next, we define the window of time that we want to forecast over. For each day within this time period, the model will sample from the path (joint) forecast distribution *1:k* days into the future.

```python
# Define the forecast range
T = len(totaldata)
forecast_end_date = totaldata.index[-k]
forecast_start_date = forecast_end_date - pd.DateOffset(days=365)
```

The first analysis is run on the 'totaldata', which is used to learn a latent factor. In this case, we fit a normal DLM to the log of total sales in order to learn the weekly season effect, which is stored in the latent factor.

```python
# Get multiscale signal (a latent factor) from higher level log-normal model
latent_factor = analysis(totaldata['Y'].values, totaldata['X'].values, k,
                         forecast_start_date, forecast_end_date, dates=totaldata.index,
                         seasPeriods=[7], seasHarmComponents=[[1,2,3]],
                         family="normal", ret=['new_latent_factors'], new_latent_factors= [seas_weekly_lf.copy()],
                         prior_length=prior_length)
```

    beginning forecasting

The second analysis is performed on 'data', which is the simulated sales of a single item. The latent factor is used to inform on the sales of this item. On each day, a copula is used to draw joint forecast samples from *1:k* days ahead.

```python
# Update and forecast the model
mod, forecast_samples = analysis_dbcm(data['Y_transaction'].values.reshape(-1), data['X_transaction'].values.reshape(-1,1),
                                 data[['mt1', 'mt2', 'mt3', 'mt4']].values, data['X_cascade'].values.reshape(-1,1),
                                 data['excess'].values,
                                 forecast_start=forecast_start_date, forecast_end=forecast_end_date,
                                 prior_length=prior_length, k=k,
                                 nsamps=nsamps, rho=rho,
                                 latent_factor=latent_factor, dates = data.index,
                                 delregn_pois=.98)
```

    beginning forecasting

Finally, we can examine the results, first by plotting both the *1-* and *14-* step ahead forecasts:

```python
forecast = median(forecast_samples)

horizon = 1
plot_length = 50
fig, ax = plt.subplots(figsize=(8,4))
start_date = forecast_end_date + pd.DateOffset(horizon - plot_length)
end_date = forecast_end_date + pd.DateOffset(horizon - 1)
ax = plot_data_forecast(fig, ax, data.loc[start_date:end_date].Sales,
                        forecast[-plot_length:,horizon - 1],
                        forecast_samples[:,-plot_length:,horizon - 1],
                        data.loc[start_date:end_date].index,
                        linewidth = 2)
```

```python
horizon = 14
plot_length = 50
fig, ax = plt.subplots(figsize=(8,4))
start_date = forecast_end_date + pd.DateOffset(horizon - plot_length)
end_date = forecast_end_date + pd.DateOffset(horizon - 1)
ax = plot_data_forecast(fig, ax, data.loc[start_date:end_date].Sales,
                        forecast[-plot_length:,horizon - 1],
                        forecast_samples[:,-plot_length:,horizon - 1],
                        data.loc[start_date:end_date].index,
                        linewidth = 2)
```

As well as looking at the mean absolute deviation (MAD) between the forecast median and the observations over the forecast horizons. Interestingly, there is only a small increase in the MAD for longer forecast horizons.

```python
# Mean absolute deviation at increasing forecast horizons
horizons = list(range(1, k+1))
list(map(lambda k: MAD(data.loc[forecast_start_date + pd.DateOffset(k-1):forecast_end_date + pd.DateOffset(k-1)].Sales,
                      forecast[:,k-1]),
         horizons))
```

    [3.07103825136612,
     3.0382513661202184,
     3.080601092896175,
     3.0628415300546448,
     3.1079234972677594,
     3.0942622950819674,
     3.0846994535519126,
     3.0860655737704916,
     3.08879781420765,
     3.1434426229508197,
     3.1420765027322406,
     3.129781420765027,
     3.080601092896175,
     3.069672131147541]

```python

```

examples/DBCM Latent Factor Example.ipynb


# Partial Differential Equations and Gaussian Process with GPy

#### presented at the EBI BioPreDyn Course 'The Systems Biology Modelling Cycle'

#### Mu Niu, Neil Lawrence, 12th May 20014, University of Sheffield

## The Spatio-Temporal Model

In this notebook we consider the latent force model paradigm (Alvarez et al, 2013, Alvarez et al, 2011, Alvarez et al, 2009) to drive spatio-temporal differential equation with a Gaussian process. Latent force models are differential equations whose initial conditions or driving forces are given by a stochastic process. Linear latent force models are linear (partial or ordinary) differential equations. If a linear latent force model is driven by a Gaussian process latent force, this describes a joint Gaussian process distribution across all the variables of interest. The Gaussian process covariance function encodes the relationships between the variables, as proscribed by the differential equation, through the covariance function.

This direction of research is part of our ideas as to how to merge mechanistic and statistical models of data. It also maps onto our ideas about 'Gaussian processes over everything'. The covariance function interelates the protein and mRNA concentrations in the same model.

### Differential Equation Model

A model of post-transcriptional processing is formulated to describe the spatio-temporal Drosophila
protein expression data (Becker et al, 2013, Alvarez et al, 2011). Protein production is considered to be linearly dependent on the concentration of mRNA at an earlier time point. The model also allows for diffusion of protein between nuclei and linear protein decay. These processes are dependent on the diffusion parameter and the degradation rate of protein respectively.

\begin{equation}
 a \frac{\partial ^2 y_{x,t}}{\partial x^2} + b \frac{\partial y_{x,t}}{\partial t} + c y_{x,t}=  f_{x,t}
\end{equation}

The coefficients $a$, $b$ and $c$ are unknown. In this study, we use Gaussian process with an exponentiated quadratic kernel as a prior over $y_{x,t}$ (protein). The kernel of $f_{x,t}$ (mRNA) is derived by applying the partial differential operator on the spatial-temporal kernel of protein. The multi-output Gaussian process are developed by combining the covariance matrix of mRNA and protein and their cross covariance.

```python
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
import numpy as np
import pylab as pb
import GPy
import pandas
from pandas import read_csv
```

The spatio-temporal multi-output partial differential equation covariance functions have been developed with the kernel name `GPy.kern.ODE_st` in GPy. The inputs are one dimension spatial data, one dimension temporal data and one dimension index which is used to indicate $f$ and $y$.

###

```python
data = GPy.util.datasets.drosophila_knirps()
```

The next thing to do is to compose the data ready for presentation to GPy. Here we need to use the time field as the input and a concatanation of the expression levels as the output. We need to provide a corresponding index for to each input to describe what output is being represented.

Now we set up the covariance function with the relevant parameters.

```python
kern = GPy.kern.ODE_st(input_dim=3,
                       a=1., b=1., c=1.,
                       variance_Yx=1., variance_Yt=1.,
                       lengthscale_Yx=15.,
                       lengthscale_Yt=15.)
```

With the data correctly presented and the covariance function defined, we are ready to proceed with the Gaussian process regression.

```python
data['X']
data['Y']
```

    array([[  5.90000000e-01],
           [  5.00000000e-01],
           [  9.00000000e-02],
           [  2.50000000e-01],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  8.00000000e-02],
           [  2.30000000e-01],
           [  0.00000000e+00],
           [  1.90000000e-01],
           [  0.00000000e+00],
           [  2.70000000e-01],
           [  1.40000000e-01],
           [  1.00000000e-01],
           [  2.70000000e-01],
           [  8.20000000e-01],
           [  2.04000000e+00],
           [  2.01000000e+00],
           [  3.19000000e+00],
           [  4.74000000e+00],
           [  8.47000000e+00],
           [  9.74000000e+00],
           [  1.44700000e+01],
           [  2.02400000e+01],
           [  2.74100000e+01],
           [  3.54200000e+01],
           [  4.33400000e+01],
           [  5.29000000e+01],
           [  6.03400000e+01],
           [  6.57900000e+01],
           [  7.28200000e+01],
           [  7.45700000e+01],
           [  7.55900000e+01],
           [  7.54700000e+01],
           [  7.48900000e+01],
           [  7.24400000e+01],
           [  6.73000000e+01],
           [  6.15700000e+01],
           [  5.56400000e+01],
           [  4.92700000e+01],
           [  4.11100000e+01],
           [  3.35900000e+01],
           [  2.76600000e+01],
           [  2.22200000e+01],
           [  1.69400000e+01],
           [  1.26200000e+01],
           [  1.03800000e+01],
           [  7.10000000e+00],
           [  5.81000000e+00],
           [  4.27000000e+00],
           [  3.05000000e+00],
           [  2.55000000e+00],
           [  1.76000000e+00],
           [  1.35000000e+00],
           [  1.44000000e+00],
           [  1.22000000e+00],
           [  4.00000000e-02],
           [  1.00000000e-02],
           [  0.00000000e+00],
           [  7.00000000e-02],
           [  0.00000000e+00],
           [  8.00000000e-02],
           [  0.00000000e+00],
           [  1.60000000e-01],
           [  8.00000000e-01],
           [  4.90000000e-01],
           [  9.70000000e-01],
           [  1.10000000e+00],
           [  1.28000000e+00],
           [  1.50000000e+00],
           [  1.15000000e+00],
           [  1.74000000e+00],
           [  2.31000000e+00],
           [  2.45000000e+00],
           [  3.40000000e+00],
           [  4.53000000e+00],
           [  5.91000000e+00],
           [  9.42000000e+00],
           [  1.37000000e+01],
           [  2.05500000e+01],
           [  2.95600000e+01],
           [  4.14100000e+01],
           [  5.40700000e+01],
           [  6.88200000e+01],
           [  8.37000000e+01],
           [  9.77600000e+01],
           [  1.09540000e+02],
           [  1.16130000e+02],
           [  1.20800000e+02],
           [  1.21370000e+02],
           [  1.19050000e+02],
           [  1.14270000e+02],
           [  1.06430000e+02],
           [  9.58400000e+01],
           [  8.20200000e+01],
           [  7.07700000e+01],
           [  5.85700000e+01],
           [  4.64300000e+01],
           [  3.57600000e+01],
           [  2.91800000e+01],
           [  2.30300000e+01],
           [  1.71900000e+01],
           [  1.42700000e+01],
           [  1.05000000e+01],
           [  8.81000000e+00],
           [  7.22000000e+00],
           [  6.12000000e+00],
           [  5.20000000e+00],
           [  4.17000000e+00],
           [  3.32000000e+00],
           [  3.02000000e+00],
           [  2.76000000e+00],
           [  1.97000000e+00],
           [  4.00000000e-01],
           [  2.60000000e-01],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  4.10000000e-01],
           [  1.57000000e+00],
           [  3.16000000e+00],
           [  5.27000000e+00],
           [  8.68000000e+00],
           [  1.48000000e+01],
           [  2.42800000e+01],
           [  3.78200000e+01],
           [  5.36300000e+01],
           [  7.41300000e+01],
           [  9.58900000e+01],
           [  1.17020000e+02],
           [  1.36130000e+02],
           [  1.49680000e+02],
           [  1.57060000e+02],
           [  1.59200000e+02],
           [  1.56380000e+02],
           [  1.49960000e+02],
           [  1.36460000e+02],
           [  1.18340000e+02],
           [  9.93600000e+01],
           [  8.16100000e+01],
           [  6.28500000e+01],
           [  4.85500000e+01],
           [  3.77600000e+01],
           [  2.90100000e+01],
           [  2.17400000e+01],
           [  1.62400000e+01],
           [  1.18200000e+01],
           [  9.01000000e+00],
           [  6.69000000e+00],
           [  5.40000000e+00],
           [  4.44000000e+00],
           [  3.80000000e+00],
           [  3.08000000e+00],
           [  2.46000000e+00],
           [  2.06000000e+00],
           [  1.63000000e+00],
           [  1.60000000e+00],
           [  1.44000000e+00],
           [  3.80000000e-01],
           [  1.60000000e-01],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  2.60000000e-01],
           [  4.40000000e-01],
           [  1.55000000e+00],
           [  1.38000000e+00],
           [  1.16000000e+00],
           [  1.54000000e+00],
           [  1.06000000e+00],
           [  9.30000000e-01],
           [  1.47000000e+00],
           [  2.04000000e+00],
           [  3.61000000e+00],
           [  4.61000000e+00],
           [  6.02000000e+00],
           [  8.15000000e+00],
           [  1.25200000e+01],
           [  1.92400000e+01],
           [  3.05000000e+01],
           [  4.59700000e+01],
           [  6.48700000e+01],
           [  9.24300000e+01],
           [  1.23410000e+02],
           [  1.49660000e+02],
           [  1.71480000e+02],
           [  1.85620000e+02],
           [  1.92350000e+02],
           [  1.93720000e+02],
           [  1.86770000e+02],
           [  1.75700000e+02],
           [  1.58920000e+02],
           [  1.37310000e+02],
           [  1.12660000e+02],
           [  8.71900000e+01],
           [  6.75500000e+01],
           [  5.13100000e+01],
           [  3.89600000e+01],
           [  2.91500000e+01],
           [  2.24100000e+01],
           [  1.70300000e+01],
           [  1.31100000e+01],
           [  9.82000000e+00],
           [  8.22000000e+00],
           [  7.00000000e+00],
           [  6.37000000e+00],
           [  5.53000000e+00],
           [  5.27000000e+00],
           [  4.75000000e+00],
           [  4.11000000e+00],
           [  3.31000000e+00],
           [  2.78000000e+00],
           [  2.11000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  1.40000000e-01],
           [  3.00000000e-01],
           [  3.20000000e-01],
           [  7.00000000e-02],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  4.90000000e-01],
           [  1.63000000e+00],
           [  2.71000000e+00],
           [  3.17000000e+00],
           [  4.86000000e+00],
           [  8.34000000e+00],
           [  1.60300000e+01],
           [  2.77100000e+01],
           [  4.26200000e+01],
           [  6.24900000e+01],
           [  8.68800000e+01],
           [  1.22690000e+02],
           [  1.57310000e+02],
           [  1.81910000e+02],
           [  1.98100000e+02],
           [  2.04160000e+02],
           [  2.07460000e+02],
           [  2.04180000e+02],
           [  1.96550000e+02],
           [  1.80970000e+02],
           [  1.56840000e+02],
           [  1.24870000e+02],
           [  9.50400000e+01],
           [  6.91700000e+01],
           [  5.02900000e+01],
           [  3.68100000e+01],
           [  2.77600000e+01],
           [  2.00500000e+01],
           [  1.53700000e+01],
           [  1.21600000e+01],
           [  9.60000000e+00],
           [  7.65000000e+00],
           [  6.37000000e+00],
           [  5.76000000e+00],
           [  5.11000000e+00],
           [  4.38000000e+00],
           [  3.70000000e+00],
           [  2.94000000e+00],
           [  2.46000000e+00],
           [  1.85000000e+00],
           [  1.33000000e+00],
           [  6.50000000e-01],
           [  1.70000000e-01],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  1.60000000e-01],
           [  2.70000000e-01],
           [  2.10000000e-01],
           [  1.00000000e-01],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  3.00000000e-01],
           [  1.56000000e+00],
           [  2.69000000e+00],
           [  3.37000000e+00],
           [  4.87000000e+00],
           [  9.06000000e+00],
           [  1.78500000e+01],
           [  2.90600000e+01],
           [  4.27800000e+01],
           [  6.01100000e+01],
           [  8.42900000e+01],
           [  1.16780000e+02],
           [  1.48300000e+02],
           [  1.71600000e+02],
           [  1.88430000e+02],
           [  1.97980000e+02],
           [  1.99570000e+02],
           [  1.95680000e+02],
           [  1.86220000e+02],
           [  1.68300000e+02],
           [  1.42590000e+02],
           [  1.16470000e+02],
           [  8.96500000e+01],
           [  6.17400000e+01],
           [  4.44800000e+01],
           [  3.31100000e+01],
           [  2.39100000e+01],
           [  1.75700000e+01],
           [  1.30500000e+01],
           [  9.73000000e+00],
           [  7.60000000e+00],
           [  6.15000000e+00],
           [  5.53000000e+00],
           [  5.03000000e+00],
           [  4.36000000e+00],
           [  3.90000000e+00],
           [  3.06000000e+00],
           [  2.52000000e+00],
           [  1.74000000e+00],
           [  1.58000000e+00],
           [  1.05000000e+00],
           [  7.50000000e-01],
           [  1.26000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  5.30000000e-01],
           [  6.20000000e-01],
           [  2.40000000e-01],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  1.39000000e+00],
           [  2.45000000e+00],
           [  3.01000000e+00],
           [  3.79000000e+00],
           [  6.01000000e+00],
           [  1.32400000e+01],
           [  2.62000000e+01],
           [  4.06700000e+01],
           [  5.35400000e+01],
           [  7.02200000e+01],
           [  9.75800000e+01],
           [  1.32250000e+02],
           [  1.61920000e+02],
           [  1.84690000e+02],
           [  1.96490000e+02],
           [  1.93580000e+02],
           [  1.87730000e+02],
           [  1.80960000e+02],
           [  1.65470000e+02],
           [  1.42400000e+02],
           [  1.14660000e+02],
           [  8.52300000e+01],
           [  5.92000000e+01],
           [  4.41300000e+01],
           [  3.23600000e+01],
           [  2.28700000e+01],
           [  1.60200000e+01],
           [  1.15200000e+01],
           [  8.47000000e+00],
           [  6.32000000e+00],
           [  5.36000000e+00],
           [  4.78000000e+00],
           [  4.19000000e+00],
           [  3.67000000e+00],
           [  3.09000000e+00],
           [  1.98000000e+00],
           [  1.10000000e+00],
           [  5.40000000e-01],
           [  7.00000000e-02],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  4.80000000e+00],
           [  9.30000000e-01],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  1.30000000e-01],
           [  2.11000000e+00],
           [  2.49000000e+00],
           [  1.71000000e+00],
           [  3.30000000e-01],
           [  2.40000000e-01],
           [  1.80000000e-01],
           [  1.00000000e-01],
           [  4.40000000e-01],
           [  3.31000000e+00],
           [  4.53000000e+00],
           [  4.35000000e+00],
           [  4.78000000e+00],
           [  8.90000000e+00],
           [  2.19300000e+01],
           [  3.68400000e+01],
           [  4.94300000e+01],
           [  6.58800000e+01],
           [  8.36400000e+01],
           [  1.08710000e+02],
           [  1.35760000e+02],
           [  1.61310000e+02],
           [  1.78790000e+02],
           [  1.75260000e+02],
           [  1.65930000e+02],
           [  1.64850000e+02],
           [  1.53460000e+02],
           [  1.34780000e+02],
           [  1.10040000e+02],
           [  8.71300000e+01],
           [  6.10500000e+01],
           [  4.57600000e+01],
           [  3.38100000e+01],
           [  2.53000000e+01],
           [  1.76600000e+01],
           [  1.24000000e+01],
           [  8.71000000e+00],
           [  6.55000000e+00],
           [  5.65000000e+00],
           [  5.49000000e+00],
           [  4.93000000e+00],
           [  3.95000000e+00],
           [  3.25000000e+00],
           [  2.31000000e+00],
           [  1.63000000e+00],
           [  1.10000000e+00],
           [  1.70000000e-01],
           [  5.60000000e-01],
           [  1.50000000e-01],
           [  2.40000000e-01],
           [  0.00000000e+00],
           [  7.49000000e+00],
           [  6.96000000e+00],
           [  4.73000000e+00],
           [  4.20000000e+00],
           [  6.12000000e+00],
           [  7.15000000e+00],
           [  6.70000000e+00],
           [  6.91000000e+00],
           [  5.57000000e+00],
           [  6.08000000e+00],
           [  7.77000000e+00],
           [  5.54000000e+00],
           [  4.36000000e+00],
           [  4.27000000e+00],
           [  5.92000000e+00],
           [  2.99000000e+00],
           [  3.46000000e+00],
           [  4.01000000e+00],
           [  3.55000000e+00],
           [  5.34000000e+00],
           [  4.55000000e+00],
           [  8.77000000e+00],
           [  1.36900000e+01],
           [  1.92600000e+01],
           [  2.82600000e+01],
           [  4.04600000e+01],
           [  5.21300000e+01],
           [  6.87400000e+01],
           [  8.51200000e+01],
           [  1.01550000e+02],
           [  1.09970000e+02],
           [  1.21430000e+02],
           [  1.25950000e+02],
           [  1.36690000e+02],
           [  1.21220000e+02],
           [  1.17650000e+02],
           [  1.06490000e+02],
           [  9.43300000e+01],
           [  7.57700000e+01],
           [  6.22000000e+01],
           [  5.63100000e+01],
           [  3.78600000e+01],
           [  2.97000000e+01],
           [  2.27400000e+01],
           [  2.01100000e+01],
           [  1.45500000e+01],
           [  1.08300000e+01],
           [  9.30000000e+00],
           [  7.59000000e+00],
           [  5.80000000e+00],
           [  2.81000000e+00],
           [  3.60000000e+00],
           [  3.06000000e+00],
           [  1.35000000e+00],
           [  2.64000000e+00],
           [  2.58000000e+00],
           [  4.29000000e+00],
           [  2.27000000e+00],
           [  4.11000000e+00],
           [  8.40000000e-01],
           [  2.92000000e+00],
           [  2.92000000e+00],
           [  1.76000000e+00],
           [  1.23000000e+00],
           [  4.90000000e-01],
           [  1.72000000e+00],
           [  1.46000000e+00],
           [  1.88000000e+00],
           [  5.10000000e-01],
           [  0.00000000e+00],
           [  2.30000000e-01],
           [  1.67000000e+00],
           [  0.00000000e+00],
           [  9.50000000e-01],
           [  7.00000000e-01],
           [  2.71000000e+00],
           [  2.41000000e+00],
           [  5.45000000e+00],
           [  1.19900000e+01],
           [  1.65900000e+01],
           [  3.23400000e+01],
           [  4.86000000e+01],
           [  7.45900000e+01],
           [  9.83700000e+01],
           [  1.31450000e+02],
           [  1.57250000e+02],
           [  1.86570000e+02],
           [  1.85670000e+02],
           [  1.88920000e+02],
           [  1.93460000e+02],
           [  1.89980000e+02],
           [  1.66270000e+02],
           [  1.42150000e+02],
           [  1.15260000e+02],
           [  8.94400000e+01],
           [  6.21500000e+01],
           [  4.91100000e+01],
           [  3.18100000e+01],
           [  2.20200000e+01],
           [  1.30800000e+01],
           [  9.26000000e+00],
           [  5.29000000e+00],
           [  3.32000000e+00],
           [  2.41000000e+00],
           [  1.30000000e+00],
           [  1.55000000e+00],
           [  1.69000000e+00],
           [  0.00000000e+00],
           [  1.90000000e+00],
           [  3.90000000e-01],
           [  1.37000000e+00],
           [  1.65000000e+00],
           [  4.27000000e+00],
           [  4.36000000e+00],
           [  7.17000000e+00],
           [  7.45000000e+00],
           [  5.27000000e+00],
           [  7.56000000e+00],
           [  4.34000000e+00],
           [  6.87000000e+00],
           [  9.60000000e+00],
           [  8.12000000e+00],
           [  8.26000000e+00],
           [  6.87000000e+00],
           [  6.70000000e+00],
           [  7.15000000e+00],
           [  7.15000000e+00],
           [  6.01000000e+00],
           [  5.38000000e+00],
           [  6.57000000e+00],
           [  4.76000000e+00],
           [  5.34000000e+00],
           [  5.75000000e+00],
           [  7.10000000e+00],
           [  4.57000000e+00],
           [  1.01600000e+01],
           [  1.69600000e+01],
           [  3.11300000e+01],
           [  4.74200000e+01],
           [  6.79300000e+01],
           [  9.62600000e+01],
           [  1.28880000e+02],
           [  1.64790000e+02],
           [  1.93420000e+02],
           [  1.91820000e+02],
           [  2.02190000e+02],
           [  2.07870000e+02],
           [  1.91080000e+02],
           [  1.66440000e+02],
           [  1.34880000e+02],
           [  1.07760000e+02],
           [  8.03400000e+01],
           [  5.57500000e+01],
           [  3.55900000e+01],
           [  2.61900000e+01],
           [  1.94900000e+01],
           [  1.12300000e+01],
           [  9.05000000e+00],
           [  6.43000000e+00],
           [  7.01000000e+00],
           [  6.64000000e+00],
           [  4.57000000e+00],
           [  4.20000000e+00],
           [  4.92000000e+00],
           [  4.94000000e+00],
           [  6.52000000e+00],
           [  4.62000000e+00],
           [  4.59000000e+00],
           [  5.24000000e+00],
           [  6.80000000e+00],
           [  5.31000000e+00],
           [  6.29000000e+00],
           [  4.41000000e+00],
           [  6.12000000e+00],
           [  7.15000000e+00],
           [  6.84000000e+00],
           [  1.02800000e+01],
           [  8.70000000e+00],
           [  1.10400000e+01],
           [  1.11400000e+01],
           [  1.04600000e+01],
           [  6.45000000e+00],
           [  5.24000000e+00],
           [  7.40000000e+00],
           [  6.87000000e+00],
           [  9.35000000e+00],
           [  6.17000000e+00],
           [  6.24000000e+00],
           [  5.59000000e+00],
           [  3.71000000e+00],
           [  4.52000000e+00],
           [  4.27000000e+00],
           [  1.00000000e+01],
           [  2.00000000e+01],
           [  3.27400000e+01],
           [  4.02800000e+01],
           [  5.48900000e+01],
           [  7.31300000e+01],
           [  1.01500000e+02],
           [  1.30410000e+02],
           [  1.66530000e+02],
           [  1.85670000e+02],
           [  1.83470000e+02],
           [  1.89470000e+02],
           [  1.75320000e+02],
           [  1.53000000e+02],
           [  1.24000000e+02],
           [  9.26600000e+01],
           [  6.00200000e+01],
           [  3.71700000e+01],
           [  2.88400000e+01],
           [  2.07400000e+01],
           [  1.61500000e+01],
           [  1.23700000e+01],
           [  8.96000000e+00],
           [  9.91000000e+00],
           [  9.19000000e+00],
           [  8.54000000e+00],
           [  1.03500000e+01],
           [  9.65000000e+00],
           [  8.31000000e+00],
           [  8.86000000e+00],
           [  5.73000000e+00],
           [  7.38000000e+00],
           [  4.41000000e+00],
           [  5.92000000e+00],
           [  5.36000000e+00],
           [  3.80000000e+00],
           [  4.92000000e+00],
           [  2.51000000e+00],
           [  3.69000000e+00],
           [  3.76000000e+00],
           [  2.60000000e+00],
           [  3.94000000e+00],
           [  4.80000000e+00],
           [  7.40000000e+00],
           [  7.10000000e+00],
           [  8.33000000e+00],
           [  3.57000000e+00],
           [  5.78000000e+00],
           [  6.17000000e+00],
           [  6.66000000e+00],
           [  6.40000000e+00],
           [  4.59000000e+00],
           [  5.57000000e+00],
           [  5.89000000e+00],
           [  4.96000000e+00],
           [  7.08000000e+00],
           [  9.58000000e+00],
           [  1.60300000e+01],
           [  2.89800000e+01],
           [  3.74700000e+01],
           [  4.70500000e+01],
           [  6.58000000e+01],
           [  7.91400000e+01],
           [  9.78600000e+01],
           [  1.32150000e+02],
           [  1.43070000e+02],
           [  1.44420000e+02],
           [  1.33890000e+02],
           [  1.23240000e+02],
           [  1.12130000e+02],
           [  9.55400000e+01],
           [  6.61700000e+01],
           [  4.82600000e+01],
           [  3.18300000e+01],
           [  2.68900000e+01],
           [  1.82600000e+01],
           [  1.42000000e+01],
           [  1.04900000e+01],
           [  1.10900000e+01],
           [  9.28000000e+00],
           [  7.17000000e+00],
           [  9.47000000e+00],
           [  8.84000000e+00],
           [  9.12000000e+00],
           [  9.07000000e+00],
           [  7.28000000e+00],
           [  1.03000000e+01],
           [  9.74000000e+00],
           [  8.51000000e+00],
           [  9.02000000e+00],
           [  5.71000000e+00],
           [  8.65000000e+00],
           [  9.05000000e+00],
           [  4.08000000e+00],
           [  7.10000000e+00],
           [  4.50000000e+00],
           [  4.45000000e+00],
           [  3.62000000e+00],
           [  5.17000000e+00],
           [  6.17000000e+00],
           [  4.20000000e+00],
           [  5.57000000e+00],
           [  9.50000000e-01],
           [  5.15000000e+00],
           [  3.02000000e+00],
           [  2.58000000e+00],
           [  2.76000000e+00],
           [  2.81000000e+00],
           [  4.59000000e+00],
           [  3.22000000e+00],
           [  4.57000000e+00],
           [  4.06000000e+00],
           [  1.67000000e+01],
           [  2.84200000e+01],
           [  4.03200000e+01],
           [  5.13400000e+01],
           [  6.14600000e+01],
           [  7.26400000e+01],
           [  8.06700000e+01],
           [  1.00970000e+02],
           [  1.16020000e+02],
           [  1.10130000e+02],
           [  1.04790000e+02],
           [  9.14100000e+01],
           [  7.64400000e+01],
           [  6.24100000e+01],
           [  5.10900000e+01],
           [  3.87000000e+01],
           [  3.18500000e+01],
           [  2.00200000e+01],
           [  1.72100000e+01],
           [  1.35700000e+01],
           [  1.02500000e+01],
           [  8.51000000e+00],
           [  1.02500000e+01],
           [  7.93000000e+00],
           [  7.54000000e+00],
           [  8.75000000e+00],
           [  9.19000000e+00],
           [  7.70000000e+00],
           [  6.68000000e+00],
           [  7.66000000e+00],
           [  8.44000000e+00],
           [  5.38000000e+00],
           [  8.00000000e+00],
           [  1.53000000e+00],
           [  1.44000000e+00],
           [  2.48000000e+00],
           [  2.32000000e+00],
           [  1.90000000e-01],
           [  4.59000000e+00],
           [  6.01000000e+00],
           [  6.22000000e+00],
           [  1.06000000e+01],
           [  9.60000000e+00],
           [  9.21000000e+00],
           [  8.89000000e+00],
           [  1.14400000e+01],
           [  8.05000000e+00],
           [  1.32900000e+01],
           [  8.54000000e+00],
           [  8.75000000e+00],
           [  4.11000000e+00],
           [  7.40000000e+00],
           [  4.50000000e+00],
           [  8.98000000e+00],
           [  4.64000000e+00],
           [  5.80000000e+00],
           [  4.22000000e+00],
           [  8.82000000e+00],
           [  1.36900000e+01],
           [  2.51300000e+01],
           [  2.87200000e+01],
           [  3.26200000e+01],
           [  3.50600000e+01],
           [  4.06000000e+01],
           [  5.13400000e+01],
           [  5.24600000e+01],
           [  7.27600000e+01],
           [  5.97600000e+01],
           [  4.51500000e+01],
           [  3.50600000e+01],
           [  3.06500000e+01],
           [  3.00700000e+01],
           [  2.65600000e+01],
           [  2.31800000e+01],
           [  1.65200000e+01],
           [  1.51700000e+01],
           [  1.00000000e+01],
           [  1.05300000e+01],
           [  1.04900000e+01],
           [  7.54000000e+00],
           [  7.35000000e+00],
           [  8.84000000e+00],
           [  7.52000000e+00],
           [  9.65000000e+00],
           [  9.47000000e+00],
           [  9.67000000e+00],
           [  7.47000000e+00],
           [  1.08100000e+01],
           [  6.80000000e+00],
           [  5.71000000e+00],
           [  5.87000000e+00],
           [  4.92000000e+00],
           [  9.84000000e+00],
           [  6.59000000e+00],
           [  7.12000000e+00],
           [  1.46000000e+00],
           [  2.80000000e-01],
           [  4.62000000e+00],
           [  4.27000000e+00],
           [  2.13000000e+00],
           [  3.06000000e+00],
           [  1.74000000e+00],
           [  1.02000000e+00],
           [  0.00000000e+00],
           [  3.04000000e+00],
           [  1.48000000e+00],
           [  2.13000000e+00],
           [  1.21000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  0.00000000e+00],
           [  9.30000000e-01],
           [  1.00000000e+00],
           [  1.62000000e+00],
           [  1.16000000e+00],
           [  2.00000000e+00],
           [  3.18000000e+00],
           [  9.51000000e+00],
           [  1.60500000e+01],
           [  1.50800000e+01],
           [  1.84700000e+01],
           [  1.93700000e+01],
           [  1.98400000e+01],
           [  2.76500000e+01],
           [  1.97200000e+01],
           [  1.86100000e+01],
           [  1.26000000e+01],
           [  1.07400000e+01],
           [  1.37600000e+01],
           [  1.01600000e+01],
           [  2.18000000e+00],
           [  4.66000000e+00],
           [  3.55000000e+00],
           [  5.13000000e+00],
           [  1.88000000e+00],
           [  4.41000000e+00],
           [  4.08000000e+00],
           [  3.00000000e-01],
           [  5.36000000e+00],
           [  5.45000000e+00],
           [  0.00000000e+00],
           [  4.48000000e+00],
           [  2.51000000e+00],
           [  4.71000000e+00],
           [  3.36000000e+00],
           [  4.13000000e+00],
           [  3.99000000e+00],
           [  4.50000000e+00],
           [  4.41000000e+00],
           [  7.68000000e+00],
           [  6.73000000e+00],
           [  7.08000000e+00]])

```python
m = GPy.models.GPRegression(data['X'],data['Y'],kern)
```

# Initial Fit

The initial value of $a$, $b$ and $c$ are 1. For these choices of covariance function parameters, we can plot the random field of $f$ and $y$ separately.

```python
leng = data['X'].shape[0]
m.plot(fixed_inputs=[(2,0)], which_data_rows = slice(0,leng*2/2))
m.plot(fixed_inputs=[(2,1)], which_data_rows = slice(leng*2/2,leng*2))
```

    <matplotlib.axes._subplots.AxesSubplot at 0x7f61c55af790>

Now we optimize the model, this will take a few minutes.

```python
m.optimize(messages=True)
```

After optimization, the estimated value of $a$, $b$ and $c$ can be printed.

```python
print m
```

    Name : GP regression
    Objective : 2746.1527561
    Number of Parameters : 8
    Number of Optimization Parameters : 8
    Updates : True
    Parameters:
      GP_regression.           |           value  |  constraints  |  priors
      ode_st.a                 |  0.439572373353  |      +ve      |
      ode_st.b                 |   10.0570722172  |      +ve      |
      ode_st.c                 |  0.620499976794  |      +ve      |
      ode_st.variance_Yt       |   32.8822754879  |      +ve      |
      ode_st.variance_Yx       |   32.8822754879  |      +ve      |
      ode_st.lengthscale_Yt    |   18.3834609145  |      +ve      |
      ode_st.lengthscale_Yx    |    14.356693167  |      +ve      |
      Gaussian_noise.variance  |   3.26945467609  |      +ve      |

The plot of the random fields are plotted below.

```python
m.plot(fixed_inputs=[(2,0)], which_data_rows = slice(0,leng*2/2))
pb.savefig("gene.pdf")
GPy.plotting.show(m.plot(fixed_inputs=[(2,1)], which_data_rows = slice(leng*2/2,leng*2)), filename='test')
pb.savefig("protein.pdf")
```

In his diploma thesis Kolja Becker estimated the parameters of the partial differential equation where $a = 0.159$, $b =12.77$ and $c =0.983$. The results from the GP approach is $a =0.439$, $b= 10.06$ and $c=0.62$. The GP results are different but they are still within the range of the confidence interval defined in Becker's paper. Two further issues may lead to the difference. One reason could be that the original partial differential equation had a delay parameter $\tau$ for the mRNA ($f$). In our GP model, we did not include this parameter. However, since the Protein-mRNA partial differential equation is linear and Becker's estimate of $\tau$ is small comparing with the time step of the data. The delay impact should not be too big. The estimation algorithm used in Becker's thesis is based on least squares optimization.  The GP approach considers protein and mRNA as a nonlinear function of space and time. And treat the PDE as a linear function to link them. The different modelling methods could also lead to different estimation of the parameters.

Finally, we didn't perform a sensitivity analysis in the above notebook. One thing we can do next is to run a Hamiltonian Monte-Carlo sampler on the model to form error bars for our own analysis. It may be that they are not very well determined given the data.

#### work funded by the BioPreDyn project, it is a collaboration with Nicolas Durrande, Johannes Jaeger.


# Two Loop FDEM

```python
from geoscilabs.base import widgetify
import geoscilabs.em.InductionLoop as IND
from ipywidgets import interact, FloatSlider, FloatText
```

## Parameter Descriptions

Below are the adjustable parameters for widgets within this notebook:

* $I_p$: Transmitter current amplitude [A]
* $a_{Tx}$: Transmitter loop radius [m]
* $a_{Rx}$: Receiver loop radius [m]
* $x_{Rx}$: Receiver x position [m]
* $z_{Rx}$: Receiver z position [m]
* $\theta$: Receiver normal vector relative to vertical [degrees]
* $R$: Resistance of receiver loop [$\Omega$]
* $L$: Inductance of receiver loop [H]
* $f$: Specific frequency [Hz]
* $t$: Specific time [s]

## Background Theory: Induced Currents due to a Harmonic Primary Signal

Consider the case in the image above, where a circular loop of wire ($Tx$) caries a harmonic current $I_p (\omega)$. According to the Biot-Savart law, this produces a harmonic primary magnetic field. The harmonic nature of the corresponding magnetic flux which passes through the receiver coil ($Rx$) generates an induced secondary current $I_s (\omega)$, which depends on the coil's resistance ($R$) and inductance ($L$). Here, we will provided final analytic results associated with the app below. Full derivations can be found at the bottom of the page.

### Frequency Response

The frequency response which characterizes the induced currents in $Rx$ is given by:

\begin{equation}
I_s (\omega) = - \frac{i \omega  A \beta_n}{R + i \omega L} I_p(\omega)
\end{equation}

where $A$ is the area of $Rx$ and $\beta$ contains the geometric information pertaining to the problem. The induced current has both in-phase and quadrature components. These are given by:

\begin{align}
I_{Re} (\omega) &= - \frac{i \omega A \beta_n R}{R^2 + (\omega L)^2} I_p(\omega) \\
I_{Im} (\omega) &= - \frac{ \omega^2 A \beta_n L}{R^2 + (\omega L)^2} I_p(\omega)
\end{align}

### Time-Harmonic Response

In the time domain, let us consider a time-harmonic primary current of the form $I_p(t) = I_0 \textrm{cos}(\omega t)$. In this case, the induced currents within $Rx$ are given by:

\begin{equation}
I_s (t) = - \Bigg [ \frac{\omega I_0 A \beta_n}{R \, \textrm{sin} \phi + \omega L \, \textrm{cos} \phi} \Bigg ] \, \textrm{cos} (\omega t -\phi) \;\;\;\;\; \textrm{where} \;\;\;\;\; \phi = \textrm{tan}^{-1} \Bigg ( \frac{\omega L}{R} \Bigg ) \, \in \, [\pi/2, \pi ]
\end{equation}

The phase-lag between the primary and secondary currents is represented by $\phi$. As a result, there are both in-phase and quadrature components of the induced current, which are given by:
\begin{align}
\textrm{In phase:} \, I_s (t) &= - \Bigg [ \frac{\omega I_0 A \beta_n}{R \, \textrm{sin} \phi + \omega L \, \textrm{cos} \phi} \Bigg ] \textrm{cos} \phi \, \textrm{cos} (\omega t) \\
\textrm{Quadrature:} \, I_s (t) &= - \Bigg [ \frac{\omega I_0 A \beta_n}{R \, \textrm{sin} \phi + \omega L \, \textrm{cos} \phi} \Bigg ] \textrm{sin} \phi \, \textrm{sin} (\omega t)
\end{align}

```python
# RUN FREQUENCY DOMAIN WIDGET
widgetify(IND.fcn_FDEM_Widget,I=FloatSlider(min=1, max=10., value=1., step=1., continuous_update=False, description = "$I_0$"),\
                        a1=FloatSlider(min=1., max=20., value=10., step=1., continuous_update=False, description = "$a_{Tx}$"),\
                        a2=FloatSlider(min=1., max=20.,value=5.,step=1.,continuous_update=False,description = "$a_{Rx}$"),\
                        xRx=FloatSlider(min=-15., max=15., value=0., step=1., continuous_update=False, description = "$x_{Rx}$"),\
                        zRx=FloatSlider(min=-15., max=15., value=-8., step=1., continuous_update=False, description = "$z_{Rx}$"),\
                        azm=FloatSlider(min=-90., max=90., value=0., step=10., continuous_update=False, description = "$\\theta$"),\
                        logR=FloatSlider(min=0., max=6., value=2., step=1., continuous_update=False, description = "$log_{10}(R)$"),\
                        logL=FloatSlider(min=-7., max=-2., value=-4., step=1., continuous_update=False, description = "$log_{10}(L)$"),\
                        logf=FloatSlider(min=0., max=8., value=5., step=1., continuous_update=False, description = "$log_{10}(f)$"))

```

## Supporting Derivation for the Frequency Response

Consider a transmitter loop which carries a harmonic primary current $I_p(\omega)$. According to the Biot-Savart law, this results in a primary magnetic field:
\begin{equation}
\mathbf{B_p} (\mathbf{r},\omega) = \boldsymbol{\beta} \, I_p(\omega)  \;\;\;\; \textrm{where} \;\;\;\;\; \boldsymbol{\beta} = \frac{\mu_0}{4 \pi} \int_C \frac{d \mathbf{l} \times \mathbf{r'}}{|\mathbf{r'}|^2}
\end{equation}
where $\boldsymbol{\beta}$ contains the problem geometry. Assume the magnetic field is homogeneous through the receiver loop. The primary field generates an EMF within the receiver loop equal to:
\begin{equation}
EMF = - i\omega \Phi \;\;\;\;\; \textrm{where} \;\;\;\;\; \Phi =  A \beta_n I_p(\omega)
\end{equation}
where $A$ is the area of the receiver loop and $\beta_n$ is the component of $\boldsymbol{\beta}$ along $\hat n$. The EMF induces a secondary current $I_s(\omega)$ within the receiver loop. The secondary current is defined by the following expression:
\begin{equation}
V = - i \omega  A \beta_n I_p (\omega) =  \big (R + i\omega L \big )I_s(\omega)
\end{equation}
Rearranging this expression to solve for the secondary current we obtain
\begin{equation}
I_s (\omega) = - \frac{i \omega  A \beta_n}{R + i \omega L} I_p(\omega)
\end{equation}
The secondary current has both real and imaginary components. These are given by:
\begin{equation}
I_{Re} (\omega) = - \frac{i \omega A \beta_n R}{R^2 + (\omega L)^2} I_p(\omega)
\end{equation}
and
\begin{equation}
I_{Im} (\omega) = - \frac{ \omega^2 A \beta_n L}{R^2 + (\omega L)^2} I_p(\omega)
\end{equation}

## Supporting Derivation for the Time-Harmonic Response

Consider a transmitter loop which carries a harmonic primary current of the form:
\begin{equation}
I_p(t) = I_0 \textrm{cos} (\omega t)
\end{equation}
According to the Biot-Savart law, this results in a primary magnetic field:
\begin{equation}
\mathbf{B_p} (\mathbf{r},t) =  \boldsymbol{\beta} \, I_0 \, \textrm{cos} (\omega t)  \;\;\;\; \textrm{where} \;\;\;\;\; \boldsymbol{\beta} = \frac{\mu_0}{4 \pi} \int_C \frac{d \mathbf{l} \times \mathbf{r'}}{|\mathbf{r'}|^2}
\end{equation}
where $\boldsymbol{\beta}$ contains the problem geometry. If the magnetic field is homogeneous through the receiver loop, the primary field generates an EMF within the receiver loop equal to:
\begin{equation}
EMF = - \frac{\partial \Phi}{\partial t} \;\;\;\;\; \textrm{where} \;\;\;\;\; \Phi = A\hat n \cdot \mathbf{B_p} = I_0 A \beta_n \, \textrm{cos} (\omega t)
\end{equation}
where $A$ is the area of the receiver loop and $\beta_n$ is the component of $\boldsymbol{\beta}$ along $\hat n$. The EMF induces a secondary current $I_s$ within the receiver loop. The secondary current is defined by the following ODE:
\begin{equation}
V = \omega I_0 A \beta_n \, \textrm{sin} (\omega t) = I_s R + L \frac{dI_s}{dt}
\end{equation}
The ODE has a solution of the form:
\begin{equation}
I_s (t) = \alpha \, \textrm{cos} (\omega t - \phi)
\end{equation}
where $\alpha$ is the amplitude of the secondary current and $\phi$ is the phase lag. By solving the ODE, the secondary current induced in the receiver loop is given by:
\begin{equation}
I_s (t) = - \Bigg [ \frac{\omega I_0 A \beta_n}{R \, \textrm{sin} \phi + \omega L \, \textrm{cos} \phi} \Bigg ] \, \textrm{cos} (\omega t -\phi) \;\;\;\;\; \textrm{where} \;\;\;\;\; \phi = \textrm{tan}^{-1} \Bigg ( \frac{\omega L}{R} \Bigg ) \, \in \, [\pi/2, \pi ]
\end{equation}
The secondary current has both in-phase and quadrature components, these are given by:
\begin{equation}
\textrm{In phase:} \, I_s (t) = - \Bigg [ \frac{\omega I_0 A \beta_n}{R \, \textrm{sin} \phi + \omega L \, \textrm{cos} \phi} \Bigg ] \textrm{cos} \phi \, \textrm{cos} (\omega t)
\end{equation}
and
\begin{equation}
\textrm{Quadrature:} \, I_s (t) = - \Bigg [ \frac{\omega I_0 A \beta_n}{R \, \textrm{sin} \phi + \omega L \, \textrm{cos} \phi} \Bigg ] \textrm{sin} \phi \, \textrm{sin} (\omega t)
\end{equation}

```python

```


# CMD plots showing the effect of filtering on RUWE

Reproduce the figures on slides 41 to 46 of the [presentation](https://www.cosmos.esa.int/documents/29201/1770596/Lindegren_GaiaDR2_Astrometry_extended.pdf/1ebddb25-f010-6437-cb14-0e360e2d9f09) by L. Lindegren et al.

### The renormalized unit weight error

The unit weight error is given by:

\begin{equation}
    \text{UWE} = \left(\frac{\text{astrometric_chi2_al}}{\text{astrometric_n_good_obs_al}-5)}\right)^{1/2}\,.
\end{equation}

In the second and third query above the value of UWE is already calculated as part of the ADQL query. This value is then renormalized by dividing by the typical value for the UWE, $u_0$, as a function of colour and magnitude.

\begin{equation}
    \text{RUWE} = \frac{\text{UWE}}{u_0(G, G_\mathrm{BP}-G_\mathrm{RP})}\,.
\end{equation}

### Example query

The Gaia DR2 archive query for the input data to the plots below is:
```
select source_id, bp_rp, phot_g_mean_mag, parallax,
sqrt(astrometric_chi2_al/(astrometric_n_good_obs_al-5)) as u
from gaiadr2.gaia_source
where parallax>10
and parallax_over_error>10
and phot_bp_mean_flux_over_error>10
and phot_rp_mean_flux_over_error>10
```

__NOTE__ The value of the UWE is calculated as part of the query. You can download the `astrometric_chi2_al` and `astrometric_n_good_obs_al` columns and then do the calculation yourself.

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

from astropy.table import Table

from ruwetools import U0Interpolator
```

```python
alldata = Table.read('dr2data/LLRuweSelection.fits', format='fits')
print("Number of sources in input table: {0}".format(alldata['bp_rp'].size))

gabs = alldata['phot_g_mean_mag']+5*np.log10(alldata['parallax'])-10

rwi = U0Interpolator()
ruwe = alldata['u']/rwi.get_u0(alldata['phot_g_mean_mag'], alldata['bp_rp'])
```

    Number of sources in input table: 338833

## Raw HRD, no UWE or RUWE filtering

```python
figa, axa = plt.subplots(1, 1, figsize=(10,10))

axa.hexbin(alldata['bp_rp'], gabs, mincnt=1, bins='log', gridsize=500, cmap='cividis')
axa.set_xlabel(r'$G_\mathrm{BP}-G_\mathrm{RP}$')
axa.set_ylabel(r'$M_G$')
axa.set_xlim(-1,6)
axa.set_ylim(-4,22)
axa.invert_yaxis()

plt.show()
```

## UWE and RUWE histograms

```python
figb, axb = plt.subplots(1, 1, figsize=(10,8))

axb.hist(np.log10(alldata['u']), bins='auto', histtype='step', density=True, label='UWE')
axb.hist(np.log10(ruwe), bins='auto', histtype='step', density=True, label='RUWE')
axb.legend(loc='best')
axb.set_xticks(np.log10([0.5,1,2,5,10,20,50,100]), minor=False)
axb.set_xticklabels(['0.5','1','2','5','10','20','50','100'], minor=False)
axb.set_xlabel('$\log_{10}(\mathrm{Goodness\ of\ fit})$')
axb.set_ylabel('Density')
axb.set_xlim(np.log10(0.5),np.log10(100))

plt.show()
```

## HR diagrams with UWE/RUWE filtering

```python
figc, (axc, axd) = plt.subplots(1, 2, figsize=(16,9))

uwefilter = alldata['u']<1.96
ruwefilter = ruwe<1.40

axc.hexbin(alldata['bp_rp'][uwefilter], gabs[uwefilter], mincnt=1, bins='log', gridsize=500, cmap='cividis')
axc.set_xlabel(r'$G_\mathrm{BP}-G_\mathrm{RP}$')
axc.set_ylabel(r'$M_G$')
axc.set_xlim(-1,6)
axc.set_ylim(-4,22)
axc.invert_yaxis()
axc.set_title('UWE$<1.96$')

axd.hexbin(alldata['bp_rp'][ruwefilter], gabs[ruwefilter], mincnt=1, bins='log', gridsize=500, cmap='cividis')
axd.set_xlabel(r'$G_\mathrm{BP}-G_\mathrm{RP}$')
axd.set_ylabel(r'$M_G$')
axd.set_xlim(-1,6)
axd.set_ylim(-4,22)
axd.invert_yaxis()
axd.set_title('RUWE$<1.40$')

print('Number of source with UWE<1.96: {0}'.format(gabs[uwefilter].size))
print('Number of source with RUWE<1.40: {0}'.format(gabs[ruwefilter].size))

plt.show()
```

```python
figd, (axe, axf) = plt.subplots(1, 2, figsize=(16,9))

filterA = (alldata['u']<1.96) & (ruwe>=1.4)
filterB = (ruwe<1.40) & (alldata['u']>=1.96)

axe.hexbin(alldata['bp_rp'][filterA], gabs[filterA], mincnt=1, bins='log', gridsize=500, cmap='cividis')
axe.set_xlabel(r'$G_\mathrm{BP}-G_\mathrm{RP}$')
axe.set_ylabel(r'$M_G$')
axe.set_xlim(-1,6)
axe.set_ylim(-4,22)
axe.invert_yaxis()
axe.set_title('UWE$<1.96$ and RUWE$\geq1.40$')

axf.hexbin(alldata['bp_rp'][filterB], gabs[filterB], mincnt=1, bins='log', gridsize=500, cmap='cividis')
axf.set_xlabel(r'$G_\mathrm{BP}-G_\mathrm{RP}$')
axf.set_ylabel(r'$M_G$')
axf.set_xlim(-1,6)
axf.set_ylim(-4,22)
axf.invert_yaxis()
axf.set_title('RUWE$<1.40$ and RUWE$\geq1.96$')

print('Number of source with UWE<1.96, RUWE>=1.4: {0}'.format(gabs[filterA].size))
print('Number of source with RUWE<1.40, UWE>=1.96: {0}'.format(gabs[filterB].size))

plt.show()
```