{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Collecting experiments data in a data frame\n",
"\n",
"### Bogumił Kamiński"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"using DataFrames"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"using Statistics"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"using PyPlot"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"using Random"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"using Pipe"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this part we will run a simple Monte Carlo simulation so show examples how one can work with data frames."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Consider the following puzzle.\n",
"\n",
"We draw independent random numbers from $U(0,1)$ distribution. On the average, how many draws do we need, till the sum of these numbers exceeds $1$?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here is the code that runs this experiment once. For tutorial reasons we keep all the generated random numbers and recalculate their sum in each iteration (you can try to improve the efficiency of this code as an exercise)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"sim_e (generic function with 1 method)"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"function sim_e()\n",
" draw = Float64[]\n",
" while true\n",
" push!(draw, rand())\n",
" sum(draw) > 1.0 && return draw\n",
" end\n",
"end"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"Random.seed!(1234); # just to make sure we get the same results if we are on the same version of Julia"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us run our simulation several times:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5-element Array{Array{Float64,1},1}:\n",
" [0.5908446386657102, 0.7667970365022592]\n",
" [0.5662374165061859, 0.4600853424625171]\n",
" [0.7940257103317943, 0.8541465903790502]\n",
" [0.20058603493384108, 0.2986142783434118, 0.24683718661000897, 0.5796722333690416]\n",
" [0.6488819502093455, 0.010905889635595356, 0.06642303695533736, 0.9567533636029237]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"res = [sim_e() for _ in 1:5]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and check that each time we finished just when we exceeded $1$:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5-element Array{Float64,1}:\n",
" 1.3576416751679694\n",
" 1.026322758968703\n",
" 1.6481723007108444\n",
" 1.3257097332563035\n",
" 1.682964240403202"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sum.(res)"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5-element Array{Float64,1}:\n",
" 0.5908446386657102\n",
" 0.5662374165061859\n",
" 0.7940257103317943\n",
" 0.7460374998872619\n",
" 0.7262108768002782"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"@. sum(res) - last(res)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All looks good so far! (and as a bonus we have just made a small exercise in broadcasting)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let us populate a data frame with the results of our experiments"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 9.025314 seconds (101.54 M allocations: 3.616 GiB, 27.70% gc time)\n"
]
}
],
"source": [
"df = DataFrame()\n",
"\n",
"@time for i in 1:10^7\n",
" push!(df, (id=i, pos=sim_e()))\n",
"end"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see the process was quite fast, `push!`-ing data to a `DataFrame` is efficient."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
| id | pos |
---|
| Int64 | Array… |
---|
10,000,000 rows × 2 columns
1 | 1 | [0.646691, 0.112486, 0.276021] |
---|
2 | 2 | [0.651664, 0.0566425, 0.842714] |
---|
3 | 3 | [0.950498, 0.96467] |
---|
4 | 4 | [0.945775, 0.789904] |
---|
5 | 5 | [0.82116, 0.0341601, 0.0945445, 0.314926] |
---|
6 | 6 | [0.12781, 0.374187, 0.931115] |
---|
7 | 7 | [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] |
---|
8 | 8 | [0.732, 0.299058] |
---|
9 | 9 | [0.449182, 0.875096] |
---|
10 | 10 | [0.0462887, 0.698356, 0.365109] |
---|
11 | 11 | [0.302478, 0.372575, 0.150508, 0.147329, 0.283401] |
---|
12 | 12 | [0.404953, 0.499531, 0.658815] |
---|
13 | 13 | [0.515627, 0.260715, 0.59552] |
---|
14 | 14 | [0.292462, 0.28858, 0.61816] |
---|
15 | 15 | [0.66426, 0.753508] |
---|
16 | 16 | [0.0368842, 0.643704, 0.401421] |
---|
17 | 17 | [0.525057, 0.61201] |
---|
18 | 18 | [0.432577, 0.082207, 0.199058, 0.576082] |
---|
19 | 19 | [0.218177, 0.362036, 0.204728, 0.932984] |
---|
20 | 20 | [0.827263, 0.0992992, 0.6343] |
---|
21 | 21 | [0.132715, 0.775194, 0.869237] |
---|
22 | 22 | [0.0396356, 0.79041, 0.431188] |
---|
23 | 23 | [0.137658, 0.60808, 0.255054] |
---|
24 | 24 | [0.498734, 0.0940369, 0.52509] |
---|
25 | 25 | [0.265511, 0.110096, 0.834362] |
---|
26 | 26 | [0.633427, 0.337865, 0.112987] |
---|
27 | 27 | [0.78299, 0.838042] |
---|
28 | 28 | [0.0878598, 0.386568, 0.330579, 0.748041] |
---|
29 | 29 | [0.265595, 0.291069, 0.612628] |
---|
30 | 30 | [0.705766, 0.508363] |
---|
⋮ | ⋮ | ⋮ |
---|
"
],
"text/latex": [
"\\begin{tabular}{r|cc}\n",
"\t& id & pos\\\\\n",
"\t\\hline\n",
"\t& Int64 & Array…\\\\\n",
"\t\\hline\n",
"\t1 & 1 & [0.646691, 0.112486, 0.276021] \\\\\n",
"\t2 & 2 & [0.651664, 0.0566425, 0.842714] \\\\\n",
"\t3 & 3 & [0.950498, 0.96467] \\\\\n",
"\t4 & 4 & [0.945775, 0.789904] \\\\\n",
"\t5 & 5 & [0.82116, 0.0341601, 0.0945445, 0.314926] \\\\\n",
"\t6 & 6 & [0.12781, 0.374187, 0.931115] \\\\\n",
"\t7 & 7 & [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] \\\\\n",
"\t8 & 8 & [0.732, 0.299058] \\\\\n",
"\t9 & 9 & [0.449182, 0.875096] \\\\\n",
"\t10 & 10 & [0.0462887, 0.698356, 0.365109] \\\\\n",
"\t11 & 11 & [0.302478, 0.372575, 0.150508, 0.147329, 0.283401] \\\\\n",
"\t12 & 12 & [0.404953, 0.499531, 0.658815] \\\\\n",
"\t13 & 13 & [0.515627, 0.260715, 0.59552] \\\\\n",
"\t14 & 14 & [0.292462, 0.28858, 0.61816] \\\\\n",
"\t15 & 15 & [0.66426, 0.753508] \\\\\n",
"\t16 & 16 & [0.0368842, 0.643704, 0.401421] \\\\\n",
"\t17 & 17 & [0.525057, 0.61201] \\\\\n",
"\t18 & 18 & [0.432577, 0.082207, 0.199058, 0.576082] \\\\\n",
"\t19 & 19 & [0.218177, 0.362036, 0.204728, 0.932984] \\\\\n",
"\t20 & 20 & [0.827263, 0.0992992, 0.6343] \\\\\n",
"\t21 & 21 & [0.132715, 0.775194, 0.869237] \\\\\n",
"\t22 & 22 & [0.0396356, 0.79041, 0.431188] \\\\\n",
"\t23 & 23 & [0.137658, 0.60808, 0.255054] \\\\\n",
"\t24 & 24 & [0.498734, 0.0940369, 0.52509] \\\\\n",
"\t25 & 25 & [0.265511, 0.110096, 0.834362] \\\\\n",
"\t26 & 26 & [0.633427, 0.337865, 0.112987] \\\\\n",
"\t27 & 27 & [0.78299, 0.838042] \\\\\n",
"\t28 & 28 & [0.0878598, 0.386568, 0.330579, 0.748041] \\\\\n",
"\t29 & 29 & [0.265595, 0.291069, 0.612628] \\\\\n",
"\t30 & 30 & [0.705766, 0.508363] \\\\\n",
"\t$\\dots$ & $\\dots$ & $\\dots$ \\\\\n",
"\\end{tabular}\n"
],
"text/plain": [
"10000000×2 DataFrame\n",
"│ Row │ id │ pos │\n",
"│ │ \u001b[90mInt64\u001b[39m │ \u001b[90mArray{Float64,1}\u001b[39m │\n",
"├──────────┼──────────┼──────────────────────────────────────────────────────┤\n",
"│ 1 │ 1 │ [0.646691, 0.112486, 0.276021] │\n",
"│ 2 │ 2 │ [0.651664, 0.0566425, 0.842714] │\n",
"│ 3 │ 3 │ [0.950498, 0.96467] │\n",
"│ 4 │ 4 │ [0.945775, 0.789904] │\n",
"│ 5 │ 5 │ [0.82116, 0.0341601, 0.0945445, 0.314926] │\n",
"│ 6 │ 6 │ [0.12781, 0.374187, 0.931115] │\n",
"│ 7 │ 7 │ [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] │\n",
"│ 8 │ 8 │ [0.732, 0.299058] │\n",
"│ 9 │ 9 │ [0.449182, 0.875096] │\n",
"│ 10 │ 10 │ [0.0462887, 0.698356, 0.365109] │\n",
"⋮\n",
"│ 9999990 │ 9999990 │ [0.209058, 0.338017, 0.567608] │\n",
"│ 9999991 │ 9999991 │ [0.700468, 0.220524, 0.347931] │\n",
"│ 9999992 │ 9999992 │ [0.231368, 0.862016] │\n",
"│ 9999993 │ 9999993 │ [0.869351, 0.444795] │\n",
"│ 9999994 │ 9999994 │ [0.821356, 0.509054] │\n",
"│ 9999995 │ 9999995 │ [0.589245, 0.669708] │\n",
"│ 9999996 │ 9999996 │ [0.806262, 0.734397] │\n",
"│ 9999997 │ 9999997 │ [0.216506, 0.430571, 0.283787, 0.335015] │\n",
"│ 9999998 │ 9999998 │ [0.0100723, 0.836315, 0.942299] │\n",
"│ 9999999 │ 9999999 │ [0.499669, 0.25214, 0.964065] │\n",
"│ 10000000 │ 10000000 │ [0.663339, 0.887989] │"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us count the number of jumps we have made in each step using the `transform!` function:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
" | id | pos | jumps |
---|
| Int64 | Array… | Int64 |
---|
10,000,000 rows × 3 columns
1 | 1 | [0.646691, 0.112486, 0.276021] | 3 |
---|
2 | 2 | [0.651664, 0.0566425, 0.842714] | 3 |
---|
3 | 3 | [0.950498, 0.96467] | 2 |
---|
4 | 4 | [0.945775, 0.789904] | 2 |
---|
5 | 5 | [0.82116, 0.0341601, 0.0945445, 0.314926] | 4 |
---|
6 | 6 | [0.12781, 0.374187, 0.931115] | 3 |
---|
7 | 7 | [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] | 5 |
---|
8 | 8 | [0.732, 0.299058] | 2 |
---|
9 | 9 | [0.449182, 0.875096] | 2 |
---|
10 | 10 | [0.0462887, 0.698356, 0.365109] | 3 |
---|
11 | 11 | [0.302478, 0.372575, 0.150508, 0.147329, 0.283401] | 5 |
---|
12 | 12 | [0.404953, 0.499531, 0.658815] | 3 |
---|
13 | 13 | [0.515627, 0.260715, 0.59552] | 3 |
---|
14 | 14 | [0.292462, 0.28858, 0.61816] | 3 |
---|
15 | 15 | [0.66426, 0.753508] | 2 |
---|
16 | 16 | [0.0368842, 0.643704, 0.401421] | 3 |
---|
17 | 17 | [0.525057, 0.61201] | 2 |
---|
18 | 18 | [0.432577, 0.082207, 0.199058, 0.576082] | 4 |
---|
19 | 19 | [0.218177, 0.362036, 0.204728, 0.932984] | 4 |
---|
20 | 20 | [0.827263, 0.0992992, 0.6343] | 3 |
---|
21 | 21 | [0.132715, 0.775194, 0.869237] | 3 |
---|
22 | 22 | [0.0396356, 0.79041, 0.431188] | 3 |
---|
23 | 23 | [0.137658, 0.60808, 0.255054] | 3 |
---|
24 | 24 | [0.498734, 0.0940369, 0.52509] | 3 |
---|
25 | 25 | [0.265511, 0.110096, 0.834362] | 3 |
---|
26 | 26 | [0.633427, 0.337865, 0.112987] | 3 |
---|
27 | 27 | [0.78299, 0.838042] | 2 |
---|
28 | 28 | [0.0878598, 0.386568, 0.330579, 0.748041] | 4 |
---|
29 | 29 | [0.265595, 0.291069, 0.612628] | 3 |
---|
30 | 30 | [0.705766, 0.508363] | 2 |
---|
⋮ | ⋮ | ⋮ | ⋮ |
---|
"
],
"text/latex": [
"\\begin{tabular}{r|ccc}\n",
"\t& id & pos & jumps\\\\\n",
"\t\\hline\n",
"\t& Int64 & Array… & Int64\\\\\n",
"\t\\hline\n",
"\t1 & 1 & [0.646691, 0.112486, 0.276021] & 3 \\\\\n",
"\t2 & 2 & [0.651664, 0.0566425, 0.842714] & 3 \\\\\n",
"\t3 & 3 & [0.950498, 0.96467] & 2 \\\\\n",
"\t4 & 4 & [0.945775, 0.789904] & 2 \\\\\n",
"\t5 & 5 & [0.82116, 0.0341601, 0.0945445, 0.314926] & 4 \\\\\n",
"\t6 & 6 & [0.12781, 0.374187, 0.931115] & 3 \\\\\n",
"\t7 & 7 & [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] & 5 \\\\\n",
"\t8 & 8 & [0.732, 0.299058] & 2 \\\\\n",
"\t9 & 9 & [0.449182, 0.875096] & 2 \\\\\n",
"\t10 & 10 & [0.0462887, 0.698356, 0.365109] & 3 \\\\\n",
"\t11 & 11 & [0.302478, 0.372575, 0.150508, 0.147329, 0.283401] & 5 \\\\\n",
"\t12 & 12 & [0.404953, 0.499531, 0.658815] & 3 \\\\\n",
"\t13 & 13 & [0.515627, 0.260715, 0.59552] & 3 \\\\\n",
"\t14 & 14 & [0.292462, 0.28858, 0.61816] & 3 \\\\\n",
"\t15 & 15 & [0.66426, 0.753508] & 2 \\\\\n",
"\t16 & 16 & [0.0368842, 0.643704, 0.401421] & 3 \\\\\n",
"\t17 & 17 & [0.525057, 0.61201] & 2 \\\\\n",
"\t18 & 18 & [0.432577, 0.082207, 0.199058, 0.576082] & 4 \\\\\n",
"\t19 & 19 & [0.218177, 0.362036, 0.204728, 0.932984] & 4 \\\\\n",
"\t20 & 20 & [0.827263, 0.0992992, 0.6343] & 3 \\\\\n",
"\t21 & 21 & [0.132715, 0.775194, 0.869237] & 3 \\\\\n",
"\t22 & 22 & [0.0396356, 0.79041, 0.431188] & 3 \\\\\n",
"\t23 & 23 & [0.137658, 0.60808, 0.255054] & 3 \\\\\n",
"\t24 & 24 & [0.498734, 0.0940369, 0.52509] & 3 \\\\\n",
"\t25 & 25 & [0.265511, 0.110096, 0.834362] & 3 \\\\\n",
"\t26 & 26 & [0.633427, 0.337865, 0.112987] & 3 \\\\\n",
"\t27 & 27 & [0.78299, 0.838042] & 2 \\\\\n",
"\t28 & 28 & [0.0878598, 0.386568, 0.330579, 0.748041] & 4 \\\\\n",
"\t29 & 29 & [0.265595, 0.291069, 0.612628] & 3 \\\\\n",
"\t30 & 30 & [0.705766, 0.508363] & 2 \\\\\n",
"\t$\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ \\\\\n",
"\\end{tabular}\n"
],
"text/plain": [
"10000000×3 DataFrame. Omitted printing of 1 columns\n",
"│ Row │ id │ pos │\n",
"│ │ \u001b[90mInt64\u001b[39m │ \u001b[90mArray{Float64,1}\u001b[39m │\n",
"├──────────┼──────────┼──────────────────────────────────────────────────────┤\n",
"│ 1 │ 1 │ [0.646691, 0.112486, 0.276021] │\n",
"│ 2 │ 2 │ [0.651664, 0.0566425, 0.842714] │\n",
"│ 3 │ 3 │ [0.950498, 0.96467] │\n",
"│ 4 │ 4 │ [0.945775, 0.789904] │\n",
"│ 5 │ 5 │ [0.82116, 0.0341601, 0.0945445, 0.314926] │\n",
"│ 6 │ 6 │ [0.12781, 0.374187, 0.931115] │\n",
"│ 7 │ 7 │ [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] │\n",
"│ 8 │ 8 │ [0.732, 0.299058] │\n",
"│ 9 │ 9 │ [0.449182, 0.875096] │\n",
"│ 10 │ 10 │ [0.0462887, 0.698356, 0.365109] │\n",
"⋮\n",
"│ 9999990 │ 9999990 │ [0.209058, 0.338017, 0.567608] │\n",
"│ 9999991 │ 9999991 │ [0.700468, 0.220524, 0.347931] │\n",
"│ 9999992 │ 9999992 │ [0.231368, 0.862016] │\n",
"│ 9999993 │ 9999993 │ [0.869351, 0.444795] │\n",
"│ 9999994 │ 9999994 │ [0.821356, 0.509054] │\n",
"│ 9999995 │ 9999995 │ [0.589245, 0.669708] │\n",
"│ 9999996 │ 9999996 │ [0.806262, 0.734397] │\n",
"│ 9999997 │ 9999997 │ [0.216506, 0.430571, 0.283787, 0.335015] │\n",
"│ 9999998 │ 9999998 │ [0.0100723, 0.836315, 0.942299] │\n",
"│ 9999999 │ 9999999 │ [0.499669, 0.25214, 0.964065] │\n",
"│ 10000000 │ 10000000 │ [0.663339, 0.887989] │"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"transform!(df, :pos => ByRow(length) => :jumps)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us dissect what we have written above:\n",
"* `transform!` adds columns to a data frame in-place\n",
"* `:pos` is a source column\n",
"* `ByRow(length)` tells us that we want to apply `length` function to each element for `:pos` column (without it `length` would be applied to the whole column - can you guess what would be the result?)\n",
"* `:jumps` is the name of the column that should be created"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we are ready to find the average number of jumps that are made:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2.7185991"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mean(df.jumps)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"or"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
" | jumps_mean |
---|
| Float64 |
---|
1 rows × 1 columns
1 | 2.7186 |
---|
"
],
"text/latex": [
"\\begin{tabular}{r|c}\n",
"\t& jumps\\_mean\\\\\n",
"\t\\hline\n",
"\t& Float64\\\\\n",
"\t\\hline\n",
"\t1 & 2.7186 \\\\\n",
"\\end{tabular}\n"
],
"text/plain": [
"1×1 DataFrame\n",
"│ Row │ jumps_mean │\n",
"│ │ \u001b[90mFloat64\u001b[39m │\n",
"├─────┼────────────┤\n",
"│ 1 │ 2.7186 │"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"combine(df, :jumps => mean)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"which happens to be very close to:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"ℯ = 2.7182818284590..."
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"MathConstants.e"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us now find a distribution of number of jumps:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
" | jumps | jumps_length |
---|
| Int64 | Int64 |
---|
10 rows × 2 columns
1 | 2 | 4999743 |
---|
2 | 3 | 3332539 |
---|
3 | 4 | 1250009 |
---|
4 | 5 | 333738 |
---|
5 | 6 | 69865 |
---|
6 | 7 | 12145 |
---|
7 | 8 | 1725 |
---|
8 | 9 | 204 |
---|
9 | 10 | 31 |
---|
10 | 11 | 1 |
---|
"
],
"text/latex": [
"\\begin{tabular}{r|cc}\n",
"\t& jumps & jumps\\_length\\\\\n",
"\t\\hline\n",
"\t& Int64 & Int64\\\\\n",
"\t\\hline\n",
"\t1 & 2 & 4999743 \\\\\n",
"\t2 & 3 & 3332539 \\\\\n",
"\t3 & 4 & 1250009 \\\\\n",
"\t4 & 5 & 333738 \\\\\n",
"\t5 & 6 & 69865 \\\\\n",
"\t6 & 7 & 12145 \\\\\n",
"\t7 & 8 & 1725 \\\\\n",
"\t8 & 9 & 204 \\\\\n",
"\t9 & 10 & 31 \\\\\n",
"\t10 & 11 & 1 \\\\\n",
"\\end{tabular}\n"
],
"text/plain": [
"10×2 DataFrame\n",
"│ Row │ jumps │ jumps_length │\n",
"│ │ \u001b[90mInt64\u001b[39m │ \u001b[90mInt64\u001b[39m │\n",
"├─────┼───────┼──────────────┤\n",
"│ 1 │ 2 │ 4999743 │\n",
"│ 2 │ 3 │ 3332539 │\n",
"│ 3 │ 4 │ 1250009 │\n",
"│ 4 │ 5 │ 333738 │\n",
"│ 5 │ 6 │ 69865 │\n",
"│ 6 │ 7 │ 12145 │\n",
"│ 7 │ 8 │ 1725 │\n",
"│ 8 │ 9 │ 204 │\n",
"│ 9 │ 10 │ 31 │\n",
"│ 10 │ 11 │ 1 │"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"jumps_agg = @pipe df |>\n",
" groupby(_, :jumps, sort=true) |>\n",
" combine(_, :jumps => length)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and normalize it as a fraction (and at the same time calculate some theoretical result that we have *guessed* :)):"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
" | jumps | jumps_length | simulation | theory |
---|
| Int64 | Int64 | Float64 | Float64 |
---|
10 rows × 4 columns
1 | 2 | 4999743 | 0.499974 | 0.5 |
---|
2 | 3 | 3332539 | 0.333254 | 0.333333 |
---|
3 | 4 | 1250009 | 0.125001 | 0.125 |
---|
4 | 5 | 333738 | 0.0333738 | 0.0333333 |
---|
5 | 6 | 69865 | 0.0069865 | 0.00694444 |
---|
6 | 7 | 12145 | 0.0012145 | 0.00119048 |
---|
7 | 8 | 1725 | 0.0001725 | 0.000173611 |
---|
8 | 9 | 204 | 2.04e-5 | 2.20459e-5 |
---|
9 | 10 | 31 | 3.1e-6 | 2.48016e-6 |
---|
10 | 11 | 1 | 1.0e-7 | 2.50521e-7 |
---|
"
],
"text/latex": [
"\\begin{tabular}{r|cccc}\n",
"\t& jumps & jumps\\_length & simulation & theory\\\\\n",
"\t\\hline\n",
"\t& Int64 & Int64 & Float64 & Float64\\\\\n",
"\t\\hline\n",
"\t1 & 2 & 4999743 & 0.499974 & 0.5 \\\\\n",
"\t2 & 3 & 3332539 & 0.333254 & 0.333333 \\\\\n",
"\t3 & 4 & 1250009 & 0.125001 & 0.125 \\\\\n",
"\t4 & 5 & 333738 & 0.0333738 & 0.0333333 \\\\\n",
"\t5 & 6 & 69865 & 0.0069865 & 0.00694444 \\\\\n",
"\t6 & 7 & 12145 & 0.0012145 & 0.00119048 \\\\\n",
"\t7 & 8 & 1725 & 0.0001725 & 0.000173611 \\\\\n",
"\t8 & 9 & 204 & 2.04e-5 & 2.20459e-5 \\\\\n",
"\t9 & 10 & 31 & 3.1e-6 & 2.48016e-6 \\\\\n",
"\t10 & 11 & 1 & 1.0e-7 & 2.50521e-7 \\\\\n",
"\\end{tabular}\n"
],
"text/plain": [
"10×4 DataFrame\n",
"│ Row │ jumps │ jumps_length │ simulation │ theory │\n",
"│ │ \u001b[90mInt64\u001b[39m │ \u001b[90mInt64\u001b[39m │ \u001b[90mFloat64\u001b[39m │ \u001b[90mFloat64\u001b[39m │\n",
"├─────┼───────┼──────────────┼────────────┼─────────────┤\n",
"│ 1 │ 2 │ 4999743 │ 0.499974 │ 0.5 │\n",
"│ 2 │ 3 │ 3332539 │ 0.333254 │ 0.333333 │\n",
"│ 3 │ 4 │ 1250009 │ 0.125001 │ 0.125 │\n",
"│ 4 │ 5 │ 333738 │ 0.0333738 │ 0.0333333 │\n",
"│ 5 │ 6 │ 69865 │ 0.0069865 │ 0.00694444 │\n",
"│ 6 │ 7 │ 12145 │ 0.0012145 │ 0.00119048 │\n",
"│ 7 │ 8 │ 1725 │ 0.0001725 │ 0.000173611 │\n",
"│ 8 │ 9 │ 204 │ 2.04e-5 │ 2.20459e-5 │\n",
"│ 9 │ 10 │ 31 │ 3.1e-6 │ 2.48016e-6 │\n",
"│ 10 │ 11 │ 1 │ 1.0e-7 │ 2.50521e-7 │"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"transform!(jumps_agg,\n",
" :jumps_length => (x -> x ./ sum(x)) => :simulation,\n",
" :jumps => ByRow(x -> (x-1) / factorial(x)) => :theory)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let us briefly justify how we have guessed it (you can safely skip the derivation):\n",
"\n",
"Formula\n",
"$$\n",
"p_n = \\frac{n-1}{n!}\n",
"$$\n",
"\n",
"$$\n",
"\\sum_{n=2}^{+\\infty}p_n=\\sum_{n=2}^{+\\infty} \\frac{n-1}{n!} = \\sum_{n=1}^{+\\infty} \\frac{1}{n!} - \\sum_{n=2}^{+\\infty} \\frac{1}{n!} = 1\n",
"$$\n",
"\n",
"$$\n",
"\\sum_{n=2}^{+\\infty}n\\cdot p_n=\\sum_{n=2}^{+\\infty} n\\frac{n-1}{n!} = \\sum_{n=2}^{+\\infty} \\frac{1}{(n-2)!} = e\n",
"$$\n",
"\n",
"Now we note that:\n",
"\n",
"$$\n",
"1-\\sum_{n=2}^k p_n = \\frac{1}{k!}\n",
"$$\n",
"which can be most easily justified by a geometric argument."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To finish this section of the tutorial let us check if random numbers generated using `rand()` were indeed $U(0,1)$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To do this we will add some columns to `df` data frame."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
" | id | pos | jumps |
---|
| Int64 | Array… | Int64 |
---|
10,000,000 rows × 3 columns
1 | 1 | [0.646691, 0.112486, 0.276021] | 3 |
---|
2 | 2 | [0.651664, 0.0566425, 0.842714] | 3 |
---|
3 | 3 | [0.950498, 0.96467] | 2 |
---|
4 | 4 | [0.945775, 0.789904] | 2 |
---|
5 | 5 | [0.82116, 0.0341601, 0.0945445, 0.314926] | 4 |
---|
6 | 6 | [0.12781, 0.374187, 0.931115] | 3 |
---|
7 | 7 | [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] | 5 |
---|
8 | 8 | [0.732, 0.299058] | 2 |
---|
9 | 9 | [0.449182, 0.875096] | 2 |
---|
10 | 10 | [0.0462887, 0.698356, 0.365109] | 3 |
---|
11 | 11 | [0.302478, 0.372575, 0.150508, 0.147329, 0.283401] | 5 |
---|
12 | 12 | [0.404953, 0.499531, 0.658815] | 3 |
---|
13 | 13 | [0.515627, 0.260715, 0.59552] | 3 |
---|
14 | 14 | [0.292462, 0.28858, 0.61816] | 3 |
---|
15 | 15 | [0.66426, 0.753508] | 2 |
---|
16 | 16 | [0.0368842, 0.643704, 0.401421] | 3 |
---|
17 | 17 | [0.525057, 0.61201] | 2 |
---|
18 | 18 | [0.432577, 0.082207, 0.199058, 0.576082] | 4 |
---|
19 | 19 | [0.218177, 0.362036, 0.204728, 0.932984] | 4 |
---|
20 | 20 | [0.827263, 0.0992992, 0.6343] | 3 |
---|
21 | 21 | [0.132715, 0.775194, 0.869237] | 3 |
---|
22 | 22 | [0.0396356, 0.79041, 0.431188] | 3 |
---|
23 | 23 | [0.137658, 0.60808, 0.255054] | 3 |
---|
24 | 24 | [0.498734, 0.0940369, 0.52509] | 3 |
---|
25 | 25 | [0.265511, 0.110096, 0.834362] | 3 |
---|
26 | 26 | [0.633427, 0.337865, 0.112987] | 3 |
---|
27 | 27 | [0.78299, 0.838042] | 2 |
---|
28 | 28 | [0.0878598, 0.386568, 0.330579, 0.748041] | 4 |
---|
29 | 29 | [0.265595, 0.291069, 0.612628] | 3 |
---|
30 | 30 | [0.705766, 0.508363] | 2 |
---|
⋮ | ⋮ | ⋮ | ⋮ |
---|
"
],
"text/latex": [
"\\begin{tabular}{r|ccc}\n",
"\t& id & pos & jumps\\\\\n",
"\t\\hline\n",
"\t& Int64 & Array… & Int64\\\\\n",
"\t\\hline\n",
"\t1 & 1 & [0.646691, 0.112486, 0.276021] & 3 \\\\\n",
"\t2 & 2 & [0.651664, 0.0566425, 0.842714] & 3 \\\\\n",
"\t3 & 3 & [0.950498, 0.96467] & 2 \\\\\n",
"\t4 & 4 & [0.945775, 0.789904] & 2 \\\\\n",
"\t5 & 5 & [0.82116, 0.0341601, 0.0945445, 0.314926] & 4 \\\\\n",
"\t6 & 6 & [0.12781, 0.374187, 0.931115] & 3 \\\\\n",
"\t7 & 7 & [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] & 5 \\\\\n",
"\t8 & 8 & [0.732, 0.299058] & 2 \\\\\n",
"\t9 & 9 & [0.449182, 0.875096] & 2 \\\\\n",
"\t10 & 10 & [0.0462887, 0.698356, 0.365109] & 3 \\\\\n",
"\t11 & 11 & [0.302478, 0.372575, 0.150508, 0.147329, 0.283401] & 5 \\\\\n",
"\t12 & 12 & [0.404953, 0.499531, 0.658815] & 3 \\\\\n",
"\t13 & 13 & [0.515627, 0.260715, 0.59552] & 3 \\\\\n",
"\t14 & 14 & [0.292462, 0.28858, 0.61816] & 3 \\\\\n",
"\t15 & 15 & [0.66426, 0.753508] & 2 \\\\\n",
"\t16 & 16 & [0.0368842, 0.643704, 0.401421] & 3 \\\\\n",
"\t17 & 17 & [0.525057, 0.61201] & 2 \\\\\n",
"\t18 & 18 & [0.432577, 0.082207, 0.199058, 0.576082] & 4 \\\\\n",
"\t19 & 19 & [0.218177, 0.362036, 0.204728, 0.932984] & 4 \\\\\n",
"\t20 & 20 & [0.827263, 0.0992992, 0.6343] & 3 \\\\\n",
"\t21 & 21 & [0.132715, 0.775194, 0.869237] & 3 \\\\\n",
"\t22 & 22 & [0.0396356, 0.79041, 0.431188] & 3 \\\\\n",
"\t23 & 23 & [0.137658, 0.60808, 0.255054] & 3 \\\\\n",
"\t24 & 24 & [0.498734, 0.0940369, 0.52509] & 3 \\\\\n",
"\t25 & 25 & [0.265511, 0.110096, 0.834362] & 3 \\\\\n",
"\t26 & 26 & [0.633427, 0.337865, 0.112987] & 3 \\\\\n",
"\t27 & 27 & [0.78299, 0.838042] & 2 \\\\\n",
"\t28 & 28 & [0.0878598, 0.386568, 0.330579, 0.748041] & 4 \\\\\n",
"\t29 & 29 & [0.265595, 0.291069, 0.612628] & 3 \\\\\n",
"\t30 & 30 & [0.705766, 0.508363] & 2 \\\\\n",
"\t$\\dots$ & $\\dots$ & $\\dots$ & $\\dots$ \\\\\n",
"\\end{tabular}\n"
],
"text/plain": [
"10000000×3 DataFrame. Omitted printing of 1 columns\n",
"│ Row │ id │ pos │\n",
"│ │ \u001b[90mInt64\u001b[39m │ \u001b[90mArray{Float64,1}\u001b[39m │\n",
"├──────────┼──────────┼──────────────────────────────────────────────────────┤\n",
"│ 1 │ 1 │ [0.646691, 0.112486, 0.276021] │\n",
"│ 2 │ 2 │ [0.651664, 0.0566425, 0.842714] │\n",
"│ 3 │ 3 │ [0.950498, 0.96467] │\n",
"│ 4 │ 4 │ [0.945775, 0.789904] │\n",
"│ 5 │ 5 │ [0.82116, 0.0341601, 0.0945445, 0.314926] │\n",
"│ 6 │ 6 │ [0.12781, 0.374187, 0.931115] │\n",
"│ 7 │ 7 │ [0.438939, 0.246862, 0.0118196, 0.0460428, 0.496169] │\n",
"│ 8 │ 8 │ [0.732, 0.299058] │\n",
"│ 9 │ 9 │ [0.449182, 0.875096] │\n",
"│ 10 │ 10 │ [0.0462887, 0.698356, 0.365109] │\n",
"⋮\n",
"│ 9999990 │ 9999990 │ [0.209058, 0.338017, 0.567608] │\n",
"│ 9999991 │ 9999991 │ [0.700468, 0.220524, 0.347931] │\n",
"│ 9999992 │ 9999992 │ [0.231368, 0.862016] │\n",
"│ 9999993 │ 9999993 │ [0.869351, 0.444795] │\n",
"│ 9999994 │ 9999994 │ [0.821356, 0.509054] │\n",
"│ 9999995 │ 9999995 │ [0.589245, 0.669708] │\n",
"│ 9999996 │ 9999996 │ [0.806262, 0.734397] │\n",
"│ 9999997 │ 9999997 │ [0.216506, 0.430571, 0.283787, 0.335015] │\n",
"│ 9999998 │ 9999998 │ [0.0100723, 0.836315, 0.942299] │\n",
"│ 9999999 │ 9999999 │ [0.499669, 0.25214, 0.964065] │\n",
"│ 10000000 │ 10000000 │ [0.663339, 0.887989] │"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
" | first | last |
---|
| Float64 | Float64 |
---|
10,000,000 rows × 2 columns
1 | 0.646691 | 0.276021 |
---|
2 | 0.651664 | 0.842714 |
---|
3 | 0.950498 | 0.96467 |
---|
4 | 0.945775 | 0.789904 |
---|
5 | 0.82116 | 0.314926 |
---|
6 | 0.12781 | 0.931115 |
---|
7 | 0.438939 | 0.496169 |
---|
8 | 0.732 | 0.299058 |
---|
9 | 0.449182 | 0.875096 |
---|
10 | 0.0462887 | 0.365109 |
---|
11 | 0.302478 | 0.283401 |
---|
12 | 0.404953 | 0.658815 |
---|
13 | 0.515627 | 0.59552 |
---|
14 | 0.292462 | 0.61816 |
---|
15 | 0.66426 | 0.753508 |
---|
16 | 0.0368842 | 0.401421 |
---|
17 | 0.525057 | 0.61201 |
---|
18 | 0.432577 | 0.576082 |
---|
19 | 0.218177 | 0.932984 |
---|
20 | 0.827263 | 0.6343 |
---|
21 | 0.132715 | 0.869237 |
---|
22 | 0.0396356 | 0.431188 |
---|
23 | 0.137658 | 0.255054 |
---|
24 | 0.498734 | 0.52509 |
---|
25 | 0.265511 | 0.834362 |
---|
26 | 0.633427 | 0.112987 |
---|
27 | 0.78299 | 0.838042 |
---|
28 | 0.0878598 | 0.748041 |
---|
29 | 0.265595 | 0.612628 |
---|
30 | 0.705766 | 0.508363 |
---|
⋮ | ⋮ | ⋮ |
---|
"
],
"text/latex": [
"\\begin{tabular}{r|cc}\n",
"\t& first & last\\\\\n",
"\t\\hline\n",
"\t& Float64 & Float64\\\\\n",
"\t\\hline\n",
"\t1 & 0.646691 & 0.276021 \\\\\n",
"\t2 & 0.651664 & 0.842714 \\\\\n",
"\t3 & 0.950498 & 0.96467 \\\\\n",
"\t4 & 0.945775 & 0.789904 \\\\\n",
"\t5 & 0.82116 & 0.314926 \\\\\n",
"\t6 & 0.12781 & 0.931115 \\\\\n",
"\t7 & 0.438939 & 0.496169 \\\\\n",
"\t8 & 0.732 & 0.299058 \\\\\n",
"\t9 & 0.449182 & 0.875096 \\\\\n",
"\t10 & 0.0462887 & 0.365109 \\\\\n",
"\t11 & 0.302478 & 0.283401 \\\\\n",
"\t12 & 0.404953 & 0.658815 \\\\\n",
"\t13 & 0.515627 & 0.59552 \\\\\n",
"\t14 & 0.292462 & 0.61816 \\\\\n",
"\t15 & 0.66426 & 0.753508 \\\\\n",
"\t16 & 0.0368842 & 0.401421 \\\\\n",
"\t17 & 0.525057 & 0.61201 \\\\\n",
"\t18 & 0.432577 & 0.576082 \\\\\n",
"\t19 & 0.218177 & 0.932984 \\\\\n",
"\t20 & 0.827263 & 0.6343 \\\\\n",
"\t21 & 0.132715 & 0.869237 \\\\\n",
"\t22 & 0.0396356 & 0.431188 \\\\\n",
"\t23 & 0.137658 & 0.255054 \\\\\n",
"\t24 & 0.498734 & 0.52509 \\\\\n",
"\t25 & 0.265511 & 0.834362 \\\\\n",
"\t26 & 0.633427 & 0.112987 \\\\\n",
"\t27 & 0.78299 & 0.838042 \\\\\n",
"\t28 & 0.0878598 & 0.748041 \\\\\n",
"\t29 & 0.265595 & 0.612628 \\\\\n",
"\t30 & 0.705766 & 0.508363 \\\\\n",
"\t$\\dots$ & $\\dots$ & $\\dots$ \\\\\n",
"\\end{tabular}\n"
],
"text/plain": [
"10000000×2 DataFrame\n",
"│ Row │ first │ last │\n",
"│ │ \u001b[90mFloat64\u001b[39m │ \u001b[90mFloat64\u001b[39m │\n",
"├──────────┼───────────┼──────────┤\n",
"│ 1 │ 0.646691 │ 0.276021 │\n",
"│ 2 │ 0.651664 │ 0.842714 │\n",
"│ 3 │ 0.950498 │ 0.96467 │\n",
"│ 4 │ 0.945775 │ 0.789904 │\n",
"│ 5 │ 0.82116 │ 0.314926 │\n",
"│ 6 │ 0.12781 │ 0.931115 │\n",
"│ 7 │ 0.438939 │ 0.496169 │\n",
"│ 8 │ 0.732 │ 0.299058 │\n",
"│ 9 │ 0.449182 │ 0.875096 │\n",
"│ 10 │ 0.0462887 │ 0.365109 │\n",
"⋮\n",
"│ 9999990 │ 0.209058 │ 0.567608 │\n",
"│ 9999991 │ 0.700468 │ 0.347931 │\n",
"│ 9999992 │ 0.231368 │ 0.862016 │\n",
"│ 9999993 │ 0.869351 │ 0.444795 │\n",
"│ 9999994 │ 0.821356 │ 0.509054 │\n",
"│ 9999995 │ 0.589245 │ 0.669708 │\n",
"│ 9999996 │ 0.806262 │ 0.734397 │\n",
"│ 9999997 │ 0.216506 │ 0.335015 │\n",
"│ 9999998 │ 0.0100723 │ 0.942299 │\n",
"│ 9999999 │ 0.499669 │ 0.964065 │\n",
"│ 10000000 │ 0.663339 │ 0.887989 │"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_test = select(df, :pos => ByRow(first) => :first, :pos => ByRow(last) => :last)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAGdCAYAAAD+JxxnAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3df1RU953/8RcFGdCFKdEwOJaj6NlVOaRthC4BdUmaCBp/bLo5q1nTOdKTUl1JFDEbpcbW2AREXeuJRnN0PWs2MeLZsnTdDVrItkENYAwVV+KvzapBVxFtCBhjQfB+//BwvxkwKnYGM3yej3PmnMy97/u5n/uZYeaVz713DLIsyxIAAICBvnGvOwAAAHCvEIQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYKudcd+Dq7fv26zp07p4iICAUFBd3r7gAAgDtgWZYuX74st9utb3zj1nM+BKFbOHfunGJjY+91NwAAwF04c+aMvvWtb92yhiB0CxEREZJuDGRkZOQ97g0AALgTLS0tio2Ntb/Hb4UgdAudp8MiIyMJQgAABJg7uayFi6UBAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjNXjILRnzx5NnTpVbrdbQUFB+vWvf+213rIsLVu2TG63W+Hh4Xr44Yf10UcfedU0NTXJ4/HI6XTK6XTK4/Hos88+86o5fPiw0tLSFB4eriFDhmj58uWyLMurpri4WPHx8XI4HIqPj1dJSUmP+4K+Z9jid7weAAB8lZCebnDlyhV95zvf0Y9+9CM9+eST3davXLlSa9as0datW/UXf/EXevnllzVhwgQdP35cERERkqSZM2fq7Nmz2r17tyTpJz/5iTwej/7jP/5DktTS0qIJEybokUce0YEDB3TixAllZmZqwIABWrhwoSSpqqpKM2bM0C9+8Qv94Ac/UElJiaZPn659+/YpOTn5jvsSaG72xX56xeR70BMEAt4v8DXeU+hrehyEJk2apEmTJt10nWVZWrt2rZYsWaK/+Zu/kSS98cYbcrlcevvttzV79mwdPXpUu3fvVnV1tR1YNm/erJSUFB0/flwjR47Utm3b9Mc//lFbt26Vw+FQQkKCTpw4oTVr1ig3N1dBQUFau3atJkyYoLy8PElSXl6eKioqtHbtWm3fvv2O+oLA0/VD2FcfwHy495y/Xove1Fde90B8LXw19n3lNexN9/L98nV8vXochG7l1KlTamhoUHp6ur3M4XAoLS1NlZWVmj17tqqqquR0Ou0QJEkPPfSQnE6nKisrNXLkSFVVVSktLU0Oh8OuycjIUF5enk6fPq24uDhVVVVpwYIFXvvPyMjQ2rVr77gvXbW2tqq1tdV+3tLS8qcPyi3cyZvx635q5+v4pu6qNz9we7Omr7qT93xfGYu7OdY72eZu3z+++oL05/7v9vhv15+7/bu83TY3285X4+qrfZn8eSP5OAg1NDRIklwul9dyl8ulTz75xK6Jjo7utm10dLS9fUNDg4YNG9atjc51cXFxamhouOl+vtzG7frSVUFBgV566aXbHufXnT/f1L76EPZnOPHVdr0ZQr/u/QnEmTdfjZevviDvNV99Qd5t3ddtjO5ln3vz88+fn5F9JSz5NAh1CgoK8npuWZbXsq7r76Sm80Lp29V0XXYnNZ3y8vKUm5trP29paVFsbOxNa/3Bnx8U9/pD6G7+YAPhj6yvfgH0Zrv+DCz+0hf29XV7X95MIPSxK1/9HfSVz79A4NMgFBMTI+nGbMzgwYPt5Y2NjfbMTExMjC5cuNBt24sXL3rVdM7ofLkNSbet+fL62/WlK4fD4XU6LlD0lTdjV331uAKRSa+FSceKry/eh73Hp78jFBcXp5iYGJWXl9vL2traVFFRodTUVElSSkqKmpub9cEHH9g1+/fvV3Nzs1fNnj171NbWZteUlZXJ7Xbbp8xSUlK89tNZ09nGnfQFQGDq+hMJfGkAuFs9DkKff/65amtrVVtbK+nGRcm1tbWqr69XUFCQcnJylJ+fr5KSEtXV1SkzM1P9+/fXzJkzJUmjR4/WxIkTlZWVperqalVXVysrK0tTpkzRyJEjJd24vd7hcCgzM1N1dXUqKSlRfn6+fceYJM2fP19lZWUqLCzUsWPHVFhYqHfffVc5OTmSdEd9AQAAZuvxqbEPP/xQjzzyiP2885qaWbNmaevWrXrhhRd09epVzZ07V01NTUpOTlZZWZnX7/Zs27ZN8+bNs+/omjZtmtavX2+vdzqdKi8vV3Z2tpKSkhQVFaXc3Fyv63dSU1NVVFSkF198UUuXLtWIESO0Y8cOr7vR7qQvAADAXEFW159rhq2lpUVOp1PNzc2KjIz0eftM5wMATOePC8N78v3NvzUGAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMbyeRBqb2/Xiy++qLi4OIWHh2v48OFavny5rl+/btdYlqVly5bJ7XYrPDxcDz/8sD766COvdpqamuTxeOR0OuV0OuXxePTZZ5951Rw+fFhpaWkKDw/XkCFDtHz5clmW5VVTXFys+Ph4ORwOxcfHq6SkxNeHDAAAApTPg1BhYaFef/11rV+/XkePHtXKlSu1atUqrVu3zq5ZuXKl1qxZo/Xr1+vAgQOKiYnRhAkTdPnyZbtm5syZqq2t1e7du7V7927V1tbK4/HY61taWjRhwgS53W4dOHBA69at0+rVq7VmzRq7pqqqSjNmzJDH49GhQ4fk8Xg0ffp07d+/39eHDQAAAlCQ1XUK5U80ZcoUuVwubdmyxV725JNPqn///nrzzTdlWZbcbrdycnK0aNEiSVJra6tcLpcKCws1e/ZsHT16VPHx8aqurlZycrIkqbq6WikpKTp27JhGjhypjRs3Ki8vTxcuXJDD4ZAkrVixQuvWrdPZs2cVFBSkGTNmqKWlRbt27bL7MnHiREVFRWn79u23PZaWlhY5nU41NzcrMjLSl8MkSRq2+B2ftwkAQCA5vWKyz9vsyfe3z2eExo0bp//6r//SiRMnJEmHDh3Svn379Pjjj0uSTp06pYaGBqWnp9vbOBwOpaWlqbKyUtKNmRyn02mHIEl66KGH5HQ6vWrS0tLsECRJGRkZOnfunE6fPm3XfHk/nTWdbXTV2tqqlpYWrwcAAOi7Qnzd4KJFi9Tc3KxRo0YpODhYHR0deuWVV/R3f/d3kqSGhgZJksvl8trO5XLpk08+sWuio6O7tR0dHW1v39DQoGHDhnVro3NdXFycGhoabrqfzja6Kigo0EsvvdTDIwYAAIHK5zNCO3bs0FtvvaW3335bv//97/XGG29o9erVeuONN7zqgoKCvJ5bluW1rOv6O6npPMt3u5qbtS1JeXl5am5uth9nzpy51aECAIAA5/MZoX/4h3/Q4sWL9dRTT0mSHnjgAX3yyScqKCjQrFmzFBMTI+nGrM3gwYPt7RobG+3Zm5iYGF24cKFb2xcvXvSq6Tqz09jYKEm3rek6S9TJ4XB4nWoDAAB9m89nhL744gt94xvezQYHB9u3z8fFxSkmJkbl5eX2+ra2NlVUVCg1NVWSlJKSoubmZn3wwQd2zf79+9Xc3OxVs2fPHrW1tdk1ZWVlcrvd9imzlJQUr/101nS2AQAAzObzIDR16lS98soreuedd3T69GmVlJRozZo1+sEPfiDpxqmqnJwc5efnq6SkRHV1dcrMzFT//v01c+ZMSdLo0aM1ceJEZWVlqbq6WtXV1crKytKUKVM0cuRISTdur3c4HMrMzFRdXZ1KSkqUn5+v3Nxc+9TX/PnzVVZWpsLCQh07dkyFhYV69913lZOT4+vDBgAAAcjnp8bWrVunpUuXau7cuWpsbJTb7dbs2bP1s5/9zK554YUXdPXqVc2dO1dNTU1KTk5WWVmZIiIi7Jpt27Zp3rx59l1f06ZN0/r16+31TqdT5eXlys7OVlJSkqKiopSbm6vc3Fy7JjU1VUVFRXrxxRe1dOlSjRgxQjt27PC6Gw0AAJjL578j1JfwO0IAAPhXn/sdIQAAgEBBEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAY/klCP3f//2ffvjDH2rgwIHq37+/vvvd76qmpsZeb1mWli1bJrfbrfDwcD388MP66KOPvNpoamqSx+OR0+mU0+mUx+PRZ5995lVz+PBhpaWlKTw8XEOGDNHy5ctlWZZXTXFxseLj4+VwOBQfH6+SkhJ/HDIAAAhAPg9CTU1NGjt2rPr166ddu3bpyJEj+sd//Ed985vftGtWrlypNWvWaP369Tpw4IBiYmI0YcIEXb582a6ZOXOmamtrtXv3bu3evVu1tbXyeDz2+paWFk2YMEFut1sHDhzQunXrtHr1aq1Zs8auqaqq0owZM+TxeHTo0CF5PB5Nnz5d+/fv9/VhAwCAABRkdZ1C+RMtXrxY77//vvbu3XvT9ZZlye12KycnR4sWLZIktba2yuVyqbCwULNnz9bRo0cVHx+v6upqJScnS5Kqq6uVkpKiY8eOaeTIkdq4caPy8vJ04cIFORwOSdKKFSu0bt06nT17VkFBQZoxY4ZaWlq0a9cue/8TJ05UVFSUtm/ffttjaWlpkdPpVHNzsyIjI//Uoelm2OJ3fN4mAACB5PSKyT5vsyff3z6fEdq5c6eSkpL0t3/7t4qOjtaDDz6ozZs32+tPnTqlhoYGpaen28scDofS0tJUWVkp6cZMjtPptEOQJD300ENyOp1eNWlpaXYIkqSMjAydO3dOp0+ftmu+vJ/Oms42umptbVVLS4vXAwAA9F0+D0InT57Uxo0b9ed//uf6zW9+ozlz5mjevHn6l3/5F0lSQ0ODJMnlcnlt53K57HUNDQ2Kjo7u1nZ0dLRXzc3a+PI+vqqmc31XBQUF9jVJTqdTsbGxPTp2AAAQWHwehK5fv64xY8YoPz9fDz74oGbPnq2srCxt3LjRqy4oKMjruWVZXsu6rr+Tms6zfLeruVnbkpSXl6fm5mb7cebMmVsdKgAACHA+D0KDBw9WfHy817LRo0ervr5ekhQTEyNJ3WZlGhsb7dmbmJgYXbhwoVvbFy9e9Kq5WRuSblvTdZaok8PhUGRkpNcDAAD0XT4PQmPHjtXx48e9lp04cUJDhw6VJMXFxSkmJkbl5eX2+ra2NlVUVCg1NVWSlJKSoubmZn3wwQd2zf79+9Xc3OxVs2fPHrW1tdk1ZWVlcrvdGjZsmF3z5f101nS2AQAAzObzILRgwQJVV1crPz9fH3/8sd5++21t2rRJ2dnZkm6cqsrJyVF+fr5KSkpUV1enzMxM9e/fXzNnzpR0YwZp4sSJysrKUnV1taqrq5WVlaUpU6Zo5MiRkm7cXu9wOJSZmam6ujqVlJQoPz9fubm59qmv+fPnq6ysTIWFhTp27JgKCwv17rvvKicnx9eHDQAAAlCIrxv83ve+p5KSEuXl5Wn58uWKi4vT2rVr9fTTT9s1L7zwgq5evaq5c+eqqalJycnJKisrU0REhF2zbds2zZs3z77ra9q0aVq/fr293ul0qry8XNnZ2UpKSlJUVJRyc3OVm5tr16SmpqqoqEgvvviili5dqhEjRmjHjh1ed6MBAABz+fx3hPoSfkcIAAD/6nO/IwQAABAoCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCy/B6GCggIFBQUpJyfHXtba2qrnnntOgwYN0oABAzRt2jSdPXvWa7v6+npNnTpVAwYM0KBBgzRv3jy1tbV51VRUVCgxMVFhYWEaPny4Xn/99W7737Bhg+Li4hQWFqbExETt3bvXPwcKAAACjl+D0IEDB7Rp0yZ9+9vf9lqek5OjkpISFRUVad++ffr88881ZcoUdXR0SJI6Ojo0efJkXblyRfv27VNRUZGKi4u1cOFCu41Tp07p8ccf1/jx43Xw4EH99Kc/1bx581RcXGzX7NixQzk5OVqyZIkOHjyo8ePHa9KkSaqvr/fnYQMAgAARZFmW5Y+GP//8c40ZM0YbNmzQyy+/rO9+97tau3atmpubdf/99+vNN9/UjBkzJEnnzp1TbGysSktLlZGRoV27dmnKlCk6c+aM3G63JKmoqEiZmZlqbGxUZGSkFi1apJ07d+ro0aP2PufMmaNDhw6pqqpKkpScnKwxY8Zo48aNds3o0aP1xBNPqKCg4LbH0NLSIqfTqebmZkVGRvpyeCRJwxa/4/M2AQAIJKdXTPZ5mz35/vbbjFB2drYmT56sxx57zGt5TU2Nrl27pvT0dHuZ2+1WQkKCKisrJUlVVVVKSEiwQ5AkZWRkqLW1VTU1NXbNl9vorPnwww917do1tbW1qaampltNenq6vZ+uWltb1dLS4vUAAAB9V4g/Gi0qKtLvf/97HThwoNu6hoYGhYaGKioqymu5y+VSQ0ODXeNyubzWR0VFKTQ09JY1LpdL7e3tunTpkizLUkdHx01rOtvoqqCgQC+99FLPDhYAAAQsn88InTlzRvPnz9dbb72lsLCwO97OsiwFBQXZz7/833da03mW73Y1N2tbkvLy8tTc3Gw/zpw5c8f9BwAAgcfnQaimpkaNjY1KTExUSEiIQkJCVFFRoVdffVUhISFyuVxqa2tTU1OT13aNjY327E1MTEy3WZumpiZdu3btljWNjY0KCQnRwIEDNWjQIAUHB9+0pussUSeHw6HIyEivBwAA6Lt8HoQeffRRHT58WLW1tfYjKSlJTz/9tP3f/fr1U3l5ub3N+fPnVVdXp9TUVElSSkqK6urqdP78ebumrKxMDodDiYmJds2X2+is6Ww/NDRUiYmJ3WrKy8vt/QAAALP5/BqhiIgIJSQkeC0bMGCABg4caC9/5plntHDhQg0cOFD33Xefnn/+eT3wwAP2hdXp6emKj4+Xx+PRqlWr9Omnn+r5559XVlaWPUszZ84crV+/Xrm5ucrKylJVVZW2bNmi7du32/vNzc2Vx+NRUlKSUlJStGnTJtXX12vOnDm+PmwAABCA/HKx9O388pe/VEhIiKZPn66rV6/q0Ucf1datWxUcHCxJCg4O1jvvvKO5c+dq7NixCg8P18yZM7V69Wq7jbi4OJWWlmrBggV67bXX5Ha79eqrr+rJJ5+0a2bMmKE//OEPWr58uc6fP6+EhASVlpZq6NChvX7MAADg68dvvyPUF/A7QgAA+Fef/R0hAACArzuCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwls+DUEFBgb73ve8pIiJC0dHReuKJJ3T8+HGvmtbWVj333HMaNGiQBgwYoGnTpuns2bNeNfX19Zo6daoGDBigQYMGad68eWpra/OqqaioUGJiosLCwjR8+HC9/vrr3fqzYcMGxcXFKSwsTImJidq7d6+vDxkAAAQonwehiooKZWdnq7q6WuXl5Wpvb1d6erquXLli1+Tk5KikpERFRUXat2+fPv/8c02ZMkUdHR2SpI6ODk2ePFlXrlzRvn37VFRUpOLiYi1cuNBu49SpU3r88cc1fvx4HTx4UD/96U81b948FRcX2zU7duxQTk6OlixZooMHD2r8+PGaNGmS6uvrfX3YAAAgAAVZlmX5cwcXL15UdHS0Kioq9Fd/9Vdqbm7W/fffrzfffFMzZsyQJJ07d06xsbEqLS1VRkaGdu3apSlTpujMmTNyu92SpKKiImVmZqqxsVGRkZFatGiRdu7cqaNHj9r7mjNnjg4dOqSqqipJUnJyssaMGaONGzfaNaNHj9YTTzyhgoKC2/a9paVFTqdTzc3NioyM9OWwSJKGLX7H520CABBITq+Y7PM2e/L97fdrhJqbmyVJ9913nySppqZG165dU3p6ul3jdruVkJCgyspKSVJVVZUSEhLsECRJGRkZam1tVU1NjV3z5TY6az788ENdu3ZNbW1tqqmp6VaTnp5u7wcAAJgtxJ+NW5al3NxcjRs3TgkJCZKkhoYGhYaGKioqyqvW5XKpoaHBrnG5XF7ro6KiFBoaessal8ul9vZ2Xbp0SZZlqaOj46Y1nW101draqtbWVvt5S0vLXRw1AAAIFH6dEXr22Wf13//939q+ffttay3LUlBQkP38y/99pzWdZ/luV3OztqUbF3o7nU77ERsbe9t+AwCAwOW3IPTcc89p586d+t3vfqdvfetb9vKYmBi1tbWpqanJq76xsdGevYmJiek2a9PU1KRr167dsqaxsVEhISEaOHCgBg0apODg4JvWdJ0l6pSXl6fm5mb7cebMmbs7eAAAEBB8HoQsy9Kzzz6rf/u3f9Nvf/tbxcXFea1PTExUv379VF5ebi87f/686urqlJqaKklKSUlRXV2dzp8/b9eUlZXJ4XAoMTHRrvlyG501SUlJ6tevn0JDQ5WYmNitpry83N5PVw6HQ5GRkV4PAADQd/n8GqHs7Gy9/fbb+vd//3dFRETYMzJOp1Ph4eFyOp165plntHDhQg0cOFD33Xefnn/+eT3wwAN67LHHJN24oDk+Pl4ej0erVq3Sp59+queff15ZWVl2OJkzZ47Wr1+v3NxcZWVlqaqqSlu2bPE6DZebmyuPx6OkpCSlpKRo06ZNqq+v15w5c3x92AAAIAD5PAh13qr+8MMPey3/53/+Z2VmZkqSfvnLXyokJETTp0/X1atX9eijj2rr1q0KDg6WJAUHB+udd97R3LlzNXbsWIWHh2vmzJlavXq13V5cXJxKS0u1YMECvfbaa3K73Xr11Vf15JNP2jUzZszQH/7wBy1fvlznz59XQkKCSktLNXToUF8fNgAACEB+/x2hQMbvCAEA4F99/neEAAAAvq4IQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIxFEAIAAMYiCAEAAGMRhAAAgLEIQgAAwFgEIQAAYCyCEAAAMBZBCAAAGIsgBAAAjEUQAgAAxiIIAQAAYxGEAACAsQhCAADAWAQhAABgLCOC0IYNGxQXF6ewsDAlJiZq796997pLAADga6DPB6EdO3YoJydHS5Ys0cGDBzV+/HhNmjRJ9fX197prAADgHuvzQWjNmjV65pln9OMf/1ijR4/W2rVrFRsbq40bN97rrou/gWQAAAkCSURBVAEAgHss5F53wJ/a2tpUU1OjxYsXey1PT09XZWVlt/rW1la1trbaz5ubmyVJLS0tfunf9dYv/NIuAACBwh/fsZ1tWpZ129o+HYQuXbqkjo4OuVwur+Uul0sNDQ3d6gsKCvTSSy91Wx4bG+u3PgIAYDLnWv+1ffnyZTmdzlvW9Okg1CkoKMjruWVZ3ZZJUl5ennJzc+3n169f16effqqBAwfetP5P0dLSotjYWJ05c0aRkZE+bRv/H+PcOxjn3sE49x7Gunf4a5wty9Lly5fldrtvW9ung9CgQYMUHBzcbfansbGx2yyRJDkcDjkcDq9l3/zmN/3ax8jISP7IegHj3DsY597BOPcexrp3+GOcbzcT1KlPXywdGhqqxMRElZeXey0vLy9XamrqPeoVAAD4uujTM0KSlJubK4/Ho6SkJKWkpGjTpk2qr6/XnDlz7nXXAADAPRa8bNmyZfe6E/6UkJCggQMHKj8/X6tXr9bVq1f15ptv6jvf+c697pqCg4P18MMPKySkz+fRe4px7h2Mc+9gnHsPY9077vU4B1l3cm8ZAABAH9SnrxECAAC4FYIQAAAwFkEIAAAYiyAEAACMRRDyow0bNiguLk5hYWFKTEzU3r17b1lfXFys+Ph4ORwOxcfHq6SkpJd6Gth6Ms6bN2/W+PHjFRUVpaioKD322GP64IMPerG3gaun7+dORUVFCgoK0hNPPOHnHvYNPR3nzz77TNnZ2Ro8eLDCwsI0evRolZaW9lJvA1dPx3nt2rUaOXKkwsPDFRsbqwULFuiPf/xjL/U2MO3Zs0dTp06V2+1WUFCQfv3rX992m4qKCiUmJiosLEzDhw/X66+/7v+OWvCLoqIiq1+/ftbmzZutI0eOWPPnz7cGDBhgffLJJzetr6ystIKDg638/Hzr6NGjVn5+vhUSEmJVV1f3cs8DS0/HeebMmdZrr71mHTx40Dp69Kj1ox/9yHI6ndbZs2d7ueeBpafj3On06dPWkCFDrPHjx1t//dd/3Uu9DVw9HefW1lYrKSnJevzxx619+/ZZp0+ftvbu3WvV1tb2cs8DS0/H+a233rIcDoe1bds269SpU9ZvfvMba/DgwVZOTk4v9zywlJaWWkuWLLGKi4stSVZJSckt60+ePGn179/fmj9/vnXkyBFr8+bNVr9+/axf/epXfu0nQchP/vIv/9KaM2eO17JRo0ZZixcvvmn99OnTrYkTJ3oty8jIsJ566im/9bEv6Ok4d9Xe3m5FRERYb7zxhj+612fczTi3t7dbY8eOtf7pn/7JmjVrFkHoDvR0nDdu3GgNHz7camtr643u9Rk9Hefs7Gzr+9//vtey3Nxca9y4cX7rY19zJ0HohRdesEaNGuW1bPbs2dZDDz3kz65ZnBrzg7a2NtXU1Cg9Pd1reXp6uiorK2+6TVVVVbf6jIyMr6zH3Y1zV1988YWuXbum++67zx9d7BPudpyXL1+u+++/X88884y/u9gn3M0479y5UykpKcrOzpbL5VJCQoLy8/PV0dHRG10OSHczzuPGjVNNTY19Gv3kyZMqLS3V5MmT/d5fk3zV9+CHH36oa9eu+W2//FymH1y6dEkdHR3d/mFXl8vV7R+A7dTQ0NCjetzdOHe1ePFiDRkyRI899pg/utgn3M04v//++9qyZYtqa2t7o4t9wt2M88mTJ/Xb3/5WTz/9tEpLS/U///M/ys7OVnt7u372s5/1RrcDzt2M81NPPaWLFy9q3LhxsixL7e3t+vu//3stXry4N7psjK/6Hmxvb9elS5c0ePBgv+yXIORHQUFBXs8ty+q27E+pxw13O24rV67U9u3b9d577yksLMxf3esz7nScL1++rB/+8IfavHmzBg0a1Fvd6zN68n6+fv26oqOjtWnTJgUHBysxMVHnzp3TqlWrCEK30ZNxfu+99/TKK69ow4YNSk5O1scff6z58+dr8ODBWrp0aW901xg3e11uttyXCEJ+MGjQIAUHB3f7v4vGxsZuabdTTExMj+pxd+PcafXq1crPz9e7776rb3/72/7sZsDr6Tj/7//+r06fPq2pU6fay65fvy5JCgkJ0fHjxzVixAj/djoA3c37efDgwerXr5+Cg4PtZaNHj1ZDQ4Pa2toUGhrq1z4HorsZ56VLl8rj8ejHP/6xJOmBBx7QlStX9JOf/ERLlizRN77BVSa+8FXfgyEhIRo4cKDf9sur5wehoaFKTExUeXm51/Ly8nKlpqbedJuUlJRu9WVlZV9Zj7sbZ0latWqVfvGLX2j37t1KSkrydzcDXk/HedSoUTp8+LBqa2vtx7Rp0/TII4+otrZWsbGxvdX1gHI37+exY8fq448/toOmJJ04cUKDBw8mBH2FuxnnL774olvYCQ4OlnXjhiO/9dU0X/U9mJSUpH79+vlvx369FNtgnbdnbtmyxTpy5IiVk5NjDRgwwDp9+rRlWZbl8Xi87lB4//33reDgYGvFihXW0aNHrRUrVnD7/B3o6TgXFhZaoaGh1q9+9Svr/Pnz9uPy5cv36hACQk/HuSvuGrszPR3n+vp668/+7M+sZ5991jp+/Lj1n//5n1Z0dLT18ssv36tDCAg9Heef//znVkREhLV9+3br5MmTVllZmTVixAhr+vTp9+oQAsLly5etgwcPWgcPHrQkWWvWrLEOHjxo/0zB4sWLLY/HY9d33j6/YMEC68iRI9aWLVu4fT7Qvfbaa9bQoUOt0NBQa8yYMVZFRYW9Li0tzZo1a5ZX/b/+679aI0eOtPr162eNGjXKKi4u7uUeB6aejPPQoUMtSd0eP//5z3u/4wGmp+/nLyMI3bmejnNlZaWVnJxsORwOa/jw4dYrr7xitbe393KvA09PxvnatWvWsmXLrBEjRlhhYWFWbGysNXfuXKupqeke9Dxw/O53v7vp523n2M6aNctKS0vz2ua9996zHnzwQSs0NNQaNmyYtXHjRr/3M8iymNcDAABm4hohAABgLIIQAAAwFkEIAAAYiyAEAACMRRACAADGIggBAABjEYQAAICxCEIAAMBYBCEAAGAsghAAADAWQQgAABiLIAQAAIz1/wC8fLWIElIuYAAAAABJRU5ErkJggg==",
"text/plain": [
"Figure(PyObject