text:
### A Pluto.jl notebook ###
# v0.16.1

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ 22821822-1b9f-11ec-33d8-e589cf58d1ac
using Plots

# ╔═╡ bf662a28-373b-4e4b-b8e8-b19be85b671b
using PlutoUI

# ╔═╡ 8092bfb1-f042-43ed-86fc-a9815ccfb555
using Accessors

# ╔═╡ 74589c68-0428-48e2-82bd-6bde8ff3def2
md"""
# Izhikevich model with dopamine support

These equations model GABAergic *medium spiny interneurons* in the direct- and indirect pathways of the basal ganglia.

### Original Iz. equations:

$C\dot{v} = k(v-v_r)(v-v_t)-u+I$

$\dot{u} = a[b(v-v_r)-u]$

$\text{if } v \ge v_{peak} \text{ then } v \leftarrow c, u \leftarrow u + d$

### Due to Humphries et al. 2009 :

$v_r \leftarrow v_r(1 + K\phi_1)$

$d \leftarrow d(1-L\phi_1)$

$k \leftarrow k(1-\alpha\phi_2)$

$I = I_{ampa} + B(v)I_{nmda} + I_{gaba}$

$I_z = \bar{g_z}h_z(E_z-v)$

$\dot{h_z} = \frac{-h_z}{\tau_z}$

$h_z(t) \leftarrow \frac{h_z(t)+S_z(t)}{\tau_z}$

$z \in [nmda, ampa, gaba]$

$B(v) = \frac{1}{1 + \frac{[Mg^{2+}]_0}{3.57}exp(-0.062v)}$

$I^{D1}_{nmda} = I_{nmda}(1+\beta_1\phi_1)$

$I^{D2}_{ampa} = I_{ampa}(1-\beta_2\phi_2)$

* where $\phi_1$ is proportion of activated D1 receptors;
* and $\alpha$ parameterises size of appropriate reduction in $k$ to get the required f-I curve
* and $K$ is K+ current constant, $L$ is Ca2+ current constant (L-current)
* and $\bar{g_z}$ is maximum conductance
* and $E_z$ is reversal potential (?)
* and $\tau_z$ is synaptic time constant
* and $S_z(t)$
"""

# ╔═╡ 553cb9c7-2cf7-4fac-8cce-e16231e37ae6

# ╔═╡ ece420a5-0dee-4f2b-b154-4c5a8a9c7a76
function f_vr(v_r, d1, K)
	return v_r * (1 + K * d1)
end

# ╔═╡ 990c7dff-88da-46a1-a899-ae8ee0cd1366
function f_d(d, d1, L)
	return d * (1-L*d1)
end

# ╔═╡ 43a9a3e2-81b2-40e5-8622-b27bf88e5675
function f_k(k, d2, alpha)
	return k*(1-alpha*d2)
end

# ╔═╡ 9be7e945-6d91-4fd7-8bbe-2250e550bab0

# ╔═╡ f073c8ca-9918-4a41-adde-3becab1302ae
# update nmda current based on D1 activation
function f_ID1nmda(Inmda, d1, beta1)
	return Inmda * (1 + beta1 * d1)
end

# ╔═╡ dde99a00-db75-47ce-a835-1b18c74e2999
# update ampa current based on D2 activation
function f_ID2ampa(Iampa, d2, beta2)
	return Iampa * (1 - beta2 * d2)
end

# ╔═╡ 85802bb3-0684-40bc-a46a-1347ac3cbabb
#
# h ?
#

# ╔═╡ 9cae35bf-f3e5-4975-92c8-dcd0fa7dc6b7
function f_h(h_prev, sum_spikes, tau)
	return (h_prev + sum_spikes)/tau
end

# ╔═╡ 5ae88d5b-ee7b-4a40-8440-0eb59e610b27
#
# currents
#

# ╔═╡ 80c336df-b6c0-4791-a961-e96f437d961a
md"""
## Part-equation test
"""

# ╔═╡ 6467cfd6-d748-410c-9183-7f455482e317
data = Float16[]

# ╔═╡ c110f3f4-1f4e-4ea5-a774-390da7305e89
vtst = -50

# ╔═╡ 66d3d066-4e8f-429d-8d10-b83e13185623

# ╔═╡ 590fd0e9-7586-4e2b-9017-857a8bde87e8
md"""
# Constants
"""

# ╔═╡ 854e80d2-5f71-4c24-aa32-b1240feee027
md"""
Tuning results from Humphries 2009:
1. c C = 15.2
2. c $v_t$ = -29.7
3. c d = 91
4. c K = 0.0289
5. c L = 0.331
6. c $\alpha$ = 0.032
7. c $g_{ampa}$ = 6.9
7. c $g_{nmda}$ = 6.9 * 0.5
7. c $g_{gaba}$ = 6.9 / 1.4
8. c $\beta_1 = 6.3$
9. c $\beta_2 = 0.215$

"""

# ╔═╡ f744d017-5f8a-486c-a204-a5f9ba1e4e90
"""
# values from Iz model
begin
	const c_a = 0.1
	const c_b = 0.2
	const c_c = -65.0
	# const c_d = 8.0

	const c_thrs = 30.0
	const i_v = -65.0
	const i_u = -14.0
	const dt = 0.1
end
"""

# ╔═╡ 77040227-ebb1-4688-a617-f31fdb12c80a
# values from Humphries 2009, medium spiny neuron
begin
	const c_msn_a = 0.01
	const c_msn_b = -20
	const c_msn_c = -55.0
	const c_msn_thrs = 30.0

	const i_msn_v = -65.0
	const i_msn_u = -14.0

	const c_msn_k = 1
	const c_msn_vr = -80
	const c_msn_vpeak = 40
	const c_msn_Eampa = 0
	const c_msn_Enmda = 0
	const c_msn_Egaba = -60
	const c_msn_tau_ampa = 6
	const c_msn_tau_nmda = 160
	const c_msn_tau_gaba = 4
	const c_msn_Mg = 1

	const c_dt = 0.1
end

# ╔═╡ 73c30789-adba-45cd-b032-0df3bcf2279d
# Tuning results from Humphries 2009, medium spiny neuron
begin
    const c_msn_C = 15.2
	const c_msn_vt = -29.7
	const c_msn_d = 91
	const c_msn_K = 0.0289
	const c_msn_L = 0.331
	const c_msn_alpha = 0.032
	const c_msn_g_ampa = 6.9
	const c_msn_g_nmda = 0.5 * c_msn_g_ampa
	const c_msn_g_gaba = c_msn_g_ampa / 1.4
	const c_msn_beta_1 = 6.3
	const c_msn_beta_2 = 0.215
end

# ╔═╡ a78a41c7-c7d7-4fa2-954a-fc632008ee49
struct Iz_NeuronParameter
	c_a::Float16
	c_b::Float16
	c_c::Float16
	c_d::Float16
	c_thrs::Float16
	i_v::Float16
	i_u::Float16
end

# ╔═╡ b69a9769-0178-440b-809b-ca49918fdd9a
struct Hum_NeuronParameter
	c_iz::Iz_NeuronParameter

    c_k::Float16
	c_vr::Float16
	c_vpeak::Float16
	c_Eampa::Float16
	c_Enmda::Float16
	c_Egaba::Float16
	c_tau_ampa::Float16
	c_tau_nmda::Float16
	c_tau_gaba::Float16
	c_Mg::Float16

	c_C::Float16
	c_vt::Float16
	c_d::Float16
	c_K::Float16
	c_L::Float16
	c_alpha::Float16
	c_g_ampa::Float16
	c_g_nmda::Float16
	c_g_gaba::Float16
	c_beta_1::Float16
	c_beta_2::Float16
end

# ╔═╡ bc37bffc-b3f0-4014-982e-83d86c2c0a58
md"""
## Container for neural state
"""

# ╔═╡ cbd1b4a3-3246-4fa7-a248-f1ddf55395c7
struct NeuronState
	v::Float16 # voltage
	u::Float16 # feedback current
	a::Float16 #
	b::Float16 #
	c::Float16 #
	d::Float16 #
	d1::Float16 # proportion of D1 activation
	d2::Float16 # proportion of D2 activation

	h_ampa::Float16 # ampa current via spike count
	h_nmda::Float16
	h_gaba::Float16
end

# ╔═╡ dac654bd-9f19-42ca-9e9b-b444b2fbaa2d
md"""
## Neuronal computations
"""

# ╔═╡ df6382d8-3550-4937-95fb-50fc8aef341b
md"""
### Humphries dopamine modifications
"""

# ╔═╡ 46f92f9e-6ed3-43cc-881d-ed6c311e0f90
function f_B(v)
	return 1/(1+1/3.57 * exp(-0.062*v))
end

# ╔═╡ 5b935650-40bf-4ecd-ad6c-04b04acf5e51
# calculate total input current
function f_Itot(Iampa, Inmda, Igaba, v)
	return Iampa + f_B(v)*Inmda + Igaba
end

# ╔═╡ 2ca7f1cd-6ecf-4b61-8c90-83de6f7cec91
begin
	#data = Float16[]
	empty!(data)
	inp = range(-50,stop=50,length=100)

	for i in inp
		tmp = f_B(i)
		append!(data, tmp)
	end
	plot(inp, data, title="B(v)")
end

# ╔═╡ dfed20ee-7190-4dcd-a673-91924f356c3e
md"""
### Iz original
"""

# ╔═╡ ef55479b-b347-4fc7-a085-b2d726459907
function f_v(st, i, dt)
	v = st.v
	u = st.u
	return (0.04 * v * v + 5 * v + 140 - u + i) * dt
end

# ╔═╡ 8522a885-5e2f-448d-a336-64c1955a9cf3

# ╔═╡ ee249c45-d6cb-4ce8-9a64-87b1fcdf188f
function step(st, I, dt, c_thrs)
	ret_v = 0
	ret_u = 0
	if st.v >= c_thrs
		ret_v = st.c
		ret_u = st.u + st.d
	else
		dv = f_v(st, I, dt)
		du = f_u(st, dt)
		ret_v = st.v + dv
		ret_u = st.u + du
	end

	return NeuronState(ret_v, ret_u, st.a, st.b, st.c, st.d, st.d1, st.d2)

end

# ╔═╡ 868ec52d-856d-4324-b854-bbaf244e0c57
# access lenses for parameters
begin
	ln_a = @optic _.c_iz.c_a
	ln_b = @optic _.c_iz.c_b
	ln_thr = @optic _.c_iz.c_thrs
	ln_c = @optic _.c_iz.c_c
	ln_d = @optic _.c_iz.c_d
	ln_C = @optic _.c_C
	ln_k = @optic _.c_k
	ln_vr = @optic _.c_vr
	ln_vt = @optic _.c_vt
	ln_beta1 = @optic _.c_beta_1
	ln_beta2 = @optic _.c_beta_2
	ln_L = @optic _.c_L

	# assembling currents from conductance, spike inputs
	ln_Eampa = @optic _.c_Eampa
	ln_Enmda = @optic _.c_Enmda
	ln_Egaba = @optic _.c_Egaba
	ln_tau_ampa = @optic _.c_tau_ampa
	ln_tau_nmda = @optic _.c_tau_nmda
	ln_tau_gaba = @optic _.c_tau_gaba
	ln_g_ampa = @optic _.c_g_ampa
	ln_g_nmda = @optic _.c_g_nmda
	ln_g_gaba = @optic _.c_g_gaba
end

# ╔═╡ cd20e2ae-25e3-473f-9c9b-b005229c3c95
function f_h_ampa(h_ampa_prev, sum_ampa, params)
	return f_h(h_ampa_prev, sum_ampa, ln_tau_ampa(params))
end

# ╔═╡ c4253b6d-b02b-4d8c-873e-62f19551c007
function f_h_nmda(h_nmda_prev, sum_nmda, params)
	return f_h(h_nmda_prev, sum_nmda, ln_tau_nmda(params))
end

# ╔═╡ 16793c73-f437-402f-b326-d75a5d58d2b4
function f_h_gaba(h_gaba_prev, sum_gaba, params)
	return f_h(h_gaba_prev, sum_gaba, ln_tau_gaba(params))
end

# ╔═╡ 87a28783-cb8a-4c18-82ee-1aa7ea6cca2c
function f_I_ampa(h_ampa, v, params)
	return ln_g_ampa(params) * h_ampa * (ln_Eampa(params) - v)
end

# ╔═╡ 5f19bd11-fdb5-4fb9-98cb-7bdb63d3369f
function f_I_nmda(h_nmda, v, params)
	return ln_g_nmda(params) * h_nmda * (ln_Enmda(params) - v)
end

# ╔═╡ 2fba3958-2c5c-4539-a527-f44d0766e630
function f_I_gaba(h_gaba, v, params)
	return ln_g_gaba(params) * h_gaba * (ln_Egaba(params) - v)
end

# ╔═╡ 3996ad3b-5fcb-481c-8945-a38a68210088
function f_v_dopa(st, i, dt, params)
	v = st.v
	u = st.u
	C = ln_C(params)
	k = ln_k(params)
	vr = ln_vr(params)
	vt = ln_vt(params)
	return (k*(v-vr)*(v-vt) - u + i)*dt/C
end

# ╔═╡ 24f338ea-f4cb-45e1-b83b-c902f1bb64f9
function f_u_dopa(st, dt, params)
	v = st.v
	u = st.u
	a = ln_a(params)
	b = ln_b(params)
	vr = ln_vr(params)
	return a * (b * (v-vr) - u) * dt
end

# ╔═╡ 8ddc2629-b4a3-4aa1-a72b-002365ce703d

function step_dopa(st, Iampa, Inmda, Igaba, params)
	ret_v = 0
	ret_u = 0
	ret_d = st.d
	ret_hampa = st.h_ampa
	ret_hnmda = st.h_nmda
	ret_hgaba = st.h_gaba
	if st.v >= ln_thr(params)
		ret_v = ln_c(params)
		ret_d = f_d(ret_d, st.d1, ln_L(params))  # update also d
		# println("ret_d ", ret_d)
		ret_u = st.u + ret_d
	else
		# TODO update currents with h-functions
		hampa = f_h_ampa(st.h_ampa, Iampa, params)
		hnmda = f_h_nmda(st.h_nmda, Inmda, params)
		# println("hnmda ", hnmda)
		hgaba = f_h_gaba(st.h_gaba, Igaba, params)

		ampa_pre = f_I_ampa(hampa, st.v, params)
		# println("ampapre ", ampa_pre)
		nmda_pre = f_I_nmda(hnmda, st.v, params)
		# println("nmdapre ", nmda_pre)
		gaba_pre = f_I_gaba(hgaba, st.v, params)

		# update currents dept on dopa
		i_ampa = f_ID2ampa(ampa_pre, st.d2, ln_beta2(params))
		# println("i_ampa ", i_ampa)
		i_nmda = f_ID1nmda(nmda_pre, st.d1, ln_beta1(params))
		# println("i_nmda ", i_nmda)
		Itot = f_Itot(i_ampa, i_nmda, gaba_pre, st.v)

		# update h current values
		dhampa = (-hampa/ln_tau_ampa(params))*c_dt
		dhnmda = (-hnmda/ln_tau_nmda(params))*c_dt
		dhgaba = (-hgaba/ln_tau_gaba(params))*c_dt
		dv = f_v_dopa(st, Itot, c_dt, params)
		du = f_u_dopa(st, c_dt, params)

		ret_hampa = hampa + dhampa
		ret_hnmda = hnmda + dhnmda
		ret_hgaba = hgaba + dhgaba
		ret_v = st.v + dv
		ret_u = st.u + du
		# println()
	end
	# TODO update h_ values
	return NeuronState(ret_v, ret_u, st.a, st.b, st.c, ret_d, st.d1, st.d2, ret_hampa, ret_hnmda, ret_hgaba)

end

# ╔═╡ 9a0d0774-5134-4643-a4a6-2c7fb1842907
function injcur(a, t, mn, mx)
	return a * (mn < t < mx)
end

# ╔═╡ 6458986b-4b15-4998-aa96-36384379798e
md"""
# Simulation
"""

# ╔═╡ 00aae887-d1ea-4edf-b5e7-0c755b78d972
begin
	#ampl = 100.0 # amplify input current
	i_v=-65 # initial voltage
	i_u=-14 # initial u
end

# ╔═╡ 18fa260b-4789-487e-b279-b0b8c38753db
begin
	vlt = Float16[]
	ampa_data = Float16[]
	nmda_data = Float16[]
	gaba_data = Float16[]
end

# ╔═╡ 51038af2-38bb-4aef-b8d9-a6a3861d056f
injcurdata = Float16[]

# ╔═╡ cae7f940-b184-4a4c-8ee0-9f3a77f94271
# TODO: set up state and msn params; test

# ╔═╡ 21449dfe-196b-42a7-98f6-ccb747521daf
msn_params = Hum_NeuronParameter(
	Iz_NeuronParameter(
		c_msn_a,
		c_msn_b,
		c_msn_c,
		c_msn_d,
		c_msn_thrs,
		i_msn_v,
		i_msn_u),
	c_msn_k,
	c_msn_vr,
	c_msn_vpeak,
	c_msn_Eampa ,
	c_msn_Enmda ,
	c_msn_Egaba,
	c_msn_tau_ampa ,
	c_msn_tau_nmda,
	c_msn_tau_gaba ,
	c_msn_Mg,
	c_msn_C,
	c_msn_vt,
	c_msn_d,
	c_msn_K,
	c_msn_L,
	c_msn_alpha,
	c_msn_g_ampa,
	c_msn_g_nmda,
	c_msn_g_gaba,
	c_msn_beta_1,
	c_msn_beta_2)

# ╔═╡ fd7d426a-a0e4-4ed9-a916-f09209e3042b
d1_ui = @bind d1_val Slider(0:100)

# ╔═╡ dc193a59-7f70-48b2-8a60-0fb872283625
d1_val

# ╔═╡ e696e625-943f-431f-9776-339420f3db91
d2_ui = @bind d2_val Slider(0:100)

# ╔═╡ 532843c0-4dd2-49ab-9fe6-a5865d1d42a0
ampl_ui = @bind ampl Slider(-30:1530)

# ╔═╡ 477d77f2-8626-439a-8087-569e88f0f5ae
ampl

# ╔═╡ fc02eb71-f9fc-4d39-83c4-defa3f8fe613
ampa_ui = @bind ampa_frac Slider(0:100)

# ╔═╡ 46ce7229-e3fa-469e-820d-157cf9ef9d4a
ampa_frac

# ╔═╡ 5188c442-4205-46cc-8396-ef664b11f9b8
nmda_ui = @bind nmda_frac Slider(0:100)

# ╔═╡ 02f8b97a-0f6f-4daa-8fd6-e94f2dcb8875
nmda_frac

# ╔═╡ 759ee2c9-d2cc-4f21-a140-a1e0308892d8
gaba_ui = @bind gaba_frac Slider(0:100)

# ╔═╡ 7931cec0-610e-4836-b2b8-5fcc20d31b34
gaba_frac

# ╔═╡ 7013902a-b421-4abb-a1f2-df3fe58a62a1
state = NeuronState(i_v, i_u, 0.0, 0.0, 0.0, ln_d(msn_params), d1_val/100.0, d2_val/100.0, 10.9, 0.9, 0.9)

# ╔═╡ f7c89ffc-8230-4853-bbb3-d4287682e32a
f_v_dopa(state, 30, c_dt, msn_params)

# ╔═╡ 1901353b-62bd-4328-a6f3-13460c7a770d
begin
	ampl_ampa = ampl * ampa_frac/100.0
	ampl_nmda = ampl * nmda_frac/100.0
	ampl_gaba = -ampl * gaba_frac/100.0
end

# ╔═╡ c95d2ef5-eee1-4286-9702-e40c3282b5ae
begin
	empty!(vlt)
	empty!(ampa_data)
	empty!(nmda_data)
	empty!(gaba_data)
	nst = state
	for i in 2:500
		# push!(steps, step(steps[i-1], injcur(i), dt))
		i_ampa = injcur(ampl_ampa, i, 100, 130)
		i_nmda = injcur(ampl_nmda, i, 0, 200)
		i_gaba = injcur(ampl_gaba, i, 120, 130)
		push!(ampa_data, i_ampa)
		push!(nmda_data, i_nmda)
		push!(gaba_data, i_gaba)

		tmp = step_dopa(
			nst,
			i_ampa,
			i_nmda,
			i_gaba,
			msn_params)
		push!(vlt, tmp.v)
		nst = tmp
		#push!(injcurdata, injcur(ampl, i))
		# push!(plt, state.v)
		# push!(vlt, steps[i].v)
		# println(state.v)
	end
end

# ╔═╡ be927f12-e945-4aed-965a-62c0691ad23f
md"""
# Plots
"""

# ╔═╡ 007a14b3-583f-4df6-8ef4-eab29b882641
begin
	plot(vlt, title="Voltage", label="neuron")
	plot!(ampa_data, label="AMPA")
	plot!(nmda_data, label="NMDA")
	plot!(gaba_data, label="GABA")
	#plot!(injcurdata, title="Injection")
	#display(p1)
	#display(p2)
end

# ╔═╡ 215cfb07-96bb-4267-938a-efce8b90153a
md"""
# Test
"""

# ╔═╡ 8b3614b1-17d5-462e-a3a0-eb14df11dccc
st = NeuronState(i_v, i_u, c_a, c_b, c_c, c_d, 0.8, 0.8)

# ╔═╡ 7b4b5f56-3316-4ae5-b53d-4d588bda7975
f_v(st, 30, 1)

# ╔═╡ 7886a63b-928a-42a2-a4f5-bfd920eeb2ce
f_u(st, 1)

# ╔═╡ e9282a6f-3239-4e9c-b11e-e6d68aefde2d
st_b = step(st, 30, 1)

# ╔═╡ 2497e93a-3a45-46ac-a3b4-076047bb8c80
md"""
## References

* Humphries et al 2009 - Capturing dopaminergic modulation and bimodal membrane behaviour of striatal medium spiny neurons in accurate, reduced models

"""

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"

[compat]
Accessors = "~0.1.4"
Plots = "~1.22.1"
PlutoUI = "~0.7.10"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[Accessors]]
deps = ["Compat", "CompositionsBase", "ConstructionBase", "Future", "LinearAlgebra", "MacroTools", "Requires", "Test"]
git-tree-sha1 = "ba270110280297b36d566cb19c948e6c724432c0"
uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
version = "0.1.4"

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "84918055d15b3114ede17ac6a7182f68870c16f7"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.1"

[[ArgTools]]
git-tree-sha1 = "bdf73eec6a88885256f282d48eafcad25d7de494"
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
version = "1.1.1"

[[Artifacts]]
deps = ["Pkg"]
git-tree-sha1 = "c30985d8821e0cd73870b17b0ed0ce6dc44cb744"
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
version = "1.3.0"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c3598e525718abcc440f69cc6d5f60dda0a1b61e"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.6+5"

[[Cairo_jll]]
deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "e2f47f6d8337369411569fd45ae5753ca10394c6"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.0+6"

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "9995eb3977fbf67b86d0a0a0508e83017ded03f2"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.14.0"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "1a90210acd935f222ea19657f143004d2c2a1117"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.38.0"

[[CompilerSupportLibraries_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "8e695f735fca77e9708e795eda62afdb869cbb70"
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
version = "0.3.4+0"

[[CompositionsBase]]
git-tree-sha1 = "455419f7e328a1a2493cabc6428d79e951349769"
uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
version = "0.1.1"

[[ConstructionBase]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f74e9d5388b8620b4cee35d4c5a618dd4dc547f4"
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
version = "1.3.0"

[[Contour]]
deps = ["StaticArrays"]
git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
version = "0.5.7"

[[DataAPI]]
git-tree-sha1 = "cc70b17275652eb47bc9e5f81635981f13cea5c8"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.9.0"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "7d9d316f04214f7efdbb6398d545446e246eff02"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.10"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
git-tree-sha1 = "135bf1896be424235eadb17474b2a78331567f08"
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
version = "1.5.1"

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "92d8f9f208637e8d2d28c664051a00569c01493d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.1.5+1"

[[Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "1402e52fcda25064f51c77a9655ce8680b76acf0"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.2.7+6"

[[FFMPEG]]
deps = ["FFMPEG_jll"]
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8"
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
version = "0.4.1"

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "LibVPX_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
git-tree-sha1 = "3cc57ad0a213808473eafef4845a74766242e05f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.3.1+4"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "35895cf184ceaab11fd778b4590144034a167a2f"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.1+14"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "cbd58c9deb1d304f5a245a0b7eb841a2560cfec6"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.1+5"

[[FriBidi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "0d20aed5b14dd4c9a2453c1b601d08e1149679cc"
uuid = "559328eb-81f9-559d-9380-de523a88c83c"
version = "1.0.5+6"

[[Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "a199aefead29c3c2638c3571a9993b564109d45a"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.4+0"

[[GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "c2178cfbc0a5a552e16d097fae508f2024de61a3"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.59.0"

[[GR_jll]]
deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt5Base_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "d59e8320c2747553788e4fc42231489cc602fa50"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.58.1+0"

[[GeometryBasics]]
deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
git-tree-sha1 = "58bcdf5ebc057b085e58d95c138725628dd7453c"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
version = "0.4.1"

[[Gettext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "8c14294a079216000a0bdca5ec5a447f073ddc9d"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.20.1+7"

[[Glib_jll]]
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "04690cc5008b38ecbdfede949220bc7d9ba26397"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.59.0+4"

[[Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
version = "1.0.2"

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "Logging", "MbedTLS", "NetworkOptions", "Sockets", "URIs"]
git-tree-sha1 = "60ed5f1643927479f845b0135bb369b031b541fa"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.14"

[[HypertextLiteral]]
git-tree-sha1 = "72053798e1be56026b81d4e2682dbe58922e5ec9"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.0"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.0"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.3.0"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "8076680b162ada2a031f707ac7b4953e30667a37"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.2"

[[JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9aff0587d9603ea0de2c6f6300d9f9492bbefbd3"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.0.1+3"

[[LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "df381151e871f41ee86cee4f5f6fd598b8a68826"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.0+3"

[[LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f128cd6cd05ffd6d3df0523ed99b90ff6f9b349a"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.0+3"

[[LaTeXStrings]]
git-tree-sha1 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.1"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "a4b12a1bd2ebade87891ab7e36fdbce582301a92"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.15.6"

[[LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
git-tree-sha1 = "cdbe7465ab7b52358804713a53c7fe1dac3f8a3f"
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"
version = "0.6.3"

[[LibCURL_jll]]
deps = ["LibSSH2_jll", "Libdl", "MbedTLS_jll", "Pkg", "Zlib_jll", "nghttp2_jll"]
git-tree-sha1 = "897d962c20031e6012bba7b3dcb7a667170dad17"
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"
version = "7.70.0+2"

[[LibGit2]]
deps = ["Printf"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibSSH2_jll]]
deps = ["Libdl", "MbedTLS_jll", "Pkg"]
git-tree-sha1 = "717705533148132e5466f2924b9a3657b16158e8"
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
version = "1.9.0+3"

[[LibVPX_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "85fcc80c3052be96619affa2fe2e6d2da3908e11"
uuid = "dd192d2f-8180-539f-9fb4-cc70b1dcf69a"
version = "1.9.0+1"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "a2cd088a88c0d37eef7d209fd3d8712febce0d90"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.1+4"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "b391a18ab1170a2e568f9fb8d83bc7c780cb9999"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.5+4"

[[Libglvnd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
version = "1.3.0+3"

[[Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ec7f2e8ad5c9fa99fc773376cdbc86d9a5a23cb7"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.36.0+3"

[[Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "cba7b560fcc00f8cd770fa85a498cbc1d63ff618"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.0+8"

[[Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51ad0c01c94c1ce48d5cad629425035ad030bfd5"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.34.0+3"

[[Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "291dd857901f94d683973cdf679984cdf73b56d0"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.1.0+2"

[[Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f879ae9edbaa2c74c922e8b85bb83cc84ea1450b"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.34.0+7"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "5a5bc6bf062f0f95e62d0fe0a2d99699fed82dd9"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.8"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.0.3"

[[MbedTLS_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "0eef589dd1c26a3ac9d753fe1a8bcad63f956fa6"
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
version = "2.16.8+1"

[[Measures]]
git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.1"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.2"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[MozillaCACerts_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f1662575f7bf53c73c2bbc763bace4b024de822c"
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"
version = "2021.1.19+0"

[[NaNMath]]
git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.5"

[[NetworkOptions]]
git-tree-sha1 = "ed3157f48a05543cce9b241e1f2815f7e843d96e"
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
version = "1.2.0"

[[Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "a42c0f138b9ebe8b58eba2271c5053773bde52d0"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.4+2"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "71bbbc616a1d710879f5a1021bcba65ffba6ce58"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.1+6"

[[Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f9d57f4126c39565e05a2b0264df99f497fc6f37"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.1+3"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "1b556ad51dceefdbf30e86ffa8f528b73c7df2bb"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.42.0+4"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "438d35d2d95ae2c5e8780b330592b6de8494e779"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.0.3"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6a20a83c1ae86416f0a5de605eaea08a552844a3"
uuid = "30392449-352a-5448-841d-b1acce4e97dc"
version = "0.40.0+0"

[[Pkg]]
deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PlotThemes]]
deps = ["PlotUtils", "Requires", "Statistics"]
git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
version = "2.0.1"

[[PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
git-tree-sha1 = "2537ed3c0ed5e03896927187f5f2ee6a4ab342db"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.14"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"]
git-tree-sha1 = "4c2637482176b1c2fb99af4d83cb2ff0328fc33c"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.22.1"

[[PlutoUI]]
deps = ["Base64", "Dates", "HypertextLiteral", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "Suppressor"]
git-tree-sha1 = "26b4d16873562469a0a1e6ae41d90dec9e51286d"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.10"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.2"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[Qt5Base_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"]
git-tree-sha1 = "16626cfabbf7206d60d84f2bf4725af7b37d4a77"
uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1"
version = "5.15.2+0"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RecipesBase]]
git-tree-sha1 = "44a75aa7a527910ee3d1751d1f0e4148698add9e"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.1.2"

[[RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "7ad0dfa8d03b7bcf8c597f59f5292801730c55b8"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.4.1"

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.1.0"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[Showoff]]
deps = ["Dates", "Grisu"]
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de"
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
version = "1.0.3"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3240808c6d463ac46f1c1cd7638375cd22abbccb"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.12"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

[[StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "8cbbc098554648c84f79a463c9ff0fd277144b6c"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.10"

[[StructArrays]]
deps = ["Adapt", "DataAPI", "StaticArrays", "Tables"]
git-tree-sha1 = "2ce41e0d042c60ecd131e9fb7154a3bfadbf50d3"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.6.3"

[[Suppressor]]
git-tree-sha1 = "a819d77f31f83e5792a76081eee1ea6342ab8787"
uuid = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
version = "0.2.0"

[[TOML]]
deps = ["Dates"]
git-tree-sha1 = "44aaac2d2aec4a850302f9aa69127c74f0c3787e"
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
version = "1.0.3"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "1162ce4a6c4b7e31e0e6b14486a6986951c73be9"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.5.2"

[[Test]]
deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[URIs]]
git-tree-sha1 = "97bbe755a53fe859669cd907f2d96aee8d2c1355"
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
version = "1.3.0"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "dc643a9b774da1c2781413fd7b6dcd2c56bb8056"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.17.0+4"

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

[[XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "be0db24f70aae7e2b89f2f3092e93b8606d659a6"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.10+3"

[[XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "2b3eac39df218762d2d005702d601cd44c997497"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.33+4"

[[Xorg_libX11_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
version = "1.6.9+4"

[[Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.9+4"

[[Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
version = "1.2.0+4"

[[Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.3+4"

[[Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
version = "1.3.4+4"

[[Xorg_libXfixes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
version = "5.0.3+4"

[[Xorg_libXi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
version = "1.7.10+4"

[[Xorg_libXinerama_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
version = "1.1.4+4"

[[Xorg_libXrandr_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
version = "1.5.2+4"

[[Xorg_libXrender_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
version = "0.9.10+4"

[[Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.0+3"

[[Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
version = "1.13.0+3"

[[Xorg_libxkbfile_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
version = "1.1.0+4"

[[Xorg_xcb_util_image_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
version = "0.4.0+1"

[[Xorg_xcb_util_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
version = "0.4.0+1"

[[Xorg_xcb_util_keysyms_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
version = "0.4.0+1"

[[Xorg_xcb_util_renderutil_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
version = "0.3.9+1"

[[Xorg_xcb_util_wm_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
version = "0.4.1+1"

[[Xorg_xkbcomp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
version = "1.4.2+4"

[[Xorg_xkeyboard_config_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
uuid = "33bec58e-1273-512f-9401-5d533626f822"
version = "2.27.0+4"

[[Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.4.0+3"

[[Zlib_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "320228915c8debb12cb434c59057290f0834dbf6"
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
version = "1.2.11+18"

[[Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "2c1332c54931e83f8f94d310fa447fd743e8d600"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.4.8+0"

[[libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "acc685bcf777b2202a904cdcb49ad34c2fa1880c"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.14.0+4"

[[libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7a5780a0d9c6864184b3a2eeeb833a0c871f00ab"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "0.1.6+4"

[[libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "6abbc424248097d69c0c87ba50fcb0753f93e0ee"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.37+6"

[[libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "fa14ac25af7a4b8a7f61b287a124df7aab601bcd"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.6+6"

[[nghttp2_jll]]
deps = ["Libdl", "Pkg"]
git-tree-sha1 = "8e2c44ab4d49ad9518f359ed8b62f83ba8beede4"
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
version = "1.40.0+2"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d713c1ce4deac133e3334ee12f4adff07f81778f"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2020.7.14+2"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "487da2f8f2f0c8ee0e83f39d13037d6bbf0a45ab"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.0.0+3"

[[xkbcommon_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
version = "0.9.1+5"
"""

# ╔═╡ Cell order:
# ╠═22821822-1b9f-11ec-33d8-e589cf58d1ac
# ╠═bf662a28-373b-4e4b-b8e8-b19be85b671b
# ╠═8092bfb1-f042-43ed-86fc-a9815ccfb555
# ╟─74589c68-0428-48e2-82bd-6bde8ff3def2
# ╠═553cb9c7-2cf7-4fac-8cce-e16231e37ae6
# ╠═ece420a5-0dee-4f2b-b154-4c5a8a9c7a76
# ╠═990c7dff-88da-46a1-a899-ae8ee0cd1366
# ╠═43a9a3e2-81b2-40e5-8622-b27bf88e5675
# ╠═9be7e945-6d91-4fd7-8bbe-2250e550bab0
# ╠═f073c8ca-9918-4a41-adde-3becab1302ae
# ╠═dde99a00-db75-47ce-a835-1b18c74e2999
# ╠═5b935650-40bf-4ecd-ad6c-04b04acf5e51
# ╠═85802bb3-0684-40bc-a46a-1347ac3cbabb
# ╠═9cae35bf-f3e5-4975-92c8-dcd0fa7dc6b7
# ╠═cd20e2ae-25e3-473f-9c9b-b005229c3c95
# ╠═c4253b6d-b02b-4d8c-873e-62f19551c007
# ╠═16793c73-f437-402f-b326-d75a5d58d2b4
# ╠═5ae88d5b-ee7b-4a40-8440-0eb59e610b27
# ╠═87a28783-cb8a-4c18-82ee-1aa7ea6cca2c
# ╠═5f19bd11-fdb5-4fb9-98cb-7bdb63d3369f
# ╠═2fba3958-2c5c-4539-a527-f44d0766e630
# ╟─80c336df-b6c0-4791-a961-e96f437d961a
# ╠═6467cfd6-d748-410c-9183-7f455482e317
# ╠═c110f3f4-1f4e-4ea5-a774-390da7305e89
# ╠═66d3d066-4e8f-429d-8d10-b83e13185623
# ╟─590fd0e9-7586-4e2b-9017-857a8bde87e8
# ╟─854e80d2-5f71-4c24-aa32-b1240feee027
# ╟─f744d017-5f8a-486c-a204-a5f9ba1e4e90
# ╠═77040227-ebb1-4688-a617-f31fdb12c80a
# ╠═73c30789-adba-45cd-b032-0df3bcf2279d
# ╠═a78a41c7-c7d7-4fa2-954a-fc632008ee49
# ╠═b69a9769-0178-440b-809b-ca49918fdd9a
# ╟─bc37bffc-b3f0-4014-982e-83d86c2c0a58
# ╠═cbd1b4a3-3246-4fa7-a248-f1ddf55395c7
# ╟─dac654bd-9f19-42ca-9e9b-b444b2fbaa2d
# ╟─df6382d8-3550-4937-95fb-50fc8aef341b
# ╠═46f92f9e-6ed3-43cc-881d-ed6c311e0f90
# ╠═2ca7f1cd-6ecf-4b61-8c90-83de6f7cec91
# ╟─dfed20ee-7190-4dcd-a673-91924f356c3e
# ╠═ef55479b-b347-4fc7-a085-b2d726459907
# ╠═3996ad3b-5fcb-481c-8945-a38a68210088
# ╠═f7c89ffc-8230-4853-bbb3-d4287682e32a
# ╠═24f338ea-f4cb-45e1-b83b-c902f1bb64f9
# ╠═8522a885-5e2f-448d-a336-64c1955a9cf3
# ╠═ee249c45-d6cb-4ce8-9a64-87b1fcdf188f
# ╠═868ec52d-856d-4324-b854-bbaf244e0c57
# ╠═8ddc2629-b4a3-4aa1-a72b-002365ce703d
# ╠═9a0d0774-5134-4643-a4a6-2c7fb1842907
# ╟─6458986b-4b15-4998-aa96-36384379798e
# ╠═00aae887-d1ea-4edf-b5e7-0c755b78d972
# ╠═18fa260b-4789-487e-b279-b0b8c38753db
# ╠═51038af2-38bb-4aef-b8d9-a6a3861d056f
# ╠═cae7f940-b184-4a4c-8ee0-9f3a77f94271
# ╠═21449dfe-196b-42a7-98f6-ccb747521daf
# ╠═fd7d426a-a0e4-4ed9-a916-f09209e3042b
# ╠═dc193a59-7f70-48b2-8a60-0fb872283625
# ╠═e696e625-943f-431f-9776-339420f3db91
# ╠═532843c0-4dd2-49ab-9fe6-a5865d1d42a0
# ╠═477d77f2-8626-439a-8087-569e88f0f5ae
# ╠═fc02eb71-f9fc-4d39-83c4-defa3f8fe613
# ╠═46ce7229-e3fa-469e-820d-157cf9ef9d4a
# ╠═5188c442-4205-46cc-8396-ef664b11f9b8
# ╠═02f8b97a-0f6f-4daa-8fd6-e94f2dcb8875
# ╠═759ee2c9-d2cc-4f21-a140-a1e0308892d8
# ╠═7931cec0-610e-4836-b2b8-5fcc20d31b34
# ╠═7013902a-b421-4abb-a1f2-df3fe58a62a1
# ╠═1901353b-62bd-4328-a6f3-13460c7a770d
# ╠═c95d2ef5-eee1-4286-9702-e40c3282b5ae
# ╟─be927f12-e945-4aed-965a-62c0691ad23f
# ╠═007a14b3-583f-4df6-8ef4-eab29b882641
# ╟─215cfb07-96bb-4267-938a-efce8b90153a
# ╠═8b3614b1-17d5-462e-a3a0-eb14df11dccc
# ╠═7b4b5f56-3316-4ae5-b53d-4d588bda7975
# ╠═7886a63b-928a-42a2-a4f5-bfd920eeb2ce
# ╠═e9282a6f-3239-4e9c-b11e-e6d68aefde2d
# ╠═2497e93a-3a45-46ac-a3b4-076047bb8c80
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


text:
test = """
    nop +0
    acc +1
    jmp +4
    acc +3
    jmp -3
    acc -99
    acc +1
    jmp -4
    acc +6
    """

function parse_program(prog::AbstractString)::Vector
    return split(prog, "\n"; keepempty = false) .|> parse_cmd
end

function parse_cmd(cmd::AbstractString)::Tuple
    (opc, adr) = split(cmd, " ")
    return (getfield(@__MODULE__, Symbol(opc)), parse(Int, adr))
end

struct State
    ip::Int
    acc::Int
end

State() = State(1, 0)

step(prog::AbstractVector, state::State) = step(prog[state.ip], state)
step((opc, adr), state::State) = opc(state, adr)

nop(state::State, adr::Int)::State = State(state.ip + 1, state.acc)
acc(state::State, adr::Int)::State = State(state.ip + 1, state.acc + adr)
jmp(state::State, adr::Int)::State = State(state.ip + adr, state.acc)

function run(prog::AbstractVector)::Tuple
    len = length(prog)
    visited = fill(false, len)
    state = State()
    while state.ip <= len && !visited[state.ip]
        visited[state.ip] = true
        state = step(prog, state)
    end
    return (state.ip > len, state.acc)
end

function swap(prog::V, i::Int)::V where {V <: AbstractVector}
    swp((opc, arg)) = (opc == nop ? jmp : nop, arg)
    return [prog[1:i - 1]; swp(prog[i]); prog[i + 1:end]]
end

function q2(prog::AbstractVector)::Int
    for i in 1:length(prog)
        prog[i][1] != acc || continue
        (ok, a) = run(swap(prog, i))
        ok && return a
    end
end

let prog = parse_program(test)
    @assert run(prog) == (false, 5)
    @assert q2(prog) == 8
end

prog = parse_program(read("day08.in", String))
println("Q1: ", run(prog) |> last)
println("Q2: ", q2(prog))

ext: jl

max_stars_repo_name: dhanak/competitive-coding

max_issues_repo_name: dhanak/competitive-coding

max_forks_repo_name: dhanak/competitive-coding


text:
using DashBootstrapComponents

number_input = html_div(
    [
        html_p("Type a number outside the range 0-10"),
        dbc_input(type = "number", min = 0, max = 10, step = 1),
    ],
    id = "styled-numeric-input",
);

max_issues_repo_name: sthagen/dash-bootstrap-components

max_forks_repo_name: sthagen/dash-bootstrap-components


text:
# This file was generated, do not modify it. # hide
fit!(rfr_m, rows=train);


text:
# syntax: proto3
using ProtoBuf
import ProtoBuf.meta
import ._ProtoBuf_Top_.tensorflow
import ._ProtoBuf_Top_.xla

mutable struct DeviceAssignment_ComputationDevice_DeviceMeshCoordinates <: ProtoType
    value::Base.Vector{Int32}
    DeviceAssignment_ComputationDevice_DeviceMeshCoordinates(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct DeviceAssignment_ComputationDevice_DeviceMeshCoordinates
const __pack_DeviceAssignment_ComputationDevice_DeviceMeshCoordinates = Symbol[:value]
meta(t::Type{DeviceAssignment_ComputationDevice_DeviceMeshCoordinates}) = meta(t, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, true, __pack_DeviceAssignment_ComputationDevice_DeviceMeshCoordinates, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES, ProtoBuf.DEF_FIELD_TYPES)

mutable struct DeviceAssignment_ComputationDevice <: ProtoType
    replica_devices::Base.Vector{DeviceAssignment_ComputationDevice_DeviceMeshCoordinates}
    DeviceAssignment_ComputationDevice(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct DeviceAssignment_ComputationDevice

mutable struct DeviceAssignment <: ProtoType
    computation_devices::Base.Vector{DeviceAssignment_ComputationDevice}
    DeviceAssignment(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct DeviceAssignment

mutable struct XLAComputationConfig <: ProtoType
    num_replicas::Int32
    num_cores_per_replica::Int32
    host_compute_metadata::tensorflow.tf2xla.HostComputeMetadata
    program_shape::xla.ProgramShapeProto
    per_core_program_shape::Base.Vector{xla.ProgramShapeProto}
    device_assignment::DeviceAssignment
    debug_options::xla.DebugOptions
    XLAComputationConfig(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct XLAComputationConfig

mutable struct XLAComputation <: ProtoType
    config::XLAComputationConfig
    hlo_snapshot::xla.HloSnapshot
    XLAComputation(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct XLAComputation

mutable struct XLAAllocation <: ProtoType
    device_ordinal::Int32
    value::xla.LiteralProto
    XLAAllocation(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct XLAAllocation

mutable struct XLATupleNode <: ProtoType
    input_index::Int32
    release_input_handle::Bool
    tuples::Base.Vector{XLATupleNode}
    XLATupleNode(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct XLATupleNode

mutable struct XRTExecutionConfig <: ProtoType
    device_ordinal::Int32
    core_index_in_replica::Int32
    execution_instance_key::AbstractString
    rng_seed::UInt32
    release_input_handles::Bool
    release_compilation_handle::Bool
    return_exploded_tuple::Bool
    XRTExecutionConfig(; kwargs...) = (o=new(); fillunset(o); isempty(kwargs) || ProtoBuf._protobuild(o, kwargs); o)
end #mutable struct XRTExecutionConfig

export DeviceAssignment_ComputationDevice_DeviceMeshCoordinates, DeviceAssignment_ComputationDevice, DeviceAssignment, XLAComputationConfig, XLAComputation, XLAAllocation, XLATupleNode, XRTExecutionConfig


text:
using IterativeSolvers

""" Convex Factorization Machine with Hazan's algorithm (squared loss)
    Yamada, M. et. al., http://arxiv.org/abs/1507.01073

Model:

f(x;w,W) = w^t z + 0.5 trace(W (xx^t - diag(x.*x)))

Parameters
----------

num_iter: int
   The number of iteration for Hazan's algorithm: (default: 100)

reg_W: double
   The regularization parameter for interaction term (2-way factors) (default 100)

w: double
   d + 1 dimensional vector the global bias (w[0]) and user-item bias (w[1:])

U: double
   d by T dimensional matrix such that W = U U^t

"""
mutable struct CFM
  num_iter::Int64
  reg_W::Float64
  w::Array{Float64, 1}
  U::Array{Float64, 2}

  CFM(num_iter, reg_W) = new(num_iter, reg_W, Float64[], Array{Float64}(0,0))
end

function train(model::CFM, X, Y)
  X = convert(SparseMatrixCSC{Float64,Int64}, X)
  Y = Array(Y)

  n, d = size(X)

  #Add bias for training data
  Z = hcat(ones(n), X)

  T = model.num_iter
  η = model.reg_W

  model.U = zeros(d, T)
  P = zeros(d, T)
  λ = ones(T)
  w = zeros(d+1, 1)
  global fval = zeros(T)

  for t in 1:T
    tmp = X * model.U[:, 1:t]
    fQ = 0.5 * (vec(sum(tmp .* tmp, 2)) - (X .* X) * vec(sum(model.U[:, 1:t] .* model.U[:, 1:t], 2)))

    ZY = Z' * (Y - fQ)

    #Conjugate Gradient: Solve Zw = Y
    wout = cg!(w, Z'*Z, ZY, tol=1e-6, verbose = false, maxiter=100)
    model.w = vec(wout)

    tr_err = Y - (Z*model.w + fQ)

    #Frank-Wolfe update: eigs(X diag(tr_err) X^t, 1)
    pout = eigs(X'*spdiagm(sparsevec(tr_err))*X, nev=1, which=:LR, maxiter = 300, tol = 1e-1)[2]

    p = vec(real(pout))

    #Optimal step size
    err = η*((X*p).^2 - (X .* X) * (p .* p)) - fQ
    α = ((tr_err' * err) / (err' * err))

    #Update
    P[:, t] = √η * p
    λ[1:t-1] = (1 - α) * λ[1:t-1]
    λ[t] = max(1e-10, α)

    model.U[:, 1:t] = P[:, 1:t] .* sqrt.(λ[1:t])'

    #Traning RMSE
    global fval[t] = sqrt(mean(tr_err.^2))

    #fval: training RMSE
    println("iteration:", t, " Training RMSE:", fval[t])

		tmp = nothing
		fQ = nothing
		ZY = nothing
		wout = nothing
		tr_err = nothing
		pout = nothing
		p = nothing
		err = nothing
		α= nothing
	end
end

function predicter(model::CFM, X)
  X = convert(SparseMatrixCSC{Float64,Int64}, X)

  #Compute fQ (2-way factor)
  tmp = X * model.U
  fQ = 0.5 * (sum(tmp .* tmp, 2) - (X .* X) * sum(model.U .* model.U, 2))

  Ŷ = model.w[1] + X * model.w[2:end] + fQ

  return Ŷ
end


text:
function read_dtf(file_path::String)::DataFrames.DataFrame
    """
    Helper function that allows you to read DTF files into a DataFrame.
    The DataFrame can then be used to reconstruct the orderbook.

    Argument Descriptions:

    `file_path::String` : Relative path to file.
    """
    FLAG_EMPTY = 0b00000000
    FLAG_IS_BID = 0b00000001
    FLAG_IS_TRADE = 0b00000010
    MAGIC_VALUE = [0x44, 0x54, 0x46, 0x90, 0x01]
    RECORD_OFFSET = 96

    dtf_file = open(file_path, "r")
    dtf_bytes = UInt8[]
    # Read bytes into a buffer
    readbytes!(dtf_file, dtf_bytes, Inf)
    close(dtf_file)

    # We will store our resulting data points in this dataframe and return it
    df = DataFrames.DataFrame(ts = Float64[], seq = UInt64[], is_trade = Bool[], is_bid = Bool[], price = Float64[], volume = Float64[])

    # File metadata
    symbol = String(collect(Char, dtf_bytes[6:25]))
    n_records = parse(UInt64, bytes2hex(dtf_bytes[26:33]), base=16)
    max_ts = parse(UInt64, bytes2hex(dtf_bytes[34:41]), base=16)

    # We will have regular updates of these values in order to calculate date and seq values
    # from a dataset that has limited precision for storage space purposes.
    ref_ts = parse(UInt64, bytes2hex(dtf_bytes[82:89]), base=16)
    ref_seq = parse(UInt32, bytes2hex(dtf_bytes[90:93]), base=16)
    next_record = parse(UInt16, bytes2hex(dtf_bytes[94:95]), base=16)

    if dtf_bytes[1:5] != MAGIC_VALUE
        throw(ArgumentError("File $(file_path) is not a valid DTF file"))
    end

    println("Symbol: $(symbol)\n, n_records: $(n_records)\n, max_ts: $(max_ts)\n, ref_ts: $(ref_ts)\n, ref_seq: $(ref_seq)\n, next_record: $(next_record)\n")
    #return

    x = RECORD_OFFSET
    i = 1

    while true
        # Set to x + 11 so that we don't skip a record by accident at the end of the file
        if length(dtf_bytes) < x + 11
            break
        end

        # Check if we've passed our `next_record` count and the current byte is a metadata indicator
        if next_record < i && dtf_bytes[x] == 0x01
            ref_ts = parse(UInt64, bytes2hex(dtf_bytes[x+1:x+8]), base=16)
            ref_seq = parse(UInt32, bytes2hex(dtf_bytes[x+9:x+12]), base=16)
            next_record = parse(UInt16, bytes2hex(dtf_bytes[x+13:x+14]), base=16)

            # Reset record count
            i = 1
            # Jump to the next record available
            x = x + 15
        end

        push!(df, [
                # timestamp
                (ref_ts + parse(UInt16, bytes2hex(dtf_bytes[x:x+1]), base=16)) * 0.001,
                # seq count
                ref_seq + dtf_bytes[x+2], # seq count
                # is trade
                (dtf_bytes[x+3] & FLAG_IS_TRADE) == FLAG_IS_TRADE,
                # is bid
                (dtf_bytes[x+3] & FLAG_IS_BID) == FLAG_IS_BID,

                # Reverse the bytes to convert them into little endian before parsing the int bytes as a float
                # Hacky way to convert Float32 into Float64 values accurately
                # ----------------------
                # price
                parse(Float64, string(reinterpret(Float32, reverse(dtf_bytes[x+4:x+7]))[1])),
                # size
                parse(Float64, string(reinterpret(Float32, reverse(dtf_bytes[x+8:x+11]))[1])),
        ])

        i = i + 1
        # 12 bytes per row. Jumps to the next row
        x = x + 12
    end

    # Sort timestamp in Float format before converting to DateTime
    sort!(df, (:ts));
    # Set :ts field equal to DateTimes
    df[:ts] = Dates.unix2datetime.(df[:ts]);

    return df
end


text:
using QCMaterial
using PyCall
using LinearAlgebra
using HDF5
import Random
import PyCall: pyimport

#make taus list file.h5
#length=8
function taus_list(file_name)
    x = Float64[]
    for i in 1:10
        tau = 0.005*(i-1) + exp((0.1*(i-1))) -1
        push!(x,tau)
    end
    fid = h5open(file_name,"w")
    fid["/test/data"] = x
    close(fid)
end

function taus_list(file_name2)
    x = Float64[]
    for i in 1:10
        tau = 0.005*(i-1) + exp((0.1*(i-1))) -1
        push!(x,tau)
    end
    fid = h5open(file_name,"w")
    fid["/test/data2"] = x
    close(fid)
end

#read taus list file.h5
function read_taus_list(file_name)
    fid = h5open(file_name,"r")
    x = fid["/test/data"][:]
    y = fid["/test/data2"][:]
    close(fid)
    return x
end

#read taus list file.txt
function read_and_parse_float(file_name)
    x = zeros(Float64, 0)
    open(file_name, "r") do fp
        num_elm = parse(Int64,readline(fp))
        for i in 1:num_elm
            push!(x, parse(Float64, readline(fp)))
        end
    end
    return x
end

function hev(n_qubit, depth)
    circuit = QulacsParametricQuantumCircuit(n_qubit)
    for d in 1:depth
        for i in 1:n_qubit
            add_parametric_RY_gate!(circuit, i, 0.0)
            add_parametric_RZ_gate!(circuit, i, 0.0)
        end
        for i in 1:n_qubit÷2
            add_CNOT_gate!(circuit, 2*i-1, 2*i)
        end
        for i in 1:n_qubit÷2-1
            add_CNOT_gate!(circuit, 2*i, 2*i+1)
        end
    end
    for i in 1:n_qubit
        add_parametric_RY_gate!(circuit, i, 0.0)
        add_parametric_RZ_gate!(circuit, i, 0.0)
    end
    circuit = QulacsVariationalQuantumCircuit(circuit)
    circuit
end

nsite = 2
n_qubit = 2 * nsite
U = 1.0
V = 1.0
μ = U/2
ε = 1.0
d_theta = 1e-5
verbose = QCMaterial.MPI_rank == 0
Random.seed!(100)

#Hamiltonian
ham_op = generate_impurity_ham_with_1imp_multibath(U, V, μ, ε, nsite)

n_electron_gs = 2
@assert mod(n_electron_gs, 2) == 0
sparse_mat = get_number_preserving_sparse_operator(ham_op, n_qubit, n_electron_gs);
enes_ed = eigvals(sparse_mat.toarray());
println("Ground_enegry_ED=", minimum(enes_ed))
#N+1系のground energy
#n_electron_ex = 3
#sparse_mat_ex = get_number_preserving_sparse_operator(ham_op, n_qubit, n_electron_ex);
#enes_ex_ed = eigvals(sparse_mat_ex.toarray());

#debug
#N = particle number
#println("Ground energy_2_ED=",minimum(enes_ed))
#println("Ground_enegry_3_ED=", minimum(enes_ex_ed))

#1 system
#n_electron_1 = 1
#sparse_mat_enum_1 = get_number_preserving_sparse_operator(ham_op, n_qubit, n_electron_1);
#enes_ed_enum_1 = eigvals(sparse_mat_enum_1.toarray());
#debug
#println("Ground energy_ED=",minimum(enes_ed_enum_1))
#println("Ground energy_1_ED=",minimum(enes_ed_enum_1))

#1 system
#n_electron_4 = 4
#sparse_mat_enum_4 = get_number_preserving_sparse_operator(ham_op, n_qubit, n_electron_4);
#enes_ed_enum_4 = eigvals(sparse_mat_enum_4.toarray());
#debug
#println("Ground energy_ED=",minimum(enes_ed_enum_1))
#println("Ground energy_4_ED=",minimum(enes_ed_enum_4))

#ansatz
state0 = create_hf_state(n_qubit, n_electron_gs)
vc = uccgsd(n_qubit, nocc = 1, orbital_rot=true, uccgsd = true, p_uccgsd = false)
#depth = n_qubit
#vc = hev(n_qubit, depth )
theta_init = rand(num_theta(vc))

#Perform VQE
cost_history, thetas_opt =
QCMaterial.solve_gs(jordan_wigner(ham_op), vc, state0, theta_init=theta_init, verbose=true,
    comm=QCMaterial.MPI_COMM_WORLD
)

#debug
println("Ground energy_VQE=",cost_history[end])

#c^{dag},c
up1 = up_index(1)
down1 = down_index(1)
up2 = up_index(2)
down2 = down_index(2)

if ARGS[1] == "plus_true"
    right_op = FermionOperator("$(up1)^ ", 1.0)
    right_op = jordan_wigner(right_op)
    left_op = FermionOperator("$(up1) ", 1.0)
    left_op = jordan_wigner(left_op)

    n_electron_ex = 3

    sign = 1
end

if ARGS[2] == "minus_true"
    right_op = FermionOperator("$(up1) ", 1.0)
    right_op = jordan_wigner(right_op)
    left_op = FermionOperator("$(up1)^ ", 1.0)
    left_op = jordan_wigner(left_op)

    n_electron_ex = 1

    sign = -1
end

vc_ex = uccgsd(n_qubit, nocc = 1, orbital_rot = true, uccgsd = true, p_uccgsd = false)
#vc_ex = hev(n_qubit, depth )
state_gs = create_hf_state(n_qubit, n_electron_gs)
update_circuit_param!(vc, thetas_opt)
update_quantum_state!(vc, state_gs)

state0_ex = create_hf_state(n_qubit, n_electron_ex)

#taus = collect(range(0.0, 0.02, length = 2))

#make taus list file
#taus_list("dimer_plus.h5")
#generate taus list file
#taus = read_taus_list("dimer_plus.h5")
#println("taus=",taus)

taus = read_and_parse_float(ARGS[3])
println("taus=",taus)

Gfunc_ij_list, norm =  compute_gtau(
    jordan_wigner(ham_op),
    left_op,
    right_op,
    vc_ex,
    state_gs,
    state0_ex,
    taus,
    d_theta,
    verbose = verbose,
    algorithm = "vqs",
    recursive = true
)

Gfunc_ij_list *= sign

println("Gfunc_ij_list_plus=", Gfunc_ij_list)
println("norm=", norm)

function write_to_txt(file_name, x, y)
    open(file_name, "w") do fp
        for i = 1:length(x)
            println(fp, x[i], " ", real(y[i]))
        end
    end
end

function write_to_txt_(file_name, x, y)
    open(file_name, "w") do fp
        for i = 1:length(x)
            println(fp, 1000-x[i], " ", -real(y[i]))
        end
    end
end

write_to_txt("gf_dimer_plus_shotnoise1000_proc1_relative_thetadot.txt", taus, Gfunc_ij_list)
write_to_txt("dimer_plus_vqs_norm__relativeerr_1000_thetadot.txt", taus, norm)
#write_to_txt_("gf_dimer_recurisive_direct_minus3_freq.txt", taus, Gfunc_ij_list)
println("done!!")

max_stars_repo_name: Sakurairihito/QCMaterialNew

max_issues_repo_name: sakurairihito/QCMaterialNew

max_forks_repo_name: sakurairihito/QCMaterialNew


text:
#!/usr/bin/julia

# Trizen
# 27 March 2016
# https://github.com/trizen

# Generate a random Julia set as a PNG image.

# See also:
#    https://en.wikipedia.org/wiki/Julia_set

using Images

@inline function hsv2rgb(h, s, v)
    c = v * s
    x = c * (1 - abs(((h/60) % 2) - 1))
    m = v - c

    if h < 60
        r,g,b = (c, x, 0)
    elseif h < 120
        r,g,b = (x, c, 0)
    elseif h < 180
        r,g,b = (0, c, x)
    elseif h < 240
        r,g,b = (0, x, c)
    elseif h < 300
        r,g,b = (x, 0, c)
    else
        r,g,b = (c, 0, x)
    end

    (r + m), (b + m), (g + m)
end

function julia_set()

    w, h = 1000, 1000

    zoom  = 0.5       # the zoom factor
    moveX = 0         # the amount of shift on the x axis
    moveY = 0         # the amount of shift on the y axis

    L = 2             # the maximum value of |z|
    I = 30            # the maximum number of iterations

    img = zeros(RGB{Float64}, h, w)
    c = Complex(-rand(), 2 * rand() * (rand() < 0.5 ? 1 : -1))

    for x in 1:w, y in 1:h
        n = 0
        z = Complex(
            (2*x - w) / (w * zoom) + moveX,
            (2*y - h) / (h * zoom) + moveY
        )
        while abs(z) < L && (n += 1) < I
            z = z^2 + c
        end
        v = (I - n) / I
        r,g,b = hsv2rgb(v*360, 1, v)
        img[y,x] = RGB{Float64}(r, g, b)
    end

    println("Generating image...")
    save("$c-$zoom.png", img)
end

julia_set()

max_stars_repo_name: trizen/julia-scripts

max_issues_repo_name: trizen/julia-scripts

max_forks_repo_name: trizen/julia-scripts


text:
using Statistics

#=
Linear regression

Note: var() and cov() use corrected=true (1/(N-1) rather than 1/N) by default.

Reference: `Data Analysis: A Bayesian Tutorial` by D. Sivia, Section 3.5.1
=#
function linreg(;x,y,dy=0)
    if dy==0 # dy is NOT provided
        m = cov(x,y)/var(x)
        c = mean(y) - m*mean(x)
        N = length(x)
        S2 = (N-1)/(N-2)*var(m*x .+ c .- y)
        dm = sqrt(S2/N/var(x,corrected=false))
        dc = sqrt(S2*mean(x.^2)/N/var(x,corrected=false))

    else # dy is provided
        α = sum(x.^2 ./ dy.^2)
        β = sum(1    ./ dy.^2)
        γ = sum(x    ./ dy.^2)
        p = sum(x.*y ./ dy.^2)
        q = sum(y    ./ dy.^2)

        denom = α*β - γ^2
        m = (β*p - γ*q)/denom
        c = (α*q - γ*p)/denom
        dm = sqrt(β/denom)
        dc = sqrt(α/denom)
    end

    return m, c, dm, dc
end


text:
function nthsmallest(arr::Array{T,1}, pos::Integer)::T where T <: Number
    sort(arr)[pos]
end

max_stars_repo_name: UlrichBerntien/Codewars-Katas

max_issues_repo_name: UlrichBerntien/Codewars-Katas

max_forks_repo_name: UlrichBerntien/Codewars-Katas


text:
export setSlowDAC, getSlowADC, slowDACClockDivider

function setSlowDAC(rp::RedPitaya, channel, value)
  command = string("RP:PDM:CHannel", Int64(channel), ":NextValueVolt ", value)
  send(rp, command)
end

function getSlowADC(rp::RedPitaya, channel)
  command = string("RP:XADC:CHannel", Int64(channel), "?")
  query(rp, command, Float64)
end

slowDACClockDivider(rp::RedPitaya) = query(rp,"RP:PDM:ClockDivider?", Int64)
function slowDACClockDivider(rp::RedPitaya, value)
  command = string("RP:PDM:ClockDivider ", Int32(value))
  send(rp, command)
end


text:
##### Beginning of file

Test.@test( isdir(PredictMDFull.package_directory()) )

Test.@test( isdir(PredictMDFull.package_directory("ci")) )

Test.@test( isdir(PredictMDFull.package_directory("ci", "travis")) )

Test.@test( isdir(PredictMDFull.package_directory(TestModuleA)) )

Test.@test( isdir(PredictMDFull.package_directory(TestModuleB)) )

Test.@test( isdir( PredictMDFull.package_directory(
            TestModuleB, "directory2",
            ) ) )

Test.@test( isdir( PredictMDFull.package_directory(
            TestModuleB, "directory2", "directory3",
            ) ) )

Test.@test_throws(
    ErrorException,
    PredictMDFull.package_directory(TestModuleC),
    )

##### End of file


text:
# ---------------------------- fit_1c_local ---------------------------------------
# Function to conduct non-linear least squares curve fitting for each pixel
# in a one-color SAIM image stack
# Images sequences should be saved as a tif stack
# Sequences should be organized as (λ1₁...λ1ₙ) where n indicates the
# nth and last angle; λ1ᵢ is the ith image acquired with the excitation
# wavelength
# INPUTS:
# name: A string that stores base file name of tif stack
# file_ext: file extension for iumage stack; Only ".tif" has been tested so far
# optic: Optical struct containing parameters for the excitation wavelength
# angles: 1D array containing incidence angles in radians for the acquisition
# 	sequence
# init_params: Intial parameters, [Aₒ, Bₒ, Hₒ]
# lower_bounds: Lower bounds for [A, B, H]
# upper_bounds: Lower bounds for [A, B, H]
# show: When true, a heatmap for the fit heights will be displayed
# OUTPUTS: 1) Heatmap with fitted heights; 2) 16-bit image image with intensities
# proportional to best-fit pixel height -  Pixel intensity = 100*height in nm;
# 3) JLD file with results for each pixel - Fields are "A," "B,"  "H,"
# and "errors"; errors are the standard errors for fit [A, B, H]
function fit_1c_local(file_path::String, file_name::String, optic::SAIMOptics, angles::AbstractArray,
	init_params::AbstractArray, lower_bounds::AbstractArray, upper_bounds::AbstractArray, disp::Bool=false)

	#Calculate the optical model constants for each image frame angle
	constants = calculate_constants_1c(optic, angles)

	#------------- OPEN IMAGE STACK AND INITIALIZE CONTAINERS -------------
	file = file_path*"\\"*file_name*".tif"
	#Open an image
	img1_HWC = load(file);						#image stored as height X width X channels
	img_CHW = permutedims(img1_HWC, (3, 1, 2))  		#image stored as channels X height X width; CHW indexing more memory friendly
	channels = channelview(float64.(img_CHW))*65535; 	#Each channel corresponds to a specific excitation angle
	rows = size(channels,2)  							#Image size is (number channels X rows X cols)
	cols = size(channels,3)								#Image size is (number channels X rows X cols)

	#Initialize container to store the fitted heights and fitting results
	fit_params = Array{Float64}(undef, rows, cols, 3)
	fit_errors = fill(-1.0, rows, cols, 3)

	#-------------- CONDUCT THE FITTING ----------------------
	println("Conducting fit for ", file_name)  #Threads.@threads
	counter = 0
	@time Threads.@threads for i = 1:rows
		for j = 1:cols
			ydata = channels[:,i,j]

			result = curve_fit(model_1c, jacobian_model_1c, constants, ydata,
				init_params, lower=lower_bounds, upper=upper_bounds)

			fit_params[i,j,:] = coef(result)

			#Calculate the standard errors for the fitted parameters
			try
           		fit_errors[i,j,:] = stderror(result)
       		catch e
           		counter = counter + 1
       		end
		end
	end
	println("  ", (rows*cols - counter), " out of ", (rows*cols), " pixels fit within bounds")

	#-------------- GENERATE THE OUTPUTS ----------------------
	println("Generating outputs for ", file_name)

	#Make an output directory if needed
	dir = file_path*"\\output\\"*file_name

	if !isdir(file_path*"\\output")
		mkdir(file_path*"\\output")
	end

	if !isdir(dir)
		mkdir(dir)
	end

	#Save height information in a 16-bit image; Pixel intensity = 100*height in nm
	save(File(format"PNG", dir*"\\"*file_name*"_H.png"), n0f16.((fit_params[:,:,3]/1000.)*(100000. / 65535.)))

	#Save the fit information as a JLD file (includes fit parameters, errors, and metadata)
	save(File(format"JLD", dir*"\\"*file_name*"_results.jld"),"A", fit_params[:,:,1], "B",
		fit_params[:,:,2], "H",fit_params[:,:,3], "errors", fit_errors,
		"constants", constants, "angles", angles, "ip", init_params,
		"lb", lower_bounds, "ub", upper_bounds, "optic",
		optic, "type", "one-color local")

	#Save the fit parameters and height standard err as CSV files
	if !isdir(dir*"\\CSV")
		mkdir(dir*"\\CSV")
	end
	CSV.write(dir*"\\CSV\\"*file_name*"_A.csv",  DataFrame(fit_params[:,:,1]), writeheader=false)
	CSV.write(dir*"\\CSV\\"*file_name*"_B.csv",  DataFrame(fit_params[:,:,2]), writeheader=false)
	CSV.write(dir*"\\CSV\\"*file_name*"_H.csv",  DataFrame(fit_params[:,:,3]), writeheader=false)
	CSV.write(dir*"\\CSV\\"*file_name*"_H_sterr.csv",  DataFrame(fit_errors[:,:,3]), writeheader=false)

	#Construct a height map and save
	hm = heatmap(fit_params[:,:,3], yflip=true, colorbar_title="height (nm)",
		color=:RdYlBu_10, aspect_ratio=:equal, xaxis = (nothing, false),
		 yaxis = (nothing, false))
	ylims!((1,rows))
	xlims!((1,cols))

	savefig(hm, dir*"\\"*file_name*"_Hmap.pdf")
	println("  Completed ", file_name)
	println()
	if disp
		display(hm)
	end
end

# ---------------------------- fit_1c_global ----------------------------------
# Function to conduct global non-linear least squares curve fitting for each
# pixel in a one-color SAIM image stack
# Executes a simple grid search, stepping through initial guesses for H; search
# is conducted along H from lower_bounds to upper_bounds
# Images sequences should be saved as a tif stack
# Sequences should be organized as (λ1₁...λ1ₙ) where n indicates the
# nth and last angle; λ1ᵢ is the ith image acquired with the excitation
# wavelength
# INPUTS:
# name: A string that stores base file name of tif stack
# file_ext: file extension for iumage stack; Only ".tif" has been tested so far
# optic: Optical struct containing parameters for the excitation wavelength
# angles: 1D array containing incidence angles in radians for the acquisition
# sequence
# init_params: Intial parameters, [Aₒ, Bₒ]
# lower_bounds: Lower bounds for [A, B, H]
# upper_bounds: Lower bounds for [A, B, H]
# step: Step size for initial guesses for H in grid search
# show: When true, a heatmap for the fit heights will be displayed
# OUTPUTS: 1) Heatmap with fitted heights; 2) 16-bit image image with intensities
# proportional to best-fit pixel height -  Pixel intensity = 100*height in nm;
# 3) JLD file with results for each pixel - Fields are "A," "B,"  "H,"
# and "errors"; errors are the standard errors for fit [A, B, H]
function fit_1c_global(file_path::String, file_name::String, optic::SAIMOptics, angles::AbstractArray,
	init_params::AbstractArray, lower_bounds::AbstractArray, upper_bounds::AbstractArray,
	step::Float64=40., disp::Bool=false)

	#Calculate the optical model constants for each image frame angle
	constants = calculate_constants_1c(optic, angles)

	#------------- OPEN IMAGE STACK AND INITIALIZE CONTAINERS -------------
	file = file_path*"\\"*file_name*".tif"
	#Open an image
	img1_HWC = load(file);						#image stored as height X width X channels
	img_CHW = permutedims(img1_HWC, (3, 1, 2))  		#image stored as channels X height X width; CHW indexing more memory friendly
	channels = channelview(float64.(img_CHW))*65535; 	#Each channel corresponds to a specific excitation angle
	rows = size(channels,2)  							#Image size is (number channels X rows X cols)
	cols = size(channels,3)								#Image size is (number channels X rows X cols)

	#Initialize container to store the fitted heights and fitting results
	fit_params = fill(0.0, rows, cols, 3)
	fit_errors = fill(-1.0, rows, cols, 3)

	#-------------- CONDUCT THE FITTING ----------------------
	println("Conducting fit for ", file_name)  #Threads.@threads
	guesses = collect( lower_bounds[3]:step:upper_bounds[3] )		#initial guesses for heights
	params = Array{Float64}(undef, 3)
	params[1] = init_params[1]
	params[2] = init_params[2]

	@time Threads.@threads for i = 1:rows
		for j = 1:cols
			ydata = channels[:,i,j]
			err_lo = 1.0e10				#Set arbitrarily high
			#Global fitting routine - grid search
			for Hₒ in guesses
				params[3] = Hₒ
				result = curve_fit(model_1c, jacobian_model_1c, constants, ydata,
					params, lower=lower_bounds, upper=upper_bounds)
				#Calculate the standard errors for the fitted parameters
				if result.converged
					try
						err = stderror(result)
						if err[3] < err_lo
							fit_params[i,j,:] = coef(result)
							fit_errors[i,j,:] = err
							err_lo = err[3]
						end
					catch e
					end
				end
			end
		end
	end

	#-------------- GENERATE THE OUTPUTS ----------------------
	println("Generating outputs for ", file_name)

	#Make an output directory if needed
	dir = file_path*"\\output\\"*file_name

	if !isdir(file_path*"\\output")
		mkdir(file_path*"\\output")
	end

	if !isdir(dir)
		mkdir(dir)
	end

	#Save height information in a 16-bit image; Pixel intensity = 100*height in nm
	save(File(format"PNG", dir*"\\"*file_name*"_H.png"), n0f16.((fit_params[:,:,3]/1000.)*(100000. / 65535.)))

	#Save the fit information as a JLD file (includes fit parameters, errors, and metadata)
	save(File(format"JLD", dir*"\\"*file_name*"_results.jld"),"A", fit_params[:,:,1], "B",
		fit_params[:,:,2], "H",fit_params[:,:,3], "errors", fit_errors,
		"constants", constants, "angles", angles, "ip", init_params,
		"lb", lower_bounds, "ub", upper_bounds, "step", step, "optic",
		optic, "type", "one-color global")

	#Save the fit parameters and height standard err as CSV files
	if !isdir(dir*"\\CSV")
		mkdir(dir*"\\CSV")
	end
	CSV.write(dir*"\\CSV\\"*file_name*"_A.csv",  DataFrame(fit_params[:,:,1]), writeheader=false)
	CSV.write(dir*"\\CSV\\"*file_name*"_B.csv",  DataFrame(fit_params[:,:,2]), writeheader=false)
	CSV.write(dir*"\\CSV\\"*file_name*"_H.csv",  DataFrame(fit_params[:,:,3]), writeheader=false)
	CSV.write(dir*"\\CSV\\"*file_name*"_H_sterr.csv",  DataFrame(fit_errors[:,:,3]), writeheader=false)

	#Construct a height map and save
	hm = heatmap(fit_params[:,:,3], yflip=true, colorbar_title="height (nm)",
		color=:RdYlBu_10, aspect_ratio=:equal, xaxis = (nothing, false),
		 yaxis = (nothing, false))
	ylims!((1,rows))
	xlims!((1,cols))
	savefig(hm, dir*"\\"*file_name*"_Hmap.pdf")
	println("  Completed ", file_name)
	println()
	if disp
		display(hm)
	end

end

# ------------------------ calculate_constants_1c -----------------------------
# Function that returns constants for calculating Fresnel coefficients (real
# and imag components) and phase constants in one-color SAIM fitting routines
# INPUTS:
# optic: Optical struct containing parameters for the excitation wavelength
# angles: 1D array containing incidence angles in radians for the acquisition
# sequence
function calculate_constants_1c(optic, angles)

	#Initialize containers for holding the constants
	constants = Array{Float64}(undef, length(angles), 3)

	wavelength = optic.λ_Ex_1	#The Excitation wavelength
	dOx = optic.dOx 			#The thickness of the SiO2 layer in units of nm
	nB = optic.nB				#The refractive index of the ambient media / cytoplasm
	nOx = optic.nOx_1			#The refractive index of SiO2
	nSi = optic.nSi_1			#The efractive index of Si

	inds = axes(angles, 1)
	for i = inds
		#Calculate the incidence angle of excitation light in each material
		θB = angles[i]						#Incidence angle in buffer
		θOx = asin(nB*sin(θB)/nOx) 			#Incidence angle in silicon oxide
		θSi = asin(nOx*sin(θOx)/nSi)		#Incidence angle in silicon

		#Calculate the Fresnesl coefficient (perpendicular components) for the layer system (Si02, Si)
		kOx = 2*pi*nOx/wavelength
		lOx = kOx*dOx*cos(θOx)
		pSi = nSi*cos(θSi)
		pOx = nOx*cos(θOx)
		pB = nB*cos(θB)

		m11TE = cos(lOx)
		m12TE = -(im/pOx)*sin(lOx)
		m21TE = -im*pOx*sin(lOx)
		m22TE = m11TE

		rTE = ((m11TE + m12TE*pSi)*pB - (m21TE + m22TE*pSi)) / ((m11TE + m12TE*pSi)*pB + (m21TE + m22TE*pSi));

		constants[i,1] = real(rTE)		#Real component of rTE
		constants[i,2] = imag(rTE)		#Imaginary compnent of rTE
		constants[i,3] = (4*pi*nB/wavelength)*cos(θB) 	#phase shift/height
	end

	return constants
end

#Optical model for one-color experiments: y = A*Pex(H,theta)+B
#p = [A, B, H]
#x[i,:] holds the optical model constants for each excitation incidence angle
function model_1c(x, p)
    y= Vector{Float64}(undef, length(x[:,1]))
    for i in eachindex(y)
		c = x[i,1]			#Real part of rTE
		d = x[i,2]			#Imaginary part of rTE
		ϕₕ = x[i,3]		#ϕₕ*H is the phase shift
		Pex = 1 + 2*c*cos(ϕₕ*p[3]) - 2*d*sin(ϕₕ*p[3]) + c*c + d*d
        y[i] = p[1]*Pex + p[2]
    end
    y
end

#Generate the analytical Jacobian for model
#p = [A, B, H]
#x[i,:] holds the optical model constants for each excitation incidence angle
function jacobian_model_1c(x,p)
    J = Array{Float64}(undef, length(x[:,1]), length(p))
    for i = 1:length(x[:,1])
		c = x[i,1]			#Real part of rTE
		d = x[i,2]			#Imaginary part of rTE
		ϕₕ = x[i,3]			#ϕₕ*H is the phase shift

        J[i,1] = 1 + 2*c*cos(ϕₕ*p[3]) - 2*d*sin(ϕₕ*p[3]) + c*c + d*d 	  	 #dmodel/dA
        J[i,2] = 1										 		#dmodel/dB
		J[i,3] = -2*p[1]*ϕₕ*(c*sin(ϕₕ*p[3]) + d*cos(ϕₕ*p[3])) 	#dmodel/dH
    end
    J
end


text:
abstract type Grid{T} end

# ******************************************************************************
# T
# ******************************************************************************
struct GridT{T} <: Grid{T}
    arch :: ARCH{T}
    # number of grid points:
    Nt :: Int
    # units:
    tu :: T
    wu :: T
    # domain size:
    tmin :: T
    tmax :: T
    # grid points:
    t :: StepRangeLen{T}
    w :: AbstractVector{T}
    # grid spacing:
    dt :: T
    # Guards:
    tguard :: T
    wguard :: T
end

function GridT(
    arch::ARCH{T}=CPU(); tu=1, tmin, tmax, Nt, tguard=0, wguard=0,
) where T
    wu = 1 / tu
    t, dt, w = _grid_rectangular(tmin, tmax, Nt)
    return GridT{T}(arch, Nt, tu, wu, tmin, tmax, t, w, dt, tguard, wguard)
end

function info(g::GridT{T}) where T
    str =
    """
    GridT{$T}:
        Nt = $(g.Nt) - resolution in t
        tu = $(g.tu) [s] - unit of t
      tmin = $(g.tmin) [tu] - left boundary of t domain
      tmax = $(g.tmax) [tu] - right boundary of t domain
        dt = $(g.dt) [tu] - t step
    tguard = $(g.tguard)
    wguard = $(g.wguard)
    """
    return str
end

# ******************************************************************************
# RT
# ******************************************************************************
struct GridRT{T} <: Grid{T}
    arch :: ARCH{T}
    # number of grid points:
    Nr :: Int
    Nt :: Int
    # units:
    ru :: T
    tu :: T
    ku :: T
    wu :: T
    # domain size:
    rmax :: T
    tmin :: T
    tmax :: T
    # Grid points:
    r :: AbstractVector{T}
    t :: StepRangeLen{T}
    k :: AbstractVector{T}
    w :: AbstractVector{T}
    # Grid spacing:
    dr :: AbstractVector{T}
    dt :: T
    # Guards:
    rguard :: T
    tguard :: T
    kguard :: T
    wguard :: T
end

function GridRT(
    arch::ARCH{T}=CPU();
    ru=1, rmax, Nr, rguard=0, kguard=90,
    tu=1, tmin, tmax, Nt, tguard=0, wguard=0,
) where T
    ku = 1 / ru
    r, dr, k = _grid_axial(rmax, Nr)

    wu = 1 / tu
    t, dt, w = _grid_rectangular(tmin, tmax, Nt)

    return GridRT{T}(
        arch, Nr, Nt, ru, tu, ku, wu, rmax, tmin, tmax, r, t, k, w, dr, dt,
        rguard, tguard, kguard, wguard,
    )
end

function info(g::GridRT{T}) where T
    dr_min = minimum(diff(g.r)) * g.ru
    dr_max = maximum(diff(g.r)) * g.ru
    dr_avg = sum(diff(g.r)) / length(diff(g.r)) * g.ru
    str =
    """
    GridRT{$T}:
        Nr = $(g.Nr) - resolution in r
        ru = $(g.ru) [m] - unit of r
      rmax = $(g.rmax) [ru] - domain in r
    dr_min = $(dr_min) [m] - minimum r step
    dr_avg = $(dr_avg) [m] - average r step
    dr_max = $(dr_max) [m] - maximum r step
    rguard = $(g.rguard) [ru]
    kguard = $(g.kguard) [deg]
        Nt = $(g.Nt) - resolution in t
        tu = $(g.tu) [s] - unit of t
      tmin = $(g.tmin) [tu] - left boundary of t domain
      tmax = $(g.tmax) [tu] - right boundary of t domain
        dt = $(g.dt) [tu] - t step
    tguard = $(g.tguard) [tu]
    wguard = $(g.wguard) [1/s]
    """
    return str
end

# ******************************************************************************
# Tools
# ******************************************************************************
function _grid_rectangular(tmin, tmax, Nt)
    # t = range(tmin, tmax, length=Nt)   # grid points

    # Exploit the fact that the Fourier transform of even real functions is
    # real. As a result, there are less noise in the corresponding spectra.
    # https://discourse.julialang.org/t/fft-function-does-not-return-the-correct-analytic-result/50644/6
    t = range(tmin, tmax, length=Nt+1)
    t = t[1:Nt]

    dt = t[2] - t[1]
    w = 2 * pi * fftfreq(Nt, 1/dt)   # angular frequency
    return t, dt, w
end

function _grid_axial(rmax, Nr)
    r = dhtcoord(rmax, Nr)
    v = dhtfreq(rmax, Nr)
    k = 2 * pi * v   # angular frequency

    # nonuniform steps:
    Nr = length(r)
    dr = zeros(Nr)
    for i=1:Nr
        dr[i] = _step(i, r)
    end
    return r, dr, k
end

"""Calculates step dx for a specific index i on a nonuniform grid x."""
function _step(i::Int, x::AbstractArray)
    Nx = length(x)
    if i == 1
        dx = x[2] - x[1]
    elseif i == Nx
        dx = x[Nx] - x[Nx - 1]
    else
        dx = (x[i+1] - x[i-1]) / 2
    end
    return dx
end


text:
using .Rewriters

let
    PLUS_RULES = [
        @rule(~x::isnotflat(+) => flatten_term(+, ~x))
        @rule(~x::needs_sorting(+) => sort_args(+, ~x))
        @ordered_acrule(~a::is_literal_number + ~b::is_literal_number => ~a + ~b)

        @acrule(*(~~x) + *(~β, ~~x) => *(1 + ~β, (~~x)...))
        @acrule(*(~α, ~~x) + *(~β, ~~x) => *(~α + ~β, (~~x)...))
        @acrule(*(~~x, ~α) + *(~~x, ~β) => *(~α + ~β, (~~x)...))

        @acrule(~x + *(~β, ~x) => *(1 + ~β, ~x))
        @acrule(*(~α::is_literal_number, ~x) + ~x => *(~α + 1, ~x))
        @rule(+(~~x::hasrepeats) => +(merge_repeats(*, ~~x)...))

        @ordered_acrule((~z::_iszero + ~x) => ~x)
        @rule(+(~x) => ~x)
    ]

    TIMES_RULES = [
        @rule(~x::isnotflat(*) => flatten_term(*, ~x))
        @rule(~x::needs_sorting(*) => sort_args(*, ~x))

        @ordered_acrule(~a::is_literal_number * ~b::is_literal_number => ~a * ~b)
        @rule(*(~~x::hasrepeats) => *(merge_repeats(^, ~~x)...))

        @acrule((~y)^(~n) * ~y => (~y)^(~n+1))
        @ordered_acrule((~x)^(~n) * (~x)^(~m) => (~x)^(~n + ~m))

        @ordered_acrule((~z::_isone  * ~x) => ~x)
        @ordered_acrule((~z::_iszero *  ~x) => ~z)
        @rule(*(~x) => ~x)
    ]

    POW_RULES = [
        @rule(^(*(~~x), ~y::_isinteger) => *(map(a->pow(a, ~y), ~~x)...))
        @rule((((~x)^(~p::_isinteger))^(~q::_isinteger)) => (~x)^((~p)*(~q)))
        @rule(^(~x, ~z::_iszero) => 1)
        @rule(^(~x, ~z::_isone) => ~x)
        @rule(inv(~x) => ~x ^ -1)
    ]

    ASSORTED_RULES = [
        @rule(identity(~x) => ~x)
        @rule(-(~x) => -1*~x)
        @rule(-(~x, ~y) => ~x + -1(~y))
        @rule(~x::_isone \ ~y => ~y)
        @rule(~x \ ~y => ~y / (~x))
        @rule(~x / ~y => ~x * pow(~y, -1))
        @rule(one(~x) => one(symtype(~x)))
        @rule(zero(~x) => zero(symtype(~x)))
        @rule(conj(~x::_isreal) => ~x)
        @rule(real(~x::_isreal) => ~x)
        @rule(imag(~x::_isreal) => zero(symtype(~x)))
        @rule(ifelse(~x::is_literal_number, ~y, ~z) => ~x ? ~y : ~z)
    ]

    TRIG_RULES = [
        @acrule(sin(~x)^2 + cos(~x)^2 => one(~x))
        @acrule(sin(~x)^2 + -1        => cos(~x)^2)
        @acrule(cos(~x)^2 + -1        => sin(~x)^2)

        @acrule(tan(~x)^2 + -1*sec(~x)^2 => one(~x))
        @acrule(tan(~x)^2 +  1 => sec(~x)^2)
        @acrule(sec(~x)^2 + -1 => tan(~x)^2)

        @acrule(cot(~x)^2 + -1*csc(~x)^2 => one(~x))
        @acrule(cot(~x)^2 +  1 => csc(~x)^2)
        @acrule(csc(~x)^2 + -1 => cot(~x)^2)
    ]

    BOOLEAN_RULES = [
        @rule((true | (~x)) => true)
        @rule(((~x) | true) => true)
        @rule((false | (~x)) => ~x)
        @rule(((~x) | false) => ~x)
        @rule((true & (~x)) => ~x)
        @rule(((~x) & true) => ~x)
        @rule((false & (~x)) => false)
        @rule(((~x) & false) => false)

        @rule(!(~x) & ~x => false)
        @rule(~x & !(~x) => false)
        @rule(!(~x) | ~x => true)
        @rule(~x | !(~x) => true)
        @rule(xor(~x, !(~x)) => true)
        @rule(xor(~x, ~x) => false)

        @rule(~x == ~x => true)
        @rule(~x != ~x => false)
        @rule(~x < ~x => false)
        @rule(~x > ~x => false)

        # simplify terms with no symbolic arguments
        # e.g. this simplifies term(isodd, 3, type=Bool)
        # or term(!, false)
        @rule((~f)(~x::is_literal_number) => (~f)(~x))
        # and this simplifies any binary comparison operator
        @rule((~f)(~x::is_literal_number, ~y::is_literal_number) => (~f)(~x, ~y))
    ]

    function number_simplifier()
        rule_tree = [If(istree, Chain(ASSORTED_RULES)),
                     If(is_operation(+),
                        Chain(PLUS_RULES)),
                     If(is_operation(*),
                        Chain(TIMES_RULES)),
                     If(is_operation(^),
                        Chain(POW_RULES))] |> RestartedChain

        rule_tree
    end

    trig_simplifier(;kw...) = Chain(TRIG_RULES)

    bool_simplifier() = Chain(BOOLEAN_RULES)

    global default_simplifier
    global serial_simplifier
    global threaded_simplifier
    global serial_simplifier
    global serial_expand_simplifier

    function default_simplifier(; kw...)
        IfElse(has_trig,
               Postwalk(IfElse(x->symtype(x) <: Number,
                               Chain((number_simplifier(),
                                      trig_simplifier())),
                               If(x->symtype(x) <: Bool,
                                  bool_simplifier()))
                        ; kw...),
               Postwalk(Chain((If(x->symtype(x) <: Number,
                                  number_simplifier()),
                               If(x->symtype(x) <: Bool,
                                  bool_simplifier())))
                        ; kw...))
    end

    # reduce overhead of simplify by defining these as constant
    serial_simplifier = If(istree, Fixpoint(default_simplifier()))

    threaded_simplifier(cutoff) = Fixpoint(default_simplifier(threaded=true,
                                                              thread_cutoff=cutoff))

    serial_expand_simplifier = If(istree,
                                  Fixpoint(Chain((expand,
                                                  Fixpoint(default_simplifier())))))

end


text:
#! /usr/bin/env julia

#version
include("version.jl")

# check for Hardware-Dimensions
!isdir("Hardware-Dimensions") && mkdir("Hardware-Dimensions")

# check for latest tag folder
!isdir("Hardware-Dimensions/v$ver") &&
download("https://github.com/FactoryOS/Hardware-Dimensions/archive/v$ver.zip",
         "Hardware-Dimensions/v$ver.zip")

@unix_only begin
    run(`unzip Hardware-Dimensions/v$ver.zip -d Hardware-Dimensions`)
    # extracted as Hardware-dimensions-x.x.x
    mv("Hardware-Dimensions/Hardware-Dimensions-$ver",
       "Hardware-Dimensions/v$ver")
end


text:
using GR
inline("iterm", false)

x = collect(0:0.01:2*pi)
for i = 1:200
    plot(x, sin(x + i / 10.0))
end


text:
#--------------------------------------------------------------------#
#     Input data used for heat and moisture transfer calculation     #
#--------------------------------------------------------------------#

#DODATI RUBNE UVJETE

#########
#Timestep if necessary#
##########

#dt=1        #Timestep in h
#T=8760      #Time domain

###########
#Mesh size#
###########

dl=0.005 #defined in m

########################
#Geometry and materials#
########################

#Elements -- matrix of vectors E_1=[material_key,x_0,y_0,x_1,y_1] to E_n

ne=6 #number of elements

E=zeros(Float64,ne,9) #Geometry and material matrix + boundary conditions

#Element 1 (XPS)
E[1,1]=14
E[1,2]=0
E[1,3]=0
E[1,4]=0.08
E[1,5]=1
E[1,6]=1
E[1,7]=0.035
E[1,8]=50
E[1,9]=1015

#Element 1 (Reinforced concrete)
E[2,1]=13
E[2,2]=0.08
E[2,3]=0
E[2,4]=0.28
E[2,5]=1
E[2,6]=2
E[2,7]=2.6
E[2,8]=2500
E[2,9]=1000

##############################
#Boundary condition materials#
##############################

#Element 17 (dolje)
E[3,1]=100
E[3,2]=0
E[3,3]=-dl
E[3,4]=0.28
E[3,5]=0
E[3,6]=3
E[3,7]=(10000)*2/dl #Assign as (h)*dl/2 if h is convection coef.
E[3,8]=1
E[3,9]=-1

#Element 18 (lijevo)
E[4,1]=101
E[4,2]=-dl
E[4,3]=0
E[4,4]=0
E[4,5]=1
E[4,6]=4
E[4,7]=(10000)*2/dl #Assign as (h)*dl/2 if h is convection coef.
E[4,8]=0
E[4,9]=1

#Element 19 (gore)
E[5,1]=102
E[5,2]=0
E[5,3]=1
E[5,4]=0.28
E[5,5]=1+dl
E[5,6]=5
E[5,7]=(10000)*2/dl #Assign as (h)*dl/2 if h is convection coef.
E[5,8]=20
E[5,9]=-1

#Element 20 (desno)
E[6,1]=103
E[6,2]=0.28
E[6,3]=0
E[6,4]=0.28+dl
E[6,5]=1
E[6,6]=6
E[6,7]=(10000)*2/dl #Assign as (h)*dl/2 if h is convection coef.
E[6,8]=22
E[6,9]=1


text:
if isdefined(Base, :ASCIIString)==false && isdefined(Base, :String)
	const ASCIIString = String
end


text:
# Abstract types

abstract PredictionModel{NDIn, NDOut}

### Generic functions

isvalidparam(pm::PredictionModel, θ::AbstractArray) = (size(θ) == paramsize(pm))

### Prediciton models

## LinearPred

immutable LinearPred <: PredictionModel{1,0}
    dim::Int
    LinearPred(d::Int) = new(d)
end

inputlen(pm::LinearPred) = pm.dim
inputsize(pm::LinearPred) = (pm.dim,)
outputlen(pm::LinearPred) = 1
outputsize(pm::LinearPred) = ()
paramlen(pm::LinearPred) = pm.dim
paramsize(pm::LinearPred) = (pm.dim,)

function ninputs(pm::LinearPred, x::StridedVecOrMat)
    @_checkdims inputlen(pm) == size(x,1)
    size(x, 2)
end

function predict{T<:BlasReal}(pm::LinearPred, θ::StridedVector{T}, x::StridedVector{T})
    @_checkdims length(θ) == length(x) == pm.dim
    dot(θ, x)
end

function predict{T<:BlasReal}(pm::LinearPred, θ::StridedVector{T}, X::StridedMatrix{T})
    @_checkdims length(θ) == size(X,1) == pm.dim
    X'θ
end

function predict!{T<:BlasReal}(r::StridedVector{T}, pm::LinearPred, θ::StridedVector{T}, X::StridedMatrix{T})
    d = pm.dim
    n = size(X,2)
    @_checkdims length(θ) == size(X,1) == pm.dim && n == length(r)
    At_mul_B!(r, X, θ)
end

## AffinePred

immutable AffinePred <: PredictionModel{1,0}
    dim::Int
    bias::Float64

    AffinePred(d::Int) = new(d, 1.0)
    AffinePred(d::Int, b::Real) = new(d, convert(Float64, b))
end

inputlen(pm::AffinePred) = pm.dim
inputsize(pm::AffinePred) = (pm.dim,)
outputlen(pm::AffinePred) = 1
outputsize(pm::AffinePred) = ()
paramlen(pm::AffinePred) = pm.dim + 1
paramsize(pm::AffinePred) = (pm.dim + 1,)

function ninputs(pm::AffinePred, x::StridedVecOrMat)
    @_checkdims inputlen(pm) == size(x,1)
    size(x, 2)
end

function predict{T<:BlasReal}(pm::AffinePred, θ::StridedVector{T}, x::StridedVector{T})
    d = pm.dim
    @_checkdims length(θ) == d + 1 && length(x) == d
    w = Base.view(θ, 1:d)
    b = convert(T, pm.bias) * θ[d+1]
    dot(w, x) + b
end

function predict{T<:BlasReal}(pm::AffinePred, θ::StridedVector{T}, X::StridedMatrix{T})
    d = pm.dim
    @_checkdims length(θ) == d + 1 && size(X,1) == d
    w = Base.view(θ, 1:d)
    b = convert(T, pm.bias) * θ[d+1]
    r = X'w;
    broadcast!(+, r, r, b)
end

function predict!{T<:BlasReal}(r::StridedVector{T}, pm::AffinePred, θ::StridedVector{T}, X::StridedMatrix{T})
    d = pm.dim
    n = size(X,2)
    @_checkdims length(θ) == d + 1 && size(X,1) == d && n == length(r)
    b = convert(T, pm.bias) * θ[d+1]
    w = Base.view(θ, 1:d)
    At_mul_B!(r, X, w)
    broadcast!(+, r, r, b)
end

## MvLinearPred

immutable MvLinearPred <: PredictionModel{1,1}
    dim::Int
    k::Int

    MvLinearPred(d::Int, k::Int) = new(d, k)
end

inputlen(pm::MvLinearPred) = pm.dim
inputsize(pm::MvLinearPred) = (pm.dim,)
outputlen(pm::MvLinearPred) = pm.k
outputsize(pm::MvLinearPred) = (pm.k,)
paramlen(pm::MvLinearPred) = pm.k * pm.dim
paramsize(pm::MvLinearPred) = (pm.k, pm.dim)

function ninputs(pm::MvLinearPred, x::StridedVecOrMat)
    @_checkdims inputlen(pm) == size(x,1)
    size(x, 2)
end

function predict{T<:BlasReal}(pm::MvLinearPred, θ::StridedMatrix{T}, x::StridedVector{T})
    d = pm.dim
    k = pm.k
    @_checkdims size(θ) == (k,d) && length(x) == d
    θ * x
end

function predict{T<:BlasReal}(pm::MvLinearPred, θ::StridedMatrix{T}, X::StridedMatrix{T})
    d = pm.dim
    k = pm.k
    @_checkdims size(θ) == (k,d) && size(X,1) == d
    θ * X
end

function predict!{T<:BlasReal}(r::StridedMatrix{T}, pm::MvLinearPred, θ::StridedMatrix{T}, X::StridedMatrix{T})
    d = pm.dim
    k = pm.k
    n = size(X,2)
    @_checkdims size(θ) == (k,d) && size(X,1) == d && size(r) == (k,n)
    A_mul_B!(r, θ, X)
end

## MvAffinePred

immutable MvAffinePred <: PredictionModel{1,1}
    dim::Int
    k::Int
    bias::Float64

    MvAffinePred(d::Int, k::Int) = new(d, k, 1.0)
    MvAffinePred(d::Int, k::Int, b::Real) = new(d, k, convert(Float64, b))
end

inputlen(pm::MvAffinePred) = pm.dim
inputsize(pm::MvAffinePred) = (pm.dim,)
outputlen(pm::MvAffinePred) = pm.k
outputsize(pm::MvAffinePred) = (pm.k,)
paramlen(pm::MvAffinePred) = pm.k * (pm.dim + 1)
paramsize(pm::MvAffinePred) = (pm.k, pm.dim + 1)

function ninputs(pm::MvAffinePred, x::StridedVecOrMat)
    @_checkdims inputlen(pm) == size(x,1)
    size(x, 2)
end

function predict{T<:BlasReal}(pm::MvAffinePred, θ::StridedMatrix{T}, x::StridedVector{T})
    d = pm.dim
    k = pm.k
    @_checkdims size(θ) == (k,d+1) && length(x) == d
    W = Base.view(θ, :, 1:d)
    b = Base.view(θ, :, d+1)
    r = W * x
    axpy!(convert(T, pm.bias), b, r)
    r
end

function predict{T<:BlasReal}(pm::MvAffinePred, θ::StridedMatrix{T}, X::StridedMatrix{T})
    d = pm.dim
    k = pm.k
    @_checkdims size(θ) == (k,d+1) && size(X,1) == d
    W = Base.view(θ, :, 1:d)
    b = Base.view(θ, :, d+1)
    R = W * X
    bias = convert(T, pm.bias)
    for i = 1:size(X,2)
        axpy!(bias, b, Base.view(R,:,i))
    end
    R
end

function predict!{T<:BlasReal}(r::StridedMatrix{T}, pm::MvAffinePred, θ::StridedMatrix{T}, X::StridedMatrix{T})
    d = pm.dim
    k = pm.k
    n = size(X,2)
    @_checkdims size(θ) == (k,d+1) && size(X,1) == d && size(r) == (k,n)
    bias = convert(T, pm.bias)
    W = Base.view(θ, :, 1:d)
    b = Base.view(θ, :, d+1)
    A_mul_B!(r, W, X)
    bias = convert(T, pm.bias)
    for i = 1:size(X,2)
        axpy!(bias, b, Base.view(r,:,i))
    end
    r
end