Repository: Saran-nns/sorn (language: python)

Issue:
[JOSS review] Suggestions and requests
Hi, I have a couple of suggestions / requests for your documentation. Let me know if you disagree with any of these:

- [x] your documentation references a [configuration file](https://self-organizing-recurrent-neural-networks.readthedocs.io/en/latest/usage.html#update-network-configuration) which lives inside the installed python package, and is suggested to be edited by the user. This doesn't seem like a good solution for configuring the core part of your library, as the site package directory may not always be editable by the user (e.g. if the library was installed by an administrator, the library is shared across users, etc.)

    I would suggest changing the way this is handled. One way would be to define these in code, in a frozen dictionary inside the modules you have elsewhere. You could then allow users to copy this dictionary, edit it, and pass it as an argument to the SORN class.

- [x] It would be great if you could expand the OpenAI gym example to be "self-contained". Currently it references a pickle file which isn't generated in the documentation. If this is intended to be the pkl file in the github repository, this should be explained, because that pkl file doesn't exist if someone installs the library via pip. It also references computing gradients - is it possible to supply a simple example of this?
- [x] There seems to be some discrepancy between the README and the hosted documentation, for example the OpenAI Gym example. It would be nice if they could match (you could even include your README in your documentation itself).
- [x] It would be nice to include some example pictures of the plots in the documentation, so that users know what to expect

- [x] Running test_sorn.py produces some corrupted graphs, e.g.:
    ![image](https://user-images.githubusercontent.com/4092425/129411686-13abc284-392a-4c75-853b-4ddb7547d2b0.png)

[JOSS review] Examples in README fail
Hi there,

I was just trying to run the examples as provided in the README, but ran into an error:

```python
from sorn import Simulator
import numpy as np

# Sample input
num_features = 10
time_steps = 200
inputs = np.random.rand(num_features,time_steps)

# To simulate the network;
matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features)

# To resume the simulation, load the matrices_dict from previous simulation;
matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=matrices_dict, noise= True, time_steps=time_steps,_ne = 200, _nu=num_features)
```

Produces the following error:
```
Network Initialized
Number of connections in Wee 3881 , Wei 1584, Wie 8000
Shapes Wee (200, 200) Wei (40, 200) Wie (200, 40)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-3e49ac279123> in <module>
      8
      9 # To simulate the network;
---> 10 matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features)
     11
     12 # To resume the simulation, load the matrices_dict from previous simulation;

~/github/joss-reviews/.venv/lib/python3.9/site-packages/sorn/sorn.py in simulate_sorn(self, inputs, phase, matrices, time_steps, noise, freeze, **kwargs)
    956
    957             # STDP
--> 958             if 'stdp' not in self.freeze:
    959                 Wee_t = plasticity.stdp(
    960                     Wee[i], x_buffer, cutoff_weights=(0.0, 1.0))

TypeError: argument of type 'NoneType' is not iterable
```

I assume this is a relatively easy fix for the `freeze` attribute?

Thanks


_this is part of the review: https://github.com/openjournals/joss-reviews/issues/3545_
[JOSS review] Suggestions and requests
Hi, I have a couple of suggestions / requests for your documentation. Let me know if you disagree with any of these:

- [x] your documentation references a [configuration file](https://self-organizing-recurrent-neural-networks.readthedocs.io/en/latest/usage.html#update-network-configuration) which lives inside the installed python package, and is suggested to be edited by the user. This doesn't seem like a good solution for configuring the core part of your library, as the site package directory may not always be editable by the user (e.g. if the library was installed by an administrator, the library is shared across users, etc.)

    I would suggest changing the way this is handled. One way would be to define these in code, in a frozen dictionary inside the modules you have elsewhere. You could then allow users to copy this dictionary, edit it, and pass it as an argument to the SORN class.

- [x] It would be great if you could expand the OpenAI gym example to be "self-contained". Currently it references a pickle file which isn't generated in the documentation. If this is intended to be the pkl file in the github repository, this should be explained, because that pkl file doesn't exist if someone installs the library via pip. It also references computing gradients - is it possible to supply a simple example of this?
- [x] There seems to be some discrepancy between the README and the hosted documentation, for example the OpenAI Gym example. It would be nice if they could match (you could even include your README in your documentation itself).
- [x] It would be nice to include some example pictures of the plots in the documentation, so that users know what to expect

- [x] Running test_sorn.py produces some corrupted graphs, e.g.:
    ![image](https://user-images.githubusercontent.com/4092425/129411686-13abc284-392a-4c75-853b-4ddb7547d2b0.png)

[JOSS review] Suggestions and requests
Hi, I have a couple of suggestions / requests for your documentation. Let me know if you disagree with any of these:

- [x] your documentation references a [configuration file](https://self-organizing-recurrent-neural-networks.readthedocs.io/en/latest/usage.html#update-network-configuration) which lives inside the installed python package, and is suggested to be edited by the user. This doesn't seem like a good solution for configuring the core part of your library, as the site package directory may not always be editable by the user (e.g. if the library was installed by an administrator, the library is shared across users, etc.)

    I would suggest changing the way this is handled. One way would be to define these in code, in a frozen dictionary inside the modules you have elsewhere. You could then allow users to copy this dictionary, edit it, and pass it as an argument to the SORN class.

- [x] It would be great if you could expand the OpenAI gym example to be "self-contained". Currently it references a pickle file which isn't generated in the documentation. If this is intended to be the pkl file in the github repository, this should be explained, because that pkl file doesn't exist if someone installs the library via pip. It also references computing gradients - is it possible to supply a simple example of this?
- [x] There seems to be some discrepancy between the README and the hosted documentation, for example the OpenAI Gym example. It would be nice if they could match (you could even include your README in your documentation itself).
- [x] It would be nice to include some example pictures of the plots in the documentation, so that users know what to expect

- [x] Running test_sorn.py produces some corrupted graphs, e.g.:
    ![image](https://user-images.githubusercontent.com/4092425/129411686-13abc284-392a-4c75-853b-4ddb7547d2b0.png)

[JOSS review] Suggestions and requests
Hi, I have a couple of suggestions / requests for your documentation. Let me know if you disagree with any of these:

- [x] your documentation references a [configuration file](https://self-organizing-recurrent-neural-networks.readthedocs.io/en/latest/usage.html#update-network-configuration) which lives inside the installed python package, and is suggested to be edited by the user. This doesn't seem like a good solution for configuring the core part of your library, as the site package directory may not always be editable by the user (e.g. if the library was installed by an administrator, the library is shared across users, etc.)

    I would suggest changing the way this is handled. One way would be to define these in code, in a frozen dictionary inside the modules you have elsewhere. You could then allow users to copy this dictionary, edit it, and pass it as an argument to the SORN class.

- [x] It would be great if you could expand the OpenAI gym example to be "self-contained". Currently it references a pickle file which isn't generated in the documentation. If this is intended to be the pkl file in the github repository, this should be explained, because that pkl file doesn't exist if someone installs the library via pip. It also references computing gradients - is it possible to supply a simple example of this?
- [x] There seems to be some discrepancy between the README and the hosted documentation, for example the OpenAI Gym example. It would be nice if they could match (you could even include your README in your documentation itself).
- [x] It would be nice to include some example pictures of the plots in the documentation, so that users know what to expect

- [x] Running test_sorn.py produces some corrupted graphs, e.g.:
    ![image](https://user-images.githubusercontent.com/4092425/129411686-13abc284-392a-4c75-853b-4ddb7547d2b0.png)



Discussion / hints:

Note that when I try to provide an argument for `freeze`, I also encounter errors:

```python
matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(
    inputs = inputs, phase='plasticity', matrices=None, noise = True,
    time_steps=time_steps, _ne = 200, _nu=num_features,
    freeze=['ip'])

Network Initialized
Number of connections in Wee 3904 , Wei 1569, Wie 8000
Shapes Wee (200, 200) Wei (40, 200) Wie (200, 40)
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-4-8c54dfffe88b> in <module>
      8
      9 # To simulate the network;
---> 10 matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features, freeze=['ip'])

~/github/joss-reviews/.venv/lib/python3.9/site-packages/sorn/sorn.py in simulate_sorn(self, inputs, phase, matrices, time_steps, noise, freeze, **kwargs)
    981             # Assign the matrices to the matrix collections
    982             matrix_collection.weight_matrix(Wee_t, Wei_t, Wie[i], i)
--> 983             matrix_collection.threshold_matrix(Te_t, Ti[i], i)
    984             matrix_collection.network_activity_t(x_buffer, y_buffer, i)
    985

UnboundLocalError: local variable 'Te_t' referenced before assignment
```
I should note that I am currently using the latest install from github, but the first error also occurred on the version in PyPi!
Hi @janfreyberg. Thank you for reporting the issue. The variable assignment and the freeze options are fixed. The github repo and the pypi (v0.5.2) are also updated. Test runs of README examples are done at [colab notebook](https://colab.research.google.com/drive/1qz_Xkfam0wCCu2pz2kFogEJDWU2ED8Q4#scrollTo=xpHqf0bijR_d)
 Thank you :)
Thanks @Saran-nns (and sorry for the delay) - I can run the examples from that notebook, but the following from the README seems to still fail:

```python
matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features, freeze=['ip'])
```

Seems like the main difference between this and your colab is the `time_steps` argument, which is set to `time_steps` in the README, but 1 in the colab.

Can you clarify whether this should work as is in the readme and fix a bug if so - or change the readme otherwise?

You might also want to use some way of testing your README examples automatically. This library could help with that:
https://github.com/koaning/mktestdocs




Fix patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 52aea9c..43df0ae 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,11 +1,11 @@
 repos:
-- repo: https://github.com/ambv/black
-  rev: stable
-  hooks:
-    - id: black
-      language_version: python3.5
-- repo: https://gitlab.com/pycqa/flake8
-  rev: 3.8.3
-  hooks: 
-    - id: flake8
-      language: python_venv
+  - repo: https://github.com/ambv/black
+    rev: stable
+    hooks:
+      - id: black
+        language_version: python3.8
+  - repo: https://gitlab.com/pycqa/flake8
+    rev: 3.8.3
+    hooks:
+      - id: flake8
+        language: python_venv
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 6b434e0..7110c38 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -13,8 +13,8 @@ sphinx:
 formats: all
 
 python:
-  version: 3.6
+  version: 3.8
   install:
-     - requirements: docs/requirements.txt
-     - method: pip
-       path: .
\ No newline at end of file
+    - requirements: docs/requirements.txt
+    - method: pip
+      path: .
diff --git a/Dockerfile b/Dockerfile
index 1118cc7..2d0465d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
 # set base image (host OS)
-FROM python:3.5
+FROM python:3.8
 
 # set the working directory in the scontainer
 WORKDIR /sorn
diff --git a/README.md b/README.md
index f20dd58..1d6ac2f 100644
--- a/README.md
+++ b/README.md
@@ -61,31 +61,10 @@ To install all optional dependencies,
 For detailed documentation about usage and development, please visit [SORN-Documentation](https://self-organizing-recurrent-neural-networks.readthedocs.io/)
 
 ## Usage
-
-### Update Network configurations
-There are two ways to update/configure the network parameters,
-1. Navigate to home/conda/envs/ENVNAME/Lib/site-packages/sorn
- ```or``` if you are unsure about the directory of ```sorn```
-
-Run
+### Plasticity Phase
 
 ```python
 import sorn
-
-sorn.__file__
-```
-to find the location of the sorn package
-
-Then, update/edit arguments in `configuration.ini`
-
-2. While instantiating the network using `Simulator` or `Trainer` objects, override the defaults by assigning the values to the ```kwargs``` shown below,
-```Python
-kwargs = {'_ne', '_nu', '_network_type_ee', '_network_type_ei', '_network_type_ie', '_lambda_ee','_lambda_ei', '_lambda_ie', '_eta_stdp','_eta_inhib', '_eta_ip', '_te_max', '_ti_max', '_ti_min', '_te_min', '_mu_ip','_sigma_ip'}
-```
-### Plasticity Phase
-The default ```_ne, _nu``` values are overriden by passing them as kwargs inside ```simulate_sorn``` method.
-
-```Python
 from sorn import Simulator
 import numpy as np
 
@@ -94,75 +73,125 @@ num_features = 10
 time_steps = 200
 inputs = np.random.rand(num_features,time_steps)
 
-# To simulate the network;
-matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features)
+# Simulate the network with default hyperparameters under gaussian white noise
+state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                matrices=None, noise = True,
+                                                time_steps=time_steps)
 
-# To resume the simulation, load the matrices_dict from previous simulation;
-matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=matrices_dict, noise= True, time_steps=time_steps,_ne = 200, _nu=num_features)
+```
+The default values of the network hyperparameters are,
+
+Keyword argument | Value | Description |
+--- | --- | --- |
+ne              | 200      | Number of Encitatory neurons in the reservoir                              |
+nu              | 10       | Number of Input neurons in the reservoir                                   |
+network_type_ee | "Sparse" | `Sparse` or `Dense` connectivity between Excitatory neurons                |
+network_type_ie | "Dense"  | `Sparse` or `Dense` connectivity from Excitatory to Inhibitory neurons     |
+network_type_ei | "Sparse" | `Sparse` or `Dense` connectivity from Inhibitory to Excitatory neurons     |
+lambda_ee       | 20       | % of connections between neurons in Excitatory pool                        |
+lambda_ei       | 40       | % of connections from Inhibitory to Excitatory neurons                     |
+lambda_ie       | 100      | % of connections from Excitatory to Inhibitory neurons                     |
+eta_stdp        | 0.004    | Hebbian Learning rate for connections between excitatory neurons           |
+eta_inhib       | 0.001    | Hebbian Learning rate for connections from Inhibitory to Excitatory neurons|
+eta_ip          | 0.01     | Intrinsic plasticity learning rate                                         |
+te_max          | 1.0      | Maximum excitatory neuron threshold value                                  |
+ti_max          | 0.5      | Maximum inhibitory neuron threshold value                                  |
+ti_min          | 0.0      | Minimum inhibitory neuron threshold value                                  |
+te_min          | 0.0      | Minimum excitatory neuron threshold value                                  |
+mu_ip           | 0.1      | Target mean firing rate of excitatory neuron                               |
+sigma_ip        | 0.0      | Standard deviation of firing rate of excitatory neuron                     |
+
+To override the default hyperparameters, use the `kwargs` as shown below,
+```python
+state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                matrices=None, noise= True,
+                                                time_steps=time_steps,
+                                                ne = 200, nu=num_features)
 ```
 ### Training phase
 
 ```Python
 from sorn import Trainer
+# NOTE: During training phase, input to `sorn` should have second (time) dimension set to 1. ie., input shape should be (input_features,1).
+
 inputs = np.random.rand(num_features,1)
 
 # SORN network is frozen during training phase
-matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Trainer.train_sorn(inputs = inputs, phase='training', matrices=matrices_dict,_nu=num_features, time_steps=1)
+state_dict, E, I, R, C = Trainer.train_sorn(inputs = inputs, phase='training',
+                                            matrices=state_dict,
+                                            nu=num_features, time_steps=1)
 ```
-
-To turn off any plasticity mechanisms during simulation or training phase, you can use `freeze` argument.
-For example to stop intrinsic plasticity during training phase,
+### Freeze plasticity
+To turn off any plasticity mechanisms during `simulation` or `training` phase, use `freeze` argument.
+For example to stop intrinsic plasticity during simulation phase,
 
 ```python
-matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features, freeze=['ip'])
+# Sample input
+num_features = 10
+time_steps = 200
+inputs = np.random.rand(num_features,time_steps)
+
+state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                matrices=None, noise = True,
+                                                time_steps=time_steps, ne = 200,
+                                                nu=num_features, freeze=['ip'])
 ```
 
 The other options are,
 
-`'stdp'` - Spike Timing Dependent Plasticity
+`stdp` - Spike Timing Dependent Plasticity
 
-`'ss'` - Synaptic Scaling
+`ss` - Synaptic Scaling
 
-`'sp'` - Structural Plasticity
+`sp` - Structural Plasticity
 
-`'istdp'` - Inhibitory Spike Timing Dependent Plasticity
+`istdp` - Inhibitory Spike Timing Dependent Plasticity
 
 Note: If you pass all above options to `freeze`, then the network will behave as Liquid State Machine(LSM)
 
 ### Network Output Descriptions
-  ```matrices_dict```  - Dictionary of connection weights ('Wee','Wei','Wie') , Excitatory network activity ('X'), Inhibitory network activities('Y'), Threshold values ('Te','Ti')
+  `state_dict`  - Dictionary of connection weights (`Wee`,`Wei`,`Wie`) , Excitatory network activity (`X`), Inhibitory network activities(`Y`), Threshold values (`Te`,`Ti`)
 
-  ```Exc_activity``` - Collection of Excitatory network activity of entire simulation period
+  `E` - Collection of Excitatory network activity of entire simulation period
 
-  ```Inh_activity``` - Collection of Inhibitory network activity of entire simulation period
+  `I` - Collection of Inhibitory network activity of entire simulation period
 
-  ```Rec_activity``` - Collection of Recurrent network activity of entire simulation period
+  `R` - Collection of Recurrent network activity of entire simulation period
 
-  ```num_active_connections``` - List of number of active connections in the Excitatory pool at each time step
+  `C` - List of number of active connections in the Excitatory pool at each time step
 
 ### Colaboratory Notebook
 Sample simulation and training runs with few plotting functions are found at [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/10TElAAE1dsgzuvaHO_NjgMAE5Pic3_jL#scrollTo=VDa0U4mf1Z75)
 
 ## Usage with OpenAI gym
 ### Cartpole balance problem
-With default network parameters.
 
 ```python
 from sorn import Simulator, Trainer
 import gym
 
-# Load the simulated network matrices
-# Note that these matrices are obtained after the network achieved convergence under random inputs and noise
+# Hyperparameters
+NUM_EPISODES = int(2e6)
+NUM_PLASTICITY_EPISODES = 20
 
-with open('simulation_matrices.pkl','rb') as f:
-    sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = pickle.load(f)
+LEARNING_RATE = 0.0001 # Gradient ascent learning rate
+GAMMA = 0.99 # Discounting factor for the Rewards
 
-# Training parameters
+# Open AI gym; Cartpole Environment
+env = gym.make('CartPole-v0')
+action_space = env.action_space.n
 
-NUM_EPISODES = 2e6
-NUM_PLASTICITY_EPISODES = 20000
+# SORN network parameters
+ne = 50
+nu = 4
+# Init SORN using Simulator under random input;
+state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = np.random.randn(4,1),
+                                                 phase ='plasticity',
+                                                 time_steps = 1,
+                                                 noise=False,
+                                                 ne = ne, nu=nu)
 
-env = gym.make('CartPole-v0')
+w = np.random.rand(ne, 2) # Output layer weights
 
 # Policy
 def policy(state,w):
@@ -171,65 +200,148 @@ def policy(state,w):
     exp = np.exp(z)
     return exp/np.sum(exp)
 
+# Vectorized softmax Jacobian
+def softmax_grad(softmax):
+    s = softmax.reshape(-1,1)
+    return np.diagflat(s) - np.dot(s, s.T)
+
 for EPISODE in range(NUM_EPISODES):
 
-    # Environment observation; Input to sorn should be of shape (input_features,time_steps)
+    # Environment observation;
+    # NOTE: Input to sorn should have time dimension. ie., input shape should be (input_features,time_steps)
     state = env.reset()[:, None] # (4,) --> (4,1)
-    state = np.array(state)
+
+    grads = [] # Episode log policy gradients
+    rewards = [] # Episode rewards
+
+    # Keep track of total score
+    score = 0
 
     # Play the episode
     while True:
-      state = np.array(state[:,None])
-      if EPISODE < NUM_PLASTICITY_EPISODE:
+
+      # env.render() # Uncomment to see your model train in real time (slow down training progress)
+      if EPISODE < NUM_PLASTICITY_EPISODES:
 
         # Plasticity phase
-        sim_matrices, excit_states, inhib_states, recur_states, num_reservoir_conn = Simulator.simulate_sorn(inputs = state, phase ='plasticity', matrices = sim_matrices, time_steps = 1, noise=False)
+        state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = state, phase ='plasticity',
+                                                        matrices = state_dict, time_steps = 1,
+                                                        ne = ne, nu=nu,
+                                                        noise=False)
 
       else:
         # Training phase with frozen reservoir connectivity
-        sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = Trainer.train_sorn(inputs = state, phase = 'training', matrices = sim_matrices, noise= False)
+        state_dict, E, I, R, C = Trainer.train_sorn(inputs = state, phase = 'training',
+                                                matrices = state_dict, time_steps = 1,
+                                                ne = ne, nu=nu,
+                                                noise= False)
 
-      # Feed excit_states as input states to your RL algorithm, below goes for simple policy gradient algorithm
+      # Feed E as input states to your RL algorithm, below goes for simple policy gradient algorithm
       # Sample policy w.r.t excitatory states and take action in the environment
-      probs = policy(np.asarray(excit_states),output_layer_weights))
-      action = np.random.choice(action_space,probs)
-
+      probs = policy(np.asarray(E),w)
+      action = np.random.choice(action_space,p=probs[0])
       state,reward,done,_ = env.step(action)
+      state = state[:,None]
+
+      # COMPUTE GRADIENTS BASED ON YOUR OBJECTIVE FUNCTION;
+      # Sample computation of policy gradient objective function
+      dsoftmax = softmax_grad(probs)[action,:]
+      dlog = dsoftmax / probs[0,action]
+      grad = np.asarray(E).T.dot(dlog[None,:])
+      grads.append(grad)
+      rewards.append(reward)
+      score+=reward
 
       if done:
-        break
+          break
+
+    # OPTIMIZE OUTPUT LAYER WEIGHTS `w` BASED ON YOUR OPTIMIZATION METHOD;
+    # Below is a sample of weight update based on gradient ascent(maximize cumulative reward) method for temporal difference learning
+    for i in range(len(grads)):
 
-  # YOUR CODE HERE
-  # COMPUTE GRADIENTS BASED ON YOUR OBJECTIVE FUNCTION
-  # OPTIMIZE `output_layer_weights` BASED ON YOUR OPTIMIZATION METHOD
+        # Loop through everything that happened in the episode and update towards the log policy gradient times future reward
+        w += LEARNING_RATE * grads[i] * sum([ r * (GAMMA ** r) for t,r in enumerate(rewards[i:])])
+    print('Episode %s  Score %s' %(str(EPISODE),str(score)))
 ```
+
 There are several neural data analysis and visualization methods inbuilt with `sorn` package. Sample call for few plotting and statistical methods are shown below;
 
 ## Plotting functions
 
-```Python
+```python
 from sorn import Plotter
 # Plot weight distribution in the network
-Plotter.weight_distribution(weights= matrices_dict['Wee'], bin_size = 5, savefig = False)
+Wee = np.random.randn(200,200) # For example, the network has 200 neurons in the excitatory pool. Note that generally Wee is sparse
+Wee=Wee/Wee.max() # state_dict['Wee'] returned by the SORN is already normalized
+Plotter.weight_distribution(weights= Wee, bin_size = 5, savefig = True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/weight_distribution.png" height="320" width="430"></a>
 
+```python
 # Plot Spike train of all neurons in the network
-Plotter.scatter_plot(spike_train = np.asarray(Exc_activity), savefig=False)
+E = np.random.randint(2, size=(200,1000)) # For example, activity of 200 excitatory neurons in 1000 time steps
+Plotter.scatter_plot(spike_train = E, savefig=True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/ScatterSpikeTrain.png" height="320" width="430"></a>
+
+```python
+# Raster plot of activity of only first 10 neurons in the excitatory pool
+Plotter.raster_plot(spike_train = E[:,0:10], savefig=True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/RasterSpikeTrain.png" height="320" width="430"></a>
+
+```python
+# Histogram of number of presynaptic connections per neuron in the excitatory pool
+Plotter.hist_incoming_conn(weights=Wee, bin_size=10, histtype='bar', savefig=True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_incoming_conn.png" height="310" width="430"></a>
 
-Plotter.raster_plot(spike_train = np.asarray(Exc_activity), savefig=False)
+```python
+# Distribution of firing rate of the network
+Plotter.hist_firing_rate_network(E, bin_size=10, savefig=True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_firing_rate_network.png" height="320" width="430"></a>
+
+```python
+# Plot pearson correlation between neurons
+from sorn import Statistics
+avg_corr_coeff,_ = Statistics.avg_corr_coeff(E)
+Plotter.correlation(avg_corr_coeff,savefig=True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/correlation_between_neurons.png" height="320" width="430"></a>
+
+```python
+# Inter spike intervals with exponential curve fit for neuron 1 in the Excitatory pool
+Plotter.isi_exponential_fit(E,neuron=1,bin_size=5, savefig=True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/isi_exponential_fit.png" height="320" width="430"></a>
+
+```python
+# Distribution of connection weights in linear and lognormal scale
+Plotter.linear_lognormal_fit(weights=Wee,num_points=100, savefig=True)
+```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/LinearLognormalFit.png" height="300" width="440"></a>
+
+```python
+# Draw network connectivity using the pearson correlation function between neurons in the excitatory pool
+Plotter.plot_network(avg_corr_coeff,corr_thres=0.1,fig_name='network.png')
 ```
+<a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/network.png" height="340" width="410"></a>
 
 ## Statistics and Analysis functions
 
 ```Python
 from sorn import Statistics
 #t-lagged auto correlation between neural activity
-Statistics.autocorr(firing_rates = [1,1,5,6,3,7],t= 2)
+pearson_corr_matrix = Statistics.autocorr(firing_rates = [1,1,5,6,3,7], t= 2)
 
 # Fano factor: To verify poissonian process in spike generation of neuron 10
-Statistics.fanofactor(spike_train= np.asarray(Exc_activity),neuron = 10,window_size = 10)
+mean_firing_rate, variance_firing_rate, fano_factor = Statistics.fanofactor(spike_train= E,
+                                                                            neuron = 10,
+                                                                            window_size = 10)
 
-# Measure the uncertainty about the origin of spike from the network using entropy
-Statistics.spike_source_entropy(spike_train= np.asarray(Exc_activity), num_neurons=200)
+# Spike Source Entropy: To measure the uncertainty about the origin of spike from the network using entropy
+sse = Statistics.spike_source_entropy(spike_train= E, num_neurons=200)
 ```
 ## Citation
 ### Package
diff --git a/Untitled.ipynb b/Untitled.ipynb
deleted file mode 100644
index f0717fc..0000000
--- a/Untitled.ipynb
+++ /dev/null
@@ -1,140 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from sorn import Simulator\n",
-    "import numpy as np\n",
-    "\n",
-    "# Sample input\n",
-    "num_features = 10\n",
-    "time_steps = 200\n",
-    "inputs = np.random.rand(num_features,time_steps)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Network Initialized\n",
-      "Number of connections in Wee 3894 , Wei 1580, Wie 8000\n",
-      "Shapes Wee (200, 200) Wei (40, 200) Wie (200, 40)\n"
-     ]
-    }
-   ],
-   "source": [
-    "# To simulate the network;\n",
-    "matrices_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', \n",
-    "                                                    matrices=None, noise = True, \n",
-    "                                                    time_steps=time_steps,\n",
-    "                                                    _ne = 200, _nu=num_features)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "matrices_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', \n",
-    "                                                    matrices=matrices_dict, noise= True, \n",
-    "                                                    time_steps=time_steps,_ne = 200, \n",
-    "                                                    _nu=num_features)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from sorn import Trainer\n",
-    "inputs = np.random.rand(num_features,1)\n",
-    "\n",
-    "matrices_dict, E, I, R, C = Trainer.train_sorn(inputs = inputs, phase='training', \n",
-    "                                               matrices=matrices_dict,_nu=num_features, \n",
-    "                                               time_steps=1)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Network Initialized\n",
-      "Number of connections in Wee 3891 , Wei 1580, Wie 8000\n",
-      "Shapes Wee (200, 200) Wei (40, 200) Wie (200, 40)\n"
-     ]
-    }
-   ],
-   "source": [
-    "matrices_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', \n",
-    "                                                    matrices=None, noise = True, time_steps=1, \n",
-    "                                                    _ne = 200, _nu=num_features, \n",
-    "                                                    freeze=['ip'])\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Network Initialized\n",
-      "Number of connections in Wee 3900 , Wei 1582, Wie 8000\n",
-      "Shapes Wee (200, 200) Wei (40, 200) Wie (200, 40)\n"
-     ]
-    }
-   ],
-   "source": [
-    "matrices_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', \n",
-    "                                                    matrices=None, noise = True, time_steps=1, \n",
-    "                                                    _ne = 200, _nu=num_features, \n",
-    "                                                    freeze=['ip','sp','ss'])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.6.10"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/build/lib/sorn/__init__.py b/build/lib/sorn/__init__.py
index 6223714..e39b9d9 100644
--- a/build/lib/sorn/__init__.py
+++ b/build/lib/sorn/__init__.py
@@ -3,6 +3,6 @@
 from .utils import *
 
 __author__ = "Saranraj Nambusubramaniyan"
-__version__ = "0.5.2"
+__version__ = "0.5.7"
 
 logging.basicConfig(level=logging.INFO)
diff --git a/build/lib/sorn/configuration.ini b/build/lib/sorn/configuration.ini
deleted file mode 100644
index 3e21f6f..0000000
--- a/build/lib/sorn/configuration.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-[Network_Config]
-
-# Number of neurons in the reservoir
-Ne = 200
-
-# Number of input units in the reservoir
-Nu = 10
-
-# Connection/Network type: Sparse or Dense
-
-network_type_ee = Sparse
-network_type_ei = Sparse
-network_type_ie = Dense
-
-# Mean number of incoming and outgoing connections per neuron
-lambda_ee = 20
-lambda_ei = 40
-lambda_ie = 100
-
-# Hebbian Learning rate 
-eta_stdp = 0.004
-
-# Anti-Hebbian learning rate
-eta_inhib = 0.001
-
-# Intrinsic plasticity constants    
-eta_ip = 0.01
-
-# Threshold initialization values
-te_max = 1.0
-ti_max = 0.5
-ti_min = 0.0
-te_min = 0.0
-
-# Mean and standard deviation of target firing rate , h_ip
-mu_ip = 0.1
-sigma_ip = 0.0 
-
diff --git a/build/lib/sorn/sorn.py b/build/lib/sorn/sorn.py
index 3d4edf7..3b941c9 100644
--- a/build/lib/sorn/sorn.py
+++ b/build/lib/sorn/sorn.py
@@ -3,7 +3,6 @@
 from __future__ import division
 import numpy as np
 import os
-from configparser import ConfigParser
 import random
 
 try:
@@ -11,13 +10,6 @@
 except:
     from utils import Initializer
 
-parser = ConfigParser()
-config_file = os.path.join(
-    os.path.dirname(os.path.abspath(__file__)), "configuration.ini"
-)
-parser.read(config_file)
-
-
 class Sorn(object):
 
     """ This class wraps initialization of the network and its parameters
@@ -25,7 +17,7 @@ class Sorn(object):
     Args:
         nu (int): Number of input units. Defaults to 10
 
-        ne (int): Sorn._ne  # Number of excitatory units. Defaults to 200
+        ne (int): Number of excitatory units. Defaults to 200
 
         eta_stdp (float): STDP plasticity Learning rate constant; SORN1 and SORN2. Defaults to 0.004
 
@@ -33,13 +25,13 @@ class Sorn(object):
 
         eta_inhib (float): Intrinsic plasticity learning rate constant; SORN2 only. Defaults to 0.01
 
-        h_ip (float): Target firing rate. Defaults to 2 * Sorn._nu / Sorn._ne
+        h_ip (float): Target firing rate. Defaults to 2 * nu / ne
 
         mu_ip (float): Mean target firing rate. Defaults to 0.1
 
         sigma_ip (float): Variance of target firing rate. Defaults to 0.0
 
-        ni (int): Number of inhibitory units in the network. Defaults to int(0.2 * Sorn._ne)
+        ni (int): Number of inhibitory units in the network. Defaults to int(0.2*ne)
 
         time_steps (float): Total time steps of simulation
 
@@ -66,37 +58,34 @@ class Sorn(object):
     def __init__(self):
         pass
 
-    _nu = int(parser.get("Network_Config", "Nu"))
-    _ne = int(parser.get("Network_Config", "Ne"))
-    _ni = int(0.2 * _ne)
-    _eta_stdp = float(parser.get("Network_Config", "eta_stdp"))
-    _eta_inhib = float(parser.get("Network_Config", "eta_inhib"))
-    _eta_ip = float(parser.get("Network_Config", "eta_ip"))
-    _te_max = float(parser.get("Network_Config", "te_max"))
-    _ti_max = float(parser.get("Network_Config", "ti_max"))
-    _ti_min = float(parser.get("Network_Config", "ti_min"))
-    _te_min = float(parser.get("Network_Config", "te_min"))
-    _mu_ip = float(parser.get("Network_Config", "mu_ip"))
-    _sigma_ip = float(parser.get("Network_Config", "sigma_ip"))
-    _network_type_ee = str(parser.get("Network_Config", "network_type_ee"))
-    _network_type_ei = str(parser.get("Network_Config", "network_type_ei"))
-    _network_type_ie = str(parser.get("Network_Config", "network_type_ie"))
-    _lambda_ee = int(parser.get("Network_Config", "lambda_ee"))
-    _lambda_ei = int(parser.get("Network_Config", "lambda_ei"))
-    _lambda_ie = int(parser.get("Network_Config", "lambda_ie"))
-
+    nu = 10
+    ne = 200
+    ni = int(0.2 * ne)
+    eta_stdp = 0.004
+    eta_inhib = 0.001
+    eta_ip = 0.01
+    te_max = 1.0
+    ti_max = 0.5
+    ti_min = 0.0
+    te_min = 0.0
+    mu_ip = 0.1
+    sigma_ip = 0.0
+    network_type_ee = "Sparse"
+    network_type_ei = "Sparse"
+    network_type_ie = "Dense"
+    lambda_ee = 20
+    lambda_ei = 40
+    lambda_ie = 100
     @staticmethod
     def initialize_weight_matrix(
         network_type: str, synaptic_connection: str, self_connection: str, lambd_w: int
     ):
         """Wrapper for initializing the weight matrices for SORN
-
         Args:
             network_type (str): Spare or Dense
             synaptic_connection (str): EE,EI,IE. Note that Spare connection is defined only for EE connections
             self_connection (str): True or False: Synaptic delay or time delay
             lambd_w (int): Average number of incoming and outgoing connections per neuron
-
         Returns:
             weight_matrix (array): Array of connection strengths
         """
@@ -104,17 +93,17 @@ def initialize_weight_matrix(
         if (network_type == "Sparse") and (self_connection == "False"):
 
             # Generate weight matrix for E-E/ E-I connections with mean lamda incoming and out-going connections per neuron
-            assert (lambd_w <= Sorn._ne), "Number of connections per unit (lambda) should be less than number of units(Ne) in the pool and also Ne should be greater than 25"
+            assert (lambd_w <= Sorn.ne), "Number of connections per unit (lambda) should be less than number of units(Ne) in the pool and also Ne should be greater than 25"
             weight_matrix = Initializer.generate_lambd_connections(
-                synaptic_connection, Sorn._ne, Sorn._ni, lambd_w, lambd_std=1
+                synaptic_connection, Sorn.ne, Sorn.ni, lambd_w, lambd_std=1
             )
 
         # Dense matrix for W_ie
         elif (network_type == "Dense") and (self_connection == "False"):
 
             # Uniform distribution of weights
-            weight_matrix = np.random.uniform(0.0, 0.1, (Sorn._ne, Sorn._ni))
-            weight_matrix.reshape((Sorn._ne, Sorn._ni))
+            weight_matrix = np.random.uniform(0.0, 0.1, (Sorn.ne, Sorn.ni))
+            weight_matrix.reshape((Sorn.ne, Sorn.ni))
 
         return weight_matrix
 
@@ -123,35 +112,29 @@ def initialize_threshold_matrix(
         te_min: float, te_max: float, ti_min: float, ti_max: float
     ):
         """Initialize the threshold for excitatory and inhibitory neurons
-
         Args:
             te_min (float): Min threshold value for excitatory units
             te_max (float): Min threshold value for inhibitory units
             ti_min (float): Max threshold value for excitatory units
             ti_max (float): Max threshold value for inhibitory units
-
         Returns:
             te (array): Threshold values for excitatory units
             ti (array): Threshold values for inhibitory units
         """
 
-        te = np.random.uniform(te_min, te_max, (Sorn._ne, 1))
-        ti = np.random.uniform(ti_min, ti_max, (Sorn._ni, 1))
+        te = np.random.uniform(te_min, te_max, (Sorn.ne, 1))
+        ti = np.random.uniform(ti_min, ti_max, (Sorn.ni, 1))
 
         return te, ti
 
     @staticmethod
     def initialize_activity_vector(ne: int, ni: int):
         """Initialize the activity vectors X and Y for excitatory and inhibitory neurons
-
         Args:
             ne (int): Number of excitatory neurons
-
             ni (int): Number of inhibitory neurons
-
         Returns:
             x (array): Array of activity vectors of excitatory population
-
             y (array): Array of activity vectors of inhibitory population"""
 
         x = np.zeros((ne, 2))
@@ -162,69 +145,51 @@ def initialize_activity_vector(ne: int, ni: int):
 class Plasticity(Sorn):
     """Instance of class Sorn. Inherits the variables and functions defined in class Sorn.
     It encapsulates all plasticity mechanisms mentioned in the article. Inherits all attributed from parent class Sorn
-
     Args:
         nu (int): Number of input units. Defaults to 10
-
-        ne (int): Sorn._ne  # Number of excitatory units. Defaults to 200
-
+        ne (int): Sorn.ne  # Number of excitatory units. Defaults to 200
         eta_stdp (float): STDP plasticity Learning rate constant; SORN1 and SORN2. Defaults to 0.004
-
         eta_ip (float): Intrinsic plasticity learning rate constant; SORN1 and SORN2. Defaults to 0.001
-
         eta_inhib (float): Intrinsic plasticity learning rate constant; SORN2 only. Defaults to 0.01
-
-        h_ip (float): Target firing rate. Defaults to 2 * Sorn._nu / Sorn._ne
-
+        h_ip (float): Target firing rate. Defaults to 2 * Sorn.nu / Sorn.ne
         mu_ip (float): Mean target firing rate. Defaults to 0.1
-
         sigma_ip (float): Variance of target firing rate. Defaults to 0.0
-
-        ni (int): Number of inhibitory units in the network. Defaults to int(0.2 * Sorn._ne)
-
+        ni (int): Number of inhibitory units in the network. Defaults to int(0.2 * Sorn.ne)
         time_steps (float): Total time steps of simulation
-
         te_min (float): Excitatory minimum Threshold. Defaults to 0.0
-
         te_max (float): Excitatory maximum Threshold. Defaults to 1.0
-
         ti_min (float): Inhibitory minimum Threshold. Defaults to 0.0
-
         ti_max (float): Inhibitory maximum Threshold. Defaults to 0.5
     """
 
     def __init__(self):
 
         super().__init__()
-        self.nu = Sorn._nu  # Number of input units
-        self.ne = Sorn._ne  # Number of excitatory units
+        self.nu = Sorn.nu  # Number of input units
+        self.ne = Sorn.ne  # Number of excitatory units
         self.eta_stdp = (
-            Sorn._eta_stdp
+            Sorn.eta_stdp
         )  # STDP plasticity Learning rate constant; SORN1 and SORN2
         self.eta_ip = (
-            Sorn._eta_ip
+            Sorn.eta_ip
         )  # Intrinsic plasticity learning rate constant; SORN1 and SORN2
         self.eta_inhib = (
-            Sorn._eta_inhib
+            Sorn.eta_inhib
         )  # Intrinsic plasticity learning rate constant; SORN2 only
-        self.h_ip = 2 * Sorn._nu / Sorn._ne  # Target firing rate
-        self.mu_ip = Sorn._mu_ip  # Mean target firing rate
+        self.h_ip = 2 * Sorn.nu / Sorn.ne  # Target firing rate
+        self.mu_ip = Sorn.mu_ip  # Mean target firing rate
         # Number of inhibitory units in the network
-        self.ni = int(0.2 * Sorn._ne)
-        self.time_steps = Sorn._time_steps  # Total time steps of simulation
-        self.te_min = Sorn._te_min  # Excitatory minimum Threshold
-        self.te_max = Sorn._te_max  # Excitatory maximum Threshold
+        self.ni = int(0.2 * Sorn.ne)
+        self.time_steps = Sorn.time_steps  # Total time steps of simulation
+        self.te_min = Sorn.te_min  # Excitatory minimum Threshold
+        self.te_max = Sorn.te_max  # Excitatory maximum Threshold
 
     def stdp(self, wee: np.array, x: np.array, cutoff_weights: list):
         """Apply STDP rule : Regulates synaptic strength between the pre(Xj) and post(Xi) synaptic neurons
-
         Args:
             wee (array):  Weight matrix
-
             x (array): Excitatory network activity
-
             cutoff_weights (list): Maximum and minimum weight ranges
-
         Returns:
             wee (array):  Weight matrix
         """
@@ -262,12 +227,9 @@ def stdp(self, wee: np.array, x: np.array, cutoff_weights: list):
 
     def ip(self, te: np.array, x: np.array):
         """Intrinsic Plasiticity mechanism
-
         Args:
             te (array): Threshold vector of excitatory units
-
             x (array): Excitatory network activity
-
         Returns:
             te (array): Threshold vector of excitatory units
         """
@@ -290,10 +252,8 @@ def ip(self, te: np.array, x: np.array):
     @staticmethod
     def ss(wee: np.array):
         """Synaptic Scaling or Synaptic Normalization
-
         Args:
             wee (array):  Weight matrix
-
         Returns:
             wee (array):  Scaled Weight matrix
         """
@@ -302,16 +262,11 @@ def ss(wee: np.array):
 
     def istdp(self, wei: np.array, x: np.array, y: np.array, cutoff_weights: list):
         """Apply iSTDP rule, which regulates synaptic strength between the pre inhibitory(Xj) and post Excitatory(Xi) synaptic neurons
-
         Args:
             wei (array): Synaptic strengths from inhibitory to excitatory
-
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             cutoff_weights (list): Maximum and minimum weight ranges
-
         Returns:
             wei (array): Synaptic strengths from inhibitory to excitatory"""
 
@@ -355,10 +310,8 @@ def istdp(self, wei: np.array, x: np.array, y: np.array, cutoff_weights: list):
     @staticmethod
     def structural_plasticity(wee: np.array):
         """Add new connection value to the smallest weight between excitatory units randomly
-
         Args:
             wee (array): Weight matrix
-
         Returns:
             wee (array):  Weight matrix"""
 
@@ -383,31 +336,29 @@ def structural_plasticity(wee: np.array):
     @staticmethod
     def initialize_plasticity():
         """Initialize weight matrices for plasticity phase based on network configuration
-
         Args:
             kwargs (self.__dict__): All arguments are inherited from Sorn attributes
-
         Returns:
             tuple(array): Weight matrices WEI, WEE, WIE and threshold matrices Te, Ti and Initial state vectors X,Y """
 
         sorn_init = Sorn()
         WEE_init = sorn_init.initialize_weight_matrix(
-            network_type=Sorn._network_type_ee,
+            network_type=Sorn.network_type_ee,
             synaptic_connection="EE",
             self_connection="False",
-            lambd_w=Sorn._lambda_ee,
+            lambd_w=Sorn.lambda_ee,
         )
         WEI_init = sorn_init.initialize_weight_matrix(
-            network_type=Sorn._network_type_ei,
+            network_type=Sorn.network_type_ei,
             synaptic_connection="EI",
             self_connection="False",
-            lambd_w=Sorn._lambda_ei,
+            lambd_w=Sorn.lambda_ei,
         )
         WIE_init = sorn_init.initialize_weight_matrix(
-            network_type=Sorn._network_type_ie,
+            network_type=Sorn.network_type_ie,
             synaptic_connection="IE",
             self_connection="False",
-            lambd_w=Sorn._lambda_ie,
+            lambd_w=Sorn.lambda_ie,
         )
 
         Wee_init = Initializer.zero_sum_incoming_check(WEE_init)
@@ -433,10 +384,10 @@ def initialize_plasticity():
         normalized_wie = Initializer.normalize_weight_matrix(Wie_init)
 
         te_init, ti_init = sorn_init.initialize_threshold_matrix(
-            Sorn._te_min, Sorn._te_max, Sorn._ti_min, Sorn._ti_max
+            Sorn.te_min, Sorn.te_max, Sorn.ti_min, Sorn.ti_max
         )
         x_init, y_init = sorn_init.initialize_activity_vector(
-            Sorn._ne, Sorn._ni)
+            Sorn.ne, Sorn.ni)
 
         # Initializing variables from sorn_initialize.py
 
@@ -453,12 +404,9 @@ def initialize_plasticity():
 
 class MatrixCollection(Sorn):
     """Collect all matrices initialized and updated during simulation (plasiticity and training phases)
-
     Args:
         phase (str): Training or Plasticity phase
-
         matrices (dict): Network activity, threshold and connection matrices
-
     Returns:
         MatrixCollection instance"""
 
@@ -469,7 +417,7 @@ def __init__(self, phase: str, matrices: dict = None):
         self.matrices = matrices
         if self.phase == "plasticity" and self.matrices == None:
 
-            self.time_steps = Sorn._time_steps + 1  # Total training steps
+            self.time_steps = Sorn.time_steps + 1  # Total training steps
             self.Wee, self.Wei, self.Wie, self.Te, self.Ti, self.X, self.Y = (
                 [0] * self.time_steps,
                 [0] * self.time_steps,
@@ -492,7 +440,7 @@ def __init__(self, phase: str, matrices: dict = None):
 
         elif self.phase == "plasticity" and self.matrices != None:
 
-            self.time_steps = Sorn._time_steps + 1  # Total training steps
+            self.time_steps = Sorn.time_steps + 1  # Total training steps
             self.Wee, self.Wei, self.Wie, self.Te, self.Ti, self.X, self.Y = (
                 [0] * self.time_steps,
                 [0] * self.time_steps,
@@ -514,7 +462,7 @@ def __init__(self, phase: str, matrices: dict = None):
         elif self.phase == "training":
 
             # NOTE:time_steps here is diferent for plasticity and training phase
-            self.time_steps = Sorn._time_steps + 1  # Total training steps
+            self.time_steps = Sorn.time_steps + 1  # Total training steps
             self.Wee, self.Wei, self.Wie, self.Te, self.Ti, self.X, self.Y = (
                 [0] * self.time_steps,
                 [0] * self.time_steps,
@@ -535,16 +483,11 @@ def __init__(self, phase: str, matrices: dict = None):
 
     def weight_matrix(self, wee: np.array, wei: np.array, wie: np.array, i: int):
         """Update weight matrices
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wei (array): Inhibitory-Excitatory weight matrix
-
             wie (array): Excitatory-Inhibitory weight matrix
-
             i (int): Time step
-
         Returns:
             tuple (array): Weight Matrices Wee, Wei, Wie"""
 
@@ -556,12 +499,9 @@ def weight_matrix(self, wee: np.array, wei: np.array, wie: np.array, i: int):
 
     def threshold_matrix(self, te: np.array, ti: np.array, i: int):
         """Update threshold matrices
-
         Args:
             te (array): Excitatory threshold
-
             ti (array): Inhibitory threshold
-
             i (int): Time step
         Returns:
             tuple (array): Threshold Matrices Te and Ti"""
@@ -574,14 +514,10 @@ def network_activity_t(
         self, excitatory_net: np.array, inhibitory_net: np.array, i: int
     ):
         """Network state at current time step
-
         Args:
             excitatory_net (array): Excitatory network activity
-
             inhibitory_net (array): Inhibitory network activity
-
             i (int): Time step
-
         Returns:
             tuple (array): Updated Excitatory and Inhibitory states
         """
@@ -593,14 +529,10 @@ def network_activity_t(
 
     def network_activity_t_1(self, x: np.array, y: np.array, i: int):
         """Network activity at previous time step
-
         Args:
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             i (int): Time step
-
         Returns:
             tuple (array): Previous Excitatory and Inhibitory states
         """
@@ -614,33 +546,28 @@ def network_activity_t_1(self, x: np.array, y: np.array, i: int):
 class NetworkState(Plasticity):
 
     """The evolution of network states
-
     Args:
         v_t (array): External input/stimuli
-
     Returns:
         instance (object): NetworkState instance"""
 
     def __init__(self, v_t: np.array):
         super().__init__()
         self.v_t = v_t
-        assert Sorn._nu == len(
+        assert Sorn.nu == len(
             self.v_t
         ), "Input units and input size mismatch: {} != {}".format(
-            Sorn._nu, len(self.v_t)
+            Sorn.nu, len(self.v_t)
         )
-        if Sorn._nu != Sorn._ne:
-            self.v_t = list(self.v_t) + [0.0] * (Sorn._ne - Sorn._nu)
+        if Sorn.nu != Sorn.ne:
+            self.v_t = list(self.v_t) + [0.0] * (Sorn.ne - Sorn.nu)
         self.v_t = np.expand_dims(self.v_t, 1)
 
     def incoming_drive(self, weights: np.array, activity_vector: np.array):
         """Excitatory Post synaptic potential towards neurons in the reservoir in the absence of external input
-
         Args:
             weights (array): Synaptic strengths
-
             activity_vector (list): Acitivity of inhibitory or Excitatory neurons
-
         Returns:
             incoming (array): Excitatory Post synaptic potential towards neurons
         """
@@ -658,20 +585,13 @@ def excitatory_network_state(
         white_noise_e: np.array,
     ):
         """Activity of Excitatory neurons in the network
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wei (array): Inhibitory-Excitatory weight matrix
-
             te (array): Excitatory threshold
-
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             white_noise_e (array): Gaussian noise
-
         Returns:
             x (array): Current Excitatory network activity
         """
@@ -703,24 +623,18 @@ def inhibitory_network_state(
         self, wie: np.array, ti: np.array, y: np.array, white_noise_i: np.array
     ):
         """Activity of Excitatory neurons in the network
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wie (array): Excitatory-Inhibitory weight matrix
-
             ti (array): Inhibitory threshold
-
             y (array): Inhibitory network activity
-
             white_noise_i (array): Gaussian noise
-
         Returns:
             y (array): Current Inhibitory network activity"""
 
         wie = np.asarray(wie)
         yt = y[:, 1]
-        yt = yt.reshape(Sorn._ne, 1)
+        yt = yt.reshape(Sorn.ne, 1)
 
         incoming_drive_e = np.expand_dims(
             self.incoming_drive(weights=wie, activity_vector=yt), 1
@@ -742,20 +656,13 @@ def recurrent_drive(
         white_noise_e: np.array,
     ):
         """Network state due to recurrent drive received by the each unit at time t+1. Activity of Excitatory neurons without external stimuli
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wei (array): Inhibitory-Excitatory weight matrix
-
             te (array): Excitatory threshold
-
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             white_noise_e (array): Gaussian noise
-
         Returns:
             xt (array): Recurrent network state
         """
@@ -783,27 +690,17 @@ def recurrent_drive(
 class Simulator_(Sorn):
 
     """Simulate SORN using external input/noise using the fresh or pretrained matrices
-
     Args:
         inputs (np.array, optional): External stimuli. Defaults to None.
-
         phase (str, optional): Plasticity phase. Defaults to "plasticity".
-
         matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
         time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
         noise (bool, optional): If True, noise will be added. Defaults to True.
-
     Returns:
         plastic_matrices (dict): Network states, connections and threshold matrices
-
         X_all (array): Excitatory network activity collected during entire simulation steps
-
         Y_all (array): Inhibitory network activity collected during entire simulation steps
-
         R_all (array): Recurrent network activity collected during entire simulation steps
-
         frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
     def __init__(self):
@@ -821,29 +718,18 @@ def simulate_sorn(
         **kwargs
     ):
         """Simulation/Plasticity phase
-
         Args:
             inputs (np.array, optional): External stimuli. Defaults to None.
-
             phase (str, optional): Plasticity phase. Defaults to "plasticity"
-
             matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
             time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
             noise (bool, optional): If True, noise will be added. Defaults to True.
-
             freeze (list, optional): List of synaptic plasticity mechanisms which will be turned off during simulation. Defaults to None.
-
         Returns:
             plastic_matrices (dict): Network states, connections and threshold matrices
-
             X_all (array): Excitatory network activity collected during entire simulation steps
-
             Y_all (array): Inhibitory network activity collected during entire simulation steps
-
             R_all (array): Recurrent network activity collected during entire simulation steps
-
             frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
         assert (
@@ -851,35 +737,35 @@ def simulate_sorn(
         ), "Phase can be either 'plasticity' or 'training'"
 
         self.time_steps = time_steps
-        Sorn._time_steps = time_steps
+        Sorn.time_steps = time_steps
         self.phase = phase
         self.matrices = matrices
         self.freeze = [] if freeze == None else freeze
 
         kwargs_ = [
-            "_ne",
-            "_nu",
-            "_network_type_ee",
-            "_network_type_ei",
-            "_network_type_ie",
-            "_lambda_ee",
-            "_lambda_ei",
-            "_lambda_ie",
-            "_eta_stdp",
-            "_eta_inhib",
-            "_eta_ip",
-            "_te_max",
-            "_ti_max",
-            "_ti_min",
-            "_te_min",
-            "_mu_ip",
-            "_sigma_ip",
+            "ne",
+            "nu",
+            "network_type_ee",
+            "network_type_ei",
+            "network_type_ie",
+            "lambda_ee",
+            "lambda_ei",
+            "lambda_ie",
+            "eta_stdp",
+            "eta_inhib",
+            "eta_ip",
+            "te_max",
+            "ti_max",
+            "ti_min",
+            "te_min",
+            "mu_ip",
+            "sigma_ip",
         ]
         for key, value in kwargs.items():
             if key in kwargs_:
                 setattr(Sorn, key, value)
-        # assert Sorn._nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
-        Sorn._ni = int(0.2 * Sorn._ne)
+        # assert Sorn.nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
+        Sorn.ni = int(0.2 * Sorn.ne)
 
         # Initialize/Get the weight, threshold matrices and activity vectors
         matrix_collection = MatrixCollection(
@@ -898,10 +784,10 @@ def simulate_sorn(
 
             if noise:
                 white_noise_e = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ne
+                    mu=0.0, sigma=0.04, t=Sorn.ne
                 )
                 white_noise_i = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ni
+                    mu=0.0, sigma=0.04, t=Sorn.ni
                 )
             else:
                 white_noise_e, white_noise_i = 0.0, 0.0
@@ -912,10 +798,10 @@ def simulate_sorn(
 
             # Buffers to get the resulting x and y vectors at the current time step and update the master matrix
             x_buffer, y_buffer = np.zeros(
-                (Sorn._ne, 2)), np.zeros((Sorn._ni, 2))
+                (Sorn.ne, 2)), np.zeros((Sorn.ni, 2))
 
             te_buffer, ti_buffer = np.zeros(
-                (Sorn._ne, 1)), np.zeros((Sorn._ni, 1))
+                (Sorn.ne, 1)), np.zeros((Sorn.ni, 1))
 
             Wee, Wei, Wie = (
                 matrix_collection.Wee,
@@ -1002,29 +888,18 @@ def simulate_sorn(
 
 class Trainer_(Sorn):
     """Train the network with the fresh or pretrained network matrices and external stimuli
-
     Args:
         inputs (np.array, optional): External stimuli. Defaults to None.
-
         phase (str, optional): Training phase. Defaults to "training".
-
         matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
         time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
         noise (bool, optional): If True, noise will be added. Defaults to True.
-
         freeze (list, optional): List of synaptic plasticity mechanisms which will be turned off during simulation. Defaults to None.
-
     Returns:
         plastic_matrices (dict): Network states, connections and threshold matrices
-
         X_all (array): Excitatory network activity collected during entire simulation steps
-
         Y_all (array): Inhibitory network activity collected during entire simulation steps
-
         R_all (array): Recurrent network activity collected during entire simulation steps
-
         frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
     def __init__(self):
@@ -1042,27 +917,17 @@ def train_sorn(
         **kwargs
     ):
         """Train the network with the fresh or pretrained network matrices and external stimuli
-
         Args:
             inputs (np.array, optional): External stimuli. Defaults to None.
-
             phase (str, optional): Training phase. Defaults to "training".
-
             matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
             time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
             noise (bool, optional): If True, noise will be added. Defaults to True.
-
         Returns:
             plastic_matrices (dict): Network states, connections and threshold matrices
-
             X_all (array): Excitatory network activity collected during entire simulation steps
-
             Y_all (array): Inhibitory network activity collected during entire simulation steps
-
             R_all (array): Recurrent network activity collected during entire simulation steps
-
             frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
         assert (
@@ -1070,34 +935,34 @@ def train_sorn(
         ), "Phase can be either 'plasticity' or 'training'"
 
         kwargs_ = [
-            "_ne",
-            "_nu",
-            "_network_type_ee",
-            "_network_type_ei",
-            "_network_type_ie",
-            "_lambda_ee",
-            "_lambda_ei",
-            "_lambda_ie",
-            "_eta_stdp",
-            "_eta_inhib",
-            "_eta_ip",
-            "_te_max",
-            "_ti_max",
-            "_ti_min",
-            "_te_min",
-            "_mu_ip",
-            "_sigma_ip",
+            "ne",
+            "nu",
+            "network_type_ee",
+            "network_type_ei",
+            "network_type_ie",
+            "lambda_ee",
+            "lambda_ei",
+            "lambda_ie",
+            "eta_stdp",
+            "eta_inhib",
+            "eta_ip",
+            "te_max",
+            "ti_max",
+            "ti_min",
+            "te_min",
+            "mu_ip",
+            "sigma_ip",
         ]
         for key, value in kwargs.items():
             if key in kwargs_:
                 setattr(Sorn, key, value)
-        Sorn._ni = int(0.2 * Sorn._ne)
-        # assert Sorn._nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
+        Sorn.ni = int(0.2 * Sorn.ne)
+        # assert Sorn.nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
 
         self.phase = phase
         self.matrices = matrices
         self.time_steps = time_steps
-        Sorn._time_steps = time_steps
+        Sorn.time_steps = time_steps
         self.inputs = np.asarray(inputs)
         self.freeze = [] if freeze == None else freeze
 
@@ -1114,10 +979,10 @@ def train_sorn(
 
             if noise:
                 white_noise_e = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ne
+                    mu=0.0, sigma=0.04, t=Sorn.ne
                 )
                 white_noise_i = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ni
+                    mu=0.0, sigma=0.04, t=Sorn.ni
                 )
             else:
                 white_noise_e = 0.0
@@ -1129,9 +994,9 @@ def train_sorn(
 
             # Buffers to get the resulting x and y vectors at the current time step and update the master matrix
             x_buffer, y_buffer = np.zeros(
-                (Sorn._ne, 2)), np.zeros((Sorn._ni, 2))
+                (Sorn.ne, 2)), np.zeros((Sorn.ni, 2))
             te_buffer, ti_buffer = np.zeros(
-                (Sorn._ne, 1)), np.zeros((Sorn._ni, 1))
+                (Sorn.ne, 1)), np.zeros((Sorn.ni, 1))
 
             Wee, Wei, Wie = (
                 matrix_collection.Wee,
@@ -1221,4 +1086,4 @@ def train_sorn(
 Trainer = Trainer_()
 Simulator = Simulator_()
 if __name__ == "__main__":
-    pass
+    pass
\ No newline at end of file
diff --git a/build/lib/sorn/utils.py b/build/lib/sorn/utils.py
index 070cbea..85a230b 100644
--- a/build/lib/sorn/utils.py
+++ b/build/lib/sorn/utils.py
@@ -424,7 +424,7 @@ def __init__(self):
     def hist_incoming_conn(
         weights: np.array, bin_size: int, histtype: str, savefig: bool
     ):
-        """Plot the histogram of number of incoming connections per neuron
+        """Plot the histogram of number of presynaptic connections per neuron
 
         Args:
             weights (array): Connection weights
@@ -438,36 +438,30 @@ def hist_incoming_conn(
         Returns:
             plot (matplotlib.pyplot): plot object
         """
-
-        # Plot the histogram of distribution of number of incoming connections in the network
-
         num_incoming_weights = np.sum(np.array(weights) > 0, axis=0)
 
         plt.figure(figsize=(12, 5))
-
-        plt.title("Number of incoming connections")
         plt.xlabel("Number of connections")
-        plt.ylabel("Count")
-        plt.hist(num_incoming_weights, bins=bin_size, histtype=histtype)
-
-        # Empirical average and variance are computed
-        avg = np.mean(num_incoming_weights)
-        var = np.var(num_incoming_weights)
-        # From hist plot above, it is clear that connection count follow gaussian distribution
-        pdf_x = np.linspace(
-            np.min(num_incoming_weights), np.max(num_incoming_weights), 100
-        )
-        pdf_y = 1.0 / np.sqrt(2 * np.pi * var) * np.exp(-0.5 * (pdf_x - avg) ** 2 / var)
+        plt.ylabel("Probability")
 
-        plt.plot(pdf_x, pdf_y, "k--", label="Gaussian fit")
-        plt.axvline(x=avg, color="r", linestyle="--", label="Mean")
-        plt.legend()
+        # Fit a normal distribution to the data
+        mu, std = norm.fit(num_incoming_weights)
+        plt.hist(num_incoming_weights, bins=bin_size, density=True, alpha=0.6, color='b')
+
+        # PDF
+        xmin, xmax = plt.xlim()
+        x = np.linspace(xmin, xmax, max(num_incoming_weights))
+        p = norm.pdf(x, mu, std)
+        plt.plot(x, p, 'k', linewidth=2)
+        title = "Distribution of presynaptic connections: mu = %.2f,  std = %.2f" % (mu, std)
+        plt.title(title)
 
         if savefig:
             plt.savefig("hist_incoming_conn")
 
         return plt.show()
 
+
     @staticmethod
     def hist_outgoing_conn(
         weights: np.array, bin_size: int, histtype: str, savefig: bool
@@ -491,23 +485,20 @@ def hist_outgoing_conn(
         num_outgoing_weights = np.sum(np.array(weights) > 0, axis=1)
 
         plt.figure(figsize=(12, 5))
-
-        plt.hist(num_outgoing_weights, bins=bin_size, histtype=histtype)
-        plt.title("Number of Outgoing connections")
         plt.xlabel("Number of connections")
-        plt.ylabel("Count")
-        # Empirical average and variance are computed
-        avg = np.mean(num_outgoing_weights)
-        var = np.var(num_outgoing_weights)
+        plt.ylabel("Probability")
 
-        pdf_x = np.linspace(
-            np.min(num_outgoing_weights), np.max(num_outgoing_weights), 100
-        )
-        pdf_y = 1.0 / np.sqrt(2 * np.pi * var) * np.exp(-0.5 * (pdf_x - avg) ** 2 / var)
+        # Fit a normal distribution to the data
+        mu, std = norm.fit(num_outgoing_weights)
+        plt.hist(num_outgoing_weights, bins=bin_size, density=True, alpha=0.6, color='b')
 
-        plt.plot(pdf_x, pdf_y, "k--", label="Gaussian fit")
-        plt.axvline(x=avg, color="r", linestyle="--", label="Mean")
-        plt.legend()
+        # PDF
+        xmin, xmax = plt.xlim()
+        x = np.linspace(xmin, xmax, max(num_outgoing_weights))
+        p = norm.pdf(x, mu, std)
+        plt.plot(x, p, 'k', linewidth=2)
+        title = "Distribution of post synaptic connections: mu = %.2f,  std = %.2f" % (mu, std)
+        plt.title(title)
 
         if savefig:
             plt.savefig("hist_outgoing_conn")
@@ -516,17 +507,13 @@ def hist_outgoing_conn(
 
     @staticmethod
     def network_connection_dynamics(
-        connection_counts: np.array, initial_steps: int, final_steps: int, savefig: bool
+        connection_counts: np.array, savefig: bool
     ):
         """Plot number of positive connection in the excitatory pool
 
         Args:
             connection_counts (array) - 1D Array of number of connections in the network per time step
 
-            initial_steps (int) - Plot for initial steps
-
-            final_steps (int) - Plot for final steps
-
             savefig (bool) - If True plot will be saved as png file in the cwd
 
         Returns:
@@ -545,30 +532,6 @@ def network_connection_dynamics(
         plt.legend(loc="upper right")
         plt.tight_layout()
 
-        # Inset plot for initial simulation steps
-
-        ax2 = plt.axes([0, 0, 1, 1])
-
-        # Set the position and relative size of the inset axes within ax1
-        ip = InsetPosition(ax1, [0.25, 0.4, 0.3, 0.3])
-        ax2.set_axes_locator(ip)
-        ax2.plot(connection_counts[0:initial_steps])
-        plt.margins(x=0)
-        ax2.set_title("Initial %s time steps of Decay Phase" % initial_steps)
-        ax2.set_xticks(ax2.get_xticks()[::2])
-
-        # End Inset plot
-        ax3 = plt.axes([0, 0, 0, 0])
-
-        # Set the position and relative size of the inset axes within ax1
-        ip1 = InsetPosition(ax1, [0.6, 0.4, 0.3, 0.3])
-        ax3.set_axes_locator(ip1)
-        # Plot the last 10000 time steps
-        ax3.plot(connection_counts[-final_steps:])
-        plt.margins(x=0)
-        ax3.set_title("Final %s time steps of Stable Phase" % final_steps)
-        ax3.set_xticks(ax3.get_xticks()[::1])
-
         if savefig:
             plt.savefig("connection_dynamics")
 
@@ -631,9 +594,9 @@ def scatter_plot(spike_train: np.array, savefig: bool):
         plt.legend(loc="upper left")
 
         plt.scatter(y, x, s=0.1, color="black")
-
-        plt.xlabel("Time(ms)")
-        plt.ylabel("Neuron #")
+        plt.title('Spike Trains')
+        plt.xlabel("Time step")
+        plt.ylabel("Neuron")
         plt.legend(loc="upper left")
 
         if savefig:
@@ -663,13 +626,13 @@ def raster_plot(spike_train: np.array, savefig: bool):
         firing_rates = Statistics.firing_rate_network(spike_train).tolist()
         plt.plot(firing_rates, label="Firing rate")
         plt.legend(loc="upper left")
-
+        plt.title('Spike Trains')
         # Get the indices where spike_train is 1
         x, y = np.argwhere(spike_train.T == 1).T
 
         plt.plot(y, x, "|r")
-        plt.xlabel("Time(ms)")
-        plt.ylabel("Neuron #")
+        plt.xlabel("Time step")
+        plt.ylabel("Neuron")
 
         if savefig:
             plt.savefig("RasterSpikeTrain.png")
@@ -698,7 +661,7 @@ def correlation(corr: np.array, savefig: bool):
         # Custom diverging colormap
         cmap = sns.diverging_palette(220, 10, as_cmap=True)
 
-        sns.heatmap(
+        ax = sns.heatmap(
             corr,
             mask=mask,
             cmap=cmap,
@@ -710,6 +673,10 @@ def correlation(corr: np.array, savefig: bool):
             linewidths=0.0,
             cbar_kws={"shrink": 0.9},
         )
+        plt.title('Pearson correlation between neurons', fontsize = 20)
+        plt.xlabel('Neurons', fontsize = 15)
+        plt.ylabel('Neurons', fontsize = 15)
+
         if savefig:
             plt.savefig("Correlation between neurons")
         return None
@@ -724,7 +691,7 @@ def isi_exponential_fit(
         Args:
             spike_train (array): Array of spike trains
 
-            neuron (int): If True, firing rate of the network will be plotted
+            neuron (int): Target neuron
 
             bin_size (int): Spike train will be splitted into bins of size bin_size
 
@@ -733,11 +700,8 @@ def isi_exponential_fit(
         Returns:
             plot object"""
 
-        spike_time = Statistics.spike_times(
-            spike_train.T[neuron]
-        )  # Locate the spike time of the target neuron
 
-        isi = Statistics.spike_time_intervals(spike_time)
+        isi = Statistics.spike_time_intervals(spike_train[:,neuron])
 
         y, x = np.histogram(sorted(isi), bins=bin_size)
 
@@ -755,8 +719,9 @@ def exponential_func(y, a, b, c):
             exponential_func(x[1:bin_size], *popt),
             label="Exponential fit",
         )
+        plt.title('Distribution of Inter Spike Intervals and Exponential Curve Fit')
         plt.scatter(x[1:bin_size], y[1:bin_size], s=2.0, color="black", label="ISI")
-        plt.xlabel("ISI(time step)")
+        plt.xlabel("ISI")
         plt.ylabel("Frequency")
         plt.legend()
 
@@ -783,13 +748,13 @@ def weight_distribution(weights: np.array, bin_size: int, savefig: bool):
             weights >= 0.01
         ]  # Remove the weight values less than 0.01 # As reported in article SORN 2013
         y, x = np.histogram(weights, bins=bin_size)  # Create histogram with bin_size
-
+        plt.title('Synaptic weight distribution')
         plt.scatter(x[:-1], y, s=2.0, c="black")
-        plt.xlabel("Weight")
+        plt.xlabel("Connection strength")
         plt.ylabel("Frequency")
 
         if savefig:
-            plt.savefig("weight distribution")
+            plt.savefig("weight_distribution")
 
         return plt.show()
 
@@ -808,15 +773,16 @@ def linear_lognormal_fit(weights: np.array, num_points: int, savefig: bool):
         Returns:
             plot object"""
 
-        X = weights.copy()
+        weights = np.array(weights.tolist())
+        weights = weights[weights >= 0.01]
 
-        M = float(np.mean(X))  # Geometric mean
-        s = float(np.std(X))  # Geometric standard deviation
+        M = float(np.mean(weights))  # Geometric mean
+        s = float(np.std(weights))  # Geometric standard deviation
 
         # Lognormal distribution parameters
 
-        mu = float(np.mean(np.log(X)))  # Mean of log(X)
-        sigma = float(np.std(np.log(X)))  # Standard deviation of log(X)
+        mu = float(np.mean(np.log(weights)))  # Mean of log(X)
+        sigma = float(np.std(np.log(weights)))  # Standard deviation of log(X)
         shape = sigma  # Scipy's shape parameter
         scale = np.exp(mu)  # Scipy's scale parameter
         median = np.exp(mu)
@@ -832,7 +798,7 @@ def linear_lognormal_fit(weights: np.array, num_points: int, savefig: bool):
         )
 
         plt.figure(figsize=(12, 4.5))
-
+        plt.title('Curve fit on connection weight distribution')
         # Figure on linear scale
         plt.subplot(121)
         plt.plot(x, pdf)
@@ -1117,8 +1083,7 @@ def spike_time_intervals(spike_train):
         """
 
         spike_times = Statistics.spike_times(spike_train)
-        # isi = sorted(np.diff(spike_times)[-1])
-        isi = np.diff(spike_times)[-1]
+        isi = np.diff(spike_times[-1])
         return isi
 
     @staticmethod
diff --git a/dist/sorn-0.5.2-py3-none-any.whl b/dist/sorn-0.5.2-py3-none-any.whl
deleted file mode 100644
index c0d84a4..0000000
Binary files a/dist/sorn-0.5.2-py3-none-any.whl and /dev/null differ
diff --git a/dist/sorn-0.5.2.tar.gz b/dist/sorn-0.5.2.tar.gz
deleted file mode 100644
index 85cbcc7..0000000
Binary files a/dist/sorn-0.5.2.tar.gz and /dev/null differ
diff --git a/dist/sorn-0.5.7-py3-none-any.whl b/dist/sorn-0.5.7-py3-none-any.whl
new file mode 100644
index 0000000..c65e6d0
Binary files /dev/null and b/dist/sorn-0.5.7-py3-none-any.whl differ
diff --git a/dist/sorn-0.5.7.tar.gz b/dist/sorn-0.5.7.tar.gz
new file mode 100644
index 0000000..2bd354c
Binary files /dev/null and b/dist/sorn-0.5.7.tar.gz differ
diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle
index 8e29f09..e66444a 100644
Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ
diff --git a/docs/build/doctrees/installation.doctree b/docs/build/doctrees/installation.doctree
index 416729c..dc659dc 100644
Binary files a/docs/build/doctrees/installation.doctree and b/docs/build/doctrees/installation.doctree differ
diff --git a/docs/build/doctrees/reference.doctree b/docs/build/doctrees/reference.doctree
index 18e380f..4d74c95 100644
Binary files a/docs/build/doctrees/reference.doctree and b/docs/build/doctrees/reference.doctree differ
diff --git a/docs/build/doctrees/usage.doctree b/docs/build/doctrees/usage.doctree
index a75c31d..83b6245 100644
Binary files a/docs/build/doctrees/usage.doctree and b/docs/build/doctrees/usage.doctree differ
diff --git a/docs/build/html/_modules/index.html b/docs/build/html/_modules/index.html
index 946eb80..6852b8d 100644
--- a/docs/build/html/_modules/index.html
+++ b/docs/build/html/_modules/index.html
@@ -60,7 +60,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/_modules/sorn/sorn.html b/docs/build/html/_modules/sorn/sorn.html
index 591b697..8346934 100644
--- a/docs/build/html/_modules/sorn/sorn.html
+++ b/docs/build/html/_modules/sorn/sorn.html
@@ -60,7 +60,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
@@ -179,7 +179,6 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 <span class="kn">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">division</span>
 <span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
 <span class="kn">import</span> <span class="nn">os</span>
-<span class="kn">from</span> <span class="nn">configparser</span> <span class="kn">import</span> <span class="n">ConfigParser</span>
 <span class="kn">import</span> <span class="nn">random</span>
 
 <span class="k">try</span><span class="p">:</span>
@@ -187,13 +186,6 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 <span class="k">except</span><span class="p">:</span>
     <span class="kn">from</span> <span class="nn">utils</span> <span class="kn">import</span> <span class="n">Initializer</span>
 
-<span class="n">parser</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="p">()</span>
-<span class="n">config_file</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
-    <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)),</span> <span class="s2">&quot;configuration.ini&quot;</span>
-<span class="p">)</span>
-<span class="n">parser</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">config_file</span><span class="p">)</span>
-
-
 <div class="viewcode-block" id="Sorn"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Sorn">[docs]</a><span class="k">class</span> <span class="nc">Sorn</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
 
     <span class="sd">&quot;&quot;&quot; This class wraps initialization of the network and its parameters</span>
@@ -240,29 +232,27 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 <span class="sd">        lambda_ie (int):  Number of connections to and from a single excitatory unit to inhibitory unit at initialization. Defaults to 100&quot;&quot;&quot;</span>
 
     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
-        <span class="k">pass</span>
 
-    <span class="n">_nu</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;Nu&quot;</span><span class="p">))</span>
-    <span class="n">_ne</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;Ne&quot;</span><span class="p">))</span>
-    <span class="n">_ni</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.2</span> <span class="o">*</span> <span class="n">_ne</span><span class="p">)</span>
-    <span class="n">_eta_stdp</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;eta_stdp&quot;</span><span class="p">))</span>
-    <span class="n">_eta_inhib</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;eta_inhib&quot;</span><span class="p">))</span>
-    <span class="n">_eta_ip</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;eta_ip&quot;</span><span class="p">))</span>
-    <span class="n">_te_max</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;te_max&quot;</span><span class="p">))</span>
-    <span class="n">_ti_max</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;ti_max&quot;</span><span class="p">))</span>
-    <span class="n">_ti_min</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;ti_min&quot;</span><span class="p">))</span>
-    <span class="n">_te_min</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;te_min&quot;</span><span class="p">))</span>
-    <span class="n">_mu_ip</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;mu_ip&quot;</span><span class="p">))</span>
-    <span class="n">_sigma_ip</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;sigma_ip&quot;</span><span class="p">))</span>
-    <span class="n">_network_type_ee</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;network_type_ee&quot;</span><span class="p">))</span>
-    <span class="n">_network_type_ei</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;network_type_ei&quot;</span><span class="p">))</span>
-    <span class="n">_network_type_ie</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;network_type_ie&quot;</span><span class="p">))</span>
-    <span class="n">_lambda_ee</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;lambda_ee&quot;</span><span class="p">))</span>
-    <span class="n">_lambda_ei</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;lambda_ei&quot;</span><span class="p">))</span>
-    <span class="n">_lambda_ie</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">parser</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;Network_Config&quot;</span><span class="p">,</span> <span class="s2">&quot;lambda_ie&quot;</span><span class="p">))</span>
-
-<div class="viewcode-block" id="Sorn.initialize_weight_matrix"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Sorn.initialize_weight_matrix">[docs]</a>    <span class="nd">@staticmethod</span>
-    <span class="k">def</span> <span class="nf">initialize_weight_matrix</span><span class="p">(</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">nu</span> <span class="o">=</span> <span class="mi">10</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ne</span> <span class="o">=</span> <span class="mi">200</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ni</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.2</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">eta_stdp</span> <span class="o">=</span> <span class="mf">0.004</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">eta_inhib</span> <span class="o">=</span> <span class="mf">0.001</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">eta_ip</span> <span class="o">=</span> <span class="mf">0.01</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">te_max</span> <span class="o">=</span> <span class="mf">1.0</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ti_max</span> <span class="o">=</span> <span class="mf">0.5</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ti_min</span> <span class="o">=</span> <span class="mf">0.0</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">te_min</span> <span class="o">=</span> <span class="mf">0.0</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">mu_ip</span> <span class="o">=</span> <span class="mf">0.1</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">sigma_ip</span> <span class="o">=</span> <span class="mf">0.0</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">network_type_ee</span> <span class="o">=</span> <span class="s2">&quot;Sparse&quot;</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">network_type_ei</span> <span class="o">=</span> <span class="s2">&quot;Sparse&quot;</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">network_type_ie</span> <span class="o">=</span> <span class="s2">&quot;Dense&quot;</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">lambda_ee</span> <span class="o">=</span> <span class="mi">20</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">lambda_ei</span> <span class="o">=</span> <span class="mi">40</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">lambda_ie</span> <span class="o">=</span> <span class="mi">100</span>
+
+<div class="viewcode-block" id="Sorn.initialize_weight_matrix"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Sorn.initialize_weight_matrix">[docs]</a>    <span class="k">def</span> <span class="nf">initialize_weight_matrix</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
         <span class="n">network_type</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">synaptic_connection</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">self_connection</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">lambd_w</span><span class="p">:</span> <span class="nb">int</span>
     <span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;Wrapper for initializing the weight matrices for SORN</span>
@@ -280,22 +270,21 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
         <span class="k">if</span> <span class="p">(</span><span class="n">network_type</span> <span class="o">==</span> <span class="s2">&quot;Sparse&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">self_connection</span> <span class="o">==</span> <span class="s2">&quot;False&quot;</span><span class="p">):</span>
 
             <span class="c1"># Generate weight matrix for E-E/ E-I connections with mean lamda incoming and out-going connections per neuron</span>
-            <span class="k">assert</span> <span class="p">(</span><span class="n">lambd_w</span> <span class="o">&lt;=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">),</span> <span class="s2">&quot;Number of connections per unit (lambda) should be less than number of units(Ne) in the pool and also Ne should be greater than 25&quot;</span>
+            <span class="k">assert</span> <span class="p">(</span><span class="n">lambd_w</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">),</span> <span class="s2">&quot;Number of connections per unit (lambda) should be less than number of units(Ne) in the pool and also Ne should be greater than 25&quot;</span>
             <span class="n">weight_matrix</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">generate_lambd_connections</span><span class="p">(</span>
-                <span class="n">synaptic_connection</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">,</span> <span class="n">lambd_w</span><span class="p">,</span> <span class="n">lambd_std</span><span class="o">=</span><span class="mi">1</span>
+                <span class="n">synaptic_connection</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">,</span> <span class="n">lambd_w</span><span class="p">,</span> <span class="n">lambd_std</span><span class="o">=</span><span class="mi">1</span>
             <span class="p">)</span>
 
         <span class="c1"># Dense matrix for W_ie</span>
         <span class="k">elif</span> <span class="p">(</span><span class="n">network_type</span> <span class="o">==</span> <span class="s2">&quot;Dense&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">self_connection</span> <span class="o">==</span> <span class="s2">&quot;False&quot;</span><span class="p">):</span>
 
             <span class="c1"># Uniform distribution of weights</span>
-            <span class="n">weight_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">))</span>
-            <span class="n">weight_matrix</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">))</span>
+            <span class="n">weight_matrix</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">))</span>
+            <span class="n">weight_matrix</span><span class="o">.</span><span class="n">reshape</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">))</span>
 
         <span class="k">return</span> <span class="n">weight_matrix</span></div>
 
-<div class="viewcode-block" id="Sorn.initialize_threshold_matrix"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Sorn.initialize_threshold_matrix">[docs]</a>    <span class="nd">@staticmethod</span>
-    <span class="k">def</span> <span class="nf">initialize_threshold_matrix</span><span class="p">(</span>
+<div class="viewcode-block" id="Sorn.initialize_threshold_matrix"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Sorn.initialize_threshold_matrix">[docs]</a>    <span class="k">def</span> <span class="nf">initialize_threshold_matrix</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span>
         <span class="n">te_min</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">te_max</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">ti_min</span><span class="p">:</span> <span class="nb">float</span><span class="p">,</span> <span class="n">ti_max</span><span class="p">:</span> <span class="nb">float</span>
     <span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;Initialize the threshold for excitatory and inhibitory neurons</span>
@@ -311,13 +300,12 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 <span class="sd">            ti (array): Threshold values for inhibitory units</span>
 <span class="sd">        &quot;&quot;&quot;</span>
 
-        <span class="n">te</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">te_min</span><span class="p">,</span> <span class="n">te_max</span><span class="p">,</span> <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
-        <span class="n">ti</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">ti_min</span><span class="p">,</span> <span class="n">ti_max</span><span class="p">,</span> <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
+        <span class="n">te</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">te_min</span><span class="p">,</span> <span class="n">te_max</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
+        <span class="n">ti</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="n">ti_min</span><span class="p">,</span> <span class="n">ti_max</span><span class="p">,</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
 
         <span class="k">return</span> <span class="n">te</span><span class="p">,</span> <span class="n">ti</span></div>
 
-<div class="viewcode-block" id="Sorn.initialize_activity_vector"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Sorn.initialize_activity_vector">[docs]</a>    <span class="nd">@staticmethod</span>
-    <span class="k">def</span> <span class="nf">initialize_activity_vector</span><span class="p">(</span><span class="n">ne</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">ni</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
+<div class="viewcode-block" id="Sorn.initialize_activity_vector"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Sorn.initialize_activity_vector">[docs]</a>    <span class="k">def</span> <span class="nf">initialize_activity_vector</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ne</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">ni</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;Initialize the activity vectors X and Y for excitatory and inhibitory neurons</span>
 
 <span class="sd">        Args:</span>
@@ -328,13 +316,15 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 <span class="sd">        Returns:</span>
 <span class="sd">            x (array): Array of activity vectors of excitatory population</span>
 
-<span class="sd">            y (array): Array of activity vectors of inhibitory population&quot;&quot;&quot;</span>
+<span class="sd">            y (array): Array of activity vectors of inhibitory population</span>
+<span class="sd">        &quot;&quot;&quot;</span>
 
         <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">ne</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
         <span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">ni</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
 
         <span class="k">return</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span></div></div>
 
+
 <div class="viewcode-block" id="Plasticity"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Plasticity">[docs]</a><span class="k">class</span> <span class="nc">Plasticity</span><span class="p">(</span><span class="n">Sorn</span><span class="p">):</span>
     <span class="sd">&quot;&quot;&quot;Instance of class Sorn. Inherits the variables and functions defined in class Sorn.</span>
 <span class="sd">    It encapsulates all plasticity mechanisms mentioned in the article. Inherits all attributed from parent class Sorn</span>
@@ -370,26 +360,8 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 <span class="sd">    &quot;&quot;&quot;</span>
 
     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
-
         <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">nu</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_nu</span>  <span class="c1"># Number of input units</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">ne</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span>  <span class="c1"># Number of excitatory units</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">eta_stdp</span> <span class="o">=</span> <span class="p">(</span>
-            <span class="n">Sorn</span><span class="o">.</span><span class="n">_eta_stdp</span>
-        <span class="p">)</span>  <span class="c1"># STDP plasticity Learning rate constant; SORN1 and SORN2</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">eta_ip</span> <span class="o">=</span> <span class="p">(</span>
-            <span class="n">Sorn</span><span class="o">.</span><span class="n">_eta_ip</span>
-        <span class="p">)</span>  <span class="c1"># Intrinsic plasticity learning rate constant; SORN1 and SORN2</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">eta_inhib</span> <span class="o">=</span> <span class="p">(</span>
-            <span class="n">Sorn</span><span class="o">.</span><span class="n">_eta_inhib</span>
-        <span class="p">)</span>  <span class="c1"># Intrinsic plasticity learning rate constant; SORN2 only</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">h_ip</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_nu</span> <span class="o">/</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span>  <span class="c1"># Target firing rate</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">mu_ip</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_mu_ip</span>  <span class="c1"># Mean target firing rate</span>
-        <span class="c1"># Number of inhibitory units in the network</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">ni</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.2</span> <span class="o">*</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">)</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_time_steps</span>  <span class="c1"># Total time steps of simulation</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">te_min</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_te_min</span>  <span class="c1"># Excitatory minimum Threshold</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">te_max</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_te_max</span>  <span class="c1"># Excitatory maximum Threshold</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">h_ip</span> <span class="o">=</span> <span class="mi">2</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">nu</span> <span class="o">/</span> <span class="bp">self</span><span class="o">.</span><span class="n">ne</span>  <span class="c1"># Target firing rate</span>
 
 <div class="viewcode-block" id="Plasticity.stdp"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Plasticity.stdp">[docs]</a>    <span class="k">def</span> <span class="nf">stdp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wee</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">x</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">cutoff_weights</span><span class="p">:</span> <span class="nb">list</span><span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;Apply STDP rule : Regulates synaptic strength between the pre(Xj) and post(Xi) synaptic neurons</span>
@@ -463,7 +435,8 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
         <span class="k">return</span> <span class="n">te_update</span></div>
 
-<div class="viewcode-block" id="Plasticity.ss"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Plasticity.ss">[docs]</a>    <span class="k">def</span> <span class="nf">ss</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">wee</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">):</span>
+<div class="viewcode-block" id="Plasticity.ss"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Plasticity.ss">[docs]</a>    <span class="nd">@staticmethod</span>
+    <span class="k">def</span> <span class="nf">ss</span><span class="p">(</span><span class="n">wee</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;Synaptic Scaling or Synaptic Normalization</span>
 
 <span class="sd">        Args:</span>
@@ -555,8 +528,7 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
         <span class="k">return</span> <span class="n">wee</span></div>
 
-<div class="viewcode-block" id="Plasticity.initialize_plasticity"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Plasticity.initialize_plasticity">[docs]</a>    <span class="nd">@staticmethod</span>
-    <span class="k">def</span> <span class="nf">initialize_plasticity</span><span class="p">():</span>
+<div class="viewcode-block" id="Plasticity.initialize_plasticity"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Plasticity.initialize_plasticity">[docs]</a>    <span class="k">def</span> <span class="nf">initialize_plasticity</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;Initialize weight matrices for plasticity phase based on network configuration</span>
 
 <span class="sd">        Args:</span>
@@ -565,24 +537,23 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 <span class="sd">        Returns:</span>
 <span class="sd">            tuple(array): Weight matrices WEI, WEE, WIE and threshold matrices Te, Ti and Initial state vectors X,Y &quot;&quot;&quot;</span>
 
-        <span class="n">sorn_init</span> <span class="o">=</span> <span class="n">Sorn</span><span class="p">()</span>
-        <span class="n">WEE_init</span> <span class="o">=</span> <span class="n">sorn_init</span><span class="o">.</span><span class="n">initialize_weight_matrix</span><span class="p">(</span>
-            <span class="n">network_type</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_network_type_ee</span><span class="p">,</span>
+        <span class="n">WEE_init</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_weight_matrix</span><span class="p">(</span>
+            <span class="n">network_type</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">network_type_ee</span><span class="p">,</span>
             <span class="n">synaptic_connection</span><span class="o">=</span><span class="s2">&quot;EE&quot;</span><span class="p">,</span>
             <span class="n">self_connection</span><span class="o">=</span><span class="s2">&quot;False&quot;</span><span class="p">,</span>
-            <span class="n">lambd_w</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_lambda_ee</span><span class="p">,</span>
+            <span class="n">lambd_w</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">lambda_ee</span><span class="p">,</span>
         <span class="p">)</span>
-        <span class="n">WEI_init</span> <span class="o">=</span> <span class="n">sorn_init</span><span class="o">.</span><span class="n">initialize_weight_matrix</span><span class="p">(</span>
-            <span class="n">network_type</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_network_type_ei</span><span class="p">,</span>
+        <span class="n">WEI_init</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_weight_matrix</span><span class="p">(</span>
+            <span class="n">network_type</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">network_type_ei</span><span class="p">,</span>
             <span class="n">synaptic_connection</span><span class="o">=</span><span class="s2">&quot;EI&quot;</span><span class="p">,</span>
             <span class="n">self_connection</span><span class="o">=</span><span class="s2">&quot;False&quot;</span><span class="p">,</span>
-            <span class="n">lambd_w</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_lambda_ei</span><span class="p">,</span>
+            <span class="n">lambd_w</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">lambda_ei</span><span class="p">,</span>
         <span class="p">)</span>
-        <span class="n">WIE_init</span> <span class="o">=</span> <span class="n">sorn_init</span><span class="o">.</span><span class="n">initialize_weight_matrix</span><span class="p">(</span>
-            <span class="n">network_type</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_network_type_ie</span><span class="p">,</span>
+        <span class="n">WIE_init</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_weight_matrix</span><span class="p">(</span>
+            <span class="n">network_type</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">network_type_ie</span><span class="p">,</span>
             <span class="n">synaptic_connection</span><span class="o">=</span><span class="s2">&quot;IE&quot;</span><span class="p">,</span>
             <span class="n">self_connection</span><span class="o">=</span><span class="s2">&quot;False&quot;</span><span class="p">,</span>
-            <span class="n">lambd_w</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_lambda_ie</span><span class="p">,</span>
+            <span class="n">lambd_w</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">lambda_ie</span><span class="p">,</span>
         <span class="p">)</span>
 
         <span class="n">Wee_init</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">zero_sum_incoming_check</span><span class="p">(</span><span class="n">WEE_init</span><span class="p">)</span>
@@ -607,11 +578,11 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
         <span class="n">normalized_wei</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">normalize_weight_matrix</span><span class="p">(</span><span class="n">Wei_init</span><span class="p">)</span>
         <span class="n">normalized_wie</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">normalize_weight_matrix</span><span class="p">(</span><span class="n">Wie_init</span><span class="p">)</span>
 
-        <span class="n">te_init</span><span class="p">,</span> <span class="n">ti_init</span> <span class="o">=</span> <span class="n">sorn_init</span><span class="o">.</span><span class="n">initialize_threshold_matrix</span><span class="p">(</span>
-            <span class="n">Sorn</span><span class="o">.</span><span class="n">_te_min</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_te_max</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ti_min</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ti_max</span>
+        <span class="n">te_init</span><span class="p">,</span> <span class="n">ti_init</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_threshold_matrix</span><span class="p">(</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">te_min</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">te_max</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ti_min</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ti_max</span>
         <span class="p">)</span>
-        <span class="n">x_init</span><span class="p">,</span> <span class="n">y_init</span> <span class="o">=</span> <span class="n">sorn_init</span><span class="o">.</span><span class="n">initialize_activity_vector</span><span class="p">(</span>
-            <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">)</span>
+        <span class="n">x_init</span><span class="p">,</span> <span class="n">y_init</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">initialize_activity_vector</span><span class="p">(</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">)</span>
 
         <span class="c1"># Initializing variables from sorn_initialize.py</span>
 
@@ -644,7 +615,7 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
         <span class="bp">self</span><span class="o">.</span><span class="n">matrices</span> <span class="o">=</span> <span class="n">matrices</span>
         <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">phase</span> <span class="o">==</span> <span class="s2">&quot;plasticity&quot;</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">matrices</span> <span class="o">==</span> <span class="kc">None</span><span class="p">:</span>
 
-            <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_time_steps</span> <span class="o">+</span> <span class="mi">1</span>  <span class="c1"># Total training steps</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">+</span> <span class="mi">1</span>  <span class="c1"># Total training steps</span>
             <span class="bp">self</span><span class="o">.</span><span class="n">Wee</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Wei</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Wie</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Te</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Ti</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">X</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Y</span> <span class="o">=</span> <span class="p">(</span>
                 <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span><span class="p">,</span>
                 <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span><span class="p">,</span>
@@ -667,7 +638,7 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
         <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">phase</span> <span class="o">==</span> <span class="s2">&quot;plasticity&quot;</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">matrices</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
 
-            <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_time_steps</span> <span class="o">+</span> <span class="mi">1</span>  <span class="c1"># Total training steps</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">+</span> <span class="mi">1</span>  <span class="c1"># Total training steps</span>
             <span class="bp">self</span><span class="o">.</span><span class="n">Wee</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Wei</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Wie</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Te</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Ti</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">X</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Y</span> <span class="o">=</span> <span class="p">(</span>
                 <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span><span class="p">,</span>
                 <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span><span class="p">,</span>
@@ -689,7 +660,7 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
         <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">phase</span> <span class="o">==</span> <span class="s2">&quot;training&quot;</span><span class="p">:</span>
 
             <span class="c1"># NOTE:time_steps here is diferent for plasticity and training phase</span>
-            <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_time_steps</span> <span class="o">+</span> <span class="mi">1</span>  <span class="c1"># Total training steps</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">+</span> <span class="mi">1</span>  <span class="c1"># Total training steps</span>
             <span class="bp">self</span><span class="o">.</span><span class="n">Wee</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Wei</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Wie</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Te</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Ti</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">X</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">Y</span> <span class="o">=</span> <span class="p">(</span>
                 <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span><span class="p">,</span>
                 <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span><span class="p">,</span>
@@ -799,13 +770,13 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">v_t</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">):</span>
         <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">v_t</span> <span class="o">=</span> <span class="n">v_t</span>
-        <span class="k">assert</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_nu</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span>
+        <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">nu</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span>
             <span class="bp">self</span><span class="o">.</span><span class="n">v_t</span>
         <span class="p">),</span> <span class="s2">&quot;Input units and input size mismatch: </span><span class="si">{}</span><span class="s2"> != </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
-            <span class="n">Sorn</span><span class="o">.</span><span class="n">_nu</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v_t</span><span class="p">)</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">nu</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v_t</span><span class="p">)</span>
         <span class="p">)</span>
-        <span class="k">if</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_nu</span> <span class="o">!=</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">:</span>
-            <span class="bp">self</span><span class="o">.</span><span class="n">v_t</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v_t</span><span class="p">)</span> <span class="o">+</span> <span class="p">[</span><span class="mf">0.0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span> <span class="o">-</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_nu</span><span class="p">)</span>
+        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">nu</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">:</span>
+            <span class="bp">self</span><span class="o">.</span><span class="n">v_t</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v_t</span><span class="p">)</span> <span class="o">+</span> <span class="p">[</span><span class="mf">0.0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">nu</span><span class="p">)</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">v_t</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">expand_dims</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">v_t</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
 
 <div class="viewcode-block" id="NetworkState.incoming_drive"><a class="viewcode-back" href="../../reference.html#sorn.sorn.NetworkState.incoming_drive">[docs]</a>    <span class="k">def</span> <span class="nf">incoming_drive</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">weights</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">activity_vector</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">):</span>
@@ -895,7 +866,7 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
         <span class="n">wie</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">wie</span><span class="p">)</span>
         <span class="n">yt</span> <span class="o">=</span> <span class="n">y</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">]</span>
-        <span class="n">yt</span> <span class="o">=</span> <span class="n">yt</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
+        <span class="n">yt</span> <span class="o">=</span> <span class="n">yt</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
 
         <span class="n">incoming_drive_e</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">expand_dims</span><span class="p">(</span>
             <span class="bp">self</span><span class="o">.</span><span class="n">incoming_drive</span><span class="p">(</span><span class="n">weights</span><span class="o">=</span><span class="n">wie</span><span class="p">,</span> <span class="n">activity_vector</span><span class="o">=</span><span class="n">yt</span><span class="p">),</span> <span class="mi">1</span>
@@ -983,7 +954,6 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
     <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
         <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
-        <span class="k">pass</span>
 
 <div class="viewcode-block" id="Simulator_.simulate_sorn"><a class="viewcode-back" href="../../reference.html#sorn.sorn.Simulator_.simulate_sorn">[docs]</a>    <span class="k">def</span> <span class="nf">simulate_sorn</span><span class="p">(</span>
         <span class="bp">self</span><span class="p">,</span>
@@ -1026,35 +996,34 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
         <span class="p">),</span> <span class="s2">&quot;Phase can be either &#39;plasticity&#39; or &#39;training&#39;&quot;</span>
 
         <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="n">time_steps</span>
-        <span class="n">Sorn</span><span class="o">.</span><span class="n">_time_steps</span> <span class="o">=</span> <span class="n">time_steps</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">phase</span> <span class="o">=</span> <span class="n">phase</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">matrices</span> <span class="o">=</span> <span class="n">matrices</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span> <span class="o">=</span> <span class="n">freeze</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">if</span> <span class="n">freeze</span> <span class="o">==</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">freeze</span>
 
         <span class="n">kwargs_</span> <span class="o">=</span> <span class="p">[</span>
-            <span class="s2">&quot;_ne&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_nu&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_network_type_ee&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_network_type_ei&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_network_type_ie&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_lambda_ee&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_lambda_ei&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_lambda_ie&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_eta_stdp&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_eta_inhib&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_eta_ip&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_te_max&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_ti_max&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_ti_min&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_te_min&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_mu_ip&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_sigma_ip&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;ne&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;nu&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;network_type_ee&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;network_type_ei&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;network_type_ie&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;lambda_ee&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;lambda_ei&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;lambda_ie&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;eta_stdp&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;eta_inhib&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;eta_ip&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;te_max&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;ti_max&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;ti_min&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;te_min&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;mu_ip&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;sigma_ip&quot;</span><span class="p">,</span>
         <span class="p">]</span>
         <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
             <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">kwargs_</span><span class="p">:</span>
                 <span class="nb">setattr</span><span class="p">(</span><span class="n">Sorn</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
         <span class="c1"># assert Sorn._nu == len(inputs[:,0]),&quot;Size mismatch: Input != Nu &quot;</span>
-        <span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.2</span> <span class="o">*</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">)</span>
+        <span class="n">Sorn</span><span class="o">.</span><span class="n">ni</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.2</span> <span class="o">*</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">ne</span><span class="p">)</span>
 
         <span class="c1"># Initialize/Get the weight, threshold matrices and activity vectors</span>
         <span class="n">matrix_collection</span> <span class="o">=</span> <span class="n">MatrixCollection</span><span class="p">(</span>
@@ -1073,10 +1042,10 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
             <span class="k">if</span> <span class="n">noise</span><span class="p">:</span>
                 <span class="n">white_noise_e</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">white_gaussian_noise</span><span class="p">(</span>
-                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span>
+                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span>
                 <span class="p">)</span>
                 <span class="n">white_noise_i</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">white_gaussian_noise</span><span class="p">(</span>
-                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span>
+                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ni</span>
                 <span class="p">)</span>
             <span class="k">else</span><span class="p">:</span>
                 <span class="n">white_noise_e</span><span class="p">,</span> <span class="n">white_noise_i</span> <span class="o">=</span> <span class="mf">0.0</span><span class="p">,</span> <span class="mf">0.0</span>
@@ -1087,12 +1056,11 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
             <span class="c1"># Buffers to get the resulting x and y vectors at the current time step and update the master matrix</span>
             <span class="n">x_buffer</span><span class="p">,</span> <span class="n">y_buffer</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span>
-                <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="mi">2</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
+                <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="mi">2</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
 
             <span class="n">te_buffer</span><span class="p">,</span> <span class="n">ti_buffer</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span>
-                <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
+                <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
 
-            <span class="c1"># Get the matrices and rename them for ease of reading</span>
             <span class="n">Wee</span><span class="p">,</span> <span class="n">Wei</span><span class="p">,</span> <span class="n">Wie</span> <span class="o">=</span> <span class="p">(</span>
                 <span class="n">matrix_collection</span><span class="o">.</span><span class="n">Wee</span><span class="p">,</span>
                 <span class="n">matrix_collection</span><span class="o">.</span><span class="n">Wei</span><span class="p">,</span>
@@ -1132,31 +1100,31 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
             <span class="c1"># STDP</span>
             <span class="k">if</span> <span class="s1">&#39;stdp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                <span class="n">Wee_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">stdp</span><span class="p">(</span>
+                <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">stdp</span><span class="p">(</span>
                     <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">,</span> <span class="n">cutoff_weights</span><span class="o">=</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">))</span>
 
             <span class="c1"># Intrinsic plasticity</span>
             <span class="k">if</span> <span class="s1">&#39;ip&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                <span class="n">Te_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ip</span><span class="p">(</span><span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">)</span>
+                <span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ip</span><span class="p">(</span><span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">)</span>
 
             <span class="c1"># Structural plasticity</span>
-            <span class="k">if</span> <span class="s1">&#39;sp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">freeze</span><span class="p">:</span>
-                <span class="n">Wee_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">structural_plasticity</span><span class="p">(</span><span class="n">Wee_t</span><span class="p">)</span>
+            <span class="k">if</span> <span class="s1">&#39;sp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
+                <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">structural_plasticity</span><span class="p">(</span><span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
 
             <span class="c1"># iSTDP</span>
-            <span class="k">if</span> <span class="s1">&#39;istdp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">freeze</span><span class="p">:</span>
-                <span class="n">Wei_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">istdp</span><span class="p">(</span>
+            <span class="k">if</span> <span class="s1">&#39;istdp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
+                <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">istdp</span><span class="p">(</span>
                     <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">,</span> <span class="n">y_buffer</span><span class="p">,</span> <span class="n">cutoff_weights</span><span class="o">=</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span>
                 <span class="p">)</span>
 
             <span class="c1"># Synaptic scaling Wee</span>
             <span class="k">if</span> <span class="s1">&#39;ss&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                <span class="n">Wee_t</span> <span class="o">=</span> <span class="n">Plasticity</span><span class="p">()</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wee_t</span><span class="p">)</span>
-                <span class="n">Wei_t</span> <span class="o">=</span> <span class="n">Plasticity</span><span class="p">()</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wei_t</span><span class="p">)</span>
+                <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
+                <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
 
             <span class="c1"># Assign the matrices to the matrix collections</span>
-            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">weight_matrix</span><span class="p">(</span><span class="n">Wee_t</span><span class="p">,</span> <span class="n">Wei_t</span><span class="p">,</span> <span class="n">Wie</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
-            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">threshold_matrix</span><span class="p">(</span><span class="n">Te_t</span><span class="p">,</span> <span class="n">Ti</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
+            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">weight_matrix</span><span class="p">(</span><span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Wie</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
+            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">threshold_matrix</span><span class="p">(</span><span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Ti</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
             <span class="n">matrix_collection</span><span class="o">.</span><span class="n">network_activity_t</span><span class="p">(</span><span class="n">x_buffer</span><span class="p">,</span> <span class="n">y_buffer</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
 
             <span class="n">X_all</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">x_buffer</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">]</span>
@@ -1246,37 +1214,36 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
         <span class="p">),</span> <span class="s2">&quot;Phase can be either &#39;plasticity&#39; or &#39;training&#39;&quot;</span>
 
         <span class="n">kwargs_</span> <span class="o">=</span> <span class="p">[</span>
-            <span class="s2">&quot;_ne&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_nu&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_network_type_ee&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_network_type_ei&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_network_type_ie&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_lambda_ee&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_lambda_ei&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_lambda_ie&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_eta_stdp&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_eta_inhib&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_eta_ip&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_te_max&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_ti_max&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_ti_min&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_te_min&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_mu_ip&quot;</span><span class="p">,</span>
-            <span class="s2">&quot;_sigma_ip&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;ne&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;nu&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;network_type_ee&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;network_type_ei&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;network_type_ie&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;lambda_ee&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;lambda_ei&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;lambda_ie&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;eta_stdp&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;eta_inhib&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;eta_ip&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;te_max&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;ti_max&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;ti_min&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;te_min&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;mu_ip&quot;</span><span class="p">,</span>
+            <span class="s2">&quot;sigma_ip&quot;</span><span class="p">,</span>
         <span class="p">]</span>
         <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
             <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">kwargs_</span><span class="p">:</span>
                 <span class="nb">setattr</span><span class="p">(</span><span class="n">Sorn</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
-        <span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.2</span> <span class="o">*</span> <span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">)</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">ni</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">0.2</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">)</span>
         <span class="c1"># assert Sorn._nu == len(inputs[:,0]),&quot;Size mismatch: Input != Nu &quot;</span>
 
         <span class="bp">self</span><span class="o">.</span><span class="n">phase</span> <span class="o">=</span> <span class="n">phase</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">matrices</span> <span class="o">=</span> <span class="n">matrices</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span> <span class="o">=</span> <span class="n">time_steps</span>
-        <span class="n">Sorn</span><span class="o">.</span><span class="n">_time_steps</span> <span class="o">=</span> <span class="n">time_steps</span>
         <span class="bp">self</span><span class="o">.</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">inputs</span><span class="p">)</span>
-        <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span> <span class="o">=</span> <span class="n">freeze</span>
-        <span class="c1"># Collect the network activity at all time steps</span>
+        <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">if</span> <span class="n">freeze</span> <span class="o">==</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">freeze</span>
+
         <span class="n">X_all</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span>
         <span class="n">Y_all</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span>
         <span class="n">R_all</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">time_steps</span>
@@ -1290,10 +1257,10 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
             <span class="k">if</span> <span class="n">noise</span><span class="p">:</span>
                 <span class="n">white_noise_e</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">white_gaussian_noise</span><span class="p">(</span>
-                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span>
+                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span>
                 <span class="p">)</span>
                 <span class="n">white_noise_i</span> <span class="o">=</span> <span class="n">Initializer</span><span class="o">.</span><span class="n">white_gaussian_noise</span><span class="p">(</span>
-                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span>
+                    <span class="n">mu</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span> <span class="n">sigma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">,</span> <span class="n">t</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">ni</span>
                 <span class="p">)</span>
             <span class="k">else</span><span class="p">:</span>
                 <span class="n">white_noise_e</span> <span class="o">=</span> <span class="mf">0.0</span>
@@ -1301,15 +1268,14 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
             <span class="n">network_state</span> <span class="o">=</span> <span class="n">NetworkState</span><span class="p">(</span>
                 <span class="bp">self</span><span class="o">.</span><span class="n">inputs</span><span class="p">[:,</span> <span class="n">i</span><span class="p">]</span>
-            <span class="p">)</span>  <span class="c1"># Feed Input as an argument to the class</span>
+            <span class="p">)</span>
 
             <span class="c1"># Buffers to get the resulting x and y vectors at the current time step and update the master matrix</span>
             <span class="n">x_buffer</span><span class="p">,</span> <span class="n">y_buffer</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span>
-                <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="mi">2</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
+                <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="mi">2</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
             <span class="n">te_buffer</span><span class="p">,</span> <span class="n">ti_buffer</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span>
-                <span class="p">(</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">Sorn</span><span class="o">.</span><span class="n">_ni</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
+                <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ne</span><span class="p">,</span> <span class="mi">1</span><span class="p">)),</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">ni</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
 
-            <span class="c1"># Get the matrices and rename them for ease of reading</span>
             <span class="n">Wee</span><span class="p">,</span> <span class="n">Wei</span><span class="p">,</span> <span class="n">Wie</span> <span class="o">=</span> <span class="p">(</span>
                 <span class="n">matrix_collection</span><span class="o">.</span><span class="n">Wee</span><span class="p">,</span>
                 <span class="n">matrix_collection</span><span class="o">.</span><span class="n">Wei</span><span class="p">,</span>
@@ -1346,35 +1312,36 @@ <h1>Source code for sorn.sorn</h1><div class="highlight"><pre>
 
                 <span class="c1"># STDP</span>
                 <span class="k">if</span> <span class="s1">&#39;stdp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                    <span class="n">Wee_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">stdp</span><span class="p">(</span>
+                    <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">stdp</span><span class="p">(</span>
                         <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">,</span> <span class="n">cutoff_weights</span><span class="o">=</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">))</span>
 
                 <span class="c1"># Intrinsic plasticity</span>
                 <span class="k">if</span> <span class="s1">&#39;ip&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                    <span class="n">Te_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ip</span><span class="p">(</span><span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">)</span>
+                    <span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ip</span><span class="p">(</span><span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">)</span>
 
                 <span class="c1"># Structural plasticity</span>
                 <span class="k">if</span> <span class="s1">&#39;sp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                    <span class="n">Wee_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">structural_plasticity</span><span class="p">(</span><span class="n">Wee_t</span><span class="p">)</span>
+                    <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">structural_plasticity</span><span class="p">(</span><span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
 
                 <span class="c1"># iSTDP</span>
                 <span class="k">if</span> <span class="s1">&#39;istdp&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                    <span class="n">Wei_t</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">istdp</span><span class="p">(</span>
+                    <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">istdp</span><span class="p">(</span>
                         <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">x_buffer</span><span class="p">,</span> <span class="n">y_buffer</span><span class="p">,</span> <span class="n">cutoff_weights</span><span class="o">=</span><span class="p">(</span><span class="mf">0.0</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span>
                     <span class="p">)</span>
 
                 <span class="c1"># Synaptic scaling Wee</span>
-                <span class="k">if</span> <span class="s1">&#39;sc&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
-                    <span class="n">Wee_t</span> <span class="o">=</span> <span class="n">Plasticity</span><span class="p">()</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wee_t</span><span class="p">)</span>
+                <span class="k">if</span> <span class="s1">&#39;ss&#39;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">freeze</span><span class="p">:</span>
+                    <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
 
                     <span class="c1"># Synaptic scaling Wei</span>
-                    <span class="n">Wei_t</span> <span class="o">=</span> <span class="n">Plasticity</span><span class="p">()</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wei_t</span><span class="p">)</span>
+                    <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">plasticity</span><span class="o">.</span><span class="n">ss</span><span class="p">(</span><span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
             <span class="k">else</span><span class="p">:</span>
-                <span class="n">Wee_t</span><span class="p">,</span> <span class="n">Wei_t</span><span class="p">,</span> <span class="n">Te_t</span> <span class="o">=</span> <span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
+                <span class="c1"># Wee[i], Wei[i], Te[i] remain same</span>
+                <span class="k">pass</span>
 
             <span class="c1"># Assign the matrices to the matrix collections</span>
-            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">weight_matrix</span><span class="p">(</span><span class="n">Wee_t</span><span class="p">,</span> <span class="n">Wei_t</span><span class="p">,</span> <span class="n">Wie</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
-            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">threshold_matrix</span><span class="p">(</span><span class="n">Te_t</span><span class="p">,</span> <span class="n">Ti</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
+            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">weight_matrix</span><span class="p">(</span><span class="n">Wee</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Wei</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Wie</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
+            <span class="n">matrix_collection</span><span class="o">.</span><span class="n">threshold_matrix</span><span class="p">(</span><span class="n">Te</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Ti</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">)</span>
             <span class="n">matrix_collection</span><span class="o">.</span><span class="n">network_activity_t</span><span class="p">(</span><span class="n">x_buffer</span><span class="p">,</span> <span class="n">y_buffer</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
 
             <span class="n">X_all</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">x_buffer</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">]</span>
diff --git a/docs/build/html/_modules/sorn/utils.html b/docs/build/html/_modules/sorn/utils.html
index 08efd0a..03f29bc 100644
--- a/docs/build/html/_modules/sorn/utils.html
+++ b/docs/build/html/_modules/sorn/utils.html
@@ -60,7 +60,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
@@ -600,7 +600,7 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
     <span class="k">def</span> <span class="nf">hist_incoming_conn</span><span class="p">(</span>
         <span class="n">weights</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">bin_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">histtype</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">savefig</span><span class="p">:</span> <span class="nb">bool</span>
     <span class="p">):</span>
-        <span class="sd">&quot;&quot;&quot;Plot the histogram of number of incoming connections per neuron</span>
+        <span class="sd">&quot;&quot;&quot;Plot the histogram of number of presynaptic connections per neuron</span>
 
 <span class="sd">        Args:</span>
 <span class="sd">            weights (array): Connection weights</span>
@@ -614,36 +614,30 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
 <span class="sd">        Returns:</span>
 <span class="sd">            plot (matplotlib.pyplot): plot object</span>
 <span class="sd">        &quot;&quot;&quot;</span>
-
-        <span class="c1"># Plot the histogram of distribution of number of incoming connections in the network</span>
-
         <span class="n">num_incoming_weights</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
 
         <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span>
-
-        <span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s2">&quot;Number of incoming connections&quot;</span><span class="p">)</span>
         <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Number of connections&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Count&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bin_size</span><span class="p">,</span> <span class="n">histtype</span><span class="o">=</span><span class="n">histtype</span><span class="p">)</span>
-
-        <span class="c1"># Empirical average and variance are computed</span>
-        <span class="n">avg</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">)</span>
-        <span class="n">var</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">var</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">)</span>
-        <span class="c1"># From hist plot above, it is clear that connection count follow gaussian distribution</span>
-        <span class="n">pdf_x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span>
-            <span class="n">np</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">),</span> <span class="mi">100</span>
-        <span class="p">)</span>
-        <span class="n">pdf_y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="n">var</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">pdf_x</span> <span class="o">-</span> <span class="n">avg</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">/</span> <span class="n">var</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Probability&quot;</span><span class="p">)</span>
 
-        <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">pdf_x</span><span class="p">,</span> <span class="n">pdf_y</span><span class="p">,</span> <span class="s2">&quot;k--&quot;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Gaussian fit&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">axvline</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="n">avg</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s2">&quot;r&quot;</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="s2">&quot;--&quot;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Mean&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">()</span>
+        <span class="c1"># Fit a normal distribution to the data</span>
+        <span class="n">mu</span><span class="p">,</span> <span class="n">std</span> <span class="o">=</span> <span class="n">norm</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bin_size</span><span class="p">,</span> <span class="n">density</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.6</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;b&#39;</span><span class="p">)</span>
+
+        <span class="c1"># PDF</span>
+        <span class="n">xmin</span><span class="p">,</span> <span class="n">xmax</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">xlim</span><span class="p">()</span>
+        <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">xmin</span><span class="p">,</span> <span class="n">xmax</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="n">num_incoming_weights</span><span class="p">))</span>
+        <span class="n">p</span> <span class="o">=</span> <span class="n">norm</span><span class="o">.</span><span class="n">pdf</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">mu</span><span class="p">,</span> <span class="n">std</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="s1">&#39;k&#39;</span><span class="p">,</span> <span class="n">linewidth</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
+        <span class="n">title</span> <span class="o">=</span> <span class="s2">&quot;Distribution of presynaptic connections: mu = </span><span class="si">%.2f</span><span class="s2">,  std = </span><span class="si">%.2f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">mu</span><span class="p">,</span> <span class="n">std</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
 
         <span class="k">if</span> <span class="n">savefig</span><span class="p">:</span>
             <span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s2">&quot;hist_incoming_conn&quot;</span><span class="p">)</span>
 
         <span class="k">return</span> <span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span></div>
 
+
 <div class="viewcode-block" id="Plotter.hist_outgoing_conn"><a class="viewcode-back" href="../../reference.html#sorn.utils.Plotter.hist_outgoing_conn">[docs]</a>    <span class="nd">@staticmethod</span>
     <span class="k">def</span> <span class="nf">hist_outgoing_conn</span><span class="p">(</span>
         <span class="n">weights</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">bin_size</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">histtype</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">savefig</span><span class="p">:</span> <span class="nb">bool</span>
@@ -667,23 +661,20 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
         <span class="n">num_outgoing_weights</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">weights</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="n">axis</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
 
         <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">12</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span>
-
-        <span class="n">plt</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bin_size</span><span class="p">,</span> <span class="n">histtype</span><span class="o">=</span><span class="n">histtype</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="s2">&quot;Number of Outgoing connections&quot;</span><span class="p">)</span>
         <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Number of connections&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Count&quot;</span><span class="p">)</span>
-        <span class="c1"># Empirical average and variance are computed</span>
-        <span class="n">avg</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">)</span>
-        <span class="n">var</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">var</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Probability&quot;</span><span class="p">)</span>
 
-        <span class="n">pdf_x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span>
-            <span class="n">np</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">),</span> <span class="n">np</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">),</span> <span class="mi">100</span>
-        <span class="p">)</span>
-        <span class="n">pdf_y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span> <span class="o">*</span> <span class="n">var</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="mf">0.5</span> <span class="o">*</span> <span class="p">(</span><span class="n">pdf_x</span> <span class="o">-</span> <span class="n">avg</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span> <span class="o">/</span> <span class="n">var</span><span class="p">)</span>
+        <span class="c1"># Fit a normal distribution to the data</span>
+        <span class="n">mu</span><span class="p">,</span> <span class="n">std</span> <span class="o">=</span> <span class="n">norm</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">hist</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bin_size</span><span class="p">,</span> <span class="n">density</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">alpha</span><span class="o">=</span><span class="mf">0.6</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">&#39;b&#39;</span><span class="p">)</span>
 
-        <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">pdf_x</span><span class="p">,</span> <span class="n">pdf_y</span><span class="p">,</span> <span class="s2">&quot;k--&quot;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Gaussian fit&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">axvline</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="n">avg</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s2">&quot;r&quot;</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="s2">&quot;--&quot;</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="s2">&quot;Mean&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">()</span>
+        <span class="c1"># PDF</span>
+        <span class="n">xmin</span><span class="p">,</span> <span class="n">xmax</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">xlim</span><span class="p">()</span>
+        <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">xmin</span><span class="p">,</span> <span class="n">xmax</span><span class="p">,</span> <span class="nb">max</span><span class="p">(</span><span class="n">num_outgoing_weights</span><span class="p">))</span>
+        <span class="n">p</span> <span class="o">=</span> <span class="n">norm</span><span class="o">.</span><span class="n">pdf</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">mu</span><span class="p">,</span> <span class="n">std</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">p</span><span class="p">,</span> <span class="s1">&#39;k&#39;</span><span class="p">,</span> <span class="n">linewidth</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
+        <span class="n">title</span> <span class="o">=</span> <span class="s2">&quot;Distribution of post synaptic connections: mu = </span><span class="si">%.2f</span><span class="s2">,  std = </span><span class="si">%.2f</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">mu</span><span class="p">,</span> <span class="n">std</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">title</span><span class="p">(</span><span class="n">title</span><span class="p">)</span>
 
         <span class="k">if</span> <span class="n">savefig</span><span class="p">:</span>
             <span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s2">&quot;hist_outgoing_conn&quot;</span><span class="p">)</span>
@@ -692,17 +683,13 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
 
 <div class="viewcode-block" id="Plotter.network_connection_dynamics"><a class="viewcode-back" href="../../reference.html#sorn.utils.Plotter.network_connection_dynamics">[docs]</a>    <span class="nd">@staticmethod</span>
     <span class="k">def</span> <span class="nf">network_connection_dynamics</span><span class="p">(</span>
-        <span class="n">connection_counts</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">initial_steps</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">final_steps</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">savefig</span><span class="p">:</span> <span class="nb">bool</span>
+        <span class="n">connection_counts</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">,</span> <span class="n">savefig</span><span class="p">:</span> <span class="nb">bool</span>
     <span class="p">):</span>
         <span class="sd">&quot;&quot;&quot;Plot number of positive connection in the excitatory pool</span>
 
 <span class="sd">        Args:</span>
 <span class="sd">            connection_counts (array) - 1D Array of number of connections in the network per time step</span>
 
-<span class="sd">            initial_steps (int) - Plot for initial steps</span>
-
-<span class="sd">            final_steps (int) - Plot for final steps</span>
-
 <span class="sd">            savefig (bool) - If True plot will be saved as png file in the cwd</span>
 
 <span class="sd">        Returns:</span>
@@ -721,30 +708,6 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
         <span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="s2">&quot;upper right&quot;</span><span class="p">)</span>
         <span class="n">plt</span><span class="o">.</span><span class="n">tight_layout</span><span class="p">()</span>
 
-        <span class="c1"># Inset plot for initial simulation steps</span>
-
-        <span class="n">ax2</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
-
-        <span class="c1"># Set the position and relative size of the inset axes within ax1</span>
-        <span class="n">ip</span> <span class="o">=</span> <span class="n">InsetPosition</span><span class="p">(</span><span class="n">ax1</span><span class="p">,</span> <span class="p">[</span><span class="mf">0.25</span><span class="p">,</span> <span class="mf">0.4</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">])</span>
-        <span class="n">ax2</span><span class="o">.</span><span class="n">set_axes_locator</span><span class="p">(</span><span class="n">ip</span><span class="p">)</span>
-        <span class="n">ax2</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">connection_counts</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">initial_steps</span><span class="p">])</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">margins</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
-        <span class="n">ax2</span><span class="o">.</span><span class="n">set_title</span><span class="p">(</span><span class="s2">&quot;Initial </span><span class="si">%s</span><span class="s2"> time steps of Decay Phase&quot;</span> <span class="o">%</span> <span class="n">initial_steps</span><span class="p">)</span>
-        <span class="n">ax2</span><span class="o">.</span><span class="n">set_xticks</span><span class="p">(</span><span class="n">ax2</span><span class="o">.</span><span class="n">get_xticks</span><span class="p">()[::</span><span class="mi">2</span><span class="p">])</span>
-
-        <span class="c1"># End Inset plot</span>
-        <span class="n">ax3</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">axes</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span>
-
-        <span class="c1"># Set the position and relative size of the inset axes within ax1</span>
-        <span class="n">ip1</span> <span class="o">=</span> <span class="n">InsetPosition</span><span class="p">(</span><span class="n">ax1</span><span class="p">,</span> <span class="p">[</span><span class="mf">0.6</span><span class="p">,</span> <span class="mf">0.4</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">,</span> <span class="mf">0.3</span><span class="p">])</span>
-        <span class="n">ax3</span><span class="o">.</span><span class="n">set_axes_locator</span><span class="p">(</span><span class="n">ip1</span><span class="p">)</span>
-        <span class="c1"># Plot the last 10000 time steps</span>
-        <span class="n">ax3</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">connection_counts</span><span class="p">[</span><span class="o">-</span><span class="n">final_steps</span><span class="p">:])</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">margins</span><span class="p">(</span><span class="n">x</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
-        <span class="n">ax3</span><span class="o">.</span><span class="n">set_title</span><span class="p">(</span><span class="s2">&quot;Final </span><span class="si">%s</span><span class="s2"> time steps of Stable Phase&quot;</span> <span class="o">%</span> <span class="n">final_steps</span><span class="p">)</span>
-        <span class="n">ax3</span><span class="o">.</span><span class="n">set_xticks</span><span class="p">(</span><span class="n">ax3</span><span class="o">.</span><span class="n">get_xticks</span><span class="p">()[::</span><span class="mi">1</span><span class="p">])</span>
-
         <span class="k">if</span> <span class="n">savefig</span><span class="p">:</span>
             <span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s2">&quot;connection_dynamics&quot;</span><span class="p">)</span>
 
@@ -808,8 +771,8 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
 
         <span class="n">plt</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mf">0.1</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s2">&quot;black&quot;</span><span class="p">)</span>
 
-        <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Time(ms)&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Neuron #&quot;</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Time step&quot;</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Neuron&quot;</span><span class="p">)</span>
         <span class="n">plt</span><span class="o">.</span><span class="n">legend</span><span class="p">(</span><span class="n">loc</span><span class="o">=</span><span class="s2">&quot;upper left&quot;</span><span class="p">)</span>
 
         <span class="k">if</span> <span class="n">savefig</span><span class="p">:</span>
@@ -844,8 +807,8 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
         <span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">argwhere</span><span class="p">(</span><span class="n">spike_train</span><span class="o">.</span><span class="n">T</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span><span class="o">.</span><span class="n">T</span>
 
         <span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="s2">&quot;|r&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Time(ms)&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Neuron #&quot;</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Time step&quot;</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Neuron&quot;</span><span class="p">)</span>
 
         <span class="k">if</span> <span class="n">savefig</span><span class="p">:</span>
             <span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s2">&quot;RasterSpikeTrain.png&quot;</span><span class="p">)</span>
@@ -886,6 +849,8 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
             <span class="n">linewidths</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
             <span class="n">cbar_kws</span><span class="o">=</span><span class="p">{</span><span class="s2">&quot;shrink&quot;</span><span class="p">:</span> <span class="mf">0.9</span><span class="p">},</span>
         <span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s1">&#39;Neurons&#39;</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s1">&#39;Neurons&#39;</span><span class="p">)</span>
         <span class="k">if</span> <span class="n">savefig</span><span class="p">:</span>
             <span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s2">&quot;Correlation between neurons&quot;</span><span class="p">)</span>
         <span class="k">return</span> <span class="kc">None</span></div>
@@ -900,7 +865,7 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
 <span class="sd">        Args:</span>
 <span class="sd">            spike_train (array): Array of spike trains</span>
 
-<span class="sd">            neuron (int): If True, firing rate of the network will be plotted</span>
+<span class="sd">            neuron (int): Target neuron</span>
 
 <span class="sd">            bin_size (int): Spike train will be splitted into bins of size bin_size</span>
 
@@ -909,11 +874,8 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
 <span class="sd">        Returns:</span>
 <span class="sd">            plot object&quot;&quot;&quot;</span>
 
-        <span class="n">spike_time</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">spike_times</span><span class="p">(</span>
-            <span class="n">spike_train</span><span class="o">.</span><span class="n">T</span><span class="p">[</span><span class="n">neuron</span><span class="p">]</span>
-        <span class="p">)</span>  <span class="c1"># Locate the spike time of the target neuron</span>
 
-        <span class="n">isi</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">spike_time_intervals</span><span class="p">(</span><span class="n">spike_time</span><span class="p">)</span>
+        <span class="n">isi</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">spike_time_intervals</span><span class="p">(</span><span class="n">spike_train</span><span class="p">[:,</span><span class="n">neuron</span><span class="p">])</span>
 
         <span class="n">y</span><span class="p">,</span> <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">isi</span><span class="p">),</span> <span class="n">bins</span><span class="o">=</span><span class="n">bin_size</span><span class="p">)</span>
 
@@ -961,11 +923,11 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
         <span class="n">y</span><span class="p">,</span> <span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">histogram</span><span class="p">(</span><span class="n">weights</span><span class="p">,</span> <span class="n">bins</span><span class="o">=</span><span class="n">bin_size</span><span class="p">)</span>  <span class="c1"># Create histogram with bin_size</span>
 
         <span class="n">plt</span><span class="o">.</span><span class="n">scatter</span><span class="p">(</span><span class="n">x</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">],</span> <span class="n">y</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mf">2.0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="s2">&quot;black&quot;</span><span class="p">)</span>
-        <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Weight&quot;</span><span class="p">)</span>
+        <span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s2">&quot;Connection strength&quot;</span><span class="p">)</span>
         <span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s2">&quot;Frequency&quot;</span><span class="p">)</span>
 
         <span class="k">if</span> <span class="n">savefig</span><span class="p">:</span>
-            <span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s2">&quot;weight distribution&quot;</span><span class="p">)</span>
+            <span class="n">plt</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="s2">&quot;weight_distribution&quot;</span><span class="p">)</span>
 
         <span class="k">return</span> <span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span></div>
 
@@ -984,15 +946,16 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
 <span class="sd">        Returns:</span>
 <span class="sd">            plot object&quot;&quot;&quot;</span>
 
-        <span class="n">X</span> <span class="o">=</span> <span class="n">weights</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
+        <span class="n">weights</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">weights</span><span class="o">.</span><span class="n">tolist</span><span class="p">())</span>
+        <span class="n">weights</span> <span class="o">=</span> <span class="n">weights</span><span class="p">[</span><span class="n">weights</span> <span class="o">&gt;=</span> <span class="mf">0.01</span><span class="p">]</span>
 
-        <span class="n">M</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">X</span><span class="p">))</span>  <span class="c1"># Geometric mean</span>
-        <span class="n">s</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">X</span><span class="p">))</span>  <span class="c1"># Geometric standard deviation</span>
+        <span class="n">M</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">weights</span><span class="p">))</span>  <span class="c1"># Geometric mean</span>
+        <span class="n">s</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">weights</span><span class="p">))</span>  <span class="c1"># Geometric standard deviation</span>
 
         <span class="c1"># Lognormal distribution parameters</span>
 
-        <span class="n">mu</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">X</span><span class="p">)))</span>  <span class="c1"># Mean of log(X)</span>
-        <span class="n">sigma</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">X</span><span class="p">)))</span>  <span class="c1"># Standard deviation of log(X)</span>
+        <span class="n">mu</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">weights</span><span class="p">)))</span>  <span class="c1"># Mean of log(X)</span>
+        <span class="n">sigma</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">std</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">weights</span><span class="p">)))</span>  <span class="c1"># Standard deviation of log(X)</span>
         <span class="n">shape</span> <span class="o">=</span> <span class="n">sigma</span>  <span class="c1"># Scipy&#39;s shape parameter</span>
         <span class="n">scale</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="n">mu</span><span class="p">)</span>  <span class="c1"># Scipy&#39;s scale parameter</span>
         <span class="n">median</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="n">mu</span><span class="p">)</span>
@@ -1293,8 +1256,7 @@ <h1>Source code for sorn.utils</h1><div class="highlight"><pre>
 <span class="sd">        &quot;&quot;&quot;</span>
 
         <span class="n">spike_times</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">spike_times</span><span class="p">(</span><span class="n">spike_train</span><span class="p">)</span>
-        <span class="c1"># isi = sorted(np.diff(spike_times)[-1])</span>
-        <span class="n">isi</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">diff</span><span class="p">(</span><span class="n">spike_times</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
+        <span class="n">isi</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">diff</span><span class="p">(</span><span class="n">spike_times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
         <span class="k">return</span> <span class="n">isi</span></div>
 
 <div class="viewcode-block" id="Statistics.hamming_distance"><a class="viewcode-back" href="../../reference.html#sorn.utils.Statistics.hamming_distance">[docs]</a>    <span class="nd">@staticmethod</span>
diff --git a/docs/build/html/_sources/installation.rst.txt b/docs/build/html/_sources/installation.rst.txt
index 4056917..c8904df 100644
--- a/docs/build/html/_sources/installation.rst.txt
+++ b/docs/build/html/_sources/installation.rst.txt
@@ -1,19 +1,19 @@
 Installation
 ============
 
-Install using pip::
+Install using pip:
 
    pip install sorn
 
-or:
+or
 
-using conda::
+using conda:
 
     conda install -c conda-forge sorn
 
-or:
+or
 
-The library is still in alpha stage, so you may want to install the latest version from the development branch::
+The library is still in alpha stage, so you may want to install the latest version from the development branch:
 
     pip install git+https://github.com/Saran-nns/sorn
 
@@ -23,7 +23,7 @@ Dependencies
 
 SORN supports Python 3.5+ ONLY. For older Python versions please use the official Python client
 
-To install all optional dependencies run::
+To install all optional dependencies run:
 
   pip install 'sorn[all]'
 
diff --git a/docs/build/html/_sources/usage.rst.txt b/docs/build/html/_sources/usage.rst.txt
index 6f6bf9b..5eec799 100644
--- a/docs/build/html/_sources/usage.rst.txt
+++ b/docs/build/html/_sources/usage.rst.txt
@@ -1,123 +1,385 @@
 Usage
 =====
 
-Update network configuration
-----------------------------
-
-Configuration file
-^^^^^^^^^^^^^^^^^^
-Navigate to `home/conda/envs/ENVNAME/Lib/site-packages/sorn` or if you are unsure about the directory of `sorn`:
+Plasticity Phase
+----------------
 
-Run::
+.. code-block:: python
 
     import sorn
-    sorn.__file__
+    from sorn import Simulator
+    import numpy as np
 
-to find the location of the sorn package:
+    # Sample input
+    num_features = 10
+    time_steps = 200
+    inputs = np.random.rand(num_features,time_steps)
 
-Then, update/edit arguments in `configuration.ini`
+    # Simulate the network with default hyperparameters under gaussian white noise
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                    matrices= None, noise = True,
+                                                    time_steps=time_steps)
+
+.. list-table:: Hyperparameters of the network and default values
+   :widths: 25 25 50
+   :header-rows: 1
+
+   * - Keyword argument
+     - Value
+     - Description
+   * - ne,
+     - 200
+     - Number of Encitatory neurons in the reservoir
+   * - nu
+     - 10
+     - Number of Input neurons in the reservoir
+   * - network_type_ee
+     - "Sparse"
+     - `Sparse` or `Dense` connectivity between Excitatory neurons
+   * - network_type_ie
+     - "Dense"
+     - `Sparse` or `Dense` connectivity from Excitatory to Inhibitory neurons
+   * - network_type_ei
+     - "Sparse"
+     - `Sparse` or `Dense` connectivity from Inhibitory to Excitatory neurons
+   * - lambda_ee
+     - 20
+     - % of connections between neurons in Excitatory pool
+   * - lambda_ei
+     - 40
+     - % of connections from Inhibitory to Excitatory neurons
+   * - lambda_ie
+     - 100
+     - % of connections from Excitatory to Inhibitory neurons
+   * - eta_stdp
+     - 0.004
+     - Hebbian Learning rate for connections between excitatory neurons
+   * - eta_inhib
+     - 0.001
+     - Hebbian Learning rate for connections from Inhibitory to Excitatory neurons
+   * - eta_ip
+     - 0.01
+     - Intrinsic plasticity learning rate
+   * - te_max
+     - 1.0
+     - Maximum excitatory neuron threshold value
+   * - ti_max
+     - 0.5
+     - Maximum inhibitory neuron threshold value
+   * - ti_min
+     - 0.0
+     - Minimum inhibitory neuron threshold value
+   * - te_min
+     - 0.0
+     - Minimum excitatory neuron threshold value
+   * - mu_ip
+     - 0.01
+     - Target mean firing rate of excitatory neuron
+   * - sigma_ip
+     - 0.0
+     - Standard deviation of firing rate of excitatory neuron
+
+To override the default hyperparameters, use the `kwargs` as shown below:
+
+.. code-block:: python
+
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                    matrices=None, noise= True,
+                                                    time_steps=time_steps,
+                                                    ne = 200, nu=num_features)
+
+Training phase
+--------------
+
+.. code-block:: python
 
-Keyword arguments 
-^^^^^^^^^^^^^^^^^
-Pass the arguments with valid names (listed below). This will override the default values at `configuration.ini`: 
+    from sorn import Trainer
+    # NOTE: During training phase, input to `sorn` should have second (time) dimension set to 1. ie., input shape
+    # should be (input_features,1).
+    inputs = np.random.rand(num_features,1)
 
-The allowed `kwargs` are::
+    # SORN network is frozen during training phase
+    state_dict, E, I, R, C = Trainer.train_sorn(inputs = inputs, phase='training',
+                                                matrices=state_dict,
+                                                nu=num_features, time_steps=1)
 
-    kwargs_ = ['ne', 'nu', 'network_type_ee', 'network_type_ei', 'network_type_ie', 
-               'lambda_ee','lambda_ei', 'lambda_ie', 'eta_stdp','eta_inhib', 'eta_ip', 
-               'te_max', 'ti_max', 'ti_min', 'te_min', 'mu_ip','sigma_ip']
+Freeze plasticity
+-----------------
 
-Simulation
-----------
-Plasticity Phase
-^^^^^^^^^^^^^^^^
-The default ne, nu values are overriden by passing them as kwargs insidesimulate_sorn method::
+To turn off any plasticity mechanisms during `simulation` or `training` phase, use `freeze` argument.
+For example to stop intrinsic plasticity during simulation phase
 
-    # Import 
-    from sorn import Simulator
-    import numpy as np
+.. code-block:: python
 
-    # Sample input 
+    # Sample input
     num_features = 10
     time_steps = 200
     inputs = np.random.rand(num_features,time_steps)
 
-    # To simulate the network
-    matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, ne = 200, nu=num_features)
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                    matrices=None, noise = True,
+                                                    time_steps=time_steps, ne = 200,
+                                                    nu=num_features, freeze=['ip'])
 
-    # To resume the simulation, load the matrices_dict from previous simulation
-    matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=matrices_dict, noise= True, time_steps=time_steps,ne = 200, nu=num_features)
+The other options are,
 
-Training Phase
-^^^^^^^^^^^^^^
-Train the network using the matrices obtained from plasticity phase::
+    `stdp` - Spike Timing Dependent Plasticity
 
-    # Import
-    from sorn import Trainer
-    # Sample input
-    inputs = np.random.rand(num_features,1) 
+    `ss` - Synaptic Scaling
 
-    # SORN network is frozen during training phase
-    matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Trainer.train_sorn(inputs = inputs, phase='Training', matrices=matrices_dict,nu=num_features, time_steps=1)
+    `sp` - Structural Plasticity
+
+    `istdp` - Inhibitory Spike Timing Dependent Plasticity
+
+Note: If you pass all above options to `freeze`, then the network will behave as Liquid State Machine(LSM)
 
 Network Output Descriptions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-During plasticity and training phase, SORN returns a dictionary of below matrices for analysis:
+---------------------------
+
+    `state_dict`  - Dictionary of connection weights (`Wee`,`Wei`,`Wie`) ,
 
-    `matrices_dict` - Dictionary of connection weights ('Wee','Wei','Wie') , Excitatory network activity ('X'), Inhibitory network activities('Y'), Threshold values ('Te','Ti')
+                    Excitatory network activity (`X`),
 
-    `Exc_activity` - Collection of Excitatory network activity of entire simulation period
+                    Inhibitory network activities(`Y`),
 
-    `Inh_activity` - Collection of Inhibitory network activity of entire simulation period
+                    Threshold values (`Te`,`Ti`)
 
-    `Rec_activity` - Collection of Recurrent network activity of entire simulation period
+    `E` - Collection of Excitatory network activity of entire simulation period
 
-    `num_active_connections` - List of number of active connections in the Excitatory pool at each time step
+    `I` - Collection of Inhibitory network activity of entire simulation period
 
-Sample use with OpenAI gym
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-`Cartpole balance problem without changing the default network parameters`::
+    `R` - Collection of Recurrent network activity of entire simulation period
 
-    # Imports
+    `C` - List of number of active connections in the Excitatory pool at each time step
+
+Usage with OpenAI gym
+---------------------
+
+Cartpole balance problem
+^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
 
     from sorn import Simulator, Trainer
     import gym
 
-    # Load the simulated network matrices
-    # Note these matrices are obtained after the network achieved convergence under random inputs and noise
+    # Hyperparameters
+    NUM_EPISODES = int(2e6)
+    NUM_PLASTICITY_EPISODES = 20
+
+    LEARNING_RATE = 0.0001 # Gradient ascent learning rate
+    GAMMA = 0.99 # Discounting factor for the Rewards
 
-    with open('simulation_matrices.pkl','rb') as f:  
-        sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = pickle.load(f)
+    # Open AI gym; Cartpole Environment
+    env = gym.make('CartPole-v0')
+    action_space = env.action_space.n
 
-    # Training parameters
+    # SORN network parameters
+    ne = 50
+    nu = 4
 
-    NUM_EPISODES = 2e6
-    NUM_PLASTICITY_EPISODES = 20000
+    # Init SORN using `Simulator` under random input
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = np.random.randn(4,1),
+                                                    phase ='plasticity',
+                                                    time_steps = 1,
+                                                    noise=False,
+                                                    ne = ne, nu=nu)
 
-    env = gym.make('CartPole-v0')
+    w = np.random.rand(ne, 2) # Output layer weights
+
+    # Implementation of softmax policy
+    def policy(state,w):
+        z = state.dot(w)
+        exp = np.exp(z)
+        return exp/np.sum(exp)
+
+    # Vectorized softmax Jacobian
+    def softmax_grad(softmax):
+        s = softmax.reshape(-1,1)
+        return np.diagflat(s) - np.dot(s, s.T)
 
     for EPISODE in range(NUM_EPISODES):
-        
-        # Environment observation
-        state = env.reset()[None,:]
-        
+
+        # Environment observation;
+        # NOTE: Input to sorn should have time dimension. ie., input shape should be (input_features,time_steps)
+        state = env.reset()[:, None] # (4,) --> (4,1)
+
+        grads = [] # Episode log policy gradients
+        rewards = [] # Episode rewards
+
+        # Keep track of total score
+        score = 0
+
         # Play the episode
         while True:
-        if EPISODE < NUM_PLASTICITY_EPISODE:
-        
+
+        # env.render() # Uncomment to see your model train in real time (slow down training progress)
+        if EPISODE < NUM_PLASTICITY_EPISODES:
+
             # Plasticity phase
-            sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = Simulator.simulate_sorn(inputs = state, phase ='plasticity', matrices = sim_matrices, noise=False)
+            state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = state, phase ='plasticity',
+                                                            matrices = state_dict, time_steps = 1,
+                                                            ne = ne, nu=nu,
+                                                            noise=False)
 
         else:
             # Training phase with frozen reservoir connectivity
-            sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = Trainer.train_sorn(inputs = state, phase = 'training', matrices = sim_matrices, noise= False)
-        
-        # Feed excit_states as input states to your RL algorithm, below goes for simple policy gradient algorithm
+            state_dict, E, I, R, C = Trainer.train_sorn(inputs = state, phase = 'training',
+                                                    matrices = state_dict, time_steps = 1,
+                                                    ne = ne, nu=nu,
+                                                    noise= False)
+
+        # Feed E as input states to your RL algorithm, below goes for simple policy gradient algorithm
         # Sample policy w.r.t excitatory states and take action in the environment
-        
-        probs = policy(np.asarray(excit_states),output_layer_weights))
-        action = np.random.choice(action_space,probs)
-        state,reward,done,_ = env.step(action) 
-        
+        probs = policy(np.asarray(E),w)
+        action = np.random.choice(action_space,p=probs[0])
+        state,reward,done,_ = env.step(action)
+        state = state[:,None]
+
+        # COMPUTE GRADIENTS BASED ON YOUR OBJECTIVE FUNCTION;
+        # Sample computation of policy gradient objective function
+        dsoftmax = softmax_grad(probs)[action,:]
+        dlog = dsoftmax / probs[0,action]
+        grad = np.asarray(E).T.dot(dlog[None,:])
+        grads.append(grad)
+        rewards.append(reward)
+        score+=reward
+
         if done:
-            break
\ No newline at end of file
+            break
+
+        # OPTIMIZE OUTPUT LAYER WEIGHTS `w` BASED ON YOUR OPTIMIZATION METHOD
+
+        # Below is a sample of weight update based on gradient
+        # ascent(maximize cumulative reward) method for temporal difference learning
+        for i in range(len(grads)):
+
+            # Loop through everything that happened in the episode and update towards
+            # the log policy gradient times future reward
+            w += LEARNING_RATE * grads[i] * sum([ r * (GAMMA ** r) for t,r in enumerate(rewards[i:])])
+
+        print('Episode %s  Score %s' %(str(EPISODE),str(score)))
+
+There are several neural data analysis and visualization methods inbuilt with `sorn` package.
+Sample call for few plotting and statistical methods are shown below
+
+Plotting functions
+------------------
+
+Plot weight distribution in the network
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    from sorn import Plotter
+    # For example, the network has 200 neurons in the excitatory pool.
+    Wee = np.random.randn(200,200) # Note that generally Wee is sparse
+    Wee=Wee/Wee.max() # state_dict['Wee'] returned by the SORN is already normalized
+    Plotter.weight_distribution(weights= Wee, bin_size = 5, savefig = True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/weight_distribution.png
+
+
+Plot Spike train
+^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    E = np.random.randint(2, size=(200,1000)) # For example, activity of 200 excitatory neurons in 1000 time steps
+    Plotter.scatter_plot(spike_train = E, savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/ScatterSpikeTrain.png
+
+
+Raster plot of Spike train
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Raster plot of activity of only first 10 neurons in the excitatory pool
+    Plotter.raster_plot(spike_train = E[:,0:10], savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/RasterSpikeTrain.png
+
+Distribution of presynaptic connections
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Histogram of number of presynaptic connections per neuron in the excitatory pool
+    Plotter.hist_incoming_conn(weights=Wee, bin_size=10, histtype='bar', savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_incoming_conn.png
+
+
+Distribution of firing rate of the network
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    Plotter.hist_firing_rate_network(E, bin_size=10, savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_firing_rate_network.png
+
+Plot pearson correlation between neurons
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    from sorn import Statistics
+    avg_corr_coeff,_ = Statistics.avg_corr_coeff(E)
+    Plotter.correlation(avg_corr_coeff,savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/correlation_between_neurons.png
+
+Inter spike intervals
+^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Inter spike intervals with exponential curve fit for neuron 1 in the Excitatory pool
+    Plotter.isi_exponential_fit(E,neuron=1,bin_size=10, savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/isi_exponential_fit.png
+
+Linear and Lognormal curve fit of Synaptic weights
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Distribution of connection weights in linear and lognormal scale
+    Plotter.linear_lognormal_fit(weights=Wee,num_points=100, savefig=True)
+
+    .. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/LinearLognormalFit.png
+
+Network plot
+^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Draw network connectivity using the pearson correlation function between neurons in the excitatory pool
+    Plotter.plot_network(avg_corr_coeff,corr_thres=0.01,fig_name='network.png')
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/network.png
+
+Statistics and Analysis functions
+----------------------------------
+
+t-lagged auto correlation between neural activity
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    from sorn import Statistics
+    pearson_corr_matrix = Statistics.autocorr(firing_rates = [1,1,5,6,3,7], t= 2)
+
+Fano factor
+^^^^^^^^^^^^
+
+.. code-block:: python
+
+    # To verify poissonian process in spike generation of neuron 10
+    mean_firing_rate, variance_firing_rate, fano_factor = Statistics.fanofactor(spike_train= E,
+                                                                            neuron = 10,
+                                                                            window_size = 10)
+
+Spike Source Entropy
+^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    # Measure the uncertainty about the origin of spike from the network using entropy
+    sse = Statistics.spike_source_entropy(spike_train= E, num_neurons=200)
+
diff --git a/docs/build/html/contact.html b/docs/build/html/contact.html
index ec57a1f..a3f6e71 100644
--- a/docs/build/html/contact.html
+++ b/docs/build/html/contact.html
@@ -61,7 +61,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/contribution.html b/docs/build/html/contribution.html
index 9e9c383..a71ad9c 100644
--- a/docs/build/html/contribution.html
+++ b/docs/build/html/contribution.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html
index 1ba8d2c..3b4bff1 100644
--- a/docs/build/html/genindex.html
+++ b/docs/build/html/genindex.html
@@ -60,7 +60,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/index.html b/docs/build/html/index.html
index f6dfdce..4e19f2b 100644
--- a/docs/build/html/index.html
+++ b/docs/build/html/index.html
@@ -61,7 +61,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
@@ -215,8 +215,13 @@ <h1>Self-Organizing Recurrent Neural Network (SORN)<a class="headerlink" href="#
 </ul>
 </li>
 <li class="toctree-l1"><a class="reference internal" href="usage.html">Usage</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="usage.html#update-network-configuration">Update network configuration</a></li>
-<li class="toctree-l2"><a class="reference internal" href="usage.html#simulation">Simulation</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#plasticity-phase">Plasticity Phase</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#training-phase">Training phase</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#freeze-plasticity">Freeze plasticity</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#network-output-descriptions">Network Output Descriptions</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#usage-with-openai-gym">Usage with OpenAI gym</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#plotting-functions">Plotting functions</a></li>
+<li class="toctree-l2"><a class="reference internal" href="usage.html#statistics-and-analysis-functions">Statistics and Analysis functions</a></li>
 </ul>
 </li>
 </ul>
diff --git a/docs/build/html/installation.html b/docs/build/html/installation.html
index b7ccf95..51072a7 100644
--- a/docs/build/html/installation.html
+++ b/docs/build/html/installation.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
@@ -183,26 +183,26 @@
   <div class="section" id="installation">
 <h1>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h1>
 <p>Install using pip:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">sorn</span>
-</pre></div>
-</div>
-<p>or:</p>
+<blockquote>
+<div><p>pip install sorn</p>
+</div></blockquote>
+<p>or</p>
 <p>using conda:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">conda</span> <span class="n">install</span> <span class="o">-</span><span class="n">c</span> <span class="n">conda</span><span class="o">-</span><span class="n">forge</span> <span class="n">sorn</span>
-</pre></div>
-</div>
-<p>or:</p>
+<blockquote>
+<div><p>conda install -c conda-forge sorn</p>
+</div></blockquote>
+<p>or</p>
 <p>The library is still in alpha stage, so you may want to install the latest version from the development branch:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="n">git</span><span class="o">+</span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">Saran</span><span class="o">-</span><span class="n">nns</span><span class="o">/</span><span class="n">sorn</span>
-</pre></div>
-</div>
+<blockquote>
+<div><p>pip install git+https://github.com/Saran-nns/sorn</p>
+</div></blockquote>
 <div class="section" id="dependencies">
 <h2>Dependencies<a class="headerlink" href="#dependencies" title="Permalink to this headline">¶</a></h2>
 <p>SORN supports Python 3.5+ ONLY. For older Python versions please use the official Python client</p>
 <p>To install all optional dependencies run:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">pip</span> <span class="n">install</span> <span class="s1">&#39;sorn[all]&#39;</span>
-</pre></div>
-</div>
+<blockquote>
+<div><p>pip install ‘sorn[all]’</p>
+</div></blockquote>
 </div>
 </div>
 
diff --git a/docs/build/html/license.html b/docs/build/html/license.html
index cd84188..b691b47 100644
--- a/docs/build/html/license.html
+++ b/docs/build/html/license.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv
index ce5394e..78588e3 100644
Binary files a/docs/build/html/objects.inv and b/docs/build/html/objects.inv differ
diff --git a/docs/build/html/paper.html b/docs/build/html/paper.html
index 7abc048..3d91f99 100644
--- a/docs/build/html/paper.html
+++ b/docs/build/html/paper.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/reference.html b/docs/build/html/reference.html
index 4678f16..53f104f 100644
--- a/docs/build/html/reference.html
+++ b/docs/build/html/reference.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
@@ -232,7 +232,7 @@ <h3>Sorn<a class="headerlink" href="#sorn" title="Permalink to this headline">¶
 </dl>
 <dl class="py method">
 <dt>
-<em class="property">static </em><code class="sig-name descname">initialize_activity_vector</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">ne</span><span class="p">:</span> <span class="n">int</span></em>, <em class="sig-param"><span class="n">ni</span><span class="p">:</span> <span class="n">int</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Sorn.initialize_activity_vector"><span class="viewcode-link">[source]</span></a></dt>
+<code class="sig-name descname">initialize_activity_vector</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">ne</span><span class="p">:</span> <span class="n">int</span></em>, <em class="sig-param"><span class="n">ni</span><span class="p">:</span> <span class="n">int</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Sorn.initialize_activity_vector"><span class="viewcode-link">[source]</span></a></dt>
 <dd><p>Initialize the activity vectors X and Y for excitatory and inhibitory neurons</p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
@@ -254,7 +254,7 @@ <h3>Sorn<a class="headerlink" href="#sorn" title="Permalink to this headline">¶
 
 <dl class="py method">
 <dt>
-<em class="property">static </em><code class="sig-name descname">initialize_threshold_matrix</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">te_min</span><span class="p">:</span> <span class="n">float</span></em>, <em class="sig-param"><span class="n">te_max</span><span class="p">:</span> <span class="n">float</span></em>, <em class="sig-param"><span class="n">ti_min</span><span class="p">:</span> <span class="n">float</span></em>, <em class="sig-param"><span class="n">ti_max</span><span class="p">:</span> <span class="n">float</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Sorn.initialize_threshold_matrix"><span class="viewcode-link">[source]</span></a></dt>
+<code class="sig-name descname">initialize_threshold_matrix</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">te_min</span><span class="p">:</span> <span class="n">float</span></em>, <em class="sig-param"><span class="n">te_max</span><span class="p">:</span> <span class="n">float</span></em>, <em class="sig-param"><span class="n">ti_min</span><span class="p">:</span> <span class="n">float</span></em>, <em class="sig-param"><span class="n">ti_max</span><span class="p">:</span> <span class="n">float</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Sorn.initialize_threshold_matrix"><span class="viewcode-link">[source]</span></a></dt>
 <dd><p>Initialize the threshold for excitatory and inhibitory neurons</p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
@@ -277,7 +277,7 @@ <h3>Sorn<a class="headerlink" href="#sorn" title="Permalink to this headline">¶
 
 <dl class="py method">
 <dt>
-<em class="property">static </em><code class="sig-name descname">initialize_weight_matrix</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">network_type</span><span class="p">:</span> <span class="n">str</span></em>, <em class="sig-param"><span class="n">synaptic_connection</span><span class="p">:</span> <span class="n">str</span></em>, <em class="sig-param"><span class="n">self_connection</span><span class="p">:</span> <span class="n">str</span></em>, <em class="sig-param"><span class="n">lambd_w</span><span class="p">:</span> <span class="n">int</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Sorn.initialize_weight_matrix"><span class="viewcode-link">[source]</span></a></dt>
+<code class="sig-name descname">initialize_weight_matrix</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">network_type</span><span class="p">:</span> <span class="n">str</span></em>, <em class="sig-param"><span class="n">synaptic_connection</span><span class="p">:</span> <span class="n">str</span></em>, <em class="sig-param"><span class="n">self_connection</span><span class="p">:</span> <span class="n">str</span></em>, <em class="sig-param"><span class="n">lambd_w</span><span class="p">:</span> <span class="n">int</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Sorn.initialize_weight_matrix"><span class="viewcode-link">[source]</span></a></dt>
 <dd><p>Wrapper for initializing the weight matrices for SORN</p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
@@ -436,7 +436,7 @@ <h3>Plasticity<a class="headerlink" href="#plasticity" title="Permalink to this
 </dl>
 <dl class="py method">
 <dt>
-<em class="property">static </em><code class="sig-name descname">initialize_plasticity</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Plasticity.initialize_plasticity"><span class="viewcode-link">[source]</span></a></dt>
+<code class="sig-name descname">initialize_plasticity</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Plasticity.initialize_plasticity"><span class="viewcode-link">[source]</span></a></dt>
 <dd><p>Initialize weight matrices for plasticity phase based on network configuration</p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
@@ -495,7 +495,7 @@ <h3>Plasticity<a class="headerlink" href="#plasticity" title="Permalink to this
 
 <dl class="py method">
 <dt>
-<code class="sig-name descname">ss</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">wee</span><span class="p">:</span> <span class="n">numpy.array</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Plasticity.ss"><span class="viewcode-link">[source]</span></a></dt>
+<em class="property">static </em><code class="sig-name descname">ss</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">wee</span><span class="p">:</span> <span class="n">numpy.array</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/sorn.html#Plasticity.ss"><span class="viewcode-link">[source]</span></a></dt>
 <dd><p>Synaptic Scaling or Synaptic Normalization</p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
@@ -856,7 +856,7 @@ <h3>Plotting<a class="headerlink" href="#plotting" title="Permalink to this head
 <dl class="py method">
 <dt>
 <em class="property">static </em><code class="sig-name descname">hist_incoming_conn</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">weights</span><span class="p">:</span> <span class="n">numpy.array</span></em>, <em class="sig-param"><span class="n">bin_size</span><span class="p">:</span> <span class="n">int</span></em>, <em class="sig-param"><span class="n">histtype</span><span class="p">:</span> <span class="n">str</span></em>, <em class="sig-param"><span class="n">savefig</span><span class="p">:</span> <span class="n">bool</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/utils.html#Plotter.hist_incoming_conn"><span class="viewcode-link">[source]</span></a></dt>
-<dd><p>Plot the histogram of number of incoming connections per neuron</p>
+<dd><p>Plot the histogram of number of presynaptic connections per neuron</p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
 <dd class="field-odd"><ul class="simple">
@@ -902,7 +902,7 @@ <h3>Plotting<a class="headerlink" href="#plotting" title="Permalink to this head
 <dt class="field-odd">Parameters</dt>
 <dd class="field-odd"><ul class="simple">
 <li><p><strong>spike_train</strong> (<em>array</em>) – Array of spike trains</p></li>
-<li><p><strong>neuron</strong> (<em>int</em>) – If True, firing rate of the network will be plotted</p></li>
+<li><p><strong>neuron</strong> (<em>int</em>) – Target neuron</p></li>
 <li><p><strong>bin_size</strong> (<em>int</em>) – Spike train will be splitted into bins of size bin_size</p></li>
 <li><p><strong>savefig</strong> (<em>bool</em>) – If True, plot will be saved in the cwd</p></li>
 </ul>
@@ -933,14 +933,12 @@ <h3>Plotting<a class="headerlink" href="#plotting" title="Permalink to this head
 
 <dl class="py method">
 <dt>
-<em class="property">static </em><code class="sig-name descname">network_connection_dynamics</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">connection_counts</span><span class="p">:</span> <span class="n">numpy.array</span></em>, <em class="sig-param"><span class="n">initial_steps</span><span class="p">:</span> <span class="n">int</span></em>, <em class="sig-param"><span class="n">final_steps</span><span class="p">:</span> <span class="n">int</span></em>, <em class="sig-param"><span class="n">savefig</span><span class="p">:</span> <span class="n">bool</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/utils.html#Plotter.network_connection_dynamics"><span class="viewcode-link">[source]</span></a></dt>
+<em class="property">static </em><code class="sig-name descname">network_connection_dynamics</code><span class="sig-paren">(</span><em class="sig-param"><span class="n">connection_counts</span><span class="p">:</span> <span class="n">numpy.array</span></em>, <em class="sig-param"><span class="n">savefig</span><span class="p">:</span> <span class="n">bool</span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/sorn/utils.html#Plotter.network_connection_dynamics"><span class="viewcode-link">[source]</span></a></dt>
 <dd><p>Plot number of positive connection in the excitatory pool</p>
 <dl class="field-list simple">
 <dt class="field-odd">Parameters</dt>
 <dd class="field-odd"><ul class="simple">
 <li><p><strong>connection_counts</strong> (<em>array</em>) – </p></li>
-<li><p><strong>initial_steps</strong> (<em>int</em>) – </p></li>
-<li><p><strong>final_steps</strong> (<em>int</em>) – </p></li>
 <li><p><strong>savefig</strong> (<em>bool</em>) – </p></li>
 </ul>
 </dd>
diff --git a/docs/build/html/search.html b/docs/build/html/search.html
index a249435..8da1d7e 100644
--- a/docs/build/html/search.html
+++ b/docs/build/html/search.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js
index 074f007..e7764ba 100644
--- a/docs/build/html/searchindex.js
+++ b/docs/build/html/searchindex.js
@@ -1,1 +1,1 @@
-Search.setIndex({docnames:["contact","contribution","index","installation","license","paper","reference","software","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["contact.rst","contribution.rst","index.rst","installation.rst","license.rst","paper.rst","reference.rst","software.rst","usage.rst"],objects:{},objnames:{},objtypes:{},terms:{"001":6,"004":6,"100":6,"13140":5,"200":[6,8],"20000":8,"2019":[4,5],"2020":7,"25393":5,"2e6":8,"4184103":7,"5281":7,"81762":5,"break":8,"case":2,"class":[2,6],"default":[6,8],"float":6,"function":2,"import":8,"int":6,"long":2,"new":[1,2,6],"return":[6,8],"static":[2,6],"true":[6,8],"while":[2,8],AND:4,BUT:4,FOR:4,For:3,NOT:4,Such:2,THE:4,The:[2,3,4,6,8],Then:8,These:2,USE:4,WITH:4,__dict__:6,__file__:8,_ne:6,_nu:6,abil:2,about:[6,8],abov:[4,6],absenc:6,achiev:8,acit:6,action:[2,4,8],action_spac:8,activ:[2,6,8],activity_vector:6,actual_spike_train:6,adapt:2,add:[1,6],added:6,after:8,algorithm:8,all:[3,4,6],allow:8,alpha:[3,7],also:2,amount:6,analysi:8,ani:[4,6],anoth:6,appar:6,appli:6,argu:2,argument:6,aris:4,arrai:6,articl:6,artifici:5,asarrai:8,aspect:2,associ:4,assum:2,attenu:2,attribut:[2,6],author:[4,7],autocorr:6,autocorrel:6,avail:6,averag:6,avg_corr_coeff:6,axi:6,balanc:[2,8],base:[2,6],befor:1,being:2,below:[6,8],between:[2,6],bin:6,bin_siz:6,biolog:[2,5],bool:6,both:2,brain:[2,5],branch:[1,3],bug:1,build:2,burst:2,calcul:6,call:6,can:[1,2],cartpol:8,cellular:2,chang:[1,2,6,8],chao:5,character:2,characterist:2,charg:4,checkout:1,choic:8,circuit:[2,5],citat:2,claim:4,client:3,clone:1,code:1,coeff_var:6,coeffeci:6,collect:[6,8],com:[0,1,3],comput:2,conda:[3,8],condit:4,configur:[2,6],confirm:2,connect:[2,4,6,8],connection_count:6,connectom:2,consequ:2,consid:6,consist:2,constant:6,constantli:2,contact:2,contract:4,contribut:2,converg:8,copi:4,copyright:4,corr:6,corr_thr:6,correl:[2,6],correspond:6,cortic:2,counteract:2,creat:1,current:6,curv:6,cutoff_weight:6,cwd:6,cycl:2,damag:4,data:6,deal:4,defin:6,delai:6,dens:6,densiti:6,depend:[2,6],depress:2,descript:2,despit:2,destabil:2,develop:3,dict:6,dictionari:8,directori:[6,8],discuss:1,distanc:6,distribut:[4,6],divid:6,document:[1,4],doi:[5,7],domin:2,done:8,drive:[2,6],driven:2,due:[2,6],dure:[6,8],dynam:2,each:[6,8],edit:8,either:2,els:8,encapsul:6,entir:[6,8],entropi:6,env:8,environ:8,envnam:8,episod:8,error:1,eta_inhib:[6,8],eta_ip:[6,8],eta_stdp:[6,8],event:4,evid:2,evolut:6,exc_act:8,excit_st:8,excitatori:[2,6,8],excitatory_net:6,excitatory_network_st:6,exitatori:6,experiment:2,exponenti:6,express:4,extend:2,extern:6,factor:6,fals:[6,8],fano:6,fanofactor:6,fast:2,featur:2,feed:8,feedback:2,fetch:1,fig:6,fig_nam:6,figur:6,file:[4,6],final_step:6,find:[1,2,8],fire:6,firing_r:6,firing_rate_network:6,firing_rate_neuron:6,first:2,fit:[4,6],follow:[4,6],forg:3,fork:1,found:2,frac_pos_active_conn:6,free:4,freez:6,fresh:6,from:[1,2,3,4,6,8],frozen:8,fundament:2,furnish:4,further:2,gaussian:6,gener:[2,5,6],get:[2,6],git:[1,3],github:[1,3],give:6,given:6,goe:8,gradient:8,grant:4,graphic:6,guid:2,h_ip:6,ham:6,hamming_dist:6,hebbian:2,help:2,henc:2,herebi:4,higher:6,hist_firing_rate_network:6,hist_incoming_conn:6,hist_outgoing_conn:6,histogram:6,histtyp:6,holder:4,home:8,homeostat:2,hotmail:0,howev:2,http:[3,7],immin:5,impli:[4,6],includ:4,incom:[2,6],incoming_dr:6,independ:6,index:2,individu:2,induc:2,influenc:2,inform:[1,2],inh_act:8,inherit:6,inhib_st:8,inhibitori:[2,6,8],inhibitory_net:6,inhibitory_network_st:6,ini:8,initi:6,initial_step:6,initialize_activity_vector:6,initialize_plast:6,initialize_threshold_matrix:6,initialize_weight_matrix:6,input:[6,8],insidesimulate_sorn:8,instal:2,instanc:6,instant:6,intellig:5,inter:6,interpret:6,interv:6,intrins:[2,6],introduc:2,investig:[2,6],isi_exponential_fit:6,issu:1,istdp:[2,6],its:[2,6],jag:6,kind:4,kwarg:[6,8],kwargs_:8,lambd_w:6,lambda_e:[6,8],lambda_ei:[6,8],lambda_i:[6,8],latest:3,ldp:2,lead:2,learn:[2,6],length:6,level:2,liabil:4,liabl:4,lib:8,librari:3,licens:2,like:6,limit:4,linear:6,linear_lognormal_fit:6,liquid:2,list:[6,8],load:8,locat:8,lognorm:6,ltd:2,ltp:2,macroscop:2,mai:[2,3],maintain:2,make:8,mani:2,master:1,mathemat:2,matplotlib:6,matric:[6,8],matrices_dict:8,matrix:6,max:6,maximum:6,mean:6,measur:6,mechan:[2,6],memori:2,mention:6,merchant:4,merg:4,mesoscop:2,method:[2,6,8],microscop:2,mimic:2,min:6,minimum:6,model:2,modifi:4,modul:2,month:7,more:2,moreov:2,morphogenesi:2,mu_ip:[6,8],nambusubramaniyan:[4,5,7],name:[1,2,6,8],navig:8,neg:2,neocort:2,neocortex:2,netork:6,network_activity_t:6,network_activity_t_1:6,network_connection_dynam:6,network_typ:6,network_type_e:[6,8],network_type_ei:[6,8],network_type_i:[6,8],neural:6,neuro:2,neuron:[2,6],neuroplast:2,next:6,nns:[1,3,7],nois:[6,8],none:[6,8],noninfring:4,normal:[2,6],note:[6,8],notic:4,nov:7,num_active_connect:8,num_episod:8,num_featur:8,num_neuron:6,num_plasticity_episod:8,num_point:6,num_reservoir_conn:8,number:[6,8],numpi:[6,8],object:6,observ:8,obtain:[4,8],occur:2,off:6,offici:3,older:3,one:6,onli:[3,6],open:[1,8],option:[3,6],org:7,origin:6,other:[2,4],otherwis:4,out:4,outgo:6,outperform:2,output_layer_weight:8,over:2,overal:[2,6],overrid:8,overriden:8,packag:8,page:2,paper:2,paramet:[6,8],parent:6,particular:[4,6],pass:8,pearson:6,per:6,period:8,permiss:4,permit:4,person:4,perturb:6,perturbed_spike_train:6,phase:6,phenomena:2,pickl:8,pip:3,pkl:8,plai:8,plasit:6,plastic:2,plastic_matric:6,plausibl:5,pleas:[0,1,3,5,7],plot_network:6,plotter:6,png:6,point:6,poisson:6,polici:8,pool:[2,6,8],popul:[2,6],portion:4,posit:[2,6],possess:2,post:6,potenti:[2,6],pre:6,pretrain:6,previou:[6,8],principl:2,prob:8,problem:8,process:[2,6],propos:2,prospect:5,prove:2,provid:[1,4],prune:6,publish:[4,7],pull:1,purpos:4,pyplot:6,python:3,question:0,r_all:6,rand:8,random:8,randomli:6,rang:[2,6,8],rapid:2,raster:6,raster_plot:6,rate:[2,6],reach:2,real:2,rebas:1,rec_act:8,receiv:6,recent:2,recur_st:8,recurr:[6,8],recurrent_dr:6,refer:2,region:2,regul:[2,6],regulatori:2,relationship:6,releas:7,remot:1,replic:2,repo:1,report:1,repositori:1,reproduc:1,request:1,research:2,resembl:2,reservoir:[2,6,8],reset:8,restrict:4,resum:8,retriev:1,reveal:2,reward:8,right:4,rule:[2,6],run:[3,8],same:6,saran:[1,3,7],saran_nn:0,saranraj:[4,5,7],saranraj_nambusubramaniyan_2020_4184103:7,save:6,savefig:6,scale:[2,6],scale_dependent_smoothness_measur:6,scale_independent_smoothness_measur:6,scatter:6,scatter_plot:6,score:6,sd_diff:6,search:2,select:2,self:6,self_connect:6,sell:4,semant:6,seri:6,set:2,shall:4,show:2,sigma_ip:[6,8],signifi:6,sim_matric:8,simpl:8,simplifi:2,simul:2,simulate_sorn:[6,8],simulation_matric:8,simulator_:6,singl:6,site:8,size:6,slide:6,small:2,smaller:[2,6],smallest:6,smooth:6,smoothem:6,smoother:6,smoothli:6,softwar:[2,4,7],solv:5,some:2,sorn1:6,sorn2:6,sorn:[1,3,7,8],sourc:6,spare:6,spars:6,spatio:2,spike:[2,6],spike_source_entropi:6,spike_tim:6,spike_time_interv:6,spike_train:6,split:6,splite:6,stabl:7,stage:3,start:2,state:[2,6,8],stdp:[2,6],step:[2,6,8],still:3,stimuli:6,str:6,strength:[2,6],strengthen:2,structur:2,structural_plast:6,studi:2,subcrit:2,subject:[2,4],sublicens:4,substanti:4,substrat:2,suffici:1,suggest:6,suitabl:2,support:3,suppress:2,synaps:2,synapt:[2,6],synaptic_connect:6,system:2,take:8,target:6,task:[2,5],te_max:[6,8],te_min:[6,8],tempor:2,thei:2,them:8,thesi:5,thi:[4,6,8],three:2,threshold:[6,8],threshold_matrix:6,through:2,ti_max:[6,8],ti_min:[6,8],time:[2,6,8],time_step:[6,8],titl:7,togeth:2,tort:4,total:6,toward:[2,6],train:6,train_sorn:[6,8],trainer:8,trainer_:6,tupl:6,turn:6,two:2,type:6,uncertainti:6,unconnect:2,uncorrel:2,under:8,underli:2,understand:2,unit:6,unlik:2,unravel:2,unsur:8,updat:[2,6],upstream:1,url:7,usag:2,use:[3,4],user:1,using:[3,6,8],v_t:6,valid:8,valu:[6,8],vari:6,variabl:6,varianc:6,vector:6,versa:6,version:[3,7],via:6,vice:6,visual:6,vivo:2,wai:6,want:3,warranti:4,weaken:2,wee:[6,8],wei:[6,8],weight:[6,8],weight_distribut:6,weight_matrix:6,whether:[4,6],which:[2,6],white_noise_:6,white_noise_i:6,whom:4,wie:[6,8],window:6,window_s:6,wish:1,with_firing_r:6,within:2,without:[4,6,8],won:6,work:6,wrap:6,wrapper:6,x_all:6,y_all:6,year:7,you:[1,3,8],your:[1,8],your_branch_nam:1,yournam:1,zenodo:7},titles:["Contact","Contributions","Self-Organizing Recurrent Neural Network (SORN)","Installation","MIT License","Cite Paper","Reference","Cite Package","Usage"],titleterms:{"function":6,analysi:6,argument:8,cite:[5,7],configur:8,contact:0,contribut:1,depend:3,descript:8,file:8,gym:8,indic:2,instal:3,keyword:8,licens:4,matrixcollect:6,mit:4,network:[2,6,8],networkst:6,neural:2,openai:8,organ:2,output:8,packag:7,paper:5,phase:8,plastic:[6,8],plot:6,recurr:2,refer:6,sampl:8,self:2,simul:[6,8],sorn:[2,6],statist:6,tabl:2,train:8,trainer:6,updat:8,usag:8,use:8,util:6}})
\ No newline at end of file
+Search.setIndex({docnames:["contact","contribution","index","installation","license","paper","reference","software","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["contact.rst","contribution.rst","index.rst","installation.rst","license.rst","paper.rst","reference.rst","software.rst","usage.rst"],objects:{},objnames:{},objtypes:{},terms:{"0001":8,"001":[6,8],"004":[6,8],"100":[6,8],"1000":8,"13140":5,"200":[6,8],"2019":[4,5],"2020":7,"25393":5,"2e6":8,"4184103":7,"5281":7,"81762":5,"break":8,"case":2,"class":[2,6],"default":6,"float":6,"function":2,"import":8,"int":[6,8],"long":2,"new":[1,2,6],"return":[6,8],"static":[2,6],"true":[6,8],"while":[2,8],AND:4,BUT:4,FOR:4,For:[3,8],NOT:4,Such:2,THE:4,The:[2,3,4,6,8],There:8,These:2,USE:4,WITH:4,__dict__:6,_ne:6,_nu:6,abil:2,about:[6,8],abov:[4,6,8],absenc:6,acit:6,action:[2,4,8],action_spac:8,activ:[2,6],activity_vector:6,actual_spike_train:6,adapt:2,add:[1,6],added:6,algorithm:8,all:[3,4,6,8],alpha:[3,7],alreadi:8,also:2,amount:6,analysi:2,ani:[4,6,8],anoth:6,appar:6,append:8,appli:6,argu:2,argument:[6,8],aris:4,arrai:6,articl:6,artifici:5,asarrai:8,ascent:8,aspect:2,associ:4,assum:2,attenu:2,attribut:[2,6],author:[4,7],autocorr:[6,8],autocorrel:6,avail:6,averag:6,avg_corr_coeff:[6,8],axi:6,balanc:2,bar:8,base:[2,6,8],befor:1,behav:8,being:2,below:[6,8],between:[2,6],bin:6,bin_siz:[6,8],biolog:[2,5],bool:6,both:2,brain:[2,5],branch:[1,3],bug:1,build:2,burst:2,calcul:6,call:[6,8],can:[1,2],cellular:2,chang:[1,2,6],chao:5,character:2,characterist:2,charg:4,checkout:1,choic:8,circuit:[2,5],citat:2,claim:4,client:3,clone:1,code:1,coeff_var:6,coeffeci:6,collect:[6,8],com:[0,1,3,8],comput:[2,8],conda:3,condit:4,configur:6,confirm:2,connect:[2,4,6],connection_count:6,connectom:2,consequ:2,consid:6,consist:2,constant:6,constantli:2,contact:2,contract:4,contribut:2,copi:4,copyright:4,corr:6,corr_thr:[6,8],correl:[2,6],correspond:6,cortic:2,counteract:2,creat:1,cumul:8,current:6,curv:6,cutoff_weight:6,cwd:6,cycl:2,damag:4,data:[6,8],deal:4,def:8,defin:6,delai:6,dens:[6,8],densiti:6,depend:[2,6,8],depress:2,descript:2,despit:2,destabil:2,develop:3,deviat:8,diagflat:8,dict:6,dictionari:8,differ:8,dimens:8,directori:6,discount:8,discuss:1,distanc:6,distribut:[4,6],divid:6,dlog:8,document:[1,4],doi:[5,7],domin:2,done:8,dot:8,down:8,draw:8,drive:[2,6],driven:2,dsoftmax:8,due:[2,6],dure:[6,8],dynam:2,each:[6,8],either:2,els:8,encapsul:6,encitatori:8,entir:[6,8],entropi:6,enumer:8,env:8,environ:8,episod:8,error:1,eta_inhib:[6,8],eta_ip:[6,8],eta_stdp:[6,8],event:4,everyth:8,evid:2,evolut:6,exampl:8,excitatori:[2,6,8],excitatory_net:6,excitatory_network_st:6,exitatori:6,exp:8,experiment:2,exponenti:[6,8],express:4,extend:2,extern:6,factor:6,fals:[6,8],fano:6,fano_factor:8,fanofactor:[6,8],fast:2,featur:2,feed:8,feedback:2,fetch:1,few:8,fig:6,fig_nam:[6,8],figur:6,file:[4,6],find:[1,2],fire:6,firing_r:[6,8],firing_rate_network:6,firing_rate_neuron:6,first:[2,8],fit:[4,6],follow:[4,6],forg:3,fork:1,found:2,frac_pos_active_conn:6,free:4,freez:[2,6],fresh:6,from:[1,2,3,4,6,8],frozen:8,fundament:2,furnish:4,further:2,futur:8,gamma:8,gaussian:[6,8],gener:[2,5,6,8],get:[2,6],git:[1,3],github:[1,3],githubusercont:8,give:6,given:6,goe:8,grad:8,gradient:8,grant:4,graphic:6,guid:2,gym:2,h_ip:6,ham:6,hamming_dist:6,happen:8,has:8,have:8,hebbian:[2,8],help:2,henc:2,herebi:4,higher:6,hist_firing_rate_network:[6,8],hist_incoming_conn:[6,8],hist_outgoing_conn:6,histogram:[6,8],histtyp:[6,8],holder:4,homeostat:2,hotmail:0,howev:2,http:[3,7,8],imag:8,img:8,immin:5,implement:8,impli:[4,6],inbuilt:8,includ:4,incom:[2,6],incoming_dr:6,independ:6,index:2,individu:2,induc:2,influenc:2,inform:[1,2],inherit:6,inhibitori:[2,6,8],inhibitory_net:6,inhibitory_network_st:6,init:8,initi:6,initialize_activity_vector:6,initialize_plast:6,initialize_threshold_matrix:6,initialize_weight_matrix:6,input:[6,8],input_featur:8,instal:2,instanc:6,instant:6,intellig:5,inter:6,interpret:6,interv:6,intrins:[2,6,8],introduc:2,investig:[2,6],isi_exponential_fit:[6,8],issu:1,istdp:[2,6,8],its:[2,6],jacobian:8,jag:6,keep:8,keyword:8,kind:4,kwarg:[6,8],lambd_w:6,lambda_e:[6,8],lambda_ei:[6,8],lambda_i:[6,8],latest:3,layer:8,ldp:2,lead:2,learn:[2,6,8],learning_r:8,len:8,length:6,level:2,liabil:4,liabl:4,librari:3,licens:2,like:6,limit:4,linear:6,linear_lognormal_fit:[6,8],linearlognormalfit:8,liquid:[2,8],list:[6,8],log:8,lognorm:6,loop:8,lsm:8,ltd:2,ltp:2,machin:8,macroscop:2,mai:[2,3],maintain:2,make:8,mani:2,master:1,mathemat:2,matplotlib:6,matric:[6,8],matrix:6,max:[6,8],maxim:8,maximum:[6,8],mean:[6,8],mean_firing_r:8,measur:[6,8],mechan:[2,6,8],memori:2,mention:6,merchant:4,merg:4,mesoscop:2,method:[2,6,8],microscop:2,mimic:2,min:6,minimum:[6,8],model:[2,8],modifi:4,modul:2,month:7,more:2,moreov:2,morphogenesi:2,mu_ip:[6,8],nambusubramaniyan:[4,5,7],name:[1,2,6],neg:2,neocort:2,neocortex:2,netork:6,network_activity_t:6,network_activity_t_1:6,network_connection_dynam:6,network_typ:6,network_type_e:[6,8],network_type_ei:[6,8],network_type_i:[6,8],neural:6,neuro:2,neuron:[2,6],neuroplast:2,next:6,nns:[1,3,7,8],nois:[6,8],none:[6,8],noninfring:4,normal:[2,6,8],note:[6,8],notic:4,nov:7,num_episod:8,num_featur:8,num_neuron:[6,8],num_plasticity_episod:8,num_point:[6,8],number:[6,8],numpi:[6,8],object:[6,8],observ:8,obtain:4,occur:2,off:[6,8],offici:3,older:3,one:6,onli:[3,6,8],open:[1,8],openai:2,optim:8,option:[3,6,8],org:7,origin:[6,8],other:[2,4,8],otherwis:4,out:4,outgo:6,outperform:2,output:2,over:2,overal:[2,6],overrid:8,packag:8,page:2,paper:2,paramet:[6,8],parent:6,particular:[4,6],pass:8,pearson:6,pearson_corr_matrix:8,per:[6,8],period:8,permiss:4,permit:4,person:4,perturb:6,perturbed_spike_train:6,phase:[2,6],phenomena:2,pip:3,plai:8,plasit:6,plastic:2,plastic_matric:6,plausibl:5,pleas:[0,1,3,5,7],plot:2,plot_network:[6,8],plotter:[6,8],png:[6,8],point:6,poisson:6,poissonian:8,polici:8,pool:[2,6,8],popul:[2,6],portion:4,posit:[2,6],possess:2,post:6,potenti:[2,6],pre:6,presynapt:6,pretrain:6,previou:6,principl:2,print:8,prob:8,process:[2,6,8],progress:8,propos:2,prospect:5,prove:2,provid:[1,4],prune:6,publish:[4,7],pull:1,purpos:4,pyplot:6,python:3,question:0,r_all:6,rand:8,randint:8,randn:8,random:8,randomli:6,rang:[2,6,8],rapid:2,raster:6,raster_plot:[6,8],rate:[2,6],raw:8,reach:2,real:[2,8],rebas:1,receiv:6,recent:2,recurr:[6,8],recurrent_dr:6,refer:2,region:2,regul:[2,6],regulatori:2,relationship:6,releas:7,remot:1,render:8,replic:2,repo:1,report:1,repositori:1,reproduc:1,request:1,research:2,resembl:2,reservoir:[2,6,8],reset:8,reshap:8,restrict:4,retriev:1,reveal:2,revis:8,reward:8,right:4,rule:[2,6],run:3,same:6,sampl:8,saran:[1,3,7,8],saran_nn:0,saranraj:[4,5,7],saranraj_nambusubramaniyan_2020_4184103:7,save:6,savefig:[6,8],scale:[2,6,8],scale_dependent_smoothness_measur:6,scale_independent_smoothness_measur:6,scatter:6,scatter_plot:[6,8],score:[6,8],sd_diff:6,search:2,second:8,see:8,select:2,self:6,self_connect:6,sell:4,semant:6,seri:6,set:[2,8],sever:8,shall:4,shape:8,should:8,show:2,shown:8,sigma_ip:[6,8],signifi:6,simpl:8,simplifi:2,simul:8,simulate_sorn:[6,8],simulator_:6,singl:6,size:[6,8],slide:6,slow:8,small:2,smaller:[2,6],smallest:6,smooth:6,smoothem:6,smoother:6,smoothli:6,softmax:8,softmax_grad:8,softwar:[2,4,7],solv:5,some:2,sorn1:6,sorn2:6,sorn:[1,3,7,8],sourc:6,spare:6,spars:[6,8],spatio:2,spike:[2,6],spike_source_entropi:[6,8],spike_tim:6,spike_time_interv:6,spike_train:[6,8],split:6,splite:6,sse:8,stabl:7,stage:3,standard:8,start:2,state:[2,6,8],state_dict:8,statist:2,stdp:[2,6,8],step:[2,6,8],still:3,stimuli:6,stop:8,str:[6,8],strength:[2,6],strengthen:2,structur:[2,8],structural_plast:6,studi:2,subcrit:2,subject:[2,4],sublicens:4,substanti:4,substrat:2,suffici:1,suggest:6,suitabl:2,sum:8,support:3,suppress:2,synaps:2,synapt:[2,6],synaptic_connect:6,system:2,take:8,target:[6,8],task:[2,5],te_max:[6,8],te_min:[6,8],tempor:[2,8],thei:2,thesi:5,thi:[4,6],three:2,threshold:[6,8],threshold_matrix:6,through:[2,8],ti_max:[6,8],ti_min:[6,8],time:[2,6,8],time_step:[6,8],titl:7,togeth:2,tort:4,total:[6,8],toward:[2,6,8],track:8,train:[2,6],train_sorn:[6,8],trainer:8,trainer_:6,tupl:6,turn:[6,8],two:2,type:6,uncertainti:[6,8],uncom:8,unconnect:2,uncorrel:2,under:8,underli:2,understand:2,unit:6,unlik:2,unravel:2,updat:[6,8],upstream:1,url:7,usag:2,use:[3,4,8],user:1,using:[3,6,8],v_t:6,valu:6,vari:6,variabl:6,varianc:6,variance_firing_r:8,vector:[6,8],verifi:8,versa:6,version:[3,7],via:6,vice:6,visual:[6,8],vivo:2,wai:6,want:3,warranti:4,weaken:2,wee:[6,8],wei:[6,8],weight:6,weight_distribut:[6,8],weight_matrix:6,whether:[4,6],which:[2,6],white:8,white_noise_:6,white_noise_i:6,whom:4,wie:[6,8],window:6,window_s:[6,8],wish:1,with_firing_r:6,within:2,without:[4,6],won:6,work:6,wrap:6,wrapper:6,x_all:6,y_all:6,year:7,you:[1,3,8],your:[1,8],your_branch_nam:1,yournam:1,zenodo:7},titles:["Contact","Contributions","Self-Organizing Recurrent Neural Network (SORN)","Installation","MIT License","Cite Paper","Reference","Cite Package","Usage"],titleterms:{"default":8,"function":[6,8],activ:8,analysi:[6,8],auto:8,balanc:8,between:8,cartpol:8,cite:[5,7],connect:8,contact:0,contribut:1,correl:8,curv:8,depend:3,descript:8,distribut:8,entropi:8,factor:8,fano:8,fire:8,fit:8,freez:8,gym:8,hyperparamet:8,indic:2,instal:3,inter:8,interv:8,lag:8,licens:4,linear:8,lognorm:8,matrixcollect:6,mit:4,network:[2,6,8],networkst:6,neural:[2,8],neuron:8,openai:8,organ:2,output:8,packag:7,paper:5,pearson:8,phase:8,plastic:[6,8],plot:[6,8],presynapt:8,problem:8,raster:8,rate:8,recurr:2,refer:6,self:2,simul:6,sorn:[2,6],sourc:8,spike:8,statist:[6,8],synapt:8,tabl:2,train:8,trainer:6,usag:8,util:6,valu:8,weight:8}})
\ No newline at end of file
diff --git a/docs/build/html/software.html b/docs/build/html/software.html
index b4e8265..6a289ce 100644
--- a/docs/build/html/software.html
+++ b/docs/build/html/software.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
diff --git a/docs/build/html/usage.html b/docs/build/html/usage.html
index 551b34d..6089fa3 100644
--- a/docs/build/html/usage.html
+++ b/docs/build/html/usage.html
@@ -62,7 +62,7 @@
             
             
               <div class="version">
-                0.4.9
+                0.5.3
               </div>
             
           
@@ -91,16 +91,30 @@
 <ul class="current">
 <li class="toctree-l1"><a class="reference internal" href="installation.html">Installation</a></li>
 <li class="toctree-l1 current"><a class="current reference internal" href="#">Usage</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="#update-network-configuration">Update network configuration</a><ul>
-<li class="toctree-l3"><a class="reference internal" href="#configuration-file">Configuration file</a></li>
-<li class="toctree-l3"><a class="reference internal" href="#keyword-arguments">Keyword arguments</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#plasticity-phase">Plasticity Phase</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#training-phase">Training phase</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#freeze-plasticity">Freeze plasticity</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#network-output-descriptions">Network Output Descriptions</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#usage-with-openai-gym">Usage with OpenAI gym</a><ul>
+<li class="toctree-l3"><a class="reference internal" href="#cartpole-balance-problem">Cartpole balance problem</a></li>
 </ul>
 </li>
-<li class="toctree-l2"><a class="reference internal" href="#simulation">Simulation</a><ul>
-<li class="toctree-l3"><a class="reference internal" href="#plasticity-phase">Plasticity Phase</a></li>
-<li class="toctree-l3"><a class="reference internal" href="#training-phase">Training Phase</a></li>
-<li class="toctree-l3"><a class="reference internal" href="#network-output-descriptions">Network Output Descriptions</a></li>
-<li class="toctree-l3"><a class="reference internal" href="#sample-use-with-openai-gym">Sample use with OpenAI gym</a></li>
+<li class="toctree-l2"><a class="reference internal" href="#plotting-functions">Plotting functions</a><ul>
+<li class="toctree-l3"><a class="reference internal" href="#plot-weight-distribution-in-the-network">Plot weight distribution in the network</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#plot-spike-train">Plot Spike train</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#raster-plot-of-spike-train">Raster plot of Spike train</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#distribution-of-presynaptic-connections">Distribution of presynaptic connections</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#distribution-of-firing-rate-of-the-network">Distribution of firing rate of the network</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#plot-pearson-correlation-between-neurons">Plot pearson correlation between neurons</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#inter-spike-intervals">Inter spike intervals</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#linear-and-lognormal-curve-fit-of-synaptic-weights">Linear and Lognormal curve fit of Synaptic weights</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#network-plot">Network plot</a></li>
+</ul>
+</li>
+<li class="toctree-l2"><a class="reference internal" href="#statistics-and-analysis-functions">Statistics and Analysis functions</a><ul>
+<li class="toctree-l3"><a class="reference internal" href="#t-lagged-auto-correlation-between-neural-activity">t-lagged auto correlation between neural activity</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#fano-factor">Fano factor</a></li>
+<li class="toctree-l3"><a class="reference internal" href="#spike-source-entropy">Spike Source Entropy</a></li>
 </ul>
 </li>
 </ul>
@@ -193,36 +207,9 @@
             
   <div class="section" id="usage">
 <h1>Usage<a class="headerlink" href="#usage" title="Permalink to this headline">¶</a></h1>
-<div class="section" id="update-network-configuration">
-<h2>Update network configuration<a class="headerlink" href="#update-network-configuration" title="Permalink to this headline">¶</a></h2>
-<div class="section" id="configuration-file">
-<h3>Configuration file<a class="headerlink" href="#configuration-file" title="Permalink to this headline">¶</a></h3>
-<p>Navigate to <cite>home/conda/envs/ENVNAME/Lib/site-packages/sorn</cite> or if you are unsure about the directory of <cite>sorn</cite>:</p>
-<p>Run:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sorn</span>
-<span class="n">sorn</span><span class="o">.</span><span class="vm">__file__</span>
-</pre></div>
-</div>
-<p>to find the location of the sorn package:</p>
-<p>Then, update/edit arguments in <cite>configuration.ini</cite></p>
-</div>
-<div class="section" id="keyword-arguments">
-<h3>Keyword arguments<a class="headerlink" href="#keyword-arguments" title="Permalink to this headline">¶</a></h3>
-<p>Pass the arguments with valid names (listed below). This will override the default values at <cite>configuration.ini</cite>:</p>
-<p>The allowed <cite>kwargs</cite> are:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="n">kwargs_</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;ne&#39;</span><span class="p">,</span> <span class="s1">&#39;nu&#39;</span><span class="p">,</span> <span class="s1">&#39;network_type_ee&#39;</span><span class="p">,</span> <span class="s1">&#39;network_type_ei&#39;</span><span class="p">,</span> <span class="s1">&#39;network_type_ie&#39;</span><span class="p">,</span>
-           <span class="s1">&#39;lambda_ee&#39;</span><span class="p">,</span><span class="s1">&#39;lambda_ei&#39;</span><span class="p">,</span> <span class="s1">&#39;lambda_ie&#39;</span><span class="p">,</span> <span class="s1">&#39;eta_stdp&#39;</span><span class="p">,</span><span class="s1">&#39;eta_inhib&#39;</span><span class="p">,</span> <span class="s1">&#39;eta_ip&#39;</span><span class="p">,</span>
-           <span class="s1">&#39;te_max&#39;</span><span class="p">,</span> <span class="s1">&#39;ti_max&#39;</span><span class="p">,</span> <span class="s1">&#39;ti_min&#39;</span><span class="p">,</span> <span class="s1">&#39;te_min&#39;</span><span class="p">,</span> <span class="s1">&#39;mu_ip&#39;</span><span class="p">,</span><span class="s1">&#39;sigma_ip&#39;</span><span class="p">]</span>
-</pre></div>
-</div>
-</div>
-</div>
-<div class="section" id="simulation">
-<h2>Simulation<a class="headerlink" href="#simulation" title="Permalink to this headline">¶</a></h2>
 <div class="section" id="plasticity-phase">
-<h3>Plasticity Phase<a class="headerlink" href="#plasticity-phase" title="Permalink to this headline">¶</a></h3>
-<p>The default ne, nu values are overriden by passing them as kwargs insidesimulate_sorn method:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="c1"># Import</span>
+<h2>Plasticity Phase<a class="headerlink" href="#plasticity-phase" title="Permalink to this headline">¶</a></h2>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sorn</span>
 <span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Simulator</span>
 <span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
 
@@ -231,84 +218,367 @@ <h3>Plasticity Phase<a class="headerlink" href="#plasticity-phase" title="Permal
 <span class="n">time_steps</span> <span class="o">=</span> <span class="mi">200</span>
 <span class="n">inputs</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="n">num_features</span><span class="p">,</span><span class="n">time_steps</span><span class="p">)</span>
 
-<span class="c1"># To simulate the network</span>
-<span class="n">matrices_dict</span><span class="p">,</span> <span class="n">Exc_activity</span><span class="p">,</span> <span class="n">Inh_activity</span><span class="p">,</span> <span class="n">Rec_activity</span><span class="p">,</span> <span class="n">num_active_connections</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">phase</span><span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span> <span class="n">matrices</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">noise</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">time_steps</span><span class="o">=</span><span class="n">time_steps</span><span class="p">,</span> <span class="n">ne</span> <span class="o">=</span> <span class="mi">200</span><span class="p">,</span> <span class="n">nu</span><span class="o">=</span><span class="n">num_features</span><span class="p">)</span>
-
-<span class="c1"># To resume the simulation, load the matrices_dict from previous simulation</span>
-<span class="n">matrices_dict</span><span class="p">,</span> <span class="n">Exc_activity</span><span class="p">,</span> <span class="n">Inh_activity</span><span class="p">,</span> <span class="n">Rec_activity</span><span class="p">,</span> <span class="n">num_active_connections</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">phase</span><span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span> <span class="n">matrices</span><span class="o">=</span><span class="n">matrices_dict</span><span class="p">,</span> <span class="n">noise</span><span class="o">=</span> <span class="kc">True</span><span class="p">,</span> <span class="n">time_steps</span><span class="o">=</span><span class="n">time_steps</span><span class="p">,</span><span class="n">ne</span> <span class="o">=</span> <span class="mi">200</span><span class="p">,</span> <span class="n">nu</span><span class="o">=</span><span class="n">num_features</span><span class="p">)</span>
+<span class="c1"># Simulate the network with default hyperparameters under gaussian white noise</span>
+<span class="n">state_dict</span><span class="p">,</span> <span class="n">E</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">C</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">phase</span><span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span>
+                                                <span class="n">matrices</span><span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">noise</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
+                                                <span class="n">time_steps</span><span class="o">=</span><span class="n">time_steps</span><span class="p">)</span>
+</pre></div>
+</div>
+<table class="colwidths-given docutils align-default" id="id1">
+<caption><span class="caption-text">Hyperparameters of the network and default values</span><a class="headerlink" href="#id1" title="Permalink to this table">¶</a></caption>
+<colgroup>
+<col style="width: 25%" />
+<col style="width: 25%" />
+<col style="width: 50%" />
+</colgroup>
+<thead>
+<tr class="row-odd"><th class="head"><p>Keyword argument</p></th>
+<th class="head"><p>Value</p></th>
+<th class="head"><p>Description</p></th>
+</tr>
+</thead>
+<tbody>
+<tr class="row-even"><td><p>ne,</p></td>
+<td><p>200</p></td>
+<td><p>Number of Encitatory neurons in the reservoir</p></td>
+</tr>
+<tr class="row-odd"><td><p>nu</p></td>
+<td><p>10</p></td>
+<td><p>Number of Input neurons in the reservoir</p></td>
+</tr>
+<tr class="row-even"><td><p>network_type_ee</p></td>
+<td><p>“Sparse”</p></td>
+<td><p><cite>Sparse</cite> or <cite>Dense</cite> connectivity between Excitatory neurons</p></td>
+</tr>
+<tr class="row-odd"><td><p>network_type_ie</p></td>
+<td><p>“Dense”</p></td>
+<td><p><cite>Sparse</cite> or <cite>Dense</cite> connectivity from Excitatory to Inhibitory neurons</p></td>
+</tr>
+<tr class="row-even"><td><p>network_type_ei</p></td>
+<td><p>“Sparse”</p></td>
+<td><p><cite>Sparse</cite> or <cite>Dense</cite> connectivity from Inhibitory to Excitatory neurons</p></td>
+</tr>
+<tr class="row-odd"><td><p>lambda_ee</p></td>
+<td><p>20</p></td>
+<td><p>% of connections between neurons in Excitatory pool</p></td>
+</tr>
+<tr class="row-even"><td><p>lambda_ei</p></td>
+<td><p>40</p></td>
+<td><p>% of connections from Inhibitory to Excitatory neurons</p></td>
+</tr>
+<tr class="row-odd"><td><p>lambda_ie</p></td>
+<td><p>100</p></td>
+<td><p>% of connections from Excitatory to Inhibitory neurons</p></td>
+</tr>
+<tr class="row-even"><td><p>eta_stdp</p></td>
+<td><p>0.004</p></td>
+<td><p>Hebbian Learning rate for connections between excitatory neurons</p></td>
+</tr>
+<tr class="row-odd"><td><p>eta_inhib</p></td>
+<td><p>0.001</p></td>
+<td><p>Hebbian Learning rate for connections from Inhibitory to Excitatory neurons</p></td>
+</tr>
+<tr class="row-even"><td><p>eta_ip</p></td>
+<td><p>0.01</p></td>
+<td><p>Intrinsic plasticity learning rate</p></td>
+</tr>
+<tr class="row-odd"><td><p>te_max</p></td>
+<td><p>1.0</p></td>
+<td><p>Maximum excitatory neuron threshold value</p></td>
+</tr>
+<tr class="row-even"><td><p>ti_max</p></td>
+<td><p>0.5</p></td>
+<td><p>Maximum inhibitory neuron threshold value</p></td>
+</tr>
+<tr class="row-odd"><td><p>ti_min</p></td>
+<td><p>0.0</p></td>
+<td><p>Minimum inhibitory neuron threshold value</p></td>
+</tr>
+<tr class="row-even"><td><p>te_min</p></td>
+<td><p>0.0</p></td>
+<td><p>Minimum excitatory neuron threshold value</p></td>
+</tr>
+<tr class="row-odd"><td><p>mu_ip</p></td>
+<td><p>0.01</p></td>
+<td><p>Target mean firing rate of excitatory neuron</p></td>
+</tr>
+<tr class="row-even"><td><p>sigma_ip</p></td>
+<td><p>0.0</p></td>
+<td><p>Standard deviation of firing rate of excitatory neuron</p></td>
+</tr>
+</tbody>
+</table>
+<p>To override the default hyperparameters, use the <cite>kwargs</cite> as shown below:</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">state_dict</span><span class="p">,</span> <span class="n">E</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">C</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">phase</span><span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span>
+                                                <span class="n">matrices</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">noise</span><span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
+                                                <span class="n">time_steps</span><span class="o">=</span><span class="n">time_steps</span><span class="p">,</span>
+                                                <span class="n">ne</span> <span class="o">=</span> <span class="mi">200</span><span class="p">,</span> <span class="n">nu</span><span class="o">=</span><span class="n">num_features</span><span class="p">)</span>
 </pre></div>
 </div>
 </div>
 <div class="section" id="training-phase">
-<h3>Training Phase<a class="headerlink" href="#training-phase" title="Permalink to this headline">¶</a></h3>
-<p>Train the network using the matrices obtained from plasticity phase:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="c1"># Import</span>
-<span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Trainer</span>
-<span class="c1"># Sample input</span>
+<h2>Training phase<a class="headerlink" href="#training-phase" title="Permalink to this headline">¶</a></h2>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Trainer</span>
+<span class="c1"># NOTE: During training phase, input to `sorn` should have second (time) dimension set to 1. ie., input shape</span>
+<span class="c1"># should be (input_features,1).</span>
 <span class="n">inputs</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="n">num_features</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
 
 <span class="c1"># SORN network is frozen during training phase</span>
-<span class="n">matrices_dict</span><span class="p">,</span> <span class="n">Exc_activity</span><span class="p">,</span> <span class="n">Inh_activity</span><span class="p">,</span> <span class="n">Rec_activity</span><span class="p">,</span> <span class="n">num_active_connections</span> <span class="o">=</span> <span class="n">Trainer</span><span class="o">.</span><span class="n">train_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">phase</span><span class="o">=</span><span class="s1">&#39;Training&#39;</span><span class="p">,</span> <span class="n">matrices</span><span class="o">=</span><span class="n">matrices_dict</span><span class="p">,</span><span class="n">nu</span><span class="o">=</span><span class="n">num_features</span><span class="p">,</span> <span class="n">time_steps</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
+<span class="n">state_dict</span><span class="p">,</span> <span class="n">E</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">C</span> <span class="o">=</span> <span class="n">Trainer</span><span class="o">.</span><span class="n">train_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">phase</span><span class="o">=</span><span class="s1">&#39;training&#39;</span><span class="p">,</span>
+                                            <span class="n">matrices</span><span class="o">=</span><span class="n">state_dict</span><span class="p">,</span>
+                                            <span class="n">nu</span><span class="o">=</span><span class="n">num_features</span><span class="p">,</span> <span class="n">time_steps</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
 </pre></div>
 </div>
 </div>
+<div class="section" id="freeze-plasticity">
+<h2>Freeze plasticity<a class="headerlink" href="#freeze-plasticity" title="Permalink to this headline">¶</a></h2>
+<p>To turn off any plasticity mechanisms during <cite>simulation</cite> or <cite>training</cite> phase, use <cite>freeze</cite> argument.
+For example to stop intrinsic plasticity during simulation phase</p>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Sample input</span>
+<span class="n">num_features</span> <span class="o">=</span> <span class="mi">10</span>
+<span class="n">time_steps</span> <span class="o">=</span> <span class="mi">200</span>
+<span class="n">inputs</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="n">num_features</span><span class="p">,</span><span class="n">time_steps</span><span class="p">)</span>
+
+<span class="n">state_dict</span><span class="p">,</span> <span class="n">E</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">C</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">inputs</span><span class="p">,</span> <span class="n">phase</span><span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span>
+                                                <span class="n">matrices</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">noise</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
+                                                <span class="n">time_steps</span><span class="o">=</span><span class="n">time_steps</span><span class="p">,</span> <span class="n">ne</span> <span class="o">=</span> <span class="mi">200</span><span class="p">,</span>
+                                                <span class="n">nu</span><span class="o">=</span><span class="n">num_features</span><span class="p">,</span> <span class="n">freeze</span><span class="o">=</span><span class="p">[</span><span class="s1">&#39;ip&#39;</span><span class="p">])</span>
+</pre></div>
+</div>
+<p>The other options are,</p>
+<blockquote>
+<div><p><cite>stdp</cite> - Spike Timing Dependent Plasticity</p>
+<p><cite>ss</cite> - Synaptic Scaling</p>
+<p><cite>sp</cite> - Structural Plasticity</p>
+<p><cite>istdp</cite> - Inhibitory Spike Timing Dependent Plasticity</p>
+</div></blockquote>
+<p>Note: If you pass all above options to <cite>freeze</cite>, then the network will behave as Liquid State Machine(LSM)</p>
+</div>
 <div class="section" id="network-output-descriptions">
-<h3>Network Output Descriptions<a class="headerlink" href="#network-output-descriptions" title="Permalink to this headline">¶</a></h3>
-<p>During plasticity and training phase, SORN returns a dictionary of below matrices for analysis:</p>
+<h2>Network Output Descriptions<a class="headerlink" href="#network-output-descriptions" title="Permalink to this headline">¶</a></h2>
+<blockquote>
+<div><p><cite>state_dict</cite>  - Dictionary of connection weights (<cite>Wee</cite>,`Wei`,`Wie`) ,</p>
 <blockquote>
-<div><p><cite>matrices_dict</cite> - Dictionary of connection weights (‘Wee’,’Wei’,’Wie’) , Excitatory network activity (‘X’), Inhibitory network activities(‘Y’), Threshold values (‘Te’,’Ti’)</p>
-<p><cite>Exc_activity</cite> - Collection of Excitatory network activity of entire simulation period</p>
-<p><cite>Inh_activity</cite> - Collection of Inhibitory network activity of entire simulation period</p>
-<p><cite>Rec_activity</cite> - Collection of Recurrent network activity of entire simulation period</p>
-<p><cite>num_active_connections</cite> - List of number of active connections in the Excitatory pool at each time step</p>
+<div><p>Excitatory network activity (<cite>X</cite>),</p>
+<p>Inhibitory network activities(<cite>Y</cite>),</p>
+<p>Threshold values (<cite>Te</cite>,`Ti`)</p>
+</div></blockquote>
+<p><cite>E</cite> - Collection of Excitatory network activity of entire simulation period</p>
+<p><cite>I</cite> - Collection of Inhibitory network activity of entire simulation period</p>
+<p><cite>R</cite> - Collection of Recurrent network activity of entire simulation period</p>
+<p><cite>C</cite> - List of number of active connections in the Excitatory pool at each time step</p>
 </div></blockquote>
 </div>
-<div class="section" id="sample-use-with-openai-gym">
-<h3>Sample use with OpenAI gym<a class="headerlink" href="#sample-use-with-openai-gym" title="Permalink to this headline">¶</a></h3>
-<p><cite>Cartpole balance problem without changing the default network parameters</cite>:</p>
-<div class="highlight-py notranslate"><div class="highlight"><pre><span></span><span class="c1"># Imports</span>
-
-<span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Simulator</span><span class="p">,</span> <span class="n">Trainer</span>
+<div class="section" id="usage-with-openai-gym">
+<h2>Usage with OpenAI gym<a class="headerlink" href="#usage-with-openai-gym" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="cartpole-balance-problem">
+<h3>Cartpole balance problem<a class="headerlink" href="#cartpole-balance-problem" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Simulator</span><span class="p">,</span> <span class="n">Trainer</span>
 <span class="kn">import</span> <span class="nn">gym</span>
 
-<span class="c1"># Load the simulated network matrices</span>
-<span class="c1"># Note these matrices are obtained after the network achieved convergence under random inputs and noise</span>
+<span class="c1"># Hyperparameters</span>
+<span class="n">NUM_EPISODES</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="mf">2e6</span><span class="p">)</span>
+<span class="n">NUM_PLASTICITY_EPISODES</span> <span class="o">=</span> <span class="mi">20</span>
 
-<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">&#39;simulation_matrices.pkl&#39;</span><span class="p">,</span><span class="s1">&#39;rb&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
-    <span class="n">sim_matrices</span><span class="p">,</span><span class="n">excit_states</span><span class="p">,</span><span class="n">inhib_states</span><span class="p">,</span><span class="n">recur_states</span><span class="p">,</span><span class="n">num_reservoir_conn</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
+<span class="n">LEARNING_RATE</span> <span class="o">=</span> <span class="mf">0.0001</span> <span class="c1"># Gradient ascent learning rate</span>
+<span class="n">GAMMA</span> <span class="o">=</span> <span class="mf">0.99</span> <span class="c1"># Discounting factor for the Rewards</span>
 
-<span class="c1"># Training parameters</span>
+<span class="c1"># Open AI gym; Cartpole Environment</span>
+<span class="n">env</span> <span class="o">=</span> <span class="n">gym</span><span class="o">.</span><span class="n">make</span><span class="p">(</span><span class="s1">&#39;CartPole-v0&#39;</span><span class="p">)</span>
+<span class="n">action_space</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">action_space</span><span class="o">.</span><span class="n">n</span>
 
-<span class="n">NUM_EPISODES</span> <span class="o">=</span> <span class="mf">2e6</span>
-<span class="n">NUM_PLASTICITY_EPISODES</span> <span class="o">=</span> <span class="mi">20000</span>
+<span class="c1"># SORN network parameters</span>
+<span class="n">ne</span> <span class="o">=</span> <span class="mi">50</span>
+<span class="n">nu</span> <span class="o">=</span> <span class="mi">4</span>
 
-<span class="n">env</span> <span class="o">=</span> <span class="n">gym</span><span class="o">.</span><span class="n">make</span><span class="p">(</span><span class="s1">&#39;CartPole-v0&#39;</span><span class="p">)</span>
+<span class="c1"># Init SORN using `Simulator` under random input</span>
+<span class="n">state_dict</span><span class="p">,</span> <span class="n">E</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">C</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span>
+                                                <span class="n">phase</span> <span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span>
+                                                <span class="n">time_steps</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
+                                                <span class="n">noise</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
+                                                <span class="n">ne</span> <span class="o">=</span> <span class="n">ne</span><span class="p">,</span> <span class="n">nu</span><span class="o">=</span><span class="n">nu</span><span class="p">)</span>
+
+<span class="n">w</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">rand</span><span class="p">(</span><span class="n">ne</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="c1"># Output layer weights</span>
+
+<span class="c1"># Implementation of softmax policy</span>
+<span class="k">def</span> <span class="nf">policy</span><span class="p">(</span><span class="n">state</span><span class="p">,</span><span class="n">w</span><span class="p">):</span>
+    <span class="n">z</span> <span class="o">=</span> <span class="n">state</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">w</span><span class="p">)</span>
+    <span class="n">exp</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
+    <span class="k">return</span> <span class="n">exp</span><span class="o">/</span><span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">exp</span><span class="p">)</span>
+
+<span class="c1"># Vectorized softmax Jacobian</span>
+<span class="k">def</span> <span class="nf">softmax_grad</span><span class="p">(</span><span class="n">softmax</span><span class="p">):</span>
+    <span class="n">s</span> <span class="o">=</span> <span class="n">softmax</span><span class="o">.</span><span class="n">reshape</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span>
+    <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">diagflat</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">s</span><span class="o">.</span><span class="n">T</span><span class="p">)</span>
 
 <span class="k">for</span> <span class="n">EPISODE</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">NUM_EPISODES</span><span class="p">):</span>
 
-    <span class="c1"># Environment observation</span>
-    <span class="n">state</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">reset</span><span class="p">()[</span><span class="kc">None</span><span class="p">,:]</span>
+    <span class="c1"># Environment observation;</span>
+    <span class="c1"># NOTE: Input to sorn should have time dimension. ie., input shape should be (input_features,time_steps)</span>
+    <span class="n">state</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">reset</span><span class="p">()[:,</span> <span class="kc">None</span><span class="p">]</span> <span class="c1"># (4,) --&gt; (4,1)</span>
+
+    <span class="n">grads</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Episode log policy gradients</span>
+    <span class="n">rewards</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># Episode rewards</span>
+
+    <span class="c1"># Keep track of total score</span>
+    <span class="n">score</span> <span class="o">=</span> <span class="mi">0</span>
 
     <span class="c1"># Play the episode</span>
     <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
-    <span class="k">if</span> <span class="n">EPISODE</span> <span class="o">&lt;</span> <span class="n">NUM_PLASTICITY_EPISODE</span><span class="p">:</span>
+
+    <span class="c1"># env.render() # Uncomment to see your model train in real time (slow down training progress)</span>
+    <span class="k">if</span> <span class="n">EPISODE</span> <span class="o">&lt;</span> <span class="n">NUM_PLASTICITY_EPISODES</span><span class="p">:</span>
 
         <span class="c1"># Plasticity phase</span>
-        <span class="n">sim_matrices</span><span class="p">,</span><span class="n">excit_states</span><span class="p">,</span><span class="n">inhib_states</span><span class="p">,</span><span class="n">recur_states</span><span class="p">,</span><span class="n">num_reservoir_conn</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">state</span><span class="p">,</span> <span class="n">phase</span> <span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span> <span class="n">matrices</span> <span class="o">=</span> <span class="n">sim_matrices</span><span class="p">,</span> <span class="n">noise</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
+        <span class="n">state_dict</span><span class="p">,</span> <span class="n">E</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">C</span> <span class="o">=</span> <span class="n">Simulator</span><span class="o">.</span><span class="n">simulate_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">state</span><span class="p">,</span> <span class="n">phase</span> <span class="o">=</span><span class="s1">&#39;plasticity&#39;</span><span class="p">,</span>
+                                                        <span class="n">matrices</span> <span class="o">=</span> <span class="n">state_dict</span><span class="p">,</span> <span class="n">time_steps</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
+                                                        <span class="n">ne</span> <span class="o">=</span> <span class="n">ne</span><span class="p">,</span> <span class="n">nu</span><span class="o">=</span><span class="n">nu</span><span class="p">,</span>
+                                                        <span class="n">noise</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
 
     <span class="k">else</span><span class="p">:</span>
         <span class="c1"># Training phase with frozen reservoir connectivity</span>
-        <span class="n">sim_matrices</span><span class="p">,</span><span class="n">excit_states</span><span class="p">,</span><span class="n">inhib_states</span><span class="p">,</span><span class="n">recur_states</span><span class="p">,</span><span class="n">num_reservoir_conn</span> <span class="o">=</span> <span class="n">Trainer</span><span class="o">.</span><span class="n">train_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">state</span><span class="p">,</span> <span class="n">phase</span> <span class="o">=</span> <span class="s1">&#39;training&#39;</span><span class="p">,</span> <span class="n">matrices</span> <span class="o">=</span> <span class="n">sim_matrices</span><span class="p">,</span> <span class="n">noise</span><span class="o">=</span> <span class="kc">False</span><span class="p">)</span>
+        <span class="n">state_dict</span><span class="p">,</span> <span class="n">E</span><span class="p">,</span> <span class="n">I</span><span class="p">,</span> <span class="n">R</span><span class="p">,</span> <span class="n">C</span> <span class="o">=</span> <span class="n">Trainer</span><span class="o">.</span><span class="n">train_sorn</span><span class="p">(</span><span class="n">inputs</span> <span class="o">=</span> <span class="n">state</span><span class="p">,</span> <span class="n">phase</span> <span class="o">=</span> <span class="s1">&#39;training&#39;</span><span class="p">,</span>
+                                                <span class="n">matrices</span> <span class="o">=</span> <span class="n">state_dict</span><span class="p">,</span> <span class="n">time_steps</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
+                                                <span class="n">ne</span> <span class="o">=</span> <span class="n">ne</span><span class="p">,</span> <span class="n">nu</span><span class="o">=</span><span class="n">nu</span><span class="p">,</span>
+                                                <span class="n">noise</span><span class="o">=</span> <span class="kc">False</span><span class="p">)</span>
 
-    <span class="c1"># Feed excit_states as input states to your RL algorithm, below goes for simple policy gradient algorithm</span>
+    <span class="c1"># Feed E as input states to your RL algorithm, below goes for simple policy gradient algorithm</span>
     <span class="c1"># Sample policy w.r.t excitatory states and take action in the environment</span>
-
-    <span class="n">probs</span> <span class="o">=</span> <span class="n">policy</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">excit_states</span><span class="p">),</span><span class="n">output_layer_weights</span><span class="p">))</span>
-    <span class="n">action</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">action_space</span><span class="p">,</span><span class="n">probs</span><span class="p">)</span>
+    <span class="n">probs</span> <span class="o">=</span> <span class="n">policy</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">E</span><span class="p">),</span><span class="n">w</span><span class="p">)</span>
+    <span class="n">action</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">action_space</span><span class="p">,</span><span class="n">p</span><span class="o">=</span><span class="n">probs</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
     <span class="n">state</span><span class="p">,</span><span class="n">reward</span><span class="p">,</span><span class="n">done</span><span class="p">,</span><span class="n">_</span> <span class="o">=</span> <span class="n">env</span><span class="o">.</span><span class="n">step</span><span class="p">(</span><span class="n">action</span><span class="p">)</span>
+    <span class="n">state</span> <span class="o">=</span> <span class="n">state</span><span class="p">[:,</span><span class="kc">None</span><span class="p">]</span>
+
+    <span class="c1"># COMPUTE GRADIENTS BASED ON YOUR OBJECTIVE FUNCTION;</span>
+    <span class="c1"># Sample computation of policy gradient objective function</span>
+    <span class="n">dsoftmax</span> <span class="o">=</span> <span class="n">softmax_grad</span><span class="p">(</span><span class="n">probs</span><span class="p">)[</span><span class="n">action</span><span class="p">,:]</span>
+    <span class="n">dlog</span> <span class="o">=</span> <span class="n">dsoftmax</span> <span class="o">/</span> <span class="n">probs</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="n">action</span><span class="p">]</span>
+    <span class="n">grad</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">E</span><span class="p">)</span><span class="o">.</span><span class="n">T</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">dlog</span><span class="p">[</span><span class="kc">None</span><span class="p">,:])</span>
+    <span class="n">grads</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">grad</span><span class="p">)</span>
+    <span class="n">rewards</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">reward</span><span class="p">)</span>
+    <span class="n">score</span><span class="o">+=</span><span class="n">reward</span>
 
     <span class="k">if</span> <span class="n">done</span><span class="p">:</span>
         <span class="k">break</span>
+
+    <span class="c1"># OPTIMIZE OUTPUT LAYER WEIGHTS `w` BASED ON YOUR OPTIMIZATION METHOD</span>
+
+    <span class="c1"># Below is a sample of weight update based on gradient</span>
+    <span class="c1"># ascent(maximize cumulative reward) method for temporal difference learning</span>
+    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">grads</span><span class="p">)):</span>
+
+        <span class="c1"># Loop through everything that happened in the episode and update towards</span>
+        <span class="c1"># the log policy gradient times future reward</span>
+        <span class="n">w</span> <span class="o">+=</span> <span class="n">LEARNING_RATE</span> <span class="o">*</span> <span class="n">grads</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*</span> <span class="nb">sum</span><span class="p">([</span> <span class="n">r</span> <span class="o">*</span> <span class="p">(</span><span class="n">GAMMA</span> <span class="o">**</span> <span class="n">r</span><span class="p">)</span> <span class="k">for</span> <span class="n">t</span><span class="p">,</span><span class="n">r</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">rewards</span><span class="p">[</span><span class="n">i</span><span class="p">:])])</span>
+
+    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Episode </span><span class="si">%s</span><span class="s1">  Score </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">EPISODE</span><span class="p">),</span><span class="nb">str</span><span class="p">(</span><span class="n">score</span><span class="p">)))</span>
+</pre></div>
+</div>
+<p>There are several neural data analysis and visualization methods inbuilt with <cite>sorn</cite> package.
+Sample call for few plotting and statistical methods are shown below</p>
+</div>
+</div>
+<div class="section" id="plotting-functions">
+<h2>Plotting functions<a class="headerlink" href="#plotting-functions" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="plot-weight-distribution-in-the-network">
+<h3>Plot weight distribution in the network<a class="headerlink" href="#plot-weight-distribution-in-the-network" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Plotter</span>
+<span class="c1"># For example, the network has 200 neurons in the excitatory pool.</span>
+<span class="n">Wee</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span><span class="mi">200</span><span class="p">)</span> <span class="c1"># Note that generally Wee is sparse</span>
+<span class="n">Wee</span><span class="o">=</span><span class="n">Wee</span><span class="o">/</span><span class="n">Wee</span><span class="o">.</span><span class="n">max</span><span class="p">()</span> <span class="c1"># state_dict[&#39;Wee&#39;] returned by the SORN is already normalized</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">weight_distribution</span><span class="p">(</span><span class="n">weights</span><span class="o">=</span> <span class="n">Wee</span><span class="p">,</span> <span class="n">bin_size</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span> <span class="n">savefig</span> <span class="o">=</span> <span class="kc">True</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/weight_distribution.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/weight_distribution.png" />
+</div>
+<div class="section" id="plot-spike-train">
+<h3>Plot Spike train<a class="headerlink" href="#plot-spike-train" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">E</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">size</span><span class="o">=</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span><span class="mi">1000</span><span class="p">))</span> <span class="c1"># For example, activity of 200 excitatory neurons in 1000 time steps</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">scatter_plot</span><span class="p">(</span><span class="n">spike_train</span> <span class="o">=</span> <span class="n">E</span><span class="p">,</span> <span class="n">savefig</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/ScatterSpikeTrain.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/ScatterSpikeTrain.png" />
+</div>
+<div class="section" id="raster-plot-of-spike-train">
+<h3>Raster plot of Spike train<a class="headerlink" href="#raster-plot-of-spike-train" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Raster plot of activity of only first 10 neurons in the excitatory pool</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">raster_plot</span><span class="p">(</span><span class="n">spike_train</span> <span class="o">=</span> <span class="n">E</span><span class="p">[:,</span><span class="mi">0</span><span class="p">:</span><span class="mi">10</span><span class="p">],</span> <span class="n">savefig</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/RasterSpikeTrain.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/RasterSpikeTrain.png" />
+</div>
+<div class="section" id="distribution-of-presynaptic-connections">
+<h3>Distribution of presynaptic connections<a class="headerlink" href="#distribution-of-presynaptic-connections" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Histogram of number of presynaptic connections per neuron in the excitatory pool</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">hist_incoming_conn</span><span class="p">(</span><span class="n">weights</span><span class="o">=</span><span class="n">Wee</span><span class="p">,</span> <span class="n">bin_size</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">histtype</span><span class="o">=</span><span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="n">savefig</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_incoming_conn.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_incoming_conn.png" />
+</div>
+<div class="section" id="distribution-of-firing-rate-of-the-network">
+<h3>Distribution of firing rate of the network<a class="headerlink" href="#distribution-of-firing-rate-of-the-network" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="n">Plotter</span><span class="o">.</span><span class="n">hist_firing_rate_network</span><span class="p">(</span><span class="n">E</span><span class="p">,</span> <span class="n">bin_size</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">savefig</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_firing_rate_network.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_firing_rate_network.png" />
+</div>
+<div class="section" id="plot-pearson-correlation-between-neurons">
+<h3>Plot pearson correlation between neurons<a class="headerlink" href="#plot-pearson-correlation-between-neurons" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Statistics</span>
+<span class="n">avg_corr_coeff</span><span class="p">,</span><span class="n">_</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">avg_corr_coeff</span><span class="p">(</span><span class="n">E</span><span class="p">)</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">correlation</span><span class="p">(</span><span class="n">avg_corr_coeff</span><span class="p">,</span><span class="n">savefig</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/correlation_between_neurons.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/correlation_between_neurons.png" />
+</div>
+<div class="section" id="inter-spike-intervals">
+<h3>Inter spike intervals<a class="headerlink" href="#inter-spike-intervals" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Inter spike intervals with exponential curve fit for neuron 1 in the Excitatory pool</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">isi_exponential_fit</span><span class="p">(</span><span class="n">E</span><span class="p">,</span><span class="n">neuron</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span><span class="n">bin_size</span><span class="o">=</span><span class="mi">10</span><span class="p">,</span> <span class="n">savefig</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/isi_exponential_fit.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/isi_exponential_fit.png" />
+</div>
+<div class="section" id="linear-and-lognormal-curve-fit-of-synaptic-weights">
+<h3>Linear and Lognormal curve fit of Synaptic weights<a class="headerlink" href="#linear-and-lognormal-curve-fit-of-synaptic-weights" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Distribution of connection weights in linear and lognormal scale</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">linear_lognormal_fit</span><span class="p">(</span><span class="n">weights</span><span class="o">=</span><span class="n">Wee</span><span class="p">,</span><span class="n">num_points</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">savefig</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
+
+<span class="o">..</span> <span class="n">image</span><span class="p">::</span> <span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">raw</span><span class="o">.</span><span class="n">githubusercontent</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">Saran</span><span class="o">-</span><span class="n">nns</span><span class="o">/</span><span class="n">sorn</span><span class="o">/</span><span class="n">revision</span><span class="o">/</span><span class="n">imgs</span><span class="o">/</span><span class="n">LinearLognormalFit</span><span class="o">.</span><span class="n">png</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="network-plot">
+<h3>Network plot<a class="headerlink" href="#network-plot" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Draw network connectivity using the pearson correlation function between neurons in the excitatory pool</span>
+<span class="n">Plotter</span><span class="o">.</span><span class="n">plot_network</span><span class="p">(</span><span class="n">avg_corr_coeff</span><span class="p">,</span><span class="n">corr_thres</span><span class="o">=</span><span class="mf">0.01</span><span class="p">,</span><span class="n">fig_name</span><span class="o">=</span><span class="s1">&#39;network.png&#39;</span><span class="p">)</span>
+</pre></div>
+</div>
+<img alt="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/network.png" src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/network.png" />
+</div>
+</div>
+<div class="section" id="statistics-and-analysis-functions">
+<h2>Statistics and Analysis functions<a class="headerlink" href="#statistics-and-analysis-functions" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="t-lagged-auto-correlation-between-neural-activity">
+<h3>t-lagged auto correlation between neural activity<a class="headerlink" href="#t-lagged-auto-correlation-between-neural-activity" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sorn</span> <span class="kn">import</span> <span class="n">Statistics</span>
+<span class="n">pearson_corr_matrix</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">autocorr</span><span class="p">(</span><span class="n">firing_rates</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">6</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">7</span><span class="p">],</span> <span class="n">t</span><span class="o">=</span> <span class="mi">2</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="fano-factor">
+<h3>Fano factor<a class="headerlink" href="#fano-factor" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># To verify poissonian process in spike generation of neuron 10</span>
+<span class="n">mean_firing_rate</span><span class="p">,</span> <span class="n">variance_firing_rate</span><span class="p">,</span> <span class="n">fano_factor</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">fanofactor</span><span class="p">(</span><span class="n">spike_train</span><span class="o">=</span> <span class="n">E</span><span class="p">,</span>
+                                                                        <span class="n">neuron</span> <span class="o">=</span> <span class="mi">10</span><span class="p">,</span>
+                                                                        <span class="n">window_size</span> <span class="o">=</span> <span class="mi">10</span><span class="p">)</span>
+</pre></div>
+</div>
+</div>
+<div class="section" id="spike-source-entropy">
+<h3>Spike Source Entropy<a class="headerlink" href="#spike-source-entropy" title="Permalink to this headline">¶</a></h3>
+<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="c1"># Measure the uncertainty about the origin of spike from the network using entropy</span>
+<span class="n">sse</span> <span class="o">=</span> <span class="n">Statistics</span><span class="o">.</span><span class="n">spike_source_entropy</span><span class="p">(</span><span class="n">spike_train</span><span class="o">=</span> <span class="n">E</span><span class="p">,</span> <span class="n">num_neurons</span><span class="o">=</span><span class="mi">200</span><span class="p">)</span>
 </pre></div>
 </div>
 </div>
diff --git a/docs/source/installation.rst b/docs/source/installation.rst
index 4056917..b1d5bbc 100644
--- a/docs/source/installation.rst
+++ b/docs/source/installation.rst
@@ -1,19 +1,17 @@
 Installation
 ============
 
-Install using pip::
+Install using `pip`
 
-   pip install sorn
-
-or:
+.. code-block:: python
 
-using conda::
+   pip install sorn
 
-    conda install -c conda-forge sorn
+or
 
-or:
+To install the latest version from the development branch
 
-The library is still in alpha stage, so you may want to install the latest version from the development branch::
+.. code-block:: python
 
     pip install git+https://github.com/Saran-nns/sorn
 
@@ -23,7 +21,9 @@ Dependencies
 
 SORN supports Python 3.5+ ONLY. For older Python versions please use the official Python client
 
-To install all optional dependencies run::
+To install all optional dependencies run
+
+.. code-block:: python
 
-  pip install 'sorn[all]'
+    pip install 'sorn[all]'
 
diff --git a/docs/source/usage.rst b/docs/source/usage.rst
index 6f6bf9b..5eec799 100644
--- a/docs/source/usage.rst
+++ b/docs/source/usage.rst
@@ -1,123 +1,385 @@
 Usage
 =====
 
-Update network configuration
-----------------------------
-
-Configuration file
-^^^^^^^^^^^^^^^^^^
-Navigate to `home/conda/envs/ENVNAME/Lib/site-packages/sorn` or if you are unsure about the directory of `sorn`:
+Plasticity Phase
+----------------
 
-Run::
+.. code-block:: python
 
     import sorn
-    sorn.__file__
+    from sorn import Simulator
+    import numpy as np
 
-to find the location of the sorn package:
+    # Sample input
+    num_features = 10
+    time_steps = 200
+    inputs = np.random.rand(num_features,time_steps)
 
-Then, update/edit arguments in `configuration.ini`
+    # Simulate the network with default hyperparameters under gaussian white noise
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                    matrices= None, noise = True,
+                                                    time_steps=time_steps)
+
+.. list-table:: Hyperparameters of the network and default values
+   :widths: 25 25 50
+   :header-rows: 1
+
+   * - Keyword argument
+     - Value
+     - Description
+   * - ne,
+     - 200
+     - Number of Encitatory neurons in the reservoir
+   * - nu
+     - 10
+     - Number of Input neurons in the reservoir
+   * - network_type_ee
+     - "Sparse"
+     - `Sparse` or `Dense` connectivity between Excitatory neurons
+   * - network_type_ie
+     - "Dense"
+     - `Sparse` or `Dense` connectivity from Excitatory to Inhibitory neurons
+   * - network_type_ei
+     - "Sparse"
+     - `Sparse` or `Dense` connectivity from Inhibitory to Excitatory neurons
+   * - lambda_ee
+     - 20
+     - % of connections between neurons in Excitatory pool
+   * - lambda_ei
+     - 40
+     - % of connections from Inhibitory to Excitatory neurons
+   * - lambda_ie
+     - 100
+     - % of connections from Excitatory to Inhibitory neurons
+   * - eta_stdp
+     - 0.004
+     - Hebbian Learning rate for connections between excitatory neurons
+   * - eta_inhib
+     - 0.001
+     - Hebbian Learning rate for connections from Inhibitory to Excitatory neurons
+   * - eta_ip
+     - 0.01
+     - Intrinsic plasticity learning rate
+   * - te_max
+     - 1.0
+     - Maximum excitatory neuron threshold value
+   * - ti_max
+     - 0.5
+     - Maximum inhibitory neuron threshold value
+   * - ti_min
+     - 0.0
+     - Minimum inhibitory neuron threshold value
+   * - te_min
+     - 0.0
+     - Minimum excitatory neuron threshold value
+   * - mu_ip
+     - 0.01
+     - Target mean firing rate of excitatory neuron
+   * - sigma_ip
+     - 0.0
+     - Standard deviation of firing rate of excitatory neuron
+
+To override the default hyperparameters, use the `kwargs` as shown below:
+
+.. code-block:: python
+
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                    matrices=None, noise= True,
+                                                    time_steps=time_steps,
+                                                    ne = 200, nu=num_features)
+
+Training phase
+--------------
+
+.. code-block:: python
 
-Keyword arguments 
-^^^^^^^^^^^^^^^^^
-Pass the arguments with valid names (listed below). This will override the default values at `configuration.ini`: 
+    from sorn import Trainer
+    # NOTE: During training phase, input to `sorn` should have second (time) dimension set to 1. ie., input shape
+    # should be (input_features,1).
+    inputs = np.random.rand(num_features,1)
 
-The allowed `kwargs` are::
+    # SORN network is frozen during training phase
+    state_dict, E, I, R, C = Trainer.train_sorn(inputs = inputs, phase='training',
+                                                matrices=state_dict,
+                                                nu=num_features, time_steps=1)
 
-    kwargs_ = ['ne', 'nu', 'network_type_ee', 'network_type_ei', 'network_type_ie', 
-               'lambda_ee','lambda_ei', 'lambda_ie', 'eta_stdp','eta_inhib', 'eta_ip', 
-               'te_max', 'ti_max', 'ti_min', 'te_min', 'mu_ip','sigma_ip']
+Freeze plasticity
+-----------------
 
-Simulation
-----------
-Plasticity Phase
-^^^^^^^^^^^^^^^^
-The default ne, nu values are overriden by passing them as kwargs insidesimulate_sorn method::
+To turn off any plasticity mechanisms during `simulation` or `training` phase, use `freeze` argument.
+For example to stop intrinsic plasticity during simulation phase
 
-    # Import 
-    from sorn import Simulator
-    import numpy as np
+.. code-block:: python
 
-    # Sample input 
+    # Sample input
     num_features = 10
     time_steps = 200
     inputs = np.random.rand(num_features,time_steps)
 
-    # To simulate the network
-    matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, ne = 200, nu=num_features)
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                    matrices=None, noise = True,
+                                                    time_steps=time_steps, ne = 200,
+                                                    nu=num_features, freeze=['ip'])
 
-    # To resume the simulation, load the matrices_dict from previous simulation
-    matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=matrices_dict, noise= True, time_steps=time_steps,ne = 200, nu=num_features)
+The other options are,
 
-Training Phase
-^^^^^^^^^^^^^^
-Train the network using the matrices obtained from plasticity phase::
+    `stdp` - Spike Timing Dependent Plasticity
 
-    # Import
-    from sorn import Trainer
-    # Sample input
-    inputs = np.random.rand(num_features,1) 
+    `ss` - Synaptic Scaling
 
-    # SORN network is frozen during training phase
-    matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Trainer.train_sorn(inputs = inputs, phase='Training', matrices=matrices_dict,nu=num_features, time_steps=1)
+    `sp` - Structural Plasticity
+
+    `istdp` - Inhibitory Spike Timing Dependent Plasticity
+
+Note: If you pass all above options to `freeze`, then the network will behave as Liquid State Machine(LSM)
 
 Network Output Descriptions
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-During plasticity and training phase, SORN returns a dictionary of below matrices for analysis:
+---------------------------
+
+    `state_dict`  - Dictionary of connection weights (`Wee`,`Wei`,`Wie`) ,
 
-    `matrices_dict` - Dictionary of connection weights ('Wee','Wei','Wie') , Excitatory network activity ('X'), Inhibitory network activities('Y'), Threshold values ('Te','Ti')
+                    Excitatory network activity (`X`),
 
-    `Exc_activity` - Collection of Excitatory network activity of entire simulation period
+                    Inhibitory network activities(`Y`),
 
-    `Inh_activity` - Collection of Inhibitory network activity of entire simulation period
+                    Threshold values (`Te`,`Ti`)
 
-    `Rec_activity` - Collection of Recurrent network activity of entire simulation period
+    `E` - Collection of Excitatory network activity of entire simulation period
 
-    `num_active_connections` - List of number of active connections in the Excitatory pool at each time step
+    `I` - Collection of Inhibitory network activity of entire simulation period
 
-Sample use with OpenAI gym
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-`Cartpole balance problem without changing the default network parameters`::
+    `R` - Collection of Recurrent network activity of entire simulation period
 
-    # Imports
+    `C` - List of number of active connections in the Excitatory pool at each time step
+
+Usage with OpenAI gym
+---------------------
+
+Cartpole balance problem
+^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
 
     from sorn import Simulator, Trainer
     import gym
 
-    # Load the simulated network matrices
-    # Note these matrices are obtained after the network achieved convergence under random inputs and noise
+    # Hyperparameters
+    NUM_EPISODES = int(2e6)
+    NUM_PLASTICITY_EPISODES = 20
+
+    LEARNING_RATE = 0.0001 # Gradient ascent learning rate
+    GAMMA = 0.99 # Discounting factor for the Rewards
 
-    with open('simulation_matrices.pkl','rb') as f:  
-        sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = pickle.load(f)
+    # Open AI gym; Cartpole Environment
+    env = gym.make('CartPole-v0')
+    action_space = env.action_space.n
 
-    # Training parameters
+    # SORN network parameters
+    ne = 50
+    nu = 4
 
-    NUM_EPISODES = 2e6
-    NUM_PLASTICITY_EPISODES = 20000
+    # Init SORN using `Simulator` under random input
+    state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = np.random.randn(4,1),
+                                                    phase ='plasticity',
+                                                    time_steps = 1,
+                                                    noise=False,
+                                                    ne = ne, nu=nu)
 
-    env = gym.make('CartPole-v0')
+    w = np.random.rand(ne, 2) # Output layer weights
+
+    # Implementation of softmax policy
+    def policy(state,w):
+        z = state.dot(w)
+        exp = np.exp(z)
+        return exp/np.sum(exp)
+
+    # Vectorized softmax Jacobian
+    def softmax_grad(softmax):
+        s = softmax.reshape(-1,1)
+        return np.diagflat(s) - np.dot(s, s.T)
 
     for EPISODE in range(NUM_EPISODES):
-        
-        # Environment observation
-        state = env.reset()[None,:]
-        
+
+        # Environment observation;
+        # NOTE: Input to sorn should have time dimension. ie., input shape should be (input_features,time_steps)
+        state = env.reset()[:, None] # (4,) --> (4,1)
+
+        grads = [] # Episode log policy gradients
+        rewards = [] # Episode rewards
+
+        # Keep track of total score
+        score = 0
+
         # Play the episode
         while True:
-        if EPISODE < NUM_PLASTICITY_EPISODE:
-        
+
+        # env.render() # Uncomment to see your model train in real time (slow down training progress)
+        if EPISODE < NUM_PLASTICITY_EPISODES:
+
             # Plasticity phase
-            sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = Simulator.simulate_sorn(inputs = state, phase ='plasticity', matrices = sim_matrices, noise=False)
+            state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = state, phase ='plasticity',
+                                                            matrices = state_dict, time_steps = 1,
+                                                            ne = ne, nu=nu,
+                                                            noise=False)
 
         else:
             # Training phase with frozen reservoir connectivity
-            sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = Trainer.train_sorn(inputs = state, phase = 'training', matrices = sim_matrices, noise= False)
-        
-        # Feed excit_states as input states to your RL algorithm, below goes for simple policy gradient algorithm
+            state_dict, E, I, R, C = Trainer.train_sorn(inputs = state, phase = 'training',
+                                                    matrices = state_dict, time_steps = 1,
+                                                    ne = ne, nu=nu,
+                                                    noise= False)
+
+        # Feed E as input states to your RL algorithm, below goes for simple policy gradient algorithm
         # Sample policy w.r.t excitatory states and take action in the environment
-        
-        probs = policy(np.asarray(excit_states),output_layer_weights))
-        action = np.random.choice(action_space,probs)
-        state,reward,done,_ = env.step(action) 
-        
+        probs = policy(np.asarray(E),w)
+        action = np.random.choice(action_space,p=probs[0])
+        state,reward,done,_ = env.step(action)
+        state = state[:,None]
+
+        # COMPUTE GRADIENTS BASED ON YOUR OBJECTIVE FUNCTION;
+        # Sample computation of policy gradient objective function
+        dsoftmax = softmax_grad(probs)[action,:]
+        dlog = dsoftmax / probs[0,action]
+        grad = np.asarray(E).T.dot(dlog[None,:])
+        grads.append(grad)
+        rewards.append(reward)
+        score+=reward
+
         if done:
-            break
\ No newline at end of file
+            break
+
+        # OPTIMIZE OUTPUT LAYER WEIGHTS `w` BASED ON YOUR OPTIMIZATION METHOD
+
+        # Below is a sample of weight update based on gradient
+        # ascent(maximize cumulative reward) method for temporal difference learning
+        for i in range(len(grads)):
+
+            # Loop through everything that happened in the episode and update towards
+            # the log policy gradient times future reward
+            w += LEARNING_RATE * grads[i] * sum([ r * (GAMMA ** r) for t,r in enumerate(rewards[i:])])
+
+        print('Episode %s  Score %s' %(str(EPISODE),str(score)))
+
+There are several neural data analysis and visualization methods inbuilt with `sorn` package.
+Sample call for few plotting and statistical methods are shown below
+
+Plotting functions
+------------------
+
+Plot weight distribution in the network
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    from sorn import Plotter
+    # For example, the network has 200 neurons in the excitatory pool.
+    Wee = np.random.randn(200,200) # Note that generally Wee is sparse
+    Wee=Wee/Wee.max() # state_dict['Wee'] returned by the SORN is already normalized
+    Plotter.weight_distribution(weights= Wee, bin_size = 5, savefig = True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/weight_distribution.png
+
+
+Plot Spike train
+^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    E = np.random.randint(2, size=(200,1000)) # For example, activity of 200 excitatory neurons in 1000 time steps
+    Plotter.scatter_plot(spike_train = E, savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/ScatterSpikeTrain.png
+
+
+Raster plot of Spike train
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Raster plot of activity of only first 10 neurons in the excitatory pool
+    Plotter.raster_plot(spike_train = E[:,0:10], savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/RasterSpikeTrain.png
+
+Distribution of presynaptic connections
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Histogram of number of presynaptic connections per neuron in the excitatory pool
+    Plotter.hist_incoming_conn(weights=Wee, bin_size=10, histtype='bar', savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_incoming_conn.png
+
+
+Distribution of firing rate of the network
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    Plotter.hist_firing_rate_network(E, bin_size=10, savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_firing_rate_network.png
+
+Plot pearson correlation between neurons
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    from sorn import Statistics
+    avg_corr_coeff,_ = Statistics.avg_corr_coeff(E)
+    Plotter.correlation(avg_corr_coeff,savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/correlation_between_neurons.png
+
+Inter spike intervals
+^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Inter spike intervals with exponential curve fit for neuron 1 in the Excitatory pool
+    Plotter.isi_exponential_fit(E,neuron=1,bin_size=10, savefig=True)
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/isi_exponential_fit.png
+
+Linear and Lognormal curve fit of Synaptic weights
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Distribution of connection weights in linear and lognormal scale
+    Plotter.linear_lognormal_fit(weights=Wee,num_points=100, savefig=True)
+
+    .. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/LinearLognormalFit.png
+
+Network plot
+^^^^^^^^^^^^^
+.. code-block:: python
+
+    # Draw network connectivity using the pearson correlation function between neurons in the excitatory pool
+    Plotter.plot_network(avg_corr_coeff,corr_thres=0.01,fig_name='network.png')
+
+.. image:: https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/network.png
+
+Statistics and Analysis functions
+----------------------------------
+
+t-lagged auto correlation between neural activity
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    from sorn import Statistics
+    pearson_corr_matrix = Statistics.autocorr(firing_rates = [1,1,5,6,3,7], t= 2)
+
+Fano factor
+^^^^^^^^^^^^
+
+.. code-block:: python
+
+    # To verify poissonian process in spike generation of neuron 10
+    mean_firing_rate, variance_firing_rate, fano_factor = Statistics.fanofactor(spike_train= E,
+                                                                            neuron = 10,
+                                                                            window_size = 10)
+
+Spike Source Entropy
+^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: python
+
+    # Measure the uncertainty about the origin of spike from the network using entropy
+    sse = Statistics.spike_source_entropy(spike_train= E, num_neurons=200)
+
diff --git a/imgs/LinearLognormalFit.png b/imgs/LinearLognormalFit.png
new file mode 100644
index 0000000..1e00a97
Binary files /dev/null and b/imgs/LinearLognormalFit.png differ
diff --git a/imgs/RasterSpikeTrain.png b/imgs/RasterSpikeTrain.png
new file mode 100644
index 0000000..a413032
Binary files /dev/null and b/imgs/RasterSpikeTrain.png differ
diff --git a/imgs/ScatterSpikeTrain.png b/imgs/ScatterSpikeTrain.png
new file mode 100644
index 0000000..5387e2d
Binary files /dev/null and b/imgs/ScatterSpikeTrain.png differ
diff --git a/imgs/correlation_between_neurons.png b/imgs/correlation_between_neurons.png
new file mode 100644
index 0000000..aabf0e5
Binary files /dev/null and b/imgs/correlation_between_neurons.png differ
diff --git a/imgs/hist_firing_rate_network.png b/imgs/hist_firing_rate_network.png
new file mode 100644
index 0000000..df156c3
Binary files /dev/null and b/imgs/hist_firing_rate_network.png differ
diff --git a/imgs/hist_incoming_conn.png b/imgs/hist_incoming_conn.png
new file mode 100644
index 0000000..df3fa96
Binary files /dev/null and b/imgs/hist_incoming_conn.png differ
diff --git a/imgs/isi_exponential_fit.png b/imgs/isi_exponential_fit.png
new file mode 100644
index 0000000..16715ba
Binary files /dev/null and b/imgs/isi_exponential_fit.png differ
diff --git a/imgs/network.png b/imgs/network.png
new file mode 100644
index 0000000..71b8224
Binary files /dev/null and b/imgs/network.png differ
diff --git a/imgs/weight_distribution.png b/imgs/weight_distribution.png
new file mode 100644
index 0000000..d9eabaf
Binary files /dev/null and b/imgs/weight_distribution.png differ
diff --git a/paper/paper.md b/paper/paper.md
index 95a8e4f..4bdc59c 100644
--- a/paper/paper.md
+++ b/paper/paper.md
@@ -153,9 +153,9 @@ state_dict,E,I,R,C=Simulator.simulate_sorn(inputs=inputs,phase='plasticity',
 
                                         matrices=None,noise=True,
 
-                                        time_steps=time_steps,_ne=200,
+                                        time_steps=time_steps,ne=200,
 
-                                        _nu=num_features)
+                                        nu=num_features)
 ```
 'simulate_sorn' returns the dictionary of network state variables of the last time steps, the excitatory and inhibitory network activity of the whole simulation period, and also the recurrent activity and the number of active connections at each time step. To continue the simulation, load the matrices returned in the previous step as,
 
@@ -166,19 +166,19 @@ state_dict,E,I,R,C=Simulator.simulate_sorn(inputs=inputs,phase='plasticity',
 
                                         time_steps=time_steps,
 
-                                        _ne = 200,_nu=num_features)
+                                        ne = 200,nu=num_features)
 
 ```
 
 ### Network Output Descriptions
 
-`state_dict` - Dictionary of connection weights ($W_{ij}^{EE}$,$W_{ij}^{EI}$,$W_{ij}^{IE}$) ,
+`state_dict` - Dictionary of connection weights ('Wee','Wei','Wie') ,
 
-               Excitatory network activity ('E'),
+               Excitatory network activity ('X'),
 
-               Inhibitory network activities('I'),
+               Inhibitory network activities('Y'),
 
-               Threshold values $T^E,T^I$
+               Threshold values ('Te','Ti')
 
 `E` - Collection of Excitatory network activity of entire simulation period
 
diff --git a/setup.py b/setup.py
index a79960d..10cb497 100644
--- a/setup.py
+++ b/setup.py
@@ -8,10 +8,9 @@
 def read(fname):
     return open(os.path.join(os.path.dirname(__file__), fname)).read()
 
-
 setup(
     name="sorn",
-    version="0.5.2",
+    version="0.5.7",
     author="Saranraj Nambusubramaniyan",
     author_email="saran_nns@hotmail.com",
     description="Self-Organizing Recurrent Neural Networks",
@@ -20,7 +19,7 @@ def read(fname):
                   Spiking Cortical Networks, Neural Connectomics,Neuroscience, Artificial General Intelligence, Neural Information Processing""",
     url="https://github.com/Saran-nns/sorn",
     packages=["sorn"],
-    data_files=["LICENSE.md", "sorn/configuration.ini"],
+    data_files=["LICENSE.md"],
     long_description=read("README.md"),
     long_description_content_type="text/markdown",
     classifiers=[
diff --git a/sorn.egg-info/PKG-INFO b/sorn.egg-info/PKG-INFO
index 4c729bd..a6b1211 100644
--- a/sorn.egg-info/PKG-INFO
+++ b/sorn.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: sorn
-Version: 0.5.2
+Version: 0.5.7
 Summary: Self-Organizing Recurrent Neural Networks
 Home-page: https://github.com/Saran-nns/sorn
 Author: Saranraj Nambusubramaniyan
@@ -69,31 +69,10 @@ Description:
         For detailed documentation about usage and development, please visit [SORN-Documentation](https://self-organizing-recurrent-neural-networks.readthedocs.io/)
         
         ## Usage
-        
-        ### Update Network configurations
-        There are two ways to update/configure the network parameters,
-        1. Navigate to home/conda/envs/ENVNAME/Lib/site-packages/sorn
-         ```or``` if you are unsure about the directory of ```sorn```
-        
-        Run
+        ### Plasticity Phase
         
         ```python
         import sorn
-        
-        sorn.__file__
-        ```
-        to find the location of the sorn package
-        
-        Then, update/edit arguments in `configuration.ini`
-        
-        2. While instantiating the network using `Simulator` or `Trainer` objects, override the defaults by assigning the values to the ```kwargs``` shown below,
-        ```Python
-        kwargs = {'_ne', '_nu', '_network_type_ee', '_network_type_ei', '_network_type_ie', '_lambda_ee','_lambda_ei', '_lambda_ie', '_eta_stdp','_eta_inhib', '_eta_ip', '_te_max', '_ti_max', '_ti_min', '_te_min', '_mu_ip','_sigma_ip'}
-        ```
-        ### Plasticity Phase
-        The default ```_ne, _nu``` values are overriden by passing them as kwargs inside ```simulate_sorn``` method.
-        
-        ```Python
         from sorn import Simulator
         import numpy as np
         
@@ -102,75 +81,125 @@ Description:
         time_steps = 200
         inputs = np.random.rand(num_features,time_steps)
         
-        # To simulate the network;
-        matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features)
+        # Simulate the network with default hyperparameters under gaussian white noise
+        state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                        matrices=None, noise = True,
+                                                        time_steps=time_steps)
         
-        # To resume the simulation, load the matrices_dict from previous simulation;
-        matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=matrices_dict, noise= True, time_steps=time_steps,_ne = 200, _nu=num_features)
+        ```
+        The default values of the network hyperparameters are,
+        
+        Keyword argument | Value | Description |
+        --- | --- | --- |
+        ne              | 200      | Number of Encitatory neurons in the reservoir                              |
+        nu              | 10       | Number of Input neurons in the reservoir                                   |
+        network_type_ee | "Sparse" | `Sparse` or `Dense` connectivity between Excitatory neurons                |
+        network_type_ie | "Dense"  | `Sparse` or `Dense` connectivity from Excitatory to Inhibitory neurons     |
+        network_type_ei | "Sparse" | `Sparse` or `Dense` connectivity from Inhibitory to Excitatory neurons     |
+        lambda_ee       | 20       | % of connections between neurons in Excitatory pool                        |
+        lambda_ei       | 40       | % of connections from Inhibitory to Excitatory neurons                     |
+        lambda_ie       | 100      | % of connections from Excitatory to Inhibitory neurons                     |
+        eta_stdp        | 0.004    | Hebbian Learning rate for connections between excitatory neurons           |
+        eta_inhib       | 0.001    | Hebbian Learning rate for connections from Inhibitory to Excitatory neurons|
+        eta_ip          | 0.01     | Intrinsic plasticity learning rate                                         |
+        te_max          | 1.0      | Maximum excitatory neuron threshold value                                  |
+        ti_max          | 0.5      | Maximum inhibitory neuron threshold value                                  |
+        ti_min          | 0.0      | Minimum inhibitory neuron threshold value                                  |
+        te_min          | 0.0      | Minimum excitatory neuron threshold value                                  |
+        mu_ip           | 0.1      | Target mean firing rate of excitatory neuron                               |
+        sigma_ip        | 0.0      | Standard deviation of firing rate of excitatory neuron                     |
+        
+        To override the default hyperparameters, use the `kwargs` as shown below,
+        ```python
+        state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                        matrices=None, noise= True,
+                                                        time_steps=time_steps,
+                                                        ne = 200, nu=num_features)
         ```
         ### Training phase
         
         ```Python
         from sorn import Trainer
+        # NOTE: During training phase, input to `sorn` should have second (time) dimension set to 1. ie., input shape should be (input_features,1).
+        
         inputs = np.random.rand(num_features,1)
         
         # SORN network is frozen during training phase
-        matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Trainer.train_sorn(inputs = inputs, phase='Training', matrices=matrices_dict,_nu=num_features, time_steps=1)
+        state_dict, E, I, R, C = Trainer.train_sorn(inputs = inputs, phase='training',
+                                                    matrices=state_dict,
+                                                    nu=num_features, time_steps=1)
         ```
-        
-        To turn off any plasticity mechanisms during simulation or training phase, you can use `freeze` argument.
-        For example to stop intrinsic plasticity during training phase,
+        ### Freeze plasticity
+        To turn off any plasticity mechanisms during `simulation` or `training` phase, use `freeze` argument.
+        For example to stop intrinsic plasticity during simulation phase,
         
         ```python
-        matrices_dict, Exc_activity, Inh_activity, Rec_activity, num_active_connections = Simulator.simulate_sorn(inputs = inputs, phase='plasticity', matrices=None, noise = True, time_steps=time_steps, _ne = 200, _nu=num_features, freeze=['ip'])
+        # Sample input
+        num_features = 10
+        time_steps = 200
+        inputs = np.random.rand(num_features,time_steps)
+        
+        state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = inputs, phase='plasticity',
+                                                        matrices=None, noise = True,
+                                                        time_steps=time_steps, ne = 200,
+                                                        nu=num_features, freeze=['ip'])
         ```
         
         The other options are,
         
-        `'stdp'` - Spike Timing Dependent Plasticity
+        `stdp` - Spike Timing Dependent Plasticity
         
-        `'ss'` - Synaptic Scaling
+        `ss` - Synaptic Scaling
         
-        `'sp'` - Structural Plasticity
+        `sp` - Structural Plasticity
         
-        `'istdp'` - Inhibitory Spike Timing Dependent Plasticity
+        `istdp` - Inhibitory Spike Timing Dependent Plasticity
         
         Note: If you pass all above options to `freeze`, then the network will behave as Liquid State Machine(LSM)
         
         ### Network Output Descriptions
-          ```matrices_dict```  - Dictionary of connection weights ('Wee','Wei','Wie') , Excitatory network activity ('X'), Inhibitory network activities('Y'), Threshold values ('Te','Ti')
+          `state_dict`  - Dictionary of connection weights (`Wee`,`Wei`,`Wie`) , Excitatory network activity (`X`), Inhibitory network activities(`Y`), Threshold values (`Te`,`Ti`)
         
-          ```Exc_activity``` - Collection of Excitatory network activity of entire simulation period
+          `E` - Collection of Excitatory network activity of entire simulation period
         
-          ```Inh_activity``` - Collection of Inhibitory network activity of entire simulation period
+          `I` - Collection of Inhibitory network activity of entire simulation period
         
-          ```Rec_activity``` - Collection of Recurrent network activity of entire simulation period
+          `R` - Collection of Recurrent network activity of entire simulation period
         
-          ```num_active_connections``` - List of number of active connections in the Excitatory pool at each time step
+          `C` - List of number of active connections in the Excitatory pool at each time step
         
         ### Colaboratory Notebook
         Sample simulation and training runs with few plotting functions are found at [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/10TElAAE1dsgzuvaHO_NjgMAE5Pic3_jL#scrollTo=VDa0U4mf1Z75)
         
         ## Usage with OpenAI gym
         ### Cartpole balance problem
-        With default network parameters.
         
         ```python
         from sorn import Simulator, Trainer
         import gym
         
-        # Load the simulated network matrices
-        # Note that these matrices are obtained after the network achieved convergence under random inputs and noise
+        # Hyperparameters
+        NUM_EPISODES = int(2e6)
+        NUM_PLASTICITY_EPISODES = 20
         
-        with open('simulation_matrices.pkl','rb') as f:
-            sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = pickle.load(f)
+        LEARNING_RATE = 0.0001 # Gradient ascent learning rate
+        GAMMA = 0.99 # Discounting factor for the Rewards
         
-        # Training parameters
+        # Open AI gym; Cartpole Environment
+        env = gym.make('CartPole-v0')
+        action_space = env.action_space.n
         
-        NUM_EPISODES = 2e6
-        NUM_PLASTICITY_EPISODES = 20000
+        # SORN network parameters
+        ne = 50
+        nu = 4
+        # Init SORN using Simulator under random input;
+        state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = np.random.randn(4,1),
+                                                         phase ='plasticity',
+                                                         time_steps = 1,
+                                                         noise=False,
+                                                         ne = ne, nu=nu)
         
-        env = gym.make('CartPole-v0')
+        w = np.random.rand(ne, 2) # Output layer weights
         
         # Policy
         def policy(state,w):
@@ -179,65 +208,148 @@ Description:
             exp = np.exp(z)
             return exp/np.sum(exp)
         
+        # Vectorized softmax Jacobian
+        def softmax_grad(softmax):
+            s = softmax.reshape(-1,1)
+            return np.diagflat(s) - np.dot(s, s.T)
+        
         for EPISODE in range(NUM_EPISODES):
         
-            # Environment observation; Input to sorn should be of shape (input_features,time_steps)
+            # Environment observation;
+            # NOTE: Input to sorn should have time dimension. ie., input shape should be (input_features,time_steps)
             state = env.reset()[:, None] # (4,) --> (4,1)
-            state = np.array(state)
+        
+            grads = [] # Episode log policy gradients
+            rewards = [] # Episode rewards
+        
+            # Keep track of total score
+            score = 0
         
             # Play the episode
             while True:
-              state = np.array(state[:,None])
-              if EPISODE < NUM_PLASTICITY_EPISODE:
+        
+              # env.render() # Uncomment to see your model train in real time (slow down training progress)
+              if EPISODE < NUM_PLASTICITY_EPISODES:
         
                 # Plasticity phase
-                sim_matrices, excit_states, inhib_states, recur_states, num_reservoir_conn = Simulator.simulate_sorn(inputs = state, phase ='plasticity', matrices = sim_matrices, time_steps = 1, noise=False)
+                state_dict, E, I, R, C = Simulator.simulate_sorn(inputs = state, phase ='plasticity',
+                                                                matrices = state_dict, time_steps = 1,
+                                                                ne = ne, nu=nu,
+                                                                noise=False)
         
               else:
                 # Training phase with frozen reservoir connectivity
-                sim_matrices,excit_states,inhib_states,recur_states,num_reservoir_conn = Trainer.train_sorn(inputs = state, phase = 'training', matrices = sim_matrices, noise= False)
+                state_dict, E, I, R, C = Trainer.train_sorn(inputs = state, phase = 'training',
+                                                        matrices = state_dict, time_steps = 1,
+                                                        ne = ne, nu=nu,
+                                                        noise= False)
         
-              # Feed excit_states as input states to your RL algorithm, below goes for simple policy gradient algorithm
+              # Feed E as input states to your RL algorithm, below goes for simple policy gradient algorithm
               # Sample policy w.r.t excitatory states and take action in the environment
-              probs = policy(np.asarray(excit_states),output_layer_weights))
-              action = np.random.choice(action_space,probs)
-        
+              probs = policy(np.asarray(E),w)
+              action = np.random.choice(action_space,p=probs[0])
               state,reward,done,_ = env.step(action)
+              state = state[:,None]
+        
+              # COMPUTE GRADIENTS BASED ON YOUR OBJECTIVE FUNCTION;
+              # Sample computation of policy gradient objective function
+              dsoftmax = softmax_grad(probs)[action,:]
+              dlog = dsoftmax / probs[0,action]
+              grad = np.asarray(E).T.dot(dlog[None,:])
+              grads.append(grad)
+              rewards.append(reward)
+              score+=reward
         
               if done:
-                break
+                  break
+        
+            # OPTIMIZE OUTPUT LAYER WEIGHTS `w` BASED ON YOUR OPTIMIZATION METHOD;
+            # Below is a sample of weight update based on gradient ascent(maximize cumulative reward) method for temporal difference learning
+            for i in range(len(grads)):
         
-          # YOUR CODE HERE
-          # COMPUTE GRADIENTS BASED ON YOUR OBJECTIVE FUNCTION
-          # OPTIMIZE `output_layer_weights` BASED ON YOUR OPTIMIZATION METHOD
+                # Loop through everything that happened in the episode and update towards the log policy gradient times future reward
+                w += LEARNING_RATE * grads[i] * sum([ r * (GAMMA ** r) for t,r in enumerate(rewards[i:])])
+            print('Episode %s  Score %s' %(str(EPISODE),str(score)))
         ```
+        
         There are several neural data analysis and visualization methods inbuilt with `sorn` package. Sample call for few plotting and statistical methods are shown below;
         
         ## Plotting functions
         
-        ```Python
+        ```python
         from sorn import Plotter
         # Plot weight distribution in the network
-        Plotter.weight_distribution(weights= matrices_dict['Wee'], bin_size = 5, savefig = False)
+        Wee = np.random.randn(200,200) # For example, the network has 200 neurons in the excitatory pool. Note that generally Wee is sparse
+        Wee=Wee/Wee.max() # state_dict['Wee'] returned by the SORN is already normalized
+        Plotter.weight_distribution(weights= Wee, bin_size = 5, savefig = True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/weight_distribution.png" height="320" width="430"></a>
         
+        ```python
         # Plot Spike train of all neurons in the network
-        Plotter.scatter_plot(spike_train = np.asarray(Exc_activity), savefig=False)
+        E = np.random.randint(2, size=(200,1000)) # For example, activity of 200 excitatory neurons in 1000 time steps
+        Plotter.scatter_plot(spike_train = E, savefig=True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/ScatterSpikeTrain.png" height="320" width="430"></a>
+        
+        ```python
+        # Raster plot of activity of only first 10 neurons in the excitatory pool
+        Plotter.raster_plot(spike_train = E[:,0:10], savefig=True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/RasterSpikeTrain.png" height="320" width="430"></a>
+        
+        ```python
+        # Histogram of number of presynaptic connections per neuron in the excitatory pool
+        Plotter.hist_incoming_conn(weights=Wee, bin_size=10, histtype='bar', savefig=True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_incoming_conn.png" height="310" width="430"></a>
         
-        Plotter.raster_plot(spike_train = np.asarray(Exc_activity), savefig=False)
+        ```python
+        # Distribution of firing rate of the network
+        Plotter.hist_firing_rate_network(E, bin_size=10, savefig=True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/hist_firing_rate_network.png" height="320" width="430"></a>
+        
+        ```python
+        # Plot pearson correlation between neurons
+        from sorn import Statistics
+        avg_corr_coeff,_ = Statistics.avg_corr_coeff(E)
+        Plotter.correlation(avg_corr_coeff,savefig=True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/correlation_between_neurons.png" height="320" width="430"></a>
+        
+        ```python
+        # Inter spike intervals with exponential curve fit for neuron 1 in the Excitatory pool
+        Plotter.isi_exponential_fit(E,neuron=1,bin_size=5, savefig=True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/isi_exponential_fit.png" height="320" width="430"></a>
+        
+        ```python
+        # Distribution of connection weights in linear and lognormal scale
+        Plotter.linear_lognormal_fit(weights=Wee,num_points=100, savefig=True)
+        ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/LinearLognormalFit.png" height="300" width="440"></a>
+        
+        ```python
+        # Draw network connectivity using the pearson correlation function between neurons in the excitatory pool
+        Plotter.plot_network(avg_corr_coeff,corr_thres=0.01,fig_name='network.png')
         ```
+        <a href="url"><img src="https://raw.githubusercontent.com/Saran-nns/sorn/revision/imgs/network.png" height="340" width="410"></a>
         
         ## Statistics and Analysis functions
         
         ```Python
         from sorn import Statistics
         #t-lagged auto correlation between neural activity
-        Statistics.autocorr(firing_rates = [1,1,5,6,3,7],t= 2)
+        pearson_corr_matrix = Statistics.autocorr(firing_rates = [1,1,5,6,3,7], t= 2)
         
         # Fano factor: To verify poissonian process in spike generation of neuron 10
-        Statistics.fanofactor(spike_train= np.asarray(Exc_activity),neuron = 10,window_size = 10)
+        mean_firing_rate, variance_firing_rate, fano_factor = Statistics.fanofactor(spike_train= E,
+                                                                                    neuron = 10,
+                                                                                    window_size = 10)
         
-        # Measure the uncertainty about the origin of spike from the network using entropy
-        Statistics.spike_source_entropy(spike_train= np.asarray(Exc_activity), num_neurons=200)
+        # Spike Source Entropy: To measure the uncertainty about the origin of spike from the network using entropy
+        sse = Statistics.spike_source_entropy(spike_train= E, num_neurons=200)
         ```
         ## Citation
         ### Package
diff --git a/sorn.egg-info/SOURCES.txt b/sorn.egg-info/SOURCES.txt
index a56dac0..5857bdb 100644
--- a/sorn.egg-info/SOURCES.txt
+++ b/sorn.egg-info/SOURCES.txt
@@ -2,7 +2,6 @@ LICENSE.md
 README.md
 setup.py
 sorn/__init__.py
-sorn/configuration.ini
 sorn/sorn.py
 sorn/test_sorn.py
 sorn/utils.py
diff --git a/sorn/__init__.py b/sorn/__init__.py
index 6223714..e39b9d9 100644
--- a/sorn/__init__.py
+++ b/sorn/__init__.py
@@ -3,6 +3,6 @@
 from .utils import *
 
 __author__ = "Saranraj Nambusubramaniyan"
-__version__ = "0.5.2"
+__version__ = "0.5.7"
 
 logging.basicConfig(level=logging.INFO)
diff --git a/sorn/configuration.ini b/sorn/configuration.ini
deleted file mode 100644
index 3e21f6f..0000000
--- a/sorn/configuration.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-[Network_Config]
-
-# Number of neurons in the reservoir
-Ne = 200
-
-# Number of input units in the reservoir
-Nu = 10
-
-# Connection/Network type: Sparse or Dense
-
-network_type_ee = Sparse
-network_type_ei = Sparse
-network_type_ie = Dense
-
-# Mean number of incoming and outgoing connections per neuron
-lambda_ee = 20
-lambda_ei = 40
-lambda_ie = 100
-
-# Hebbian Learning rate 
-eta_stdp = 0.004
-
-# Anti-Hebbian learning rate
-eta_inhib = 0.001
-
-# Intrinsic plasticity constants    
-eta_ip = 0.01
-
-# Threshold initialization values
-te_max = 1.0
-ti_max = 0.5
-ti_min = 0.0
-te_min = 0.0
-
-# Mean and standard deviation of target firing rate , h_ip
-mu_ip = 0.1
-sigma_ip = 0.0 
-
diff --git a/sorn/sorn.py b/sorn/sorn.py
index 3d4edf7..3b941c9 100644
--- a/sorn/sorn.py
+++ b/sorn/sorn.py
@@ -3,7 +3,6 @@
 from __future__ import division
 import numpy as np
 import os
-from configparser import ConfigParser
 import random
 
 try:
@@ -11,13 +10,6 @@
 except:
     from utils import Initializer
 
-parser = ConfigParser()
-config_file = os.path.join(
-    os.path.dirname(os.path.abspath(__file__)), "configuration.ini"
-)
-parser.read(config_file)
-
-
 class Sorn(object):
 
     """ This class wraps initialization of the network and its parameters
@@ -25,7 +17,7 @@ class Sorn(object):
     Args:
         nu (int): Number of input units. Defaults to 10
 
-        ne (int): Sorn._ne  # Number of excitatory units. Defaults to 200
+        ne (int): Number of excitatory units. Defaults to 200
 
         eta_stdp (float): STDP plasticity Learning rate constant; SORN1 and SORN2. Defaults to 0.004
 
@@ -33,13 +25,13 @@ class Sorn(object):
 
         eta_inhib (float): Intrinsic plasticity learning rate constant; SORN2 only. Defaults to 0.01
 
-        h_ip (float): Target firing rate. Defaults to 2 * Sorn._nu / Sorn._ne
+        h_ip (float): Target firing rate. Defaults to 2 * nu / ne
 
         mu_ip (float): Mean target firing rate. Defaults to 0.1
 
         sigma_ip (float): Variance of target firing rate. Defaults to 0.0
 
-        ni (int): Number of inhibitory units in the network. Defaults to int(0.2 * Sorn._ne)
+        ni (int): Number of inhibitory units in the network. Defaults to int(0.2*ne)
 
         time_steps (float): Total time steps of simulation
 
@@ -66,37 +58,34 @@ class Sorn(object):
     def __init__(self):
         pass
 
-    _nu = int(parser.get("Network_Config", "Nu"))
-    _ne = int(parser.get("Network_Config", "Ne"))
-    _ni = int(0.2 * _ne)
-    _eta_stdp = float(parser.get("Network_Config", "eta_stdp"))
-    _eta_inhib = float(parser.get("Network_Config", "eta_inhib"))
-    _eta_ip = float(parser.get("Network_Config", "eta_ip"))
-    _te_max = float(parser.get("Network_Config", "te_max"))
-    _ti_max = float(parser.get("Network_Config", "ti_max"))
-    _ti_min = float(parser.get("Network_Config", "ti_min"))
-    _te_min = float(parser.get("Network_Config", "te_min"))
-    _mu_ip = float(parser.get("Network_Config", "mu_ip"))
-    _sigma_ip = float(parser.get("Network_Config", "sigma_ip"))
-    _network_type_ee = str(parser.get("Network_Config", "network_type_ee"))
-    _network_type_ei = str(parser.get("Network_Config", "network_type_ei"))
-    _network_type_ie = str(parser.get("Network_Config", "network_type_ie"))
-    _lambda_ee = int(parser.get("Network_Config", "lambda_ee"))
-    _lambda_ei = int(parser.get("Network_Config", "lambda_ei"))
-    _lambda_ie = int(parser.get("Network_Config", "lambda_ie"))
-
+    nu = 10
+    ne = 200
+    ni = int(0.2 * ne)
+    eta_stdp = 0.004
+    eta_inhib = 0.001
+    eta_ip = 0.01
+    te_max = 1.0
+    ti_max = 0.5
+    ti_min = 0.0
+    te_min = 0.0
+    mu_ip = 0.1
+    sigma_ip = 0.0
+    network_type_ee = "Sparse"
+    network_type_ei = "Sparse"
+    network_type_ie = "Dense"
+    lambda_ee = 20
+    lambda_ei = 40
+    lambda_ie = 100
     @staticmethod
     def initialize_weight_matrix(
         network_type: str, synaptic_connection: str, self_connection: str, lambd_w: int
     ):
         """Wrapper for initializing the weight matrices for SORN
-
         Args:
             network_type (str): Spare or Dense
             synaptic_connection (str): EE,EI,IE. Note that Spare connection is defined only for EE connections
             self_connection (str): True or False: Synaptic delay or time delay
             lambd_w (int): Average number of incoming and outgoing connections per neuron
-
         Returns:
             weight_matrix (array): Array of connection strengths
         """
@@ -104,17 +93,17 @@ def initialize_weight_matrix(
         if (network_type == "Sparse") and (self_connection == "False"):
 
             # Generate weight matrix for E-E/ E-I connections with mean lamda incoming and out-going connections per neuron
-            assert (lambd_w <= Sorn._ne), "Number of connections per unit (lambda) should be less than number of units(Ne) in the pool and also Ne should be greater than 25"
+            assert (lambd_w <= Sorn.ne), "Number of connections per unit (lambda) should be less than number of units(Ne) in the pool and also Ne should be greater than 25"
             weight_matrix = Initializer.generate_lambd_connections(
-                synaptic_connection, Sorn._ne, Sorn._ni, lambd_w, lambd_std=1
+                synaptic_connection, Sorn.ne, Sorn.ni, lambd_w, lambd_std=1
             )
 
         # Dense matrix for W_ie
         elif (network_type == "Dense") and (self_connection == "False"):
 
             # Uniform distribution of weights
-            weight_matrix = np.random.uniform(0.0, 0.1, (Sorn._ne, Sorn._ni))
-            weight_matrix.reshape((Sorn._ne, Sorn._ni))
+            weight_matrix = np.random.uniform(0.0, 0.1, (Sorn.ne, Sorn.ni))
+            weight_matrix.reshape((Sorn.ne, Sorn.ni))
 
         return weight_matrix
 
@@ -123,35 +112,29 @@ def initialize_threshold_matrix(
         te_min: float, te_max: float, ti_min: float, ti_max: float
     ):
         """Initialize the threshold for excitatory and inhibitory neurons
-
         Args:
             te_min (float): Min threshold value for excitatory units
             te_max (float): Min threshold value for inhibitory units
             ti_min (float): Max threshold value for excitatory units
             ti_max (float): Max threshold value for inhibitory units
-
         Returns:
             te (array): Threshold values for excitatory units
             ti (array): Threshold values for inhibitory units
         """
 
-        te = np.random.uniform(te_min, te_max, (Sorn._ne, 1))
-        ti = np.random.uniform(ti_min, ti_max, (Sorn._ni, 1))
+        te = np.random.uniform(te_min, te_max, (Sorn.ne, 1))
+        ti = np.random.uniform(ti_min, ti_max, (Sorn.ni, 1))
 
         return te, ti
 
     @staticmethod
     def initialize_activity_vector(ne: int, ni: int):
         """Initialize the activity vectors X and Y for excitatory and inhibitory neurons
-
         Args:
             ne (int): Number of excitatory neurons
-
             ni (int): Number of inhibitory neurons
-
         Returns:
             x (array): Array of activity vectors of excitatory population
-
             y (array): Array of activity vectors of inhibitory population"""
 
         x = np.zeros((ne, 2))
@@ -162,69 +145,51 @@ def initialize_activity_vector(ne: int, ni: int):
 class Plasticity(Sorn):
     """Instance of class Sorn. Inherits the variables and functions defined in class Sorn.
     It encapsulates all plasticity mechanisms mentioned in the article. Inherits all attributed from parent class Sorn
-
     Args:
         nu (int): Number of input units. Defaults to 10
-
-        ne (int): Sorn._ne  # Number of excitatory units. Defaults to 200
-
+        ne (int): Sorn.ne  # Number of excitatory units. Defaults to 200
         eta_stdp (float): STDP plasticity Learning rate constant; SORN1 and SORN2. Defaults to 0.004
-
         eta_ip (float): Intrinsic plasticity learning rate constant; SORN1 and SORN2. Defaults to 0.001
-
         eta_inhib (float): Intrinsic plasticity learning rate constant; SORN2 only. Defaults to 0.01
-
-        h_ip (float): Target firing rate. Defaults to 2 * Sorn._nu / Sorn._ne
-
+        h_ip (float): Target firing rate. Defaults to 2 * Sorn.nu / Sorn.ne
         mu_ip (float): Mean target firing rate. Defaults to 0.1
-
         sigma_ip (float): Variance of target firing rate. Defaults to 0.0
-
-        ni (int): Number of inhibitory units in the network. Defaults to int(0.2 * Sorn._ne)
-
+        ni (int): Number of inhibitory units in the network. Defaults to int(0.2 * Sorn.ne)
         time_steps (float): Total time steps of simulation
-
         te_min (float): Excitatory minimum Threshold. Defaults to 0.0
-
         te_max (float): Excitatory maximum Threshold. Defaults to 1.0
-
         ti_min (float): Inhibitory minimum Threshold. Defaults to 0.0
-
         ti_max (float): Inhibitory maximum Threshold. Defaults to 0.5
     """
 
     def __init__(self):
 
         super().__init__()
-        self.nu = Sorn._nu  # Number of input units
-        self.ne = Sorn._ne  # Number of excitatory units
+        self.nu = Sorn.nu  # Number of input units
+        self.ne = Sorn.ne  # Number of excitatory units
         self.eta_stdp = (
-            Sorn._eta_stdp
+            Sorn.eta_stdp
         )  # STDP plasticity Learning rate constant; SORN1 and SORN2
         self.eta_ip = (
-            Sorn._eta_ip
+            Sorn.eta_ip
         )  # Intrinsic plasticity learning rate constant; SORN1 and SORN2
         self.eta_inhib = (
-            Sorn._eta_inhib
+            Sorn.eta_inhib
         )  # Intrinsic plasticity learning rate constant; SORN2 only
-        self.h_ip = 2 * Sorn._nu / Sorn._ne  # Target firing rate
-        self.mu_ip = Sorn._mu_ip  # Mean target firing rate
+        self.h_ip = 2 * Sorn.nu / Sorn.ne  # Target firing rate
+        self.mu_ip = Sorn.mu_ip  # Mean target firing rate
         # Number of inhibitory units in the network
-        self.ni = int(0.2 * Sorn._ne)
-        self.time_steps = Sorn._time_steps  # Total time steps of simulation
-        self.te_min = Sorn._te_min  # Excitatory minimum Threshold
-        self.te_max = Sorn._te_max  # Excitatory maximum Threshold
+        self.ni = int(0.2 * Sorn.ne)
+        self.time_steps = Sorn.time_steps  # Total time steps of simulation
+        self.te_min = Sorn.te_min  # Excitatory minimum Threshold
+        self.te_max = Sorn.te_max  # Excitatory maximum Threshold
 
     def stdp(self, wee: np.array, x: np.array, cutoff_weights: list):
         """Apply STDP rule : Regulates synaptic strength between the pre(Xj) and post(Xi) synaptic neurons
-
         Args:
             wee (array):  Weight matrix
-
             x (array): Excitatory network activity
-
             cutoff_weights (list): Maximum and minimum weight ranges
-
         Returns:
             wee (array):  Weight matrix
         """
@@ -262,12 +227,9 @@ def stdp(self, wee: np.array, x: np.array, cutoff_weights: list):
 
     def ip(self, te: np.array, x: np.array):
         """Intrinsic Plasiticity mechanism
-
         Args:
             te (array): Threshold vector of excitatory units
-
             x (array): Excitatory network activity
-
         Returns:
             te (array): Threshold vector of excitatory units
         """
@@ -290,10 +252,8 @@ def ip(self, te: np.array, x: np.array):
     @staticmethod
     def ss(wee: np.array):
         """Synaptic Scaling or Synaptic Normalization
-
         Args:
             wee (array):  Weight matrix
-
         Returns:
             wee (array):  Scaled Weight matrix
         """
@@ -302,16 +262,11 @@ def ss(wee: np.array):
 
     def istdp(self, wei: np.array, x: np.array, y: np.array, cutoff_weights: list):
         """Apply iSTDP rule, which regulates synaptic strength between the pre inhibitory(Xj) and post Excitatory(Xi) synaptic neurons
-
         Args:
             wei (array): Synaptic strengths from inhibitory to excitatory
-
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             cutoff_weights (list): Maximum and minimum weight ranges
-
         Returns:
             wei (array): Synaptic strengths from inhibitory to excitatory"""
 
@@ -355,10 +310,8 @@ def istdp(self, wei: np.array, x: np.array, y: np.array, cutoff_weights: list):
     @staticmethod
     def structural_plasticity(wee: np.array):
         """Add new connection value to the smallest weight between excitatory units randomly
-
         Args:
             wee (array): Weight matrix
-
         Returns:
             wee (array):  Weight matrix"""
 
@@ -383,31 +336,29 @@ def structural_plasticity(wee: np.array):
     @staticmethod
     def initialize_plasticity():
         """Initialize weight matrices for plasticity phase based on network configuration
-
         Args:
             kwargs (self.__dict__): All arguments are inherited from Sorn attributes
-
         Returns:
             tuple(array): Weight matrices WEI, WEE, WIE and threshold matrices Te, Ti and Initial state vectors X,Y """
 
         sorn_init = Sorn()
         WEE_init = sorn_init.initialize_weight_matrix(
-            network_type=Sorn._network_type_ee,
+            network_type=Sorn.network_type_ee,
             synaptic_connection="EE",
             self_connection="False",
-            lambd_w=Sorn._lambda_ee,
+            lambd_w=Sorn.lambda_ee,
         )
         WEI_init = sorn_init.initialize_weight_matrix(
-            network_type=Sorn._network_type_ei,
+            network_type=Sorn.network_type_ei,
             synaptic_connection="EI",
             self_connection="False",
-            lambd_w=Sorn._lambda_ei,
+            lambd_w=Sorn.lambda_ei,
         )
         WIE_init = sorn_init.initialize_weight_matrix(
-            network_type=Sorn._network_type_ie,
+            network_type=Sorn.network_type_ie,
             synaptic_connection="IE",
             self_connection="False",
-            lambd_w=Sorn._lambda_ie,
+            lambd_w=Sorn.lambda_ie,
         )
 
         Wee_init = Initializer.zero_sum_incoming_check(WEE_init)
@@ -433,10 +384,10 @@ def initialize_plasticity():
         normalized_wie = Initializer.normalize_weight_matrix(Wie_init)
 
         te_init, ti_init = sorn_init.initialize_threshold_matrix(
-            Sorn._te_min, Sorn._te_max, Sorn._ti_min, Sorn._ti_max
+            Sorn.te_min, Sorn.te_max, Sorn.ti_min, Sorn.ti_max
         )
         x_init, y_init = sorn_init.initialize_activity_vector(
-            Sorn._ne, Sorn._ni)
+            Sorn.ne, Sorn.ni)
 
         # Initializing variables from sorn_initialize.py
 
@@ -453,12 +404,9 @@ def initialize_plasticity():
 
 class MatrixCollection(Sorn):
     """Collect all matrices initialized and updated during simulation (plasiticity and training phases)
-
     Args:
         phase (str): Training or Plasticity phase
-
         matrices (dict): Network activity, threshold and connection matrices
-
     Returns:
         MatrixCollection instance"""
 
@@ -469,7 +417,7 @@ def __init__(self, phase: str, matrices: dict = None):
         self.matrices = matrices
         if self.phase == "plasticity" and self.matrices == None:
 
-            self.time_steps = Sorn._time_steps + 1  # Total training steps
+            self.time_steps = Sorn.time_steps + 1  # Total training steps
             self.Wee, self.Wei, self.Wie, self.Te, self.Ti, self.X, self.Y = (
                 [0] * self.time_steps,
                 [0] * self.time_steps,
@@ -492,7 +440,7 @@ def __init__(self, phase: str, matrices: dict = None):
 
         elif self.phase == "plasticity" and self.matrices != None:
 
-            self.time_steps = Sorn._time_steps + 1  # Total training steps
+            self.time_steps = Sorn.time_steps + 1  # Total training steps
             self.Wee, self.Wei, self.Wie, self.Te, self.Ti, self.X, self.Y = (
                 [0] * self.time_steps,
                 [0] * self.time_steps,
@@ -514,7 +462,7 @@ def __init__(self, phase: str, matrices: dict = None):
         elif self.phase == "training":
 
             # NOTE:time_steps here is diferent for plasticity and training phase
-            self.time_steps = Sorn._time_steps + 1  # Total training steps
+            self.time_steps = Sorn.time_steps + 1  # Total training steps
             self.Wee, self.Wei, self.Wie, self.Te, self.Ti, self.X, self.Y = (
                 [0] * self.time_steps,
                 [0] * self.time_steps,
@@ -535,16 +483,11 @@ def __init__(self, phase: str, matrices: dict = None):
 
     def weight_matrix(self, wee: np.array, wei: np.array, wie: np.array, i: int):
         """Update weight matrices
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wei (array): Inhibitory-Excitatory weight matrix
-
             wie (array): Excitatory-Inhibitory weight matrix
-
             i (int): Time step
-
         Returns:
             tuple (array): Weight Matrices Wee, Wei, Wie"""
 
@@ -556,12 +499,9 @@ def weight_matrix(self, wee: np.array, wei: np.array, wie: np.array, i: int):
 
     def threshold_matrix(self, te: np.array, ti: np.array, i: int):
         """Update threshold matrices
-
         Args:
             te (array): Excitatory threshold
-
             ti (array): Inhibitory threshold
-
             i (int): Time step
         Returns:
             tuple (array): Threshold Matrices Te and Ti"""
@@ -574,14 +514,10 @@ def network_activity_t(
         self, excitatory_net: np.array, inhibitory_net: np.array, i: int
     ):
         """Network state at current time step
-
         Args:
             excitatory_net (array): Excitatory network activity
-
             inhibitory_net (array): Inhibitory network activity
-
             i (int): Time step
-
         Returns:
             tuple (array): Updated Excitatory and Inhibitory states
         """
@@ -593,14 +529,10 @@ def network_activity_t(
 
     def network_activity_t_1(self, x: np.array, y: np.array, i: int):
         """Network activity at previous time step
-
         Args:
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             i (int): Time step
-
         Returns:
             tuple (array): Previous Excitatory and Inhibitory states
         """
@@ -614,33 +546,28 @@ def network_activity_t_1(self, x: np.array, y: np.array, i: int):
 class NetworkState(Plasticity):
 
     """The evolution of network states
-
     Args:
         v_t (array): External input/stimuli
-
     Returns:
         instance (object): NetworkState instance"""
 
     def __init__(self, v_t: np.array):
         super().__init__()
         self.v_t = v_t
-        assert Sorn._nu == len(
+        assert Sorn.nu == len(
             self.v_t
         ), "Input units and input size mismatch: {} != {}".format(
-            Sorn._nu, len(self.v_t)
+            Sorn.nu, len(self.v_t)
         )
-        if Sorn._nu != Sorn._ne:
-            self.v_t = list(self.v_t) + [0.0] * (Sorn._ne - Sorn._nu)
+        if Sorn.nu != Sorn.ne:
+            self.v_t = list(self.v_t) + [0.0] * (Sorn.ne - Sorn.nu)
         self.v_t = np.expand_dims(self.v_t, 1)
 
     def incoming_drive(self, weights: np.array, activity_vector: np.array):
         """Excitatory Post synaptic potential towards neurons in the reservoir in the absence of external input
-
         Args:
             weights (array): Synaptic strengths
-
             activity_vector (list): Acitivity of inhibitory or Excitatory neurons
-
         Returns:
             incoming (array): Excitatory Post synaptic potential towards neurons
         """
@@ -658,20 +585,13 @@ def excitatory_network_state(
         white_noise_e: np.array,
     ):
         """Activity of Excitatory neurons in the network
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wei (array): Inhibitory-Excitatory weight matrix
-
             te (array): Excitatory threshold
-
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             white_noise_e (array): Gaussian noise
-
         Returns:
             x (array): Current Excitatory network activity
         """
@@ -703,24 +623,18 @@ def inhibitory_network_state(
         self, wie: np.array, ti: np.array, y: np.array, white_noise_i: np.array
     ):
         """Activity of Excitatory neurons in the network
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wie (array): Excitatory-Inhibitory weight matrix
-
             ti (array): Inhibitory threshold
-
             y (array): Inhibitory network activity
-
             white_noise_i (array): Gaussian noise
-
         Returns:
             y (array): Current Inhibitory network activity"""
 
         wie = np.asarray(wie)
         yt = y[:, 1]
-        yt = yt.reshape(Sorn._ne, 1)
+        yt = yt.reshape(Sorn.ne, 1)
 
         incoming_drive_e = np.expand_dims(
             self.incoming_drive(weights=wie, activity_vector=yt), 1
@@ -742,20 +656,13 @@ def recurrent_drive(
         white_noise_e: np.array,
     ):
         """Network state due to recurrent drive received by the each unit at time t+1. Activity of Excitatory neurons without external stimuli
-
         Args:
             wee (array): Excitatory-Excitatory weight matrix
-
             wei (array): Inhibitory-Excitatory weight matrix
-
             te (array): Excitatory threshold
-
             x (array): Excitatory network activity
-
             y (array): Inhibitory network activity
-
             white_noise_e (array): Gaussian noise
-
         Returns:
             xt (array): Recurrent network state
         """
@@ -783,27 +690,17 @@ def recurrent_drive(
 class Simulator_(Sorn):
 
     """Simulate SORN using external input/noise using the fresh or pretrained matrices
-
     Args:
         inputs (np.array, optional): External stimuli. Defaults to None.
-
         phase (str, optional): Plasticity phase. Defaults to "plasticity".
-
         matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
         time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
         noise (bool, optional): If True, noise will be added. Defaults to True.
-
     Returns:
         plastic_matrices (dict): Network states, connections and threshold matrices
-
         X_all (array): Excitatory network activity collected during entire simulation steps
-
         Y_all (array): Inhibitory network activity collected during entire simulation steps
-
         R_all (array): Recurrent network activity collected during entire simulation steps
-
         frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
     def __init__(self):
@@ -821,29 +718,18 @@ def simulate_sorn(
         **kwargs
     ):
         """Simulation/Plasticity phase
-
         Args:
             inputs (np.array, optional): External stimuli. Defaults to None.
-
             phase (str, optional): Plasticity phase. Defaults to "plasticity"
-
             matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
             time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
             noise (bool, optional): If True, noise will be added. Defaults to True.
-
             freeze (list, optional): List of synaptic plasticity mechanisms which will be turned off during simulation. Defaults to None.
-
         Returns:
             plastic_matrices (dict): Network states, connections and threshold matrices
-
             X_all (array): Excitatory network activity collected during entire simulation steps
-
             Y_all (array): Inhibitory network activity collected during entire simulation steps
-
             R_all (array): Recurrent network activity collected during entire simulation steps
-
             frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
         assert (
@@ -851,35 +737,35 @@ def simulate_sorn(
         ), "Phase can be either 'plasticity' or 'training'"
 
         self.time_steps = time_steps
-        Sorn._time_steps = time_steps
+        Sorn.time_steps = time_steps
         self.phase = phase
         self.matrices = matrices
         self.freeze = [] if freeze == None else freeze
 
         kwargs_ = [
-            "_ne",
-            "_nu",
-            "_network_type_ee",
-            "_network_type_ei",
-            "_network_type_ie",
-            "_lambda_ee",
-            "_lambda_ei",
-            "_lambda_ie",
-            "_eta_stdp",
-            "_eta_inhib",
-            "_eta_ip",
-            "_te_max",
-            "_ti_max",
-            "_ti_min",
-            "_te_min",
-            "_mu_ip",
-            "_sigma_ip",
+            "ne",
+            "nu",
+            "network_type_ee",
+            "network_type_ei",
+            "network_type_ie",
+            "lambda_ee",
+            "lambda_ei",
+            "lambda_ie",
+            "eta_stdp",
+            "eta_inhib",
+            "eta_ip",
+            "te_max",
+            "ti_max",
+            "ti_min",
+            "te_min",
+            "mu_ip",
+            "sigma_ip",
         ]
         for key, value in kwargs.items():
             if key in kwargs_:
                 setattr(Sorn, key, value)
-        # assert Sorn._nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
-        Sorn._ni = int(0.2 * Sorn._ne)
+        # assert Sorn.nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
+        Sorn.ni = int(0.2 * Sorn.ne)
 
         # Initialize/Get the weight, threshold matrices and activity vectors
         matrix_collection = MatrixCollection(
@@ -898,10 +784,10 @@ def simulate_sorn(
 
             if noise:
                 white_noise_e = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ne
+                    mu=0.0, sigma=0.04, t=Sorn.ne
                 )
                 white_noise_i = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ni
+                    mu=0.0, sigma=0.04, t=Sorn.ni
                 )
             else:
                 white_noise_e, white_noise_i = 0.0, 0.0
@@ -912,10 +798,10 @@ def simulate_sorn(
 
             # Buffers to get the resulting x and y vectors at the current time step and update the master matrix
             x_buffer, y_buffer = np.zeros(
-                (Sorn._ne, 2)), np.zeros((Sorn._ni, 2))
+                (Sorn.ne, 2)), np.zeros((Sorn.ni, 2))
 
             te_buffer, ti_buffer = np.zeros(
-                (Sorn._ne, 1)), np.zeros((Sorn._ni, 1))
+                (Sorn.ne, 1)), np.zeros((Sorn.ni, 1))
 
             Wee, Wei, Wie = (
                 matrix_collection.Wee,
@@ -1002,29 +888,18 @@ def simulate_sorn(
 
 class Trainer_(Sorn):
     """Train the network with the fresh or pretrained network matrices and external stimuli
-
     Args:
         inputs (np.array, optional): External stimuli. Defaults to None.
-
         phase (str, optional): Training phase. Defaults to "training".
-
         matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
         time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
         noise (bool, optional): If True, noise will be added. Defaults to True.
-
         freeze (list, optional): List of synaptic plasticity mechanisms which will be turned off during simulation. Defaults to None.
-
     Returns:
         plastic_matrices (dict): Network states, connections and threshold matrices
-
         X_all (array): Excitatory network activity collected during entire simulation steps
-
         Y_all (array): Inhibitory network activity collected during entire simulation steps
-
         R_all (array): Recurrent network activity collected during entire simulation steps
-
         frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
     def __init__(self):
@@ -1042,27 +917,17 @@ def train_sorn(
         **kwargs
     ):
         """Train the network with the fresh or pretrained network matrices and external stimuli
-
         Args:
             inputs (np.array, optional): External stimuli. Defaults to None.
-
             phase (str, optional): Training phase. Defaults to "training".
-
             matrices (dict, optional): Network states, connections and threshold matrices. Defaults to None.
-
             time_steps (int, optional): Total number of time steps to simulate the network. Defaults to 1.
-
             noise (bool, optional): If True, noise will be added. Defaults to True.
-
         Returns:
             plastic_matrices (dict): Network states, connections and threshold matrices
-
             X_all (array): Excitatory network activity collected during entire simulation steps
-
             Y_all (array): Inhibitory network activity collected during entire simulation steps
-
             R_all (array): Recurrent network activity collected during entire simulation steps
-
             frac_pos_active_conn (list): Number of positive connection strengths in the network at each time step during simulation"""
 
         assert (
@@ -1070,34 +935,34 @@ def train_sorn(
         ), "Phase can be either 'plasticity' or 'training'"
 
         kwargs_ = [
-            "_ne",
-            "_nu",
-            "_network_type_ee",
-            "_network_type_ei",
-            "_network_type_ie",
-            "_lambda_ee",
-            "_lambda_ei",
-            "_lambda_ie",
-            "_eta_stdp",
-            "_eta_inhib",
-            "_eta_ip",
-            "_te_max",
-            "_ti_max",
-            "_ti_min",
-            "_te_min",
-            "_mu_ip",
-            "_sigma_ip",
+            "ne",
+            "nu",
+            "network_type_ee",
+            "network_type_ei",
+            "network_type_ie",
+            "lambda_ee",
+            "lambda_ei",
+            "lambda_ie",
+            "eta_stdp",
+            "eta_inhib",
+            "eta_ip",
+            "te_max",
+            "ti_max",
+            "ti_min",
+            "te_min",
+            "mu_ip",
+            "sigma_ip",
         ]
         for key, value in kwargs.items():
             if key in kwargs_:
                 setattr(Sorn, key, value)
-        Sorn._ni = int(0.2 * Sorn._ne)
-        # assert Sorn._nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
+        Sorn.ni = int(0.2 * Sorn.ne)
+        # assert Sorn.nu == len(inputs[:,0]),"Size mismatch: Input != Nu "
 
         self.phase = phase
         self.matrices = matrices
         self.time_steps = time_steps
-        Sorn._time_steps = time_steps
+        Sorn.time_steps = time_steps
         self.inputs = np.asarray(inputs)
         self.freeze = [] if freeze == None else freeze
 
@@ -1114,10 +979,10 @@ def train_sorn(
 
             if noise:
                 white_noise_e = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ne
+                    mu=0.0, sigma=0.04, t=Sorn.ne
                 )
                 white_noise_i = Initializer.white_gaussian_noise(
-                    mu=0.0, sigma=0.04, t=Sorn._ni
+                    mu=0.0, sigma=0.04, t=Sorn.ni
                 )
             else:
                 white_noise_e = 0.0
@@ -1129,9 +994,9 @@ def train_sorn(
 
             # Buffers to get the resulting x and y vectors at the current time step and update the master matrix
             x_buffer, y_buffer = np.zeros(
-                (Sorn._ne, 2)), np.zeros((Sorn._ni, 2))
+                (Sorn.ne, 2)), np.zeros((Sorn.ni, 2))
             te_buffer, ti_buffer = np.zeros(
-                (Sorn._ne, 1)), np.zeros((Sorn._ni, 1))
+                (Sorn.ne, 1)), np.zeros((Sorn.ni, 1))
 
             Wee, Wei, Wie = (
                 matrix_collection.Wee,
@@ -1221,4 +1086,4 @@ def train_sorn(
 Trainer = Trainer_()
 Simulator = Simulator_()
 if __name__ == "__main__":
-    pass
+    pass
\ No newline at end of file
diff --git a/sorn/utils.py b/sorn/utils.py
index 070cbea..85a230b 100644
--- a/sorn/utils.py
+++ b/sorn/utils.py
@@ -424,7 +424,7 @@ def __init__(self):
     def hist_incoming_conn(
         weights: np.array, bin_size: int, histtype: str, savefig: bool
     ):
-        """Plot the histogram of number of incoming connections per neuron
+        """Plot the histogram of number of presynaptic connections per neuron
 
         Args:
             weights (array): Connection weights
@@ -438,36 +438,30 @@ def hist_incoming_conn(
         Returns:
             plot (matplotlib.pyplot): plot object
         """
-
-        # Plot the histogram of distribution of number of incoming connections in the network
-
         num_incoming_weights = np.sum(np.array(weights) > 0, axis=0)
 
         plt.figure(figsize=(12, 5))
-
-        plt.title("Number of incoming connections")
         plt.xlabel("Number of connections")
-        plt.ylabel("Count")
-        plt.hist(num_incoming_weights, bins=bin_size, histtype=histtype)
-
-        # Empirical average and variance are computed
-        avg = np.mean(num_incoming_weights)
-        var = np.var(num_incoming_weights)
-        # From hist plot above, it is clear that connection count follow gaussian distribution
-        pdf_x = np.linspace(
-            np.min(num_incoming_weights), np.max(num_incoming_weights), 100
-        )
-        pdf_y = 1.0 / np.sqrt(2 * np.pi * var) * np.exp(-0.5 * (pdf_x - avg) ** 2 / var)
+        plt.ylabel("Probability")
 
-        plt.plot(pdf_x, pdf_y, "k--", label="Gaussian fit")
-        plt.axvline(x=avg, color="r", linestyle="--", label="Mean")
-        plt.legend()
+        # Fit a normal distribution to the data
+        mu, std = norm.fit(num_incoming_weights)
+        plt.hist(num_incoming_weights, bins=bin_size, density=True, alpha=0.6, color='b')
+
+        # PDF
+        xmin, xmax = plt.xlim()
+        x = np.linspace(xmin, xmax, max(num_incoming_weights))
+        p = norm.pdf(x, mu, std)
+        plt.plot(x, p, 'k', linewidth=2)
+        title = "Distribution of presynaptic connections: mu = %.2f,  std = %.2f" % (mu, std)
+        plt.title(title)
 
         if savefig:
             plt.savefig("hist_incoming_conn")
 
         return plt.show()
 
+
     @staticmethod
     def hist_outgoing_conn(
         weights: np.array, bin_size: int, histtype: str, savefig: bool
@@ -491,23 +485,20 @@ def hist_outgoing_conn(
         num_outgoing_weights = np.sum(np.array(weights) > 0, axis=1)
 
         plt.figure(figsize=(12, 5))
-
-        plt.hist(num_outgoing_weights, bins=bin_size, histtype=histtype)
-        plt.title("Number of Outgoing connections")
         plt.xlabel("Number of connections")
-        plt.ylabel("Count")
-        # Empirical average and variance are computed
-        avg = np.mean(num_outgoing_weights)
-        var = np.var(num_outgoing_weights)
+        plt.ylabel("Probability")
 
-        pdf_x = np.linspace(
-            np.min(num_outgoing_weights), np.max(num_outgoing_weights), 100
-        )
-        pdf_y = 1.0 / np.sqrt(2 * np.pi * var) * np.exp(-0.5 * (pdf_x - avg) ** 2 / var)
+        # Fit a normal distribution to the data
+        mu, std = norm.fit(num_outgoing_weights)
+        plt.hist(num_outgoing_weights, bins=bin_size, density=True, alpha=0.6, color='b')
 
-        plt.plot(pdf_x, pdf_y, "k--", label="Gaussian fit")
-        plt.axvline(x=avg, color="r", linestyle="--", label="Mean")
-        plt.legend()
+        # PDF
+        xmin, xmax = plt.xlim()
+        x = np.linspace(xmin, xmax, max(num_outgoing_weights))
+        p = norm.pdf(x, mu, std)
+        plt.plot(x, p, 'k', linewidth=2)
+        title = "Distribution of post synaptic connections: mu = %.2f,  std = %.2f" % (mu, std)
+        plt.title(title)
 
         if savefig:
             plt.savefig("hist_outgoing_conn")
@@ -516,17 +507,13 @@ def hist_outgoing_conn(
 
     @staticmethod
     def network_connection_dynamics(
-        connection_counts: np.array, initial_steps: int, final_steps: int, savefig: bool
+        connection_counts: np.array, savefig: bool
     ):
         """Plot number of positive connection in the excitatory pool
 
         Args:
             connection_counts (array) - 1D Array of number of connections in the network per time step
 
-            initial_steps (int) - Plot for initial steps
-
-            final_steps (int) - Plot for final steps
-
             savefig (bool) - If True plot will be saved as png file in the cwd
 
         Returns:
@@ -545,30 +532,6 @@ def network_connection_dynamics(
         plt.legend(loc="upper right")
         plt.tight_layout()
 
-        # Inset plot for initial simulation steps
-
-        ax2 = plt.axes([0, 0, 1, 1])
-
-        # Set the position and relative size of the inset axes within ax1
-        ip = InsetPosition(ax1, [0.25, 0.4, 0.3, 0.3])
-        ax2.set_axes_locator(ip)
-        ax2.plot(connection_counts[0:initial_steps])
-        plt.margins(x=0)
-        ax2.set_title("Initial %s time steps of Decay Phase" % initial_steps)
-        ax2.set_xticks(ax2.get_xticks()[::2])
-
-        # End Inset plot
-        ax3 = plt.axes([0, 0, 0, 0])
-
-        # Set the position and relative size of the inset axes within ax1
-        ip1 = InsetPosition(ax1, [0.6, 0.4, 0.3, 0.3])
-        ax3.set_axes_locator(ip1)
-        # Plot the last 10000 time steps
-        ax3.plot(connection_counts[-final_steps:])
-        plt.margins(x=0)
-        ax3.set_title("Final %s time steps of Stable Phase" % final_steps)
-        ax3.set_xticks(ax3.get_xticks()[::1])
-
         if savefig:
             plt.savefig("connection_dynamics")
 
@@ -631,9 +594,9 @@ def scatter_plot(spike_train: np.array, savefig: bool):
         plt.legend(loc="upper left")
 
         plt.scatter(y, x, s=0.1, color="black")
-
-        plt.xlabel("Time(ms)")
-        plt.ylabel("Neuron #")
+        plt.title('Spike Trains')
+        plt.xlabel("Time step")
+        plt.ylabel("Neuron")
         plt.legend(loc="upper left")
 
         if savefig:
@@ -663,13 +626,13 @@ def raster_plot(spike_train: np.array, savefig: bool):
         firing_rates = Statistics.firing_rate_network(spike_train).tolist()
         plt.plot(firing_rates, label="Firing rate")
         plt.legend(loc="upper left")
-
+        plt.title('Spike Trains')
         # Get the indices where spike_train is 1
         x, y = np.argwhere(spike_train.T == 1).T
 
         plt.plot(y, x, "|r")
-        plt.xlabel("Time(ms)")
-        plt.ylabel("Neuron #")
+        plt.xlabel("Time step")
+        plt.ylabel("Neuron")
 
         if savefig:
             plt.savefig("RasterSpikeTrain.png")
@@ -698,7 +661,7 @@ def correlation(corr: np.array, savefig: bool):
         # Custom diverging colormap
         cmap = sns.diverging_palette(220, 10, as_cmap=True)
 
-        sns.heatmap(
+        ax = sns.heatmap(
             corr,
             mask=mask,
             cmap=cmap,
@@ -710,6 +673,10 @@ def correlation(corr: np.array, savefig: bool):
             linewidths=0.0,
             cbar_kws={"shrink": 0.9},
         )
+        plt.title('Pearson correlation between neurons', fontsize = 20)
+        plt.xlabel('Neurons', fontsize = 15)
+        plt.ylabel('Neurons', fontsize = 15)
+
         if savefig:
             plt.savefig("Correlation between neurons")
         return None
@@ -724,7 +691,7 @@ def isi_exponential_fit(
         Args:
             spike_train (array): Array of spike trains
 
-            neuron (int): If True, firing rate of the network will be plotted
+            neuron (int): Target neuron
 
             bin_size (int): Spike train will be splitted into bins of size bin_size
 
@@ -733,11 +700,8 @@ def isi_exponential_fit(
         Returns:
             plot object"""
 
-        spike_time = Statistics.spike_times(
-            spike_train.T[neuron]
-        )  # Locate the spike time of the target neuron
 
-        isi = Statistics.spike_time_intervals(spike_time)
+        isi = Statistics.spike_time_intervals(spike_train[:,neuron])
 
         y, x = np.histogram(sorted(isi), bins=bin_size)
 
@@ -755,8 +719,9 @@ def exponential_func(y, a, b, c):
             exponential_func(x[1:bin_size], *popt),
             label="Exponential fit",
         )
+        plt.title('Distribution of Inter Spike Intervals and Exponential Curve Fit')
         plt.scatter(x[1:bin_size], y[1:bin_size], s=2.0, color="black", label="ISI")
-        plt.xlabel("ISI(time step)")
+        plt.xlabel("ISI")
         plt.ylabel("Frequency")
         plt.legend()
 
@@ -783,13 +748,13 @@ def weight_distribution(weights: np.array, bin_size: int, savefig: bool):
             weights >= 0.01
         ]  # Remove the weight values less than 0.01 # As reported in article SORN 2013
         y, x = np.histogram(weights, bins=bin_size)  # Create histogram with bin_size
-
+        plt.title('Synaptic weight distribution')
         plt.scatter(x[:-1], y, s=2.0, c="black")
-        plt.xlabel("Weight")
+        plt.xlabel("Connection strength")
         plt.ylabel("Frequency")
 
         if savefig:
-            plt.savefig("weight distribution")
+            plt.savefig("weight_distribution")
 
         return plt.show()
 
@@ -808,15 +773,16 @@ def linear_lognormal_fit(weights: np.array, num_points: int, savefig: bool):
         Returns:
             plot object"""
 
-        X = weights.copy()
+        weights = np.array(weights.tolist())
+        weights = weights[weights >= 0.01]
 
-        M = float(np.mean(X))  # Geometric mean
-        s = float(np.std(X))  # Geometric standard deviation
+        M = float(np.mean(weights))  # Geometric mean
+        s = float(np.std(weights))  # Geometric standard deviation
 
         # Lognormal distribution parameters
 
-        mu = float(np.mean(np.log(X)))  # Mean of log(X)
-        sigma = float(np.std(np.log(X)))  # Standard deviation of log(X)
+        mu = float(np.mean(np.log(weights)))  # Mean of log(X)
+        sigma = float(np.std(np.log(weights)))  # Standard deviation of log(X)
         shape = sigma  # Scipy's shape parameter
         scale = np.exp(mu)  # Scipy's scale parameter
         median = np.exp(mu)
@@ -832,7 +798,7 @@ def linear_lognormal_fit(weights: np.array, num_points: int, savefig: bool):
         )
 
         plt.figure(figsize=(12, 4.5))
-
+        plt.title('Curve fit on connection weight distribution')
         # Figure on linear scale
         plt.subplot(121)
         plt.plot(x, pdf)
@@ -1117,8 +1083,7 @@ def spike_time_intervals(spike_train):
         """
 
         spike_times = Statistics.spike_times(spike_train)
-        # isi = sorted(np.diff(spike_times)[-1])
-        isi = np.diff(spike_times)[-1]
+        isi = np.diff(spike_times[-1])
         return isi
 
     @staticmethod


Test patch:
diff --git a/test_sorn.py b/test_sorn.py
index f7632d8..3cbe7df 100644
--- a/test_sorn.py
+++ b/test_sorn.py
@@ -20,7 +20,7 @@
 sequence_input = np.random.rand(10, 1)
 
 # Overriding defaults: Sample input
-num_features = 4
+num_features = 10
 time_steps = 1000
 inputs = np.random.rand(num_features, time_steps)
 
@@ -32,9 +32,40 @@ def test_runsorn(self):
             Simulator.simulate_sorn(
                 inputs=simulation_inputs,
                 phase="plasticity",
-                matrices=matrices_dict,
+                matrices=None,
                 time_steps=2,
                 noise=True,
+                nu=num_features
+            ),
+        )
+        self.assertRaises(
+            Exception,
+            Simulator.simulate_sorn(
+                inputs=simulation_inputs,
+                phase="plasticity",
+                matrices=matrices_dict,
+                time_steps=2,
+                noise=False,
+            ),
+        )
+        self.assertRaises(
+            Exception,
+            Simulator.simulate_sorn(
+                inputs=simulation_inputs,
+                phase="plasticity",
+                matrices=matrices_dict,
+                time_steps=2,
+                noise=False, freeze=['ip']
+            ),
+        )
+        self.assertRaises(
+            Exception,
+            Simulator.simulate_sorn(
+                inputs=simulation_inputs,
+                phase="plasticity",
+                matrices=matrices_dict,
+                time_steps=2,
+                noise=False, freeze=['stdp,istdp','ss','sp']
             ),
         )
         self.assertRaises(
@@ -64,7 +95,7 @@ def test_runsorn(self):
                 phase="training",
                 matrices=matrices_dict,
                 time_steps=1,
-                noise=True,
+                noise=True, freeze=['stdp,istdp','ss','sp']
             ),
         )
         self.assertRaises(
@@ -75,10 +106,10 @@ def test_runsorn(self):
                 matrices=None,
                 noise=True,
                 time_steps=time_steps,
-                _ne=26,
-                _lambda_ee=4,
-                _lambda_ei=4,
-                _nu=num_features,
+                ne=26,
+                lambda_ee=4,
+                lambda_ei=4,
+                nu=num_features,
             ),
         )
 
@@ -90,10 +121,10 @@ def test_runsorn(self):
                 matrices=None,
                 noise=True,
                 time_steps=time_steps,
-                _ne=40,
-                _lambda_ee=5,
-                _lambda_ei=5,
-                _nu=num_features,
+                ne=40,
+                lambda_ee=5,
+                lambda_ei=5,
+                nu=num_features,
             ),
         )
 
@@ -114,8 +145,6 @@ def test_plotter(self):
             Exception,
             Plotter.network_connection_dynamics(
                 connection_counts=num_active_connections,
-                initial_steps=10,
-                final_steps=10,
                 savefig=False,
             ),
         )