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

// Static constants instance
rWWExModel::Constants rWWExModel::mc;

// Initialize constants based on dt
void rWWExModel::init_constants(double dt) {
    mc.dt = dt; // integration step
    mc.sqrt_dt = sqrt(mc.dt); // square root of integration step
    mc.J_N = 0.2609; // synaptic coupling
    mc.a = 270; // input-output function parameter a
    mc.b = 108; // input-output function parameter b
    mc.d = 0.154; // input-output function parameter d
    mc.gamma = (double)0.641/(double)1000.0; // kinetic parameter
    mc.tau = 100; // synaptic time constant
    mc.itau = 1.0/mc.tau; // inverse of tau (1/tau)
    mc.dt_itau = mc.dt * mc.itau;
    mc.dt_gamma = mc.dt * mc.gamma;
}

void rWWExModel::h_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;
}

void rWWExModel::_j_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;
}

void rWWExModel::h_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] * rWWExModel::mc.J_N * _state_vars[2] + _global_params[0] * rWWExModel::mc.J_N * tmp_globalinput + _regional_params[1];

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

    // Synaptic dynamics with noise
    // dS = dt_gamma * ((1 - S) * r) - dt_itau * S + noise * sqrt_dt * sigma
    _intermediate_vars[1] = rWWExModel::mc.dt_gamma * ((1 - _state_vars[2]) * _state_vars[1]) - rWWExModel::mc.dt_itau * _state_vars[2] + noise[noise_idx] * rWWExModel::mc.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]));
}
