/* 
    Autogenerated using:
    - Template: 'src/ext/models/model.cu.mako'
    - Model definition: 'codegen/recipes/rwwex.yaml'
    Do not modify this autogenerated code. Instead modify template
    or model definition.
*/
#include "cubnm/includes.cuh"
#include "cubnm/defines.h"
#include "cubnm/models/rwwex.cuh"

__device__ __NOINLINE__ void rWWExModel::init(
    double* _state_vars, double* _intermediate_vars,
    double* _global_params, double* _regional_params,
    int* _ext_int, bool* _ext_bool,
    int* _ext_int_shared, bool* _ext_bool_shared
) {
    // S = 0.001
    _state_vars[2] = 0.001;
}

__device__ __NOINLINE__ void rWWExModel::restart(
    double* _state_vars, double* _intermediate_vars, 
    double* _global_params, double* _regional_params,
    int* _ext_int, bool* _ext_bool,
    int* _ext_int_shared, bool* _ext_bool_shared
) {
    // S = 0.001
    _state_vars[2] = 0.001;
}

__device__ void rWWExModel::step(
        double* _state_vars, double* _intermediate_vars,
        double* _global_params, double* _regional_params,
        double& tmp_globalinput,
        double* noise, long& noise_idx
        ) {
    // Calculate total input
    // x = w * J_N * S + G * J_N * globalinput + I0
    _state_vars[0] = _regional_params[0] * d_rWWExc.J_N * _state_vars[2] + _global_params[0] * d_rWWExc.J_N * tmp_globalinput + _regional_params[1];

    // Input-output function
    // axb = a * x - b
    _intermediate_vars[0] = d_rWWExc.a * _state_vars[0] - d_rWWExc.b;
    // r = axb / (1 - exp(-d * axb))
    _state_vars[1] = _intermediate_vars[0] / (1 - exp(-d_rWWExc.d * _intermediate_vars[0]));

    // Synaptic dynamics with noise
    // dS = dt_gamma * ((1 - S) * r) - dt_itau * S + noise * sqrt_dt * sigma
    _intermediate_vars[1] = d_rWWExc.dt_gamma * ((1 - _state_vars[2]) * _state_vars[1]) - d_rWWExc.dt_itau * _state_vars[2] + noise[noise_idx] * d_rWWExc.sqrt_dt * _regional_params[2];
    // S += dS
    _state_vars[2] += _intermediate_vars[1];

    // Clip S to valid range [0, 1]
    // S = max(0.0, min(1.0, S))
    _state_vars[2] = max(0.0, min(1.0, _state_vars[2]));
}
