## Simulation Notes
## Modelling
### 1. State Variables
A state variable is one of the set of variables that are used to describe the mathematical "state" of a dynamical system. ([Wikipedia](https://en.wikipedia.org/wiki/State_variable))
**Time** as a system state
* 1 **timestep** == 1 minute
### 2. System Parameters
System parameterization is the process of choosing variables that impact the behaviour of the model. These parameters allow us to perform simulation techniques like parameter sweeps, Monte Carlo simulations, A/B tests, and see how the system behaves under a different model parameter set.
### 3. Policy Functions
A Policy Function computes one or more signals to be passed to State Update Functions. They describe the logic and behaviour of a system component or mechanism. Adapting to use **policy functions** to drive the process, and **state update functions** to update the state according to the **differential specification**.
An illustrative example:
```python
condition = True
def policy_function(params, substep, state_history, previous_state):
'''
This logic belongs in the policy function,
but could also have been placed directly in the state update function.
'''
signal_value = 1 if condition else 0
return {'signal_name': signal_value}
```
```python
def state_update_function(params, substep, state_history, previous_state, policy_input):
state_value = policy_input['signal_name']
return 'state_name', state_value
```
### 4. State Update Functions
We create State Update Functions to design the way our model state changes over time. These will usually represent the system differential specification.
```python
def state_update_function(params, substep, state_history, previous_state, policy_input):
variable_value = 0
return 'variable_name', variable_value
```
### 5. Partial State Update Blocks
A series of Partial State Update Blocks is a structure for composing State Update Functions and Policy Functions in series or parallel, as a representation of the system model.
## Simulation
### 6. Configuration
The configuration stage is about tying all the previous model components together and choosing how the simulation should run.
Configuration parameters:
* `'N': 1` - the number of times we'll run the simulation (you'll see them called "Monte Carlo runs" later in the course, when we look at tools to analyze system models)
* `'T': range(400)` - the number of timesteps the simulation will run for
* `'M': system_params` - the parameters of the system
### 7. Execution
The Execution Engine takes a model and configuration, and computes the simulation output.
### 8. Simulation Output Preparation
The simulation results are returned as a list of Python dictionaries, which we then convert to a Pandas dataframe. At this stage of the process you'll manipulate and analyze your results to answer questions about your model.
### 9. Simulation Analysis
#
## Example
\begin{align}
\large population_t &\large= population_{t-1} + {\Delta population} \quad \textrm{(sheep)} \tag{1} \\
\large food_t &\large= food_{t-1} + {\Delta food} \quad \textrm{(tons of grass)} \tag{2}
\end{align}
where the rate of change ($\Delta$) is:
\begin{align}
\large {\Delta population} &\large= \alpha * food_{t-1} - \epsilon * population_{t-1} \quad \textrm{(sheep/month)} \\
\large {\Delta food} &\large= -\beta * population_{t-1} + \gamma \quad \textrm{(tons of grass/month)}
\end{align}
where:
*$*
\begin{align}
\alpha: \quad &\textrm{'reproduction_rate'}\\
\epsilon: \quad &\textrm{'death_rate'}\\
\beta: \quad &\textrm{'consumption_rate'}\\
\gamma: \quad &\textrm{'growth_rate'}\\
\end{align}
*$*
* A population consumes a food source, and reproduces at a rate proportional to the food source $\alpha$ (alpha), and dies at a rate proportional to the population size $\epsilon$ (epsilon).
* The food source is consumed at a rate proportional to the population $\beta$ (beta), and grows at a constant rate $\gamma$ (gamma).


## cadCAD Simulation Methods
### 1. Monte Carlo Method
> Monte Carlo methods, or Monte Carlo experiments, are a broad class of computational algorithms that rely on repeated random sampling to obtain numerical results. The underlying concept is to use randomness to solve problems that might be deterministic in principle.
Source: https://en.wikipedia.org/wiki/Monte_Carlo_method
### Non-determinism
> In computer science, a nondeterministic algorithm is an algorithm that, even for the same input, can exhibit different behaviors on different runs, as opposed to a deterministic algorithm.
Source: https://en.wikipedia.org/wiki/Nondeterministic_algorithm
\begin{align}
\large {\Delta food} &\large= -\beta * population_{t-1} + \gamma * rand() \quad \textrm{(tons of grass/month)} \\
\end{align}
* Addition of a random food growth rate, using `rand()`.
## 2. Parameter Sweeps
Parameter Sweeps are a valuable technique for exploring a wide range of system behaviors by varying input parameters.
## 3. A/B Testing
A/B Testing is a technique used to compare the performance of different model variants or configurations.

## System Requirements
### Requirements Analysis
Illustrative real-world model applications:
**1. Data Arrival**
Users send their transactions to the system.These transactions carry various amounts of data, measured in units of 'gas.' This influx of data is represented by 'D,' and it arrives continuously, much like a flowing river.
**2. Data Processing Rate**
The system is capable of processing a certain number of transactions per unit of time, symbolized as 'θ.' Imagine it as a factory's production rate, but for processing blockchain transactions.
**3. User Value**
As transactions enter the system, they brought value with them. The amount of value, 'V(D),' depend on the size of the transaction data. The larger the data, the more valuable the transaction is to the users. This relationship was described by 'V(D) = α * D,' where 'α' is a magical factor that determine the worth of each transaction.
**4. User Cost for Waiting**
However, users aren't infinitely patient. They incurr a cost if they have to wait for their transactions to be processed. The cost of waiting is denoted as 'Tu(Δt)' and is proportional to the time users have to wait. This cost, 'Tu(Δt) = β * Δt,' is a necessary inconvenience in the world of transactions.
**5. Prover Number**
To keep the system running smoothly, there are dedicated workers, provers, each with their unique capabilities. The number of provers is fixed at 'N.'
**6. Prover Efficiency**
What made the provers unique was their efficiency, represented by 'γi.' Some provers are highly efficient, while others are less so. Provers with higher 'γi' could process transactions quickly and cost-effectively, akin to master craftsmen.
**7. Cost and Delay**
The cost to prove a batch of data, 'Ci(D, i),' is determined by the size of the data and the efficiency of the prover. The larger the data and the more skilled the prover, the lower the cost.
Similarly, the time it takes to prove a batch, 'Ti(D, i),' is scaled by the efficiency of the prover.
**8. Proving Capacity:**
In the system, provers have a limited capacity within a given time interval. A prover with efficiency 'γi' could process 'γi * Δt' units of data during that time. It is like a clockwork mechanism.
**9. Prover Reliability**
Yet, even the most skilled artisans occasionally faced uncertainty. There is a small probability 'p' that any given prover might fail to complete a task.
### Questions
Why are we building the model?
### Assumptions
### Constraints / Scope
https://hackmd.io/@nilu/proverstrategy