diff --git a/A6 - 1.png b/A6 - 1.png
new file mode 100644
index 0000000000000000000000000000000000000000..8aa015b4dfa271c9c2c4ec743e1a64b2826a734d
Binary files /dev/null and b/A6 - 1.png differ
diff --git a/Isp.png b/Isp.png
new file mode 100644
index 0000000000000000000000000000000000000000..f6275b782175bc2396daaa84485204015afe4309
Binary files /dev/null and b/Isp.png differ
diff --git a/PINN/__init__.py b/PINN/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/PINN/__pycache__/__init__.cpython-310.pyc b/PINN/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d9992709a6beb646e77447b2daec40121c7c3f6c
Binary files /dev/null and b/PINN/__pycache__/__init__.cpython-310.pyc differ
diff --git a/PINN/__pycache__/pinns.cpython-310.pyc b/PINN/__pycache__/pinns.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..de236c013c7863260227c492cf24a2d4e83f46d6
Binary files /dev/null and b/PINN/__pycache__/pinns.cpython-310.pyc differ
diff --git a/PINN/pinns.py b/PINN/pinns.py
new file mode 100644
index 0000000000000000000000000000000000000000..28ae658a41f671b7c4d65398649653aeccff2f7e
--- /dev/null
+++ b/PINN/pinns.py
@@ -0,0 +1,53 @@
+from torch import nn,tensor
+import numpy as np
+import seaborn as sns
+class PINNd_p(nn.Module):
+ """ $d \mapsto P$
+
+
+ """
+ def __init__(self):
+ super(PINNd_p,self).__init__()
+ weights = tensor([60.,0.5])
+ self.weights = nn.Parameter(weights)
+ def forward(self,x):
+
+ c,b = self.weights
+ x1 = (x[0]/(c*x[1]))**0.5
+ return x1
+
+class PINNhd_ma(nn.Module):
+ """ $h,d \mapsto m_a $
+
+
+ """
+ def __init__(self):
+ super(PINNhd_ma,self).__init__()
+ weights = tensor([0.01])
+ self.weights = nn.Parameter(weights)
+ def forward(self,x):
+ c, = self.weights
+ x1 = c*x[0]*x[1]
+ return x1
+
+class PINNT_ma(nn.Module):
+ """$ m_a, U \mapsto T$
+
+
+ """
+ def __init__(self):
+ super(PINNT_ma,self).__init__()
+ weights = tensor([0.01])
+ self.weights = nn.Parameter(weights)
+ def forward(self,x):
+ c, = self.weights
+ x1 = c*x[0]*x[1]**0.5
+ return x1
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3c5518935e367bcc18919ce0da39800a0504189e
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+---
+title: Hetfit
+emoji: 📉
+colorFrom: yellow
+colorTo: blue
+sdk: streamlit
+sdk_version: 1.17.0
+app_file: app.py
+pinned: false
+license: cc-by-nc-4.0
+---
+
+Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
diff --git a/TDP.png b/TDP.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f050757571d217ddbc3709a6415ddfdb81b0d12
Binary files /dev/null and b/TDP.png differ
diff --git a/TPU.png b/TPU.png
new file mode 100644
index 0000000000000000000000000000000000000000..a37b07eb73399753a0c68b8d98d9be1ed8528cc0
Binary files /dev/null and b/TPU.png differ
diff --git a/Tisp.png b/Tisp.png
new file mode 100644
index 0000000000000000000000000000000000000000..be9222544b47f13f42b779fe38d502a2464325fa
Binary files /dev/null and b/Tisp.png differ
diff --git a/Unknown-3.jpg b/Unknown-3.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..328562b60418c84671eaf7162d34a47f915a0c96
Binary files /dev/null and b/Unknown-3.jpg differ
diff --git a/ann.png b/ann.png
new file mode 100644
index 0000000000000000000000000000000000000000..b2b601e244586dc3f30cc4cdc17717d51173d914
Binary files /dev/null and b/ann.png differ
diff --git a/app.py b/app.py
new file mode 100644
index 0000000000000000000000000000000000000000..f22589b25c40935bd3fbc067324de4c46f0e0e8d
--- /dev/null
+++ b/app.py
@@ -0,0 +1,83 @@
+import streamlit as st
+
+from nets.envs import SCI
+
+
+st.set_page_config(
+ page_title="HET_sci",
+ menu_items={
+ 'About':'https://advpropsys.github.io'
+ }
+)
+
+st.title('HETfit_scientific')
+st.markdown("#### Imagine a package which was engineered primarly for data driven plasma physics devices design, mainly low power hall effect thrusters, yup that's it"
+ "\n### :orange[Don't be scared away though, it has much simpler interface than anything you ever used for such designs]")
+st.markdown('### Main concepts:')
+st.markdown( "- Each observational/design session is called an **environment**, for now it can be either RCI or SCI (Real or scaled interface)"
+ "\n In this overview we will only touch SCI, since RCI is using PINNs which are different topic"
+ "\n- You specify most of the run parameters on this object init, :orange[**including generation of new samples**] via GAN"
+ "\n- You may want to generate new features, do it !"
+ "\n- Want to select best features for more effctive work? Done!"
+ "\n- Compile environment with your model of choice, can be ***any*** torch model or sklearn one"
+ "\n- Train !"
+ "\n- Plot, inference, save, export to jit/onnx, measure performance - **they all are one liners** "
+ )
+st.markdown('### tl;dr \n- Create environment'
+ '\n```run = SCI(*args,**kwargs)```'
+ '\n - Generate features ```run.feature_gen()``` '
+ '\n - Select features ```run.feature_importance()```'
+ '\n - Compile env ```run.compile()```'
+ '\n - Train model in env ```run.train()```'
+ '\n - Inference, plot, performance, ex. ```run.plot3d()```'
+ '\n #### And yes, it all will work even without any additional arguments from user besides column indexes'
+ )
+st.write('Comparison with *arXiv:2206.04440v3*')
+col1, col2 = st.columns(2)
+col1.metric('Geometry accuracy on domain',value='83%',delta='15%')
+col2.metric('$d \mapsto h$ prediction',value='98%',delta='14%')
+
+st.header('Example:')
+
+st.markdown('Remeber indexes and column names on this example: $P$ - 1, $d$ - 3, $h$ - 3, $m_a$ - 6,$T$ - 7')
+st.code('run = SCI(*args,**kwargs)')
+
+run = SCI()
+st.code('run.feature_gen()')
+run.feature_gen()
+st.write('New features: (index-0:22 original samples, else is GAN generated)',run.df.iloc[1:,9:].astype(float))
+st.write('Most of real dataset is from *doi:0.2514/1.B37424*, hence the results mostly agree with it in specific')
+st.code('run.feature_importance(run.df.iloc[1:,1:7].astype(float),run.df.iloc[1:,7]) # Clear and easy example')
+
+st.write(run.feature_importance(run.df.iloc[1:,1:6].astype(float),run.df.iloc[1:,6]))
+st.markdown(' As we can see only $h$ and $d$ passed for $m_a$ model, not only that linear dependacy was proven experimantally, but now we got this from data driven source')
+st.code('run.compile(idx=(1,3,7))')
+run.compile(idx=(1,3,7))
+st.code('run.train(epochs=10)')
+if st.button('Start Training⏳',use_container_width=True):
+ run.train(epochs=10)
+ st.code('run.plot3d()')
+ st.write(run.plot3d())
+ st.code('run.performance()')
+ st.write(run.performance())
+else:
+ st.markdown('#')
+
+st.markdown('---\nTry it out yourself! Select a column from 1 to 10')
+
+
+number = st.number_input('Here',min_value=1, max_value=10, step=1)
+
+if number:
+ if st.button('Compile And Train💅',use_container_width=True):
+ st.code(f'run.compile(idx=(1,3,{number}))')
+ run.compile(idx=(1,3,number))
+ st.code('run.train(epochs=10)')
+ run.train(epochs=10)
+ st.code('run.plot3d()')
+ st.write(run.plot3d())
+
+
+
+st.markdown('In this intro we covered simplest userflow while using HETFit package, resulted data can be used to leverage PINN and analytical models of Hall effect thrusters'
+ '\n #### :orange[To cite please contact author on https://github.com/advpropsys]')
\ No newline at end of file
diff --git a/bb.md b/bb.md
new file mode 100644
index 0000000000000000000000000000000000000000..fcb12dd990d9322a9fc5e6ba500ca812a7fca507
--- /dev/null
+++ b/bb.md
@@ -0,0 +1,38 @@
+
+
+# :orange[Hyper Paramaters Optimization class]
+## nets.opti.blackbox
+
+
+
+### Hyper Objects
+
+```python
+class Hyper(SCI)
+```
+
+Hyper parameter tunning class. Allows to generate best NN architecture for task. Inputs are column indexes. idx[-1] is targeted value.
+
+
+
+#### start\_study
+
+```python
+def start_study(n_trials: int = 100,
+ neptune_project: str = None,
+ neptune_api: str = None)
+```
+
+Starts study. Optionally provide your neptune repo and token for report generation.
+
+**Arguments**:
+
+- `n_trials` _int, optional_ - Number of iterations. Defaults to 100.
+- `neptune_project` _str, optional_ - None
+- neptune_api (str, optional):. Defaults to None.
+
+
+**Returns**:
+
+- `dict` - quick report of results
+
diff --git a/dH.png b/dH.png
new file mode 100644
index 0000000000000000000000000000000000000000..0db57d3e6e6f9786ea8736635140d668c0aa6c94
Binary files /dev/null and b/dH.png differ
diff --git a/dT.png b/dT.png
new file mode 100644
index 0000000000000000000000000000000000000000..c1b0a1eaf516c989323ae82e13ac096443519f29
Binary files /dev/null and b/dT.png differ
diff --git a/dashboard.png b/dashboard.png
new file mode 100644
index 0000000000000000000000000000000000000000..ace6c85f39d93ad435189cba79ee75e6154f7269
Binary files /dev/null and b/dashboard.png differ
diff --git a/data/bound.pkl b/data/bound.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..47682c95a99ef56c94b66d6fe8d136fccee65d0e
Binary files /dev/null and b/data/bound.pkl differ
diff --git a/data/dataset.csv b/data/dataset.csv
new file mode 100644
index 0000000000000000000000000000000000000000..dc2c7e854cd8a220c9a4605d14a2c84001ef605f
--- /dev/null
+++ b/data/dataset.csv
@@ -0,0 +1,24 @@
+Name,U,d,h,j,Isp,nu_t,T,m_a
+SPT-20 [21],52.4,180,15.0,5.0,32.0,0.47,3.9,839
+SPT-25 [22],134,180,20.0,5.0,10,0.59,5.5,948
+HET-100 [23],174,300,23.5,5.5,14.5,0.50,6.8,1386
+KHT-40 [24],187,325,31.0,9.0,25.5,0.69,10.3,1519
+KHT-50 [24],193,250,42.0,8.0,25.0,0.88,11.6,1339
+HEPS-200,195,250,42.5,8.5,25.0,0.88,11.2,1300
+BHT-200 [2526],200,250,21.0,5.6,11.2,0.94,12.8,1390
+KM-32 [27],215,250,32.0,7.0,16.0,1.00,12.2,1244
+SPT-50M [28],245,200,39.0,11.0,25.0,1.50,16.0,1088
+SPT-30 [23],258,250,24.0,6.0,11.0,0.98,13.2,1234
+KM-37 [29],283,292,37.0,9.0,17.5,1.15,18.5,1640
+CAM200 [3031],304,275,43.0,12.0,24,1.09,17.3,1587
+SPT-50 [21],317,300,39.0,11.0,25.0,1.18,17.5,1746
+A-3 [21],324,300,47.0,13.0,30.0,1.18,18.0,1821
+HEPS-500,482,300,49.5,15.5,25.0,1.67,25.9,1587
+BHT-600 [2632],615,300,56.0,16.0,32,2.60,39.1,1530
+SPT-70 [33],660,300,56.0,14.0,25.0,2.56,40.0,1593
+SPT-100 [934],1350,300,85.0,15.0,25.0,5.14,81.6,1540
+UAH-78AM,520,260,78.0,20,40,2,30,1450
+MaSMi40,330,300,40,6.28,12.56,1.5,13,1100
+MaSMi60,700,250,60,9.42,19,2.56,30,1300
+MaSMiDm,1000,500,67,10.5,21,3,53,1940
+Music-si,140,288,18,2,6.5,0.44,4.2,850
diff --git a/data/dataset.pkl b/data/dataset.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..969a88333fa290d236cb113182cf1b4c8850d4cc
Binary files /dev/null and b/data/dataset.pkl differ
diff --git a/data/new b/data/new
new file mode 100644
index 0000000000000000000000000000000000000000..728d4e92be85a7cde4ca2d064d65e1b3c168c0ec
Binary files /dev/null and b/data/new differ
diff --git a/data/test.pkl b/data/test.pkl
new file mode 100644
index 0000000000000000000000000000000000000000..8f2254d4dd8180893e56157294da5e26f0dea8a6
Binary files /dev/null and b/data/test.pkl differ
diff --git a/disc.png b/disc.png
new file mode 100644
index 0000000000000000000000000000000000000000..c82e2da314775444cb24b68d96986df1b686eca1
Binary files /dev/null and b/disc.png differ
diff --git a/docs/.DS_Store b/docs/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..9fc5353fda11bd30c969ab1670c87d42d73bdeb0
Binary files /dev/null and b/docs/.DS_Store differ
diff --git a/docs/main.html b/docs/main.html
new file mode 100644
index 0000000000000000000000000000000000000000..21de8388271812186b81e701b752277016e70ae6
--- /dev/null
+++ b/docs/main.html
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
import streamlit as st
+
+from nets.envs import SCI
+
+
+st . set_page_config (
+ page_title = "HET_sci" ,
+ menu_items = {
+ 'About' : 'https://advpropsys.github.io'
+ }
+)
+
+st . title ( 'HETfit_scientific' )
+st . markdown ( "#### Imagine a package which was engineered primarly for data driven plasma physics devices design, mainly hall effect thrusters, yup that's it"
+ " \n ### :orange[Don't be scared away though, it has much simpler interface than anything you ever used for such designs]" )
+st . markdown ( '### Main concepts:' )
+st . markdown ( "- Each observational/design session is called an **environment**, for now it can be either RCI or SCI (Real or scaled interface)"
+ " \n In this overview we will only touch SCI, since RCI is using PINNs which are different topic"
+ " \n - You specify most of the run parameters on this object init, :orange[**including generation of new samples**] via GAN"
+ " \n - You may want to generate new features, do it !"
+ " \n - Want to select best features for more effctive work? Done!"
+ " \n - Compile environment with your model of choice, can be ***any*** torch model or sklearn one"
+ " \n - Train !"
+ " \n - Plot, inference, save, export to jit/onnx, measure performance - **they all are one liners** "
+ )
+st . markdown ( '### tl;dr \n - Create environment'
+ ' \n ```run = SCI(*args,**kwargs)```'
+ ' \n - Generate features ```run.feature_gen()``` '
+ ' \n - Select features ```run.feature_importance()```'
+ ' \n - Compile env ```run.compile()```'
+ ' \n - Train model in env ```run.train()```'
+ ' \n - Inference, plot, performance, ex. ```run.plot3d()```'
+ ' \n #### And yes, it all will work even without any additional arguments from user besides column indexes'
+ )
+st . write ( 'Comparison with *arXiv:2206.04440v3*' )
+col1 , col2 = st . columns ( 2 )
+col1 . metric ( 'Geometry accuracy on domain' , value = '83%' , delta = '15%' )
+col2 . metric ( '$d \mapsto h$ prediction' , value = '98%' , delta = '14%' )
+
+st . header ( 'Example:' )
+
+st . markdown ( 'Remeber indexes and column names on this example: $P$ - 1, $d$ - 3, $h$ - 3, $m_a$ - 6,$T$ - 7' )
+st . code ( 'run = SCI(*args,**kwargs)' )
+
+run = SCI ()
+st . code ( 'run.feature_gen()' )
+run . feature_gen ()
+st . write ( 'New features: (index-0:22 original samples, else is GAN generated)' , run . df . iloc [ 1 :, 9 :] . astype ( float ))
+st . write ( 'Most of real dataset is from *doi:0.2514/1.B37424*, hence the results mostly agree with it in specific' )
+st . code ( 'run.feature_importance(run.df.iloc[1:,1:7].astype(float),run.df.iloc[1:,7]) # Clear and easy example' )
+
+st . write ( run . feature_importance ( run . df . iloc [ 1 :, 1 : 6 ] . astype ( float ), run . df . iloc [ 1 :, 6 ]))
+st . markdown ( ' As we can see only $h$ and $d$ passed for $m_a$ model, not only that linear dependacy was proven experimantally, but now we got this from data driven source' )
+st . code ( 'run.compile(idx=(1,3,7))' )
+run . compile ( idx = ( 1 , 3 , 7 ))
+st . code ( 'run.train(epochs=10)' )
+run . train ( epochs = 10 )
+st . code ( 'run.plot3d()' )
+st . write ( run . plot3d ())
+st . code ( 'run.performance()' )
+st . write ( run . performance ())
+
+st . write ( 'Try it out yourself! Select a column from 1 to 10' )
+number = st . number_input ( 'Here' , min_value = 1 , max_value = 10 , step = 1 )
+
+if number :
+ st . code ( f 'run.compile(idx=(1,3, { number } ))' )
+ run . compile ( idx = ( 1 , 3 , number ))
+ st . code ( 'run.train(epochs=10)' )
+ run . train ( epochs = 10 )
+ st . code ( 'run.plot3d()' )
+ st . write ( run . plot3d ())
+
+
+
+st . markdown ( 'In this intro we covered simplest user flow while using HETFit package, resulted data can be used to leverage PINN and analytical models of Hall effect thrusters'
+ ' \n #### :orange[To cite please contact author on https://github.com/advpropsys]' )
+
+
+
+
+
+
+
diff --git a/fig1.png b/fig1.png
new file mode 100644
index 0000000000000000000000000000000000000000..0caed2e4808c92904747e97491d142c622e8d6ea
Binary files /dev/null and b/fig1.png differ
diff --git a/gan.png b/gan.png
new file mode 100644
index 0000000000000000000000000000000000000000..e83df7b0f2c84b0ca10ac157728c711d8c617431
Binary files /dev/null and b/gan.png differ
diff --git a/gen.png b/gen.png
new file mode 100644
index 0000000000000000000000000000000000000000..f27997949a0950ef91817c094f8fc685f289ef02
Binary files /dev/null and b/gen.png differ
diff --git a/geom.png b/geom.png
new file mode 100644
index 0000000000000000000000000000000000000000..8eb6fd5df6f715a5a8c54c1d6f74d27f89923bf6
Binary files /dev/null and b/geom.png differ
diff --git a/graph.jpg b/graph.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..7b0921a32fc2e1a191be57b577ff534ff444a16b
Binary files /dev/null and b/graph.jpg differ
diff --git a/intro.md b/intro.md
new file mode 100644
index 0000000000000000000000000000000000000000..dccb77e40e69829b88a0a65d28329b1d1533ad36
--- /dev/null
+++ b/intro.md
@@ -0,0 +1,453 @@
+# :orange[Abstract:]
+ Hall effect thrusters are one of the most versatile and
+ popular electric propulsion systems for space use. Industry trends
+ towards interplanetary missions arise advances in design development
+ of such propulsion systems. It is understood that correct sizing of
+ discharge channel in Hall effect thruster impact performance greatly.
+ Since the complete physics model of such propulsion system is not yet
+ optimized for fast computations and design iterations, most thrusters
+ are being designed using so-called scaling laws. But this work focuses
+ on rather novel approach, which is outlined less frequently than
+ ordinary scaling design approach in literature. Using deep machine
+ learning it is possible to create predictive performance model, which
+ can be used to effortlessly get design of required hall thruster with
+ required characteristics using way less computing power than design
+ from scratch and way more flexible than usual scaling approach.
+:orange[author:] Korolev K.V [^1]
+title: Hall effect thruster design via deep neural network for additive
+ manufacturing
+
+# Nomenclature
+
+
+
+$U_d$ = discharge voltage
+$P$ = discharge power
+$T$ = thrust
+$\dot{m}_a$ = mass flow rate
+$I_{sp}$ = specific impulse
+$\eta_m$ = mass utilization efficiency
+$\eta_a$ = anode efficiency
+$j$ = $P/v$ \[power density\]
+$v$ = discharge channel volume
+$h, d, L$ = generic geometry parameters
+$C_*$ = set of scaling coefficients
+$g$ = free-fall acceleration
+$M$ = ion mass
+
+
+
+# Introduction
+
+
T he
+application of deep learning is extremely diverse, but in this study it
+focuses on case of hall effect thruster design. Hall effect thruster
+(HET) is rather simple DC plasma acceleration device, due to complex and
+non linear process physics we don’t have any full analytical performance
+models yet. Though there are a lot of ways these systems are designed in
+industry with great efficiencies, but in cost of multi-million research
+budgets and time. This problem might be solved using neural network
+design approach and few hardware iteration tweaks(Plyashkov et al.
+2022-10-25).
+
+Scaled thrusters tend to have good performance but this approach isn’t
+that flexible for numerous reasons: first and foremost, due to large
+deviations in all of the initial experimental values accuracy can be not
+that good, secondly, it is hardly possible to design thruster with
+different power density or $I_{sp}$ efficiently.
+
+On the other hand, the neural network design approach has accuracy
+advantage only on domain of the dataset(Plyashkov et al. 2022-10-25),
+this limitations is easily compensated by ability to create relations
+between multiple discharge and geometry parameters at once. Hence this
+novel approach and scaling relations together could be an ultimate
+endgame design tool for HET.
+
+Note that neither of these models do not include cathode efficiencies
+and performances. So as the neutral gas thrust components. Most
+correlations in previous literature were made using assumption or
+physics laws(Shagayda and Gorshkov 2013-03), in this paper the new
+method based on feature generation, GAN dataset augmentation and ML
+feature selection is suggested.
+
+## Dataset enlargement using GAN
+
+As we already have discussed, the data which is available is not enough
+for training NN or most ML algorithms, so I suggest using Generative
+Adversarial Network to generate more similar points. Generative model
+trains two different models - generator and discriminator. Generator
+learns how to generate new points which are classified by discriminator
+as similar to real dataset. Of course it is very understandable that
+model needs to be precise enough not to overfit on data or create new
+unknown correlations. Model was checked via Mean Absolute Percentage
+Error (MAPE) and physical boundary conditions. After assembling most
+promising architecture, the model was able to generate fake points with
+MAPE of $~4.7\%$. We need to measure MAPE to be sure point lie on same
+domain as original dataset, as in this work we are interested in
+sub-kilowatt thrusters. After model generated new points they were check
+to fit in physical boundaries of scaled values (for example thrust
+couldn’t be more than 2, efficiency more than 1.4 and so on, data was
+scaled on original dataset to retain quality), only 0.02% of points were
+found to be outliers. The GAN architecture and dataset sample is
+provided as follows.
+
+
+
+# General Relations
+
+As we will use dataset of only low power hall thrusters, we can just
+ignore derivation of any non-linear equations and relations and use
+traditional approach here. Let’s define some parameters of anode:
+$$\alpha = \frac{\dot{m}\beta}{{\dot{m}_a}},$$
+Where $\alpha$ is anode
+parameter of $\beta$ thruster parameter. This is selected because this
+way cathode and other losses wont be included in the model. One of key
+differences in this approach is fitting only best and most appropriate
+data, thus we will eliminate some variance in scaling laws. Though due
+to machine learning methods, we would need a lot of information which is
+simply not available in those volumes. So some simplifications and
+assumptions could be made. Firstly, as it was already said, we don’t
+include neutralizer efficiency in the model. Secondly, the model would
+be correct on very specific domain, defined by dataset, many parameters
+like anode power and $I_{sp}$ still are using semi-empirical modelling
+approach. The results we are looking for are outputs of machine learning
+algorithm: specific impulse, thrust, efficiency, optimal mass flow rate,
+power density. Function of input is solely dependant on power and
+voltage range. For the matter of topic let’s introduce semi-empirical
+equations which are used for scaling current thrusters.
+
+
+
+$$h=C_hd$$
+
+$$\dot{m_a} = C_m hd$$
+
+$$P_d=C_pU_dd^2$$
+
+$$T=C_t\dot{m_a}\sqrt{U_d}$$
+
+$$I_{spa}=\frac{T}{\dot{m_a} g}$$
+
+$$\eta_a=\frac{T}{2\dot{m_a}P_d}$$
+
+
+
+Where $C_x$ is scaling coefficient obtained from analytical modelling,
+which makes equations linear. Generally it has 95% prediction band but
+as was said earlier this linearity is what gives problems to current
+thrusters designs (high mass, same power density, average performance).
+The original dataset is
+
+| | | | | | | | | |
+|:---------|:---------|:-------|:------|:------|:------|:-------------|:-----|:----------|
+| Thruster | Power, W | U_d, V | d, mm | h, mm | L, mm | m_a,.g/s, | T, N | I\_spa, s |
+| SPT-20 | 52.4 | 180 | 15.0 | 5.0 | 32.0 | 0.47 | 3.9 | 839 |
+| SPT-25 | 134 | 180 | 20.0 | 5.0 | 10 | 0.59 | 5.5 | 948 |
+| Music-si | 140 | 288 | 18 | 2 | 6.5 | 0.44 | 4.2 | 850 |
+| HET-100 | 174 | 300 | 23.5 | 5.5 | 14.5 | 0.50 | 6.8 | 1386 |
+| KHT-40 | 187 | 325 | 31.0 | 9.0 | 25.5 | 0.69 | 10.3 | 1519 |
+| KHT-50 | 193 | 250 | 42.0 | 8.0 | 25.0 | 0.88 | 11.6 | 1339 |
+| HEPS-200 | 195 | 250 | 42.5 | 8.5 | 25.0 | 0.88 | 11.2 | 1300 |
+| BHT-200 | 200 | 250 | 21.0 | 5.6 | 11.2 | 0.94 | 12.8 | 1390 |
+| KM-32 | 215 | 250 | 32.0 | 7.0 | 16.0 | 1.00 | 12.2 | 1244 |
+| ... | | | | | | | | |
+| HEPS-500 | 482 | 300 | 49.5 | 15.5 | 25.0 | 1.67 | 25.9 | 1587 |
+| UAH-78AM | 520 | 260 | 78.0 | 20 | 40 | 2 | 30 | 1450 |
+| BHT-600 | 615 | 300 | 56.0 | 16.0 | 32 | 2.60 | 39.1 | 1530 |
+| SPT-70 | 660 | 300 | 56.0 | 14.0 | 25.0 | 2.56 | 40.0 | 1593 |
+| MaSMi60 | 700 | 250 | 60 | 9.42 | 19 | 2.56 | 30 | 1300 |
+| MaSMiDm | 1000 | 500 | 67 | 10.5 | 21 | 3 | 53 | 1940 |
+| SPT-100 | 1350 | 300 | 85.0 | 15.0 | 25.0 | 5.14 | 81.6 | 1540 |
+
+Hosting only 24 entries in total. The references are as follows(Beal et
+al. 2004-11)(Belikov et al. 2001-07-08)(Kronhaus et al. 2013-07)(Misuri
+and Andrenucci 2008-07-21)(Lee et al. 2019-11)
+
+In the next section the used neural networks architectures will be
+discussed.
+
+# Data driven HET designs
+
+Neural networks are a type of machine learning algorithm that is often
+used in the field of artificial intelligence. They are mathematical
+models that can be trained to recognize patterns within large datasets.
+The architecture of GAN’s generator was already shown. In this section
+we will focus on fully connected networks, which are most popular for
+type for these tasks. HETFit code leverages dynamic architecture
+generation of these FcNN’s which is done via meta learning algorithm
+Tree-structured Parzen Estimator for every data input user selects. This
+code uses state-of-art implementation made by OPTUNA. The dynamically
+suggested architecture has 2 to 6 layers from 4 to 128 nodes on each
+with SELU, Tanh or ReLU activations and most optimal optimizer. The code
+user interface is as follows: 1. Specify working environment 2. Load or
+generate data 3. Tune the architecture 4. Train and get robust scaling
+models
+
+## FNN
+
+All of Fully connected neural networks are implemented in PyTorch as it
+the most powerful ML/AI library for experiments. When the network
+architecture is generated, all of networks have similar training loops
+as they use gradient descend algorithm : Loss function:
+$$L(w, b) \equiv \frac{1}{2 n} \sum_x\|y(x)-a\|^2$$ This one is mean
+square error (MSE) error function most commonly used in FNNs. Next we
+iterate while updating weights for a number of specified epochs this
+way. Loop for number of epochs:
+
+\- Get predictions: $\hat{y}$
+
+\- Compute loss: $\mathscr{L}(w, b)$
+
+\- Make backward pass
+
+\- Update optimizer
+
+It can be mentioned that dataset of electric propulsion is extremely
+complex due to large deviations in data. Thanks to adavnces in data
+science and ML it is possible to work with it.
+
+This way we assembled dataset on our ROI domain of $P$\<1000 $W$ input
+power and 200-500 $V$ range. Sadly one of limitations of such model is
+disability to go beyond actual database limit while not sacrificing
+performance and accuracy.
+
+## Physics Informed Neural Networks
+
+For working with unscaled data PINN’s were introduced, they are using
+equations 2-7 to generate $C_x$ coefficients. Yes, it was said earlier
+that this method lacks ability to generate better performing HETs, but
+as we have generated larger dataset on same domain as Lee et al.
+(2019-11) it is important to control that our dataset is still the same
+quality as original. Using above mentioned PINN’s it was possible to fit
+coefficients and they showed only slight divergence in values of few %
+which is acceptable.
+
+## ML approach notes
+
+We already have discussed how HETFit code works and results it can
+generate, the overiew is going to be given in next section. But here i
+want to warn that this work is highly experimental and you should always
+take ML approaches with a grain of salt, as some plasma discharge
+physics in HET is yet to be understood, data driven way may have some
+errors in predictions on specific bands. Few notes on design tool I have
+developed in this work: it is meant to be used by people with little to
+no experience in ML field but those who wants to quickly analyze their
+designs or create baseline one for simulations. One can even use this
+tool for general tabular data as it has mostly no limits whatsoever to
+input data.
+
+## Two input variables prediction
+
+One of main characteristics for any type of thruster is efficiency, in
+this work I researched dependency of multiple input values to $\eta_t$.
+Results are as follows in form of predicted matrix visualisations.
+Figure 3 takes into account all previous ones in the same time, once
+again it would be way harder to do without ML.
+
+
+
+# Results discussion
+
+Let’s compare predictions of semi empirical approach(Lee et al.
+2019-11), approach in paper(Plyashkov et al. 2022-10-25), and finally
+ours. Worth to mention that current approach is easiest to redesign from
+scratch.
+
+## NN architecture generation algorithm
+
+As with 50 iterations, previously discussed meta learning model is able
+to create architecture with score of 0.9+ in matter of seconds. HETFit
+allows logging into neptune.ai environment for full control over
+simulations. Example trail run looks like that.
+
+
+
+## Power density and magnetic flux dependence
+
+Neither of the models currently support taking magnetic flux in account
+besides general physics relations, but we are planning on updating the
+model in next follow up paper. For now $\vec{B}$ relation to power
+remains unresolved to ML approach but the magnetic field distribution on
+z axis is computable and looks like that for magnetically shielded
+thrusters:
+
+
+
+## Dependency of T on d,P
+
+Following graph is describing Thrust as function of channel diameter and
+width, where hue map is thrust. It is well known dependency and it has
+few around 95% prediction band (Lee et al. 2019-11)
+
+
+
+## Dependency of T on P,U
+
+
+
+## Dependency of T on $m_a$,P
+
+Compared to(Shagayda and Gorshkov 2013-03) The model accounts for more
+parameters than linear relation. So such method proves to be more
+precise on specified domain than semi empirical linear relations.
+
+
+
+## Dependency of $I_{sp}$ on d,h
+
+
+
+We generated many models so far, but using ML we can make single model
+for all of the parameters at the same time, so these graphs tend to be
+3d projection of such model inference.
+
+## Use of pretrained model in additive manufacturing of hall effect thruster channels
+
+The above mentioned model was used to predict geometry of channel, next
+the simulation was conducted on this channel. Second one for comparison
+was calculated via usual scaling laws. The initial conditions for both
+are:
+
+| Initial condition | Value |
+|:------------------|:------------------|
+| $n_{e,0}$ | 1e13 \[m\^-3\] |
+| $\epsilon_0$ | 4 \[V\] |
+| V | 300 \[V\] |
+| T | 293.15 \[K\] |
+| P\_abs | 0.5 \[torr\] |
+| $\mu_e N_n$ | 1e25 \[1/(Vm s)\] |
+| dt | 1e-8 \[s\] |
+| Body | Ar |
+
+Outcomes are so that ML geometry results in higher density generation of
+ions which leads to more efficient thrust generation. HETFit code
+suggests HET parameters by lower estimate to compensate for not included
+variables in model of HET. This is experimentally proven to be efficient
+estimate since SEM predictions of thrust are always higher than real
+performance. Lee et al. (2019-11)
+
+
+
+## Code description
+
+Main concepts: - Each observational/design session is called an
+environment, for now it can be either RCI or SCI (Real or scaled
+interface)
+
+\- Most of the run parameters are specified on this object
+initialization, including generation of new samples via GAN
+
+\- Built-in feature generation (log10 Power, efficiency, $\vec{B}$,
+etc.)
+
+\- Top feature selection for each case. (Boruta algorithm)
+
+\- Compilation of environment with model of choice, can be any torch
+model or sklearn one
+
+\- Training
+
+\- Plot, inference, save, export to jit/onnx, measure performance
+
+## COMSOL HET simulations
+
+The simulations were conducted in COMSOL in plasma physics interface
+which gives the ability to accurately compute Electron densities,
+temperatures, energy distribution functions from initial conditions and
+geometry. Here is comparison of both channels.
+
+
+
+# Conclusion
+
+In conclusion the another model of scaling laws was made and presented.
+HETFit code is open source and free to be used by anyone. Additively
+manufactured channel was printed to prove it’s manufactureability.
+Hopefully this work will help developing more modern scaling relations
+as current ones are far from perfect.
+
+Method in this paper and firstly used in Plyashkov et al. (2022-10-25)
+has advantages over SEM one in: ability to preidct performance more
+precisely on given domain, account for experimental data. I believe with
+more input data the ML method of deisgning thrusters would be more
+widely used.
+
+The code in this work could be used with other tabular experimental data
+since most of cases and tasks tend to be the same: feature selection and
+model optimization.
+
+
+
+
+
+
+Beal, Brian E., Alec D. Gallimore, James M. Haas, and William A. Hargus.
+2004-11. “Plasma Properties in the Plume of a Hall Thruster Cluster.”
+*Journal of Propulsion and Power* 20 (6): 985–91.
+.
+
+
+
+
+
+Belikov, M., O. Gorshkov, V. Muravlev, R. Rizakhanov, A. Shagayda, and
+A. Snnirev. 2001-07-08. “High-Performance Low Power Hall Thruster.” In
+*37th Joint Propulsion Conference and Exhibit*. Salt Lake
+City,UT,U.S.A.: American Institute of Aeronautics; Astronautics.
+.
+
+
+
+
+
+Kronhaus, Igal, Alexander Kapulkin, Vladimir Balabanov, Maksim
+Rubanovich, Moshe Guelman, and Benveniste Natan. 2013-07. “Discharge
+Characterization of the Coaxial Magnetoisolated Longitudinal Anode Hall
+Thruster.” *Journal of Propulsion and Power* 29 (4): 938–49.
+.
+
+
+
+
+
+Lee, Eunkwang, Younho Kim, Hodong Lee, Holak Kim, Guentae Doh, Dongho
+Lee, and Wonho Choe. 2019-11. “Scaling Approach for Sub-Kilowatt
+Hall-Effect Thrusters.” *Journal of Propulsion and Power* 35 (6):
+1073–79. .
+
+
+
+
+
+Misuri, Tommaso, and Mariano Andrenucci. 2008-07-21. “HET Scaling
+Methodology: Improvement and Assessment.” In *44th AIAA/ASME/SAE/ASEE
+Joint Propulsion Conference &Amp; Exhibit*. Hartford, CT: American
+Institute of Aeronautics; Astronautics.
+.
+
+
+
+
+
+Plyashkov, Yegor V., Andrey A. Shagayda, Dmitrii A. Kravchenko, Fedor D.
+Ratnikov, and Alexander S. Lovtsov. 2022-10-25. “On Scaling of
+Hall-Effect Thrusters Using Neural Nets,” 2022-10-25.
+.
+
+
+
+
+
+Shagayda, Andrey A., and Oleg A. Gorshkov. 2013-03. “Hall-Thruster
+Scaling Laws.” *Journal of Propulsion and Power* 29 (2): 466–74.
+.
+
+
+
+
+
+[^1]: Founder, Pure EP
\ No newline at end of file
diff --git a/invariant.png b/invariant.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e2bc8dfab84bdc46745a0fe4e2784b08d1991d9
Binary files /dev/null and b/invariant.png differ
diff --git a/maT.png b/maT.png
new file mode 100644
index 0000000000000000000000000000000000000000..818dd629c48bddd5e7fcb1d422c23214a06cea5e
Binary files /dev/null and b/maT.png differ
diff --git a/main.md b/main.md
new file mode 100644
index 0000000000000000000000000000000000000000..a6628d6efa64e2e72f62df3bdfc0f7c90bfa4fb6
--- /dev/null
+++ b/main.md
@@ -0,0 +1,1060 @@
+# Table of Contents
+
+- [Table of Contents](#table-of-contents)
+- [main](#main)
+- [PINN](#pinn)
+- [PINN.pinns](#pinnpinns)
+ - [PINNd\_p Objects](#pinnd_p-objects)
+ - [forward](#forward)
+ - [PINNhd\_ma Objects](#pinnhd_ma-objects)
+ - [PINNT\_ma Objects](#pinnt_ma-objects)
+- [utils](#utils)
+- [utils.test](#utilstest)
+- [utils.dataset\_loader](#utilsdataset_loader)
+ - [get\_dataset](#get_dataset)
+- [utils.ndgan](#utilsndgan)
+ - [DCGAN Objects](#dcgan-objects)
+ - [\_\_init\_\_](#__init__)
+ - [define\_discriminator](#define_discriminator)
+ - [define\_generator](#define_generator)
+ - [build\_models](#build_models)
+ - [generate\_latent\_points](#generate_latent_points)
+ - [generate\_fake\_samples](#generate_fake_samples)
+ - [define\_gan](#define_gan)
+ - [summarize\_performance](#summarize_performance)
+ - [train\_gan](#train_gan)
+ - [start\_training](#start_training)
+ - [predict](#predict)
+- [utils.data\_augmentation](#utilsdata_augmentation)
+ - [dataset Objects](#dataset-objects)
+ - [\_\_init\_\_](#__init__-1)
+ - [generate](#generate)
+- [:orange\[nets\]](#orangenets)
+- [nets.envs](#netsenvs)
+ - [SCI Objects](#sci-objects)
+ - [\_\_init\_\_](#__init__-2)
+ - [feature\_gen](#feature_gen)
+ - [feature\_importance](#feature_importance)
+ - [data\_flow](#data_flow)
+ - [init\_seed](#init_seed)
+ - [train\_epoch](#train_epoch)
+ - [compile](#compile)
+ - [train](#train)
+ - [save](#save)
+ - [onnx\_export](#onnx_export)
+ - [jit\_export](#jit_export)
+ - [inference](#inference)
+ - [plot](#plot)
+ - [plot3d](#plot3d)
+ - [performance](#performance)
+ - [performance\_super](#performance_super)
+ - [RCI Objects](#rci-objects)
+ - [data\_flow](#data_flow-1)
+ - [compile](#compile-1)
+ - [plot](#plot-1)
+ - [performance](#performance-1)
+- [nets.dense](#netsdense)
+ - [Net Objects](#net-objects)
+ - [\_\_init\_\_](#__init__-3)
+- [nets.design](#netsdesign)
+ - [B\_field\_norm](#b_field_norm)
+ - [PUdesign](#pudesign)
+- [nets.deep\_dense](#netsdeep_dense)
+ - [dmodel Objects](#dmodel-objects)
+ - [\_\_init\_\_](#__init__-4)
+- [nets.opti](#netsopti)
+- [nets.opti.blackbox](#netsoptiblackbox)
+ - [Hyper Objects](#hyper-objects)
+ - [\_\_init\_\_](#__init__-5)
+ - [define\_model](#define_model)
+ - [objective](#objective)
+ - [start\_study](#start_study)
+
+
+
+# main
+
+
+
+# PINN
+
+
+
+# PINN.pinns
+
+
+
+## PINNd\_p Objects
+
+```python
+class PINNd_p(nn.Module)
+```
+
+$d \mapsto P$
+
+
+
+#### forward
+
+```python
+def forward(x)
+```
+
+$P,U$ input, $d$ output
+
+**Arguments**:
+
+- `x` __type__ - _description_
+
+
+**Returns**:
+
+- `_type_` - _description_
+
+
+
+## PINNhd\_ma Objects
+
+```python
+class PINNhd_ma(nn.Module)
+```
+
+$h,d \mapsto m_a $
+
+
+
+## PINNT\_ma Objects
+
+```python
+class PINNT_ma(nn.Module)
+```
+
+$ m_a, U \mapsto T$
+
+
+
+# utils
+
+
+
+# utils.test
+
+
+
+# utils.dataset\_loader
+
+
+
+#### get\_dataset
+
+```python
+def get_dataset(raw: bool = False,
+ sample_size: int = 1000,
+ name: str = 'dataset.pkl',
+ source: str = 'dataset.csv',
+ boundary_conditions: list = None) -> _pickle
+```
+
+Gets augmented dataset
+
+**Arguments**:
+
+- `raw` _bool, optional_ - either to use source data or augmented. Defaults to False.
+- `sample_size` _int, optional_ - sample size. Defaults to 1000.
+- `name` _str, optional_ - name of wanted dataset. Defaults to 'dataset.pkl'.
+- `boundary_conditions` _list,optional_ - y1,y2,x1,x2.
+
+**Returns**:
+
+- `_pickle` - pickle buffer
+
+
+
+# utils.ndgan
+
+
+
+## DCGAN Objects
+
+```python
+class DCGAN()
+```
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(latent, data)
+```
+
+The function takes in two arguments, the latent space dimension and the dataframe. It then sets
+
+the latent space dimension, the dataframe, the number of inputs and outputs, and then builds the
+models
+
+**Arguments**:
+
+- `latent`: The number of dimensions in the latent space
+- `data`: This is the dataframe that contains the data that we want to generate
+
+
+
+#### define\_discriminator
+
+```python
+def define_discriminator(inputs=8)
+```
+
+The discriminator is a neural network that takes in a vector of length 8 and outputs a single
+
+value between 0 and 1
+
+**Arguments**:
+
+- `inputs`: number of features in the dataset, defaults to 8 (optional)
+
+**Returns**:
+
+The model is being returned.
+
+
+
+#### define\_generator
+
+```python
+def define_generator(latent_dim, outputs=8)
+```
+
+The function takes in a latent dimension and outputs and returns a model with two hidden layers
+
+and an output layer
+
+**Arguments**:
+
+- `latent_dim`: The dimension of the latent space, or the space that the generator will map
+to
+- `outputs`: the number of outputs of the generator, defaults to 8 (optional)
+
+**Returns**:
+
+The model is being returned.
+
+
+
+#### build\_models
+
+```python
+def build_models()
+```
+
+The function returns the generator and discriminator models
+
+**Returns**:
+
+The generator and discriminator models are being returned.
+
+
+
+#### generate\_latent\_points
+
+```python
+def generate_latent_points(latent_dim, n)
+```
+
+> Generate random points in latent space as input for the generator
+
+**Arguments**:
+
+- `latent_dim`: the dimension of the latent space, which is the input to the generator
+- `n`: number of images to generate
+
+**Returns**:
+
+A numpy array of random numbers.
+
+
+
+#### generate\_fake\_samples
+
+```python
+def generate_fake_samples(generator, latent_dim, n)
+```
+
+It generates a batch of fake samples with class labels
+
+**Arguments**:
+
+- `generator`: The generator model that we will train
+- `latent_dim`: The dimension of the latent space, e.g. 100
+- `n`: The number of samples to generate
+
+**Returns**:
+
+x is the generated images and y is the labels for the generated images.
+
+
+
+#### define\_gan
+
+```python
+def define_gan(generator, discriminator)
+```
+
+The function takes in a generator and a discriminator, sets the discriminator to be untrainable,
+
+and then adds the generator and discriminator to a sequential model. The sequential model is then compiled with an optimizer and a loss function.
+
+The optimizer is adam, which is a type of gradient descent algorithm.
+
+Loss function is binary crossentropy, which is a loss function that is used for binary
+classification problems.
+
+
+The function then returns the GAN.
+
+**Arguments**:
+
+- `generator`: The generator model
+- `discriminator`: The discriminator model that takes in a dataset and outputs a single value
+representing fake/real
+
+**Returns**:
+
+The model is being returned.
+
+
+
+#### summarize\_performance
+
+```python
+def summarize_performance(epoch, generator, discriminator, latent_dim, n=200)
+```
+
+> This function evaluates the discriminator on real and fake data, and plots the real and fake
+
+data
+
+**Arguments**:
+
+- `epoch`: the number of epochs to train for
+- `generator`: the generator model
+- `discriminator`: the discriminator model
+- `latent_dim`: The dimension of the latent space
+- `n`: number of samples to generate, defaults to 200 (optional)
+
+
+
+#### train\_gan
+
+```python
+def train_gan(g_model,
+ d_model,
+ gan_model,
+ latent_dim,
+ num_epochs=2500,
+ num_eval=2500,
+ batch_size=2)
+```
+
+**Arguments**:
+
+- `g_model`: the generator model
+- `d_model`: The discriminator model
+- `gan_model`: The GAN model, which is the generator model combined with the discriminator
+model
+- `latent_dim`: The dimension of the latent space. This is the number of random numbers that
+the generator model will take as input
+- `num_epochs`: The number of epochs to train for, defaults to 2500 (optional)
+- `num_eval`: number of epochs to run before evaluating the model, defaults to 2500
+(optional)
+- `batch_size`: The number of samples to use for each gradient update, defaults to 2
+(optional)
+
+
+
+#### start\_training
+
+```python
+def start_training()
+```
+
+The function takes the generator, discriminator, and gan models, and the latent vector as
+arguments, and then calls the train_gan function.
+
+
+
+#### predict
+
+```python
+def predict(n)
+```
+
+It takes the generator model and the latent space as input and returns a batch of fake samples
+
+**Arguments**:
+
+- `n`: the number of samples to generate
+
+**Returns**:
+
+the generated fake samples.
+
+
+
+# utils.data\_augmentation
+
+
+
+## dataset Objects
+
+```python
+class dataset()
+```
+
+Creates dataset from input source
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(number_samples: int,
+ name: str,
+ source: str,
+ boundary_conditions: list = None)
+```
+
+
+**Arguments**:
+
+- `number_samples` _int_ - number of samples to be genarated
+- `name` _str_ - name of dataset
+- `source` _str_ - source file
+- `boundary_conditions` _list_ - y1,y2,x1,x2
+
+
+
+#### generate
+
+```python
+def generate()
+```
+
+The function takes in a dataframe, normalizes it, and then trains a DCGAN on it.
+
+The DCGAN is a type of generative adversarial network (GAN) that is used to generate new data.
+
+The DCGAN is trained on the normalized dataframe, and then the DCGAN is used to generate new
+data.
+
+The new data is then concatenated with the original dataframe, and the new dataframe is saved as
+a pickle file.
+
+The new dataframe is then returned.
+
+**Returns**:
+
+The dataframe is being returned.
+
+
+
+# :orange[nets]
+
+
+
+# nets.envs
+
+
+
+## SCI Objects
+
+```python
+class SCI()
+```
+
+Scaled computing interface.
+
+**Arguments**:
+
+- `hidden_dim` _int, optional_ - Max demension of hidden linear layer. Defaults to 200. Should be >80 in not 1d case
+- `dropout` _bool, optional_ - LEGACY, don't use. Defaults to True.
+- `epochs` _int, optional_ - Optionally specify epochs here, but better in train. Defaults to 10.
+- `dataset` _str, optional_ - dataset to be selected from ./data. Defaults to 'test.pkl'. If name not exists, code will generate new dataset with upcoming parameters.
+- `sample_size` _int, optional_ - Samples to be generated (note: BEFORE applying boundary conditions). Defaults to 1000.
+- `source` _str, optional_ - Source from which data will be generated. Better to not change. Defaults to 'dataset.csv'.
+- `boundary_conditions` _list, optional_ - If sepcified, whole dataset will be cut rectangulary. Input list is [ymin,ymax,xmin,xmax] type. Defaults to None.
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(hidden_dim: int = 200,
+ dropout: bool = True,
+ epochs: int = 10,
+ dataset: str = 'test.pkl',
+ sample_size: int = 1000,
+ source: str = 'dataset.csv',
+ boundary_conditions: list = None,
+ batch_size: int = 20)
+```
+
+
+
+**Arguments**:
+
+- `hidden_dim` _int, optional_ - Max demension of hidden linear layer. Defaults to 200. Should be >80 in not 1d case
+- `dropout` _bool, optional_ - LEGACY, don't use. Defaults to True.
+- `epochs` _int, optional_ - Optionally specify epochs here, but better in train. Defaults to 10.
+- `dataset` _str, optional_ - dataset to be selected from ./data. Defaults to 'test.pkl'. If name not exists, code will generate new dataset with upcoming parameters.
+- `sample_size` _int, optional_ - Samples to be generated (note: BEFORE applying boundary conditions). Defaults to 1000.
+- `source` _str, optional_ - Source from which data will be generated. Better to not change. Defaults to 'dataset.csv'.
+- `boundary_conditions` _list, optional_ - If sepcified, whole dataset will be cut rectangulary. Input list is [ymin,ymax,xmin,xmax] type. Defaults to None.
+- `batch_size` _int, optional_ - Batch size for training.
+
+
+
+#### feature\_gen
+
+```python
+def feature_gen(base: bool = True,
+ fname: str = None,
+ index: int = None,
+ func=None) -> None
+```
+
+Generate new features. If base true, generates most obvious ones. You can customize this by adding
+new feature as name of column - fname, index of parent column, and lambda function which needs to be applied elementwise.
+
+**Arguments**:
+
+- `base` _bool, optional_ - Defaults to True.
+- `fname` _str, optional_ - Name of new column. Defaults to None.
+- `index` _int, optional_ - Index of parent column. Defaults to None.
+- `func` __type_, optional_ - lambda function. Defaults to None.
+
+
+
+#### feature\_importance
+
+```python
+def feature_importance(X: pd.DataFrame, Y: pd.Series, verbose: int = 1)
+```
+
+Gets feature importance by SGD regression and score selection. Default threshold is 1.25*mean
+input X as self.df.iloc[:,(columns of choice)]
+Y as self.df.iloc[:,(column of choice)]
+
+**Arguments**:
+
+- `X` _pd.DataFrame_ - Builtin DataFrame
+- `Y` _pd.Series_ - Builtin Series
+- `verbose` _int, optional_ - either to or to not print actual report. Defaults to 1.
+
+**Returns**:
+
+ Report (str)
+
+
+
+#### data\_flow
+
+```python
+def data_flow(columns_idx: tuple = (1, 3, 3, 5),
+ idx: tuple = None,
+ split_idx: int = 800) -> torch.utils.data.DataLoader
+```
+
+Data prep pipeline
+It is called automatically, don't call it in your code.
+
+**Arguments**:
+
+- `columns_idx` _tuple, optional_ - Columns to be selected (sliced 1:2 3:4) for feature fitting. Defaults to (1,3,3,5).
+- `idx` _tuple, optional_ - 2|3 indexes to be selected for feature fitting. Defaults to None. Use either idx or columns_idx (for F:R->R idx, for F:R->R2 columns_idx)
+ split_idx (int) : Index to split for training
+
+
+**Returns**:
+
+- `torch.utils.data.DataLoader` - Torch native dataloader
+
+
+
+#### init\_seed
+
+```python
+def init_seed(seed)
+```
+
+Initializes seed for torch - optional
+
+
+
+#### train\_epoch
+
+```python
+def train_epoch(X, model, loss_function, optim)
+```
+
+Inner function of class - don't use.
+
+We iterate through the data, calculate the loss, backpropagate, and update the weights
+
+**Arguments**:
+
+- `X`: the training data
+- `model`: the model we're training
+- `loss_function`: the loss function to use
+- `optim`: the optimizer, which is the algorithm that will update the weights of the model
+
+
+
+#### compile
+
+```python
+def compile(columns: tuple = None,
+ idx: tuple = None,
+ optim: torch.optim = torch.optim.AdamW,
+ loss: nn = nn.L1Loss,
+ model: nn.Module = dmodel,
+ custom: bool = False,
+ lr: float = 0.0001) -> None
+```
+
+Builds model, loss, optimizer. Has defaults
+
+**Arguments**:
+
+- `columns` _tuple, optional_ - Columns to be selected for feature fitting. Defaults to (1,3,3,5).
+- `optim` - torch Optimizer. Default AdamW
+- `loss` - torch Loss function (nn). Defaults to L1Loss
+
+
+
+#### train
+
+```python
+def train(epochs: int = 10) -> None
+```
+
+Train model
+- If sklearn instance uses .fit()
+
+- epochs (int,optional)
+
+
+
+#### save
+
+```python
+def save(name: str = 'model.pt') -> None
+```
+
+> This function saves the model to a file
+
+**Arguments**:
+
+- `name` (`str (optional)`): The name of the file to save the model to, defaults to model.pt
+
+
+
+#### onnx\_export
+
+```python
+def onnx_export(path: str = './models/model.onnx')
+```
+
+> We are exporting the model to the ONNX format, using the input data and the model itself
+
+**Arguments**:
+
+- `path` (`str (optional)`): The path to save the model to, defaults to ./models/model.onnx
+
+
+
+#### jit\_export
+
+```python
+def jit_export(path: str = './models/model.pt')
+```
+
+Exports properly defined model to jit
+
+**Arguments**:
+
+- `path` _str, optional_ - path to models. Defaults to './models/model.pt'.
+
+
+
+#### inference
+
+```python
+def inference(X: tensor, model_name: str = None) -> np.ndarray
+```
+
+Inference of (pre-)trained model
+
+**Arguments**:
+
+- `X` _tensor_ - your data in domain of train
+
+**Returns**:
+
+- `np.ndarray` - predictions
+
+
+
+#### plot
+
+```python
+def plot()
+```
+
+> If the input and output dimensions are the same, plot the input and output as a scatter plot.
+If the input and output dimensions are different, plot the first dimension of the input and
+output as a scatter plot
+
+
+
+#### plot3d
+
+```python
+def plot3d(colX=0, colY=1)
+```
+
+Plot of inputs and predicted data in mesh format
+
+**Returns**:
+
+ plotly plot
+
+
+
+#### performance
+
+```python
+def performance(c=0.4) -> dict
+```
+
+Automatic APE based performance if applicable, else returns nan
+
+**Arguments**:
+
+- `c` _float, optional_ - ZDE mitigation constant. Defaults to 0.4.
+
+**Returns**:
+
+- `dict` - {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+
+
+
+#### performance\_super
+
+```python
+def performance_super(c=0.4,
+ real_data_column_index: tuple = (1, 8),
+ real_data_samples: int = 23,
+ generated_length: int = 1000) -> dict
+```
+
+Performance by custom parameters. APE loss
+
+**Arguments**:
+
+- `c` _float, optional_ - ZDE mitigation constant. Defaults to 0.4.
+- `real_data_column_index` _tuple, optional_ - Defaults to (1,8).
+- `real_data_samples` _int, optional_ - Defaults to 23.
+- `generated_length` _int, optional_ - Defaults to 1000.
+
+**Returns**:
+
+- `dict` - {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+
+
+
+## RCI Objects
+
+```python
+class RCI(SCI)
+```
+
+Real values interface, uses different types of NN, NO scaling.
+Parent:
+ SCI()
+
+
+
+#### data\_flow
+
+```python
+def data_flow(columns_idx: tuple = (1, 3, 3, 5),
+ idx: tuple = None,
+ split_idx: int = 800) -> torch.utils.data.DataLoader
+```
+
+Data prep pipeline
+
+**Arguments**:
+
+- `columns_idx` _tuple, optional_ - Columns to be selected (sliced 1:2 3:4) for feature fitting. Defaults to (1,3,3,5).
+- `idx` _tuple, optional_ - 2|3 indexes to be selected for feature fitting. Defaults to None. Use either idx or columns_idx (for F:R->R idx, for F:R->R2 columns_idx)
+ split_idx (int) : Index to split for training
+
+
+**Returns**:
+
+- `torch.utils.data.DataLoader` - Torch native dataloader
+
+
+
+#### compile
+
+```python
+def compile(columns: tuple = None,
+ idx: tuple = (3, 1),
+ optim: torch.optim = torch.optim.AdamW,
+ loss: nn = nn.L1Loss,
+ model: nn.Module = PINNd_p,
+ lr: float = 0.001) -> None
+```
+
+Builds model, loss, optimizer. Has defaults
+
+**Arguments**:
+
+- `columns` _tuple, optional_ - Columns to be selected for feature fitting. Defaults to None.
+- `idx` _tuple, optional_ - indexes to be selected Default (3,1)
+ optim - torch Optimizer
+ loss - torch Loss function (nn)
+
+
+
+#### plot
+
+```python
+def plot()
+```
+
+Plots 2d plot of prediction vs real values
+
+
+
+#### performance
+
+```python
+def performance(c=0.4) -> dict
+```
+
+RCI performnace. APE errors.
+
+**Arguments**:
+
+- `c` _float, optional_ - correction constant to mitigate division by 0 error. Defaults to 0.4.
+
+**Returns**:
+
+- `dict` - {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+
+
+
+# nets.dense
+
+
+
+## Net Objects
+
+```python
+class Net(nn.Module)
+```
+
+The Net class inherits from the nn.Module class, which has a number of attributes and methods (such
+as .parameters() and .zero_grad()) which we will be using. You can read more about the nn.Module
+class [here](https://pytorch.org/docs/stable/nn.html#torch.nn.Module)
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(input_dim: int = 2, hidden_dim: int = 200)
+```
+
+We create a neural network with two hidden layers, each with **hidden_dim** neurons, and a ReLU activation
+
+function. The output layer has one neuron and no activation function
+
+**Arguments**:
+
+- `input_dim` (`int (optional)`): The dimension of the input, defaults to 2
+- `hidden_dim` (`int (optional)`): The number of neurons in the hidden layer, defaults to 200
+
+
+
+# nets.design
+
+
+
+#### B\_field\_norm
+
+```python
+def B_field_norm(Bmax: float, L: float, k: int = 16, plot=True) -> np.array
+```
+
+Returns vec B_z for MS config
+
+**Arguments**:
+
+- `Bmax` _any_ - maximum B in thruster
+ L - channel length
+ k - magnetic field profile number
+
+
+
+#### PUdesign
+
+```python
+def PUdesign(P: float, U: float) -> pd.DataFrame
+```
+
+Computes design via numerical model, uses fits from PINNs
+
+**Arguments**:
+
+- `P` _float_ - _description_
+- `U` _float_ - _description_
+
+
+**Returns**:
+
+- `_type_` - _description_
+
+
+
+# nets.deep\_dense
+
+
+
+## dmodel Objects
+
+```python
+class dmodel(nn.Module)
+```
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(in_features=1, hidden_features=200, out_features=1)
+```
+
+We're creating a neural network with 4 layers, each with 200 neurons. The first layer takes in the input, the second layer takes in the output of the first layer, the third layer takes in the
+output of the second layer, and the fourth layer takes in the output of the third layer
+
+**Arguments**:
+
+- `in_features`: The number of input features, defaults to 1 (optional)
+- `hidden_features`: the number of neurons in the hidden layers, defaults to 200 (optional)
+- `out_features`: The number of classes for classification (1 for regression), defaults to 1
+(optional)
+
+
+
+# nets.opti
+
+
+
+# nets.opti.blackbox
+
+
+
+## Hyper Objects
+
+```python
+class Hyper(SCI)
+```
+
+Hyper parameter tunning class. Allows to generate best NN architecture for task. Inputs are column indexes. idx[-1] is targeted value.
+Based on OPTUNA algorithms it is very fast and reliable. Outputs are NN parameters in json. Optionally full report for every trial is available at the neptune.ai
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(idx: tuple = (1, 3, 7), *args, **kwargs)
+```
+
+The function __init__() is a constructor that initializes the class Hyper
+
+**Arguments**:
+
+- `idx` (`tuple`): tuple of integers, the indices of the data to be loaded
+
+
+
+#### define\_model
+
+```python
+def define_model(trial)
+```
+
+We define a function that takes in a trial object and returns a neural network with the number
+
+of layers, hidden units and activation functions defined by the trial object.
+
+**Arguments**:
+
+- `trial`: This is an object that contains the information about the current trial
+
+**Returns**:
+
+A sequential model with the number of layers, hidden units and activation functions
+defined by the trial.
+
+
+
+#### objective
+
+```python
+def objective(trial)
+```
+
+We define a model, an optimizer, and a loss function. We then train the model for a number of
+
+epochs, and report the loss at the end of each epoch
+
+*"optimizer": ["Adam", "RMSprop", "SGD" 'AdamW','Adamax','Adagrad']*
+*"lr" $\in$ [1e-7,1e-3], log=True*
+
+**Arguments**:
+
+- `trial`: The trial object that is passed to the objective function
+
+**Returns**:
+
+The accuracy of the model.
+
+
+
+#### start\_study
+
+```python
+def start_study(n_trials: int = 100,
+ neptune_project: str = None,
+ neptune_api: str = None)
+```
+
+It takes a number of trials, a neptune project name and a neptune api token as input and runs
+
+the objective function on the number of trials specified. If the neptune project and api token
+are provided, it logs the results to neptune
+
+**Arguments**:
+
+- `n_trials` (`int (optional)`): The number of trials to run, defaults to 100
+- `neptune_project` (`str`): the name of the neptune project you want to log to
+- `neptune_api` (`str`): your neptune api key
+
diff --git a/main.py b/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..f22589b25c40935bd3fbc067324de4c46f0e0e8d
--- /dev/null
+++ b/main.py
@@ -0,0 +1,83 @@
+import streamlit as st
+
+from nets.envs import SCI
+
+
+st.set_page_config(
+ page_title="HET_sci",
+ menu_items={
+ 'About':'https://advpropsys.github.io'
+ }
+)
+
+st.title('HETfit_scientific')
+st.markdown("#### Imagine a package which was engineered primarly for data driven plasma physics devices design, mainly low power hall effect thrusters, yup that's it"
+ "\n### :orange[Don't be scared away though, it has much simpler interface than anything you ever used for such designs]")
+st.markdown('### Main concepts:')
+st.markdown( "- Each observational/design session is called an **environment**, for now it can be either RCI or SCI (Real or scaled interface)"
+ "\n In this overview we will only touch SCI, since RCI is using PINNs which are different topic"
+ "\n- You specify most of the run parameters on this object init, :orange[**including generation of new samples**] via GAN"
+ "\n- You may want to generate new features, do it !"
+ "\n- Want to select best features for more effctive work? Done!"
+ "\n- Compile environment with your model of choice, can be ***any*** torch model or sklearn one"
+ "\n- Train !"
+ "\n- Plot, inference, save, export to jit/onnx, measure performance - **they all are one liners** "
+ )
+st.markdown('### tl;dr \n- Create environment'
+ '\n```run = SCI(*args,**kwargs)```'
+ '\n - Generate features ```run.feature_gen()``` '
+ '\n - Select features ```run.feature_importance()```'
+ '\n - Compile env ```run.compile()```'
+ '\n - Train model in env ```run.train()```'
+ '\n - Inference, plot, performance, ex. ```run.plot3d()```'
+ '\n #### And yes, it all will work even without any additional arguments from user besides column indexes'
+ )
+st.write('Comparison with *arXiv:2206.04440v3*')
+col1, col2 = st.columns(2)
+col1.metric('Geometry accuracy on domain',value='83%',delta='15%')
+col2.metric('$d \mapsto h$ prediction',value='98%',delta='14%')
+
+st.header('Example:')
+
+st.markdown('Remeber indexes and column names on this example: $P$ - 1, $d$ - 3, $h$ - 3, $m_a$ - 6,$T$ - 7')
+st.code('run = SCI(*args,**kwargs)')
+
+run = SCI()
+st.code('run.feature_gen()')
+run.feature_gen()
+st.write('New features: (index-0:22 original samples, else is GAN generated)',run.df.iloc[1:,9:].astype(float))
+st.write('Most of real dataset is from *doi:0.2514/1.B37424*, hence the results mostly agree with it in specific')
+st.code('run.feature_importance(run.df.iloc[1:,1:7].astype(float),run.df.iloc[1:,7]) # Clear and easy example')
+
+st.write(run.feature_importance(run.df.iloc[1:,1:6].astype(float),run.df.iloc[1:,6]))
+st.markdown(' As we can see only $h$ and $d$ passed for $m_a$ model, not only that linear dependacy was proven experimantally, but now we got this from data driven source')
+st.code('run.compile(idx=(1,3,7))')
+run.compile(idx=(1,3,7))
+st.code('run.train(epochs=10)')
+if st.button('Start Training⏳',use_container_width=True):
+ run.train(epochs=10)
+ st.code('run.plot3d()')
+ st.write(run.plot3d())
+ st.code('run.performance()')
+ st.write(run.performance())
+else:
+ st.markdown('#')
+
+st.markdown('---\nTry it out yourself! Select a column from 1 to 10')
+
+
+number = st.number_input('Here',min_value=1, max_value=10, step=1)
+
+if number:
+ if st.button('Compile And Train💅',use_container_width=True):
+ st.code(f'run.compile(idx=(1,3,{number}))')
+ run.compile(idx=(1,3,number))
+ st.code('run.train(epochs=10)')
+ run.train(epochs=10)
+ st.code('run.plot3d()')
+ st.write(run.plot3d())
+
+
+
+st.markdown('In this intro we covered simplest userflow while using HETFit package, resulted data can be used to leverage PINN and analytical models of Hall effect thrusters'
+ '\n #### :orange[To cite please contact author on https://github.com/advpropsys]')
\ No newline at end of file
diff --git a/model.png b/model.png
new file mode 100644
index 0000000000000000000000000000000000000000..c82e2da314775444cb24b68d96986df1b686eca1
Binary files /dev/null and b/model.png differ
diff --git a/models/model.onnx b/models/model.onnx
new file mode 100644
index 0000000000000000000000000000000000000000..fe3396f3be4aa96715939ebc78fe533460e1e14a
Binary files /dev/null and b/models/model.onnx differ
diff --git a/module_name.md b/module_name.md
new file mode 100644
index 0000000000000000000000000000000000000000..b90957d96651ccbe50c114fac80f1722c84f0072
--- /dev/null
+++ b/module_name.md
@@ -0,0 +1,456 @@
+# Table of Contents
+
+- [Table of Contents](#table-of-contents)
+- [main](#main)
+- [:orange\[PINN\]](#orangepinn)
+ - [PINN.pinns](#pinnpinns)
+ - [PINNd\_p Objects](#pinnd_p-objects)
+ - [PINNhd\_ma Objects](#pinnhd_ma-objects)
+ - [PINNT\_ma Objects](#pinnt_ma-objects)
+- [:orange\[utils\]](#orangeutils)
+ - [utils.test](#utilstest)
+ - [utils.dataset\_loader](#utilsdataset_loader)
+ - [get\_dataset](#get_dataset)
+ - [utils.ndgan](#utilsndgan)
+ - [DCGAN Objects](#dcgan-objects)
+ - [define\_discriminator](#define_discriminator)
+ - [generate\_latent\_points](#generate_latent_points)
+ - [define\_gan](#define_gan)
+ - [summarize\_performance](#summarize_performance)
+ - [train\_gan](#train_gan)
+ - [utils.data\_augmentation](#utilsdata_augmentation)
+ - [dataset Objects](#dataset-objects)
+ - [\_\_init\_\_](#__init__)
+- [:orange\[nets\]](#orangenets)
+ - [nets.envs](#netsenvs)
+ - [SCI Objects](#sci-objects)
+ - [data\_flow](#data_flow)
+ - [init\_seed](#init_seed)
+ - [compile](#compile)
+ - [train](#train)
+ - [inference](#inference)
+ - [RCI Objects](#rci-objects)
+ - [data\_flow](#data_flow-1)
+ - [compile](#compile-1)
+ - [nets.dense](#netsdense)
+ - [Net Objects](#net-objects)
+ - [\_\_init\_\_](#__init__-1)
+ - [nets.design](#netsdesign)
+ - [B\_field\_norm](#b_field_norm)
+ - [nets.deep\_dense](#netsdeep_dense)
+ - [dmodel Objects](#dmodel-objects)
+ - [\_\_init\_\_](#__init__-2)
+
+
+
+# main
+
+
+
+# :orange[PINN]
+
+
+
+## PINN.pinns
+
+
+
+## PINNd\_p Objects
+
+```python
+class PINNd_p(nn.Module)
+```
+
+$d \mapsto P$
+
+
+
+## PINNhd\_ma Objects
+
+```python
+class PINNhd_ma(nn.Module)
+```
+
+$h,d \mapsto m_a $
+
+
+
+## PINNT\_ma Objects
+
+```python
+class PINNT_ma(nn.Module)
+```
+
+$ m_a, U \mapsto T$
+
+
+
+---
+# :orange[utils]
+
+
+
+## utils.test
+
+
+
+## utils.dataset\_loader
+
+
+
+#### get\_dataset
+
+```python
+def get_dataset(raw: bool = False,
+ sample_size: int = 1000,
+ name: str = 'dataset.pkl',
+ source: str = 'dataset.csv',
+ boundary_conditions: list = None) -> _pickle
+```
+
+Gets augmented dataset
+
+**Arguments**:
+
+- `raw` _bool, optional_ - either to use source data or augmented. Defaults to False.
+- `sample_size` _int, optional_ - sample size. Defaults to 1000.
+- `name` _str, optional_ - name of wanted dataset. Defaults to 'dataset.pkl'.
+- `boundary_conditions` _list,optional_ - y1,y2,x1,x2.
+
+**Returns**:
+
+- `_pickle` - pickle buffer
+
+
+
+## utils.ndgan
+
+
+
+### DCGAN Objects
+
+```python
+class DCGAN()
+```
+
+
+
+#### define\_discriminator
+
+```python
+def define_discriminator(inputs=8)
+```
+
+function to return the compiled discriminator model
+
+
+
+#### generate\_latent\_points
+
+```python
+def generate_latent_points(latent_dim, n)
+```
+
+generate points in latent space as input for the generator
+
+
+
+#### define\_gan
+
+```python
+def define_gan(generator, discriminator)
+```
+
+define the combined generator and discriminator model
+
+
+
+#### summarize\_performance
+
+```python
+def summarize_performance(epoch, generator, discriminator, latent_dim, n=200)
+```
+
+evaluate the discriminator and plot real and fake samples
+
+
+
+#### train\_gan
+
+```python
+def train_gan(g_model,
+ d_model,
+ gan_model,
+ latent_dim,
+ num_epochs=2500,
+ num_eval=2500,
+ batch_size=2)
+```
+
+function to train gan model
+
+
+
+## utils.data\_augmentation
+
+
+
+## dataset Objects
+
+```python
+class dataset()
+```
+
+Creates dataset from input source
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(number_samples: int,
+ name: str,
+ source: str,
+ boundary_conditions: list = None)
+```
+
+_summary_
+
+**Arguments**:
+
+- `number_samples` _int_ - _description_
+- `name` _str_ - _description_
+- `source` _str_ - _description_
+- `boundary_conditions` _list_ - y1,y2,x1,x2
+
+
+
+# :orange[nets]
+
+
+
+## nets.envs
+
+
+
+### SCI Objects
+
+```python
+class SCI()
+```
+
+
+
+#### data\_flow
+
+```python
+def data_flow(columns_idx: tuple = (1, 3, 3, 5),
+ idx: tuple = None,
+ split_idx: int = 800) -> torch.utils.data.DataLoader
+```
+
+Data prep pipeline
+
+**Arguments**:
+
+- `columns_idx` _tuple, optional_ - Columns to be selected (sliced 1:2 3:4) for feature fitting. Defaults to (1,3,3,5).
+- `idx` _tuple, optional_ - 2|3 indexes to be selected for feature fitting. Defaults to None. Use either idx or columns_idx (for F:R->R idx, for F:R->R2 columns_idx)
+ split_idx (int) : Index to split for training
+
+
+**Returns**:
+
+- `torch.utils.data.DataLoader` - Torch native dataloader
+
+
+
+#### init\_seed
+
+```python
+def init_seed(seed)
+```
+
+Initializes seed for torch optional()
+
+
+
+#### compile
+
+```python
+def compile(columns: tuple = None,
+ idx: tuple = None,
+ optim: torch.optim = torch.optim.AdamW,
+ loss: nn = nn.L1Loss,
+ model: nn.Module = dmodel,
+ custom: bool = False) -> None
+```
+
+Builds model, loss, optimizer. Has defaults
+
+**Arguments**:
+
+- `columns` _tuple, optional_ - Columns to be selected for feature fitting. Defaults to (1,3,3,5).
+ optim - torch Optimizer
+ loss - torch Loss function (nn)
+
+
+
+#### train
+
+```python
+def train(epochs: int = 10) -> None
+```
+
+Train model
+If sklearn instance uses .fit()
+
+
+
+#### inference
+
+```python
+def inference(X: tensor, model_name: str = None) -> np.ndarray
+```
+
+Inference of (pre-)trained model
+
+**Arguments**:
+
+- `X` _tensor_ - your data in domain of train
+
+
+**Returns**:
+
+- `np.ndarray` - predictions
+
+
+
+### RCI Objects
+
+```python
+class RCI(SCI)
+```
+
+
+
+#### data\_flow
+
+```python
+def data_flow(columns_idx: tuple = (1, 3, 3, 5),
+ idx: tuple = None,
+ split_idx: int = 800) -> torch.utils.data.DataLoader
+```
+
+Data prep pipeline
+
+**Arguments**:
+
+- `columns_idx` _tuple, optional_ - Columns to be selected (sliced 1:2 3:4) for feature fitting. Defaults to (1,3,3,5).
+- `idx` _tuple, optional_ - 2|3 indexes to be selected for feature fitting. Defaults to None. Use either idx or columns_idx (for F:R->R idx, for F:R->R2 columns_idx)
+ split_idx (int) : Index to split for training
+
+
+**Returns**:
+
+- `torch.utils.data.DataLoader` - Torch native dataloader
+
+
+
+#### compile
+
+```python
+def compile(columns: tuple = None,
+ idx: tuple = (3, 1),
+ optim: torch.optim = torch.optim.AdamW,
+ loss: nn = nn.L1Loss,
+ model: nn.Module = PINNd_p,
+ lr: float = 0.001) -> None
+```
+
+Builds model, loss, optimizer. Has defaults
+
+**Arguments**:
+
+- `columns` _tuple, optional_ - Columns to be selected for feature fitting. Defaults to None.
+- `idx` _tuple, optional_ - indexes to be selected Default (3,1)
+ optim - torch Optimizer
+ loss - torch Loss function (nn)
+
+
+
+## nets.dense
+
+
+
+### Net Objects
+
+```python
+class Net(nn.Module)
+```
+
+4 layer model, different activations and neurons count on layer
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(input_dim: int = 2, hidden_dim: int = 200)
+```
+
+Init
+
+**Arguments**:
+
+- `input_dim` _int, optional_ - Defaults to 2.
+- `hidden_dim` _int, optional_ - Defaults to 200.
+
+
+
+## nets.design
+
+
+
+#### B\_field\_norm
+
+```python
+def B_field_norm(Bmax, L, k=16, plot=True)
+```
+
+Returns vec B_z
+
+**Arguments**:
+
+- `Bmax` _any_ - maximum B in thruster
+ k - magnetic field profile number
+
+
+
+## nets.deep\_dense
+
+
+
+### dmodel Objects
+
+```python
+class dmodel(nn.Module)
+```
+
+4 layers Torch model. Relu activations, hidden layers are same size.
+
+
+
+#### \_\_init\_\_
+
+```python
+def __init__(in_features=1, hidden_features=200, out_features=1)
+```
+
+Init
+
+**Arguments**:
+
+- `in_features` _int, optional_ - Input features. Defaults to 1.
+- `hidden_features` _int, optional_ - Hidden dims. Defaults to 200.
+- `out_features` _int, optional_ - Output dims. Defaults to 1.
+
diff --git a/nets/__init__.py b/nets/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/nets/__pycache__/HET_dense.cpython-310.pyc b/nets/__pycache__/HET_dense.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f6b725112d696e00ad712d26fe8a2c9eb7ff8eaf
Binary files /dev/null and b/nets/__pycache__/HET_dense.cpython-310.pyc differ
diff --git a/nets/__pycache__/__init__.cpython-310.pyc b/nets/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c7075fc44dc13afea7ae877925856b0d914942ec
Binary files /dev/null and b/nets/__pycache__/__init__.cpython-310.pyc differ
diff --git a/nets/__pycache__/deep_dense.cpython-310.pyc b/nets/__pycache__/deep_dense.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f8de4260ea36135905cca57d49d6085d2f53dd8c
Binary files /dev/null and b/nets/__pycache__/deep_dense.cpython-310.pyc differ
diff --git a/nets/__pycache__/dense.cpython-310.pyc b/nets/__pycache__/dense.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..98dc4d3653460afb02a4b6a72c8af4c608b8c907
Binary files /dev/null and b/nets/__pycache__/dense.cpython-310.pyc differ
diff --git a/nets/__pycache__/design.cpython-310.pyc b/nets/__pycache__/design.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5fc732b9eabbebbfb7b794f16d584d9b329fc6f4
Binary files /dev/null and b/nets/__pycache__/design.cpython-310.pyc differ
diff --git a/nets/__pycache__/envs.cpython-310.pyc b/nets/__pycache__/envs.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aa7a9de70a5d8c24b08ddb9e909b72d71bc7ccf3
Binary files /dev/null and b/nets/__pycache__/envs.cpython-310.pyc differ
diff --git a/nets/deep_dense.py b/nets/deep_dense.py
new file mode 100644
index 0000000000000000000000000000000000000000..14ca122f73f1a191c0e3ad902b1e312985b7242a
--- /dev/null
+++ b/nets/deep_dense.py
@@ -0,0 +1,32 @@
+from torch import nn
+from torch.functional import F
+
+class dmodel(nn.Module):
+ """4 layers Torch model. Relu activations, hidden layers are same size.
+
+ """
+ def __init__(self, in_features=1, hidden_features=200, out_features=1):
+ """Init
+
+ Args:
+ in_features (int, optional): Input features. Defaults to 1.
+ hidden_features (int, optional): Hidden dims. Defaults to 200.
+ out_features (int, optional): Output dims. Defaults to 1.
+ """
+ super(dmodel, self).__init__()
+
+ self.fc1 = nn.Linear(in_features, hidden_features)
+ self.fc2 = nn.Linear(hidden_features, hidden_features)
+ self.fc3 = nn.Linear(hidden_features, hidden_features)
+ self.fc4 = nn.Linear(hidden_features, out_features)
+
+
+ def forward(self, x):
+ x = self.fc1(x)
+ x = F.relu(x) # ReLU activation
+ x = self.fc2(x)
+ x = F.relu(x) # ReLU activation
+ x = self.fc3(x)
+ x = F.relu(x) # ReLU activation
+ x = self.fc4(x)
+ return x
\ No newline at end of file
diff --git a/nets/dense.py b/nets/dense.py
new file mode 100644
index 0000000000000000000000000000000000000000..2465666612d1b2e4c392ecc5699c760162a649a2
--- /dev/null
+++ b/nets/dense.py
@@ -0,0 +1,27 @@
+from torch import nn
+
+class Net(nn.Module):
+ """4 layer model, different activations and neurons count on layer
+
+ """
+ def __init__(self,input_dim:int=2,hidden_dim:int=200):
+ """Init
+
+ Args:
+ input_dim (int, optional): Defaults to 2.
+ hidden_dim (int, optional): Defaults to 200.
+ """
+ super(Net,self).__init__()
+ self.input = nn.Linear(input_dim,40)
+ self.act1 = nn.Tanh()
+ self.layer = nn.Linear(40,80)
+ self.act2 = nn.ReLU()
+ self.layer1 = nn.Linear(80,hidden_dim)
+ self.act3 = nn.ReLU()
+ self.layer2 = nn.Linear(hidden_dim,1)
+
+ def forward(self, x):
+ x = self.act2(self.layer(self.act1(self.input(x))))
+ x = self.act3(self.layer1(x))
+ x = self.layer2(x)
+ return x
diff --git a/nets/design.py b/nets/design.py
new file mode 100644
index 0000000000000000000000000000000000000000..4fd3c7dc9b97ddf8556d17595a1195acc019405f
--- /dev/null
+++ b/nets/design.py
@@ -0,0 +1,42 @@
+import numpy as np
+import seaborn as sns
+import pandas as pd
+
+def B_field_norm(Bmax:float,L:float,k:int=16,plot=True) -> np.array:
+ """ Returns vec B_z for MS config
+
+ Args:
+ Bmax (any): maximum B in thruster
+ L - channel length
+ k - magnetic field profile number
+ """
+ z = np.linspace(0,L*1.4,200)
+ B = Bmax * np.exp(-k * (z/(1.2*L) - 1)**2)
+ if plot:
+ sns.lineplot(x=z,y=B)
+ return z,B
+
+def PUdesign(P:float,U:float) -> pd.DataFrame:
+ """Computes design via numerical model, uses fits from PINNs
+
+ Args:
+ P (float): _description_
+ U (float): _description_
+
+ Returns:
+ _type_: _description_
+ """
+ d = np.sqrt(P/(635*U))
+ h = 0.245*d
+ m_a = 0.0025*h*d
+ T = 890 * m_a * np.sqrt(U)
+ j = P/(np.pi*d*h)
+ Isp = T/(m_a*9.81)
+ nu_t = T*Isp*9.81/(2*P)
+ df = pd.DataFrame([[d,h,m_a,T,j,nu_t,Isp]],columns=['d','h','m_a','T','j','nu_t','Isp'])
+ g = sns.barplot(df,facecolor='gray')
+ g.set_yscale("log")
+ return df
+
+def cathode_erosion():
+ pass
\ No newline at end of file
diff --git a/nets/envs.py b/nets/envs.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f7c79f12f8bd13283e7c651d24f30dd8c06521f
--- /dev/null
+++ b/nets/envs.py
@@ -0,0 +1,491 @@
+from utils.dataset_loader import get_dataset
+from nets.dense import Net
+from nets.deep_dense import dmodel
+from PINN.pinns import *
+
+import matplotlib.pyplot as plt
+import seaborn as sns
+import torch
+import os
+import numpy as np
+from torch import nn, tensor
+import pandas as pd
+import plotly.express as px
+from sklearn.linear_model import SGDRegressor
+from sklearn.feature_selection import SelectFromModel
+
+class SCI(): #Scaled Computing Interface
+ """ Scaled computing interface.
+ Args:
+ hidden_dim (int, optional): Max demension of hidden linear layer. Defaults to 200. Should be >80 in not 1d case
+ dropout (bool, optional): LEGACY, don't use. Defaults to True.
+ epochs (int, optional): Optionally specify epochs here, but better in train. Defaults to 10.
+ dataset (str, optional): dataset to be selected from ./data. Defaults to 'test.pkl'. If name not exists, code will generate new dataset with upcoming parameters.
+ sample_size (int, optional): Samples to be generated (note: BEFORE applying boundary conditions). Defaults to 1000.
+ source (str, optional): Source from which data will be generated. Better to not change. Defaults to 'dataset.csv'.
+ boundary_conditions (list, optional): If sepcified, whole dataset will be cut rectangulary. Input list is [ymin,ymax,xmin,xmax] type. Defaults to None.
+ """
+ def __init__(self, hidden_dim:int = 200, dropout:bool = True, epochs:int = 10, dataset:str = 'test.pkl',sample_size:int=1000,source:str='dataset.csv',boundary_conditions:list=None):
+ """Init
+ Args:
+ hidden_dim (int, optional): Max demension of hidden linear layer. Defaults to 200. Should be >80 in not 1d case
+ dropout (bool, optional): LEGACY, don't use. Defaults to True.
+ epochs (int, optional): Optionally specify epochs here, but better in train. Defaults to 10.
+ dataset (str, optional): dataset to be selected from ./data. Defaults to 'test.pkl'. If name not exists, code will generate new dataset with upcoming parameters.
+ sample_size (int, optional): Samples to be generated (note: BEFORE applying boundary conditions). Defaults to 1000.
+ source (str, optional): Source from which data will be generated. Better to not change. Defaults to 'dataset.csv'.
+ boundary_conditions (list, optional): If sepcified, whole dataset will be cut rectangulary. Input list is [ymin,ymax,xmin,xmax] type. Defaults to None.
+ """
+ self.type:str = 'legacy'
+ self.seed:int = 449
+ self.dim = hidden_dim
+ self.dropout = dropout
+ self.df = get_dataset(sample_size=sample_size,source=source,name=dataset,boundary_conditions=boundary_conditions)
+ self.epochs = epochs
+ self.len_idx = 0
+ self.input_dim_for_check = 0
+
+ def feature_gen(self, base:bool=True, fname:str=None,index:int=None,func=None) -> None:
+ """ Generate new features. If base true, generates most obvious ones. You can customize this by adding
+ new feature as name of column - fname, index of parent column, and lambda function which needs to be applied elementwise.
+ Args:
+ base (bool, optional): Defaults to True.
+ fname (str, optional): Name of new column. Defaults to None.
+ index (int, optional): Index of parent column. Defaults to None.
+ func (_type_, optional): lambda function. Defaults to None.
+ """
+
+ if base:
+ self.df['P_sqrt'] = self.df.iloc[:,1].apply(lambda x: x ** 0.5)
+ self.df['j'] = self.df.iloc[:,1]/(self.df.iloc[:,3]*self.df.iloc[:,4])
+ self.df['B'] = self.df.iloc[:,-1].apply(lambda x: x ** 2).apply(lambda x:1 if x>1 else x)
+ self.df['nu_t'] = self.df.iloc[:,7]**2/(2*self.df.iloc[:,6]*self.df.P)
+
+ if fname and index and func:
+ self.df[fname] = self.df.iloc[:,index].apply(func)
+
+ def feature_importance(self,X:pd.DataFrame,Y:pd.Series,verbose:int=1):
+ """ Gets feature importance by SGD regression and score selection. Default threshold is 1.25*mean
+ input X as self.df.iloc[:,(columns of choice)]
+ Y as self.df.iloc[:,(column of choice)]
+ Args:
+ X (pd.DataFrame): Builtin DataFrame
+ Y (pd.Series): Builtin Series
+ verbose (int, optional): either to or to not print actual report. Defaults to 1.
+ Returns:
+ Report (str)
+ """
+
+ mod = SGDRegressor()
+
+ selector = SelectFromModel(mod,threshold='1.25*mean')
+ selector.fit(np.array(X),np.array(Y))
+
+ if verbose:
+ print(f'\n Report of feature importance: {dict(zip(X.columns,selector.estimator_.coef_))}')
+ for i in range(len(selector.get_support())):
+ if selector.get_support()[i]:
+ print(f'-rank 1 PASSED:',X.columns[i])
+ else:
+ print(f'-rank 0 REJECT:',X.columns[i])
+ return f'\n Report of feature importance: {dict(zip(X.columns,selector.estimator_.coef_))}'
+
+ def data_flow(self,columns_idx:tuple = (1,3,3,5), idx:tuple=None, split_idx:int = 800) -> torch.utils.data.DataLoader:
+ """ Data prep pipeline
+ It is called automatically, don't call it in your code.
+ Args:
+ columns_idx (tuple, optional): Columns to be selected (sliced 1:2 3:4) for feature fitting. Defaults to (1,3,3,5).
+ idx (tuple, optional): 2|3 indexes to be selected for feature fitting. Defaults to None. Use either idx or columns_idx (for F:R->R idx, for F:R->R2 columns_idx)
+ split_idx (int) : Index to split for training
+
+ Returns:
+ torch.utils.data.DataLoader: Torch native dataloader
+ """
+ batch_size=2
+
+ self.split_idx=split_idx
+
+ if idx!=None:
+ self.len_idx = len(idx)
+ if len(idx)==2:
+ self.X = tensor(self.df.iloc[:,idx[0]].values[:split_idx]).float()
+ self.Y = tensor(self.df.iloc[:,idx[1]].values[:split_idx]).float()
+ batch_size = 1
+ else:
+ self.X = tensor(self.df.iloc[:,[*idx[:-1]]].values[:split_idx,:]).float()
+ self.Y = tensor(self.df.iloc[:,idx[2]].values[:split_idx]).float()
+ else:
+ self.X = tensor(self.df.iloc[:,columns_idx[0]:columns_idx[1]].values[:split_idx,:]).float()
+ self.Y = tensor(self.df.iloc[:,columns_idx[2]:columns_idx[3]].values[:split_idx]).float()
+
+ print('Shapes for debug: (X,Y)',self.X.shape, self.Y.shape)
+ train_data = torch.utils.data.TensorDataset(self.X, self.Y)
+ Xtrain = torch.utils.data.DataLoader(train_data,batch_size=batch_size)
+ self.input_dim = self.X.size(-1)
+ self.indexes = idx if idx else columns_idx
+ self.column_names = [self.df.columns[i] for i in self.indexes]
+ return Xtrain
+
+ def init_seed(self,seed):
+ """ Initializes seed for torch optional()
+ """
+
+ torch.manual_seed(seed)
+
+ def train_epoch(self,X, model, loss_function, optim):
+ for i,data in enumerate(X):
+ Y_pred = model(data[0])
+ loss = loss_function(Y_pred, data[1])
+
+ # mean_abs_percentage_error = MeanAbsolutePercentageError()
+ # ape = mean_abs_percentage_error(Y_pred, data[1])
+
+ loss.backward()
+ optim.step()
+ optim.zero_grad()
+
+
+ ape_norm = abs(np.mean((Y_pred.detach().numpy()-data[1].detach().numpy())/(data[1].detach().numpy()+0.1)))
+ if (i+1)%200==0:
+ print(f'Iter {i+1} APE =',ape_norm)
+ self.loss_history.append(loss.data.item())
+ self.ape_history.append(None if ape_norm >1 else ape_norm)
+
+ def compile(self,columns:tuple=None,idx:tuple=None, optim:torch.optim = torch.optim.AdamW,loss:nn=nn.L1Loss, model:nn.Module = dmodel, custom:bool=False, lr:float=0.0001) -> None:
+ """ Builds model, loss, optimizer. Has defaults
+ Args:
+ columns (tuple, optional): Columns to be selected for feature fitting. Defaults to (1,3,3,5).
+ optim - torch Optimizer. Default AdamW
+ loss - torch Loss function (nn). Defaults to L1Loss
+ """
+
+ self.columns = columns
+
+
+ if not(columns):
+ self.len_idx = 0
+ else:
+ self.len_idx = len(columns)
+
+ if not(self.columns) and not(idx):
+ self.Xtrain = self.data_flow()
+ elif not(idx):
+ self.Xtrain = self.data_flow(columns_idx=self.columns)
+ else:
+ self.Xtrain = self.data_flow(idx=idx)
+
+ if custom:
+ self.model = model()
+ self.loss_function = loss()
+ self.optim = optim(self.model.parameters(), lr=lr)
+ if self.len_idx == 2:
+ self.input_dim_for_check = 1
+ else:
+ if self.len_idx == 2:
+ self.model = model(in_features=1,hidden_features=self.dim).float()
+ self.input_dim_for_check = 1
+ if self.len_idx == 3:
+ self.model = Net(input_dim=2,hidden_dim=self.dim).float()
+ if (self.len_idx != 2 or 3) or self.columns:
+ self.model = Net(input_dim=self.input_dim,hidden_dim=self.dim).float()
+
+ self.optim = optim(self.model.parameters(), lr=lr)
+ self.loss_function = loss()
+
+ if self.input_dim_for_check:
+ self.X = self.X.reshape(-1,1)
+
+
+
+ def train(self,epochs:int=10) -> None:
+ """ Train model
+ If sklearn instance uses .fit()
+
+ epochs - optional
+ """
+ if 'sklearn' in str(self.model.__class__):
+ self.model.fit(np.array(self.X),np.array(self.Y))
+ plt.scatter(self.X,self.model.predict(self.X))
+ plt.scatter(self.X,self.Y)
+ plt.xlabel('Xreal')
+ plt.ylabel('Ypred/Yreal')
+ plt.show()
+ return print('Sklearn model fitted successfully')
+ else:
+ self.model.train()
+
+ self.loss_history = []
+ self.ape_history = []
+
+ self.epochs = epochs
+
+
+ for j in range(self.epochs):
+ self.train_epoch(self.Xtrain,self.model,self.loss_function,self.optim)
+
+ plt.plot(self.loss_history,label='loss_history')
+ plt.legend()
+
+ def save(self,name:str='model.pt') -> None:
+ torch.save(self.model,name)
+
+ def onnx_export(self,path:str='./models/model.onnx'):
+ torch.onnx.export(self.model,self.X,path)
+
+ def jit_export(self,path:str='./models/model.pt'):
+ """Exports properly defined model to jit
+ Args:
+ path (str, optional): path to models. Defaults to './models/model.pt'.
+ """
+ torch.jit.save(self.model,path)
+
+ def inference(self,X:tensor, model_name:str=None) -> np.ndarray:
+ """ Inference of (pre-)trained model
+ Args:
+ X (tensor): your data in domain of train
+ Returns:
+ np.ndarray: predictions
+ """
+ if model_name is None:
+ self.model.eval()
+
+ if model_name in os.listdir('./models'):
+ model = torch.load(f'./models/{model_name}')
+ model.eval()
+ return model(X).detach().numpy()
+
+ return self.model(X).detach().numpy()
+
+ def plot(self):
+ """ Automatic 2d plot
+ """
+ self.model.eval()
+ print(self.Y.shape,self.model(self.X).detach().numpy().shape,self.X.shape)
+ if self.X.shape[-1] != self.model(self.X).detach().numpy().shape[-1]:
+ print('Size mismatch, try 3d plot, plotting by first dim of largest tensor')
+ if len(self.X.shape)==1:
+ X = self.X
+ else: X = self.X[:,0]
+ plt.scatter(X,self.model(self.X).detach().numpy(),label='predicted',s=2)
+ if len(self.Y.shape)!=1:
+ plt.scatter(X,self.Y[:,1],s=1,label='real')
+ else:
+ plt.scatter(X,self.Y,s=1,label='real')
+ plt.xlabel(rf'${self.column_names[0]}$')
+ plt.ylabel(rf'${self.column_names[1]}$')
+ plt.legend()
+ else:
+ plt.scatter(self.X,self.model(self.X).detach().numpy(),s=2,label='predicted')
+ plt.scatter(self.X,self.Y,s=1,label='real')
+ plt.xlabel(r'$X$')
+ plt.ylabel(r'$Y$')
+ plt.legend()
+
+ def plot3d(self,colX=0,colY=1):
+ """ Plot of inputs and predicted data in mesh format
+ Returns:
+ plotly plot
+ """
+ X = self.X
+ self.model.eval()
+ x = X[:,colX].numpy().ravel()
+ y = X[:,colY].numpy().ravel()
+ z = self.model(X).detach().numpy().ravel()
+ surf = px.scatter_3d(x=x, y=y,z=self.df.iloc[:,self.indexes[-1]].values[:self.split_idx],opacity=0.3,
+ labels={'x':f'{self.column_names[colX]}',
+ 'y':f'{self.column_names[colY]}',
+ 'z':f'{self.column_names[-1]}'
+ },title='Mesh prediction plot'
+ )
+ # fig.colorbar(surf, shrink=0.5, aspect=5)
+ surf.update_traces(marker_size=3)
+ surf.update_layout(plot_bgcolor='#888888')
+ surf.add_mesh3d(x=x, y=y, z=z, opacity=0.7,colorscale='sunsetdark',intensity=z,
+ )
+ # surf.show()
+
+ return surf
+ def performance(self,c=0.4) -> dict:
+ """ Automatic APE based performance if applicable, else returns nan
+ Args:
+ c (float, optional): ZDE mitigation constant. Defaults to 0.4.
+ Returns:
+ dict: {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+ """
+ a=[]
+ for i in range(1000):
+ a.append(100-abs(np.mean(self.df.iloc[1:24,1:8].values-self.df.iloc[24:,1:8].sample(23).values)/(self.Y.numpy()[1:]+c))*100)
+ gen_acc = np.mean(a)
+ ape = (100-abs(np.mean(self.model(self.X).detach().numpy()-self.Y.numpy()[1:])*100))
+ abs_ape = ape*gen_acc/100
+ return {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+
+ def performance_super(self,c=0.4,real_data_column_index:tuple = (1,8),real_data_samples:int=23, generated_length:int=1000) -> dict:
+ """Performance by custom parameters. APE loss
+ Args:
+ c (float, optional): ZDE mitigation constant. Defaults to 0.4.
+ real_data_column_index (tuple, optional): Defaults to (1,8).
+ real_data_samples (int, optional): Defaults to 23.
+ generated_length (int, optional): Defaults to 1000.
+ Returns:
+ dict: {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+ """
+ a=[]
+ for i in range(1000):
+ a.append(100-abs(np.mean(self.df.iloc[1:real_data_samples+1,real_data_column_index[0]:real_data_column_index[1]].values-self.df.iloc[real_data_samples+1:,real_data_column_index[0]:real_data_column_index[1]].sample(real_data_samples).values)/(self.Y.numpy()[1:]+c))*100)
+ gen_acc = np.mean(a)
+ ape = (100-abs(np.mean(self.model(self.X).detach().numpy()-self.Y.numpy()[1:])*100))
+ abs_ape = ape*gen_acc/100
+ return {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+
+ def performance_super(self,c=0.4,real_data_column_index:tuple = (1,8),real_data_samples:int=23, generated_length:int=1000) -> dict:
+ a=[]
+ for i in range(1000):
+ a.append(100-abs(np.mean(self.df.iloc[1:real_data_samples+1,real_data_column_index[0]:real_data_column_index[1]].values-self.df.iloc[real_data_samples+1:,real_data_column_index[0]:real_data_column_index[1]].sample(real_data_samples).values)/(self.Y.numpy()[1:]+c))*100)
+ gen_acc = np.mean(a)
+ ape = (100-abs(np.mean(self.model(self.X).detach().numpy()-self.Y.numpy()[1:])*100))
+ abs_ape = ape*gen_acc/100
+ return {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+ def performance_super(self,c=0.4,real_data_column_index:tuple = (1,8),real_data_samples:int=23, generated_length:int=1000) -> dict:
+ a=[]
+ for i in range(1000):
+ a.append(100-abs(np.mean(self.df.iloc[1:real_data_samples+1,real_data_column_index[0]:real_data_column_index[1]].values-self.df.iloc[real_data_samples+1:,real_data_column_index[0]:real_data_column_index[1]].sample(real_data_samples).values)/(self.Y.numpy()[1:]+c))*100)
+ gen_acc = np.mean(a)
+ ape = (100-abs(np.mean(self.model(self.X).detach().numpy()-self.Y.numpy()[1:])*100))
+ abs_ape = ape*gen_acc/100
+ return {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+
+class RCI(SCI): #Real object interface
+ """ Real values interface, uses different types of NN, NO scaling.
+ Parent:
+ SCI()
+ """
+ def __init__(self,*args,**kwargs):
+ super(RCI,self).__init__()
+
+ def data_flow(self,columns_idx:tuple = (1,3,3,5), idx:tuple=None, split_idx:int = 800) -> torch.utils.data.DataLoader:
+ """ Data prep pipeline
+ Args:
+ columns_idx (tuple, optional): Columns to be selected (sliced 1:2 3:4) for feature fitting. Defaults to (1,3,3,5).
+ idx (tuple, optional): 2|3 indexes to be selected for feature fitting. Defaults to None. Use either idx or columns_idx (for F:R->R idx, for F:R->R2 columns_idx)
+ split_idx (int) : Index to split for training
+
+ Returns:
+ torch.utils.data.DataLoader: Torch native dataloader
+ """
+ batch_size=2
+
+ real_scale = pd.read_csv('data/dataset.csv').iloc[17,1:].to_numpy()
+ self.df.iloc[:,1:] = self.df.iloc[:,1:] * real_scale
+
+ self.split_idx=split_idx
+
+
+ if idx!=None:
+ self.len_idx = len(idx)
+ if len(idx)==2:
+ self.X = tensor(self.df.iloc[:,idx[0]].values[:split_idx].astype(float)).float()
+ self.Y = tensor(self.df.iloc[:,idx[1]].values[:split_idx].astype(float)).float()
+ batch_size = 1
+ else:
+ self.X = tensor(self.df.iloc[:,[idx[0],idx[1]]].values[:split_idx,:].astype(float)).float()
+ self.Y = tensor(self.df.iloc[:,idx[2]].values[:split_idx].astype(float)).float()
+ else:
+ self.X = tensor(self.df.iloc[:,columns_idx[0]:columns_idx[1]].values[:split_idx,:].astype(float)).float()
+ self.Y = tensor(self.df.iloc[:,columns_idx[2]:columns_idx[3]].values[:split_idx].astype(float)).float()
+ self.Y = self.Y.abs()
+ self.X = self.X.abs()
+
+ print('Shapes for debug: (X,Y)',self.X.shape, self.Y.shape)
+ train_data = torch.utils.data.TensorDataset(self.X, self.Y)
+ Xtrain = torch.utils.data.DataLoader(train_data,batch_size=batch_size)
+ self.input_dim = self.X.size(-1)
+ self.indexes = idx if idx else columns_idx
+ self.column_names = [ self.df.columns[i] for i in self.indexes ]
+
+
+
+
+ return Xtrain
+
+ def compile(self,columns:tuple=None,idx:tuple=(3,1), optim:torch.optim = torch.optim.AdamW,loss:nn=nn.L1Loss, model:nn.Module = PINNd_p,lr:float=0.001) -> None:
+ """ Builds model, loss, optimizer. Has defaults
+ Args:
+ columns (tuple, optional): Columns to be selected for feature fitting. Defaults to None.
+ idx (tuple, optional): indexes to be selected Default (3,1)
+ optim - torch Optimizer
+ loss - torch Loss function (nn)
+ """
+
+ self.columns = columns
+
+
+ if not(columns):
+ self.len_idx = 0
+ else:
+ self.len_idx = len(columns)
+
+ if not(self.columns) and not(idx):
+ self.Xtrain = self.data_flow()
+ elif not(idx):
+ self.Xtrain = self.data_flow(columns_idx=self.columns)
+ else:
+ self.Xtrain = self.data_flow(idx=idx)
+
+ self.model = model().float()
+ self.input_dim_for_check = self.X.size(-1)
+
+ self.optim = optim(self.model.parameters(), lr=lr)
+ self.loss_function = loss()
+
+ if self.input_dim_for_check == 1:
+ self.X = self.X.reshape(-1,1)
+ def plot(self):
+ """ Plots 2d plot of prediction vs real values
+ """
+ self.model.eval()
+ if 'PINN' in str(self.model.__class__):
+ self.preds=np.array([])
+ for i in self.X:
+ self.preds = np.append(self.preds,self.model(i).detach().numpy())
+ print(self.Y.shape,self.preds.shape,self.X.shape)
+ if self.X.shape[-1] != self.preds.shape[-1]:
+ print('Size mismatch, try 3d plot, plotting by first dim of largest tensor')
+ try: X = self.X[:,0]
+ except:
+ X = self.X
+ pass
+ plt.scatter(X,self.preds,label='predicted',s=2)
+ if self.Y.shape[-1]!=1:
+ sns.scatterplot(x=X,y=self.Y,s=2,label='real')
+ else:
+ sns.scatterplot(x=X,y=self.Y,s=1,label='real')
+ plt.xlabel(rf'${self.column_names[0]}$')
+ plt.ylabel(rf'${self.column_names[1]}$')
+ plt.legend()
+ else:
+ sns.scatterplot(x=self.X,y=self.preds,s=2,label='predicted')
+ sns.scatterplot(x=self.X,y=self.Y,s=1,label='real')
+ plt.xlabel(r'$X$')
+ plt.ylabel(r'$Y$')
+ plt.legend()
+
+ def performance(self,c=0.4) -> dict:
+ """RCI performnace. APE errors.
+ Args:
+ c (float, optional): correction constant to mitigate division by 0 error. Defaults to 0.4.
+ Returns:
+ dict: {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+ """
+ a=[]
+ for i in range(1000):
+ dfcopy = (self.df.iloc[:,1:8]-self.df.iloc[:,1:8].min())/(self.df.iloc[:,1:8].max()-self.df.iloc[:,1:8].min())
+ a.append(100-abs(np.mean(dfcopy.iloc[1:24,1:].values-dfcopy.iloc[24:,1:].sample(23).values)/(dfcopy.iloc[1:24,1:].values+c))*100)
+ gen_acc = np.mean(a)
+
+ ape = (100-abs(np.mean(self.preds-self.Y.numpy())*100))
+ abs_ape = ape*gen_acc/100
+ return {'Generator_Accuracy, %':np.mean(a),'APE_abs, %':abs_ape,'Model_APE, %': ape}
+
+
+
\ No newline at end of file
diff --git a/nets/opti/__init__.py b/nets/opti/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/nets/opti/__pycache__/__init__.cpython-310.pyc b/nets/opti/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4f50fc11d48d27fa5059f206147f75dcfc8626bd
Binary files /dev/null and b/nets/opti/__pycache__/__init__.cpython-310.pyc differ
diff --git a/nets/opti/__pycache__/blackbox.cpython-310.pyc b/nets/opti/__pycache__/blackbox.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d3732fb7ac591c146fbe2b16310104ce7eb7055d
Binary files /dev/null and b/nets/opti/__pycache__/blackbox.cpython-310.pyc differ
diff --git a/nets/opti/blackbox.py b/nets/opti/blackbox.py
new file mode 100644
index 0000000000000000000000000000000000000000..98900d67b9c5cd544153ce3d1a447f5d55d5c89f
--- /dev/null
+++ b/nets/opti/blackbox.py
@@ -0,0 +1,163 @@
+from nets.envs import SCI
+
+import os
+import numpy as np
+import optuna
+from optuna.trial import TrialState
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import torch.optim as optim
+import torch.utils.data
+from torchmetrics import R2Score
+import neptune.new as neptune
+import neptune.new.integrations.optuna as outils
+from optuna.visualization import plot_contour, plot_optimization_history,plot_parallel_coordinate
+
+DEVICE = torch.device("cpu")
+BATCHSIZE = 2
+DIR = os.getcwd()
+EPOCHS = 10
+N_TRAIN_EXAMPLES = BATCHSIZE * 10
+N_VALID_EXAMPLES = BATCHSIZE * 10
+
+class Hyper(SCI):
+ """ Hyper parameter tunning class. Allows to generate best NN architecture for task. Inputs are column indexes. idx[-1] is targeted value.
+
+
+ """
+ def __init__(self,idx:tuple=(1,3,7),*args, **kwargs):
+ super(Hyper,self).__init__()
+ self.loader = self.data_flow(idx=idx)
+
+ # call self dataflow
+ def define_model(self,trial):
+ # We optimize the number of layers, hidden units and
+ n_layers = trial.suggest_int("n_layers", 2, 6)
+ layers = []
+
+ in_features = self.input_dim
+
+ for i in range(n_layers):
+ out_features = trial.suggest_int("n_units_l{}".format(i), 4, 128)
+ activations = trial.suggest_categorical('activation',['ReLU','Tanh','SiLU','SELU','RReLU'])
+
+ layers.append(nn.Linear(in_features, out_features))
+ layers.append(getattr(nn,activations)())
+ p = trial.suggest_float("dropout_l{}".format(i), 0.0, 0.2)
+ layers.append(nn.Dropout(p))
+
+ in_features = out_features
+ layers.append(nn.Linear(in_features, 1))
+
+ return nn.Sequential(*layers)
+ def objective(self,trial):
+ # Generate the model.
+ model = self.define_model(trial).to(DEVICE)
+ mape = R2Score()
+ # Generate the optimizers.
+ optimizer_name = trial.suggest_categorical("optimizer", ["Adam", "RMSprop", "SGD",'AdamW','Adamax','Adagrad'])
+ lr = trial.suggest_float("lr", 1e-7, 1e-3, log=True)
+ optimizer = getattr(optim, optimizer_name)(model.parameters(), lr=lr)
+
+ train_loader, valid_loader = self.loader,self.loader
+
+ # Training of the model.
+ for epoch in range(EPOCHS):
+ model.train()
+ for batch_idx, (data, target) in enumerate(train_loader):
+ # Limiting training data for faster epochs.
+ if batch_idx * BATCHSIZE >= N_TRAIN_EXAMPLES:
+ break
+
+ data, target = data.view(data.size(0), -1).to(DEVICE), target.to(DEVICE)
+
+ optimizer.zero_grad()
+ output = model(data)
+ loss = F.mse_loss(output, target)
+ loss.backward()
+ optimizer.step()
+
+ # Validation of the model.
+ model.eval()
+ correct = 0
+ pred=torch.tensor([])
+ targs=torch.tensor([])
+ with torch.no_grad():
+ for batch_idx, (data, target) in enumerate(valid_loader):
+ # Limiting validation data.
+ if batch_idx * BATCHSIZE >= N_VALID_EXAMPLES:
+ break
+ data, target = data.view(data.size(0), -1).to(DEVICE), target.to(DEVICE)
+
+ output = model(data)
+ # print(output,target)
+ # print(output.squeeze()-target)
+ # # Get the index of the max log-probability.
+ pred = torch.cat((pred,output.squeeze()))
+ targs = torch.cat((targs,target))
+ # correct += pred.eq(target.view_as(pred)).sum().item()
+
+ accuracy = mape(pred,targs)
+
+ trial.report(accuracy, epoch)
+
+ # Handle pruning based on the intermediate value.
+ if trial.should_prune():
+ raise optuna.exceptions.TrialPruned()
+
+ return accuracy
+
+ def start_study(self,n_trials:int=100,neptune_project:str=None,neptune_api:str=None):
+ """ Starts study. Optionally provide your neptune repo and token for report generation.
+
+ Args:
+ n_trials (int, optional): Number of iterations. Defaults to 100.
+ neptune_project (str, optional): . Defaults to None.
+ neptune_api (str, optional):. Defaults to None.
+
+ Returns:
+ dict: quick report of results
+ """
+
+ study = optuna.create_study(direction="maximize")
+ if neptune_project and neptune_api:
+ run = neptune.init_run(
+ project=neptune_project,
+ api_token=neptune_api,
+ )
+ neptune_callback = outils.NeptuneCallback(run)
+ study.optimize(self.objective, n_trials=n_trials, timeout=600,callbacks=[neptune_callback])
+ else:
+ study.optimize(self.objective, n_trials=n_trials, timeout=600)
+
+
+
+ pruned_trials = study.get_trials(deepcopy=False, states=[TrialState.PRUNED])
+ complete_trials = study.get_trials(deepcopy=False, states=[TrialState.COMPLETE])
+
+ print("Study statistics: ")
+ print(" Number of finished trials: ", len(study.trials))
+ print(" Number of pruned trials: ", len(pruned_trials))
+ print(" Number of complete trials: ", len(complete_trials))
+
+ print("Best trial:")
+ self.trial = study.best_trial
+
+ print(" Value: ", self.trial.value)
+
+ print(" Params: ")
+ for key, value in self.trial.params.items():
+ print(" {}: {}".format(key, value))
+
+ if neptune_api and neptune_project:
+ run.stop()
+
+ return {" Number of finished trials: ":len(study.trials),
+ " Number of pruned trials: ": len(pruned_trials),
+ " Number of complete trials: ": len(complete_trials),
+ "Best trial score" : self.trial.value,
+ " Params: ": self.trial.params
+ },plot_contour(study, params=["lr", "n_layers"]),\
+ plot_optimization_history(study),\
+ plot_parallel_coordinate(study)
\ No newline at end of file
diff --git a/objective.png b/objective.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7b3d7a6893b18278d2042f02a8337b412d7bee8
Binary files /dev/null and b/objective.png differ
diff --git "a/pages/\360\237\223\203 Docs.py" "b/pages/\360\237\223\203 Docs.py"
new file mode 100644
index 0000000000000000000000000000000000000000..45a069a78a2da038910a99c5db682f0b69b45a94
--- /dev/null
+++ "b/pages/\360\237\223\203 Docs.py"
@@ -0,0 +1,6 @@
+import streamlit as st
+
+st.header('Welcome to Docs!')
+with open('main.md','r+') as f:
+ mdfile = f.read()
+st.markdown(mdfile,unsafe_allow_html=True)
diff --git "a/pages/\360\237\224\215 Finding design optima.py" "b/pages/\360\237\224\215 Finding design optima.py"
new file mode 100644
index 0000000000000000000000000000000000000000..5cb123dc75b026f6609557d66aba635847dc36b7
--- /dev/null
+++ "b/pages/\360\237\224\215 Finding design optima.py"
@@ -0,0 +1,161 @@
+import streamlit as st
+
+
+st.markdown('## :orange[Finding optimal HET design]')
+st.markdown(' Firstly we import SCI environment from HETFit module as well as design design module which will plot magnetic flux on $d{B}/d{z}$ Magntically shielded HET configuration and function to get whole deisgn of HET via just $P,U$ as inputs')
+st.markdown(' We are generating new features and specifying new domain based on $n_t$ value ')
+st.code("""
+from nets.envs import SCI
+import torch
+from nets.design import B_field_norm,PUdesign
+B = B_field_norm(0.0002,14,k=16)
+a = SCI()
+a.feature_gen()
+a.df = a.df[(a.df.nu_t < 0.66) & (a.df.nu_t > 0)]
+ """)
+import plotly.express as px
+from nets.envs import SCI
+import torch
+from nets.design import B_field_norm
+data = B_field_norm(0.0002,14,k=16)
+fig = px.line(y=data[1],x=data[0],labels={'y':'B','x':'L'})
+st.write(fig)
+a = SCI()
+a.feature_gen()
+a.df = a.df[(a.df.nu_t < 0.66) & (a.df.nu_t > 0)]
+
+st.markdown('\n As you can see it is possible to access every bit of data you are working on via simple HETFit interface\n---')
+st.code("""
+ a.compile(idx=(1,2,3,4,5,7,-1))\na.train()
+ """)
+a.compile(idx=(1,2,3,4,5,7,-1))
+a.train()
+st.markdown(
+ "\n #### We select the $P,U,d,h,L,T$ columns for this case. As we know the geometry and needed thrust."
+ "\n---\n"
+ " Now we will assemble 2d matrix where rows are $n_t$ values and i,j (U,d) are changing. $h = 0.242*d$ as per PINN, L is approximated to be 2h, T - const = 0.3")
+
+st.code("""
+from torch import tensor
+import numpy as np
+
+y=[]
+for i in np.arange(0.1,0.8,0.01):
+ x=[]
+ for j in np.arange(0.1,0.8,0.01):
+ x.append(a.inference(tensor([0.25,float(i),float(j),float(j*0.242),2*float(j*0.242),0.3])).item())
+ y.append(x)
+
+ """)
+st.markdown('---')
+from torch import tensor
+import numpy as np
+
+y=[]
+for i in np.arange(0.1,0.8,0.01):
+ x=[]
+ for j in np.arange(0.1,0.8,0.01):
+ x.append(a.inference(tensor([0.25,float(i),float(j),float(j*0.242),2*float(j*0.242),0.3])).item())
+ y.append(x)
+
+st.markdown("#### Now we plot and analyze: Seems like you need higher voltages and channel diamater for higher efficiencies.\n---")
+st.code("""
+fig = px.imshow(np.array(y),labels={r'x':r'$d_s$',r'y':r'$U_s$',r'color':r'$n_t$'})
+fig.update_layout(
+ dragmode='drawrect', # define dragmode
+ newshape=dict(line_color='cyan'))
+# Add modebar buttons
+fig.show(config={'modeBarButtonsToAdd':['drawline',
+ 'drawopenpath',
+ 'drawclosedpath',
+ 'drawrect',
+ 'eraseshape'
+ ]})
+ """)
+
+fig = px.imshow(np.array(y),labels={r'x':r'd',r'y':r'U',r'color':r'n_t'},title=r'U,d -> n_t at P,h,L,T Invariants')
+fig.update_layout(
+ dragmode='drawrect', # define dragmode
+ newshape=dict(line_color='cyan'))
+# Add modebar buttons
+st.write(fig,include_mathjax='cdn')
+
+st.markdown('---\nUsing this strategy we just have assembled model for $U,d \mapsto n_t$ with other design variables as invariants. It also can be done another way by overlaying predictions of two varibles models.')
+
+###
+if st.button(r'Generate $f:R^2 \to R$ maps',use_container_width=True):
+ a.compile(idx=(2,3,-1))
+ a.train()
+
+ y=[]
+ for i in np.arange(0.1,0.8,0.01):
+ x=[]
+ for j in np.arange(0.1,0.8,0.01):
+ x.append(a.inference(tensor([float(i),float(j)])).item())
+ y.append(x)
+
+ fig = px.imshow(np.array(y),labels={r'x':r'd',r'y':r'U',r'color':r'n_t'},title=r'U,d -> n_t')
+ fig.update_layout(
+ dragmode='drawrect', # define dragmode
+ newshape=dict(line_color='cyan'))
+ # Add modebar buttons
+ st.write(fig)
+
+
+
+
+ a.compile(idx=(3,4,-1))
+ a.train()
+
+ y=[]
+ for i in np.arange(0.1,0.8,0.01):
+ x=[]
+ for j in np.arange(0.1,0.8,0.01):
+ x.append(a.inference(tensor([float(i),float(j)])).item())
+ y.append(x)
+
+ fig = px.imshow(np.array(y),labels={r'x':r'h',r'y':r'd',r'color':r'n_t'},title=r'd,h -> n_t')
+ fig.update_layout(
+ dragmode='drawrect', # define dragmode
+ newshape=dict(line_color='cyan'))
+ # Add modebar buttons
+ st.write(fig)
+
+
+ ###
+
+ a.compile(idx=(6,7,-1))
+ a.train()
+
+ y=[]
+ for i in np.arange(0.1,0.8,0.01):
+ x=[]
+ for j in np.arange(0.1,0.8,0.01):
+ x.append(a.inference(tensor([float(i),float(j)])).item())
+ y.append(x)
+
+ fig = px.imshow(np.array(y),labels={r'x':r'T',r'y':r'm_a',r'color':r'n_t'},title=r'm_a,T -> n_t')
+ fig.update_layout(
+ dragmode='drawrect', # define dragmode
+ newshape=dict(line_color='cyan'))
+ # Add modebar buttons
+ st.write(fig)
+
+ ###
+ a.compile(idx=(7,8,-1))
+ a.train()
+
+ y=[]
+ for i in np.arange(0.1,0.8,0.01):
+ x=[]
+ for j in np.arange(0.1,0.8,0.01):
+ x.append(a.inference(tensor([float(i),float(j)])).item())
+ y.append(x)
+
+ fig = px.imshow(np.array(y),labels={r'x':r'Isp',r'y':r'T',r'color':r'n_t'}, title=r'T,Isp -> n_t')
+ fig.update_layout(
+ dragmode='drawrect', # define dragmode
+ newshape=dict(line_color='cyan'))
+ # Add modebar buttons
+ st.write(fig)
+
diff --git "a/pages/\360\237\244\227 Intro.py" "b/pages/\360\237\244\227 Intro.py"
new file mode 100644
index 0000000000000000000000000000000000000000..dba93787a56f4e3ab61db8e0dbffe91aa433cb5a
--- /dev/null
+++ "b/pages/\360\237\244\227 Intro.py"
@@ -0,0 +1,10 @@
+import os
+import re
+import base64
+from pathlib import Path
+
+import streamlit as st
+
+with open('intro.md', 'r') as f:
+ st.markdown(f.read(),unsafe_allow_html=True)
+
diff --git "a/pages/\360\237\247\252 Optmiziations.py" "b/pages/\360\237\247\252 Optmiziations.py"
new file mode 100644
index 0000000000000000000000000000000000000000..58df74284545826e603f833a132ea612a9770f43
--- /dev/null
+++ "b/pages/\360\237\247\252 Optmiziations.py"
@@ -0,0 +1,23 @@
+from nets.opti.blackbox import Hyper
+import streamlit as st
+
+with open('bb.md','r+') as f:
+ st.markdown(f.read(),unsafe_allow_html=True)
+
+st.code('from nets.opti.blackbox import Hyper')
+st.code('api = Hyper(**kwargs)')
+api = Hyper()
+st.code('api.start_study(n_trials=n,neptune_id,neptune_api)')
+run = None
+def study():
+ run = api.start_study(50)
+ st.success('Study Finished!',icon='✅')
+ st.markdown('### :orange[Most recent run:]')
+ st.write(run[0])
+ st.write(run[1])
+ st.write(run[2])
+ st.write(run[3])
+if st.button('Start study',use_container_width=True):
+ st.info('Study is running',icon='🔄')
+ study()
+
diff --git a/pydoc-markdown.yml b/pydoc-markdown.yml
new file mode 100644
index 0000000000000000000000000000000000000000..0efd50c42dcaf07c2de2a9d52c422888b7bed97b
--- /dev/null
+++ b/pydoc-markdown.yml
@@ -0,0 +1,22 @@
+loaders:
+ - type: python
+processors:
+ - type: filter
+ - type: smart
+ - type: crossref
+renderer:
+ type: hugo
+ config:
+ title: My Project
+ theme: {clone_url: "https://github.com/alex-shpak/hugo-book.git"}
+ # The "book" theme only renders pages in "content/docs" into the nav.
+ content_directory: content/docs
+ default_preamble: {menu: main}
+ pages:
+ - title: Home
+ name: index
+ source: README.md
+ - title: API Documentation
+ children:
+ - title: my_project
+ contents: [ my_project, my_project.* ]
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f35e11b873ba06184a85a8fdccf9a88f3329d3f4
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,166 @@
+absl-py==1.4.0
+alembic==1.9.4
+altair==4.2.2
+appnope==0.1.3
+arrow==1.2.3
+asttokens==2.2.1
+astunparse==1.6.3
+attrs==22.2.0
+backcall==0.2.0
+blinker==1.5
+boto3==1.26.79
+botocore==1.29.79
+bravado==11.0.3
+bravado-core==5.17.1
+cachetools==5.3.0
+certifi==2022.12.7
+charset-normalizer==3.0.1
+click==8.1.3
+cmaes==0.9.1
+colorlog==6.7.0
+comm==0.1.2
+contourpy==1.0.7
+cycler==0.11.0
+databind==1.5.3
+databind.core==1.5.3
+databind.json==1.5.3
+debugpy==1.6.6
+decorator==5.1.1
+Deprecated==1.2.13
+docspec==2.0.2
+docspec-python==2.0.2
+docstring-parser==0.11
+entrypoints==0.4
+executing==1.2.0
+fastjsonschema==2.16.2
+flatbuffers==23.1.21
+fonttools==4.38.0
+fqdn==1.5.1
+future==0.18.3
+gast==0.4.0
+gitdb==4.0.10
+GitPython==3.1.31
+google-auth==2.16.1
+google-auth-oauthlib==0.4.6
+google-pasta==0.2.0
+grpcio==1.51.3
+h5py==3.8.0
+idna==3.4
+importlib-metadata==6.0.0
+ipykernel==6.21.2
+ipython==8.10.0
+isoduration==20.11.0
+jedi==0.18.2
+Jinja2==3.1.2
+jmespath==1.0.1
+joblib==1.2.0
+jsonpointer==2.3
+jsonref==1.1.0
+jsonschema==4.17.3
+jupyter_client==8.0.3
+jupyter_core==5.2.0
+keras==2.11.0
+kiwisolver==1.4.4
+lazydocs==0.4.8
+libclang==15.0.6.1
+Mako==1.2.4
+Markdown==3.4.1
+markdown-it-py==2.2.0
+MarkupSafe==2.1.2
+matplotlib==3.7.0
+matplotlib-inline==0.1.6
+mdurl==0.1.2
+monotonic==1.6
+msgpack==1.0.4
+nbformat==5.7.3
+neptune==1.0.0
+neptune-client==0.16.18
+neptune-optuna==1.0.0
+nest-asyncio==1.5.6
+nr.util==0.8.12
+numpy==1.24.2
+oauthlib==3.2.2
+opt-einsum==3.3.0
+optuna==3.1.0
+packaging==23.0
+pandas==1.5.3
+parso==0.8.3
+pexpect==4.8.0
+pickleshare==0.7.5
+Pillow==9.4.0
+platformdirs==3.0.0
+plotly==5.13.0
+prompt-toolkit==3.0.37
+protobuf==3.19.6
+psutil==5.9.4
+ptyprocess==0.7.0
+pure-eval==0.2.2
+pyarrow==11.0.0
+pyasn1==0.4.8
+pyasn1-modules==0.2.8
+Pycco==0.6.0
+pydeck==0.8.0
+pydoc-markdown==4.6.4
+Pygments==2.14.0
+PyJWT==2.6.0
+pylit==0.8.0
+Pympler==1.0.1
+pyparsing==3.0.9
+pyrsistent==0.19.3
+pystache==0.6.0
+python-dateutil==2.8.2
+pytz==2022.7.1
+pytz-deprecation-shim==0.1.0.post0
+PyYAML==5.4.1
+pyzmq==25.0.0
+requests==2.28.2
+requests-oauthlib==1.3.1
+rfc3339-validator==0.1.4
+rfc3987==1.3.8
+rich==13.3.1
+rsa==4.9
+s3transfer==0.6.0
+scikit-learn==1.2.1
+scipy==1.10.1
+seaborn==0.12.2
+semver==2.13.0
+simplejson==3.18.3
+six==1.16.0
+smartypants==2.0.1
+smmap==5.0.0
+SQLAlchemy==2.0.4
+stack-data==0.6.2
+streamlit==1.18.1
+swagger-spec-validator==3.0.3
+tenacity==8.2.1
+tensorboard==2.11.2
+tensorboard-data-server==0.6.1
+tensorboard-plugin-wit==1.8.1
+tensorflow-estimator==2.11.0
+tensorflow==2.11.0
+termcolor==2.2.0
+threadpoolctl==3.1.0
+toml==0.10.2
+tomli==2.0.1
+tomli_w==1.0.0
+toolz==0.12.0
+torch==1.13.1
+torchmetrics==0.11.1
+tornado==6.2
+tqdm==4.64.1
+traitlets==5.9.0
+typer==0.7.0
+typing_extensions==4.5.0
+tzdata==2022.7
+tzlocal==4.2
+uri-template==1.2.0
+urllib3==1.26.14
+validators==0.20.0
+watchdog==2.2.1
+wcwidth==0.2.6
+webcolors==1.12
+websocket-client==1.5.1
+Werkzeug==2.2.3
+wrapt==1.14.1
+yapf==0.32.0
+zipp==3.14.0
diff --git a/topgeom.png b/topgeom.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ca02eacab8ab0f1c69273443e38d73d8751df05
Binary files /dev/null and b/topgeom.png differ
diff --git a/unet.html b/unet.html
new file mode 100644
index 0000000000000000000000000000000000000000..37847599eb3624ab69a98a42009d924259c9a55c
--- /dev/null
+++ b/unet.html
@@ -0,0 +1,1458 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
U-Net model for Denoising Diffusion Probabilistic Models (DDPM)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This is a U-Net based model to predict noise ϵ θ ( x t , t ) .
+
U-Net is a gets it's name from the U shape in the model diagram. It processes a given image by progressively lowering (halving) the feature map resolution and then increasing the resolution. There are pass-through connection at each resolution.
+
+
This implementation contains a bunch of modifications to original U-Net (residual blocks, multi-head attention) and also adds time-step embeddings t .
+
+
+
+
24 import math
+25 from typing import Optional , Tuple , Union , List
+26
+27 import torch
+28 from torch import nn
+29
+30 from labml_helpers.module import Module
+
+
+
+
+
+
Swish actiavation function
+
x ⋅ σ ( x )
+
+
+
+
+
+
+
+
40 def forward ( self , x ):
+41 return x * torch . sigmoid ( x )
+
+
+
+
+
+
44 class TimeEmbedding ( nn . Module ):
+
+
+
+
+
+
n_channels
+ is the number of dimensions in the embedding
+
+
+
+
49 def __init__ ( self , n_channels : int ):
+
+
+
+
+
+
53 super () . __init__ ()
+54 self . n_channels = n_channels
+
+
+
+
+
+
First linear layer
+
+
+
+
56 self . lin1 = nn . Linear ( self . n_channels // 4 , self . n_channels )
+
+
+
+
+
+
+
Second linear layer
+
+
+
+
60 self . lin2 = nn . Linear ( self . n_channels , self . n_channels )
+
+
+
+
+
+
62 def forward ( self , t : torch . Tensor ):
+
+
+
+
+
+
72 half_dim = self . n_channels // 8
+73 emb = math . log ( 10_000 ) / ( half_dim - 1 )
+74 emb = torch . exp ( torch . arange ( half_dim , device = t . device ) * - emb )
+75 emb = t [:, None ] * emb [ None , :]
+76 emb = torch . cat (( emb . sin (), emb . cos ()), dim = 1 )
+
+
+
+
+
+
Transform with the MLP
+
+
+
+
79 emb = self . act ( self . lin1 ( emb ))
+80 emb = self . lin2 ( emb )
+
+
+
+
+
+
+
Residual block
+
A residual block has two convolution layers with group normalization. Each resolution is processed with two residual blocks.
+
+
+
+
86 class ResidualBlock ( Module ):
+
+
+
+
+
+
in_channels
+ is the number of input channels
+out_channels
+ is the number of input channels
+time_channels
+ is the number channels in the time step (t ) embeddings
+n_groups
+ is the number of groups for group normalization
+dropout
+ is the dropout rate
+
+
+
+
94 def __init__ ( self , in_channels : int , out_channels : int , time_channels : int ,
+95 n_groups : int = 32 , dropout : float = 0.1 ):
+
+
+
+
+
+
+
Group normalization and the first convolution layer
+
+
+
+
105 self . norm1 = nn . GroupNorm ( n_groups , in_channels )
+106 self . act1 = Swish ()
+107 self . conv1 = nn . Conv2d ( in_channels , out_channels , kernel_size = ( 3 , 3 ), padding = ( 1 , 1 ))
+
+
+
+
+
+
Group normalization and the second convolution layer
+
+
+
+
110 self . norm2 = nn . GroupNorm ( n_groups , out_channels )
+111 self . act2 = Swish ()
+112 self . conv2 = nn . Conv2d ( out_channels , out_channels , kernel_size = ( 3 , 3 ), padding = ( 1 , 1 ))
+
+
+
+
+
+
If the number of input channels is not equal to the number of output channels we have to project the shortcut connection
+
+
+
+
116 if in_channels != out_channels :
+117 self . shortcut = nn . Conv2d ( in_channels , out_channels , kernel_size = ( 1 , 1 ))
+118 else :
+119 self . shortcut = nn . Identity ()
+
+
+
+
+
+
Linear layer for time embeddings
+
+
+
+
122 self . time_emb = nn . Linear ( time_channels , out_channels )
+123 self . time_act = Swish ()
+124
+125 self . dropout = nn . Dropout ( dropout )
+
+
+
+
+
+
x
+ has shape [ batch_size , in_channels , height , width ]
+
+t
+ has shape [ batch_size , time_channels ]
+
+
+
+
+
127 def forward ( self , x : torch . Tensor , t : torch . Tensor ):
+
+
+
+
+
+
First convolution layer
+
+
+
+
133 h = self . conv1 ( self . act1 ( self . norm1 ( x )))
+
+
+
+
+
+
Add time embeddings
+
+
+
+
135 h += self . time_emb ( self . time_act ( t ))[:, :, None , None ]
+
+
+
+
+
+
Second convolution layer
+
+
+
+
137 h = self . conv2 ( self . dropout ( self . act2 ( self . norm2 ( h ))))
+
+
+
+
+
+
Add the shortcut connection and return
+
+
+
+
140 return h + self . shortcut ( x )
+
+
+
+
+
+
143 class AttentionBlock ( Module ):
+
+
+
+
+
+
n_channels
+ is the number of channels in the input
+n_heads
+ is the number of heads in multi-head attention
+d_k
+ is the number of dimensions in each head
+n_groups
+ is the number of groups for group normalization
+
+
+
+
150 def __init__ ( self , n_channels : int , n_heads : int = 1 , d_k : int = None , n_groups : int = 32 ):
+
+
+
+
+
+
+
160 if d_k is None :
+161 d_k = n_channels
+
+
+
+
+
+
Normalization layer
+
+
+
+
163 self . norm = nn . GroupNorm ( n_groups , n_channels )
+
+
+
+
+
+
Projections for query, key and values
+
+
+
+
165 self . projection = nn . Linear ( n_channels , n_heads * d_k * 3 )
+
+
+
+
+
+
Linear layer for final transformation
+
+
+
+
167 self . output = nn . Linear ( n_heads * d_k , n_channels )
+
+
+
+
+
+
Scale for dot-product attention
+
+
+
+
169 self . scale = d_k ** - 0.5
+
+
+
+
+
+
171 self . n_heads = n_heads
+172 self . d_k = d_k
+
+
+
+
+
+
x
+ has shape [ batch_size , in_channels , height , width ]
+
+t
+ has shape [ batch_size , time_channels ]
+
+
+
+
+
174 def forward ( self , x : torch . Tensor , t : Optional [ torch . Tensor ] = None ):
+
+
+
+
+
+
t
+ is not used, but it's kept in the arguments because for the attention layer function signature to match with ResidualBlock
+.
+
+
+
+
+
+
+
+
183 batch_size , n_channels , height , width = x . shape
+
+
+
+
+
+
Change x
+ to shape [ batch_size , seq , n_channels ]
+
+
+
+
+
185 x = x . view ( batch_size , n_channels , - 1 ) . permute ( 0 , 2 , 1 )
+
+
+
+
+
+
Get query, key, and values (concatenated) and shape it to [ batch_size , seq , n_heads , 3 * d_k ]
+
+
+
+
+
187 qkv = self . projection ( x ) . view ( batch_size , - 1 , self . n_heads , 3 * self . d_k )
+
+
+
+
+
+
Split query, key, and values. Each of them will have shape [ batch_size , seq , n_heads , d_k ]
+
+
+
+
+
189 q , k , v = torch . chunk ( qkv , 3 , dim =- 1 )
+
+
+
+
+
+
Calculate scaled dot-product d k Q K ⊤
+
+
+
+
191 attn = torch . einsum ( 'bihd,bjhd->bijh' , q , k ) * self . scale
+
+
+
+
+
+
Softmax along the sequence dimension se q so f t ma x ( d k Q K ⊤ )
+
+
+
+
193 attn = attn . softmax ( dim = 2 )
+
+
+
+
+
+
Multiply by values
+
+
+
+
195 res = torch . einsum ( 'bijh,bjhd->bihd' , attn , v )
+
+
+
+
+
+
Reshape to [ batch_size , seq , n_heads * d_k ]
+
+
+
+
+
197 res = res . view ( batch_size , - 1 , self . n_heads * self . d_k )
+
+
+
+
+
+
Transform to [ batch_size , seq , n_channels ]
+
+
+
+
+
199 res = self . output ( res )
+
+
+
+
+
+
Add skip connection
+
+
+
+
+
+
+
+
Change to shape [ batch_size , in_channels , height , width ]
+
+
+
+
+
205 res = res . permute ( 0 , 2 , 1 ) . view ( batch_size , n_channels , height , width )
+
+
+
+
+
+
+
Down block
+
This combines ResidualBlock
+ and AttentionBlock
+. These are used in the first half of U-Net at each resolution.
+
+
+
+
211 class DownBlock ( Module ):
+
+
+
+
+
+
218 def __init__ ( self , in_channels : int , out_channels : int , time_channels : int , has_attn : bool ):
+219 super () . __init__ ()
+220 self . res = ResidualBlock ( in_channels , out_channels , time_channels )
+221 if has_attn :
+222 self . attn = AttentionBlock ( out_channels )
+223 else :
+224 self . attn = nn . Identity ()
+
+
+
+
+
+
226 def forward ( self , x : torch . Tensor , t : torch . Tensor ):
+227 x = self . res ( x , t )
+228 x = self . attn ( x )
+229 return x
+
+
+
+
+
+
Up block
+
This combines ResidualBlock
+ and AttentionBlock
+. These are used in the second half of U-Net at each resolution.
+
+
+
+
232 class UpBlock ( Module ):
+
+
+
+
+
+
239 def __init__ ( self , in_channels : int , out_channels : int , time_channels : int , has_attn : bool ):
+240 super () . __init__ ()
+
+
+
+
+
+
The input has in_channels + out_channels
+ because we concatenate the output of the same resolution from the first half of the U-Net
+
+
+
+
243 self . res = ResidualBlock ( in_channels + out_channels , out_channels , time_channels )
+244 if has_attn :
+245 self . attn = AttentionBlock ( out_channels )
+246 else :
+247 self . attn = nn . Identity ()
+
+
+
+
+
+
249 def forward ( self , x : torch . Tensor , t : torch . Tensor ):
+250 x = self . res ( x , t )
+251 x = self . attn ( x )
+252 return x
+
+
+
+
+
+
Middle block
+
It combines a ResidualBlock
+, AttentionBlock
+, followed by another ResidualBlock
+. This block is applied at the lowest resolution of the U-Net.
+
+
+
+
255 class MiddleBlock ( Module ):
+
+
+
+
+
+
263 def __init__ ( self , n_channels : int , time_channels : int ):
+264 super () . __init__ ()
+265 self . res1 = ResidualBlock ( n_channels , n_channels , time_channels )
+266 self . attn = AttentionBlock ( n_channels )
+267 self . res2 = ResidualBlock ( n_channels , n_channels , time_channels )
+
+
+
+
+
+
269 def forward ( self , x : torch . Tensor , t : torch . Tensor ):
+270 x = self . res1 ( x , t )
+271 x = self . attn ( x )
+272 x = self . res2 ( x , t )
+273 return x
+
+
+
+
+
+
Scale up the feature map by 2 ×
+
+
+
+
276 class Upsample ( nn . Module ):
+
+
+
+
+
+
281 def __init__ ( self , n_channels ):
+282 super () . __init__ ()
+283 self . conv = nn . ConvTranspose2d ( n_channels , n_channels , ( 4 , 4 ), ( 2 , 2 ), ( 1 , 1 ))
+
+
+
+
+
+
285 def forward ( self , x : torch . Tensor , t : torch . Tensor ):
+
+
+
+
+
+
t
+ is not used, but it's kept in the arguments because for the attention layer function signature to match with ResidualBlock
+.
+
+
+
+
288 _ = t
+289 return self . conv ( x )
+
+
+
+
+
+
Scale down the feature map by 2 1 ×
+
+
+
+
292 class Downsample ( nn . Module ):
+
+
+
+
+
+
297 def __init__ ( self , n_channels ):
+298 super () . __init__ ()
+299 self . conv = nn . Conv2d ( n_channels , n_channels , ( 3 , 3 ), ( 2 , 2 ), ( 1 , 1 ))
+
+
+
+
+
+
301 def forward ( self , x : torch . Tensor , t : torch . Tensor ):
+
+
+
+
+
+
t
+ is not used, but it's kept in the arguments because for the attention layer function signature to match with ResidualBlock
+.
+
+
+
+
304 _ = t
+305 return self . conv ( x )
+
+
+
+
+
+
+
image_channels
+ is the number of channels in the image. 3 for RGB.
+n_channels
+ is number of channels in the initial feature map that we transform the image into
+ch_mults
+ is the list of channel numbers at each resolution. The number of channels is ch_mults [ i ] * n_channels
+
+is_attn
+ is a list of booleans that indicate whether to use attention at each resolution
+n_blocks
+ is the number of UpDownBlocks
+ at each resolution
+
+
+
+
313 def __init__ ( self , image_channels : int = 3 , n_channels : int = 64 ,
+314 ch_mults : Union [ Tuple [ int , ... ], List [ int ]] = ( 1 , 2 , 2 , 4 ),
+315 is_attn : Union [ Tuple [ bool , ... ], List [ int ]] = ( False , False , True , True ),
+316 n_blocks : int = 2 ):
+
+
+
+
+
+
+
Number of resolutions
+
+
+
+
327 n_resolutions = len ( ch_mults )
+
+
+
+
+
+
Project image into feature map
+
+
+
+
330 self . image_proj = nn . Conv2d ( image_channels , n_channels , kernel_size = ( 3 , 3 ), padding = ( 1 , 1 ))
+
+
+
+
+
+
Time embedding layer. Time embedding has n_channels * 4
+ channels
+
+
+
+
333 self . time_emb = TimeEmbedding ( n_channels * 4 )
+
+
+
+
+
+
First half of U-Net - decreasing resolution
+
+
+
+
+
+
+
+
Number of channels
+
+
+
+
338 out_channels = in_channels = n_channels
+
+
+
+
+
+
For each resolution
+
+
+
+
340 for i in range ( n_resolutions ):
+
+
+
+
+
+
Number of output channels at this resolution
+
+
+
+
342 out_channels = in_channels * ch_mults [ i ]
+
+
+
+
+
+
344 for _ in range ( n_blocks ):
+345 down . append ( DownBlock ( in_channels , out_channels , n_channels * 4 , is_attn [ i ]))
+346 in_channels = out_channels
+
+
+
+
+
+
Down sample at all resolutions except the last
+
+
+
+
348 if i < n_resolutions - 1 :
+349 down . append ( Downsample ( in_channels ))
+
+
+
+
+
+
Combine the set of modules
+
+
+
+
352 self . down = nn . ModuleList ( down )
+
+
+
+
+
+
355 self . middle = MiddleBlock ( out_channels , n_channels * 4 , )
+
+
+
+
+
+
Second half of U-Net - increasing resolution
+
+
+
+
+
+
+
+
Number of channels
+
+
+
+
360 in_channels = out_channels
+
+
+
+
+
+
For each resolution
+
+
+
+
362 for i in reversed ( range ( n_resolutions )):
+
+
+
+
+
+
n_blocks
+ at the same resolution
+
+
+
+
364 out_channels = in_channels
+365 for _ in range ( n_blocks ):
+366 up . append ( UpBlock ( in_channels , out_channels , n_channels * 4 , is_attn [ i ]))
+
+
+
+
+
+
Final block to reduce the number of channels
+
+
+
+
368 out_channels = in_channels // ch_mults [ i ]
+369 up . append ( UpBlock ( in_channels , out_channels , n_channels * 4 , is_attn [ i ]))
+370 in_channels = out_channels
+
+
+
+
+
+
Up sample at all resolutions except last
+
+
+
+
372 if i > 0 :
+373 up . append ( Upsample ( in_channels ))
+
+
+
+
+
+
Combine the set of modules
+
+
+
+
376 self . up = nn . ModuleList ( up )
+
+
+
+
+
+
Final normalization and convolution layer
+
+
+
+
379 self . norm = nn . GroupNorm ( 8 , n_channels )
+380 self . act = Swish ()
+381 self . final = nn . Conv2d ( in_channels , image_channels , kernel_size = ( 3 , 3 ), padding = ( 1 , 1 ))
+
+
+
+
+
+
x
+ has shape [ batch_size , in_channels , height , width ]
+
+t
+ has shape [ batch_size ]
+
+
+
+
+
383 def forward ( self , x : torch . Tensor , t : torch . Tensor ):
+
+
+
+
+
+
Get time-step embeddings
+
+
+
+
+
+
+
+
Get image projection
+
+
+
+
393 x = self . image_proj ( x )
+
+
+
+
+
+
h
+ will store outputs at each resolution for skip connection
+
+
+
+
+
+
+
+
First half of U-Net
+
+
+
+
398 for m in self . down :
+399 x = m ( x , t )
+400 h . append ( x )
+
+
+
+
+
+
403 x = self . middle ( x , t )
+
+
+
+
+
+
Second half of U-Net
+
+
+
+
406 for m in self . up :
+407 if isinstance ( m , Upsample ):
+408 x = m ( x , t )
+409 else :
+
+
+
+
+
+
Get the skip connection from first half of U-Net and concatenate
+
+
+
+
411 s = h . pop ()
+412 x = torch . cat (( x , s ), dim = 1 )
+
+
+
+
+
+
+
Final normalization and convolution
+
+
+
+
417 return self . final ( self . act ( self . norm ( x )))
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/utils/.DS_Store b/utils/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..ab804a388b557fb3e3da07f84c4ebe9541306d48
Binary files /dev/null and b/utils/.DS_Store differ
diff --git a/utils/1d-gan.ipynb b/utils/1d-gan.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..81601ddb0ccb52b5123c2bd64ff3c3a8e7a3088c
--- /dev/null
+++ b/utils/1d-gan.ipynb
@@ -0,0 +1,2567 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "**This notebook implements a one-dimensional GAN which generates the output of a cubic function**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The function below generates n samples of the cubic function, the domain of the function is chosen to be n random integers in the range -0.5 to 0.5. The function returns a two dimensional vector(inputs in the first column and outputs in the second) and a one dimensional vector of class labels( in this case, 1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/var/folders/qv/zzgcbq096_v04lckg4gc06280000gn/T/ipykernel_9938/1884976865.py:6: FutureWarning: In a future version of pandas all arguments of concat except for the argument 'objs' will be keyword-only.\n",
+ " dfs = pd.concat([df.Name,dfs],1)\n"
+ ]
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "df = pd.read_csv('/Users/apsys/Downloads/hetfit2/data/dataset.csv')\n",
+ "dfs = df.drop(\"Name\",axis=1)\n",
+ "dfs = (dfs-dfs.min())/(dfs.max()-dfs.min())\n",
+ "dfs = pd.concat([df.Name,dfs],1)\n",
+ "def generate_real_samples(n):\n",
+ " '''generate n real samples with class labels'''\n",
+ " x1 = np.random.rand(n) - 0.5 #generate a random number between [-0.5,0.5]\n",
+ " x2 = x1**3 #generate outputs\n",
+ " x1 = x1.reshape(n, 1)\n",
+ " x2 = x2.reshape(n, 1)\n",
+ " X = np.hstack((x1, x2)) #stack layers\n",
+ " y = np.ones((n, 1)) #generate class label\n",
+ " return X,y"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " Name \n",
+ " U \n",
+ " d \n",
+ " h \n",
+ " j \n",
+ " Isp \n",
+ " nu_t \n",
+ " T \n",
+ " m_a \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " SPT-20 [21] \n",
+ " 0.000000 \n",
+ " 0.000000 \n",
+ " 0.000000 \n",
+ " 0.166667 \n",
+ " 0.761194 \n",
+ " 0.006383 \n",
+ " 0.000000 \n",
+ " 0.000000 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " SPT-25 [22] \n",
+ " 0.062885 \n",
+ " 0.000000 \n",
+ " 0.071429 \n",
+ " 0.166667 \n",
+ " 0.104478 \n",
+ " 0.031915 \n",
+ " 0.020592 \n",
+ " 0.099001 \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " HET-100 [23] \n",
+ " 0.093711 \n",
+ " 0.375000 \n",
+ " 0.121429 \n",
+ " 0.194444 \n",
+ " 0.238806 \n",
+ " 0.012766 \n",
+ " 0.037323 \n",
+ " 0.496821 \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " KHT-40 [24] \n",
+ " 0.103730 \n",
+ " 0.453125 \n",
+ " 0.228571 \n",
+ " 0.388889 \n",
+ " 0.567164 \n",
+ " 0.053191 \n",
+ " 0.082368 \n",
+ " 0.617620 \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " KHT-50 [24] \n",
+ " 0.108354 \n",
+ " 0.218750 \n",
+ " 0.385714 \n",
+ " 0.333333 \n",
+ " 0.552239 \n",
+ " 0.093617 \n",
+ " 0.099099 \n",
+ " 0.454133 \n",
+ " \n",
+ " \n",
+ " 5 \n",
+ " HEPS-200 \n",
+ " 0.109895 \n",
+ " 0.218750 \n",
+ " 0.392857 \n",
+ " 0.361111 \n",
+ " 0.552239 \n",
+ " 0.093617 \n",
+ " 0.093951 \n",
+ " 0.418710 \n",
+ " \n",
+ " \n",
+ " 6 \n",
+ " BHT-200 [2526] \n",
+ " 0.113748 \n",
+ " 0.218750 \n",
+ " 0.085714 \n",
+ " 0.200000 \n",
+ " 0.140299 \n",
+ " 0.106383 \n",
+ " 0.114543 \n",
+ " 0.500454 \n",
+ " \n",
+ " \n",
+ " 7 \n",
+ " KM-32 [27] \n",
+ " 0.125308 \n",
+ " 0.218750 \n",
+ " 0.242857 \n",
+ " 0.277778 \n",
+ " 0.283582 \n",
+ " 0.119149 \n",
+ " 0.106821 \n",
+ " 0.367847 \n",
+ " \n",
+ " \n",
+ " 8 \n",
+ " SPT-50M [28] \n",
+ " 0.148428 \n",
+ " 0.062500 \n",
+ " 0.342857 \n",
+ " 0.500000 \n",
+ " 0.552239 \n",
+ " 0.225532 \n",
+ " 0.155727 \n",
+ " 0.226158 \n",
+ " \n",
+ " \n",
+ " 9 \n",
+ " SPT-30 [23] \n",
+ " 0.158446 \n",
+ " 0.218750 \n",
+ " 0.128571 \n",
+ " 0.222222 \n",
+ " 0.134328 \n",
+ " 0.114894 \n",
+ " 0.119691 \n",
+ " 0.358765 \n",
+ " \n",
+ " \n",
+ " 10 \n",
+ " KM-37 [29] \n",
+ " 0.177713 \n",
+ " 0.350000 \n",
+ " 0.314286 \n",
+ " 0.388889 \n",
+ " 0.328358 \n",
+ " 0.151064 \n",
+ " 0.187902 \n",
+ " 0.727520 \n",
+ " \n",
+ " \n",
+ " 11 \n",
+ " CAM200 [3031] \n",
+ " 0.193896 \n",
+ " 0.296875 \n",
+ " 0.400000 \n",
+ " 0.555556 \n",
+ " 0.522388 \n",
+ " 0.138298 \n",
+ " 0.172458 \n",
+ " 0.679382 \n",
+ " \n",
+ " \n",
+ " 12 \n",
+ " SPT-50 [21] \n",
+ " 0.203915 \n",
+ " 0.375000 \n",
+ " 0.342857 \n",
+ " 0.500000 \n",
+ " 0.552239 \n",
+ " 0.157447 \n",
+ " 0.175032 \n",
+ " 0.823797 \n",
+ " \n",
+ " \n",
+ " 13 \n",
+ " A-3 [21] \n",
+ " 0.209309 \n",
+ " 0.375000 \n",
+ " 0.457143 \n",
+ " 0.611111 \n",
+ " 0.701493 \n",
+ " 0.157447 \n",
+ " 0.181467 \n",
+ " 0.891916 \n",
+ " \n",
+ " \n",
+ " 14 \n",
+ " HEPS-500 \n",
+ " 0.331073 \n",
+ " 0.375000 \n",
+ " 0.492857 \n",
+ " 0.750000 \n",
+ " 0.552239 \n",
+ " 0.261702 \n",
+ " 0.283140 \n",
+ " 0.679382 \n",
+ " \n",
+ " \n",
+ " 15 \n",
+ " BHT-600 [2632] \n",
+ " 0.433570 \n",
+ " 0.375000 \n",
+ " 0.585714 \n",
+ " 0.777778 \n",
+ " 0.761194 \n",
+ " 0.459574 \n",
+ " 0.453024 \n",
+ " 0.627611 \n",
+ " \n",
+ " \n",
+ " 16 \n",
+ " SPT-70 [33] \n",
+ " 0.468249 \n",
+ " 0.375000 \n",
+ " 0.585714 \n",
+ " 0.666667 \n",
+ " 0.552239 \n",
+ " 0.451064 \n",
+ " 0.464607 \n",
+ " 0.684832 \n",
+ " \n",
+ " \n",
+ " 17 \n",
+ " SPT-100 [934] \n",
+ " 1.000000 \n",
+ " 0.375000 \n",
+ " 1.000000 \n",
+ " 0.722222 \n",
+ " 0.552239 \n",
+ " 1.000000 \n",
+ " 1.000000 \n",
+ " 0.636694 \n",
+ " \n",
+ " \n",
+ " 18 \n",
+ " UAH-78AM \n",
+ " 0.360358 \n",
+ " 0.250000 \n",
+ " 0.900000 \n",
+ " 1.000000 \n",
+ " 1.000000 \n",
+ " 0.331915 \n",
+ " 0.335907 \n",
+ " 0.554950 \n",
+ " \n",
+ " \n",
+ " 19 \n",
+ " MaSMi40 \n",
+ " 0.213933 \n",
+ " 0.375000 \n",
+ " 0.357143 \n",
+ " 0.237778 \n",
+ " 0.180896 \n",
+ " 0.225532 \n",
+ " 0.117117 \n",
+ " 0.237057 \n",
+ " \n",
+ " \n",
+ " 20 \n",
+ " MaSMi60 \n",
+ " 0.499075 \n",
+ " 0.218750 \n",
+ " 0.642857 \n",
+ " 0.412222 \n",
+ " 0.373134 \n",
+ " 0.451064 \n",
+ " 0.335907 \n",
+ " 0.418710 \n",
+ " \n",
+ " \n",
+ " 21 \n",
+ " MaSMiDm \n",
+ " 0.730271 \n",
+ " 1.000000 \n",
+ " 0.742857 \n",
+ " 0.472222 \n",
+ " 0.432836 \n",
+ " 0.544681 \n",
+ " 0.631918 \n",
+ " 1.000000 \n",
+ " \n",
+ " \n",
+ " 22 \n",
+ " Music-si \n",
+ " 0.067509 \n",
+ " 0.337500 \n",
+ " 0.042857 \n",
+ " 0.000000 \n",
+ " 0.000000 \n",
+ " 0.000000 \n",
+ " 0.003861 \n",
+ " 0.009991 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Name U d h j Isp \\\n",
+ "0 SPT-20 [21] 0.000000 0.000000 0.000000 0.166667 0.761194 \n",
+ "1 SPT-25 [22] 0.062885 0.000000 0.071429 0.166667 0.104478 \n",
+ "2 HET-100 [23] 0.093711 0.375000 0.121429 0.194444 0.238806 \n",
+ "3 KHT-40 [24] 0.103730 0.453125 0.228571 0.388889 0.567164 \n",
+ "4 KHT-50 [24] 0.108354 0.218750 0.385714 0.333333 0.552239 \n",
+ "5 HEPS-200 0.109895 0.218750 0.392857 0.361111 0.552239 \n",
+ "6 BHT-200 [2526] 0.113748 0.218750 0.085714 0.200000 0.140299 \n",
+ "7 KM-32 [27] 0.125308 0.218750 0.242857 0.277778 0.283582 \n",
+ "8 SPT-50M [28] 0.148428 0.062500 0.342857 0.500000 0.552239 \n",
+ "9 SPT-30 [23] 0.158446 0.218750 0.128571 0.222222 0.134328 \n",
+ "10 KM-37 [29] 0.177713 0.350000 0.314286 0.388889 0.328358 \n",
+ "11 CAM200 [3031] 0.193896 0.296875 0.400000 0.555556 0.522388 \n",
+ "12 SPT-50 [21] 0.203915 0.375000 0.342857 0.500000 0.552239 \n",
+ "13 A-3 [21] 0.209309 0.375000 0.457143 0.611111 0.701493 \n",
+ "14 HEPS-500 0.331073 0.375000 0.492857 0.750000 0.552239 \n",
+ "15 BHT-600 [2632] 0.433570 0.375000 0.585714 0.777778 0.761194 \n",
+ "16 SPT-70 [33] 0.468249 0.375000 0.585714 0.666667 0.552239 \n",
+ "17 SPT-100 [934] 1.000000 0.375000 1.000000 0.722222 0.552239 \n",
+ "18 UAH-78AM 0.360358 0.250000 0.900000 1.000000 1.000000 \n",
+ "19 MaSMi40 0.213933 0.375000 0.357143 0.237778 0.180896 \n",
+ "20 MaSMi60 0.499075 0.218750 0.642857 0.412222 0.373134 \n",
+ "21 MaSMiDm 0.730271 1.000000 0.742857 0.472222 0.432836 \n",
+ "22 Music-si 0.067509 0.337500 0.042857 0.000000 0.000000 \n",
+ "\n",
+ " nu_t T m_a \n",
+ "0 0.006383 0.000000 0.000000 \n",
+ "1 0.031915 0.020592 0.099001 \n",
+ "2 0.012766 0.037323 0.496821 \n",
+ "3 0.053191 0.082368 0.617620 \n",
+ "4 0.093617 0.099099 0.454133 \n",
+ "5 0.093617 0.093951 0.418710 \n",
+ "6 0.106383 0.114543 0.500454 \n",
+ "7 0.119149 0.106821 0.367847 \n",
+ "8 0.225532 0.155727 0.226158 \n",
+ "9 0.114894 0.119691 0.358765 \n",
+ "10 0.151064 0.187902 0.727520 \n",
+ "11 0.138298 0.172458 0.679382 \n",
+ "12 0.157447 0.175032 0.823797 \n",
+ "13 0.157447 0.181467 0.891916 \n",
+ "14 0.261702 0.283140 0.679382 \n",
+ "15 0.459574 0.453024 0.627611 \n",
+ "16 0.451064 0.464607 0.684832 \n",
+ "17 1.000000 1.000000 0.636694 \n",
+ "18 0.331915 0.335907 0.554950 \n",
+ "19 0.225532 0.117117 0.237057 \n",
+ "20 0.451064 0.335907 0.418710 \n",
+ "21 0.544681 0.631918 1.000000 \n",
+ "22 0.000000 0.003861 0.009991 "
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dfs"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(array([[-1.87734512e-01, -6.61656146e-03],\n",
+ " [ 1.56515103e-01, 3.83414693e-03],\n",
+ " [-9.56463469e-02, -8.74994174e-04],\n",
+ " [ 3.87038474e-01, 5.79778915e-02],\n",
+ " [ 1.38966732e-01, 2.68369114e-03],\n",
+ " [-1.19105367e-01, -1.68963927e-03],\n",
+ " [-8.97560680e-02, -7.23088503e-04],\n",
+ " [ 1.07071289e-02, 1.22749320e-06],\n",
+ " [ 2.05332738e-01, 8.65714309e-03],\n",
+ " [ 3.16184027e-01, 3.16096567e-02]]),\n",
+ " array([[1.],\n",
+ " [1.],\n",
+ " [1.],\n",
+ " [1.],\n",
+ " [1.],\n",
+ " [1.],\n",
+ " [1.],\n",
+ " [1.],\n",
+ " [1.],\n",
+ " [1.]]))"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "generate_real_samples(10)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The function below defines the discriminator model, it is one of the two components of a GAN. It's job is to classify whether the numbers generated by the generator model are real or fake( ie: if they are the output to our function or not). "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "_cell_guid": "79c7e3d0-c299-4dcb-8224-4455121ee9b0",
+ "_uuid": "d629ff2d2480ee46fbb7e2d37f6b5fab8052498a"
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Model: \"sequential\"\n",
+ "_________________________________________________________________\n",
+ " Layer (type) Output Shape Param # \n",
+ "=================================================================\n",
+ " dense (Dense) (None, 20) 180 \n",
+ " \n",
+ " leaky_re_lu (LeakyReLU) (None, 20) 0 \n",
+ " \n",
+ " dense_1 (Dense) (None, 15) 315 \n",
+ " \n",
+ " leaky_re_lu_1 (LeakyReLU) (None, 15) 0 \n",
+ " \n",
+ " dense_2 (Dense) (None, 5) 80 \n",
+ " \n",
+ " re_lu (ReLU) (None, 5) 0 \n",
+ " \n",
+ " dense_3 (Dense) (None, 1) 6 \n",
+ " \n",
+ "=================================================================\n",
+ "Total params: 581\n",
+ "Trainable params: 581\n",
+ "Non-trainable params: 0\n",
+ "_________________________________________________________________\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAATcAAANQCAYAAABNTCj5AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOy9e1QUR/r//x6ujsgoEq7RoEEhUfAWb6wmikYWMboaUOQm4DGKhqyGj2L8EsVEPeruZiXBOzHCblBARUCzBHHXuARk/QgqMRjk4iYiiGgIyADDwDy/P/jRH9sZZAZmmGGs1zmcQ1dVP/3Upd/TXVVdJSAiAoPBYOgXpwy07QGDwWBoAiZuDAZDL2HixmAw9BImbgwGQy8xUiXxX//6V1y5ckVTvjAYDEaXREREwM3NTen0Kj25XblyBfn5+So7xdAelZWVOH36tLbd0HlOnz6NyspKbbvB6ILTp0/j3r17Kp2j0pMbAEyfPh2nTp1S9TSGlkhJSYGvry+rs24QCAT48MMPsWzZMm27wlCAQCBQ+RzW58ZgMPQSJm4MBkMvYeLGYDD0EiZuDAZDL2HixmAw9BKVR0t7y88//4yjR48iMTER//3vf/v68j2mrq4OM2bMwObNmxEcHKxtd/qcFz3/z3Lu3DkkJydzxwsWLICfnx8vTWlpKdLS0mBnZ8eFzZs3DzY2Nrx0EokEqampaG9vBwAYGBjA09MTQ4cO1WAOeoZYLEZCQgIqKiowePBgLFu2DM7OzgCAS5cuYeDAgZg2bRrvnGvXriEmJoY7njRpEiIiIjTua58/uVVUVOC7777rd3OKjIyMYGlpiUGDBmnNB4lEorVrv+j5f5bi4mL885//xOeff47PP/8cf/jDH3jxqamp+OKLLxAREQEPDw/k5OQgKCgIixcvlsuHqakp5s+fj+zsbBw6dAhvvfWWTgpbbW0txo8fD5FIhB07dsDDwwNLlixBWloaAMDd3R3FxcXYs2cP77xx48Zx5dTQ0IDLly/3ib99Lm7u7u6YMWNGX1+215ibmyMnJwfe3t5a8yEqKgoymUwr137R868IAwMDWFpawtLSEgMHDuTCi4qKsG/fPsTGxsLQ0BDW1tY4cuQInJ2dkZ+fj7CwMDlbQ4YMgYeHB+bMmYNhw4b1ZTaUZu/evRg9ejQCAwMhFAoxbdo0BAUFYdOmTVya0NBQlJSU4MKFC1yYiYkJV04mJiZ95q9W+tyMjY21cdl+zQ8//IDDhw9r2w2t0V/y397eDm9vbwQEBMjFmZmZwc3NDfHx8bzXtE5MTEy0+mTcHZWVlaiursbTS0CamZlhwIABvHQ7duxAWFgYxGJxX7vIo0/ETSqVIiUlBVu2bEFWVpbCX9+GhgbExcUhIiIC+/fvR2NjIxdXVlaGjz/+GDKZDKWlpdi1axfi4uIglUp5Nr7//ntERUXh8OHDOHr0qNL2laGlpQV///vfeb9IyvhVXl7ONeRO/xISErgySE5OxsmTJ3mfSJ0+fRonT57kHvdzc3PxzjvvQCwWIykpSStfG+hi/sViMT799FOUlJRoPP/Kkp6ejvv378Pf319hfGpqKoYNG4aNGzfi4sWL3dqTSCS4cOECoqKicODAAZSXl/Pilb03etv+AWDOnDm4efMmtm3bBgBoa2tDYmIiNmzYwEs3bNgwmJubc+m0BqmAj48P+fj4qHIK/fbbbzR37lzavn07PX78mBISEsjExIQMDQ25NHfu3KGFCxdSVlYW3bhxg1xcXMjR0ZHq6uooPj6ebGxsCABlZGTQu+++SwsWLCAAtHXrVs5GZGQkJSYmklgsppMnT9KgQYOUsq8Mt2/fpsWLFxMA2rt3LxGRUn7FxsbSoEGDyM7OjhITE8nV1ZWEQiEBIG9vbyIiamhooBkzZpBIJOKuV1VVRa6urmRra0tERDk5ORQQEEAA6Pz585SVlaV0+ScnJ5OK1dxv8n/hwgUCQJGRkb3KHxERAEpOTlY6/Z49e8je3l4u3N3dnSZMmKDwnEmTJhER0bVr10goFNLQoUOprKyMi09JSaE9e/Zwx83NzTR79mxKSkqiuro6io2NJXNzczpz5gwRKVcHRL1v/520traSu7s7AaDg4GAKCQmho0ePKkwbFhZGDg4OcuHe3t60aNEila5LpHr9EFGKxsVt3bp1tHjxYl7YO++8wxO3efPm0dmzZ7njzMxMXgVFRkYSAEpPT+fSuLu7k5OTExF1FLqlpSWVlJRw8evXr1favjLcv3+fd3Mr4xcRka+vL5mZmdHXX39NRB03rpubGwHgbtLw8HDezU1EtGrVKu7mJiL65JNPCADJZDKlfSZSj7gR6Wb+29raKD09nR4/ftzr/KlD3GQyGQ0YMIC8vLwUntMpbkREJ06cIAA0duxYamhoICJ5cfP396fQ0FCeDR8fHxIKhXTv3j0iUq4O1NH+O2lqauIEbtKkSVRTU6MwXXR0NAGQq5u+FDeNvpY+fPgQcXFx8PDw4IWPGzeO+7+6uhrZ2dnIy8vDli1bsGXLFnzzzTeYPHkympqaAHS81wOAl5cXd56Liws34mpsbAxzc3O8/fbbyMzMBNDR+aysfWVQ1BfSnV+daUQiEdcHY2dnh927dwMAsrOzAXR0TD+LojBtoov5NzQ0xKJFi3RmZLG6uhotLS2wt7fvNq2fnx8++ugj/PjjjwgMDOT1YwFAU1MTTp06hYkTJ/LC165di+bmZhw/fhxA93WgrvbfydWrV2Fvb49NmzahsLAQ06ZNU7hah7W1NQDgxo0bKl9DXWh0ntvNmzchlUpha2vLC3/6C//S0lIAQGRkJF566SWFdhQ1dDMzM7S1tXHH+/fvR1BQELy8vLhOWysrK6XsK4OyN+CzfgHyKxpMmTIFAFRewkWbvOj5V4aamhoAgEgkUir9rl27cOvWLWRkZGDbtm28H/28vDxIpVIYGfFv0dGjRwMA7ty5A6D7OlBX+weA/Px8BAcHo6ioCCKRCA4ODggPD8e6detw7tw5XtrOa5WUlGDOnDm9um5P0ejjwZMnTwB0/Hp0RefQcGFhYZfnK8OCBQtQVlaGDRs2oKCgAJMnT8bt27fVZl+dmJiYwNTUFK+88opWrq9t9DX/o0aNgkAgwOPHj5VKb2BggMTERLz++uvYuXMnb6Coc0JvXl4e75xO0XByclLqGups/wcOHMDUqVM58X7//fcRGRmJrKwsPHr0iJe2c6T02QnLfYlGxe21114DAO5V8Wk6R8ucnZ1haGiI6OhotLa2cvG1tbVITExU6jpisRhxcXEYOnQo9u3bh++++w6NjY04efKkWuz3lpaWFt5xXl4eJBIJpk6dCqDjl/7ZiZ1ExDXwp1EUpuu8KPk3NzeHo6MjHj58qPQ5IpEIGRkZsLCw4InbxIkTYWpqitzcXF762tpaAMCbb76plH11tv+amhoYGhrywtasWQOpVCqX56qqKgDAyJEjVbqGOtGouI0ZMwaenp44f/484uPjAQCtra24ceMGiAj37t2Dubk5wsLCkJ+fj1mzZuHEiROIj49HQEAA9znLr7/+CgBobm7mbLe1tUEqlUIikUAmkyE6Opq7idzc3DB69GhYWVnBwsKiW/vK0Dl0/vTcne786qS+vh6//PILd/ztt99i8uTJ3IRYBwcHSCQSZGdng4iQnJyMvLw81NfXo76+Hu3t7bCysgIAFBQUICcnR04wNI0u5v/BgwdYtmyZnABok4kTJ3Ypbvfv31fYzzVq1CikpKTwhMPa2hoffPAB7t69i0uXLnHhaWlpWLp0KWbNmgWg+zpQpv3v2bMH/v7+nCB1xapVq3D+/Hneta5fv47x48dzDzKdVFVVYciQIXLhfYoqww89GS198OABvfnmmwSAnJycaNGiRRQYGEiDBg2i8PBwqqysJLFYTCtWrCAABIBEIhE3upOWlkYjRowgALR+/XqqqKigpKQkGjlyJAGgTZs2UVlZGQmFQnJ1daUvvviCtm/fTqGhodTa2kpE9Fz7yvDLL7/Q2rVrCQCNGTOGMjMzlfKrpqaGVq5cSWZmZrRo0SI6cOAArV69mmbOnEl3797l7IvFYnJxcSEAZGNjQwkJCbR69WqysLCgjRs30qNHj6iiooJsbGzIwsKCvvzyS6V9V8doqa7m/+LFiwSAoqOje5U/IvVNBTlx4gSZmppSY2MjF1ZYWEirVq0iALR06VLKzs5WaDMmJoY3Wtre3k4RERFkZWVFmzdvpuDgYFq2bBk1NzcTkXL3Rk1NTbftf/jw4QSAoqKinpvntrY22rJlC40fP572799PUVFRtHz5cqqoqJBL6+bmRhEREXLhejUVpJOysjIqKSkhmUxGFRUVVF9fL5emtraWCgoKqKmpSSXbMpmMxGIxNTQ0UEFBAT158kRhup7a7w0rV64ke3t7kkgkdP36dYUNgagjD0VFRSQWi4moY27Ss362traq7Lu6poL0FE3n/86dO9Te3t5rP9UlbkRE8+fPp4yMjB75UVtbKxfW1NREhYWFnKj1lK7a/4MHDyg3N5c3fep5tLS00K1bt+jhw4cK44uLi8nU1JTKy8vl4vpS3PpsVRBHR0fu/67ew1966aUejegIBALu275JkyZ1ma6n9tWBiYkJJkyY0GW8QCCAq6srd9w5KvY0xsbG/fbTNU3lX1E6bXPkyBGEhIRgwYIFKk/pUdQ+hUKh3JSQntBV+7exscGxY8cQEhKilB1TU1OMHTu2y/i4uDgcPHgQr776ak9dVQu6NZlKD2lqatL6N3baRJ/zT0SQyWSQyWS8eWrDhw9HeHi43OoYusqhQ4fg6en53B8fZUlKSoJQKMTKlSt54YrKSdP0+XpuusS9e/cQGhrabbrg4GAEBQWpZFsqlSIuLg6XL1/GkydPsHXrVqxZs0ZnV3xQN/qef0dHR7zxxhvcUkfvvvsury0tWbIEEyZMwJkzZ7S6kooyrFmzRi2TxnNycmBhYYFdu3bxwq9cuYKdO3dyx8+u96YpBKSClC5duhQA9GabOCLiDY93hZGRkdwQeH+hc2u/vvzF7I8IBAIkJyezrf10lB7Uz6kX+slNIBDA1NRU224wGAwNwPrcGAyGXsLEjcFg6CVM3BgMhl7CxI3BYOglKg8onD59Wm4JG4buw+qse3x9feHr66ttNxhqQmVxmz59Oj788ENN+MLQAFeuXEFMTAxvj02GPL6+vtiwYQPc3Ny07QpDAT350VFZ3IYNG8bmAvUzYmJiWJ11g6+vL9zc3Fg56Sg9ETfW58ZgMPQSJm4MBkMvYeLGYDD0EiZuDAZDL2HixmAw9JI++3C+qKgIRUVFvDA7OzvMnTu3r1xQyNWrV7lt0joxMjLC8uXLteQRoz9w7tw53vSaBQsWyO3JUVpairS0NNjZ2XFh8+bNk9sRSiKRIDU1ldv8xsDAAJ6enjqzH+vTiMViJCQkoKKiAoMHD8ayZcvg7OwMALh06RIGDhwot6TRtWvXEBMTwx1PmjQJERERmndWlXV7e7PMOBHR7du3afDgwQSA/va3v1FbW1uPbfWGlpYW3vG///1vMjY25nbu7lzqWh/Q9jLjz5a1rtpGD5YZt7W1pUePHtGjR4/k2syZM2coPDyc2traqKamhlavXk0AaPr06Qr9rquroxUrVtDvfvc7bjd5XePhw4fk6OhIf//736mpqYny8/Pp9ddf5+3H8NVXX9Hu3bt550kkEq6cFi5cqB87zj/La6+9xu3tGBAQoLU10qKioritBYGObdJefvllWFpaYtGiRdyS5Yze82xZ9xfbymBgYABLS0tYWlry2kxRURH27duH2NhYGBoawtraGkeOHIGzszPy8/MRFhYmZ2vIkCHw8PDAnDlzdHZBz71792L06NEIDAyEUCjEtGnTEBQUhE2bNnFpQkNDUVJSggsXLnBhJiYmXDl17qPaF/R5n9uAAQNgaGiolpU/e8IPP/yAw4cPy4WbmJj0acG/CHRV1rpuuze0t7fD29sbAQEBcnFmZmZwc3NDfHw87zWtExMTEwwaNKgv3OwRlZWVqK6u5i18amZmhgEDBvDS7dixA2FhYVpfXl4nFqssKytDfHw8Pv30U5SXlyMlJQXW1tYICQnhNgQpLy/HuXPnsGHDBnz//ffIzMyEk5MTgoKCYGBggOTkZMhkMhgbG8PHxwdAx3ewUqkUQqEQixcvRm5uLvz9/SEWi5GUlARjY2NudWFVKC0txT/+8Q/89ttvmDp1KubPnw8ASE9P5/alFAgEXL/djz/+yPU3enh4wNLSEg0NDUhOTsbt27fx6quvIiQkhGvY5eXliI+Px/bt25GZmYni4mJ8+OGHfbo5jEQiweXLl3H58mXY29vD09OT2+SnN2WtyXoUi8X47LPP4Ovry/UD9TXp6em4f/8+/P39FcanpqZiypQp2LhxI1xcXPD2228/197z6gFQ7t4B8Nz2pixz5sxBcnIytm3bhh07dqCtrQ2JiYnYsGEDL92wYcNgbm6Obdu24bPPPlPpGmpFlZfY3va5ERHNmDGDjIyMuOP4+HiysbEhAJSRkUHvvvsuLViwgADQ1q1biYgoNjaWBg0aRHZ2dpSYmEiurq4kFAoJAHl7exMRUUNDA82YMYNEIhFnu6qqilxdXcnW1paIiHJyciggIIAA0Pnz5ykrK4tL6+TkRHZ2dt36/8EHH9Cbb75Jjx49ogsXLpBAIOD2mrx9+zbZ2dkRACotLeXOaW9vp7lz59L+/ftJJpPRnTt3aOHChZSVlUU3btwgFxcXcnR0pLq6OkpISCBbW1sCQPHx8TRx4kQCQLm5uT0q7570uTU3N9Ps2bMpKSmJ6urqKDY2lszNzenMmTNE1POy1nQ9XrhwgQBQZGSkyuUENW3t5+7uThMmTFB4zqRJk4iI6Nq1ayQUCmno0KFUVlbGxaekpPD2Le2uHpS5d4joue1NFVpbW8nd3Z0AUHBwMIWEhNDRo0cVpg0LCyMHBwe5cL3ct7STZ8WNiCgyMpLrzO/E3d2dnJycuGNfX18yMzOjr7/+mog6GrybmxsB4Bp3eHg476YgIlq1ahV3UxARffLJJwSAZDIZL52y4jZ48GDauXMndzxmzBiaPn06d5yYmMjziaijUUyePJkbQJk3bx6vEzYzM5PXIKOiojhxIyL66aef5PxVlp6Im7+/P4WGhvLCfHx8SCgUcp3dPS1rTdZjW1sbpaen0+PHj1XKL5F6xE0mk9GAAQPIy8tL4Tmd4kbUsXkzABo7diw1NDQQkby4KVMPytw73bU3VWhqauIEbtKkSVRTU6MwXXR0NAGQq4u+FDedmOdmZmYGAPDy8uLCXFxcUFlZyUsjEom4vgw7Ozvs3r0bAJCdnQ0ACvvx1N23980332Dt2rUAOqaREBGam5u5eF9fX4waNQp/+ctfuLCzZ89i8eLFMDQ0RHV1NbKzs5GXl4ctW7Zgy5Yt+OabbzB58mTulVYoFAIAN7XA2dm5z5YsampqwqlTp+T2yVy7di2am5tx/PhxAD0va03Wo6GhIRYtWqS1KRTV1dVoaWmBvb19t2n9/Pzw0Ucf4ccff0RgYKDcBj7K1kN3944y7U0Vrl69Cnt7e2zatAmFhYWYNm0a7t27J5fO2toaAHDjxg2Vr6EudKLPTVHDNTMzQ1tbGy/s2Rt8ypQpAKCwcDXFjBkzcPbsWaSmpuL3v/89RowYgfv373PxhoaG2Lx5M9577z1cvXoVU6dOxbFjx5CQkACgo78OACIjI7vcIFqba6/l5eVBKpXCyIjfNDo3P352TmBP0IV61AQ1NTUAAJFIpFT6Xbt24datW8jIyMC2bdswbtw4Lk7Zeuju3lGmvSlLfn4+goODUVRUBJFIBAcHB4SHh2PdunU4d+4cL23ntUpKSjBnzpxeXben6MSTW08xMTGBqakpXnnlFY1f6+lG8tVXXyEuLg6BgYEKd89asWIFXn75ZezatQslJSUYMmQIbG1tOZ8BoLCwUO68J0+eaDAHytE5kTQvL48X3tlYnZyc1H7NvqxHTdI5zenx48dKpTcwMEBiYiJef/117Ny5k7dlprrqQZ3t7cCBA5g6dSon3u+//z4iIyORlZWFR48e8dJ2jpQ+O2G5L+lX4tbS0sI7zsvLg0QiwdSpUwF0/GJKJBJeGiLiGsrTKAp79tWgE5lMhri4OBQUFODPf/4z3n//fd7w97PnmZiYYOPGjdyo4NPzmpydnWFoaIjo6Gjenqm1tbVITEzsKut9xsSJE2Fqaorc3FxeeG1tLYCOOYFA78pa0/WoLczNzeHo6IiHDx8qfY5IJEJGRgYsLCx44qZsPXSHOttbTU2N3NzUNWvWQCqVyuW5qqoKADBy5EiVrqFO+lzcnjx5gra2NjQ2NnJhv/76KwDw+q7a2toglUp5jby+vh6//PILd/ztt99i8uTJ3I7eDg4OkEgkyM7OBhEhOTkZeXl5qK+vR319Pdrb22FlZQUAKCgoQE5ODnejVVdX49GjR3I3lUQiwR//+EeMGDGCm6iZlpaGtrY2XLx4ETdv3kRdXR1KS0tx9+5d7rz33nsPlpaWuHv3Ltzd3blwCwsLhIWFIT8/H7NmzcKJEycQHx+PgIAAro9NKpUCgNJPAOrE2toaH3zwAe7evYtLly5x4WlpaVi6dClmzZoFoHdlral6fPDgAZYtWyYnCH3JxIkTuxS3+/fvK+znGjVqFFJSUnjCoWw9dHfvKNPe9uzZA39/f06QumLVqlU4f/4871rXr1/H+PHj8dprr/HSVlVVYciQIXLhfYoqww+9GS29efMmhYeHk4GBAQGggIAAunDhAqWlpdGIESMIAK1fv54qKiooKSmJRo4cSQBo06ZNVFNTQytXriQzMzNatGgRHThwgFavXk0zZ86ku3fvctcQi8Xk4uJCAMjGxoYSEhJo9erVZGFhQRs3bqRHjx5RRUUF2djYkIWFBX355ZeUn5/PTSsAQMOGDaMpU6bQ1KlTady4cWRubk4CgYAqKyuJiCgoKIgMDAzIxsaGDh8+TDt37iQDAwPauHGjXJ4jIyPpr3/9q1y4WCymFStWcNcUiUTcaNbp06fJ2dmZANDSpUvp5s2bPSrvTnoyWtre3k4RERFkZWVFmzdvpuDgYFq2bBk1Nzfz8qBqWRORxuqRiOjixYsEgKKjo1UuJ6hpKsiJEyfI1NSUGhsbubDCwkJatWoVV6fZ2dkKbcbExPBGS7urB2Xvnee1NyKi4cOHEwCKiop6bp7b2tpoy5YtNH78eNq/fz9FRUXR8uXLqaKiQi6tm5sbRUREyIXr9VSQnrJy5Uqyt7cniURC169fV1igRB3D8UVFRdy3fnfu3KGmpiZemtbWVrkwVXj48CG1trZyx7/++qvCdF5eXl3GERHV1tZSQUFBr3zpjt58W9rU1ESFhYU8UXuanpS1puvxzp071N7erlpGSX3iRkQ0f/58ysjIUNkHoo428Szd1YMqthW1twcPHlBubi6tX79eKTstLS1069YtevjwocL44uJiMjU1pfLycrm4vhQ3nRgtVQUTExNMmDChy3iBQABXV1fuuHN06WmMjY17Ndu/85WoEwsLC7k0eXl5GD58uMK4Tl566aVej2BpEqFQKDcV4Wl6U9aaqkdF6fqaI0eOICQkBAsWLFB5KpKi9tBdPahiW5F9GxsbHDt2DCEhIUrZMTU1xdixY7uMj4uLw8GDB/Hqq6/21FW10G/ErampSevfqnXH1atXERERgbFjx6K4uBjnz5/Xtks6R3+oR2UhIu7DfYFAwE1xGT58OMLDw7Fnzx78v//3/7TpolIcOnQInp6ez/2xUZakpCQIhUKsXLmSF95ZTtTFoJ0m0PnRUqlUioMHD+Ly5ct48uQJtm7dypvcq2uUlpaioqICMTExGDx4sLbd0Rn6Wz12h6OjI9544w384Q9/wB/+8AfEx8fz4pcsWQI/Pz+cOXNGOw6qwJo1azBp0qRe28nJyYGFhQV27drFC79y5QoWLlyIhQsXoqWlBW+88Uavr6UMAlJBSjs/Mn96yJqh26SkpMDX17dPfzH7IwKBAMnJyWxrPx2lB/VzSuef3BgMBqMnMHFjMBh6CRM3BoOhlzBxYzAYeonKU0EqKyuRkpKiCV8YGuDKlSsAoPU6a2trg0Qi4Zbo0UU6y4qhJ6gy5dfHx4f7hIP9sT/2x/768k/VLxRUmgrCYPQUNiWF0cewqSAMBkM/YeLGYDD0EiZuDAZDL2HixmAw9BImbgwGQy9h4sZgMPQSJm4MBkMvYeLGYDD0EiZuDAZDL2HixmAw9BImbgwGQy9h4sZgMPQSJm4MBkMvYeLGYDD0EiZuDAZDL2HixmAw9BImbgwGQy9h4sZgMPQSJm4MBkMvYeLGYDD0EiZuDAZDL2HixmAw9BImbgwGQy9h4sZgMPQSJm4MBkMvYeLGYDD0EiZuDAZDL2HixmAw9BImbgwGQy9h4sZgMPQSJm4MBkMvMdK2Awz9QyqVorGxkRcmFosBAHV1dbxwgUCAIUOG9JlvjBcHJm4MtfPrr7/i5ZdfRnt7u1zc0KFDecfu7u7417/+1VeuMV4g2GspQ+3Y2NjgrbfegoHB85uXQCDA8uXL+8grxosGEzeGRggKCuo2jaGhIby9vfvAG8aLCBM3hkbw9vaGkVHXvR6Ghob4/e9/D0tLyz70ivEiwcSNoRFEIhE8PT27FDgiQmBgYB97xXiRYOLG0BiBgYEKBxUAwMTEBAsXLuxjjxgvEkzcGBpj4cKFGDhwoFy4sbExlixZAjMzMy14xXhRYOLG0BgDBgzAu+++C2NjY164VCpFQECAlrxivCgwcWNoFH9/f0ilUl6YSCTCvHnztOQR40WBiRtDo7z99tu8ibvGxsbw8/ODiYmJFr1ivAgwcWNoFCMjI/j5+XGvplKpFP7+/lr2ivEiwMSNoXGWL1/OvZra2Nhg5syZWvaI8SLAxI2hcWbMmAF7e3sAHV8udPdZFoOhDlgrY2gcgUDAfY7FviVl9BVM3Bh9gp+fH1577TW88cYb2naF8YKgM0seCQQCbbvA6ANYPes3Pj4+OHXqlLbdAKBD4gYAGzZsgJubm7bd0CpXrlxBTEwMkpOTte2KTgLdeXkAACAASURBVOPr68vai46xb98+bbvAQ6fEzc3NDcuWLdO2G1onJiaGlUM3+Pr6svaiY+jKE1snrM+NwWDoJUzcGAyGXsLEjcFg6CVM3BgMhl7CxI3BYOglOjVaqg5+/vlnHD16FImJifjvf/+rbXe0Rl1dHWbMmIHNmzcjODhY2+7oPKWlpUhLS4OdnR0XNm/ePNjY2PDSSSQSpKamcisMGxgYwNPTU27LQl1ALBYjISEBFRUVGDx4MJYtWwZnZ2cAwKVLlzBw4EBMmzZNy15qDr17cquoqMB3332HyspKbbuiVYyMjGBpaYlBgwZpzQeJRKK1a6tCamoqvvjiC0RERMDDwwM5OTkICgrC4sWL5fJgamqK+fPnIzs7G4cOHcJbb72lk8JWW1uL8ePHQyQSYceOHfDw8MCSJUuQlpYGoGO/2OLiYuzZs0fLnmoOvRM3d3d3zJgxQ9tuaB1zc3Pk5ORodeu8qKgoyGQyrV1fGYqKirBv3z7ExsbC0NAQ1tbWOHLkCJydnZGfn4+wsDC5c4YMGQIPDw/MmTMHw4YN04LX3bN3716MHj0agYGBEAqFmDZtGoKCgrBp0yYuTWhoKEpKSnDhwgUteqo59E7cAMgta83oe3744QccPnxY2248l/b2dnh7eytc8tzMzAxubm6Ij49HTEyMXLyJiYlWn4q7o7KyEtXV1SAiLszMzAwDBgzgpduxYwfCwsIgFov72kWNoxfiJpVKkZKSgi1btiArK0vh00JDQwPi4uIQERGB/fv3o7GxkYsrKyvDxx9/DJlMhtLSUuzatQtxcXFyy2N///33iIqKwuHDh3H06FGl7WuDlpYW/P3vf+f9KiuTz/Lycu5m7sxvQkICV6bJyck4efIkTp8+zZ1z+vRpnDx5knvlyc3NxTvvvAOxWIykpCRu5rpYLMann36KkpISjedfGdLT03H//v0uF89MTU3FsGHDsHHjRly8eLFbexKJBBcuXEBUVBQOHDiA8vJyXryy7UwdbWnOnDm4efMmtm3bBgBoa2tDYmIiNmzYwEs3bNgwmJubc+n0CtIRAFBycrLK5/322280d+5c2r59Oz1+/JgSEhLIxMSEDA0NuTR37tyhhQsXUlZWFt24cYNcXFzI0dGR6urqKD4+nmxsbAgAZWRk0LvvvksLFiwgALR161bORmRkJCUmJpJYLKaTJ0/SoEGDlLKvKsnJydTbarl9+zYtXryYANDevXuJiJTKZ2xsLA0aNIjs7OwoMTGRXF1dSSgUEgDy9vYmIqKGhgaaMWMGiUQi7npVVVXk6upKtra2RESUk5NDAQEBBIDOnz9PWVlZRER04cIFAkCRkZG9yh9Rz9vL07i7u9OECRMUxk2aNImIiK5du0ZCoZCGDh1KZWVlXHxKSgrt2bOHO25ubqbZs2dTUlIS1dXVUWxsLJmbm9OZM2eISLnyJ1JfW2ptbSV3d3cCQMHBwRQSEkJHjx5VmDYsLIwcHBxUsq8IHx8f8vHx6bUdNZHS78Vt3bp1tHjxYl7YO++8wxO3efPm0dmzZ7njzMxMXqOKjIwkAJSens6lcXd3JycnJyLqaCiWlpZUUlLCxa9fv15p+6qgDnEjIrp//z5P3Ii6zycRka+vL5mZmdHXX39NRB3C5ebmRgA4kQoPD+eJGxHRqlWrOHEjIvrkk08IAMlkMi6sra2N0tPT6fHjx73OX2/FTSaT0YABA8jLy0thfKe4ERGdOHGCANDYsWOpoaGBiOTFzd/fn0JDQ3k2fHx8SCgU0r1794hIufJXZ1tqamriBG7SpElUU1OjMF10dDQB6HW96Jq49evX0ocPHyIuLg4eHh688HHjxnH/V1dXIzs7G3l5ediyZQu2bNmCb775BpMnT0ZTUxMAcPtnenl5cee5uLhwI67GxsYwNzfH22+/jczMTAAdneXK2tcGivqDustnZxqRSMT1Q9nZ2WH37t0AgOzsbABQuJKuMqvrGhoaYtGiRToxulhdXY2WlhZuheDn4efnh48++gg//vgjAgMDef1YANDU1IRTp05h4sSJvPC1a9eiubkZx48fB9B9+au7LV29ehX29vbYtGkTCgsLMW3aNNy7d08unbW1NQDgxo0bKl9Dl+nX89xu3rwJqVQKW1tbXvjTa4aVlpYCACIjI/HSSy8ptKPoxjQzM0NbWxt3vH//fgQFBcHLy4vraLayslLKvjZQVoCezScgv+balClTAEDhjdFfqampAdCxzaAy7Nq1C7du3UJGRga2bdvG+wHNy8uDVCqFkRH/dho9ejQA4M6dOwC6L391tqX8/HwEBwejqKgIIpEIDg4OCA8Px7p163Du3Dle2s5rlZSUYM6cOb26ri7Rr5/cnjx5AqDjF68rOreQKyws7PJ8ZViwYAHKysqwYcMGFBQUYPLkybh9+7ba7OsyJiYmMDU1xSuvvKJtV9TGqFGjIBAI8PjxY6XSGxgYIDExEa+//jp27tzJW96nc0JvXl4e75xO0XByclLqGupsSwcOHMDUqVM58X7//fcRGRmJrKwsPHr0iJe2c6T02QnL/Z1+LW6vvfYaAHCvik/TObrn7OwMQ0NDREdHo7W1lYuvra1FYmKiUtcRi8WIi4vD0KFDsW/fPnz33XdobGzEyZMn1WJf12hpaeEd5+XlQSKRYOrUqQA6nnaendxKRNxN/jSKwnQBc3NzODo64uHDh0qfIxKJkJGRAQsLC564TZw4EaampsjNzeWlr62tBQC8+eabStlXZ1uqqamBoaEhL2zNmjWQSqVyea6qqgIAjBw5UqVr6Dr9WtzGjBkDT09PnD9/HvHx8QCA1tZW3LhxA0SEe/fuwdzcHGFhYcjPz8esWbNw4sQJxMfHIyAgAH5+fgCAX3/9FQDQ3NzM2W5ra4NUKoVEIoFMJkN0dDR307u5uWH06NGwsrKChYVFt/a1Qef0gafnL3WXz07q6+vxyy+/cMfffvstJk+ezE0IdnBwgEQiQXZ2NogIycnJyMvLQ319Perr69He3g4rKysAQEFBAXJyctDS0oIHDx5g2bJlciKgLSZOnNiluN2/f19hP9eoUaOQkpLCEw5ra2t88MEHuHv3Li5dusSFp6WlYenSpZg1axaA7stfmba0Z88e+Pv7c4LUFatWrcL58+d517p+/TrGjx/PPRR0UlVVhSFDhsiF93u0O6Dxf6CHo18PHjygN998kwCQk5MTLVq0iAIDA2nQoEEUHh5OlZWVJBaLacWKFQSAAJBIJOJGpNLS0mjEiBEEgNavX08VFRWUlJREI0eOJAC0adMmKi8vJ6FQSK6urvTFF1/Q9u3bKTQ0lFpbW4mInmtfVdQxWvrLL7/Q2rVrCQCNGTOGMjMzlcpnTU0NrVy5kszMzGjRokV04MABWr16Nc2cOZPu3r3L2ReLxeTi4kIAyMbGhhISEmj16tVkYWFBGzdupEePHlFFRQXZ2NiQhYUFffnll0REdPHiRQJA0dHRvcofkXqmgpw4cYJMTU2psbGRCyssLKRVq1YRAFq6dCllZ2crPDcmJoY3Wtre3k4RERFkZWVFmzdvpuDgYFq2bBk1NzcTkXLtrKamptu2NHz4cAJAUVFRz81bW1sbbdmyhcaPH0/79++nqKgoWr58OVVUVMildXNzo4iICJXKThG6Nlra78Wtk7KyMiopKSGZTEYVFRVUX18vl6a2tpYKCgqoqalJJdsymYzEYjE1NDRQQUEBPXnyRGG6ntp/GnVNBekpK1euJHt7e5JIJHT9+nWFNwNRR5kUFRWRWCwmoo75Wc/mu7W1VS7szp071N7e3ms/1SFuRETz58+njIyMHp1bW1srF9bU1ESFhYWcqPWUrtrSgwcPKDc3lzcV6Xm0tLTQrVu36OHDhwrji4uLydTUlMrLy3vlL5HuiVu/Hi19GkdHR+7/rvoOXnrppR6NQgkEAgwcOBAAMGnSpC7T9dS+LmJiYoIJEyZ0GS8QCODq6sodd44MPo2xsbHcp3CK0mmTI0eOICQkBAsWLFB5s2hFdS0UCuWmhPSErtqSjY0Njh07hpCQEKXsmJqaYuzYsV3Gx8XF4eDBg3j11Vd76qrO0q/73Bjqp6mpSS+/M+yK4cOHIzw8vN+sjnHo0CF4eno+94dHWZKSkiAUCrFy5Uo1eKZ7MHFjAOj4PvfgwYO4fPkynjx5gq1bt74wy0YtWbIEfn5+OHPmjLZd6ZY1a9Y89+1BWXJycmBhYYFdu3apwSvdRG9eSxm9w9jYGOvWrcO6deu07YpWGDlyZL+YCqHqq3NXKDs9pT/DntwYDIZewsSNwWDoJUzcGAyGXsLEjcFg6CU6NaBw5coVbbugdTrLICUlRcue6D6svegWlZWVOrWnhIDomcWptMSzy+wwGIz+h4+PD29RAS1ySqdeS5OTk0FEL/RfcnIyAGjdD13/Y+1F9/58fHy0KR9y6JS4MRgMhrpg4sZgMPQSJm4MBkMvYeLGYDD0EiZuDAZDL2HixmAw9BKdmsSrLLm5ubh79y4vzMjICIMHD8bQoUPh6urKLS7JYDxLaWkp0tLSYGdnx4XNmzdPbvcniUSC1NRUbpMbAwMDeHp66sS+q8/y888/IzExEQ8fPsSECRMQEBAgt1Ao0LGPwpkzZ/DKK6/A39+f29/20qVLGDhwIKZNm9bXrmuMfvnk9rvf/Q5WVlZYsWIFPvjgA5SWlqKlpQXXr1/Hnj17YGlpCS8vL/z000/adrXf8eyuVv3FtrKkpqbiiy++QEREBDw8PJCTk4OgoCAsXrxYzj9TU1PMnz8f2dnZOHToEN566y2dFLbi4mKMHTsWhw4dwsGDBxEaGorp06dzmwR1cvz4cURFReG9997DgAEDMHv2bG6bP3d3dxQXF/ebRTuVgnQE9GBN/KFDh5Kzs7Nc+MWLF8nW1pYGDBhA+fn56nKxT9D2Hgr/8z//o5Y9DjRtuyft5ebNmzRz5ky5cGdnZwJAISEhCs/7+uuv6eOPP+6Rn31BREQEXblyhYiIKisrydfXlwDQRx99xKX58ccfydzcnKqqqrgwDw8PWrt2Lc9WSEgIZWVl9cgPXdtDoV8+uXXSuYnts8ydOxfHjh1DS0sLvL29deKJoT/www8/4PDhw/3OtjK0t7fD29sbAQEBcnFmZmZwc3NDfHw8YmJi5OJNTEy41zdd47fffsPMmTMxffp0AMDLL7+MvXv3QiAQ4D//+Q+XbuPGjRg9ejTvVXzOnDk4duwY7t27x4Xt2LEDYWFherHUfL/sc1MGLy8vzJ07F//85z9x6tQpBAYGAgAaGhqQnJyM27dv49VXX0VISAjXcMvKyhAfH49PP/0U5eXlSElJgbW1NUJCQnj9F99//z0yMzMxfPhwGBgYYPXq1Vzc8+xrEolEgsuXL+Py5cuwt7eHp6cnt2lOcnIyZDIZjI2NuU9kTp8+DalUCqFQiMWLFyM3Nxf+/v4Qi8VISkqCsbExli5divLycpw7dw4bNmzg8u3k5ISgoCAYGBj0yrZYLMZnn30GX19fODs7a7R80tPTcf/+ffj7+yuMT01NxZQpU7Bx40a4uLjg7bfffq6955U3oHxb6m17GTJkCJYsWcILc3BwwNixY3mb8RQWFsLd3Z2XbsSIEWhtbUV2dja3j8KwYcNgbm6Obdu24bPPPlPaD51E28+OnaAHrxm2trYKX0s7+fjjjwkArVy5kog6tpVbuHAhZWVl0Y0bN8jFxYUcHR2prq6O4uPjycbGhgBQRkYGvfvuu7RgwQICQFu3buVsRkZGUmJiIonFYjp58iQNGjSIi3uefWXpyWtpc3MzzZ49m5KSkqiuro5iY2PJ3Nyczpw5Q0REDQ0NNGPGDBKJRNw5VVVV5OrqSra2tkRElJOTQwEBAQSAzp8/T1lZWRQbG0uDBg0iOzs7SkxMJFdXVxIKhQSAvL29e2WbiOjChQsEgCIjI1XKL5Hq7cXd3Z0mTJigMG7SpElERHTt2jUSCoU0dOhQKisr4+JTUlJ4e5R2V97KtiV1tBdFtLe3k5mZGedPbW0tAaD333+fly4/P58AyL1yh4WFkYODg8rX1bXXUr0Wt7/97W8EgObNm0dERPPmzeNtcJuZmclrcJGRkQSA0tPTuTTu7u7k5ORERB37cFpaWlJJSQkX//T+kd3ZV4aeiJu/vz+Fhobywnx8fEgoFNK9e/eIiCg8PJwnQEREq1at4gSIiOiTTz4hACSTybgwX19fMjMzo6+//pqIOoTLzc2NAHAi1VPbbW1tlJ6eTo8fP1Ypv0SqtReZTEYDBgwgLy8vhfGd4kbUsVEzABo7diw1NDQQkby4KVPe3bUlIvW0F0WcPXuWpk2bxpX1v/71LwJA27Zt46UrLy8nABQcHMwLj46OJgAq14uuiVu/7nPrjs5+AysrK1RXVyM7Oxt5eXnYsmULtmzZgm+++QaTJ09GU1MTgI6+F6DjlbYTFxcXbhcoY2NjmJub4+2330ZmZiYAICoqCgCUsq8JmpqacOrUKbm9MteuXYvm5mYcP34cgOKNRZTZbMTMzAwikYjrq7Kzs8Pu3bsBANnZ2b2ybWhoiEWLFml8BLK6uhotLS2wt7fvNq2fnx8++ugj/PjjjwgMDORWIOlE2fLuri1pqr1IpVLs3r0bCQkJ3DJinXl4dmpIc3MzAMDW1pYXbm1tDQC4ceNGj/3QBfS2zw0ASkpKAABjxoxBaWkpACAyMrLLjZMV3ZBmZmZoa2vjjvfv34+goCB4eXlxndBWVlZK2dcEeXl5kEqlMDLiV2Vnf8udO3d6fY1n19qbMmUKAPA6onWZmpoaAIBIJFIq/a5du3Dr1i1kZGRg27ZtGDduHBenbHl315Y01V42bNiA6OhoXh9m5wKSdXV1vLSdP/4uLi688E5/SkpKMGfOHLX51tfo7ZNba2srzp8/DyMjIyxZsoQbWS0sLJRL++TJE6XtLliwAGVlZdiwYQMKCgowefJk3L59W232VaVzgmleXh4vvLOBOjk5qf2aJiYmMDU1xSuvvKJ225pg1KhREAgEePz4sVLpDQwMkJiYiNdffx07d+7kLb6orvLWRHv5/PPPMWXKFN7TItAxcDB06FBUV1fzwn/++WcAkNuRvlP0np3U3N/QW3H785//zInQmDFj4OzsDENDQ0RHR6O1tZVLV1tbi8TERKVsisVixMXFYejQodi3bx++++47NDY24uTJk2qx3xMmTpwIU1NT5Obm8sJra2sB/N/+lCKRSG5KDBFxN+vTPBvW0tLCO87Ly4NEIsHUqVN7bbsvMDc3h6OjIx4+fKj0OSKRCBkZGbCwsOCJm7Ll3R3qbi9fffUVBAIBQkJCuDAiwk8//QQTExP4+/sjJyeHd05RURGsrKwwZswYXnhVVRUA9It9XJ9HvxU3qVTKNainkUgk+PDDD/HJJ59gy5Yt2LlzJwDAwsICYWFhyM/Px6xZs3DixAnEx8cjICAAfn5+AIBff/0VwP/1RQBAW1sbpFIpJBIJZDIZoqOjuZvdzc0No0ePhpWVlVL2NYG1tTU++OAD3L17F5cuXeLC09LSsHTpUsyaNQtAx/QAiUSC7OxsEHWs+JuXl4f6+nrU19ejvb0dVlZWAICCggLk5ORw+ayvr8cvv/zC2f72228xefJkeHt798r2gwcPsGzZMjmh0AQTJ07sUtzu37+vsJ9r1KhRSElJgaGhIRembHl315aUaS979uyBv78/JzZdcfjwYXz55ZcQiUSIj4/H8ePHERsbi3feeYe7RzZv3oy2tjZO4BobG3H06FHs3LkTpqamPHtVVVUYMmQIXnvttedeV+fR4mgGD6gw+vXvf/+bvL29CQAZGRnRxIkTacmSJeTt7U3vvPMOhYWFUUFBgdx5YrGYVqxYQQAIAIlEIm60Ki0tjUaMGEEAaP369VRRUUFJSUk0cuRIAkCbNm2i8vJyEgqF5OrqSl988QVt376dQkNDqbW1tVv7ytKT0dL29naKiIggKysr2rx5MwUHB9OyZcuoubmZl3cXFxcCQDY2NpSQkECrV68mCwsL2rhxIz169IgqKirIxsaGLCws6MsvvyQiopUrV5KZmRktWrSIDhw4QKtXr6aZM2fS3bt3e2374sWLBICio6NVyi+R6qPrJ06cIFNTU2psbOTCCgsLadWqVQSAli5dStnZ2QrPjYmJ4Y2WdlfeyrSlmpqabtvL8OHDCQBFRUV1ma/jx49z5z/7N3LkSN7o9H/+8x+aO3cu/elPfyJ/f3+KiYlRaNPNzY0iIiKUK9in0LXR0n4pbr2ltraWCgoKqKmpSaXzZDIZicViamhooIKCAnry5Ila7RP17vOrpqYmKiws5Ina08hkMioqKiKxWExEHfOsnvWxtbWVF7Zy5Uqyt7cniURC169fp4qKCrXZ7kzXk0+yetJe5s+fTxkZGSpfi6ijTp+lu/JWxbai9vLgwQPKzc3lTTdSBxUVFV2WeXFxMZmamlJ5ebnKdnVN3PR6tLQrXnrppR6NUAkEAm61kUmTJqndfm8RCoVyUxSeRiAQwNXVlTt+egZ7J8bGxgpXkzAxMcGECRPUbltROk1x5MgRhISEYMGCBUpNVXkaRfXZXXmrYluRfRsbGxw7dozXj6YOnteXFhcXh4MHD+LVV19V6zW1Qb/tc2P0DU1NTXrxnSEADB8+HOHh4f1m5YtDhw7B09PzuT8q6iQpKQlCoZD7FKu/w8SNoRCpVIqDBw/i8uXLePLkCbZu3cpNQO3PLFmyBH5+fjhz5oy2XemWNWvWPPcNQZ3k5OTAwsICu3bt6pPr9QUv5Gspo3uMjY2xbt06rFu3TtuuqJ2RI0f2i2kOqr469wZlp7D0J9iTG4PB0EuYuDEYDL2EiRuDwdBLmLgxGAy9RKcGFPbt28f7ju9FpHNEcunSpVr2RL2IxWLU1NSodf4Uay+6RX5+PrfcuS4gIHpmwSotoW83M4NPZWUl8vPzuaXIGfqJm5sbIiIitO0GAJzSGXFj6DcpKSnw9fWVW/yRwdAQp1ifG4PB0EuYuDEYDL2EiRuDwdBLmLgxGAy9hIkbg8HQS5i4MRgMvYSJG4PB0EuYuDEYDL2EiRuDwdBLmLgxGAy9hIkbg8HQS5i4MRgMvYSJG4PB0EuYuDEYDL2EiRuDwdBLmLgxGAy9hIkbg8HQS5i4MRgMvYSJG4PB0EuYuDEYDL2EiRuDwdBLmLgxGAy9hIkbg8HQS5i4MRgMvYSJG4PB0EuYuDEYDL2EiRuDwdBLmLgxGAy9hIkbg8HQS5i4MRgMvYSJG4PB0EuMtO0AQ/+ora3F2bNneWHXrl0DABw9epQXbm5uDj8/vz7zjfHiICAi0rYTDP1CIpHAysoKYrEYhoaGAAAigkwm444BQCqVYsWKFUhISNCWqwz95RR7LWWoHVNTUyxduhRGRkaQSqWQSqVoa2uDTCbjjqVSKQDA399fy94y9BUmbgyN4O/vj9bW1uemGTJkCObOndtHHjFeNJi4MTSCu7s7rKysuow3NjZGYGAgjIxYty9DMzBxY2gEAwMD+Pv7w8TERGG8VCplAwkMjcLEjaEx/Pz8unw1tbOzg5ubWx97xHiRYOLG0BjTpk2Dg4ODXLiJiQlCQkIgEAi04BXjRYGJG0OjBAUFwdjYmBfW2trKXkkZGoeJG0OjBAQEcNM+Ohk1ahRcXV215BHjRYGJG0OjvPbaaxgzZgz3CmpsbIzQ0FAte8V4EWDixtA4K1as4L5MkEqlWLZsmZY9YrwIMHFjaJzly5ejvb0dAPDGG29g1KhRWvaI8SLAxI2hcRwcHDB16lQAQHBwsJa9YbwoMHFj9Amdr6ZLly7VtiuMFwSVv31JSUnRhB8MPcfExATjxo3Dv//9b227wuiHDB8+XOVJ3yovecQmXjIYjL7Gx8cHp06dUuWUUz36ajk5OZmNePUzUlJS4OvrC7Z83/MRCASsfesYPe3KYH1uDAZDL2HixmAw9BImbgwGQy9h4sZgMPQSJm4MBkMvYeLGYDD0kj5ZwL6trQ3p6ek4dOgQFi5ciPXr1/faZnV1NeLi4vDVV1/hhx9+gLm5uRo87Xs0UTaapK6uDjNmzMDmzZvZp1TPUFpairS0NNjZ2XFh8+bNg42NDS+dRCJBamoq972tgYEBPD09MXTo0D71Vxl+/vlnJCYm4uHDh5gwYQICAgLk1ucDgOvXr+PMmTN45ZVX4O/vj0GDBgEALl26hIEDB2LatGl97XrfPLlVVlaiqqoK//znP+XW9uopd+/eRV5eHn7++We12NMWmigbTWJkZARLS0uu8WoDiUSitWt3RWpqKr744gtERETAw8MDOTk5CAoKwuLFi+X8NTU1xfz585GdnY1Dhw7hrbfe0klhKy4uxtixY3Ho0CEcPHgQoaGhmD59OhobG3npjh8/jqioKLz33nsYMGAAZs+ejUePHgHo2CiouLgYe/bs6XP/+0TcRowYofb9KX/3u9/hrbfeUqtNbaCJstEk5ubmyMnJgbe3t9Z8iIqKgkwm09r1n6WoqAj79u1DbGwsDA0NYW1tjSNHjsDZ2Rn5+fkICwuTO2fIkCHw8PDAnDlzMGzYMC143T3Hjh3DxYsXce/ePdy9exe+vr4oLCzErl27uDTFxcVYv349jh07BgcHB6xYsQKWlpbYtm0blyY0NBQlJSW4cOFCn/rfZ31umtjCTV+2hdOXfPQFP/zwAw4fPqxtNzja29vh7e2NgIAAuTgzMzO4ubkhPj4eMTExcvEmJiZafQJ+Hr/99htmzpyJ6dOnAwBefvll7N27FwKBAP/5z3+4dBs3bsTo0aN5r+Jz5szBsWPHcO/ePS5sx44dCAsLg1gs7rM89Nld1dU3qQ0NDUhOTsbt27fx6quvIiQkhFfhpaWl+Mc//oHffvsNU6dOxfz587u0+b//+78oKysD0NGPYWpqiubmZi7t8uXLAQA//vgjioqKAAAe6zbP+wAAIABJREFUHh6wtLTs1v/y8nLEx8dj+/btyMzMRHFxMT788EMYGxt3mwdVyyY5ORkymQzGxsbw8fEBAJw+fRpSqRRCoRCLFy9W2ra6aWlpwalTp2BjYwMPDw8AQFlZGeLj4/Hpp5+ivLwcKSkpsLa2RkhICNc/U15ejnPnzmHDhg34/vvvkZmZCScnJwQFBcHAwECpPOfm5sLf3x9isRhJSUkwNjbG0qVLIRaL8dlnn8HX1xfOzs59Wh7p6em4f/9+l0/fqampmDJlCjZu3AgXFxe8/fbbz7UnkUhw+fJlXL58Gfb29vD09ISjoyMXr0xZA93fV90xZMgQLFmyhBfm4OCAsWPHYvTo0VxYYWEh3N3deelGjBiB1tZWZGdnY+XKlQCAYcOGwdzcHNu2bcNnn32mtB+9glQEACUnJ6t6GtXX1xMA+vOf/8yF3blzhxYuXEhZWVl048YNcnFxIUdHR6qrqyMiog8++IDefPNNevToEV24cIEEAgHt2bOHO/9Pf/oTAaCGhgYiIrp79y5ZWFhQQkICNTY20u3bt8nOzo4AUGlpKXdee3s7zZ07l/bv308ymaxb3xMSEsjW1pYAUHx8PE2cOJEAUG5ubrd56EnZNDQ00IwZM0gkEnFpqqqqyNXVlWxtbZW2+zTJycnUg+rmcfv2bVq8eDEBoL179xIRUXx8PNnY2BAAysjIoHfffZcWLFhAAGjr1q1ERBQbG0uDBg0iOzs7SkxMJFdXVxIKhQSAvL29lc5zTk4OBQQEEAA6f/48ZWVlERHRhQsXCABFRkb2Kn9Eqrdvd3d3mjBhgsK4SZMmERHRtWvXSCgU0tChQ6msrIyLT0lJ4bXn5uZmmj17NiUlJVFdXR3FxsaSubk5nTlzhoiUK2ui7u+rntLe3k5mZmacP7W1tQSA3n//fV66/Px8AkAff/wxLzwsLIwcHBxUvq6Pjw/5+PioelqKVsVt3rx5dPbsWe44MzOTV1GDBw+mnTt3cvFjxoyh6dOnc8dPi1tVVRV5enpScXEx77qJiYkEgLsRiIhaW1tp8uTJ1NbWprT/UVFRnLgREf30008kk8m6zYMyKCqb8PBw3o1ORLRq1SqtihsR0f3793niRkQUGRlJACg9PZ0Lc3d3JycnJ+7Y19eXzMzM6OuvvyaiDuFyc3Pj1Y0yef7kk08IAO9Hqa2tjdLT0+nx48e9zp8q7Vsmk9GAAQPIy8tLYXynuBERnThxggDQ2LFjuR/jZ8XN39+fQkNDeTZ8fHxIKBTSvXv3iEi5slZHm1TE2bNnadq0aVzZ/+tf/yIAtG3bNl668vJyAkDBwcG88OjoaAKgcj31VNy01tlTXV2N7OxsTJgwgXuHb2xsxOTJk9HU1AQA+Oabb/D6668DAK5evQoi4l4zn6a0tBQfffQRvvzyS7zyyiu8OF9fX0RHR+Mvf/kL9xp19uxZLF68mFvXXxmEQiEAcFvSOTs7K5WHnmJgIN8dqiisr1H0amNmZgYA8PLy4sJcXFx4fTNmZmYQiURc35SdnR12796N2bNnIzs7Gx4eHj3Os6GhIRYtWqRyXnpLdXU1WlpaYG9v321aPz8/FBUVYc+ePQgMDERaWhovvqmpCadOnZJ7ZVu7di1Onz6N48ePY+vWrd2WtabapFQqxe7du/G3v/2N60ah/3+FmWenhnTeo7a2trxwa2trAMCNGzcwZ86cHvuiLFoTt9LSUgBAZGQkXnrpJYVpZsyYgbNnzyI1NRW///3vMWLECNy/f18u3R//+EeUlZUpFCtDQ0Ns3rwZ7733Hq5evYqpU6fi2LFjSEhIUMlfRX2GyuRB31BWgMzMzNDW1sYLe7YMp0yZAgC8juf+RE1NDQBAJBIplX7Xrl24desWMjIysG3bNowbN46Ly8vLg1QqlRtc6uzfunPnDoDuy1pTbXLDhg2Ijo7m9Wl2jvLW1dXx0nYOGri4uPDCO/0pKSnpE3HT2qOAiYkJgI4OyWd58uQJgI4K+uqrrxAXF4fAwECYmpoqtHXo0CG0tbXB29sbra2tcvErVqzAyy+/jF27dqGkpARDhgyR+1XRVB4YXWNiYgJTU1O5p+3+wqhRoyAQCPD48WOl0hsYGCAxMRGvv/46du7cyVt8sXNCb15eHu+cTkFwcnJS6hqaaJOff/45pkyZwntaBDoGDv4/9s48KqpjXftPg4At0rFRRFQiKBFlyELjEKLGOCMkXgwiAUTQaxSNHpWDqDFCTPRqkpPIibM4wL2BAE5I9KrgSaIENCbgkIhRphMVHFAJytQ09Pv94df7sukGupseoK3fWq7lrqr91ruraz/sXfXuKmtra9y7d4+XLo89dXV15aXLRa95ULOuMJi4OTs7w9TUFDExMTxBKi8vR2JiInJzc/HFF1/ggw8+QNeuXbl8UrLYooODA5KSkvDLL79g2bJlCvnm5uaIjIzkZuuUxR3p4hrag0gkUgj+JCLuJuiM1NXV8Y5zcnIgkUi4zWPUueaO0A5WVlYYNGgQHj58qPI5IpEI6enpEIvFPHEbNmwYLCwskJ2dzStfXl4OABg3bpxK9rXdJw8cOACBQICwsDAujYjwxx9/wNzcHEFBQcjKyuKdc+3aNdjY2MDFxYWXXlZWBgBwdHRU2w9N0Ju4yaOa5eotFosRHh6OixcvYvz48UhKSkJ8fDyCg4MRGBiIbt26AQDS0tLQ0NCAs2fP4urVq6ioqEBBQQFKSkp4NqdOnYro6Gjs3bsX27dvV6j//fffR8+ePVFSUqIwda0K8q8Hmv6VbusaNG0b4Pm0u0QiQWZmJogIKSkpyMnJQWVlJSorKw12cyvz9cmTJwDAGw9taGiAVCrliVVlZSVu377NHZ8+fRojRozgAoJVuWYbGxsAQG5uLrKyslBXV4f79+9j9uzZCsKgD4YNG9aiuJWWliod53JyckJqaipvGKV3795YtmwZSkpK8MMPP3DpaWlp8Pf3x/jx4wG03daq9MktW7YgKCiIE5uW2L17N/bt2weRSIT4+HgcPHgQ27Ztw9tvv82J7urVq9HQ0MAJXFVVFfbu3YuNGzcqvGmVlZWhR48eGDJkSKv1ag11pyCgwWxpWVkZLV68mACQi4sLpaWlERFRdXU1zZ07lwAQABKJRLxZnpCQEDIxMSFbW1vavXs3bdy4kUxMTCgyMpJSU1PJxcWFm4ouKCigkydPEgAyMTGh5cuX040bN3h+REVF0VdffaXuJdPhw4fJ2dmZAJC/vz9dvXqVy2vrGtrTNm5ubgSAbG1tKSEhgRYuXEhisZgiIyPp0aNHal2DNmZLb9++zfP11KlTlJaWRg4ODgSAli9fTsXFxZScnEyOjo4EgFatWkUPHjyg+fPnk6WlJc2YMYN27NhBCxcupLFjx1JJSQlnX5VrLi4uJltbWxKLxbRv3z4iIjp79iwBoJiYmHZdH5H6/TspKYksLCyoqqqKS8vLy6MFCxZw/SUzM1PpubGxsbzZ0sbGRoqIiCAbGxtavXo1hYaG0uzZs6m2tpaISOW2bqtP2tvbEwBat25di9d18OBB7vzm/xwdHXmz1T///DNNmjSJPv/8cwoKCqLY2FilNj09PSkiIkK1hm1Chw8FaY3y8nLKzc2lmpoahbyHDx9SfX09d/zkyRON6/H29m7X+a3R2jVoikwmo2vXrlF1dTURPY9f0tS+tkJBNGX+/PnUt29fkkgkdPnyZSouLlZaTpVrrq+vV0i7desWNTY2tttPTfr39OnTKT09XaP6ysvLFdJqamooLy+PEzVNaalP3r9/n7Kzs2n58uXtst+c4uLiFn+D/Px8srCwoKKiIrXtdrpQkKb06tWrxZkd+WuIHLFYrFEdOTk5sLe31/j8tmjtGjRFIBDA3d2dO24aGd5ZMTc3h4eHR4v5qlyzmZmZQviBIdtmz549CAsLg4+Pj9rhOsr6jFAoxLBhw9rtV0t90tbWFvv37+eNo2mD1sbS4uLisHPnTgwcOFCrdbZGhxA3XXHp0iVERETA1dUV+fn5OHHihKFdemGpqanR63eF+sTe3h5Lly7Fli1b8OGHHxranTbZtWsXvLy8Wv0jo02Sk5MhFAq5T7H0hVGLG/A87kcoFCI2NhYvvfQSL+/OnTuYN29emzZCQ0MREhKiVr26tN2ZkEqliIuLw7lz5/Ds2TOsX78eixYt6rArYWjKzJkz4eHhgSNHjhh0xRRVWLRokd4CwrOysiAWi3kriegLoxa3UaNGcYGWyujfvz9OnjzZph1NVu3Qpe3OhJmZGZYsWYIlS5YY2hWd4+joqLcwh/agzy9dVA1h0QXGfWe1gUAgaDEwuCPbZjAYbWP4jxUZDAZDBzBxYzAYRgkTNwaDYZRoNOa2detW3ndxjI7P3bt3AQD+/v4G9qTjw/p3x+LixYvccufqwJ7cGAyGUSIgUrLMRmsnCARISUnB7NmzdeUTQwekpqYiICBA6aoqjP+D9e+Oh/xtQ82n6UPsyY3BYBglTNwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCU6/bb00qVL3K49XIVdunA7v2uTe/fuIS4uDgcOHMBvv/0GKysrjexkZ2ejpKSEO5Z/IyoSieDm5qbSNm5NUacNjh8/ztvEQyAQYOTIkdzmIHV1dTh27Bi3xLiJiQkmTpyolc1uGO2noKAAaWlpsLOz49KmTJmisCGKRCLB0aNHeb+jl5cXrK2t9eqvKvz5559ITEzEw4cP4eHhgeDgYIW19ADg8uXLOHLkCF5++WUEBQVxW0D+8MMP6NatG0aPHq1v13W/zPj58+fJzMyM20hWvsKqtsnOzqZp06bxdqDXBJlMRqdPnyaBQEC9evWir7/+mrZu3UqvvfYamZiY0MqVK9VeDVfVNpBIJBQdHU0AqE+fPnTlyhWFMn/99RfNnTuXhg4dqrABdWsYeiXeurq6TmFb3f4t58iRI7R06VJqaGigBw8e0MKFCwkAvf7660r9q6iooLlz59Ibb7zBbbjc0bh+/TpZWlpS//79uf47fPhwevbsGa/cgQMHaPr06fTvf/+bEhIS6LXXXuOtMHzgwAHavHmzxn506GXGHRwcqGfPnupWpTabNm1qt7jJsba2pqFDh/LSgoKCCABt2LBBbXuqtsG1a9cIAL399tstlklOTqYVK1aoVb+hxe3vf/+7VpYB17VtTfr31atXaezYsQrp8n03wsLClJ73zTff0EcffaSRn/ogIiKCLly4QEREd+/epYCAAAJAa9as4cpcv36drKysqKysjEubOnUqLV68mGcrLCyMzpw5o5EfmoqbXsbczM3Nuf0UdYk210ZT5u9//ud/Ani+sqgm9lRpg549ewJofaNfc3NzhYU3OzK//fYbdu/e3elsq0JjYyP8/PwQHByskGdpaQlPT0/Ex8cjNjZWId/c3Jx7feto/PXXXxg7diz32VO/fv3w2WefQSAQcDvZA0BkZCReeeUV3qv4xIkTsX//ft5m259++inCw8P1uhpzh1vP7enTp0hJScGNGzcwcOBAhIWF8TpAQUEB/vd//xd//fUXRo0ahenTp3N5zXc0/+WXX1BYWAjg+biGhYUFtyWaQCDgxr2uX7+Oa9euAQCmTp3KCUxz5IKjbEHCtvzurEgkEpw7dw7nzp1D37594eXlhUGDBgEAUlJSIJPJYGZmhlmzZgEADh8+DKlUCqFQCF9fX2RnZyMoKAjV1dVITk6GmZkZ/P39UVRUxO0j+9NPP+HUqVMYPHgwQkJCYGJi0i7b1dXV+PLLLxEQEMDbIV0XHD9+HKWlpQgKClKaf/ToUYwcORKRkZFwc3PD5MmTW7XXWnsDQGFhIeLj4/HJJ5+gqKgIqamp6N27N8LCwnhjYe3tjz169MDMmTN5aQMGDICrqytvv4q8vDyFrTIdHBxQX1+PzMxMbmnx/v37w8rKCtHR0fjyyy9V9qNdqPusBw0e2wcPHkx2dnZtlrt16xa98847dObMGbpy5Qq5ubnRoEGDqKKigoiIli1bRuPGjaNHjx5RRkYGCQQC3tZon3/+Oe+1tKSkhMRiMSUkJFBVVRXduHGD7OzsCAAVFBRw5zU2NtKkSZNo+/bt3JZlffr04b2WNjY20syZMwmAwtZ9bfmtThuUlpYSAAoKCmqxzNGjR9Xexk6T19La2lp66623KDk5mSoqKmjbtm1kZWVFR44cISKip0+f0pgxY0gkEnHnlJWVkbu7O/Xp04eIiLKysig4OJgA0IkTJ+jMmTO0bds26t69O9nZ2VFiYiK5u7uTUCgkAOTn59cu20REGRkZBICioqLUul4i9fv3hAkTyMPDQ2ne8OHDiYjo119/JaFQSNbW1lRYWMjlp6am8vpvW+0dHx9Ptra2BIDS09Pp3XffJR8fHwJA69ev5+yo0h81obGxkSwtLTl/ysvLua01m3Lx4kUCoPDKHR4eTgMGDFC73g495qbqjT1lyhSecJw6dYr3w7300ku0ceNGLt/FxYVef/117ripuJWVlZGXl5fCoHtiYiIB4L3/19fX04gRI6ihoYFL69OnD/Xr14/i4+Pp008/JRcXFxo9ejQdOnRIbb/VaYOOJG5BQUE0b948XtqsWbNIKBRyg+BLly7lCRAR0YIFCzgBIiLasGEDAeDtdRkQEECWlpb0zTffENFz4fL09OT9NprabmhooOPHj9Pjx4/Vul4i9fq3TCajrl27kre3t9J8ubgRPd/fFAC5urpyf3ybi5sq7R0VFcVNTMmZMGECDR48mDtWpT9qwrFjx2j06NFcW3///fcEgKKjo3nlioqKCACFhoby0mNiYgiA2r9Lhx5zU4V79+4hMzMTOTk5WLt2LdauXYuTJ09ixIgR3K7dJ0+exOLFiwE8D7EgIt7O23IKCgoQGhqKPXv2YOjQoby8gIAAODk54R//+AeXduzYMfj6+vJ2AAeer//v5OSEy5cvIz8/H9HR0dwrkjp+d0Zqampw6NAhhS3mFi9ejNraWhw8eBCA8vX4VVmj39LSEiKRiBursrOzw+bNmwEAmZmZ7bJtamqKGTNm6Dy04t69e6irq1MpPCgwMBBr1qzB9evXMWfOHIUFDFRtb0tLSwCAt7c3V8bNzY1b0kpX/VEqlWLz5s1ISEjghn/k19A8NER+TzYPUerduzcA4MqVKxr7oQ4dZsytoKAAABAVFdXi/p9jxozBsWPHcPToUUybNg0ODg4oLS1VKPe3v/0NhYWFCmIFPO/4q1evxvvvv49Lly5h1KhR2L9/PxISEhTKCoVCjBkzBq6ursjNzUVYWBiuXbvG+9FU8VsdunbtCgCor69vsUxtbS1XTlfk5ORAKpUqTNLIx1uax+5pQvMx0pEjRwIAbyC6IyPffKi1yZ+mbNq0Cb///jvS09MRHR2NV199lctTtb2VibulpSUaGhoAaL8/ylmxYgViYmJ4Y5jyHcwqKip4ZeWTBm5ubrx0uT83b97ExIkTteZbS3SIJ7eCggJuJjEvL08hXx7YGhUVhQMHDiAuLg5z5sxpcQOWXbt2oaGhAX5+fkpFYu7cuejXrx82bdqEmzdvokePHq0Gwvbo0QOJiYl48uQJQkNDeX91VfFbFeSdsnv37jAxMUF5eXmLZR8/ftzipIe2kAeY5uTk8NLlHVQeWKxNzM3NYWFhgZdfflnrtnWBk5MTBAIBHj9+rFJ5ExMTJCYmYujQodi4cSNvCR9ttbe2+mNT/vnPf2LkyJG8p0Xg+cSBtbU17t27x0v/888/AQCurq68dLnoNQ9q1hV6E7fmj+FyZDIZ4uLi4OzsDFNTU8TExPAEqby8HImJicjNzcUXX3yBDz74gPfUosyug4MDkpKS8Msvv2DZsmUK+ebm5oiMjORm68LDw9v0f8yYMYiOjkZGRgbvlbYtv9VpA7lv8idFZa/cAPCvf/2Le8rRFcOGDYOFhQWys7N56XLRlW/ZJhKJIJFIeGWIiLtZm9I8ra6ujneck5MDiUSCUaNGtdu2PrCyssKgQYPw8OFDlc8RiURIT0+HWCzmiZuq7d0W6vRHVThw4AAEAgFvd3oiwh9//AFzc3MEBQUhKyuLd861a9dgY2MDFxcXXnpZWRmA1nem1yZ6Ebd79+7h0aNHCh1VIpHgb3/7GxwcHCAWixEeHo6LFy9i/PjxSEpKQnx8PIKDgxEYGIhu3boBANLS0tDQ0ICzZ8/i6tWrqKioQEFBAUpKSlBVVQXg+V+IqVOnIjo6Gnv37sX27dsVfHr//ffRs2dPlJSUKExlNzQ04NGjR3j69Ckvfd26dRg3bhw3jgGgTb/VaQM5+/btg1QqxX/9138p+L1+/XoMHDhQ57uF9+7dG8uWLUNJSQl++OEHLj0tLQ3+/v4YP348gOfhARKJBJmZmSAipKSkICcnB5WVlaisrERjYyNsbGwAALm5ucjKyuJErbKyErdv3+Zsnz59GiNGjOA2NdbU9v379zF79mwFodAFw4YNa1HcSktLlY5zOTk5ITU1lTdsomp7P3nyBAB4f/gaGhoglUohkUhU6o9btmxBUFAQJzYtsXv3buzbtw8ikQjx8fE4ePAgtm3bhrfffpsT3dWrV6OhoYETuKqqKuzduxcbN25UeLMqKytDjx49MGTIkFbr1RrqTkFAjdmkixcvclP1AKh///40cuRIGjVqFL366qtkZWVFAoGA7t69S0RE1dXVNHfuXK68SCTizfqEhISQiYkJ2dra0u7du2njxo1kYmJCkZGRlJqaSi4uLtzUdEFBAZ08eZIAkImJCS1fvpxu3LjB8y8qKoq++uorXtr58+fJz8+P8yE8PJwuXbrE5d++fZvEYjF16dKFfH19KTMzs1W/1W0DOUlJSdSnTx967bXXaNmyZRQUFEQTJkyglStX8mZ1VUWT2dLGxkaKiIggGxsbWr16NYWGhtLs2bOptraWK1NdXU1ubm4EgGxtbSkhIYEWLlxIYrGYIiMj6dGjR1RcXEy2trYkFotp3759REQ0f/58srS0pBkzZtCOHTto4cKFNHbsWCopKWm37bNnzxIAtWeUidSPBkhKSiILCwuqqqri0vLy8mjBggUEgPz9/SkzM1PpubGxsbzZ0rbaOy0tjRwcHAgALV++nIqLiyk5OZkcHR0JAK1atYoePHjQ5n1kb29PAGjdunUtXtfBgwe585v/c3R05M1O//zzzzRp0iT6/PPPKSgoiGJjY5Xa9PT0pIiICNUatgkdOhREXcrLyyk3N1fpN5wPHz6k+vp67vjJkyca1+Pt7d2u85vTmt+aUF9fT7///jt9//33VFpa2i5b7fn8qqamhvLy8nii1hSZTEbXrl3jvpm9deuWQhvU19fz0ubPn099+/YliURCly9fpuLiYq3ZlpfT5JMsTfr39OnTKT09Xe26iIj3DaacttpbHdvK+uP9+/cpOzubli9f3i77zSkuLm6xzfPz88nCwoKKiorUtqupuHWY2dKm9OrVq8WZHvlriByxWKxRHTk5ObC3t9f4fGW05rcmmJmZwdXVVWFgVt8IhUKFEIWmCAQCuLu7c8dNI9jlmJmZKV1NwtzcvNVXbE1tKyunK/bs2YOwsDD4+PioFKrSFGX9pa32Vse2Mvu2trbYv38/bxxNG7Q2lhYXF4edO3di4MCBWq2zNTqkuOmKS5cuISIiAq6ursjPz8eJEycM7dILS01NjV6/M9Ql9vb2WLp0KbZs2YIPP/zQ0O60ya5du+Dl5aXzcVs5ycnJEAqF3KdY+qJDhILok4KCAhQXFyM2NrZTfXxuLEilUuzcuRPnzp3Ds2fPsH79ei4AtTMzc+ZMBAYG4siRI4Z2pU0WLVqE4cOH66WurKwsiMVibNq0SS/1NeWFenIbNWoUF3jJMAxmZmZYsmQJlixZYmhXtI6jo6Pewhzag7qvzu1B1RAWXfDCPbkxGIwXAyZuDAbDKGHixmAwjBImbgwGwyhh4sZgMIwSAVELX3O3dEKzZWoYDAZD18yaNYu30IAKHFI7FCQlJUXdUxgMXLhwAbGxsaz/MDTC3t5e7XPUfnJjMDQhNTUVAQEBLS77xGBomUNszI3BYBglTNwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCVM3BgMhlHCxI3BYBglTNwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCVM3BgMhlHCxI3BYBglTNwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCVM3BgMhlHCxI3BYBglTNwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCVM3BgMhlHCxI3BYBglTNwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCVM3BgMhlHCxI3BYBglXQztAMP4uHv3LkJDQ9HY2MillZeXAwDeeustXllnZ2fs2bNHn+4xXhCYuDG0Tv/+/fHvf/8bxcXFCnnnzp3jHY8bN05fbjFeMNhrKUMnzJ07F2ZmZm2We++99/TgDeNFhIkbQycEBwdDKpW2WsbFxQWurq568ojxosHEjaETnJyc8Oqrr0IgECjNNzMzQ2hoqJ69YrxIMHFj6Iy5c+fC1NRUaV5DQwNmz56tZ48YLxJM3Bg6IzAwEDKZTCFdIBBg9OjRcHBw0L9TjBcGJm4MndG3b1+88cYbMDHhdzNTU1PMnTvXQF4xXhSYuDF0SkhIiEIaEcHPz88A3jBeJJi4MXSKv78/78nN1NQUkydPRu/evQ3oFeNFgIkbQ6eIxWJMnTqVm1ggIsyZM8fAXjFeBJi4MXTOnDlzuImFLl26YMaMGQb2iPEiwMSNoXNmzJgBCwsL7v8ikcjAHjFeBJi4MXSOpaUl/uM//gMA2CspQ28wcWPoheDgYPTo0QNeXl6GdoXxgqC3VUEuXLiAr776Sl/VMToYMpkMtra27MntBefQoUN6q0tvT2537tzB4cOH9VWd0XL48GHcvXvX0G6ojYmJCVxcXPRS18WLF3Hx4kW91MVQjbt37+o4dWj+AAAgAElEQVT9/tf7em76VG5jRCAQYOXKley7zFbw9/cHwPpaRyI1NRUBAQF6rZONuTEYDKOEiRuDwTBKmLgxGAyjhIkbg8EwSpi4MRgMo6RT7X71559/Yu/evUhMTMS///1vQ7ujERkZGZBKpfDx8TGYDxUVFRgzZgxWr17NlvpWQkFBAdLS0mBnZ8elTZkyBba2trxyEokER48e5bYwNDExgZeXF6ytrfXqryr8+eefSExMxMOHD+Hh4YHg4GClG/hcvnwZR44cwcsvv4ygoCB0794dAPDDDz+gW7duGD16tL5d15hO9eRWXFyMH3/8sVPGeZ09exbTpk3DtGnT8OuvvxrUly5duqBnz55cxzUEEonEYHW3xtGjR/H1118jIiICU6dORVZWFkJCQuDr66vgs4WFBaZPn47MzEzs2rULb775ZocUtvz8fLi6umLXrl3YuXMn5s2bh9dffx1VVVW8cgcPHsS6devw/vvvo2vXrnjrrbfw6NEjAMCECROQn5+PLVu2GOISNIP0REpKCmmjulWrVpGpqakWPNIvtbW1VFJSQgDo448/1tgOAEpJSdGiZ4bh73//OzU2NurE9qxZs2jWrFlqn3f16lUaO3asQrqzszMBoLCwMKXnffPNN/TRRx+pXZ++iIiIoAsXLhAR0d27dykgIIAA0Jo1a7gy169fJysrKyorK+PSpk6dSosXL+bZCgsLozNnzqjtg7bufzVI7VRPbgBU2guzI9K1a1f069fP0G50CH777Tfs3r3b0G7waGxshJ+fH4KDgxXyLC0t4enpifj4eMTGxirkm5ubG/QpuDX++usvjB07Fq+//joAoF+/fvjss88gEAjw888/c+UiIyPxyiuv8F7FJ06ciP379+POnTtc2qefforw8HBUV1fr7yI0pMOLm1QqRWpqKtauXYszZ84o3XDk6dOniIuLQ0REBLZv38573C4sLMRHH30EmUyGgoICbNq0CXFxcQp7av70009Yt24ddu/ejb1796psXx1a2glK39TV1eF//ud/kJGRwaWp0k5FRUXczS1vr4SEBO43SUlJwbfffsv7zObw4cP49ttvkZaWBgDIzs7G22+/jerqaiQnJ3NfEVRXV+OTTz7BzZs3dX79yjh+/DhKS0sRFBSkNP/o0aPo378/IiMjcfbs2TbtSSQSZGRkYN26ddixYweKiop4+ar2y/b2vR49emDmzJm8tAEDBsDV1RWvvPIKl5aXl4fBgwfzyjk4OKC+vh6ZmZlcWv/+/WFlZYXo6Gi1/DAI+npG1OSx9K+//qJJkybRxx9/TI8fP6aEhAQyNzfnvZbeunWL3nnnHTpz5gxduXKF3NzcaNCgQVRRUUHx8fFka2tLACg9PZ3effdd8vHxIQC0fv16zkZUVBQlJiZSdXU1ffvtt9S9e3eV7KuLTCYjALRhwwa1z5WDdr6W3rhxg3x9fQkAffbZZ0REKrXTtm3bqHv37mRnZ0eJiYnk7u5OQqGQAJCfnx8RET19+pTGjBlDIpGIq6+srIzc3d2pT58+RESUlZVFwcHBBIBOnDjBveJkZGQQAIqKitL42uRo8lo6YcIE8vDwUJo3fPhwIiL69ddfSSgUkrW1NRUWFnL5qamptGXLFu64traW3nrrLUpOTqaKigratm0bWVlZ0ZEjR4hItfYm0m7fa0pjYyNZWlpy/pSXlxMA+uCDD3jlLl68SAAUXrnDw8NpwIABatVpiNfSDi1uS5YsIV9fX17a22+/zRO3KVOm0LFjx7jjU6dO8TpJVFQUAaDjx49zZSZMmECDBw8mIqL6+nrq2bMn3bx5k8tfvny5yvbVoSOIGxFRaWkpT9yI2m4nIqKAgACytLSkb775hoieC5enpycB4ERq6dKlPHEjIlqwYAEnbkREGzZsIAAkk8m4tIaGBjp+/Dg9fvy4XddGpL64yWQy6tq1K3l7eyvNl4sbEVFSUhIBIFdXV3r69CkRKYpbUFAQzZs3T8EnoVBId+7cISLV2lubfa8px44do9GjR3Pt//333xMAio6O5pUrKioiABQaGspLj4mJIQBq/VZszK0JDx8+RFxcHKZOncpLf/XVV7n/37t3D5mZmcjJycHatWuxdu1anDx5EiNGjEBNTQ2A5+MlAODt7c2d5+bmxs24mpmZwcrKCpMnT8apU6cAAOvWrVPZfmdE2fhQW+0kLyMSibhxKTs7O2zevBkAuFeX5tv4tZTWHFNTU8yYMcMgs4337t1DXV0d+vbt22bZwMBArFmzBtevX8ecOXNARLz8mpoaHDp0CMOGDeOlL168GLW1tTh48CCAtttbV31PKpVi8+bNSEhIgEAgAADuGpqPZ9fW1gIA+vTpw0uXb+5z5coVjf3QBx02zu3q1auQSqUKDSv/QYDn8UgAEBUVhV69eim1o+zGsrS0RENDA3e8fft2hISEwNvbmxs4trGxUcl+Z0RVAWreTgC//QFg5MiRAMAbdO5sPHjwAABUXv5806ZN+P3335Geno7o6GjeH9ycnBxIpVJ06cK/teTjW7du3QLQdnvrqu+tWLECMTExcHZ25tL69+8P4Hn8Y1PkkwZubm68dLk/N2/exMSJE7Xmm7bpsE9uz549A/D8L1hLmJubA3g+GNrS+arg4+ODwsJCrFixArm5uRgxYgRu3LihNfvGjLm5OSwsLPDyyy8b2hWNcXJygkAgwOPHj1Uqb2JigsTERAwdOhQbN27kLa0kD+jNycnhnSMXhOaD9i2hi773z3/+EyNHjuQ9LQLPJw6sra0V7rU///wTAODq6spLl4te86DmjkaHFbchQ4YAAPeq2BT57JyzszNMTU0RExOD+vp6Lr+8vByJiYkq1VNdXY24uDhYW1tj69at+PHHH1FVVYVvv/1WK/abIn/8b/4q05moq6vjHefk5EAikWDUqFEAnj/9NA92JSLupm+KsjRDYGVlhUGDBuHhw4cqnyMSiZCeng6xWMwTt2HDhsHCwgLZ2dm88uXl5QCAcePGqWRf233vwIEDEAgECAsL49KICH/88QfMzc0RFBSErKws3jnXrl2DjY2NwiKjZWVlAABHR0e1/dAnHVbcXFxc4OXlhRMnTiA+Ph4AUF9fjytXroCIcOfOHVhZWSE8PBwXL17E+PHjkZSUhPj4eAQHByMwMBAA8OTJEwD/N34AAA0NDZBKpZBIJJDJZIiJieFuWk9PT7zyyiuwsbGBWCxu0746yDupoWOE5OEETf1oq53kVFZW4vbt29zx6dOnMWLECG4H+QEDBkAikSAzMxNEhJSUFOTk5KCyshKVlZVobGyEjY0NACA3NxdZWVmoq6vD/fv3MXv2bAVR0BfDhg1rUdxKS0uVjnM5OTkhNTWVF+LTu3dvLFu2DCUlJfjhhx+49LS0NPj7+2P8+PEA2m5vVfreli1bEBQUxIlNS+zevRv79u2DSCRCfHw8Dh48iG3btuHtt9/mRHf16tVoaGjgBK6qqgp79+7Fxo0buZ3L5JSVlaFHjx7cA0iHRV9TF5rMlty/f5/GjRtHAGjw4ME0Y8YMmjNnDnXv3p2WLl1Kd+/eperqapo7dy4BIAAkEom4Gaa0tDRycHAgALR8+XIqLi6m5ORkcnR0JAC0atUqKioqIqFQSO7u7vT111/Txx9/TPPmzaP6+noiolbtq0NOTg4tWbKEAJCTkxPt2LGDpFKp2nbQztnS27dv0+LFiwkAubi40KlTp1RqpwcPHtD8+fPJ0tKSZsyYQTt27KCFCxfS2LFjqaSkhLNfXV1Nbm5uBIBsbW0pISGBFi5cSGKxmCIjI+nRo0dUXFxMtra2JBaLad++fUREdPbsWQJAMTExGl+bHE1CQZKSksjCwoKqqqq4tLy8PFqwYAEBIH9/f8rMzFR6bmxsLG+2tLGxkSIiIsjGxoZWr15NoaGhNHv2bKqtrSUi1frlgwcP2ux79vb2BIDWrVvX4nUdPHiQO7/5P0dHR96M9c8//0yTJk2izz//nIKCgig2NlapTU9PT4qIiFCtYf8/LBSkBQoLC+nmzZskk8mouLiYKisrFcqUl5dTbm4u1dTUqGVbJpNRdXU1PX36lHJzc+nZs2dKy2lqX9u0V9zaw/z586lv374kkUjo8uXLVFxcrLScTCaja9euUXV1NRE9j9dq3m719fUKabdu3dLKJ1mafn41ffp0Sk9P16jO8vJyhbSamhrKy8vjRE1TWup79+/fp+zsbF7okjYoLi5u8XfIz88nCwsLKioqUsumIcStw86WNmXQoEHc/1t6z+/Vq5dGs0oCgQDdunUDAAwfPrzFcpraN0bMzc3h4eHRYr5AIIC7uzt33DQSXo6ZmZlC6IGycvpkz549CAsLg4+Pj0rhK01R1jeEQqFCSIgmtNT3bG1tsX//ft44mjZobSwtLi4OO3fuxMCBA7Vapy7osGNujI5HTU2NwccLdYm9vT2WLl3aaVa+2LVrF7y8vFr9Q6NNkpOTIRQKMX/+fL3U1146xZNbR+TOnTuYN29em+VCQ0MREhKiB490h1QqRVxcHM6dO4dnz55h/fr1WLRoERcfZUzMnDkTHh4eOHLkCDdJ0lFZtGiR2k+YmpKVlQWxWIxNmzbppT5twMRNQ/r374+TJ0+2Wa55MGdnxMzMDEuWLMGSJUsM7YpecHR07PBhDoBqX35oC1VDWDoSnf/OMxACgUBhipzBYHQc2Jgbg8EwSpi4MRgMo4SJG4PBMEqYuDEYDKNE7xMKzZfMYahPQEAAAgICDO1Gh4f1tRcbvYtbSkqKvqs0KgICArBixQp4enoa2pUOy9atWwEAK1euNLAnDDkXLlxQurmOLtG7uM2ePVvfVRoVAQEB8PT0ZO3YCvIliFgbdSz0LW5szI3BYBglTNwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCWd8sP57OxslJSU8NK6dOmCl156CdbW1nB3d+cWoGQw1KWgoABpaWmws7Pj0qZMmaKw25NEIsHRo0e5jW5MTEzg5eVlkL1XVSUjIwNSqRQ+Pj5K82/duoVLly5xxyYmJggICMD58+fRrVs3jB49Wl+utptO+eT2xhtvwMbGBnPnzsWyZctQUFCAuro6XL58GVu2bEHPnj3h7e2NP/74w9CuGhXNd7XqLLbV4ejRo/j6668RERGBqVOnIisrCyEhIfD19VXw0cLCAtOnT0dmZiZ27dqFN998s8MK29mzZzFt2jRMmzYNv/76a4vlFi5ciJCQEO5fYmIiTE1NMWHCBOTn53eahTwBdOwNYtrC2tqanJ2dFdLPnj1Lffr0oa5du9LFixe1WqehgQH3UPj73/+ulT0OdG1b0z0Url69SmPHjlVId3Z2JgAUFham9LxvvvmGPvroI7Xr0ye1tbVUUlJCAOjjjz9WWubcuXO0dOlSunz5Mvfv4cOHvDJhYWF05swZtes3xB4KnfLJTY5849rmTJo0Cfv370ddXR38/Pw6zFNBZ+a3337D7t27O51tVWlsbISfnx+Cg4MV8iwtLeHp6Yn4+Hilgajm5ubo3r27PtzUmK5du6Jfv36tltm8eTM+/PBDeHh4cP/k2zDK+fTTTxEeHt4plpvvlGNuquDt7Y1JkybhX//6Fw4dOoQ5c+YAAJ4+fYqUlBTcuHEDAwcORFhYGNcxCwsLER8fj08++QRFRUVITU1F7969ERYWxtvM5KeffsKpU6dgb28PExMTLFy4kMtrzb6hkEgkOHfuHM6dO4e+ffvCy8uL23QnJSUFMpkMZmZmmDVrFgDg8OHDkEqlEAqF8PX1RXZ2NoKCglBdXY3k5GSYmZnB398fRUVF+O6777BixQquTQYPHoyQkBCYmJi0y3Z1dTW+/PJLBAQEwNnZWedtdPz4cZSWliIoKEhp/tGjRzFy5EhERkbCzc0NkydPbtVea20OqN7XtNmfmu6v2pzs7GycPn0aQ4YMweTJk7FmzRqMHDlSoVz//v1hZWWF6OhofPnllxr5oTf09Yyoi8fSPn36KH0tlfPRRx8RAJo/fz4RPd867p133qEzZ87QlStXyM3NjQYNGkQVFRUUHx9Ptra2BIDS09Pp3XffJR8fHwJA69ev52xGRUVRYmIiVVdX07fffkvdu3fn8lqzry2g5mtpbW0tvfXWW5ScnEwVFRW0bds2srKyoiNHjhAR0dOnT2nMmDEkEom4c8rKysjd3Z369OlDRERZWVkUHBxMAOjEiRN05swZ2rZtG3Xv3p3s7OwoMTGR3N3dSSgUEgDy8/Nrl20iooyMDAJAUVFRareRJq+lEyZMIA8PD6V5w4cPJyKiX3/9lYRCIVlbW1NhYSGXn5qaytu3tK02V7Wvabs/yWQyAkAbNmxQyEtPT6f33nuPXF1dSSAQUJcuXeiLL75Qaic8PJwGDBigVt1s31I1aUvc/vu//5sA0JQpU4iIaMqUKbxNbU+dOsXrUFFRUQSAjh8/zpWZMGECDR48mIie77XZs2dPunnzJpffdM/ItuxrA3XFLSgoiObNm8dLmzVrFgmFQrpz5w4RES1dupQnQERECxYs4ASIiGjDhg0EgLeJb0BAAFlaWtI333xDRM+Fy9PTkwBwIqWp7YaGBjp+/Dg9fvxY5Wtten3qiJtMJqOuXbuSt7e30ny5uBE937wZALm6utLTp0+JSFHcVGnztvoakfb7U2vi1pSTJ09Sz549CQBlZGQo5MfExBAAtX4bNuamZeTjAjY2Nrh37x4yMzORk5ODtWvXYu3atTh58iRGjBiBmpoaAM/HVoDnr7Ry3NzccPfuXQDPN0qxsrLC5MmTcerUKQDAunXrAEAl+/qmpqYGhw4dUtg7c/HixaitrcXBgwcBKN9oRJXNRywtLSESibhxKjs7O2zevBkAkJmZ2S7bpqammDFjhl5mH+/du4e6ujr07du3zbKBgYFYs2YNrl+/jjlz5oCIePmqtnlbfc2Q/cnb2xuXL1+GSCTCtm3bFPJ79+4NALhy5YpO/WgvRjvmBgA3b94EALi4uKCgoAAAEBUV1eLmyspuOktLSzQ0NHDH27dvR0hICLy9vblBZhsbG5Xs65ucnBxIpVKFHbjkmx/funWr3XU0XzNNPk5z586ddtvWFw8ePAAAiEQilcpv2rQJv//+O9LT0xEdHY1XX32Vy1O1zdvqa4buT/b29vD19cXFixcV8uT+3Lx5ExMnTtS3aypjtE9u9fX1OHHiBLp06YKZM2dyM6t5eXkKZZ89e6ayXR8fHxQWFmLFihXIzc3FiBEjcOPGDa3Z1yby4NKcnBxeurxzDh48WOt1mpubw8LCAi+//LLWbesKJycnCAQCPH78WKXyJiYmSExMxNChQ7Fx40ZuiSVAe23eEfqTl5eX0skc+RtR86DmjobRitsXX3zBiZCLiwucnZ1hamqKmJgY1NfXc+XKy8uRmJioks3q6mrExcXB2toaW7duxY8//oiqqip8++23WrGvbYYNGwYLCwtkZ2fz0svLywH8316UIpFIIVyGiLgbtSnN0+rq6njHOTk5kEgkGDVqVLtt6wsrKysMGjQIDx8+VPkckUiE9PR0iMVinrip2uZtoYv+JH+Fbv4q3RL5+fl49913FdLLysoAoMPv7dppxU0qlXIdpikSiQQrV67Ehg0bsHbtWmzcuBEAIBaLER4ejosXL2L8+PFISkpCfHw8goODERgYCAB48uQJAKC2tpaz19DQAKlUColEAplMhpiYGO6G9vT0xCuvvAIbGxuV7Oub3r17Y9myZSgpKcEPP/zApaelpcHf3x/jx48HAAwYMAASiQSZmZkgIqSkpCAnJweVlZWorKxEY2MjF++Um5uLrKwsrg0qKytx+/Ztzvbp06cxYsQIbrd2TW3fv38fs2fPVhAJXTFs2LAWxa20tFTpOJeTkxNSU1N5IRaqtnlbfU2V/rRlyxYEBQVxYtMWcpFsHqMmk8mwatUqfPfdd5DJZACAH3/8EcXFxQgLC1OwU1ZWhh49emDIkCEq1Wsw9DV1oc3ZkvPnz5Ofnx8BoC5dutCwYcNo5syZ5OfnR2+//TaFh4dTbm6uwnnV1dU0d+5cAkAASCQScbNRaWlp5ODgQABo+fLlVFxcTMnJyeTo6EgAaNWqVVRUVERCoZDc3d3p66+/po8//pjmzZtH9fX1bdrXFlBztrSxsZEiIiLIxsaGVq9eTaGhoTR79myqra3ltYubmxsBIFtbW0pISKCFCxeSWCymyMhIevToERUXF5OtrS2JxWLat28fERHNnz+fLC0tacaMGbRjxw5auHAhjR07lkpKStpt++zZswSAYmJi1G4jTUJBkpKSyMLCgqqqqri0vLw8WrBgAQEgf39/yszMVHpubGwsb7a0rTZXpa89ePCgzf5kb29PAGjdunVtXl9OTg4tWbKEAJCTkxPt2LGDpFIp5+/48eMJAPXt25d8fX1p8+bN1NDQoNSWp6cnRUREtN2oTWChIHqivLyccnNzqaamRq3zZDIZVVdX09OnTyk3N5eePXumVfuqoK64yampqaG8vDyeqDVFJpPRtWvXqLq6moiex1g197++vp6XNn/+fOrbty9JJBK6fPkyFRcXa822vJwmn2Rp+vnV9OnTKT09Xe3ziJ7/5s1pq83Vsa2sP92/f5+ys7N54UjtoaysjO7evdtqmfz8fLKwsKCioiK1bBtC3Ix6trQlevXqpdEMlEAg4FYbGT58uNbt6xKhUKgQntAUgUAAd3d37lg+u9cUMzMzXvS8HHNzc3h4eGjdtrJyumTPnj0ICwuDj4+PSuEqTVH2e7fV5urYVmbf1tYW+/fvV/rqqAlNV0Fpibi4OOzcuRMDBw7USp26pNOOuTEMT01NTaf4xlBV7O3tsXTp0k6z8sWuXbvg5eXV6h8WbZKcnAyhUIj58+frpb72wsSNoTZSqRQ7d+7EuXPn8OzZM6xfv54LPu3szJw5E4GBgThy5IihXWmTRYsWtfoGoU2ysrIgFouxadMmvdSnDV7I11JG+zAzM8OSJUuwZMkSQ7uiExwdHTt8mAOg2pce2kLVEJaOBHtyYzAYRgkTNwaDYZQwcWMwGEYJEzcGg2GU6H1CITU1Vd9VGh0XLlwwtAtq09DQAIlEwi31o0vkM7esr3UcDNFnBUQqfkXbTlJTUxEQEKCPqhgMRgdFT3IDAIf0Jm6MFxv5HzfW3Rh64hAbc2MwGEYJEzcGg2GUMHFjMBhGCRM3BoNhlDBxYzAYRgkTNwaDYZQwcWMwGEYJEzcGg2GUMHFjMBhGCRM3BoNhlDBxYzAYRgkTNwaDYZQwcWMwGEYJEzcGg2GUMHFjMBhGCRM3BoNhlDBxYzAYRgkTNwaDYZQwcWMwGEYJEzcGg2GUMHFjMBhGCRM3BoNhlDBxYzAYRgkTNwaDYZQwcWMwGEYJEzcGg2GUMHFjMBhGCRM3BoNhlDBxYzAYRgkTNwaDYZQwcWMwGEZJF0M7wDA+pFIpqqqqeGnV1dUAgIqKCl66QCBAjx499OYb48WBiRtD6zx58gT9+vVDY2OjQp61tTXveMKECfj+++/15RrjBYK9ljK0jq2tLd58802YmLTevQQCAd577z09ecV40WDixtAJISEhbZYxNTWFn5+fHrxhvIgwcWPoBD8/P3Tp0vKoh6mpKaZNm4aePXvq0SvGiwQTN4ZOEIlE8PLyalHgiAhz5szRs1eMFwkmbgydMWfOHKWTCgBgbm6Od955R88eMV4kmLgxdMY777yDbt26KaSbmZlh5syZsLS0NIBXjBcFJm4MndG1a1e8++67MDMz46VLpVIEBwcbyCvGiwITN4ZOCQoKglQq5aWJRCJMmTLFQB4xXhSYuDF0yuTJk3mBu2ZmZggMDIS5ubkBvWK8CDBxY+iULl26IDAwkHs1lUqlCAoKMrBXjBcBJm4MnfPee+9xr6a2trYYO3asgT1ivAgwcWPonDFjxqBv374Ann+50NZnWQyGNmC9jKFzBAIB9zkW+5aUoS+YuDH0QmBgIIYMGYLXXnvN0K4wXhAUvo1JTU1FQECAIXxhvAAIBAJDu8AwQohIIa3FL5tTUlJ06gyjYxEQEIAVK1bA09PT0K50WLZu3QoAWLlypYE9Yci5cOECYmNjlea1KG6zZ8/WmUOMjkdAQAA8PT3Z794Khw4dAsDujY5GS+LGxtwYDIZRwsSNwWAYJUzcGAyGUcLEjcFgGCVM3BgMhlHS7q39GhoacPz4cezatQvvvPMOli9f3m6n7t27h7i4OBw4cAC//fYbrKys2m3TEOiibVoiIyMDUqkUPj4+OqujLSoqKjBmzBisXr0aoaGhBvOjo1JQUIC0tDTY2dlxaVOmTIGtrS2vnEQiwdGjR7lVjE1MTODl5aWwLWJHoq3+d+vWLVy6dIk7NjExQUBAAM6fP49u3bph9OjRWvep3U9ud+/eRVlZGf71r38prNulKSUlJcjJycGff/6pFXuGQhdt05yzZ89i2rRpmDZtGn799Ved1KEqXbp0Qc+ePdG9e3eD+SCRSAxWd2scPXoUX3/9NSIiIjB16lRkZWUhJCQEvr6+Cj5bWFhg+vTpyMzMxK5du/Dmm292WGFTtf8tXLgQISEh3L/ExESYmppiwoQJyM/Px5YtW7TuW7vFzcHBQetL2Lzxxht48803tWrTEOiibZozduxY7NmzR6d1qIqVlRWysrIMul3funXrIJPJDFa/Mq5du4atW7di27ZtMDU1Re/evbFnzx44Ozvj4sWLCA8PVzinR48emDp1KiZOnIj+/fsbwGvVUKX/nT9/Hu7u7rh8+TL3Lz4+nsufN28ebt68iYyMDK36ppUxt9a2cOtINg2Brq+ja9eu6Nevn07r6Cz89ttv2L17t6Hd4NHY2Ag/Pz+ly6pbWlrC09MT8fHxSgNRzc3NDfoUrAqq9L/Nmzfjww8/hIeHB/fPxsaGV+bTTz9FeHg4qqurteabVu68lr4XfAX/B5kAACAASURBVPr0KVJSUnDjxg0MHDgQYWFhvB+roKAA//u//4u//voLo0aNwvTp01u0+csvv6CwsBDA8/d1CwsL1NbWcmXlq01cv34d165dAwBMnTpVpX0xi4qKEB8fj48//hinTp1Cfn4+Vq5cCTMzszavQd22SUlJgUwmg5mZGWbNmgUAOHz4MKRSKYRCIXx9fVW2LcfU1FTtc3RBXV0dDh06BFtbW0ydOhUAUFhYiPj4eHzyyScoKipCamoqevfujbCwMG4By6KiInz33XdYsWIFfvrpJ5w6dQqDBw/mlkdSpc2ys7MRFBSE6upqJCcnw8zMDP7+/qiursaXX36JgIAAODs7671Njh8/jtLS0haf4I8ePYqRI0ciMjISbm5umDx5cqv2JBIJzp07h3PnzqFv377w8vLCoEGDuHxV2hto+95Uh9b6X3Z2Nk6fPo0hQ4Zg8uTJWLNmDUaOHKlQrn///rCyskJ0dDS+/PJLjfxQgJqRkpJCSpJbpbKykgDQF198waXdunWL3nnnHTpz5gxduXKF3NzcaNCgQVRRUUFERMuWLaNx48bRo0ePKCMjgwQCAW3ZsoU7//PPPycA9PTpUyIiKikpIbFYTAkJCVRVVUU3btwgOzs7AkAFBQXceY2NjTRp0iTavn07yWSyNn1PSEigPn36EACKj4+nYcOGEQDKzs5u8xo0aZunT5/SmDFjSCQScWXKysrI3d2d+vTpo7LdpshkMgJAGzZs0Oh8IiIAlJKSovH5N27cIF9fXwJAn332GRERxcfHk62tLQGg9PR0evfdd8nHx4cA0Pr164mIaNu2bdS9e3eys7OjxMREcnd3J6FQSADIz8+PiFRrs6ysLAoODiYAdOLECTpz5gwREWVkZBAAioqK0vja5MyaNYtmzZql1jkTJkwgDw8PpXnDhw8nIqJff/2VhEIhWVtbU2FhIZefmprKuydqa2vprbfeouTkZKqoqKBt27aRlZUVHTlyhIhUa2+itu9NdWmt/6Wnp9N7771Hrq6uJBAIqEuXLjydaEp4eDgNGDBArbpb0atUnYnblClT6NixY9zxqVOneI380ksv0caNG7l8FxcXev3117njpuJWVlZGXl5elJ+fz6s3MTGRAHAdmYiovr6eRowYQQ0NDSr7v27dOk7ciIj++OMPkslkbV6DKihrm6VLl/JuVCKiBQsWdGpxIyIqLS3liRsRUVRUFAGg48ePc2kTJkygwYMHc8cBAQFkaWlJ33zzDRE9Fy5PT0/eb6tKm23YsIEA8P6oNTQ00PHjx+nx48ftujYi9cVNJpNR165dydvbW2m+XNyIiJKSkggAubq6cn/Qm4tbUFAQzZs3T8EnoVBId+7cISLV2lsb/br5darS/06ePEk9e/YkAJSRkaGQHxMTQwDU+q1aEzedxLndu3cPmZmZyMnJwdq1a7F27VqcPHkSI0aMQE1NDQDg5MmTWLx4MQDg0qVLICLuNbMpBQUFCA0NxZ49ezB06FBeXkBAAJycnPCPf/yDSzt27Bh8fX3VelUTCoUAnq85BgDOzs64f/9+m9egKcpWojWG1WmVvdbI9yb19vbm0tzc3HD37l1eGZFIxI1L2dnZYfPmzQCAzMxMAJq3mampKWbMmGGQ2cZ79+6hrq6OW4W4NQIDA7FmzRpcv34dc+bMUVjCp6amBocOHcKwYcN46YsXL0ZtbS0OHjwIoO32VuXe1BXe3t64fPkyRCIRtm3bppDfu3dvAMCVK1e0Up9ORrsLCgoAAFFRUejVq5fSMmPGjMGxY8dw9OhRTJs2DQ4ODigtLVUo97e//Q2FhYVKxcrU1BSrV6/G+++/j0uXLmHUqFHYv38/EhIS1PJX2ZihKtfA4KOqAFlaWqKhoYGX1vw3kI/L3LlzR4se6pcHDx4AeL6VoSps2rQJv//+O9LT0xEdHY1XX32Vy8vJyYFUKlWYoHrllVcAPI8jA9pub0P3a3t7e/j6+uLixYsKeXJ/bt68iYkTJ7a7Lp08Lsi3bcvLy1PIe/bsGYDnjXvgwAHExcVhzpw5sLCwUGpr165daGhogJ+fH+rr6xXy586di379+mHTpk24efMmevTogT59+ujlGhi6w9zcHBYWFnj55ZcN7YrGODk5QSAQ4PHjxyqVNzExQWJiIoYOHYqNGzdySywB4AJ6c3JyeOfIBWHw4MEq1dER+rWXl5fSyR35TGnzoGZN0Ym4OTs7w9TUFDExMTxBKi8vR2JiInJzc/HFF1/ggw8+QNeuXbn85o/iwPNYsaSkJPzyyy9YtmyZQr65uTkiIyO52TZlMUO6uIb2IBKJFAI3iYjrwOoibzdl7ddZqKur4x3n5ORAIpFg1KhRANRrM03bUdtYWVlh0KBBePjwocrniEQipKenQywW88Rt2LBhsLCwQHZ2Nq98eXk5AGDcuHEq2ddFv1a3/+Xn5+Pdd99VSC8rKwMAODo6auRHc7QiblVVVQD+T3nFYjHCw8Nx8eJFjB8/HklJSYiPj0dwcDACAwPRrVs3AEBaWhoaGhpw9uxZXL16FRUVFSgoKEBJSQnP5tSpUxEdHY29e/di+/btCvW///776NmzJ0pKSjBhwgS1/Zd/PdD0L2xb16Bp2wDAgAEDIJFIkJmZCSJCSkoKcnJyUFlZicrKSrVvTnkn1WaMkCYou9YnT54AAG88taGhAVKplCdWlZWVuH37Nnd8+vRpjBgxggsIVqXN5LFTubm5yMrKQl1dHe7fv4/Zs2criIK+GDZsWIviVlpaqnScy8nJCampqbyhmN69e2PZsmUoKSnBDz/8wKWnpaXB398f48ePB9B2e6vSr7ds2YKgoCBObNqipf4nk8mwatUqfPfdd1xg9Y8//oji4mKEhYUp2CkrK0OPHj0wZMgQleptEzVmH5RSVlZGixcvJgDk4uJCaWlpRERUXV1Nc+fOJQAEgEQiEW+GJiQkhExMTMjW1pZ2795NGzduJBMTE4qMjKTU1FRycXEhAPTBBx9QQUEBnTx5kgCQiYkJLV++nG7cuMHzIyoqir766iuV/ZZz+PBhcnZ2JgDk7+9PV69e5fLauob2tI2bmxsBIFtbW0pISKCFCxeSWCymyMhIevTokcp15OTk0JIlSwgAOTk50Y4dO0gqlareAP8ftHO29Pbt27xrPXXqFKWlpZGDgwMBoOXLl1NxcTElJyeTo6MjAaBVq1bRgwcPaP78+WRpaUkzZsygHTt20MKFC2ns2LFUUlLC2VelzYqLi8nW1pbEYjHt27ePiIjOnj1LACgmJkbja5OjSShIUlISWVhYUFVVFZeWl5dHCxYs4PpcZmam0nNjY2N5s6WNjY0UERFBNjY2tHr1agoNDaXZs2dTbW0tEZHK7d1Wv7a3tycAtG7dujavr7X+19jYSOPHjycA1LdvX/L19aXNmze3GMng6elJERERbTdqE3QeCtIa5eXllJubSzU1NQp5Dx8+pPr6eu74yZMnGtfj7e3drvNbo7Vr0BSZTEbXrl2j6upqInoee6RN++rSXnFrD/Pnz6e+ffuSRCKhy5cvU3FxsdJyqrRZfX29QtqtW7eosbGx3X5qIm5ERNOnT6f09HSN6iwvL1dIq6mpoby8PE7UNKWlfn3//n3Kzs6m5cuXt8u+nLKyMrp7926rZfLz88nCwoKKiorUst2auOn8G6devXq1OCvT/BMMsVisUR05OTmwt7fX+Py2aO0aNEUgEMDd3Z07ls96vciYm5vDw8OjxXxV2szMzIwXid9SOX2yZ88ehIWFwcfHR+2QH2X9TigUKoSEaEJL/drW1hb79+9X+uqoCU1XQWmJuLg47Ny5EwMHDtRKnYCOQkH0waVLlxAREQFXV1fk5+fjxIkThnaJoSE1NTUGHy/UJfb29li6dCm2bNmCDz/80NDutMmuXbvg5eXV6h8abZKcnAyhUIj58+dr1W6nFTfgecyOUChEbGwsXnrpJV7enTt3MG/evDZthIaGcruhq0pntd3RkEqliIuLw7lz5/Ds2TOsX78eixYt6tCrYGjKzJkz4eHhgSNHjhh01RRVWLRokd6CyrOysiAWi7Fp0yat2+604jZq1CguSFIZ/fv3x8mTJ9u0o8mqHZ3VdkfDzMwMS5YswZIlSwztil5wdHTUWpiDLtHn1zKqhrBoQue/Q1pAIBC0GBj8otpmMF4kOv8HjQwGg6EEJm4MBsMoYeLGYDCMkhbH3FJTU/XpB6MDcOHCBUO70KGRLxvE7o2OQ2t9VkDE/9o1NTUVAQEBOneKwWAwtAUpfrR/qMUnNyWFGUaMQCBASkoKZs+ebWhXOiz+/v4AwFutg2FYWnsYY2NuDAbDKGHixmAwjBImbgwGwyhh4sZgMIwSJm4MBsMoYeLGYDCMEp1+OH/p0iVuyzGuwi5d8N5772m9rnv37iEuLg4HDhzAb7/9BisrK43sZGdno6SkhDuWf8guEong5uam0h6UTVGnDY4fP87bgUggEGDkyJHczkZ1dXU4duwYt8eCiYkJJk6cqJXdvhi6p6CgAGlpabzFG6dMmaKw25NEIsHRo0d5v7OXl5dB9l5VlYyMDEilUvj4+CjNv3XrFi5dusQdm5iYICAgAOfPn0e3bt0wevRo7TulxrK9GnH+/HkyMzPjdsGWLxGtbbKzs2natGncLvWaIpPJ6PTp0yQQCKhXr1709ddf09atW+m1114jExMTWrlypdrLgavaBhKJhKKjowkA9enTh65cuaJQ5q+//qK5c+fS0KFDKT8/X6NrVAYMuMx4XV1dp7Ct6TLjRP+PvXuPaurK+8f/DldTJCPeuBTqjXoDXGi9lGrHYtUHsfVBEVFQRMah6ODYOopaK9SqgzOdjj6l3oq2+Iwo4KVI9VHBTqsUytcWsLbFUW4zKnhBpaABQiCf3x+unB8hAZIQEoif11quZc7Z2WdnZ/PJOWfvszfRiRMnKDo6mpqamujevXsUGRlJAOjll1/WWMbq6moKCwujV155RVhNvjvKysqimTNnEgB6//3320ynXEtB+c/f31/Y99lnn1F8fLxexzfpGgpERIMHD6Z+/foZNE9Ntm/f3ungptS3b18aNWqUyraQkBACQFu2bNE5P23r4OrVqwSA3njjjTbTpKSk0Ntvv61zGdpjyuD2pz/9ySBrHHR13voGtx9//JGmTJmitl25MFF4eLjG9x0+fJjee+89nY9nTPX19VReXt5ucLt48SJFR0dTYWGh8O/+/fsqacLDw+n8+fM6H7+94GaUe242NjbCYrBdyZATOGoq7+9+9zsAT6dF1ic/beqgX79+ANpfpdzGxkZt5uGe6qeffsK+fft6XN7aam5uRmBgIEJDQ9X22dnZwcfHB0lJSdi1a5fafhsbG/Tu3dsYxdRbr1698Pzzz7ebJj4+Hu+++y68vb2Ff63XT9m6dSuioqIMOt18t5ussra2Fqmpqbh27RqGDh2K8PBwlS+4uLgY//d//4dff/0VEydOxKxZs4R9IpFIJa/vv/8eJSUlAJ5e49va2grrOYpEIuG+1y+//IKrV68CAGbOnCkEmNaUAUfTbKodldscyWQyXLx4ERcvXoSLiwv8/PwwbNgwAEBqaioUCgWsra0xf/58AMDx48chl8shFosREBCAnJwchISEQCqVIiUlBdbW1ggKCkJpaamwyPa3336Ls2fPYvjw4ViyZAksLCw6lbdUKsVHH32E4OBgjaueG9qpU6dQUVGBkJAQjftPnjyJCRMmYO3atfD09MT06dPbza+9OgeAkpISJCUl4YMPPkBpaSnS0tIwcOBAhIeHqyycY8j22nJ91dZycnJw7tw5jBw5EtOnT8eGDRswYcIEtXSurq6wt7dHbGwsPvroI73KoUaH0zy9DR8+nJydnTtMd+PGDXrzzTfp/PnzdOXKFfL09KRhw4ZRdXU1ERGtWrWKXn31VXrw4AFlZmaSSCRSWdfxr3/9q8plaXl5OTk4ONChQ4foyZMndO3aNXJ2diYAVFxcLLyvubmZXn/9dfrkk09IoVAQEZGTk5PKZWlzczPNnTuXAKitXdpRuXWpg4qKCgJAISEhbaY5efKkQdbhbAk6XpbW19fTa6+9RikpKVRdXU0JCQlkb29PJ06cICKi2tpamjx5MkkkEuE9lZWV5OXlRU5OTkRElJ2dTaGhoQSATp8+TefPn6eEhATq3bs3OTs7U3JyMnl5eZFYLCYAFBgY2Km8iYgyMzMJAMXExOhcR/pclvr6+pK3t7fGfePGjSMioh9++IHEYjH17duXSkpKhP1paWkq7bujOk9KSiJHR0cCQBkZGTRv3jyaPXs2AaDNmzcL+WjTXnWhUCjavF2TkZFBCxcuJA8PDxKJRGRlZUUffvihxnyioqJo0KBBOh3b5PfctP3DnjFjhkrgOHv2rMoX85vf/Ia2bdsm7B89ejS9/PLLwuuWwa2yspL8/PzUbronJycTAJXr+8bGRho/frzKYrFOTk70/PPPU1JSEm3dupVGjx5NkyZNomPHjulcbl3qoKcEt5CQEFq2bJnKtvnz55NYLBZugEdHR6sEICKi5cuXCwGIiGjLli0EQPhRISIKDg4mOzs7Onz4MBE9DVw+Pj4q35u+eTc1NdGpU6fo4cOHWn/Wlp9Pl+CmUCioV69eKjfPW1IGN6KnizcDIA8PD+HHuXVw06bOY2JihI4rJV9fXxo+fLjwWpv2qov2gltLZ86coX79+hEAyszMVNsfFxdHAHT6bkx+z00bd+7cQVZWFnJzc7Fx40Zs3LgRZ86cwfjx41FXVwcAOHPmDFasWAHg6RALIhIuM1sqLi7G0qVLsX//fowaNUplX3BwMNzd3fG3v/1N2PbFF18gICBA7fTa2toa7u7uKCwsRFFREWJjY4XLIF3KbW7q6upw7NgxtbUzV6xYgfr6enz++ecANC80os3iI3Z2dpBIJMJ9KmdnZ8THxwMAsrKyOpW3paUl5syZY5RhFXfu3EFDQ4NWw4cWLVqEDRs24JdffsHixYvVZuXRts7t7OwAAP7+/kIaT09PYS46U7ZXf39/FBYWQiKRICEhQW3/wIEDAQBXrlwxyPG6zT234uJiAEBMTEybCyBPnjwZX3zxBU6ePIn/+q//wuDBg1FRUaGW7o9//CNKSko03guwtLTE+vXr8fvf/x6XL1/GxIkTcfDgQRw6dEgtrVgsxuTJk+Hh4YH8/HyEh4fj6tWrKuPKtCm3Lnr16gUAaGxsbDNNfX29kM4UcnNzIZfL1TpwlIsftx7Xp4/W90+V92lu3brV6byNRbk6W3udQy1t374dP//8MzIyMhAbG4sxY8YI+7Stc00B3s7ODk1NTQAM31515ebmhoCAAOTl5antU5bn+vXrmDZtWqeP1S3O3IqLi4WexIKCArX9yoGtMTEx+Oyzz5CYmIjFixe3uUrU3r170dTUhMDAQI1BIiwsDM8//zy2b9+O69evo0+fPu0OhO3Tpw+Sk5Px6NEjLF26VOVXVZtya0PZ6Hr37g0LCwtUVVW1mfbhw4dtdnoYg3JwaW5ursp2ZeNUDjo2JBsbG9ja2uKFF14weN5dxd3dHSKRCA8fPtQqvYWFBZKTkzFq1Chs27ZNZd44Q9W5odprZ/j5+WnszFH2lLYe1KwvowW31qfZSgqFAomJiRgxYgQsLS0RFxenEpCqqqqQnJyM/Px8fPjhh/jDH/6gctaiKd/BgwfjyJEj+P7777Fq1Sq1/TY2Nli7dq3QIxcVFdVh+SdPnozY2FhkZmaqXNJ2VG5d6kBZNuWZoqZLbgD46quvNPY4GcvYsWNha2uLnJwcle3KgKxci1IikUAmk6mkISLhD7Wl1tsaGhpUXufm5kImk2HixImdzttY7O3tMWzYMNy/f1/r90gkEmRkZMDBwUEluGlb5x3Rpb1qS9mu22rfrRUVFWHevHlq2ysrKwFoHo2gD6MEtzt37uDBgwdqjVEmk+GPf/wjBg8eDAcHB0RFRSEvLw9Tp07FkSNHkJSUhNDQUCxatAjPPfccACA9PR1NTU24cOECfvzxR1RXV6O4uBjl5eV48uQJgKe/ADNnzkRsbCw+/fRTfPLJJ2pl+v3vf49+/fqhvLwcvr6+Kvuamprw4MED1NbWqmzftGkTXn31VeE+BYAOy61LHSgdOHAAcrkcf/7zn9XKvXnzZgwdOhTe3t4dVXuXGThwIFatWoXy8nJ8/fXXwvb09HQEBQVh6tSpAIBBgwZBJpMhKysLRITU1FTk5uaipqYGNTU1aG5uFsY75efnIzs7WwhqNTU1uHnzppD3uXPnMH78eGG1dn3zvnv3LhYsWKAWJLrK2LFj2wxuFRUVGu9zubu7Iy0tTeW2irZ1/ujRIwBQ+WFsamqCXC6HTCbTqr3u2LEDISEhQrDpiDJIth6jplAosG7dOnz55ZdQKBQAgG+++QZlZWUIDw9Xy6eyshJ9+vTByJEjtTpuh3TofdBZXl6e0B0PgFxdXWnChAk0ceJEGjNmDNnb25NIJKLbt28TEZFUKqWwsDAhvUQiUenVWbJkCVlYWJCjoyPt27ePtm3bRhYWFrR27VpKS0uj0aNHEwD6wx/+QMXFxXTmzBkCQBYWFrR69Wq6du2aSvliYmLo73//u8q2S5cuUWBgoFCGqKgounz5srD/5s2b5ODgQFZWVhQQEEBZWVntllvXOlA6cuQIOTk50UsvvUSrVq2ikJAQ8vX1pXfeeUelV9dQoGNvaXNzM61Zs4YGDBhA69evp6VLl9KCBQuovr5eSCOVSsnT05MAkKOjIx06dIgiIyPJwcGB1q5dSw8ePKCysjJydHQkBwcHOnDgABERRUREkJ2dHc2ZM4d2795NkZGRNGXKFCovL+903hcuXCAAevU26zMU5MiRI2Rra0tPnjwRthUUFNDy5csJAAUFBVFWVpbG9+7atUult7SjOk9PT6fBgwcTAFq9ejWVlZVRSkoKDRkyhADQunXr6N69ex3+nbm5uREA2rRpU4efLzc3l1auXEkAyN3dnXbv3k1yuVwor/KxKxcXFwoICKD4+Pg226+Pjw+tWbOm40ptweRDQXRVVVVF+fn5Gp/hvH//PjU2NgqvHz16pPdx/P39O/X+1tortz4aGxvp559/pn/+859UUVFhkDzbomtwU6qrq6OCggKVoNaSQqGgq1evCs/T3rhxQ61+GhsbVbZFRESQi4sLyWQyKiwspLKyMoPlrUynzyNZ+j5+NWvWLMrIyND5fURP21RrHdW5Lnlraq93796lnJwcWr16dafyV6qsrFT78W6tqKiIbG1tqbS0VKe82wtu3aa3tKX+/fu32ZPT+rENBwcHvY6Rm5sLNzc3vd+vSXvl1oe1tTU8PDzg4eFhsDwNTSwWqw1PaEkkEsHLy0t4rezda8na2lpl9LySjY1Nu5ff+uatKV1X2r9/P8LDwzF79mythqu0pKk9dVTnuuStKX9HR0ccPHhQ46WjPlrOgtKWxMRE7NmzB0OHDjXIMYFuNBTEGC5fvow1a9bAw8MDRUVFOH36tKmLxDSoq6sz6DOGpubm5obo6Gjs2LED7777rqmL06G9e/fCz8/PaPd1U1JSIBaLERERYdB8u8VQEGMqLi5GWVkZdu3aZTYPn5sLuVyOPXv24OLFi3j8+DE2b94sDD7t6ebOnYtFixbhxIkTpi5Kh9566y2MGzfOKMfKzs6Gg4MDtm/fbvC8n6kzt4kTJwoDK1n3Y21tjZUrV2LlypWmLkqXGDJkiMGGOXQlXS+dO0PbISz6eObO3BhjzwYObowxs8TBjTFmlji4McbMUpsdCkFBQcYsB+sGdu7cqfI8oyFJpVLcu3fPoOOYjE05kwX/bXQf7fWmi4hUn3b97rvv8Pe//73LC8WeLbdv30ZeXp7afHiMGYKGH+VjasGNsa6QlpaG4OBgrWeOYKyTjvE9N8aYWeLgxhgzSxzcGGNmiYMbY8wscXBjjJklDm6MMbPEwY0xZpY4uDHGzBIHN8aYWeLgxhgzSxzcGGNmiYMbY8wscXBjjJklDm6MMbPEwY0xZpY4uDHGzBIHN8aYWeLgxhgzSxzcGGNmiYMbY8wscXBjjJklDm6MMbPEwY0xZpY4uDHGzBIHN8aYWeLgxhgzSxzcGGNmiYMbY8wscXBjjJklDm6MMbPEwY0xZpasTF0AZn6qqqrwxRdfqGz74YcfAACffvqpynZ7e3ssWrTIaGVjzw4REZGpC8HMi0wmw4ABAyCVSmFpaQkAICIoFArhNQDI5XKEhYXh0KFDpioqM1/H+LKUGZytrS2CgoJgZWUFuVwOuVyOpqYmKBQK4bVcLgcAhISEmLi0zFxxcGNdIiQkBI2Nje2m6dOnD15//XUjlYg9azi4sS7h6+uLAQMGtLnf2toaixcvhpUV3/ZlXYODG+sSFhYWCAkJgY2Njcb9crmcOxJYl+LgxrrMokWL2rw0dXZ2ho+Pj5FLxJ4lHNxYl5k0aRIGDRqktt3Gxgbh4eEQiUQmKBV7VnBwY11qyZIlsLa2VtnW2NjIl6Ssy3FwY10qNDRUGPah5O7uDi8vLxOViD0rOLixLjVy5EiMHj1auAS1trbGsmXLTFwq9izg4Ma6XFhYmPBkglwux4IFC0xcIvYs4ODGutzChQvR3NwMAHjppZfg7u5u4hKxZwEHN9blBg0ahIkTJwIAli5dauLSsGcFBzdmFMpL06CgIFMXhT0jjPbsy+3bt5Gbm2usw7FuxsbGBmPGjMGlS5dMXRRmQsa832q0KY/S0tIQHBxsjEMxxropI86wdszoTy3z9HGdIxKJkJqayj2O7VBe+h47dszEJWFKpji54XtujDGzxMGNMWaWOLgxxswSBzfGmFni4MYYM0sc3BhjZqlHTWD/n//8B59++imSk5Px73//29TF0cl//vMfJCcn4/79+/D29kZoaKjaPGfGUl1djcmTJ2P9+vX8OJQGxcXFBN2v4QAAIABJREFUSE9Ph7Ozs7BtxowZcHR0VEknk8lw8uRJ4blZCwsL+Pn5oW/fvkYtry4yMzMhl8sxe/Zsjftv3LiBy5cvC68tLCwQHByMS5cu4bnnnsOkSZOMVdTOIyNJTU2lzh7un//8J73yyitkaWlpoFIZxy+//EJ2dnbk6upK1tbWBIDGjRtHjx8/1jkvAJSamtqp8tTW1tKUKVPo+PHjncqnMxoaGros7/nz59P8+fP1eu+JEycoOjqampqa6N69exQZGUkA6OWXX9ZY5urqagoLC6NXXnmFbt261dmid5msrCyaOXMmAaD333+/zXRTp04lAMI/f39/Yd9nn31G8fHxeh3fEH//OkrrUZelvr6+mDx5sqmLobODBw/iwoULuHXrFsrLyxEcHIyCggJs377dJOWxt7dHdnY2AgMDTXJ8ANi0aRMUCoXJjq/J1atXsXPnTiQkJMDS0hIDBw7E/v37MWLECOTl5SEqKkrtPX369MHMmTMxbdo0uLq6mqDU2pkyZQr279/fbppLly7By8sLhYWFwr+kpCRh/7Jly3D9+nVkZmZ2cWkNo0cFNwAmu5TT16+//oopU6bg5ZdfBgA8//zz+Mtf/gKRSIT/9//+n4lLZxo//fQT9u3bZ+piqGhubkZgYCBCQ0PV9tnZ2cHHxwdJSUnYtWuX2n4bGxv07t3bGMXUW69evfD888+3myY+Ph7vvvsuvL29hX+tl2fcunUroqKiIJVKu7K4BtHtg5tcLkdaWho2btyI8+fPa/y1r62tRWJiItasWYNPPvkET548EfaVlJTgvffeg0KhQHFxMbZv347ExES1qa+//fZbbNq0Cfv27cOnn36qdf4d6dOnD+bOnauybdCgQfDw8MCLL76odT6G1NDQgH/84x8qv8Da1FNpaanwx62sr0OHDgnfSWpqKo4ePYrjx48L7zl+/DiOHj2K9PR0AEBOTg7eeOMNSKVSpKSkCI9ISaVSfPDBB7h+/XqXf35NTp06hYqKCoSEhGjcf/LkSbi6umLt2rW4cOFCh/nJZDJkZmZi06ZN2L17N0pLS1X2a9suO9P2WlNOGKpJTk4Ozp07h5EjRyIwMBDff/+9xnSurq6wt7dHbGys3uUwGmNdAOtzzf3rr7/S66+/Tu+//z49fPiQDh06RDY2Nir33G7cuEFvvvkmnT9/nq5cuUKenp40bNgwqq6upqSkJHJ0dCQAlJGRQfPmzaPZs2cTANq8ebOQR0xMDCUnJ5NUKqWjR49S7969tcpfX83NzWRnZ0cnTpzQ+b3o5D23a9euUUBAAAGgv/zlL0REWtVTQkIC9e7dm5ydnSk5OZm8vLxILBYTAAoMDCSip/fyJk+eTBKJRDheZWUleXl5kZOTExERZWdnU2hoKAGg06dP0/nz54mIKDMzkwBQTEyM3p9NSZ97br6+vuTt7a1x37hx44iI6IcffiCxWEx9+/alkpISYX9aWhrt2LFDeF1fX0+vvfYapaSkUHV1NSUkJJC9vb3wfWvbLg3d9hQKBQGgLVu2qO3LyMighQsXkoeHB4lEIrKysqIPP/xQYz5RUVE0aNAgnY5tintu3Tq4rVy5kgICAlS2vfHGGyrBbcaMGfTFF18Ir8+ePavSSGJiYggAnTp1Skjj6+tLw4cPJyKixsZG6tevH12/fl3Yv3r1aq3z18cXX3xBkyZNIoVCofN7OxvciIgqKipUghtRx/VERBQcHEx2dnZ0+PBhInoauHx8fAiAEKSio6NVghsR0fLly4XgRkS0ZcsWAqDy+ZuamujUqVP08OHDTn02It2Dm0KhoF69eqncPG9JGdyIiI4cOUIAyMPDg2pra4lIPbiFhITQsmXL1MokFouFTgdt6tvQba+94NbSmTNnqF+/fgSAMjMz1fbHxcURAJ2+K+5QaOH+/ftITEzEzJkzVbaPGTNG+P+dO3eQlZWF3NxcbNy4ERs3bsSZM2cwfvx41NXVAXh6vwQA/P39hfd5enri9u3bAJ7ew7O3t8f06dNx9uxZAE9vdmubv67kcjni4+Nx6NAhk63bqen+UEf1pEwjkUiE+1LOzs6Ij48HAGRlZQF4OnSgNU3bWrO0tMScOXNMMozizp07aGhogIuLS4dpFy1ahA0bNuCXX37B4sWL1Wa5qaurw7FjxzB27FiV7StWrEB9fT0+//xzAB3Xd1e0PW35+/ujsLAQEokECQkJavsHDhwIALhy5UqXlqOzuu04tx9//BFyuRxOTk4q21sGhOLiYgBATEwM+vfvrzEfTX9YdnZ2aGpqEl5/8sknWLJkCfz9/YUbxwMGDNAqf129/fbbiIuLw4gRIwySnz60DUCt6wmAWkCeMGECAODWrVsGLKFx3bt3DwAgkUi0Sr99+3b8/PPPyMjIQGxsrMoPbm5uLuRyOaysVP+0lPdXb9y4AaDj+u6KtqcLNzc3BAQEIC8vT22fsjzXr1/HtGnTjF00rXXbM7fHjx8DePoL1hYbGxsAQEFBQZvv18bs2bNRUlKCt99+G/n5+Rg/fjyuXbtmsPyV/ud//gcTJkxQ+bXu6WxsbGBra4sXXnjB1EXRm7u7O0QiER4+fKhVegsLCyQnJ2PUqFHYtm2byrxxygG9rWedVgaE4cOHa3UMQ7c9ffj5+Wn8EVb2lLYe1NzddNvgNnLkSAAQLhVbUvbOjRgxApaWloiLi0NjY6Owv6qqCsnJyVodRyqVIjExEX379sXOnTvxzTff4MmTJzh69KhB8lf67LPPIBKJEB4eLmwjIvzrX//SKR9Ta2hoUHmdm5sLmUwmLAAjkUggk8lU0hCR8EffkqZtpmBvb49hw4bh/v37Wr9HIpEgIyMDDg4OKsFt7NixsLW1RU5Ojkr6qqoqAMCrr76qVf6GbHtKykvo1pfSbSkqKsK8efPUtldWVgIAhgwZolc5jKXbBrfRo0fDz88Pp0+fFgYSNjY24sqVKyAi3Lp1C/b29oiKikJeXh6mTp2KI0eOICkpCaGhoVi0aBEA4NGjRwCA+vp6Ie+mpibI5XLIZDIoFArExcUJf7Q+Pj548cUXMWDAADg4OHSYvzb27duHAwcOQCKRICkpCZ9//jkSEhLwxhtvCI3emJTDCVqOVeqonpRqampw8+ZN4fW5c+cwfvx4YUDwoEGDIJPJkJWVBSJCamoqcnNzUVNTg5qaGjQ3Nwtjp/Lz85GdnY2GhgbcvXsXCxYsUAsKxjJ27Ng2g1tFRYXG+1zu7u5IS0tTGWIxcOBArFq1CuXl5fj666+F7enp6QgKCsLUqVMBdFzf2rS9HTt2ICQkRAg2HVEGydZj1BQKBdatW4cvv/xSOHH45ptvUFZWpvJjrFRZWYk+ffoIJyDdlrG6LvTpLbl79y69+uqrBICGDx9Oc+bMocWLF1Pv3r0pOjqabt++TVKplMLCwoTHRSQSidDDlJ6eToMHDyYAtHr1aiorK6OUlBQaMmQIAaB169ZRSUkJicVi8vLyoo8//pjef/99WrZsGTU2NhIRtZu/Nj7//HOVx1la/hsyZIjOPaboZG/pzZs3acWKFQSARo8eTWfPntWqnu7du0cRERFkZ2dHc+bMod27d1NkZCRNmTKFysvLhfylUil5enoSAHJ0dKRDhw5RZGQkOTg40Nq1a+nBgwdUVlZGjo6O5ODgQAcOHCAiogsXLhAAiouL0/uzKekzFOTIkSNka2tLT548EbYVFBTQ8uXLCQAFBQVRVlaWxvfu2rVLpbe0ubmZ1qxZQwMGDKD169fT0qVLacGCBVRfX09E2rXLe/fuddj23NzcCABt2rSpw8+Xm5tLK1euJADk7u5Ou3fvJrlcLpRX+diVi4sLBQQEUHx8PDU1NWnMy8fHh9asWdNxpbbAQ0HaUFJSQtevXyeFQkFlZWVUU1Ojlqaqqory8/Oprq5Op7wVCgVJpVKqra2l/Pz8Np/31Dd/Q+tscOuMiIgIcnFxIZlMRoWFhVRWVqYxnUKhoKtXr5JUKiWip+O1WtdbY2Oj2rYbN25Qc3Nzp8up77Ols2bNooyMDL2OWVVVpbatrq6OCgoKhKCmr7ba3t27dyknJ0dl6FJnVFZW0u3bt9tNU1RURLa2tlRaWqpT3qYIbt22t7SlYcOGCf9v6zq/f//+evUqiUQiPPfccwCAcePGtZlO3/zNkY2NDby9vdvcLxKJ4OXlJbzW9CSGtbW12qN0pnpiQ2n//v0IDw/H7NmztRq+0pKmtiEWi9WGhOijrbbn6OiIgwcParx01EfLWVDakpiYiD179mDo0KEGOWZX6rb33Fj3U1dX1yOeKdSXm5sboqOjsWPHDlMXRSt79+6Fn59fuz80hpSSkgKxWIyIiAijHK+zesSZW3d069YtLFu2rMN0S5cuxZIlS4xQoq4jl8uRmJiIixcv4vHjx9i8eTPeeuutbj0Lhr7mzp0Lb29vnDhxwqSzpmjjrbfe0vkMU1/Z2dlwcHAw2Uw2+uDgpidXV1ecOXOmw3StB3P2RNbW1li5ciVWrlxp6qIYxZAhQ7r9MAdAuyc/DEXbISzdSc//yzMRkUgEW1tbUxeDMdYGvufGGDNLHNwYY2aJgxtjzCwZ/Z5bUFCQsQ9pdnbu3KnyPCNTpZzJgtta99Fy6ixj4TM3xphZMvqZG59xdI5IJMI777yDBQsWmLoo3ZbyjI3bWveRlpaG4OBgox6Tz9wYY2aJgxtjzCxxcGOMmSUObowxs8TBjTFmlnrks6U5OTkoLy9X2WZlZYXf/OY36Nu3L7y8vIQ52hjrrOLiYqSnp6vMdzZjxgy1BVJkMhlOnjwprA1hYWEBPz8/kyxXqI0bN27g8uXLwmsLCwsEBwfj0qVLeO655zBp0iQTlq7zeuSZ2yuvvIIBAwYgLCwMq1atQnFxMRoaGlBYWIgdO3agX79+8Pf373GLr3R3rRd+6Sl5d8bJkyfx8ccfY82aNZg5cyays7OxZMkSBAQEqJXZ1tYWs2bNQlZWFvbu3Yvf/va33TawAUBkZCSWLFki/EtOToalpSV8fX1RVFTUY+a1a5Ox5vztimmG+/btSyNGjFDbfuHCBXJycqJevXpRXl6eQY9pajDhNON/+tOfDDINeFfnre804639+OOPNGXKFLXtI0aMIAAUHh6u8X2HDx+m9957r9PH70oXL16k6OhoKiwsFP7dv39fJU14eDidP3/eIMfjFed1pFzbsbXXX38dBw8eRENDAwIDA7vtWUFP8tNPP2Hfvn09Lm99NTc3IzAwEKGhoWr77OzshMW7d+3apbbfxsYGvXv3NkYx9RYfH493330X3t7ewj/lqmRKW7duRVRUVI+dfblH3nPThr+/P15//XV89dVXOHbsGBYvXgwAqK2tRWpqKq5du4ahQ4ciPDxcaIglJSVISkrCBx98gNLSUqSlpWHgwIEIDw9Xme//22+/xdmzZ+Hm5gYLCwtERkYK+9rL31RkMhkuXryIixcvwsXFBX5+fsK6FKmpqVAoFLC2tsb8+fMBAMePH4dcLodYLEZAQABycnIQEhICqVSKlJQUWFtbIygoCKWlpfjyyy/x9ttvC3UyfPhwLFmyBBYWFp3KWyqV4qOPPkJwcLDGhYG72qlTp1BRUYGQkBCN+0+ePIkJEyZg7dq18PT0xPTp09vNr73vANC+7RmifeXk5ODcuXMYOXIkpk+fjg0bNmDChAlq6VxdXWFvb4/Y2Fh89NFHOh2jWzDWOWJXnJY6OTlpvCxVeu+99wgARUREENHT1ZXefPNNOn/+PF25coU8PT1p2LBhVF1dTUlJSeTo6EgAKCMjg+bNm0ezZ88mALR582Yhz5iYGEpOTiapVEpHjx6l3r17C/vay99QoONlaX19Pb322muUkpJC1dXVlJCQQPb29nTixAkiIqqtraXJkyeTRCIR3lNZWUleXl7k5ORERETZ2dkUGhpKAOj06dN0/vx5SkhIoN69e5OzszMlJyeTl5cXicViAkCBgYGdypuIKDMzkwBQTEyMznVkiMtSX19f8vb21rhv3LhxRET0ww8/kFgspr59+1JJSYmwPy0tTWWpv46+A23bnqHaV0ZGBi1cuJA8PDxIJBKRlZUVffjhhxrTRkVF0aBBg3TKXxNe2k9HHQW3//3f/yUANGPGDCIimjFjhsq6j2fPnlVpQDExMQSATp06JaTx9fWl4cOHE9HT5ej69etH169fF/a3XFato/wNQdfgFhISQsuWLVPZNn/+fBKLxXTr1i0iIoqOjlYJQEREy5cvFwIQEdGWLVsIgMo6q8HBwWRnZ0eHDx8moqeBy8fHhwAIQUrfvJuamujUqVP08OFDrT9ry8/XmeCmUCioV69e5O/vr3G/MrgRPV3vFAB5eHhQbW0tEakHN22+g47aHlHXtK8zZ85Qv379CABlZmaq7Y+LiyMAen0PLfE9NwNT3isYMGAA7ty5g6ysLOTm5mLjxo3YuHEjzpw5g/HjxwuridvZ2QF4ekmr5OnpKUzXYm1tDXt7e0yfPh1nz54FAGzatAkAtMrf2Orq6nDs2DG15eVWrFiB+vp6fP755wA0z8Wvzfz8dnZ2kEgkwn0pZ2dnxMfHAwCysrI6lbelpSXmzJljkt7GO3fuoKGhAS4uLh2mXbRoETZs2IBffvkFixcvBhGp7Nf2O+io7XVV+/L390dhYSEkEgkSEhLU9g8cOBAAcOXKFb2PYSpme88NAK5fvw4AGD16NIqLiwEAMTExba4/qumPzs7ODk1NTcLrTz75BEuWLIG/v79wU3nAgAFa5W9subm5kMvlaovUKNcHvXHjRqePIRKJVF4r793cunWr03mbyr179wAAEolEq/Tbt2/Hzz//jIyMDMTGxmLMmDHCPm2/g47aXle2Lzc3NwQEBAjz4LWkPNb169cxbdo0gx63q5ntmVtjYyNOnz4NKysrzJ07V+hZLSgoUEv7+PFjrfOdPXs2SkpK8PbbbyM/Px/jx4/HtWvXDJa/ISkHk+bm5qpsVzbY4cOHG/yYNjY2sLW1xQsvvGDwvI3F3d0dIpEIDx8+1Cq9hYUFkpOTMWrUKGzbtk1lqiVDfQdd3b78/Pw0dtwor35aD1juCcw2uH344YdCEBo9ejRGjBgBS0tLxMXFobGxUUhXVVWF5ORkrfKUSqVITExE3759sXPnTnzzzTd48uQJjh49apD8DW3s2LGwtbVFTk6OyvaqqioA//9ybRKJRG24DBEJf5gttd7W0NCg8jo3NxcymQwTJ07sdN6mYm9vj2HDhuH+/ftav0cikSAjIwMODg4qwU3b76AjXd2+ioqKMG/ePLXtlZWVANAjljpsrccGN7lcLjSQlmQyGd555x1s2bIFGzduxLZt2wAADg4OiIqKQl5eHqZOnYojR44gKSkJoaGhWLRoEQDg0aNHAID6+nohv6amJsjlcshkMigUCsTFxQl/0D4+PnjxxRcxYMAArfI3toEDB2LVqlUoLy/H119/LWxPT09HUFAQpk6dCgAYNGgQZDIZsrKyQERITU1Fbm4uampqUFNTg+bmZmEMVH5+PrKzs4U6qKmpwc2bN4W8z507h/HjxwsLGuub9927d7FgwQK1oGAsY8eObTO4VVRUaLzP5e7ujrS0NFhaWgrbtP0OOmp72rSvHTt2ICQkRAhImigUCqxbtw5ffvklFAoFAOCbb75BWVkZwsPD1dJXVlaiT58+GDlyZJt5dlvG6rowZG/JpUuXKDAwkACQlZUVjR07lubOnUuBgYH0xhtvUFRUFOXn56u9TyqVUlhYGAEgACSRSITep/T0dBo8eDABoNWrV1NZWRmlpKTQkCFDCACtW7eOSktLSSwWk5eXF3388cf0/vvv07Jly6ixsbHD/A0FOvaWNjc305o1a2jAgAG0fv16Wrp0KS1YsIDq6+tV6sXT05MAkKOjIx06dIgiIyPJwcGB1q5dSw8ePKCysjJydHQkBwcHOnDgABERRUREkJ2dHc2ZM4d2795NkZGRNGXKFCovL+903hcuXCAAFBcXp3MdGWIoyJEjR8jW1paePHkibCsoKKDly5cTAAoKCqKsrCyN7921a5dKb2lH34E2be/evXsdti83NzcCQJs2bWrzczU3N9PUqVMJALm4uFBAQADFx8dTU1OTxvQ+Pj60Zs0anepOEx4KYiRVVVWUn59PdXV1Or1PoVCQVCql2tpays/Pp8ePHxs0f23oGtyU6urqqKCgQCWotaRQKOjq1asklUqJ6OmYqtblb2xsVNkWERFBLi4uJJPJqLCwkMrKygyWtzKdPo9kGerxq1mzZlFGRoZe762qqlLb1tF3oEvemtrX3bt3KScnR2V4UlsqKyvp9u3b7aYpKioiW1tbKi0t7VR5iUwT3My6t7Qt/fv316vHSSQSCbONjBs3zuD5dyWxWKw2HKElkUgELy8v4bWyN68la2trldHySjY2NvD29jZ43prSGdP+/fsRHh6O2bNnazV8pSVN339H34EueWvK39HREQcPHtR4edlayxlO2pKYmIg9e/Zg6NCh+hTT5HrsPTdmenV1dT32uUNtuLm5ITo6usfMjrF37174+fm1+0OjrZSUFIjFYkRERBigZKbBwY3pTC6XY8+ePbh48SIeP36MzZs3m2RdSmOYO3cuFi1ahBMnTpi6KB1666232r2i0FZ2djYcHBywfft2A5TKdJ7Jy1LWOdbW1li5ciVWrlxp6qIYxZAhQ3rEUAhdL53bou3wlO6Oz9wYY2aJgxtjzCxxcGOMmSUObowxs8TBjTFmlozeW9p6ihymu+DgYAQHB5u6GN0et7Vnm9GC2yuvvILU1FRjHY51M9999x127drFbYAZjYio1dShjHWBtLQ0BAcHq81Uy1gXOcb33BhjZomDG2PMLHFwY4yZJQ5ujDGzxMGNMWaWOLgxxswSBzfGmFni4MYYM0sc3BhjZomDG2PMLHFwY4yZJQ5ujDGzxMGNMWaWOLgxxswSBzfGmFni4MYYM0sc3BhjZomDG2PMLHFwY4yZJQ5ujDGzxMGNMWaWOLgxxswSBzfGmFni4MYYM0sc3BhjZomDG2PMLHFwY4yZJQ5ujDGzxMGNMWaWOLgxxswSBzfGmFmyMnUBmPm5ffs2li5diubmZmFbVVUVAOC1115TSTtixAjs37/fmMVjzwgObszgXF1d8e9//xtlZWVq+y5evKjy+tVXXzVWsdgzhi9LWZcICwuDtbV1h+kWLlxohNKwZxEHN9YlQkNDIZfL200zevRoeHh4GKlE7FnDwY11CXd3d4wZMwYikUjjfmtrayxdutTIpWLPEg5urMuEhYXB0tJS476mpiYsWLDAyCVizxIObqzLLFq0CAqFQm27SCTCpEmTMHjwYOMXij0zOLixLuPi4oJXXnkFFhaqzczS0hJhYWEmKhV7VnBwY11qyZIlatuICIGBgSYoDXuWcHBjXSooKEjlzM3S0hLTp0/HwIEDTVgq9izg4Ma6lIODA2bOnCl0LBARFi9ebOJSsWcBBzfW5RYvXix0LFhZWWHOnDkmLhF7FnBwY11uzpw5sLW1Ff4vkUhMXCL2LODgxrqcnZ0d/vu//xsA+JKUGQ0HN2YUoaGh6NOnD/z8/ExdFPaM6Lazgnz33Xf4+9//bupiMANRKBRwdHTkMzczc+zYMVMXoU3d9szt1q1bOH78uKmL0S3k5eUhLy/P1MXoFAsLC4wePbrL8r99+za3FyPqCfXdbc/clLrzL4OxBAUFAeC6aE9aWhqCg4O5joxEWd/dWbc9c2OMsc7g4MYYM0sc3BhjZomDG2PMLHFwY4yZpW7fW9odNTU14dSpU9i7dy/efPNNrF692tRF6lB1dTUmT56M9evX8/TeGhQXFyM9PR3Ozs7CthkzZsDR0VElnUwmw8mTJ4VlCy0sLODn54e+ffsatbzaunHjBi5fviy8trCwQHBwMC5duoTnnnsOkyZNMmHpuhafuenh9u3bqKysxFdffdXhIijdhZWVFfr164fevXubrAwymcxkx27PyZMn8fHHH2PNmjWYOXMmsrOzsWTJEgQEBKiV2dbWFrNmzUJWVhb27t2L3/72t902sAFAZGQklixZIvxLTk6GpaUlfH19UVRUhB07dpi6iF2Gg5seBg8ejJCQEFMXQyf29vbIzs426SSRmzZt0jjtuCldvXoVO3fuREJCAiwtLTFw4EDs378fI0aMQF5eHqKiotTe06dPH8ycORPTpk2Dq6urCUqtnUuXLsHLywuFhYXCv6SkJGH/smXLcP36dWRmZpqukF2Ig5uerKz4il4XP/30E/bt22fqYqhobm5GYGAgQkND1fbZ2dnBx8cHSUlJ2LVrl9p+Gxsbk54FayM+Ph7vvvsuvL29hX8DBgxQSbN161ZERUVBKpWaqJRdx6yDW2lpKTZv3ozm5macPn0af/3rX4XLyNraWiQmJmLNmjX45JNP8OTJE53ybr1kXWpqKo4eParySMrx48dx9OhRpKend/7DdFJDQwP+8Y9/qPxKl5SU4L333oNCoUBxcTG2b9+OxMRElUvt0tJS4Y/722+/xaZNm3Do0CHhDEybz52Tk4M33ngDUqkUKSkpwlMEUqkUH3zwAa5fv97ln1+TU6dOoaKios2z8JMnT8LV1RVr167FhQsXOsxPJpMhMzMTmzZtwu7du1FaWqqyX5v6BjrfNoGndX7u3DmMHDkSgYGB+P777zWmc3V1hb29PWJjY3U+RrdH3VRqaip1pniHDh0iJycnAkBJSUk0duxYAkA5OTl048YNevPNN+n8+fN05coV8vT0pGHDhlF1dbXW+dfU1BAA+vDDD4mIqLa2liZPnkwSiURIU1lZSV5eXuTk5KT35yAimj9/Ps2fP1/v91+7do0CAgIIAP3lL38hIqKkpCRydHQkAJSRkUHz5s2j2bNnEwDavHkzERElJCRQ7969ydnZmZKTk8nLy4vEYjEBoMDAQCLS7nOVD5mAAAAgAElEQVRnZ2dTaGgoAaDTp0/T+fPniYgoMzOTAFBMTIzen01Jn/bi6+tL3t7eGveNGzeOiIh++OEHEovF1LdvXyopKRH2p6Wl0Y4dO4TX9fX19Nprr1FKSgpVV1dTQkIC2dvb04kTJ4hIu/omIoO0TSKijIwMWrhwIXl4eJBIJCIrKyuhrbYWFRVFgwYN0in/zv59GkFaty2dISpv06ZNQnAjIvrXv/5FCoWCZsyYQV988YWQ7uzZs2qNrCOtgxsRUXR0tMofORHR8uXLTR7ciIgqKipUghsRUUxMDAGgU6dOCdt8fX1p+PDhwuvg4GCys7Ojw4cPE9HTwOXj40MAhCClzefesmULASCFQiFsa2pqolOnTtHDhw879dmIdG8vCoWCevXqRf7+/hr3K4MbEdGRI0cIAHl4eFBtbS0RqQe3kJAQWrZsmUoe8+fPJ7FYTLdu3SIi7erbEG2ztTNnzlC/fv0IAGVmZqrtj4uLIwA6fQ89IbiZ9WWpWCwG8HT9TAAYMWIE7t69i6ysLOTm5mLjxo3YuHEjzpw5g/Hjx6Ourq5Tx2u9hF1b20xB0/0hOzs7AIC/v7+wzdPTE7dv31ZJI5FIhPtSzs7OiI+PBwBkZWUB0P9zW1paYs6cOSbpbbxz5w4aGhrg4uLSYdpFixZhw4YN+OWXX7B48WIQkcr+uro6HDt2DGPHjlXZvmLFCtTX1+Pzzz8H0HF937lzp0vapr+/PwoLCyGRSJCQkKC2X7lYz5UrV/Q+Rndk1nfFW98XA56OZwKAmJgY9O/f39hFMhltA5CdnR2amppUtrWuxwkTJgB4Oi1VT3Xv3j0A0HrK8+3bt+Pnn39GRkYGYmNjMWbMGGFfbm4u5HK5WifTiy++CODpWDOg4/ruyrbp5uaGgIAAjVNnKY91/fp1TJs2zaDHNaXucVphRDY2NgCAgoICtX2PHz82dnF6JBsbG9ja2uKFF14wdVH05u7uDpFIhIcPH2qV3sLCAsnJyRg1ahS2bdumMrWSckBvbm6uynuUQWP48OFaHaOr26afnx9GjBihtl3ZU9p6wHJP98wFtxEjRsDS0hJxcXFobGwUtldVVSE5OblTeUskErVBn0QkNP6eqqGhQeV1bm4uZDIZJk6cCEC3z91d6sLe3h7Dhg3D/fv3tX6PRCJBRkYGHBwcVILb2LFjYWtri5ycHJX0VVVVAIBXX31Vq/y7sm0CQFFREebNm6e2vbKyEgAwZMiQTh+jOzHr4KbsYm/56+zg4ICoqCjk5eVh6tSpOHLkCJKSkhAaGircm9OGsnu+5figQYMGQSaTISsrC0SE1NRU5ObmoqamBjU1NSb9w9ZU3kePHgEA6uvrhW1NTU2Qy+UqwaqmpgY3b94UXp87dw7jx48XBgRr87mV46vy8/ORnZ2NhoYG3L17FwsWLFALCsYyduzYNoNbRUWFxvtc7u7uSEtLE9ZhBZ7es1q1ahXKy8vx9ddfC9vT09MRFBSEqVOnAui4vrVpmzt27EBISIgQkDRRKBRYt24dvvzyS2HIzjfffIOysjKEh4erpa+srESfPn0wcuTINvPskUzan9GOzvbGHD9+nEaMGEEAKCgoiH788Udhn1QqpbCwMAJAAEgikaj0UHWksrKSVqxYQQBo9OjRlJ6eLuTr6elJAMjR0ZEOHTpEkZGR5ODgQGvXrqUHDx7o9Vk621t68+ZNlfKePXuW0tPTafDgwQSAVq9eTWVlZZSSkkJDhgwhALRu3Tq6d+8eRUREkJ2dHc2ZM4d2795NkZGRNGXKFCovLxfy1+Zzl5WVkaOjIzk4ONCBAweIiOjChQsEgOLi4vT+bEr6tJcjR46Qra0tPXnyRNhWUFBAy5cvF9pNVlaWxvfu2rVLpbe0ubmZ1qxZQwMGDKD169fT0qVLacGCBVRfX09EpHV9d9Q23dzcCABt2rSpzc/V3NxMU6dOJQDk4uJCAQEBFB8fT01NTRrT+/j40Jo1a3Squ57QW9ptS2eMyquqqqL8/Hyqq6szWJ4KhYKuXr1KUqmUiJ6OW+ps/oYYCqKviIgIcnFxIZlMRoWFhVRWVqYxnTafu7GxUW3bjRs3qLm5udPl1Le9zJo1izIyMvQ6ZlVVldq2uro6KigoEIKavtpqm3fv3qWcnBxavXp1h3lUVlbS7du3201TVFREtra2VFpaqlP5ekJwM+ve0o7079/f4L1SIpEIXl5ewmtlj1lPZ2NjA29v7zb3a/O5ra2tYW1trbLN1PWzf/9+hIeHY/bs2ToP29HUdsRisdqQEH201TYdHR1x8OBBjZeXrbWc4aQtiYmJ2LNnD4YOHapPMbs1s77nxjqvrq7OLJ87VHJzc0N0dHSPmR1j79698PPza/eHRlspKSkQi8WIiIgwQMm6n2f6zK21W7duYdmyZR2mW7p0KZYsWWKEEpmOXC5HYmIiLl68iMePH2Pz5s146623uvUsGPqaO3cuvL29ceLECZPOmqKNt956yyADw7Ozs+Hg4IDt27cboFTdEwe3FlxdXXHmzJkO0z0LM4JYW1tj5cqVWLlypamLYhRDhgzpEUMhDPXEi7bDU3oy8/8r1YFIJIKtra2pi8EYMwC+58YYM0sc3BhjZomDG2PMLHFwY4yZpW7foaBp2qJnFddFx7iOmFK3D26pqammLoLJ7dy5EwDwzjvvmLgk3dd3332HXbt2cXsxEmV9d2fdPrgtWLDA1EUwOeX0OlwX7du1axfXkRF19+DG99wYY2aJgxtjzCxxcGOMmSUObowxs8TBjTFmlrp9b6m2cnJyUF5eLrxWPgQvkUjg6emp1fqULV2+fFlYkk3JysoKCxcuVEt76tQpldWJRCIRJkyYIKx61NDQgC+++EJYQ8HCwgLTpk2Dk5OTTmViXae4uBjp6ekqEzzOmDFDbUUomUyGkydPqnyXfn5+Jll7VRs3btzA5cuXhdcWFhYIDg7GpUuX8Nxzz2HSpEkmLF0XM/VcwG3RZwXxc+fOkUgkov79+9PHH39MO3fupJdeeoksLCzonXfe0Xm670uXLpG1tbWwSrhyCu3WZDIZxcbGEgBycnKiK1euqKX59ddfKSwsjEaNGkVFRUU6lcOU04wTETU0NHT7vDsz7fWJEycoOjqampqa6N69exQZGUkA6OWXX9ZYvurqagoLC6NXXnlFWE2+u1KupaD85+/vL+z77LPPKD4+Xq98e8I04922dPpWXt++fWnUqFEq20JCQggAbdmyRef8Bg8eTP369esw3dWrVwkAvfHGG22mSUlJobffflvnMpg6uP3pT38yyDoHXZm3vu3lxx9/pClTpqhtVy4uFB4ervF9hw8fpvfee0/n4xnTxYsXKTo6mgoLC4V/9+/fV0kTHh5O58+f1znvnhDczO6em3Jh25Z+97vfAXg6rbI++WnKs7V+/foBaH8FcxsbG/zmN7/RuQym9NNPP2Hfvn09Lm9tNDc3IzAwEKGhoWr77Ozs4OPjg6SkJI2DVW1sbNC7d29jFFNv8fHxePfdd+Ht7S38Uy6xqLR161ZERUWZ5VTyZnPPrT3KgKNpptXa2lqkpqbi2rVrGDp0KMLDw7t9o9WWTCbDxYsXcfHiRbi4uMDPzw/Dhg0D8PSxNoVCAWtra8yfPx8AcPz4ccjlcojFYgQEBCAnJwchISGQSqVISUmBtbU1goKCUFpaii+//BJvv/02vv32W5w9exbDhw/HkiVLYGFh0am8pVIpPvroIwQHB2tcHd2QTp06hYqKCoSEhGjcf/LkSUyYMAFr166Fp6cnpk+f3m5+7dU3AJSUlCApKQkffPABSktLkZaWhoEDByI8PFxl4RxDtMmcnBycO3cOI0eOxPTp07FhwwZMmDBBLZ2rqyvs7e0RGxuLjz76SKdjdHumPndsi76nvU5OTiqXpc3NzTR37lwCoLY26Y0bN+jNN9+k8+fP05UrV8jT05OGDRtG1dXVQprhw4eTs7Nzh8etqKggABQSEtJmmpMnT+q1Rqc+l6X19fX02muvUUpKClVXV1NCQgLZ29vTiRMniIiotraWJk+eTBKJRHhPZWUleXl5kZOTExERZWdnU2hoKAGg06dP0/nz5ykhIYF69+5Nzs7OlJycTF5eXiQWiwkABQYGdipvIqLMzEwCQDExMTp9Xn3ai6+vL3l7e2vcN27cOCIi+uGHH0gsFlPfvn2ppKRE2J+WlqaybmlH9Z2UlESOjo4EgDIyMmjevHk0e/ZsAkCbN28W8tGmTWojIyODFi5cSB4eHiQSicjKyoo+/PBDjWmjoqJo0KBBOuXfEy5Lu23pOhPcnn/+eUpKSqKtW7fS6NGjadKkSXTs2DG1tDNmzFAJeGfPnlVrbD01uIWEhNCyZcvU8hGLxcJN8OjoaJUARES0fPlyIQAREW3ZsoUAkEKhELYFBweTnZ0dHT58mIieBi4fHx8CIAQpffNuamqiU6dO0cOHD3X6vPp0QPXq1UvlBntLyuBG9HTxZgDk4eFBtbW1RKQe3LSp75iYGKFzSsnX15eGDx8uvNamTerqzJkz1K9fPwJAmZmZavvj4uIIgE513hOCm9ndcwOeLm7i7u6OwsJCFBUVITY2Vrg8Urpz5w6ysrKQm5uLjRs3YuPGjThz5gzGjx+Puro6E5XcMOrq6nDs2DG19TNXrFiB+vp6fP755wA0LzaizQIkdnZ2kEgkwr0qZ2dnxMfHAwCysrI6lbelpSXmzJnT5UMr7ty5g4aGBq2GCC1atAgbNmzAL7/8gsWLF4OIVPZrW992dnYAAH9/fyGNp6cnbt++LZSpK9qkv78/CgsLIZFIkJCQoLZ/4MCBAIArV67ofYzuyCzvuYnFYkyePBkeHh7Iz89HeHg4rl69qjKurLi4GAAQExNjkIWZe/XqBQBobGxsM019fb2Qrivl5uZCLperrdKlXAC59fg9fbSeN015P+fWrVudztsY7t27B6D9DqCWtm/fjp9//hkZGRmIjY3FmDFjhH3a1rem4G5nZ4empiYAhm+TLbm5uSEgIAB5eXlq+5THun79OqZNm2bQ45qSWZ65KfXp0wfJycl49OgRli5dqvKLq+wBLSgoUHtfywG5HVE2yN69e8PCwgJVVVVtpn348KHQq9qVlANMc3NzVbYrG7FycLEh2djYwNbWFi+88ILB8+4K7u7uEIlEePjwoVbpLSwskJycjFGjRmHbtm3CNFSA4erbUG2yLX5+fho7aZQ9pa0HLPd0Zh3cAGDy5MmIjY1FZmYm/va3vwnbR4wYAUtLS8TFxamcbVVVVSE5OVklj9aXIUoKhQKJiYkAnjZM5ZlifX29xvRfffWVxh4rQxs7dixsbW2Rk5Ojsl0ZeJVrVkokEshkMpU0RCT8sbbUeltDQ4PK69zcXMhkMkycOLHTeRuDvb09hg0bhvv372v9HolEgoyMDDg4OKgEN23ruyO6tEl9FBUVYd68eWrbKysrAWgeTdCTmVVwa2pqwoMHD1BbW6uyfdOmTXj11VeFexgA4ODggKioKOTl5WHq1Kk4cuQIkpKSEBoaikWLFgnvvXPnDh48eKD2hyqTyfDHP/4RgwcPFrYdOHAAcrkcf/7zn9XKtnnzZgwdOhTe3t4G/MSaDRw4EKtWrUJ5eTm+/vprYXt6ejqCgoIwdepUAMCgQYMgk8mQlZUFIkJqaipyc3NRU1ODmpoaNDc3C+Oi8vPzkZ2dLQS1mpoa3Lx5U8j73LlzGD9+vLBiu7553717FwsWLFALFF1h7NixbQa3iooKjfe53N3dkZaWBktLS2GbtvX96NEjAFD58WtqaoJcLodMJtOqTe7YsQMhISFCQNJEoVBg3bp1+PLLL6FQKAAA33zzDcrKyhAeHq6WvrKyEn369MHIkSPbzLNHMmFvRrt07Y25dOkSBQYGCo+ZREVF0eXLl4X9N2/eJAcHB7KysqKAgADKysoiqVRKYWFhwnskEonQU5WXlycMVQBArq6uNGHCBJo4cSKNGTOG7O3tSSQS0e3bt1XKceTIEXJycqKXXnqJVq1aRSEhIeTr60vvvPMONTU16VUX+vSWNjc305o1a2jAgAG0fv16Wrp0KS1YsIDq6+uFNFKplDw9PQkAOTo60qFDhygyMpIcHBxo7dq19ODBAyorKyNHR0dycHCgAwcOEBFRREQE2dnZ0Zw5c2j37t0UGRlJU6ZMofLy8k7nfeHCBQKgc6+yPr13R44cIVtbW3ry5ImwraCggJYvX04AKCgoiLKysjS+d9euXSq9pR3Vd3p6Og0ePJgA0OrVq6msrIxSUlJoyJAhBIDWrVtH9+7da7dNEhG5ubkRANq0aVObn6u5uVl47MrFxYUCAgIoPj6+zfbn4+NDa9as0anuekJvabctnTErr6qqivLz83V+9rQtjY2N9PPPP9M///lPqqio6HR+nXn8qq6ujgoKClSCWksKhYKuXr0qPDd748YNtXpobGxU2RYREUEuLi4kk8mosLCQysrKDJa3Mp2uj2Tp215mzZpFGRkZOr+P6Gm7aa2j+tYlb01t8u7du5STk0OrV6/uMI/Kykq1H9/WioqKyNbWlkpLS3UqX08IbmbZW6qr/v37G7R3ytraGh4eHvDw8DBYnvoSi8VqQxRaEolE8PLyEl4re/hasra2VhlBr2RjY9PuZba+eWtK11X279+P8PBwzJ49W6uhKi1pajMd1bcueWvK39HREQcPHtR4edlayxlO2pKYmIg9e/Zg6NCh+hSzWzOre27MOOrq6szmWUQ3NzdER0djx44dpi6KVvbu3Qs/Pz+D3LtNSUmBWCxGRESEAUrW/XBwY1qTy+XYs2cPLl68iMePH2Pz5s3CANSebO7cuVi0aBFOnDhh6qJ06K233sK4ceM6nU92djYcHBywfft2A5Sqe+LLUqY1a2trrFy5EitXrjR1UQxuyJAhPWIohK6Xzm3RdnhKT8Znbowxs8TBjTFmlji4McbMEgc3xphZ6vYdCmlpaaYugskpeyR7cl00NTVBJpMJ0/4Y2nfffQegZ9dRT6Ks7+5MRNTGU+EmlpaWhuDgYFMXgzHWjm4aPgDgWLcNbsy8KH+suLkxIznG99wYY2aJgxtjzCxxcGOMmSUObowxs8TBjTFmlji4McbMEgc3xphZ4uDGGDNLHNwYY2aJgxtjzCxxcGOMmSUObowxs8TBjTFmlji4McbMEgc3xphZ4uDGGDNLHNwYY2aJgxtjzCxxcGOMmSUObowxs8TBjTFmlji4McbMEgc3xphZ4uDGGDNLHNwYY2aJgxtjzCxxcGOMmSUObowxs8TBjTFmlji4McbMEgc3xphZsjJ1AZj5kcvlePLkico2qVQKAKiurlbZLhKJ0KdPH6OVjT07OLgxg3v06BGef/75/6+9cw+K6kjb+DNcHYGJoICyEKOiGAULXUzCakJQUQR1QUDkoiJlKVJaElZRliiaaOlWKivlXYkl7ooCXhZQCwF3RQlIraLGJLrIbdcLgoS4gAMMA/N+f/BxlnEGZwYGDgP9q5oqTneft9956fPMOd19utHe3q6QZ2FhIXfs7u6Of/zjH/3lGmMIwR5LGVrH2toan332GfT03t28BAIBli9f3k9eMYYaTNwYfcKKFStUltHX14efn18/eMMYijBxY/QJfn5+MDDovtdDX18fCxYswMiRI/vRK8ZQgokbo08QiUTw9PTsVuCICKGhof3sFWMowcSN0WeEhoYqHVQAACMjIyxevLifPWIMJZi4MfqMxYsXY/jw4QrphoaG8PX1hYmJCQ9eMYYKTNwYfcawYcOwdOlSGBoayqVLpVKEhITw5BVjqMDEjdGnBAcHQyqVyqWJRCJ4eHjw5BFjqMDEjdGnzJs3T27irqGhIYKCgmBkZMSjV4yhABM3Rp9iYGCAoKAg7tFUKpUiODiYZ68YQwEmbow+Z/ny5dyjqbW1NWbPns2zR4yhABM3Rp8za9Ys2NjYAOh4c0HVa1kMhjZgrYzR5wgEAu51LPYuKaO/YOLG6BeCgoIwefJk/Pa3v+XbFcYQgdcljwICAnDhwgU+XWD0MwKBgG8XGP1Eamoqli1bxlv9vK/n9sknn+CLL77g2w2d5fbt20hISEBqairfrgxoAgMDERUVBVdXV75dGRIEBgby7QL/4mZra8urug8GEhISWAxVEBgYCFdXVxanfmIgiBvrc2MwGIMSJm4MBmNQwsSNwWAMSpi4MRiMQQkTNwaDMSjhfbS0t/znP//BiRMnkJycjH//+998u6MRYrEYly9fxp07d+Di4oLly5fzNg/s9evXmDVrFrZu3YpVq1bx4sNApbS0FOnp6RgzZgyX5uHhAWtra7lyEokEly5d4lYf1tPTg6enp8J2hgOFJ0+e4J///Cd3rKenh8DAQNy6dQvDhw/Hxx9/zKN3vUfnxa2iogJ5eXl4/vw5365oRHV1Ndzc3GBvb4+CggL8+c9/xu3bt3HgwAFe/DEwMMDIkSNhamrKS/1AhzgYGxvzVr8yLl26hBs3biAhIQF1dXXYvn07Tpw4gU8++QR5eXly/hobG2PhwoXYtGkTysrKkJqaOmCFDQDWrl2LmzdvcsdeXl4IDg6Gu7s7Tp06hRs3bmDbtm08etg7dP6x1N3dHbNmzeLbDY05duwY7t69i6tXr+Lly5eYNm0aTp48iYaGBl78MTMzQ35+Pq9b7cXFxUEmk/FW/9s8fPgQ+/fvx8GDB6Gvrw8rKyscP34cDg4OKCoqQkREhMI5I0aMwPz58zFnzhzY2try4LV63Lp1C05OTrh//z73SUpK4vJXr16NkpIS5OTk8OdkL9F5cQOgsIy1LhAbGwszMzMAgFAoxMqVKyEQCIbsIo4//vgjjh07xrcbHO3t7fDz81O6HLqJiQlcXV2RlJSEhIQEhXwjIyNe74DVYe/evfjjH/8IZ2dn7mNpaSlX5uuvv0ZERATEYjFPXvYOnRQ3qVSKtLQ0xMbGIjs7W+mvfUNDAxITExEdHY1Dhw7hzZs3XF5ZWRm+/PJLyGQylJaWYs+ePUhMTFRYDvv7779HXFwcjh07hhMnTqhtXx3efvyqra1FVFQUhg0bppEdbdHS0oK//vWvcr/U6sSpvLycu8A743X69Gnuf5Kamopz587JvUN84cIFnDt3Dunp6QCAgoICLFq0CGKxGCkpKTh//jyAjj7Jr776CiUlJX3+/d8mIyMDL1686HZhzUuXLsHW1habN2/G9evXVdqTSCTIyclBXFwcDh8+jPLycrl8ddtkb9sd0BHva9euYfLkyfDz88OdO3eUlrO1tYWZmRl27NihcR0DAuIRf39/8vf31+ic//73vzR37lzauXMn1dXV0enTp8nIyIj09fW5Mk+ePKHFixdTdnY2PXjwgBwdHWnChAn0+vVrSkpKImtrawJAmZmZtHTpUvL29iYAtH37ds5GTEwMJScnk1gspnPnzpGpqala9nvCnTt3yNfXl2QymcbnpqamUm//jY8fPyYfHx8CQH/605+IiNSK08GDB8nU1JTGjBlDycnJ5OTkREKhkACQn58fERE1NDTQrFmzSCQScfVVVVWRk5MTjR49moiI8vPzKSQkhADQlStXKDs7m4iIcnJyCADFxMT06vsREQGg1NRUtcu7u7uTs7Oz0rwZM2YQEdHdu3dJKBSShYUFlZWVcflpaWm0b98+7ri5uZk+//xzSklJodevX9PBgwfJzMyMLl68SETqxZpIe+0uMzOTli9fTlOnTiWBQEAGBgb0zTffKC0bERFBY8eO1cg+kebx7gPSdE7cIiMjycfHRy5t0aJFcuLm4eFBf/vb37jjrKwsuYYSExNDACgjI4Mr4+7uTpMmTSIiotbWVho5ciSVlJRw+Zs2bVLbvro0NjbS+vXrOUGIiooiiUSikQ1tiBsR0YsXL+TEjUh1nIiIAgMDycTEhM6cOUNEHcLl6upKADiR2rBhg5y4ERGtWbOGEzciol27dhEAOYFva2ujjIwMqqur6/X30+Rik8lkNGzYMPLy8lKa3yluRERnz54lADR16lRqaGggIkVxCw4OptWrV8vZ8Pf3J6FQSM+ePSMi9WKtrXbXlatXr9LIkSMJAOXk5Cjkx8fHEwCN/wcDQdx06rH01atXSExMxPz58+XSp02bxv398uVL5ObmorCwELGxsYiNjcXVq1fh4uKCpqYmAOD2y/Ty8uLOc3R05EZcDQ0NYWZmhnnz5iErKwtAR2e3uvbVxdTUFIcPH8atW7fg6uqKhIQEpKWlaRgV7aCsj0hVnDrLiEQirm9qzJgx2Lt3LwAgNzcXAJSuvKvOarz6+vpYsmRJv484vnz5Ei0tLdzqwe8iKCgI27Ztw88//4zQ0FB0XNf/o6mpCefPn8f06dPl0tevX4/m5macOnUKgOpYa7PddcXLywv379+HSCTCwYMHFfKtrKwAAA8ePOhxHXyhU1NBfvjhB0ilUowePVouvevcsNLSUgBATEwMRo0apdSOsgvLxMQEbW1t3PGhQ4ewYsUKeHl5cZ3HlpaWatnXBIFAABcXF2RlZWHChAm4cuUKQkNDe21XU9QVoLfjBCiu0TZz5kwAwLNnz7ToYf9RU1MDoGMLQnXYs2cPfvrpJ2RmZmLHjh1yP7aFhYWQSqUwMJC/1CZOnAigY64ZoDrW2m53XbGzs4OPjw+KiooU8jrrKikpwZw5c7Rab1+jU3dujY2NADp+xbqjc7Tx3r173Z6vDt7e3igrK0NUVBSKi4vh4uKCx48fa83+27z33ntwc3NDa2trj20MFIyMjGBsbIz333+fb1d6hL29PQQCAerq6tQqr6enh+TkZHz44YfYvXs3NyACgJvQW1hYKHdOp2hMmjRJrTr6qt114unpCQcHB4X0zpHStycs6wI6JW6TJ08GAO5RsSudo3MODg7Q19dHfHy8nFDU1tYiOTlZrXrEYjESExNhYWGB/fv3Iy8vD2/evI0ODsMAABF1SURBVMG5c+e0Yr87ampq4Obm1isbfNDS0iJ3XFhYCIlEgo8++ghAxx2QRCKRK0NE3IXfFWVp/Y2ZmRkmTJiAV69eqX2OSCRCZmYmzM3N5cRt+vTpMDY2RkFBgVz52tpaAMCnn36qlv2+bHcA8OjRIyxdulQhvaqqCgAwbty4XtfR3+iUuE2ZMgWenp64cuUKN+GwtbUVDx48ABHh2bNnMDMzQ0REBIqKiuDm5oazZ88iKSkJISEhCAoKAgD8+uuvAIDm5mbOdltbG6RSKSQSCWQyGeLj47mL1tXVFRMnToSlpSXMzc1V2ldFW1sbzp49K9d3lZeXh6amJqxfv14bodKYzikFXec0qYpTJ/X19Xj69Cl3fO3aNbi4uHATgseOHQuJRILc3FwQEVJTU1FYWIj6+nrU19ejvb2dm2NVXFyM/Px8tLS0oLq6GsuWLVMQhv5g+vTp3YrbixcvlPZz2dvbIy0tDfr6+lyalZUVNm7ciMrKSty4cYNLT09PR0BAAPdjpirW6rS7ffv2ITg4mBMkZchkMmzZsgWXL1/mbgjy8vJQUVGBsLAwhfJVVVUYMWIEd2OhU/A5nNGT0dLq6mr69NNPCQBNmjSJlixZQqGhoWRqakobNmyg58+fk1gsppUrVxIAAkAikYgbZUpPT6cPPviAANCmTZuooqKCUlJSaNy4cQSAtmzZQuXl5SQUCsnJyYkOHDhAO3fupNWrV1NraysR0Tvtq0NNTQ1ZWFiQoaEh/f73vycfHx/auHEjNTU1aRQLIu2Mlj59+pTWr19PAGjKlCmUlZWlVpxqamooPDycTExMaMmSJXT48GFau3YtzZ49myorKzn7YrGYHB0dCQBZW1vT6dOnae3atWRubk6bN2+mX375hSoqKsja2prMzc3pu+++IyKi69evEwCKj4/v1fcj0nz07uzZs2RsbExv3rzh0u7du0dr1qwhABQQEEC5ublKz01ISJAbLW1vb6fo6GiytLSkrVu30qpVq2jZsmXU3NxMROq1yZqaGpXtzs7OjgBQXFxct9+rvb2d3NzcCADZ2NiQj48P7d27l9ra2pSWd3V1pejoaLXj1omm8e4DdG8qSCdlZWVUUlJCMpmMKioqqL6+XqFMbW0tFRcXaywaMpmMxGIxNTQ0UHFxMTU2Niot11P7nXWUlpbS06dPNT63K9qaCtJTwsPDycbGhiQSCd2/f58qKiqUlpPJZPTw4UMSi8VE1DFn6+24tba2KqQ9efKE2tvbe+1nTy62hQsXUmZmZo/qq62tVUhramqie/fucaLWU7prd9XV1VRQUCA3bak7qqqq6Pnz5+8s8+jRIzI2Nqby8nKNfRwI4qZTo6VdmTBhAvd3d/0Bo0aN6tHIkkAgwPDhwwEAM2bM6LZcT+131mFvb9+jcwciRkZGcHZ27jZfIBDAycmJO+4cLeyKoaGhwqt0ysr1F8ePH0dYWBi8vb013khaWbsQCoUKU0J6QnftztraGidPnlT6ePk2XVc46Y7ExEQcOXIE48eP74mbvKNTfW6MgUdTU5POvnuoCjs7O2zYsAH79u3j2xW1OHr0KDw9Pd/5I6MuKSkpEAqFCA8P14Jn/KCzd24DkWfPnmH16tUqy61atYrbgV1XkUqlSExMxM2bN9HY2Ijt27dj3bp1A3oljJ7g6+sLZ2dnXLx4kdcVU9Rh3bp1Gt9hKiM/Px/m5ubYs2ePFrziDyZuWsTW1hZXr15VWe7tCZ26iKGhISIjIxEZGcm3K33OuHHjdGIqhDaEDVB/espAR/evsgGEQCAYcIstMhhDFdbnxmAwBiVM3BgMxqCEiRuDwRiU8N7n9vz5c96W+RkM3L59GwBYDNWgM1aMIQKfU4j9/f25V0nYh33YZ3B9+H5DgffHUn9/fxAR+/Twk5qaCgC8+zHQP0DHfg58+zFUPgMB3sWNwWAw+gImbgwGY1DCxI3BYAxKmLgxGIxBCRM3BoMxKGHixmAwBiW8T+LVFgUFBaisrJRLMzAwwHvvvQcLCws4OTlxC1AyGJpQWlqK9PR0uQUePTw8FHaEkkgkuHTpErfJjZ6eHjw9Pft931VNyMnJgVQqhbe3N5d248YNDB8+HB9//DGPnvWeQXPn9rvf/Q6WlpZYuXIlNm7ciNLSUrS0tOD+/fvYt28fRo4cCS8vL/zrX//i29VBxdu7WumKbXW5dOkSDhw4gOjoaMyfPx/5+flYsWIFfHx8FPwzNjbGwoULkZubi6NHj+Kzzz4bsMJ2/fp1LFiwAAsWLMDdu3fl8tzd3fHo0SOdWaSzW4hHerOHQndYWFiQg4ODQvr169dp9OjRNGzYMCoqKtJqnXzC9x4Kf/jDH7Syx0Ff20YPZsz/8MMPNHv2bIV0BwcHAkBhYWFKzztz5gx9+eWXPfKzv2hubqbKykoCQDt37lRaJiwsjLKzs3tkvyfx1jL8v6GgbTo3r32buXPn4uTJk2hpaYGfn9+AuCvQdX788UccO3ZM52yrQ3t7O/z8/BASEqKQZ2JiAldXVyQlJSEhIUEh38jICKampv3hZo8ZNmwYfvOb37yzzNdff42IiAidXUZ+0PS5qYOXlxfmzp2Lv//97zh//jxCQ0MBAA0NDUhNTcXjx48xfvx4hIWFcY2zrKwMSUlJ+Oqrr1BeXo60tDRYWVkhLCxMbjOT77//HllZWbCzs4Oenh7Wrl3L5b3LPl9IJBLcvHkTN2/ehI2NDTw9PblNd1JTUyGTyWBoaAh/f38AwIULFyCVSiEUCuHj44OCggIEBwdDLBYjJSUFhoaGCAgIQHl5OS5fvoyoqCguJpMmTcKKFSugp6fXK9tisRjffvstAgMDle6Ork0yMjLw4sULBAcHK82/dOkSZs6cic2bN8PR0RHz5s17p713xRtQv51psy113V9VGba2tjAzM8OOHTvw7bff9qgOXuHzvrEvHktHjx6t9LG0ky+//JIAUHh4OBF1bB23ePFiys7OpgcPHpCjoyNNmDCBXr9+TUlJSWRtbU0AKDMzk5YuXUre3t4EgLZv387ZjImJoeTkZBKLxXTu3DkyNTXl8t5lXxv05LG0ubmZPv/8c0pJSaHXr1/TwYMHyczMjC5evEhERA0NDTRr1iwSiUTcOVVVVeTk5ESjR48mIqL8/HwKCQkhAHTlyhXKzs6mgwcPkqmpKY0ZM4aSk5PJycmJhEIhASA/P79e2SYiysnJIQAUExOjcZyg4WOSu7s7OTs7K82bMWMGERHdvXuXhEIhWVhYUFlZGZeflpYmt2+pqnir28603ZZkMhkBoF27dnVbJiIigsaOHauxbU3j3Qfo7r6l3aFK3P7yl78QAPLw8CAiIg8PD7mNbbOysuQaVUxMDAGgjIwMroy7uztNmjSJiDr22hw5ciSVlJRw+V33jVRlv7f0RNyCg4Np9erVcmn+/v4kFArp2bNnRES0YcMGOQEiIlqzZg0nQEREu3btIgAkk8m4tMDAQDIxMaEzZ84QUYdwubq6EgBOpHpqu62tjTIyMqiurk6j70uk2cUmk8lo2LBh5OXlpTS/U9yIOjZvBkBTp06lhoYGIlIUN3XiraqdEWm/LakjbvHx8QRA45gPBHEbdH1uqujsP7C0tMTLly+Rm5uLwsJCxMbGIjY2FlevXoWLiwuampoAdPSvAB2PtJ04Ojri+fPnADo2SjEzM8O8efOQlZUFAIiLiwMAtez3N01NTTh//rzC/pnr169Hc3MzTp06BUD5ZiPqbEBiYmICkUjE9VWNGTMGe/fuBQDk5ub2yra+vj6WLFnS5yOQL1++REtLC2xsbFSWDQoKwrZt2/Dzzz8jNDRUYUUMdeOtqp3x1ZasrKwAAA8ePOizOvqKIdXnBgAlJSUAgClTpqC0tBQAEBMT0+3mysouOhMTE7S1tXHHhw4dwooVK+Dl5cV1NFtaWqplv78pLCyEVCpV2IGrc/PjJ0+e9LoOgUAgdzxz5kwAHVsf6gI1NTUAAJFIpFb5PXv24KeffkJmZiZ27NiBadOmcXnqxltVO+OrLXXWVVJSgjlz5vRbvdpgSN25tba24sqVKzAwMICvry83snrv3j2Fso2NjWrb9fb2RllZGaKiolBcXAwXFxc8fvxYa/a1SecE08LCQrn0zkY8adIkrddpZGQEY2NjvP/++1q33RfY29tDIBCgrq5OrfJ6enpITk7Ghx9+iN27d+P8+fNcnrbizVdb6nzSeXvCsi4wpMTtm2++4URoypQpcHBwgL6+PuLj49Ha2sqVq62tRXJyslo2xWIxEhMTYWFhgf379yMvLw9v3rzBuXPntGJf20yfPh3GxsYoKCiQS6+trQXwvz0rRSKRwnQZIuIu1q68ndbS0iJ3XFhYCIlEgo8++qjXtvsDMzMzTJgwAa9evVL7HJFIhMzMTJibm8uJm7rxVkVftKXOR+i3H6W7UlVVBQA6sW/r2wwqcZNKpVyj6YpEIsEXX3yBXbt2ITY2Frt37wYAmJubIyIiAkVFRXBzc8PZs2eRlJSEkJAQBAUFAQB+/fVXAEBzczNnr62tDVKpFBKJBDKZDPHx8dwF7erqiokTJ8LS0lIt+/2NlZUVNm7ciMrKSty4cYNLT09PR0BAANzc3AAAY8eOhUQiQW5uLog6VvwtLCxEfX096uvr0d7eDktLSwBAcXEx8vPzuRjU19fj6dOnnO1r167BxcWF27G9p7arq6uxbNkyBaHoC6ZPn96tuL148UJpP5e9vT3S0tLkplioG29V7UydtrRv3z4EBwdzgqSKTpF81zy2qqoqjBgxApMnT1bL5oCCx9EMrY6W3rp1i/z8/AgAGRgY0PTp08nX15f8/Pxo0aJFFBERQcXFxQrnicViWrlyJbfuu0gk4kak0tPT6YMPPiAAtGnTJqqoqKCUlBQaN24cAaAtW7ZQeXk5CYVCcnJyogMHDtDOnTtp9erV1NraqtK+NujJaGl7eztFR0eTpaUlbd26lVatWkXLli2j5uZmubg4OjoSALK2tqbTp0/T2rVrydzcnDZv3ky//PILVVRUkLW1NZmbm9N3331HRETh4eFkYmJCS5YsocOHD9PatWtp9uzZVFlZ2Wvb169fJwAUHx+vcZyg4ejd2bNnydjYmN68ecOl3bt3j9asWUMAKCAggHJzc5Wem5CQIDdaqire6rSzmpoalW3Jzs6OAFBcXJzK71dYWEiRkZEEgOzt7enw4cMklUoVyrm6ulJ0dLTacetE03j3AYNvKkhPqa2tpeLiYmpqatLoPJlMRmKxmBoaGqi4uJgaGxu1al8VvXn9qqmpie7duycnal2RyWT08OFDEovFRNQxz+pt/1tbW+XSwsPDycbGhiQSCd2/f58qKiq0ZruzXE9eyerJxbZw4ULKzMzUuC6ijv/326iKtya2lbWl6upqKigokJuK1BsePXpExsbGVF5ervG5A0HchtxoaXeMGjWqR6NQAoGAW21kxowZWrfflwiFQoUpCl0RCARwcnLijjtH+LpiaGgoN4O+EyMjIzg7O2vdtrJyfcXx48cRFhYGb29vtaaqdEXZ/1pVvDWxrcy+tbU1Tp48ibCwsF7XAQCJiYk4cuQIxo8frxV7/c2g6nNj8E9TU5POvov4NnZ2dtiwYYPOrI5x9OhReHp6vvNHRV1SUlIgFAoRHh6uBc/4gYkbQytIpVIcOXIEN2/eRGNjI7Zv385NQNVlfH19ERQUhIsXL/LtikrWrVv3zqcHdcnPz4e5uTn27NmjBa/4gz2WMrSCoaEhIiMjERkZybcrWmfcuHE6MRVC00fn7lB3espAh925MRiMQQkTNwaDMShh4sZgMAYlTNwYDMaghPcBhaKiIgQEBPDths7SOSLJYqia/fv3y733yRjc8Cpurq6ufFY/KLC1teWW62Z0D4tR/+Lv7w87OztefRD8/6sSDAaDMZg4z/rcGAzGoISJG4PBGJQwcWMwGIMSJm4MBmNQ8n+gqZrt/q4J3wAAAABJRU5ErkJggg==",
+ "text/plain": [
+ "
"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from keras.models import Sequential\n",
+ "from keras.layers import Dense, LeakyReLU,ReLU\n",
+ "from keras.utils import plot_model\n",
+ "import matplotlib.pyplot as plt\n",
+ "\n",
+ "def define_discriminator(inputs = 8):\n",
+ " ''' function to return the compiled discriminator model'''\n",
+ " model = Sequential()\n",
+ " model.add(Dense(20, activation = 'relu', kernel_initializer = 'he_uniform', input_dim = inputs))\n",
+ " model.add(LeakyReLU(alpha=0.1))\n",
+ " model.add(Dense(15, activation = 'relu', kernel_initializer = 'he_uniform'))\n",
+ " model.add(LeakyReLU(alpha = 0.1))\n",
+ " model.add(Dense(5, activation = 'relu', kernel_initializer = 'he_uniform'))\n",
+ " model.add(ReLU())\n",
+ " model.add(Dense(1, activation = 'selu'))\n",
+ " model.compile(optimizer = 'adam', loss = 'binary_focal_crossentropy', metrics = ['accuracy'])\n",
+ " return model\n",
+ "\n",
+ "discriminator_model = define_discriminator()\n",
+ "discriminator_model.summary()\n",
+ "plot_model(discriminator_model, to_file = 'discriminator_model.png', show_shapes = True, show_layer_names = True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The function below makes up the second component of a GAN. It takes an input point from a latent space and generate a vector with two dimensions(like the X vector returned by the generate_real_samples function)\n",
+ " \n",
+ "A latent variable is a hidden variable, and the space it belongs to is called the latent space. We can arbitrarily assign a size to our latent space(here it is 5). The points in the latent space are meaningless until the generator model begins learning and starts assigning meaning to the points in the space. After training, the points in the latent space correspond to the generated samples."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Note that the generator model isn't compiled here, it's because it is fit indirectly."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def define_generator(latent_dim, outputs = 8):\n",
+ " model = Sequential()\n",
+ " model.add(Dense(20, activation = 'relu', kernel_initializer= 'he_uniform', input_dim = latent_dim))\n",
+ " model.add(LeakyReLU(alpha = 0.3))\n",
+ " model.add(Dense(15, activation = 'relu', kernel_initializer = 'he_uniform'))\n",
+ " model.add(ReLU())\n",
+ " model.add(Dense(outputs, activation = 'elu'))\n",
+ " return model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Model: \"sequential_1\"\n",
+ "_________________________________________________________________\n",
+ " Layer (type) Output Shape Param # \n",
+ "=================================================================\n",
+ " dense_4 (Dense) (None, 20) 340 \n",
+ " \n",
+ " leaky_re_lu_2 (LeakyReLU) (None, 20) 0 \n",
+ " \n",
+ " dense_5 (Dense) (None, 15) 315 \n",
+ " \n",
+ " re_lu_1 (ReLU) (None, 15) 0 \n",
+ " \n",
+ " dense_6 (Dense) (None, 8) 128 \n",
+ " \n",
+ "=================================================================\n",
+ "Total params: 783\n",
+ "Trainable params: 783\n",
+ "Non-trainable params: 0\n",
+ "_________________________________________________________________\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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TA8ePCAi9YCoTX03186I9N+WmgqIjzt27Bj16NGDANCpU6fUtkdERBAAnX+X9hQQn9g+xOao+jpsbGxw69YtpKamIiMjA2vWrMGaNWtw7NgxDB8+HBUVFQDq+4uA+sttFRcXFxQWFgKoX2zJysoKr776Ko4fPw4AWLt2LQBolb+hVVRUYP/+/WrrAy9atAiVlZXYs2cPAM0LFmmziJGlpSVkMpnQ92ZnZ4fIyEgAQGpqaqvyNjU1xbRp09p85PbWrVuoqqpCnz59mt13xowZeOedd3D58mXMnDkT1OCpetrWd3PtzJhtycvLC+fPn4dMJkN0dLTa9l69egEALly40KblaEtPZR8iAFy9ehUAMHToUOTm5gIAwsLCGl1wXtMfqqWlJWpra4X3n3/+OWbNmgUvLy+hs93Gxkar/A0tIyMDNTU1aiv/qRaEv3btWquPIZFIRO9VfU83b95sdd6GcOfOHQCATCbTav+NGzfil19+QUpKCsLDw/H8888L27St7+bambHbkoODA7y9vZGZmam2TVWeq1evYvz48YYuml48lWeI1dXVOHr0KDp16oTp06cLI9LZ2dlq+z58+FDrfKdMmYLr169j+fLlyMrKwvDhw3HlyhW95a9PqknDGRkZonRVox40aJDej2lubg4LCws8++yzes+7LTg6OkIikeD+/fta7W9iYoL4+HgMGTIEGzZsED3WSl/13R7akqenp8bBLNVVV8OJ6h3JUxkQP/nkEyFwDR06FE5OTjA1NUVERASqq6uF/UpKShAfH69VnuXl5YiJiUH37t2xefNmfPvtt3j06BH27dunl/z1zd3dHRYWFkhPTxell5SUAPi/9XZlMpna1CQiEv7AH9cwraqqSvQ+IyMDcrkcI0eObHXehmBlZYWBAwfi7t27Wn9GJpMhJSUF1tbWooCobX03py3akuryvuFlfmNycnLwxhtvqKUXFxcDQIdYu7oxT2RArKmpERra4+RyOVasWIH169djzZo12LBhAwDA2toaISEhyMzMxNixY7F3717ExsYiKCgIM2bMAAD8/vvvAIDKykohv9raWtTU1EAul0OhUCAiIkIIAh4eHnjuuedgY2OjVf6G1qtXLyxduhQFBQX45ptvhPTk5GT4+flh7NixAIC+fftCLpcjNTUVRITExERkZGSgrKwMZWVlqKurE+akZWVlIS0t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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "latent_dim = 16\n",
+ "generator_model = define_generator(latent_dim)\n",
+ "generator_model.summary()\n",
+ "plot_model(generator_model, to_file = 'generator_model.png', show_shapes = True, show_layer_names = True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The function generates_latent_points generates n points in the latent space. The generate_fake_samples function uses the generator model to generate 'fake' samples."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def generate_latent_points(latent_dim, n):\n",
+ " '''generate points in latent space as input for the generator'''\n",
+ " x_input = np.random.rand(latent_dim*n) #generate points in latent space\n",
+ " x_input = x_input.reshape(n,latent_dim) #reshape\n",
+ " return x_input\n",
+ "\n",
+ "def generate_fake_samples(generator, latent_dim, n):\n",
+ " x_input = generate_latent_points(latent_dim, n) #genarate points in latent space\n",
+ " x = generator.predict(x_input) #predict outputs\n",
+ " y = np.zeros((n, 1))\n",
+ " return x, y"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "As of now, the fake samples produced by the generator is garbage because we haven't trained it yet. It is supposed to closely follow our function after training."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4/4 [==============================] - 0s 688us/step\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "2023-03-01 10:21:39.004994: W tensorflow/tsl/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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qqqqtHTpUhUXF2vKlCl65JFHFI1GnWq27dLph+uvv1779u3rn8o5fPiwdu7cqc9+9rOOtNkLgvb9aJdYLKauri5ff0em68c//rEOHz6surq6YT+XLzbKS8eJEycUjUZVXFyccLy4uFhvvvlm0se0t7cnPb+9vT1j7cykdPrgfMuXL9f48eMHfAn5STr9sGfPHj311FNqaWlxoIXOSKcfDh8+rF27dunzn/+8du7cqUOHDumLX/yizp49a8sXkBvS6Yc77rhDJ06c0MyZM2UYhj744APde++9vp6msSrV92MkEtHf/vY3XXDBBS61zF3r1q3TX//6V91+++1uN8VRf/zjH7VixQr97ne/04gRww8lAjsyguFbu3attm7dqp///OcqKChwuzmO6erq0oIFC7Rp0yaNGzfO7ea4KhaLqaioSD/4wQ80Y8YMzZs3T1/72te0ceNGt5vmqN27d+uRRx7R97//fTU3N+uFF17Qjh07tHr1arebBhdt2bJF9fX1evbZZ1VUVOR2cxwTjUZ1xx13qL6+XpdddpktzxnYkZFx48YpNzdXHR0dCcc7OjpUUlKS9DElJSWWzve6dPogbt26dVq7dq1+85vf6Oqrr85kMzPOaj+8/fbbeuedd1RTU9N/LBaLSZJGjBihgwcPavLkyZltdAak8/dQWlqqkSNHKjc3t//YlVdeqfb2dvX29iovLy+jbc6EdPrhoYce0oIFC3T33XdLkq666ip1d3frC1/4gr72ta8pJyf493Wpvh8LCwuzclRk69atuvvuu/Xcc8/5euQ4HV1dXXr99df1xhtvaNmyZZL6viMNw9CIESP061//WrNmzbL0nIH9LygvL08zZsxQY2Nj/7FYLKbGxkZVVVUlfUxVVVXC+ZL08ssvpzzf69LpA0n61re+pdWrV6uhoUHXXHONE03NKKv9cMUVV+gPf/iDWlpa+n8+97nP9a8iKCsrc7L5tknn7+GGG27QoUOH+oMxSXrrrbdUWlrqy0BESq8fTp8+PSDgiAdoRpZs7xW078fheOaZZ7R48WI988wzuuWWW9xujuMKCwsHfEfee++9uvzyy9XS0qLKykrrT5p26qsPbN261cjPzzeefvppY//+/cYXvvAF46KLLjLa29sNwzCMBQsWGCtWrOg///e//70xYsQIY926dcaBAweMuro6Y+TIkcYf/vAHt97CsFntg7Vr1xp5eXnG888/b7S1tfX/dHV1ufUWbGG1H84XlNU0Vvvh6NGjxujRo41ly5YZBw8eNH75y18aRUVFxje+8Q233oItrPZDXV2dMXr0aOOZZ54xDh8+bPz61782Jk+ebNx+++1uvYVh6+rqMt544w3jjTfeMCQZjz/+uPHGG28Y7777rmEYhrFixQpjwYIF/ecfPnzYGDVqlPEf//EfxoEDB4wNGzYYubm5RkNDg1tvwRZW++FnP/uZMWLECGPDhg0J35GnTp1y6y3Ywmo/nG+4q2kCHYwYhmF873vfMy655BIjLy/PqKioMF577bX+f7vpppuMRYsWJZz/7LPPGpdddpmRl5dnfPKTnzR27NjhcIvtZ6UPPv7xjxuSBvzU1dU533CbWf1bOFdQghHDsN4Pr776qlFZWWnk5+cbl156qfHNb37T+OCDDxxutf2s9MPZs2eNVatWGZMnTzYKCgqMsrIy44tf/KLxl7/8xfmG2+SVV15J+t96/H0vWrTIuOmmmwY8Ztq0aUZeXp5x6aWXGj/+8Y8db7fdrPbDTTfdNOj5fpXO38O5hhuMhAwjS8YYAQCAJwU2ZwQAAPgDwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHAVwQgAAHDV/w8HYAqsYvwFkAAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "X, _ = generate_fake_samples(generator_model, latent_dim, 100)\n",
+ "plt.scatter(X[:,0], X[:,1])\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The function below combines the generator and discriminator models. The layers of the discriminator model are made non-trainable( because we do not want to update it's weights during the training of the generator). Here, the discriminator's only job is to classify real and fake samples."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def define_gan(generator, discriminator):\n",
+ " '''define the combined generator and discriminator model'''\n",
+ " discriminator.trainable = False\n",
+ " model = Sequential()\n",
+ " model.add(generator)\n",
+ " model.add(discriminator)\n",
+ " model.compile(optimizer = 'adam', loss = 'binary_crossentropy')\n",
+ " return model"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Model: \"sequential_2\"\n",
+ "_________________________________________________________________\n",
+ " Layer (type) Output Shape Param # \n",
+ "=================================================================\n",
+ " sequential_1 (Sequential) (None, 8) 783 \n",
+ " \n",
+ " sequential (Sequential) (None, 1) 581 \n",
+ " \n",
+ "=================================================================\n",
+ "Total params: 1,364\n",
+ "Trainable params: 783\n",
+ "Non-trainable params: 581\n",
+ "_________________________________________________________________\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 10,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "gan_model = define_gan(generator_model, discriminator_model)\n",
+ "gan_model.summary()\n",
+ "plot_model(gan_model, to_file = 'gan_model.png', show_layer_names = True, show_shapes = True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We want the discriminator model to believe that the samples generated by the generator are real, so we label them as '1'(real). In the ideal case, the discriminator is fooled about half of the times into believing that the samples generated by the generator are real."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[0. , 0. , 0. , 0.16666667, 0.76119403,\n",
+ " 0.00638298, 0. , 0. ],\n",
+ " [0.06288533, 0. , 0.07142857, 0.16666667, 0.10447761,\n",
+ " 0.03191489, 0.02059202, 0.09900091],\n",
+ " [0.09371147, 0.375 , 0.12142857, 0.19444444, 0.23880597,\n",
+ " 0.01276596, 0.03732304, 0.49682107],\n",
+ " [0.10372996, 0.453125 , 0.22857143, 0.38888889, 0.56716418,\n",
+ " 0.05319149, 0.08236808, 0.61762035],\n",
+ " [0.10835388, 0.21875 , 0.38571429, 0.33333333, 0.55223881,\n",
+ " 0.09361702, 0.0990991 , 0.45413261],\n",
+ " [0.10989519, 0.21875 , 0.39285714, 0.36111111, 0.55223881,\n",
+ " 0.09361702, 0.09395109, 0.41871026],\n",
+ " [0.11374846, 0.21875 , 0.08571429, 0.2 , 0.14029851,\n",
+ " 0.10638298, 0.11454311, 0.50045413],\n",
+ " [0.12530826, 0.21875 , 0.24285714, 0.27777778, 0.28358209,\n",
+ " 0.11914894, 0.10682111, 0.36784741],\n",
+ " [0.14842787, 0.0625 , 0.34285714, 0.5 , 0.55223881,\n",
+ " 0.22553191, 0.15572716, 0.22615804],\n",
+ " [0.15844636, 0.21875 , 0.12857143, 0.22222222, 0.13432836,\n",
+ " 0.11489362, 0.11969112, 0.35876476],\n",
+ " [0.1777127 , 0.35 , 0.31428571, 0.38888889, 0.32835821,\n",
+ " 0.15106383, 0.18790219, 0.72752044],\n",
+ " [0.19389642, 0.296875 , 0.4 , 0.55555556, 0.52238806,\n",
+ " 0.13829787, 0.17245817, 0.67938238],\n",
+ " [0.20391492, 0.375 , 0.34285714, 0.5 , 0.55223881,\n",
+ " 0.15744681, 0.17503218, 0.82379655],\n",
+ " [0.20930949, 0.375 , 0.45714286, 0.61111111, 0.70149254,\n",
+ " 0.15744681, 0.18146718, 0.89191644],\n",
+ " [0.33107275, 0.375 , 0.49285714, 0.75 , 0.55223881,\n",
+ " 0.26170213, 0.28314028, 0.67938238],\n",
+ " [0.43356967, 0.375 , 0.58571429, 0.77777778, 0.76119403,\n",
+ " 0.45957447, 0.45302445, 0.62761126],\n",
+ " [0.46824908, 0.375 , 0.58571429, 0.66666667, 0.55223881,\n",
+ " 0.45106383, 0.46460746, 0.68483197],\n",
+ " [1. , 0.375 , 1. , 0.72222222, 0.55223881,\n",
+ " 1. , 1. , 0.63669391],\n",
+ " [0.36035758, 0.25 , 0.9 , 1. , 1. ,\n",
+ " 0.33191489, 0.33590734, 0.55495005],\n",
+ " [0.21393342, 0.375 , 0.35714286, 0.23777778, 0.18089552,\n",
+ " 0.22553191, 0.11711712, 0.23705722],\n",
+ " [0.49907522, 0.21875 , 0.64285714, 0.41222222, 0.37313433,\n",
+ " 0.45106383, 0.33590734, 0.41871026],\n",
+ " [0.73027127, 1. , 0.74285714, 0.47222222, 0.43283582,\n",
+ " 0.54468085, 0.63191763, 1. ],\n",
+ " [0.06750925, 0.3375 , 0.04285714, 0. , 0. ,\n",
+ " 0. , 0.003861 , 0.00999092]])"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "dfs.iloc[:,1:].values"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The train_gan function simultaneously trains the discriminator and the GAN."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def train_gan(g_model,d_model,gan_model,latent_dim, num_epochs = 1000,num_eval = 1000, batch_size = 2):\n",
+ " ''' function to train gan model'''\n",
+ " half_batch = 1\n",
+ " #run epochs\n",
+ " for i in range(num_epochs):\n",
+ " X_real, y_real = dfs.iloc[:,1:].values, np.ones((23, 1)) #generate real examples\n",
+ " d_model.train_on_batch(X_real, y_real) # train on real data\n",
+ " X_fake, y_fake = generate_fake_samples(g_model, latent_dim, half_batch) #generate fake samples\n",
+ " d_model.train_on_batch(X_fake, y_fake) #train on fake data\n",
+ " #prepare points in latent space as input for the generator\n",
+ " x_gan = generate_latent_points(latent_dim, batch_size)\n",
+ " y_gan = np.ones((batch_size, 1)) #generate fake labels for gan\n",
+ " gan_model.train_on_batch(x_gan, y_gan)\n",
+ " if (i+1) % num_eval == 0:\n",
+ " summarize_performance(i + 1, g_model, d_model, latent_dim)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The function defined below is called every two thousand epochs to summarize the performance of the training."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def summarize_performance(epoch, generator, discriminator, latent_dim, n = 200):\n",
+ " '''evaluate the discriminator and plot real and fake samples'''\n",
+ " x_real, y_real = dfs.iloc[:,1:].values, np.ones((23, 1))\n",
+ " _, acc_real = discriminator.evaluate(x_real, y_real, verbose = 1)\n",
+ " x_fake, y_fake = generate_fake_samples(generator, latent_dim, n)\n",
+ " _, acc_fake = discriminator.evaluate(x_fake, y_fake, verbose = 1)\n",
+ " print('Epoch: ' + str(epoch) + ' Real Acc.: ' + str(acc_real) + ' Fake Acc.: '+ str(acc_fake))\n",
+ " # x_real /= np.max(np.abs(x_real),axis=0)\n",
+ " plt.scatter(x_real[:,0], x_real[:,1], color = 'red')\n",
+ " plt.scatter(x_fake[:,0], x_fake[:,1], color = 'blue',s=20)\n",
+ " plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 29,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 28ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 30ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 8ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 18ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 20ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 16ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step - loss: 0.1332 - accuracy: 0.7826\n",
+ "7/7 [==============================] - 0s 396us/step\n",
+ "7/7 [==============================] - 0s 615us/step - loss: 0.1625 - accuracy: 0.7300\n",
+ "Epoch: 1000 Real Acc.: 0.782608687877655 Fake Acc.: 0.7300000190734863\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi8AAAGdCAYAAADaPpOnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABI20lEQVR4nO3dfXRU1b0H/O9kJIPeS14UCAGiPJCE1perAiWNEik0OhEXtQ+3S66xgF6FqwVr5T61oCi1WnFZddkiauHWi/d5SoIi+FgNQUKJiKBQIM+yggwBvISXpEIwQdRAJvv54zDDzOTMeZvzOvP9rDVLc+acOfucGWb/Zu/929snhBAgIiIi8ogspwtAREREpAeDFyIiIvIUBi9ERETkKQxeiIiIyFMYvBAREZGnMHghIiIiT2HwQkRERJ7C4IWIiIg85QKnC2C2np4eHD16FP369YPP53O6OERERKSBEAKnTp3C4MGDkZWl3LaSdsHL0aNHUVRU5HQxiIiIyICWlhYMHTpUcZ+0C1769esHQLr4nJwch0tDREREWnR2dqKoqChajytJu+Al0lWUk5PD4IWIiMhjtAz54IBdIiIi8hQGL0REROQpDF6IiIjIUxi8EBERkacweCEiIiJPYfBCREREnsLghYiIiDyFwQsRERF5CoMXIiIi8pS0m2GXyKhQCNi/HyguBkpKnC4NERElw5YXynjt7UBVFTByJDBpElBaKv198qTTJSMiIjkMXijjVVcDDQ3x2xoagNtvd6Y8RESkjMELZbRQCFi3DgiH47eHw9L2ffucKRcRESXH4IUy2v79ys83N9tTDiIi0o7BC2W0ESOUny8utqccRESkHYMXymilpUAwCPj98dv9fmk7s46IiNyHwQtlvJoaoLIyfltlpbSdiIjch/O8UMbLzwfq66XBuc3NnOeFiMjtGLwQnVNSwqCFiMgL2G1EREREnsLghYiIiDyFwQsRERF5CoMXIiIi8hQGL0REROQpDF6IiIjIUxi8EBERkacweCEiIiJPYfBCREREnsLghYiIiDyFwQsRERF5CoMXIiIi8hQGL0REROQpDF6IiIjIUxi8EBERkacweCEiIiJPYfBCREREnmJp8LJp0yZMnjwZgwcPhs/nw1tvvaW4/+rVq3HjjTdiwIAByMnJQXl5OdatW2dlEYmIiMhjLA1eTp8+jauvvhpLlizRtP+mTZtw4403oq6uDjt27MCECRMwefJk7Nq1y8piEhERkYf4hBDClhP5fFizZg1+/OMf6zruiiuuwNSpU/HYY49p2r+zsxO5ubno6OhATk6OgZKSnUIhYP9+oLgYKClxujREROQUPfX3BTaVyZCenh6cOnUKF198cdJ9urq60NXVFf27s7PTjqJRitrbgepqILZXMBgEamqA/HznykVERO7n6gG7zz77LL766ivcdtttSfdZtGgRcnNzo4+ioiIbS0hGVVcDDQ3x2xoagNtvd6Y8RETkHa4NXlasWIHHH38cr7/+OgYOHJh0v/nz56OjoyP6aGlpsbGUZEQoJLW4hMPx28Nhafu+fc6Ui4iIvMGV3Ua1tbW455578MYbb6CyslJx30AggEAgYFPJyAz79ys/39zM8S9ERJSc61peampqcNddd6Gmpga33HKL08UhC4wYofx8cbE95SAiIm+yNHj56quv0NTUhKamJgDAwYMH0dTUhEOHDgGQunymT58e3X/FihWYPn06nnvuOZSVlaG1tRWtra3o6Oiwsphks9JSaXCu3x+/3e+XtrPVhYiIlFgavPztb3/Dtddei2uvvRYAMHfuXFx77bXRtOdjx45FAxkAWLp0Kbq7uzF79mwUFhZGHw888ICVxSQH1NQAiT2ClZXSdiIiIiW2zfNiF87z4i379kljXDjPC6WC8wUReV/azPNC6a+khJUNGcf5gogyk+sG7BIRacX5gogyE4MXIvIkzhdElLkYvBCRJ2mZL4iI0hODFyLyJM4XRJS5GLwQkSdxviCizMXghYg8i/MFEWUmpkoTkWfl5wP19ZwviCjTMHghIs/jfEFEmYXdRkREROQpDF6IiIjIUxi8EBERkacweCEiIiJPYfBCREREnsLghYiIiDyFwQsRERF5CoMXIiIi8hQGL0REROQpDF6IiIjIUxi8EBERkacweCEiIiJPYfBCREREnsLghYiIiDyFwQsRERF5ygVOF4CISE0oBOzfDxQXAyUlTpeGiJzGlhcicq32dqCqChg5Epg0CSgtlf4+edLpkhGRkxi8EJFrVVcDDQ3x2xoagNtvd6Y8ROQODF6IyJVCIWDdOiAcjt8eDkvb9+1zplxE5DwGL0TkSvv3Kz/f3GxPOYjIfRi8EJErjRih/HxxsT3lICL3YfBCRK5UWgoEg4DfH7/d75e2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i5XF9Ay993P//v34/PPPMXny5Oi2np4eAMAFF1yAvXv3YsSIEdYW2uWMfEYLCwvRp08f+P3+6Lbvfve7aG1txZkzZ5CdnW1pmd3OyD199NFHMW3aNNxzzz0AgKuuugqnT5/GrFmz8MgjjyAri7/p9UhWN+Xk5FjW6gKw5cUR2dnZGD16NDZs2BDd1tPTgw0bNqC8vFz2mPLy8rj9AWD9+vVJ9880Ru4pADzzzDN44oknUF9fjzFjxthRVE/Qez+/853v4JNPPkFTU1P08aMf/QgTJkxAU1MTioqK7Cy+Kxn5jF5//fVobm6OBoIAEAqFUFhYmPGBC2Dsnn799de9ApRIcCi41J9ujtVNlg4HpqRqa2tFIBAQy5cvF7t37xazZs0SeXl5orW1VQghxLRp08S8efOi+3/44YfiggsuEM8++6zYs2ePWLhwIVOlE+i9p08//bTIzs4Wq1atEseOHYs+Tp065dQluIre+5mI2Ua96b2nhw4dEv369RNz5swRe/fuFe+8844YOHCgePLJJ526BNfRe08XLlwo+vXrJ2pqasSBAwfEe++9J0aMGCFuu+02py7BVU6dOiV27doldu3aJQCI559/XuzatUv87//+rxBCiHnz5olp06ZF94+kSv/yl78Ue/bsEUuWLGGqdLpbvHixuPTSS0V2drYYO3as+Oijj6LPjR8/XsyYMSNu/9dff12UlpaK7OxsccUVV4h3333X5hK7n557etlllwkAvR4LFy60v+AupfczGovBizy993TLli2irKxMBAIBMXz4cPHb3/5WdHd321xqd9NzT8+ePSt+/etfixEjRoi+ffuKoqIi8bOf/UycPHnS/oK70MaNG2W/FyP3cMaMGWL8+PG9jrnmmmtEdna2GD58uPjv//5vy8vpE4LtZEREROQdHPNCREREnsLghYiIiDyFwQsRERF5CoMXIiIi8hQGL0REROQpDF6IiIjIUxi8EBERkacweCEiIiJPYfBCREREnsLghYiIiDyFwQsRERF5CoMXIiIi8pT/HwbKDhDKLN//AAAAAElFTkSuQmCC",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "train_gan(generator_model, discriminator_model, gan_model, latent_dim)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def predict(n):\n",
+ " x_fake, y_fake = generate_fake_samples(generator_model, latent_dim, n)\n",
+ " return x_fake, y_fake"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4/4 [==============================] - 0s 583us/step\n"
+ ]
+ }
+ ],
+ "source": [
+ "x,y=predict(100)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "array([[0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.],\n",
+ " [0.]])"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "y"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 48,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "(10,)"
+ ]
+ },
+ "execution_count": 48,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "x[:,7][x[:,7]>0][:10].shape"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 49,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 49,
+ "metadata": {},
+ "output_type": "execute_result"
+ },
+ {
+ "data": {
+ "image/png": "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yUZE4khgBQAARhGMAAAAo/I6GCksLNTatWtVWFhouim+xnV2DtfaGVxnZ3CdneGG6+yJBFYAAOBfeT0yAgAAzCMYAQAARhGMAAAAowhGAACAUb4PRrZs2aLq6moVFRWpvr5er7/+etLjf/rTn+rKK69UUVGR5syZo927dzvUUm+zc523b9+um266SZdddpkuu+wyNTQ0jPt7wYfs/k3H7dy5U4FAQLfffntuG+gTdq/z+++/r5UrV2ratGkqLCzUxz72Mb4/UmD3Om/atEmzZ8/WxIkTVVlZqVWrVunPf/6zQ631pl/+8pdavHixpk+frkAgoBdeeGHcc/bt26frrrtOhYWFmjVrln70ox/ltpGWj+3cudMqKCiwnnnmGeutt96y7rrrLuvSSy+1+vr6xjz+17/+tRUKhawnnnjCevvtt62HH37YuuSSS6yOjg6HW+4tdq/zHXfcYW3ZssV68803rc7OTusf/uEfrNLSUuvdd991uOXeY/dax3V1dVkzZsywbrrpJutv//ZvnWmsh9m9zqdPn7bmzZtn3XrrrdZrr71mdXV1Wfv27bMOHDjgcMu9xe51/vGPf2wVFhZaP/7xj62uri7rlVdesaZNm2atWrXK4ZZ7y+7du62HHnrIeu655yxJ1vPPP5/0+KNHj1qTJk2ympubrbffftv67ne/a4VCIautrS1nbfR1MDJ//nxr5cqVw4+j0ag1ffp0a/369WMev2TJEuu2224b8Vx9fb21YsWKnLbT6+xe59HOnj1rlZSUWDt27MhVE30jnWt99uxZ64YbbrB+8IMfWMuXLycYSYHd6/y9733PuuKKK6wzZ8441URfsHudV65caf31X//1iOeam5utG2+8Maft9JNUgpGvfe1r1ic+8YkRzy1dutRatGhRztrl22maM2fOqL29XQ0NDcPPBYNBNTQ0aP/+/WOes3///hHHS9KiRYsSHo/0rvNoJ0+e1AcffKCPfOQjuWqmL6R7rb/xjW+ovLxcX/ziF51opuelc51/9rOfacGCBVq5cqUqKip01VVXad26dYpGo04123PSuc433HCD2tvbh6dyjh49qt27d+vWW291pM35wkRf6ImN8tJx/PhxRaNRVVRUjHi+oqJCBw8eHPOc3t7eMY/v7e3NWTu9Lp3rPNoDDzyg6dOnX/THj5HSudavvfaafvjDH+rAgQMOtNAf0rnOR48e1X/913/p7//+77V7924dPnxYX/nKV/TBBx9o7dq1TjTbc9K5znfccYeOHz+uT37yk7IsS2fPntU999yjBx980Ikm541EfWEkEtGpU6c0ceLErL+nb0dG4A0bNmzQzp079fzzz6uoqMh0c3xlYGBATU1N2r59u6ZMmWK6Ob4Wi8VUXl6u73//+6qrq9PSpUv10EMPaevWraab5iv79u3TunXr9PTTT+uNN97Qc889p5dfflmPPfaY6aYhQ74dGZkyZYpCoZD6+vpGPN/X16epU6eOec7UqVNtHY/0rnPck08+qQ0bNmjPnj2aO3duLpvpC3av9ZEjR9Td3a3FixcPPxeLxSRJEyZM0KFDh1RTU5PbRntQOn/T06ZN0yWXXKJQKDT8XG1trXp7e3XmzBkVFBTktM1elM51fuSRR9TU1KQvfelLkqQ5c+ZoaGhId999tx566CEFg9xfZ0OivjAcDudkVETy8chIQUGB6urqtHfv3uHnYrGY9u7dqwULFox5zoIFC0YcL0m/+MUvEh6P9K6zJD3xxBN67LHH1NbWpnnz5jnRVM+ze62vvPJKdXR06MCBA8M/n/3sZ3XLLbfowIEDqqysdLL5npHO3/SNN96ow4cPDwd7kvS73/1O06ZNIxBJIJ3rfPLkyYsCjngAaLHNWtYY6QtzlhrrAjt37rQKCwutH/3oR9bbb79t3X333dall15q9fb2WpZlWU1NTdbq1auHj//1r39tTZgwwXryySetzs5Oa+3atSztTYHd67xhwwaroKDAevbZZ60//elPwz8DAwOmPoJn2L3Wo7GaJjV2r3NPT49VUlJi3XvvvdahQ4esl156ySovL7e++c1vmvoInmD3Oq9du9YqKSmx/v3f/906evSo9Z//+Z9WTU2NtWTJElMfwRMGBgasN99803rzzTctSdbGjRutN9980/r9739vWZZlrV692mpqaho+Pr6096tf/arV2dlpbdmyhaW9mfrud79rVVVVWQUFBdb8+fOt3/72t8P/tnDhQmv58uUjjm9tbbU+9rGPWQUFBdYnPvEJ6+WXX3a4xd5k5zr/xV/8hSXpop+1a9c633APsvs3fSGCkdTZvc6/+c1vrPr6equwsNC64oorrMcff9w6e/asw632HjvX+YMPPrD+5V/+xaqpqbGKioqsyspK6ytf+Yr1f//3f8433EP++7//e8zv3Pi1Xb58ubVw4cKLzrnmmmusgoIC64orrrD+7d/+LadtDFgWY1sAAMAc3+aMAAAAbyAYAQAARhGMAAAAowhGAACAUQQjAADAKIIRAABgFMEIAAAwimAEAAAYRTACAACMIhgBAABGEYwAAACjCEYAAIBR/z8RXFSxvniDCgAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plt.scatter(x[:,2][x[:,2]>0],x[:,7][x[:,7]>0][:76],c='gray')\n",
+ "plt.scatter(dfs.iloc[:,3],dfs.iloc[:,-1],s=7)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 31,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " Name \n",
+ " U \n",
+ " d \n",
+ " h \n",
+ " j \n",
+ " Isp \n",
+ " nu_t \n",
+ " T \n",
+ " m_a \n",
+ " \n",
+ " \n",
+ " \n",
+ " \n",
+ " 0 \n",
+ " SPT-20 [21] \n",
+ " 52.400000 \n",
+ " 180.000000 \n",
+ " 15.000000 \n",
+ " 5.000000 \n",
+ " 32.000000 \n",
+ " 0.470000 \n",
+ " 3.900000 \n",
+ " 839.000000 \n",
+ " \n",
+ " \n",
+ " 1 \n",
+ " SPT-25 [22] \n",
+ " 134.000000 \n",
+ " 180.000000 \n",
+ " 20.000000 \n",
+ " 5.000000 \n",
+ " 10.000000 \n",
+ " 0.590000 \n",
+ " 5.500000 \n",
+ " 948.000000 \n",
+ " \n",
+ " \n",
+ " 2 \n",
+ " HET-100 [23] \n",
+ " 174.000000 \n",
+ " 300.000000 \n",
+ " 23.500000 \n",
+ " 5.500000 \n",
+ " 14.500000 \n",
+ " 0.500000 \n",
+ " 6.800000 \n",
+ " 1386.000000 \n",
+ " \n",
+ " \n",
+ " 3 \n",
+ " KHT-40 [24] \n",
+ " 187.000000 \n",
+ " 325.000000 \n",
+ " 31.000000 \n",
+ " 9.000000 \n",
+ " 25.500000 \n",
+ " 0.690000 \n",
+ " 10.300000 \n",
+ " 1519.000000 \n",
+ " \n",
+ " \n",
+ " 4 \n",
+ " KHT-50 [24] \n",
+ " 193.000000 \n",
+ " 250.000000 \n",
+ " 42.000000 \n",
+ " 8.000000 \n",
+ " 25.000000 \n",
+ " 0.880000 \n",
+ " 11.600000 \n",
+ " 1339.000000 \n",
+ " \n",
+ " \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " ... \n",
+ " \n",
+ " \n",
+ " 95 \n",
+ " NaN \n",
+ " 0.508939 \n",
+ " -0.354882 \n",
+ " 0.747163 \n",
+ " 0.191082 \n",
+ " 1.318361 \n",
+ " 0.262004 \n",
+ " 0.210962 \n",
+ " 0.839841 \n",
+ " \n",
+ " \n",
+ " 96 \n",
+ " NaN \n",
+ " -0.127709 \n",
+ " -0.398011 \n",
+ " 1.063189 \n",
+ " 1.168259 \n",
+ " 1.512382 \n",
+ " 0.259802 \n",
+ " 0.314027 \n",
+ " 0.882875 \n",
+ " \n",
+ " \n",
+ " 97 \n",
+ " NaN \n",
+ " 0.979954 \n",
+ " -0.023562 \n",
+ " 1.216619 \n",
+ " 0.557483 \n",
+ " 1.534266 \n",
+ " -0.189749 \n",
+ " 0.736419 \n",
+ " 1.130576 \n",
+ " \n",
+ " \n",
+ " 98 \n",
+ " NaN \n",
+ " 0.027803 \n",
+ " -0.496064 \n",
+ " 1.156737 \n",
+ " 1.343929 \n",
+ " 1.987885 \n",
+ " 0.098937 \n",
+ " 1.031702 \n",
+ " 0.915652 \n",
+ " \n",
+ " \n",
+ " 99 \n",
+ " NaN \n",
+ " 0.323144 \n",
+ " -0.311483 \n",
+ " 1.114895 \n",
+ " 1.247261 \n",
+ " 1.822533 \n",
+ " -0.067361 \n",
+ " 0.989002 \n",
+ " 1.152484 \n",
+ " \n",
+ " \n",
+ "
\n",
+ "
123 rows × 9 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Name U d h j Isp \\\n",
+ "0 SPT-20 [21] 52.400000 180.000000 15.000000 5.000000 32.000000 \n",
+ "1 SPT-25 [22] 134.000000 180.000000 20.000000 5.000000 10.000000 \n",
+ "2 HET-100 [23] 174.000000 300.000000 23.500000 5.500000 14.500000 \n",
+ "3 KHT-40 [24] 187.000000 325.000000 31.000000 9.000000 25.500000 \n",
+ "4 KHT-50 [24] 193.000000 250.000000 42.000000 8.000000 25.000000 \n",
+ ".. ... ... ... ... ... ... \n",
+ "95 NaN 0.508939 -0.354882 0.747163 0.191082 1.318361 \n",
+ "96 NaN -0.127709 -0.398011 1.063189 1.168259 1.512382 \n",
+ "97 NaN 0.979954 -0.023562 1.216619 0.557483 1.534266 \n",
+ "98 NaN 0.027803 -0.496064 1.156737 1.343929 1.987885 \n",
+ "99 NaN 0.323144 -0.311483 1.114895 1.247261 1.822533 \n",
+ "\n",
+ " nu_t T m_a \n",
+ "0 0.470000 3.900000 839.000000 \n",
+ "1 0.590000 5.500000 948.000000 \n",
+ "2 0.500000 6.800000 1386.000000 \n",
+ "3 0.690000 10.300000 1519.000000 \n",
+ "4 0.880000 11.600000 1339.000000 \n",
+ ".. ... ... ... \n",
+ "95 0.262004 0.210962 0.839841 \n",
+ "96 0.259802 0.314027 0.882875 \n",
+ "97 -0.189749 0.736419 1.130576 \n",
+ "98 0.098937 1.031702 0.915652 \n",
+ "99 -0.067361 0.989002 1.152484 \n",
+ "\n",
+ "[123 rows x 9 columns]"
+ ]
+ },
+ "execution_count": 31,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pd.concat([df,pd.DataFrame(x,columns=df.columns[1:])])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "os.chdir('..')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "/Users/apsys/Downloads/hetfit2/utils/data_augmentation.py:32: FutureWarning: In a future version of pandas all arguments of concat except for the argument 'objs' will be keyword-only.\n",
+ " dfs = pd.concat([local.Name,dfs],1)\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " Name U d h j Isp nu_t \\\n",
+ "0 SPT-20 [21] 0.000000 0.000000 0.000000 0.166667 0.761194 0.006383 \n",
+ "1 SPT-25 [22] 0.062885 0.000000 0.071429 0.166667 0.104478 0.031915 \n",
+ "2 HET-100 [23] 0.093711 0.375000 0.121429 0.194444 0.238806 0.012766 \n",
+ "3 KHT-40 [24] 0.103730 0.453125 0.228571 0.388889 0.567164 0.053191 \n",
+ "4 KHT-50 [24] 0.108354 0.218750 0.385714 0.333333 0.552239 0.093617 \n",
+ "\n",
+ " T m_a \n",
+ "0 0.000000 0.000000 \n",
+ "1 0.020592 0.099001 \n",
+ "2 0.037323 0.496821 \n",
+ "3 0.082368 0.617620 \n",
+ "4 0.099099 0.454133 \n",
+ "1/1 [==============================] - 0s 39ms/step\n"
+ ]
+ },
+ {
+ "name": "stderr",
+ "output_type": "stream",
+ "text": [
+ "2023-02-20 20:36:55.213546: W tensorflow/tsl/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 30ms/step\n",
+ "1/1 [==============================] - 0s 17ms/step\n",
+ "1/1 [==============================] - 0s 14ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 15ms/step\n",
+ "1/1 [==============================] - 0s 16ms/step\n",
+ "1/1 [==============================] - 0s 17ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 19ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 12ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 13ms/step\n",
+ "1/1 [==============================] - 0s 11ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 10ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n",
+ "1/1 [==============================] - 0s 9ms/step\n"
+ ]
+ },
+ {
+ "ename": "KeyboardInterrupt",
+ "evalue": "",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[0;32mIn [5], line 3\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[39mfrom\u001b[39;00m \u001b[39mdata_augmentation\u001b[39;00m \u001b[39mimport\u001b[39;00m dataset\n\u001b[1;32m 2\u001b[0m obj \u001b[39m=\u001b[39m dataset(\u001b[39m1000\u001b[39m,\u001b[39m'\u001b[39m\u001b[39mnew\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[0;32m----> 3\u001b[0m obj\u001b[39m.\u001b[39;49mgenerate()\n",
+ "File \u001b[0;32m~/Downloads/hetfit2/utils/data_augmentation.py:36\u001b[0m, in \u001b[0;36mdataset.generate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 32\u001b[0m dfs \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39mconcat([local\u001b[39m.\u001b[39mName,dfs],\u001b[39m1\u001b[39m)\n\u001b[1;32m 34\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mvae \u001b[39m=\u001b[39m DCGAN(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlatent_dim,dfs)\n\u001b[0;32m---> 36\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mvae\u001b[39m.\u001b[39;49mstart_training()\n\u001b[1;32m 37\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msamples \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mvae\u001b[39m.\u001b[39mpredict(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39msample_size)\n\u001b[1;32m 38\u001b[0m \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39mSamples:\u001b[39m\u001b[39m\"\u001b[39m,\u001b[39mself\u001b[39m\u001b[39m.\u001b[39msamples)\n",
+ "File \u001b[0;32m~/Downloads/hetfit2/utils/ndgan.py:99\u001b[0m, in \u001b[0;36mDCGAN.start_training\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 98\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mstart_training\u001b[39m(\u001b[39mself\u001b[39m):\n\u001b[0;32m---> 99\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mtrain_gan(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mgenerator_model, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mdiscriminator_model, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mgan_model, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mlatent)\n",
+ "File \u001b[0;32m~/Downloads/hetfit2/utils/ndgan.py:89\u001b[0m, in \u001b[0;36mDCGAN.train_gan\u001b[0;34m(self, g_model, d_model, gan_model, latent_dim, num_epochs, num_eval, batch_size)\u001b[0m\n\u001b[1;32m 87\u001b[0m X_real, y_real \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdfs\u001b[39m.\u001b[39miloc[:,\u001b[39m1\u001b[39m:]\u001b[39m.\u001b[39mvalues, np\u001b[39m.\u001b[39mones((\u001b[39m23\u001b[39m, \u001b[39m1\u001b[39m)) \u001b[39m#generate real examples\u001b[39;00m\n\u001b[1;32m 88\u001b[0m d_model\u001b[39m.\u001b[39mtrain_on_batch(X_real, y_real) \u001b[39m# train on real data\u001b[39;00m\n\u001b[0;32m---> 89\u001b[0m X_fake, y_fake \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mgenerate_fake_samples(g_model, latent_dim, half_batch) \u001b[39m#generate fake samples\u001b[39;00m\n\u001b[1;32m 90\u001b[0m d_model\u001b[39m.\u001b[39mtrain_on_batch(X_fake, y_fake) \u001b[39m#train on fake data\u001b[39;00m\n\u001b[1;32m 91\u001b[0m \u001b[39m#prepare points in latent space as input for the generator\u001b[39;00m\n",
+ "File \u001b[0;32m~/Downloads/hetfit2/utils/ndgan.py:56\u001b[0m, in \u001b[0;36mDCGAN.generate_fake_samples\u001b[0;34m(self, generator, latent_dim, n)\u001b[0m\n\u001b[1;32m 54\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mgenerate_fake_samples\u001b[39m(\u001b[39mself\u001b[39m,generator, latent_dim, n):\n\u001b[1;32m 55\u001b[0m x_input \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mgenerate_latent_points(latent_dim, n) \u001b[39m#genarate points in latent space\u001b[39;00m\n\u001b[0;32m---> 56\u001b[0m x \u001b[39m=\u001b[39m generator\u001b[39m.\u001b[39;49mpredict(x_input) \u001b[39m#predict outputs\u001b[39;00m\n\u001b[1;32m 57\u001b[0m y \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mzeros((n, \u001b[39m1\u001b[39m))\n\u001b[1;32m 58\u001b[0m \u001b[39mreturn\u001b[39;00m x, y\n",
+ "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/keras/utils/traceback_utils.py:65\u001b[0m, in \u001b[0;36mfilter_traceback..error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 63\u001b[0m filtered_tb \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m 64\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m---> 65\u001b[0m \u001b[39mreturn\u001b[39;00m fn(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 66\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mException\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[1;32m 67\u001b[0m filtered_tb \u001b[39m=\u001b[39m _process_traceback_frames(e\u001b[39m.\u001b[39m__traceback__)\n",
+ "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/keras/engine/training.py:2346\u001b[0m, in \u001b[0;36mModel.predict\u001b[0;34m(self, x, batch_size, verbose, steps, callbacks, max_queue_size, workers, use_multiprocessing)\u001b[0m\n\u001b[1;32m 2344\u001b[0m callbacks\u001b[39m.\u001b[39mon_predict_begin()\n\u001b[1;32m 2345\u001b[0m batch_outputs \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m\n\u001b[0;32m-> 2346\u001b[0m \u001b[39mfor\u001b[39;00m _, iterator \u001b[39min\u001b[39;00m data_handler\u001b[39m.\u001b[39menumerate_epochs(): \u001b[39m# Single epoch.\u001b[39;00m\n\u001b[1;32m 2347\u001b[0m \u001b[39mwith\u001b[39;00m data_handler\u001b[39m.\u001b[39mcatch_stop_iteration():\n\u001b[1;32m 2348\u001b[0m \u001b[39mfor\u001b[39;00m step \u001b[39min\u001b[39;00m data_handler\u001b[39m.\u001b[39msteps():\n",
+ "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/keras/engine/data_adapter.py:1304\u001b[0m, in \u001b[0;36mDataHandler.enumerate_epochs\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1302\u001b[0m \u001b[39m\"\"\"Yields `(epoch, tf.data.Iterator)`.\"\"\"\u001b[39;00m\n\u001b[1;32m 1303\u001b[0m \u001b[39mwith\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_truncate_execution_to_epoch():\n\u001b[0;32m-> 1304\u001b[0m data_iterator \u001b[39m=\u001b[39m \u001b[39miter\u001b[39;49m(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_dataset)\n\u001b[1;32m 1305\u001b[0m \u001b[39mfor\u001b[39;00m epoch \u001b[39min\u001b[39;00m \u001b[39mrange\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_initial_epoch, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_epochs):\n\u001b[1;32m 1306\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_insufficient_data: \u001b[39m# Set by `catch_stop_iteration`.\u001b[39;00m\n",
+ "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/tensorflow/python/data/ops/dataset_ops.py:499\u001b[0m, in \u001b[0;36mDatasetV2.__iter__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 497\u001b[0m \u001b[39mif\u001b[39;00m context\u001b[39m.\u001b[39mexecuting_eagerly() \u001b[39mor\u001b[39;00m ops\u001b[39m.\u001b[39minside_function():\n\u001b[1;32m 498\u001b[0m \u001b[39mwith\u001b[39;00m ops\u001b[39m.\u001b[39mcolocate_with(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_variant_tensor):\n\u001b[0;32m--> 499\u001b[0m \u001b[39mreturn\u001b[39;00m iterator_ops\u001b[39m.\u001b[39;49mOwnedIterator(\u001b[39mself\u001b[39;49m)\n\u001b[1;32m 500\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 501\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39m`tf.data.Dataset` only supports Python-style \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 502\u001b[0m \u001b[39m\"\u001b[39m\u001b[39miteration in eager mode or within tf.function.\u001b[39m\u001b[39m\"\u001b[39m)\n",
+ "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/tensorflow/python/data/ops/iterator_ops.py:703\u001b[0m, in \u001b[0;36mOwnedIterator.__init__\u001b[0;34m(self, dataset, components, element_spec)\u001b[0m\n\u001b[1;32m 699\u001b[0m \u001b[39mif\u001b[39;00m (components \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mor\u001b[39;00m element_spec \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m):\n\u001b[1;32m 700\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\n\u001b[1;32m 701\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mWhen `dataset` is provided, `element_spec` and `components` must \u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m 702\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mnot be specified.\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m--> 703\u001b[0m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_create_iterator(dataset)\n\u001b[1;32m 705\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_get_next_call_count \u001b[39m=\u001b[39m \u001b[39m0\u001b[39m\n",
+ "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/tensorflow/python/data/ops/iterator_ops.py:742\u001b[0m, in \u001b[0;36mOwnedIterator._create_iterator\u001b[0;34m(self, dataset)\u001b[0m\n\u001b[1;32m 739\u001b[0m \u001b[39massert\u001b[39;00m \u001b[39mlen\u001b[39m(fulltype\u001b[39m.\u001b[39margs[\u001b[39m0\u001b[39m]\u001b[39m.\u001b[39margs[\u001b[39m0\u001b[39m]\u001b[39m.\u001b[39margs) \u001b[39m==\u001b[39m \u001b[39mlen\u001b[39m(\n\u001b[1;32m 740\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_flat_output_types)\n\u001b[1;32m 741\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_iterator_resource\u001b[39m.\u001b[39mop\u001b[39m.\u001b[39mexperimental_set_type(fulltype)\n\u001b[0;32m--> 742\u001b[0m gen_dataset_ops\u001b[39m.\u001b[39;49mmake_iterator(ds_variant, \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_iterator_resource)\n",
+ "File \u001b[0;32m/opt/homebrew/lib/python3.10/site-packages/tensorflow/python/ops/gen_dataset_ops.py:3409\u001b[0m, in \u001b[0;36mmake_iterator\u001b[0;34m(dataset, iterator, name)\u001b[0m\n\u001b[1;32m 3407\u001b[0m \u001b[39mif\u001b[39;00m tld\u001b[39m.\u001b[39mis_eager:\n\u001b[1;32m 3408\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m-> 3409\u001b[0m _result \u001b[39m=\u001b[39m pywrap_tfe\u001b[39m.\u001b[39;49mTFE_Py_FastPathExecute(\n\u001b[1;32m 3410\u001b[0m _ctx, \u001b[39m\"\u001b[39;49m\u001b[39mMakeIterator\u001b[39;49m\u001b[39m\"\u001b[39;49m, name, dataset, iterator)\n\u001b[1;32m 3411\u001b[0m \u001b[39mreturn\u001b[39;00m _result\n\u001b[1;32m 3412\u001b[0m \u001b[39mexcept\u001b[39;00m _core\u001b[39m.\u001b[39m_NotOkStatusException \u001b[39mas\u001b[39;00m e:\n",
+ "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
+ ]
+ }
+ ],
+ "source": [
+ "\n",
+ "from data_augmentation import dataset\n",
+ "obj = dataset(1000,'new')\n",
+ "obj.generate()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import torch\n",
+ "obj.vae.gan_model.save_weights('generator_model',save_format='h5')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import tensorflow as tf\n",
+ "tf.keras.utils.plot_model(\n",
+ " obj.vae.gan_model,\n",
+ " expand_nested=True,\n",
+ " # show_shapes=True,\n",
+ " show_layer_activations=True,\n",
+ " to_file='gan.png')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "References:\n",
+ "1. This blog article.\n",
+ "2. The GAN paper by Ian Goodfellow: https://arxiv.org/pdf/1406.2661.pdf"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Improvements and further insights possible:\n",
+ "1. Try deeper layers in discriminator and generator models.\n",
+ "2. Try experimenting with different activation functions and learning rates\n",
+ "3. Try out more functions!"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.9"
+ },
+ "vscode": {
+ "interpreter": {
+ "hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e"
+ }
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/utils/__init__.py b/utils/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/utils/__pycache__/__init__.cpython-310.pyc b/utils/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..db4d9d362381bf3d92fd27ee10317b10cf3a32a2
Binary files /dev/null and b/utils/__pycache__/__init__.cpython-310.pyc differ
diff --git a/utils/__pycache__/data_augmentation.cpython-310.pyc b/utils/__pycache__/data_augmentation.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fcf1d806e3cfc95fee8a09b9c91c24bfe7fcc456
Binary files /dev/null and b/utils/__pycache__/data_augmentation.cpython-310.pyc differ
diff --git a/utils/__pycache__/dataset_loader.cpython-310.pyc b/utils/__pycache__/dataset_loader.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bd2379b8d563b8f9e0eabeb912e2ec9a91c00a2e
Binary files /dev/null and b/utils/__pycache__/dataset_loader.cpython-310.pyc differ
diff --git a/utils/__pycache__/ndgan.cpython-310.pyc b/utils/__pycache__/ndgan.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2a0a4730322486771afc0b1c2a97b8d757e7b957
Binary files /dev/null and b/utils/__pycache__/ndgan.cpython-310.pyc differ
diff --git a/utils/__pycache__/test.cpython-310.pyc b/utils/__pycache__/test.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a02f6237488b218136c10ac561cf36f5cb637a98
Binary files /dev/null and b/utils/__pycache__/test.cpython-310.pyc differ
diff --git a/utils/__pycache__/vae.cpython-310.pyc b/utils/__pycache__/vae.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c439ac1d39a96c45bd61b0983d40e32da35f3e75
Binary files /dev/null and b/utils/__pycache__/vae.cpython-310.pyc differ
diff --git a/utils/data_augmentation.py b/utils/data_augmentation.py
new file mode 100644
index 0000000000000000000000000000000000000000..14565eec2a404e78c3c04427ca24692ef36162b9
--- /dev/null
+++ b/utils/data_augmentation.py
@@ -0,0 +1,59 @@
+import numpy as np
+import _pickle
+import pandas as pd
+# import tensorflow as tf
+# from keras.layers import Input,Dense
+# from keras.models import Model
+# from sklearn.model_selection import train_test_split
+
+from utils.ndgan import DCGAN
+
+np.random.seed(4269)
+
+
+
+class dataset():
+ """ Creates dataset from input source
+ """
+ def __init__(self,number_samples:int, name:str,source:str,boundary_conditions:list=None):
+ """ Init
+
+ Args:
+ number_samples (int): number of samples to be genarated
+ name (str): name of dataset
+ source (str): source file
+ boundary_conditions (list): y1,y2,x1,x2
+ """
+ self.sample_size = number_samples
+ self.name = name
+ self.samples = []
+ self.encoding_dim = 8
+ self.latent_dim = 16
+ self.source = source
+ self.boundary_conditions = boundary_conditions
+
+ def generate(self):
+ with open(f"./data/{self.source}", "rb") as input_file:
+ local = pd.read_csv(input_file)
+ dfs = local.drop("Name",axis=1)
+ dfs = (dfs-dfs.min())/(dfs.max()-dfs.min())
+ dfs = pd.concat([local.Name,dfs],1)
+
+ self.vae = DCGAN(self.latent_dim,dfs)
+
+ self.vae.start_training()
+ self.samples = self.vae.predict(self.sample_size)
+
+ if self.boundary_conditions:
+ self.samples=self.samples[((self.samples[:,0]>self.boundary_conditions[2]) & (self.samples[:,0] < self.boundary_conditions[-1]))&((self.samples[:,0]>self.boundary_conditions[0]) & (self.samples[:,0] < self.boundary_conditions[1]))]
+
+ print("Samples:",self.samples)
+ dataframe = pd.concat([dfs,pd.DataFrame(self.samples,columns=dfs.columns[1:])])
+ dataframe.to_pickle(f'./data/{self.name}')
+ print(dataframe)
+
+
+
+ return dataframe
+
+
\ No newline at end of file
diff --git a/utils/dataset_loader.py b/utils/dataset_loader.py
new file mode 100644
index 0000000000000000000000000000000000000000..8370795b107046f6aceb3431d7ec31a201ce8383
--- /dev/null
+++ b/utils/dataset_loader.py
@@ -0,0 +1,31 @@
+from utils.data_augmentation import dataset
+import os
+import _pickle
+import pandas as pd
+
+
+
+
+def get_dataset(raw:bool=False, sample_size:int=1000, name:str='dataset.pkl',source:str='dataset.csv',boundary_conditions:list=None) -> _pickle:
+ """ Gets augmented dataset
+
+ Args:
+ raw (bool, optional): either to use source data or augmented. Defaults to False.
+ sample_size (int, optional): sample size. Defaults to 1000.
+ name (str, optional): name of wanted dataset. Defaults to 'dataset.pkl'.
+ boundary_conditions (list,optional): y1,y2,x1,x2.
+ Returns:
+ _pickle: pickle buffer
+ """
+ print(os.listdir('./data'))
+ if not(raw):
+ if name not in os.listdir('./data'):
+ ldat = dataset(sample_size,name,source,boundary_conditions)
+ ldat.generate()
+ with open(f"./data/{name}", "rb") as input_file:
+ buffer = _pickle.load(input_file)
+ else:
+ with open(f"./data/{source}", "rb") as input_file:
+ buffer = pd.read_csv(input_file)
+ return buffer
+
diff --git a/utils/discriminator_model.png b/utils/discriminator_model.png
new file mode 100644
index 0000000000000000000000000000000000000000..b69ef3881ed1722829e9e1c937de8efb7c54bc9c
Binary files /dev/null and b/utils/discriminator_model.png differ
diff --git a/utils/gan_model.png b/utils/gan_model.png
new file mode 100644
index 0000000000000000000000000000000000000000..8a7e238566273a2eb1070ae92707c388d144ff85
Binary files /dev/null and b/utils/gan_model.png differ
diff --git a/utils/generator_model.png b/utils/generator_model.png
new file mode 100644
index 0000000000000000000000000000000000000000..dd3e7f740d3ad30af217f497db3003c22d619337
Binary files /dev/null and b/utils/generator_model.png differ
diff --git a/utils/ndgan.py b/utils/ndgan.py
new file mode 100644
index 0000000000000000000000000000000000000000..7672ddb3b6153f41b7467d96bbbae957fdfe835f
--- /dev/null
+++ b/utils/ndgan.py
@@ -0,0 +1,104 @@
+from keras.models import Sequential
+from keras.layers import Dense, LeakyReLU,ReLU
+# from keras.utils import plot_model
+import matplotlib.pyplot as plt
+import numpy as np
+np.random.seed(4062710504)
+from keras.utils import set_random_seed
+set_random_seed(440)
+
+class DCGAN():
+ def __init__(self,latent,data):
+ self.latent=16
+ self.dfs=data
+ print(data.head())
+ self.inputs=8
+ self.outputs=8
+ self.generator_model, self.discriminator_model = self.build_models()
+ self.gan_model = self.define_gan(self.generator_model,self.discriminator_model)
+
+
+ def define_discriminator(self,inputs=8):
+ ''' function to return the compiled discriminator model'''
+ model = Sequential()
+ model.add(Dense(20, activation = 'relu', kernel_initializer = 'he_uniform', input_dim = self.inputs))
+ model.add(LeakyReLU(alpha=0.3))
+ model.add(Dense(15, activation = 'relu', kernel_initializer = 'he_uniform'))
+ model.add(LeakyReLU(alpha=0.3))
+ model.add(Dense(5, activation = 'relu', kernel_initializer = 'he_uniform'))
+ model.add(LeakyReLU(alpha=0.3))
+ model.add(Dense(1, activation = 'selu'))
+ model.compile(optimizer = 'adam', loss = 'binary_focal_crossentropy', metrics = ['accuracy'])
+ return model
+
+ def define_generator(self,latent_dim, outputs = 8):
+ model = Sequential()
+ model.add(Dense(20, activation = 'relu', kernel_initializer= 'he_uniform', input_dim = latent_dim))
+ model.add(LeakyReLU(alpha = 0.3))
+ model.add(Dense(15, activation = 'relu', kernel_initializer = 'he_uniform'))
+ model.add(LeakyReLU(alpha=0.3))
+ model.add(Dense(self.outputs, activation = 'elu'))
+ return model
+
+ def build_models(self):
+ discriminator_model = self.define_discriminator()
+ generator_model = self.define_generator(self.latent)
+ return generator_model,discriminator_model
+
+ def generate_latent_points(self,latent_dim, n):
+ '''generate points in latent space as input for the generator'''
+ x_input = np.random.rand(latent_dim*n) #generate points in latent space
+ x_input = x_input.reshape(n,latent_dim) #reshape
+ return x_input
+
+ def generate_fake_samples(self,generator, latent_dim, n):
+ x_input = self.generate_latent_points(latent_dim, n) #genarate points in latent space
+ x = generator.predict(x_input) #predict outputs
+ y = np.zeros((n, 1))
+ return x, y
+
+ def define_gan(self,generator, discriminator):
+ '''define the combined generator and discriminator model'''
+ discriminator.trainable = False
+ model = Sequential()
+ model.add(generator)
+ model.add(discriminator)
+ model.compile(optimizer = 'adam', loss = 'binary_crossentropy')
+ return model
+
+
+ def summarize_performance(self,epoch, generator, discriminator, latent_dim, n = 200):
+ '''evaluate the discriminator and plot real and fake samples'''
+ x_real, y_real = self.dfs.iloc[:,1:].values, np.ones((23, 1))
+ _, acc_real = discriminator.evaluate(x_real, y_real, verbose = 1)
+ x_fake, y_fake = self.generate_fake_samples(generator, latent_dim, n)
+ _, acc_fake = discriminator.evaluate(x_fake, y_fake, verbose = 1)
+ print('Epoch: ' + str(epoch) + ' Real Acc.: ' + str(acc_real) + ' Fake Acc.: '+ str(acc_fake))
+ # x_real /= np.max(np.abs(x_real),axis=0)
+ plt.scatter(x_real[:,0], x_real[:,1], color = 'red')
+ plt.scatter(x_fake[:,0], x_fake[:,1], color = 'blue',s=20)
+ plt.show()
+
+ def train_gan(self,g_model,d_model,gan_model,latent_dim, num_epochs = 2500,num_eval = 2500, batch_size = 2):
+ ''' function to train gan model'''
+ half_batch = 1
+ #run epochs
+ for i in range(num_epochs):
+ X_real, y_real = self.dfs.iloc[:,1:].values, np.ones((23, 1)) #generate real examples
+ d_model.train_on_batch(X_real, y_real) # train on real data
+ X_fake, y_fake = self.generate_fake_samples(g_model, latent_dim, half_batch) #generate fake samples
+ d_model.train_on_batch(X_fake, y_fake) #train on fake data
+ #prepare points in latent space as input for the generator
+ x_gan = self.generate_latent_points(latent_dim, batch_size)
+ y_gan = np.ones((batch_size, 1)) #generate fake labels for gan
+ gan_model.train_on_batch(x_gan, y_gan)
+ if (i+1) % num_eval == 0:
+ self.summarize_performance(i + 1, g_model, d_model, latent_dim)
+
+ def start_training(self):
+ self.train_gan(self.generator_model, self.discriminator_model, self.gan_model, self.latent)
+
+
+ def predict(self,n):
+ x_fake, y_fake = self.generate_fake_samples(self.generator_model, self.latent, n)
+ return x_fake
\ No newline at end of file
diff --git a/utils/test.py b/utils/test.py
new file mode 100644
index 0000000000000000000000000000000000000000..31aae260d1a865d269989b5fad9f5b72deeddc68
--- /dev/null
+++ b/utils/test.py
@@ -0,0 +1,2 @@
+import os
+print(os.listdir('./data'))
\ No newline at end of file
diff --git a/variant.png b/variant.png
new file mode 100644
index 0000000000000000000000000000000000000000..ad25aad38b26bacabec16d557bea135e5d94f005
Binary files /dev/null and b/variant.png differ