This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Transference Plans and Uncertainty https://arxiv.org/abs/1808.05710

source('code/qmtrans.R')
Paket transport wurde unter R Version 3.5.1 erstellt

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

Phase space grid psgrid

Let \(M\) be a positive integer, then psgrid(M) creates a (S4) instance of a 2-dimensional \((x,k)\) grid with \(N\times N\) points \((x_i,k_i)\), where \(i=1,\ldots,N=2M+1\). Note that we set \(p=\hbar k\), then \(k\) has a dimension of inverse length (wavenumber).

N ................ Number of points (=2*M+1) 
L ................ Length, L=N*dx
dx ............... x-spacing
dk ............... k-spacing
x ................ x-points x[1],...,x[N] (x[M]=0)
k ................ k-points k[1],...,k[N] (k[M]=0)
deMoivreNumber ... exp(2*pi*i/N)
ucdftMatrix ...... Unitary centered discrete Fourier transform (matrix)
dftv ............. dftv(v) -> ucdft of vector v
dftf ............. dftf(f) -> ucdft of vector f
idftv ............ idftv(v) -> inverse ucdft of vector v
idftf ............ idftf(f) -> inverse ucdft of function f
eval ............. eval(f) -> evaluate function f at x[1..N]
evplot ........... evplot(f) -> eval(f) and plot the resulting vector
plotv ............ plotv(v) -> plot vector v
show ............. show() -> display/plot the grid

Example M=10

g=psgrid(10)
g@show()

crlf="\n"
cat("Grid parameters",crlf,
  "Number of points ...... :",g@N,crlf,
  "Length L .............. :",g@L,crlf,
  "x-spacing dx .......... :",g@dx,crlf,
  "k-spacing dx .......... :",g@dk,crlf,
  "DeMoivre number ....... :",g@deMoivreNumber,crlf)
Grid parameters 
 Number of points ...... : 21 
 Length L .............. : 11.48681 
 x-spacing dx .......... : 0.5469911 
 k-spacing dx .......... : 0.5469911 
 DeMoivre number ....... : 0.9555728+0.2947552i 
g@evplot(sin)
 [1]  0.7265407  0.9779200  0.9439293  0.6344875  0.1398938
 [6] -0.3955228 -0.8155206 -0.9975386 -0.8884616 -0.5201197
[11]  0.0000000  0.5201197  0.8884616  0.9975386  0.8155206
[16]  0.3955228 -0.1398938 -0.6344875 -0.9439293 -0.9779200
[21] -0.7265407

Schroedinger equation: schroed1d

The one dimensional Schroedinger equation \[\begin{equation} - \frac{\hbar^2}{2m} \frac{d^2\,\psi(x)}{dx^2}+V(x)\,\psi(x)=E\psi(x) \end{equation}\]

is solved on a psgrid using the matrix representation of \(H(x,\hbar k)\): \[ H_{i j} = V_i \delta_{i j} + \frac{h^2}{8 \pi mN} \left\{ \begin{array}{l} \frac{N^2 - 1}{6}, i = j\\ (- 1)^{(i - j)} \frac{\cos \left( \frac{\pi (i - j)}{N} \right) }{\sin \left( \frac{\pi (i - j)}{N} \right)^2}, i \neq j \end{array} \right. . \]

An instance of schroed1d(M,V,h=2*sqrt(2)*pi,m=1) will contain the following parameters and methods:

V ................ The potential V as function or vector
h ................ Planck constant, default: h=2*sqrt(2)*pi
m ................ Particle mass m, default: m=1
H ................ The Hamilton matrix H
ev ............... List of eigenvalues such that H v = ev[i] v 
EV ............... Eigenvectors as columns of matrix EV
plotEigVec ....... Plot eigenvector j (lowest for j=N).
contains psgrid .. inherits psgrid(M)

Example 1: Harmonic Oscillator

The potential function \(V(x)=x^2\) together with units and parameters \(m=1\), such that \(\hbar^2=2m\) yields - as is well known and easy to establish - the eigenvalues \[\begin{equation} E_j = 2 j +1, j=0,1,2,\ldots \end{equation}\]

that is the odd positive integers with the Hermite functions as eigenfunctions:

\[\begin{equation} \psi_n(x) = \left (2^n n! \sqrt{\pi} \right )^{-\frac12} e^{-\frac{x^2}{2}} H_n(x) = (-1)^n \left (2^n n! \sqrt{\pi} \right)^{-\frac12} e^{\frac{x^2}{2}} \frac{\mathrm d^n}{\mathrm dx^n} e^{-x^2} \end{equation}\]
hosc=schroed1d(100,function(x){x^2})

The first 20 eigenvalues are (as expected):

rev(hosc@ev)[1:20]
 [1]  1  3  5  7  9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39

The last 10 (of the 201) are not so precise anymore:

hosc@ev[1:10]
 [1] 593.1937 555.2614 538.1407 520.5147 507.6309 495.1428 484.8351
 [8] 474.7540 465.9999 457.4684
par(mfrow=c(2,2))
hosc@plotEigVec(hosc@N)
hosc@plotEigVec(hosc@N-1)
hosc@plotEigVec(hosc@N-2)
hosc@plotEigVec(hosc@N-3)

Let us compare the plots above with the first four Hermite functions:

par(mfrow=c(2,2))
nop=hosc@evplot(function(x){pi^(-1/4)*exp(-x^2/2)})
nop=hosc@evplot(function(x){sqrt(2)*x*pi^(-1/4)*exp(-x^2/2)})
nop=hosc@evplot(function(x){(2*x^2-1)/sqrt(2)*pi^(-1/4)*exp(-x^2/2)})
nop=hosc@evplot(function(x){(2*x^3-3*x)/sqrt(3)*pi^(-1/4)*exp(-x^2/2)})

Note: we see that the Hermite functions above are not normalized. In order to compare them, we have to normalize the resulting eval vector:

psi0=function(x){pi^(-1/4)*exp(-x^2/2)}
v0=hosc@eval(psi0)
v0=v0/sqrt(sum(v0*v0))
phi0=hosc@EV[,hosc@N]
par(mfrow=c(1,2))
hosc@plotEigVec(hosc@N)
hosc@plotv(v0)

df=phi0-v0
sum(df*Conj(df))
[1] 4.617951e-28

Example 2: The finite potential well

V=function(x){as.integer(abs(x) < 4)*(-10)}
fpw=schroed1d(100,V)
par(mfrow=c(2,2))
vp=fpw@evplot(V)
fpw@plotEigVec(fpw@N)
fpw@plotEigVec(fpw@N-1)
fpw@plotEigVec(fpw@N-2)

The bound states, for instance, can be listed as follows:

fpw@ev[fpw@ev<0]
[1] -0.002880027 -1.759517076 -3.607999344 -5.267576102 -6.696707425
[6] -7.878349365 -8.803618573 -9.467406382 -9.866727384

That is we have \(9\) negative eigenvalues (out of the 201). The theoretical number of bound states is \[ N_b=\lceil \sqrt{\frac{ m l^2 V_0}{2 h^2}} \rceil \] thus we calculate

ceiling(sqrt(1*8^2*10)/pi)
[1] 9

as expected ;-)

Example 3: \(V(x)=cosh(x)*(cosh(x)-1)\)

V3=function(x){cosh(x)*(cosh(x)-1)}
ex3=schroed1d(50,V3)
par(mfrow=c(2,2))
vp=ex3@evplot(V3)
ex3@plotEigVec(ex3@N)
ex3@plotEigVec(ex3@N-1)
ex3@plotEigVec(ex3@N-2)

Kantorovich energy kantorovich

The Kantorovich energy of a state \(\phi\) is given by \[\begin{equation} E_K(\phi)=\inf_{\gamma\in\Gamma(\phi)} \int H d\gamma \end{equation}\]

In the discrete case the optimal \(\gamma\) is a sparse matrix with (at most) \(2N-1\) positive entries (out of \(N^2\)). The \(\gamma\)-plots show the level sets (support).

An instance of kantorovich(M,H,phi) will contain the following parameters and methods:

H ................. Hamilton function H(x,p)
phi ............... Wave function phi(x)
mu ................ Measure mu(x)
nu ................ Measure nu(k)
HM ................ Hamilton matrix H_ij=H(x_i,p_i)
ES ................ Schroedinger energy
EK ................ Kantorovich energy
prodMeasure ....... Product measure mu#nu
transfPlan ........ Transference plan (as comes from "transport")
gamma ............. Measure gamma(x,k) corresponding to transfPlan
display ........... Display results
contains .......... Inherit from psgrid

Example 1: \(H(x,k)=k^2+x^2\)

H1=function(x,k){x^2+k^2}
K1=kantorovich(50,H1,function(x){exp(-x^2/2)})
K1@display()

K1@ES
[1] 1
K1@EK
[1] 1

Example 2: \(H(x,k)=x^2*k^2\)

H2=function(x,k){x^2*k^2}
K2=kantorovich(50,H2,function(x){exp(-x^2/2)})
K2@display()

K2@ES
[1] 0.25
K2@EK
[1] 0.03301429

Example 3

K3=kantorovich(20,H2,function(x){1/(1+x^2)})
K3@display()

K3@ES
[1] 0.4222049
K3@EK
[1] 0.01640796
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJhbnNmZXJlbmNlIFBsYW5zIGFuZCBVbmNlcnRhaW50eQ0KaHR0cHM6Ly9hcnhpdi5vcmcvYWJzLzE4MDguMDU3MTANCg0KDQpgYGB7cn0NCnNvdXJjZSgnQzovVXNlcnMva2ZwL0Rlc2t0b3Avd29yay9SL3FtdHJhbnMuUicpDQpgYGANCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0KDQojIyMgUGhhc2Ugc3BhY2UgZ3JpZCBgcHNncmlkYA0KTGV0ICRNJCBiZSBhIHBvc2l0aXZlIGludGVnZXIsIHRoZW4gYHBzZ3JpZChNKWAgY3JlYXRlcyBhIChTNCkgaW5zdGFuY2Ugb2YgYSAyLWRpbWVuc2lvbmFsICQoeCxrKSQgZ3JpZCB3aXRoICROXHRpbWVzIE4kIHBvaW50cyAkKHhfaSxrX2kpJCwgd2hlcmUgJGk9MSxcbGRvdHMsTj0yTSsxJC4gTm90ZSB0aGF0IHdlIHNldCAkcD1caGJhciBrJCwgdGhlbiAkayQgaGFzIGEgZGltZW5zaW9uIG9mICppbnZlcnNlIGxlbmd0aCogKHdhdmVudW1iZXIpLiANCg0KYGBgDQpOIC4uLi4uLi4uLi4uLi4uLi4gTnVtYmVyIG9mIHBvaW50cyAoPTIqTSsxKSANCkwgLi4uLi4uLi4uLi4uLi4uLiBMZW5ndGgsIEw9TipkeA0KZHggLi4uLi4uLi4uLi4uLi4uIHgtc3BhY2luZw0KZGsgLi4uLi4uLi4uLi4uLi4uIGstc3BhY2luZw0KeCAuLi4uLi4uLi4uLi4uLi4uIHgtcG9pbnRzIHhbMV0sLi4uLHhbTl0gKHhbTV09MCkNCmsgLi4uLi4uLi4uLi4uLi4uLiBrLXBvaW50cyBrWzFdLC4uLixrW05dIChrW01dPTApDQpkZU1vaXZyZU51bWJlciAuLi4gZXhwKDIqcGkqaS9OKQ0KdWNkZnRNYXRyaXggLi4uLi4uIFVuaXRhcnkgY2VudGVyZWQgZGlzY3JldGUgRm91cmllciB0cmFuc2Zvcm0gKG1hdHJpeCkNCmRmdHYgLi4uLi4uLi4uLi4uLiBkZnR2KHYpIC0+IHVjZGZ0IG9mIHZlY3RvciB2DQpkZnRmIC4uLi4uLi4uLi4uLi4gZGZ0ZihmKSAtPiB1Y2RmdCBvZiB2ZWN0b3IgZg0KaWRmdHYgLi4uLi4uLi4uLi4uIGlkZnR2KHYpIC0+IGludmVyc2UgdWNkZnQgb2YgdmVjdG9yIHYNCmlkZnRmIC4uLi4uLi4uLi4uLiBpZGZ0ZihmKSAtPiBpbnZlcnNlIHVjZGZ0IG9mIGZ1bmN0aW9uIGYNCmV2YWwgLi4uLi4uLi4uLi4uLiBldmFsKGYpIC0+IGV2YWx1YXRlIGZ1bmN0aW9uIGYgYXQgeFsxLi5OXQ0KZXZwbG90IC4uLi4uLi4uLi4uIGV2cGxvdChmKSAtPiBldmFsKGYpIGFuZCBwbG90IHRoZSByZXN1bHRpbmcgdmVjdG9yDQpwbG90diAuLi4uLi4uLi4uLi4gcGxvdHYodikgLT4gcGxvdCB2ZWN0b3Igdg0Kc2hvdyAuLi4uLi4uLi4uLi4uIHNob3coKSAtPiBkaXNwbGF5L3Bsb3QgdGhlIGdyaWQNCmBgYA0KDQojIyMjIEV4YW1wbGUgTT0xMA0KDQpgYGB7cn0NCmc9cHNncmlkKDEwKQ0KZ0BzaG93KCkNCmBgYA0KDQpgYGB7cn0NCmNybGY9IlxuIg0KY2F0KCJHcmlkIHBhcmFtZXRlcnMiLGNybGYsDQogICJOdW1iZXIgb2YgcG9pbnRzIC4uLi4uLiA6IixnQE4sY3JsZiwNCiAgIkxlbmd0aCBMIC4uLi4uLi4uLi4uLi4uIDoiLGdATCxjcmxmLA0KICAieC1zcGFjaW5nIGR4IC4uLi4uLi4uLi4gOiIsZ0BkeCxjcmxmLA0KICAiay1zcGFjaW5nIGR4IC4uLi4uLi4uLi4gOiIsZ0BkayxjcmxmLA0KICAiRGVNb2l2cmUgbnVtYmVyIC4uLi4uLi4gOiIsZ0BkZU1vaXZyZU51bWJlcixjcmxmKQ0KYGBgDQoNCg0KYGBge3J9DQpnQGV2cGxvdChzaW4pDQpgYGANCg0KIyMjIFNjaHJvZWRpbmdlciBlcXVhdGlvbjogYHNjaHJvZWQxZGANClRoZSBvbmUgZGltZW5zaW9uYWwgU2Nocm9lZGluZ2VyIGVxdWF0aW9uIA0KXGJlZ2lue2VxdWF0aW9ufQ0KICAtIFxmcmFje1xoYmFyXjJ9ezJtfSBcZnJhY3tkXjJcLFxwc2koeCl9e2R4XjJ9K1YoeClcLFxwc2koeCk9RVxwc2koeCkgDQpcZW5ke2VxdWF0aW9ufQ0KaXMgc29sdmVkIG9uIGEgYHBzZ3JpZGAgdXNpbmcgdGhlIG1hdHJpeCByZXByZXNlbnRhdGlvbiBvZiANCiRIKHgsXGhiYXIgaykkOg0KXFsgSF97aSBqfSA9IFZfaSBcZGVsdGFfe2kgan0gKyBcZnJhY3toXjJ9ezggXHBpIG1OfSAgXGxlZnRceyBcYmVnaW57YXJyYXl9e2x9DQogICAgIFxmcmFje05eMiAtIDF9ezZ9LCBpID0galxcDQogICAgICgtIDEpXnsoaSAtIGopfSAgXGZyYWN7XGNvcyBcbGVmdCggXGZyYWN7XHBpIChpIC0gail9e059DQogICAgIFxyaWdodCkgfXtcc2luIFxsZWZ0KCBcZnJhY3tccGkgKGkgLSBqKX17Tn0gXHJpZ2h0KV4yfSwgaSBcbmVxIGoNClxlbmR7YXJyYXl9IFxyaWdodC4gLiBcXQ0KDQpBbiBpbnN0YW5jZSBvZiBgc2Nocm9lZDFkKE0sVixoPTIqc3FydCgyKSpwaSxtPTEpYCB3aWxsIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzIGFuZCBtZXRob2RzOg0KDQpgYGANClYgLi4uLi4uLi4uLi4uLi4uLiBUaGUgcG90ZW50aWFsIFYgYXMgZnVuY3Rpb24gb3IgdmVjdG9yDQpoIC4uLi4uLi4uLi4uLi4uLi4gUGxhbmNrIGNvbnN0YW50LCBkZWZhdWx0OiBoPTIqc3FydCgyKSpwaQ0KbSAuLi4uLi4uLi4uLi4uLi4uIFBhcnRpY2xlIG1hc3MgbSwgZGVmYXVsdDogbT0xDQpIIC4uLi4uLi4uLi4uLi4uLi4gVGhlIEhhbWlsdG9uIG1hdHJpeCBIDQpldiAuLi4uLi4uLi4uLi4uLi4gTGlzdCBvZiBlaWdlbnZhbHVlcyBzdWNoIHRoYXQgSCB2ID0gZXZbaV0gdiANCkVWIC4uLi4uLi4uLi4uLi4uLiBFaWdlbnZlY3RvcnMgYXMgY29sdW1ucyBvZiBtYXRyaXggRVYNCnBsb3RFaWdWZWMgLi4uLi4uLiBQbG90IGVpZ2VudmVjdG9yIGogKGxvd2VzdCBmb3Igaj1OKS4NCmNvbnRhaW5zIHBzZ3JpZCAuLiBpbmhlcml0cyBwc2dyaWQoTSkNCmBgYA0KDQojIyMjIEV4YW1wbGUgMTogSGFybW9uaWMgT3NjaWxsYXRvcg0KDQpUaGUgcG90ZW50aWFsIGZ1bmN0aW9uICRWKHgpPXheMiQgdG9nZXRoZXIgd2l0aCB1bml0cyBhbmQgcGFyYW1ldGVycyAkbT0xJCwgc3VjaCB0aGF0ICRcaGJhcl4yPTJtJCB5aWVsZHMgLSBhcyBpcyB3ZWxsIGtub3duIGFuZCBlYXN5IHRvIGVzdGFibGlzaCAtIHRoZSBlaWdlbnZhbHVlcw0KXGJlZ2lue2VxdWF0aW9ufQ0KICAgRV9qID0gMiBqICsxLCBqPTAsMSwyLFxsZG90cw0KXGVuZHtlcXVhdGlvbn0NCnRoYXQgaXMgdGhlIG9kZCBwb3NpdGl2ZSBpbnRlZ2VycyB3aXRoIHRoZSAqSGVybWl0ZSBmdW5jdGlvbnMqDQphcyBlaWdlbmZ1bmN0aW9uczoNCg0KXGJlZ2lue2VxdWF0aW9ufQ0KXHBzaV9uKHgpID0gXGxlZnQgKDJebiBuISBcc3FydHtccGl9IFxyaWdodCApXnstXGZyYWMxMn0gZV57LVxmcmFje3heMn17Mn19IEhfbih4KSA9ICgtMSlebiBcbGVmdCAoMl5uIG4hIFxzcXJ0e1xwaX0gXHJpZ2h0KV57LVxmcmFjMTJ9IGVee1xmcmFje3heMn17Mn19IFxmcmFje1xtYXRocm0gZF5ufXtcbWF0aHJtIGR4Xm59IGVeey14XjJ9DQpcZW5ke2VxdWF0aW9ufQ0KDQpgYGB7cn0NCmhvc2M9c2Nocm9lZDFkKDEwMCxmdW5jdGlvbih4KXt4XjJ9KQ0KYGBgDQoNClRoZSBmaXJzdCAyMCBlaWdlbnZhbHVlcyBhcmUgKGFzIGV4cGVjdGVkKToNCmBgYHtyfQ0KcmV2KGhvc2NAZXYpWzE6MjBdDQpgYGANCg0KVGhlIGxhc3QgMTAgKG9mIHRoZSAyMDEpIGFyZSBub3Qgc28gcHJlY2lzZSBhbnltb3JlOg0KYGBge3J9DQpob3NjQGV2WzE6MTBdDQpgYGANCg0KYGBge3J9DQpwYXIobWZyb3c9YygyLDIpKQ0KaG9zY0BwbG90RWlnVmVjKGhvc2NATikNCmhvc2NAcGxvdEVpZ1ZlYyhob3NjQE4tMSkNCmhvc2NAcGxvdEVpZ1ZlYyhob3NjQE4tMikNCmhvc2NAcGxvdEVpZ1ZlYyhob3NjQE4tMykNCmBgYA0KDQpMZXQgdXMgY29tcGFyZSB0aGUgcGxvdHMgYWJvdmUgd2l0aCB0aGUgZmlyc3QgZm91ciBIZXJtaXRlIGZ1bmN0aW9uczoNCg0KYGBge3J9DQpwYXIobWZyb3c9YygyLDIpKQ0Kbm9wPWhvc2NAZXZwbG90KGZ1bmN0aW9uKHgpe3BpXigtMS80KSpleHAoLXheMi8yKX0pDQpub3A9aG9zY0BldnBsb3QoZnVuY3Rpb24oeCl7c3FydCgyKSp4KnBpXigtMS80KSpleHAoLXheMi8yKX0pDQpub3A9aG9zY0BldnBsb3QoZnVuY3Rpb24oeCl7KDIqeF4yLTEpL3NxcnQoMikqcGleKC0xLzQpKmV4cCgteF4yLzIpfSkNCm5vcD1ob3NjQGV2cGxvdChmdW5jdGlvbih4KXsoMip4XjMtMyp4KS9zcXJ0KDMpKnBpXigtMS80KSpleHAoLXheMi8yKX0pDQpgYGANCg0KKipOb3RlKio6IHdlIHNlZSB0aGF0IHRoZSBIZXJtaXRlIGZ1bmN0aW9ucyBhYm92ZSBhcmUgbm90IG5vcm1hbGl6ZWQuDQpJbiBvcmRlciB0byBjb21wYXJlIHRoZW0sIHdlIGhhdmUgdG8gbm9ybWFsaXplIHRoZSByZXN1bHRpbmcgYGV2YWxgIHZlY3RvcjoNCg0KYGBge3J9DQpwc2kwPWZ1bmN0aW9uKHgpe3BpXigtMS80KSpleHAoLXheMi8yKX0NCnYwPWhvc2NAZXZhbChwc2kwKQ0KdjA9djAvc3FydChzdW0odjAqdjApKQ0KcGhpMD1ob3NjQEVWWyxob3NjQE5dDQpwYXIobWZyb3c9YygxLDIpKQ0KaG9zY0BwbG90RWlnVmVjKGhvc2NATikNCmhvc2NAcGxvdHYodjApDQpgYGANCmBgYHtyfQ0KZGY9cGhpMC12MA0Kc3VtKGRmKkNvbmooZGYpKQ0KYGBgDQoNCg0KIyMjIyBFeGFtcGxlIDI6IFRoZSBmaW5pdGUgcG90ZW50aWFsIHdlbGwgDQoNCmBgYHtyfQ0KVj1mdW5jdGlvbih4KXthcy5pbnRlZ2VyKGFicyh4KSA8IDQpKigtMTApfQ0KZnB3PXNjaHJvZWQxZCgxMDAsVikNCnBhcihtZnJvdz1jKDIsMikpDQp2cD1mcHdAZXZwbG90KFYpDQpmcHdAcGxvdEVpZ1ZlYyhmcHdATikNCmZwd0BwbG90RWlnVmVjKGZwd0BOLTEpDQpmcHdAcGxvdEVpZ1ZlYyhmcHdATi0yKQ0KYGBgDQpUaGUgYm91bmQgc3RhdGVzLCBmb3IgaW5zdGFuY2UsIGNhbiBiZSBsaXN0ZWQgYXMgZm9sbG93czoNCmBgYHtyfQ0KZnB3QGV2W2Zwd0BldjwwXQ0KYGBgDQpUaGF0IGlzIHdlIGhhdmUgJDkkIG5lZ2F0aXZlIGVpZ2VudmFsdWVzIChvdXQgb2YgdGhlIDIwMSkuIFRoZSB0aGVvcmV0aWNhbCBudW1iZXIgb2YgYm91bmQgc3RhdGVzIGlzDQpcWw0KICAgTl9iPVxsY2VpbCBcc3FydHtcZnJhY3sgbSBsXjIgVl8wfXsyIGheMn19IFxyY2VpbCANClxdDQp0aHVzIHdlIGNhbGN1bGF0ZSANCmBgYHtyfQ0KY2VpbGluZyhzcXJ0KDEqOF4yKjEwKS9waSkNCmBgYA0KDQphcyBleHBlY3RlZCA7LSkNCg0KIyMjIyBFeGFtcGxlIDM6ICRWKHgpPWNvc2goeCkqKGNvc2goeCktMSkkDQoNCmBgYHtyfQ0KVjM9ZnVuY3Rpb24oeCl7Y29zaCh4KSooY29zaCh4KS0xKX0NCmV4Mz1zY2hyb2VkMWQoNTAsVjMpDQpwYXIobWZyb3c9YygyLDIpKQ0KdnA9ZXgzQGV2cGxvdChWMykNCmV4M0BwbG90RWlnVmVjKGV4M0BOKQ0KZXgzQHBsb3RFaWdWZWMoZXgzQE4tMSkNCmV4M0BwbG90RWlnVmVjKGV4M0BOLTIpDQpgYGANCg0KIyMjIEthbnRvcm92aWNoIGVuZXJneSBga2FudG9yb3ZpY2hgDQoNClRoZSBLYW50b3JvdmljaCBlbmVyZ3kgb2YgYSBzdGF0ZSAkXHBoaSQgaXMgZ2l2ZW4gYnkNClxiZWdpbntlcXVhdGlvbn0NCiAgICAgRV9LKFxwaGkpPVxpbmZfe1xnYW1tYVxpblxHYW1tYShccGhpKX0gXGludCBIIGRcZ2FtbWENClxlbmR7ZXF1YXRpb259DQpJbiB0aGUgZGlzY3JldGUgY2FzZSB0aGUgb3B0aW1hbCAkXGdhbW1hJCBpcyBhIHNwYXJzZSBtYXRyaXgNCndpdGggKGF0IG1vc3QpICQyTi0xJCBwb3NpdGl2ZSBlbnRyaWVzIChvdXQgb2YgJE5eMiQpLiBUaGUNCiRcZ2FtbWEkLXBsb3RzIHNob3cgdGhlIGxldmVsIHNldHMgIChzdXBwb3J0KS4NCg0KQW4gaW5zdGFuY2Ugb2YgYGthbnRvcm92aWNoKE0sSCxwaGkpYCB3aWxsIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzIGFuZCBtZXRob2RzOg0KDQoNCmBgYA0KSCAuLi4uLi4uLi4uLi4uLi4uLiBIYW1pbHRvbiBmdW5jdGlvbiBIKHgscCkNCnBoaSAuLi4uLi4uLi4uLi4uLi4gV2F2ZSBmdW5jdGlvbiBwaGkoeCkNCm11IC4uLi4uLi4uLi4uLi4uLi4gTWVhc3VyZSBtdSh4KQ0KbnUgLi4uLi4uLi4uLi4uLi4uLiBNZWFzdXJlIG51KGspDQpITSAuLi4uLi4uLi4uLi4uLi4uIEhhbWlsdG9uIG1hdHJpeCBIX2lqPUgoeF9pLHBfaSkNCkVTIC4uLi4uLi4uLi4uLi4uLi4gU2Nocm9lZGluZ2VyIGVuZXJneQ0KRUsgLi4uLi4uLi4uLi4uLi4uLiBLYW50b3JvdmljaCBlbmVyZ3kNCnByb2RNZWFzdXJlIC4uLi4uLi4gUHJvZHVjdCBtZWFzdXJlIG11I251DQp0cmFuc2ZQbGFuIC4uLi4uLi4uIFRyYW5zZmVyZW5jZSBwbGFuIChhcyBjb21lcyBmcm9tICJ0cmFuc3BvcnQiKQ0KZ2FtbWEgLi4uLi4uLi4uLi4uLiBNZWFzdXJlIGdhbW1hKHgsaykgY29ycmVzcG9uZGluZyB0byB0cmFuc2ZQbGFuDQpkaXNwbGF5IC4uLi4uLi4uLi4uIERpc3BsYXkgcmVzdWx0cw0KY29udGFpbnMgLi4uLi4uLi4uLiBJbmhlcml0IGZyb20gcHNncmlkDQpgYGANCg0KIyMjIyBFeGFtcGxlIDE6ICRIKHgsayk9a14yK3heMiQNCg0KYGBge3J9DQpIMT1mdW5jdGlvbih4LGspe3heMitrXjJ9DQpLMT1rYW50b3JvdmljaCg1MCxIMSxmdW5jdGlvbih4KXtleHAoLXheMi8yKX0pDQpgYGANCg0KDQpgYGB7cn0NCksxQGRpc3BsYXkoKQ0KYGBgDQpgYGB7cn0NCksxQEVTDQpLMUBFSw0KYGBgDQoNCiMjIyMgRXhhbXBsZSAyOiAkSCh4LGspPXheMiprXjIkDQoNCmBgYHtyfQ0KSDI9ZnVuY3Rpb24oeCxrKXt4XjIqa14yfQ0KSzI9a2FudG9yb3ZpY2goNTAsSDIsZnVuY3Rpb24oeCl7ZXhwKC14XjIvMil9KQ0KYGBgDQoNCmBgYHtyfQ0KSzJAZGlzcGxheSgpDQpgYGANCmBgYHtyfQ0KSzJARVMNCksyQEVLDQpgYGANCg0KDQoNCiMjIyMgRXhhbXBsZSAzDQoNCmBgYHtyfQ0KSzM9a2FudG9yb3ZpY2goMjAsSDIsZnVuY3Rpb24oeCl7MS8oMSt4XjIpfSkNCkszQGRpc3BsYXkoKQ0KYGBgDQpgYGB7cn0NCkszQEVTDQpLM0BFSw0KYGBgDQo=