GARCH11 with nonzero mean?

Is it possible to use the GATCH11 likelihood with nonzero mean? I want to implement the heteroscedastic variance, and am using a for loop in the model (I would use a scan, but I am unsure how to store the intermediate variables).

Any thoughts?

I’ve used Garch11 before on the sigma of a normal likelihood and then specified mu in the normal likelihood as it’s own linear regression.

How does one implement that?

It’s in an old/lost notebook. I’ll work on recreating it.

However I followed conceptually the stochastic volatility example as it’s not too dissimilar with a normal likelihood instead.

I’m getting quite a strange compilation error/haven’t tried to use GARCH since updating to PyMC v5.

pytensor_compilation_error_wk4j2kxk

Yeah I think the class needs to be extended to account for non-zero means.

i think it might be a separate bug - not sure, have you managed to use the garch distribution at all?

Can you share a minimal reproducible example? Also a longer error message?

Sure, no problem. I found this style of implementation worked in pymc3:

    import os
    
    import arviz as az
    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    import pymc as pm
    
    rng = np.random.RandomState(1234)
    az.style.use("arviz-darkgrid")
    
    
    try:
        returns = pd.read_csv(os.path.join("..", "data", "SP500.csv"), index_col="Date")
    except FileNotFoundError:
        returns = pd.read_csv(pm.get_data("SP500.csv"), index_col="Date")
    
    returns["change"] = np.log(returns["Close"]).diff()
    returns = returns.dropna()
    
    
    def make_garch_volatility_model(data):
        with pm.Model(coords={"time": data.index.values}) as model:
            omega= pm.Exponential('alpha_0', 30)
            alpha_1 = pm.Uniform('alpha_1', 0, 1 )
            upper = 1- alpha_1
            beta_1 = pm.Uniform("beta_1", 0, upper)
        
            initial_vol = pm.HalfNormal("init", 1)
            garch = pm.GARCH11("volatility", omega, alpha_1, beta_1, initial_vol, dims="time", observed=data["change"])
          
            returns = pm.Normal(
                "returns", mu= 0 , sigma=np.exp(garch/2), observed=data["change"], dims="time")
        return model
    
    
    garch_vol_model = make_garch_volatility_model(returns)
    
    with garch_vol_model:
        idata = pm.sample()
Error message

CompileError: Compilation failed (return status=1):
“C:\Users\Niall\anaconda3\envs\pymc5_env\Library\mingw-w64\bin\g++.exe” -shared -g -fwrapv -O2 -fno-strict-aliasing -Wno-c++11-narrowing -fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables -march=knl -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 -mno-sse4a -mcx16 -msahf -mmovbe -maes -msha -mpclmul -mpopcnt -mabm -mno-lwp -mfma -mno-fma4 -mno-xop -mbmi -mbmi2 -mno-tbm -mavx -mavx2 -msse4.2 -msse4.1 -mlzcnt -mno-rtm -mno-hle -mrdrnd -mf16c -mfsgsbase -mrdseed -mprfchw -madx -mfxsr -mxsave -mxsaveopt -mavx512f -mno-avx512er -mavx512cd -mno-avx512pf -mno-prefetchwt1 -mclflushopt -mxsavec -mxsaves -mavx512dq -mavx512bw -mavx512vl -mno-avx512ifma -mno-avx512vbmi -mclwb -mno-pcommit -mno-mwaitx --param l1-cache-size=48 --param l1-cache-line-size=64 --param l2-cache-size=12288 -mtune=generic -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION -m64 -DMS_WIN64 -I"C:\Users\Niall\anaconda3\envs\pymc5_env\Lib\site-packages\numpy\core\include" -I"C:\Users\Niall\anaconda3\envs\pymc5_env\include" -I"C:\Users\Niall\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\link\c\c_code" -L"C:\Users\Niall\anaconda3\envs\pymc5_env\libs" -L"C:\Users\Niall\anaconda3\envs\pymc5_env" -o “C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\scan_perform.pyd” “C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp” “C:\Users\Niall\anaconda3\envs\pymc5_env\python311.dll”
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp: In function ‘PyObject* __pyx_pf_6pytensor_4scan_12scan_perform_2perform(PyObject*, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, int, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, PyObject*, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, PyObject*, __Pyx_memviewslice, __Pyx_memviewslice, __Pyx_memviewslice, PyObject*, PyObject*, __Pyx_memviewslice, PyObject*, PyObject*, PyObject*, __Pyx_memviewslice, PyObject*)’:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:887:43: note: in definition of macro ‘likely’
#define likely(x) __builtin_expect(!!(x), 1)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1612:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:3572:19: note: in expansion of macro ‘__Pyx_GetItemInt’
__pyx_t_2 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 225, __pyx_L1_error)
^
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:887:43: note: in definition of macro ‘likely’
#define likely(x) __builtin_expect(!!(x), 1)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1612:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:3713:17: note: in expansion of macro ‘__Pyx_GetItemInt’
__pyx_t_2 = __Pyx_GetItemInt(__pyx_t_3, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 238, __pyx_L1_error)
^
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:888:43: note: in definition of macro ‘unlikely’
#define unlikely(x) __builtin_expect(!!(x), 0)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:11: note: in expansion of macro ‘likely’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1657:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:3800:20: note: in expansion of macro ‘__Pyx_SetItemInt’
if (unlikely(__Pyx_SetItemInt(__pyx_v_outer_outputs_idx, 0, __pyx_t_2, long, 1, __Pyx_PyInt_From_long, 0, 0, 0) < 0)) __PYX_ERR(0, 252, __pyx_L1_error)
^
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:887:43: note: in definition of macro ‘likely’
#define likely(x) __builtin_expect(!!(x), 1)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1612:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:3828:17: note: in expansion of macro ‘__Pyx_GetItemInt’
__pyx_t_2 = __Pyx_GetItemInt(__pyx_v_outer_outputs_idx, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 255, __pyx_L1_error)
^
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:888:43: note: in definition of macro ‘unlikely’
#define unlikely(x) __builtin_expect(!!(x), 0)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:11: note: in expansion of macro ‘likely’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1657:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:4103:22: note: in expansion of macro ‘__Pyx_SetItemInt’
if (unlikely(__Pyx_SetItemInt(PyList_GET_ITEM(__pyx_v_outer_outputs, __pyx_v_idx), 0, __pyx_t_16, long, 1, __Pyx_PyInt_From_long, 0, 0, 0) < 0)) __PYX_ERR(0, 278, __pyx_L1_error)
^
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:888:43: note: in definition of macro ‘unlikely’
#define unlikely(x) __builtin_expect(!!(x), 0)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:11: note: in expansion of macro ‘likely’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1657:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:4124:22: note: in expansion of macro ‘__Pyx_SetItemInt’
if (unlikely(__Pyx_SetItemInt(PyList_GET_ITEM(__pyx_v_outer_outputs, __pyx_v_idx), 0, Py_None, long, 1, __Pyx_PyInt_From_long, 0, 0, 0) < 0)) __PYX_ERR(0, 280, __pyx_L1_error)
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:38:0,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:4191:76: note: in expansion of macro ‘PY_SSIZE_T_MAX’
__pyx_t_16 = __Pyx_PyList_GetSlice(__pyx_v_outer_inputs, __pyx_v_offset, PY_SSIZE_T_MAX); if (unlikely(!__pyx_t_16)) __PYX_ERR(0, 287, __pyx_L1_error)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp: In function ‘PyObject* __pyx_memoryview_convert_item_to_object(__pyx_memoryview_obj*, char*)’:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:887:43: note: in definition of macro ‘likely’
#define likely(x) __builtin_expect(!!(x), 1)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1612:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:12564:21: note: in expansion of macro ‘__Pyx_GetItemInt’
__pyx_t_1 = __Pyx_GetItemInt(__pyx_v_result, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 498, __pyx_L5_except_error)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp: In function ‘PyObject* __pyx_unpickle_Enum__set_state(__pyx_MemviewEnum_obj*, PyObject*)’:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:887:43: note: in definition of macro ‘likely’
#define likely(x) __builtin_expect(!!(x), 1)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:722:28: note: in expansion of macro ‘PY_SSIZE_T_MAX’
likely(v < (type)PY_SSIZE_T_MAX ||
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:1623:6: note: in expansion of macro ‘__Pyx_fits_Py_ssize_t’
(__Pyx_fits_Py_ssize_t(i, type, is_signed) ?
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:21119:15: note: in expansion of macro ‘__Pyx_GetItemInt_Tuple’
__pyx_t_1 = __Pyx_GetItemInt_Tuple(__pyx_v___pyx_state, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 1); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 12, __pyx_L1_error)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp: In function ‘int __Pyx_PyBytes_Equals(PyObject*, PyObject*, int)’:
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:24990:43: warning: ‘PyBytesObject::ob_shash’ is deprecated [-Wdeprecated-declarations]
hash1 = ((PyBytesObject*)s1)->ob_shash;
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/bytesobject.h:62:0,
from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:50,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/cpython/bytesobject.h:7:35: note: declared here
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:24990:43: warning: ‘PyBytesObject::ob_shash’ is deprecated [-Wdeprecated-declarations]
hash1 = ((PyBytesObject*)s1)->ob_shash;
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/bytesobject.h:62:0,
from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:50,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/cpython/bytesobject.h:7:35: note: declared here
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:24990:43: warning: ‘PyBytesObject::ob_shash’ is deprecated [-Wdeprecated-declarations]
hash1 = ((PyBytesObject*)s1)->ob_shash;
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/bytesobject.h:62:0,
from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:50,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/cpython/bytesobject.h:7:35: note: declared here
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:24991:43: warning: ‘PyBytesObject::ob_shash’ is deprecated [-Wdeprecated-declarations]
hash2 = ((PyBytesObject*)s2)->ob_shash;
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/bytesobject.h:62:0,
from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:50,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/cpython/bytesobject.h:7:35: note: declared here
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:24991:43: warning: ‘PyBytesObject::ob_shash’ is deprecated [-Wdeprecated-declarations]
hash2 = ((PyBytesObject*)s2)->ob_shash;
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/bytesobject.h:62:0,
from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:50,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/cpython/bytesobject.h:7:35: note: declared here
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:24991:43: warning: ‘PyBytesObject::ob_shash’ is deprecated [-Wdeprecated-declarations]
hash2 = ((PyBytesObject*)s2)->ob_shash;
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/bytesobject.h:62:0,
from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:50,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/cpython/bytesobject.h:7:35: note: declared here
Py_DEPRECATED(3.11) Py_hash_t ob_shash;
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp: In function ‘PyObject* __Pyx_decode_c_string(const char*, Py_ssize_t, Py_ssize_t, const char*, const char*, PyObject* ()(const char, Py_ssize_t, const char*))’:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pyport.h:135:27: error: ‘INTPTR_MAX’ was not declared in this scope

define PY_SSIZE_T_MAX INTPTR_MAX

                       ^

C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:888:43: note: in definition of macro ‘unlikely’
#define unlikely(x) __builtin_expect(!!(x), 0)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:25175:38: note: in expansion of macro ‘PY_SSIZE_T_MAX’
if (unlikely(slen > (size_t) PY_SSIZE_T_MAX)) {
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp: In function ‘void __Pyx_AddTraceback(const char*, int, int, const char*)’:
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:438:62: error: invalid use of incomplete type ‘PyFrameObject {aka struct _frame}’
#define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno)
^
C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:26021:5: note: in expansion of macro ‘__Pyx_PyFrame_SetLineNumber’
__Pyx_PyFrame_SetLineNumber(py_frame, py_line);
^
In file included from C:\Users\Niall\anaconda3\envs\pymc5_env\include/Python.h:42:0,
from C:\Users\Niall\AppData\Local\PyTensor\compiledir_Windows-10-10.0.22000-SP0-Intel64_Family_6_Model_140_Stepping_1_GenuineIntel-3.11.0-64\scan_perform\mod.cpp:6:
C:\Users\Niall\anaconda3\envs\pymc5_env\include/pytypedefs.h:22:16: note: forward declaration of ‘PyFrameObject {aka struct _frame}’
typedef struct _frame PyFrameObject;
^
At global scope:
cc1plus.exe: warning: unrecognized command line option ‘-Wno-c++11-narrowing’

Apply node that caused the error: forall_inplace,cpu,scan_fn}(TensorConstant{2904}, Elemwise{Composite{(i0 + (i1 * i2))}}.0, IncSubtensor{InplaceSet;:int64:}.0, beta_1_interval___interval)
Toposort index: 22
Inputs types: [TensorType(int64, ()), TensorType(float64, (2904,)), TensorType(float64, (2905,)), TensorType(float64, ())]

HINT: Use a linker other than the C linker to print the inputs’ shapes and strides.
HINT: Re-running with most PyTensor optimizations disabled could provide a back-trace showing when this node was created. This can be done by setting the PyTensor flag ‘optimizer=fast_compile’. If that does not work, PyTensor optimizations can be disabled with ‘optimizer=None’.
HINT: Use the PyTensor flag exception_verbosity=high for a debug print-out and storage map footprint of this Apply node.

Error message

CompileError Traceback (most recent call last)
Cell In[25], line 2
1 with garch_vol_model:
----> 2 idata = pm.sample()
4 #posterior = idata.posterior.stack(pooled_chain=(“chain”, “draw”))
5 #posterior[“exp_volatility”] = np.exp(posterior[“volatility”])

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\sampling\mcmc.py:447, in sample(draws, step, init, n_init, initvals, trace, chains, cores, tune, progressbar, model, random_seed, discard_tuned_samples, compute_convergence_checks, callback, jitter_max_retries, return_inferencedata, keep_warning_stat, idata_kwargs, mp_ctx, **kwargs)
444 auto_nuts_init = False
446 initial_points = None
→ 447 step = assign_step_methods(model, step, methods=pm.STEP_METHODS, step_kwargs=kwargs)
449 if isinstance(step, list):
450 step = CompoundStep(step)

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\sampling\mcmc.py:189, in assign_step_methods(model, step, methods, step_kwargs)
181 selected = max(
182 methods,
183 key=lambda method, var=rv_var, has_gradient=has_gradient: method._competence(
184 var, has_gradient
185 ),
186 )
187 selected_steps[selected].append(var)
→ 189 return instantiate_steppers(model, steps, selected_steps, step_kwargs)

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\sampling\mcmc.py:107, in instantiate_steppers(model, steps, selected_steps, step_kwargs)
105 args = step_kwargs.get(step_class.name, {})
106 used_keys.add(step_class.name)
→ 107 step = step_class(vars=vars, model=model, **args)
108 steps.append(step)
110 unused_args = set(step_kwargs).difference(used_keys)

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\step_methods\hmc\nuts.py:182, in NUTS.init(self, vars, max_treedepth, early_max_treedepth, **kwargs)
124 def init(self, vars=None, max_treedepth=10, early_max_treedepth=8, **kwargs):
125 r""“Set up the No-U-Turn sampler.
126
127 Parameters
(…)
180 pm.sample to the desired number of tuning steps.
181 “””
→ 182 super().init(vars, **kwargs)
184 self.max_treedepth = max_treedepth
185 self.early_max_treedepth = early_max_treedepth

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\step_methods\hmc\base_hmc.py:109, in BaseHMC.init(self, vars, scaling, step_scale, is_cov, model, blocked, potential, dtype, Emax, target_accept, gamma, k, t0, adapt_step_size, step_rand, **pytensor_kwargs)
107 else:
108 vars = get_value_vars_from_user_vars(vars, self._model)
→ 109 super().init(vars, blocked=blocked, model=self._model, dtype=dtype, **pytensor_kwargs)
111 self.adapt_step_size = adapt_step_size
112 self.Emax = Emax

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\step_methods\arraystep.py:263, in GradientSharedStep.init(self, vars, model, blocked, dtype, logp_dlogp_func, **pytensor_kwargs)
260 model = modelcontext(model)
262 if logp_dlogp_func is None:
→ 263 func = model.logp_dlogp_function(vars, dtype=dtype, **pytensor_kwargs)
264 else:
265 func = logp_dlogp_func

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\model.py:648, in Model.logp_dlogp_function(self, grad_vars, tempered, **kwargs)
642 ip = self.initial_point(0)
643 extra_vars_and_values = {
644 var: ip[var.name]
645 for var in self.value_vars
646 if var in input_vars and var not in grad_vars
647 }
→ 648 return ValueGradFunction(costs, grad_vars, extra_vars_and_values, **kwargs)

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\model.py:389, in ValueGradFunction.init(self, costs, grad_vars, extra_vars_and_values, dtype, casting, compute_grads, **kwargs)
385 outputs = [cost]
387 inputs = grad_vars
→ 389 self._pytensor_function = compile_pymc(inputs, outputs, givens=givens, **kwargs)

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pymc\pytensorf.py:1121, in compile_pymc(inputs, outputs, random_seed, mode, **kwargs)
1119 opt_qry = mode.provided_optimizer.including(“random_make_inplace”, check_parameter_opt)
1120 mode = Mode(linker=mode.linker, optimizer=opt_qry)
→ 1121 pytensor_function = pytensor.function(
1122 inputs,
1123 outputs,
1124 updates={**rng_updates, **kwargs.pop(“updates”, {})},
1125 mode=mode,
1126 **kwargs,
1127 )
1128 return pytensor_function

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\compile\function_init_.py:315, in function(inputs, outputs, mode, updates, givens, no_default_updates, accept_inplace, name, rebuild_strict, allow_input_downcast, profile, on_unused_input)
309 fn = orig_function(
310 inputs, outputs, mode=mode, accept_inplace=accept_inplace, name=name
311 )
312 else:
313 # note: pfunc will also call orig_function – orig_function is
314 # a choke point that all compilation must pass through
→ 315 fn = pfunc(
316 params=inputs,
317 outputs=outputs,
318 mode=mode,
319 updates=updates,
320 givens=givens,
321 no_default_updates=no_default_updates,
322 accept_inplace=accept_inplace,
323 name=name,
324 rebuild_strict=rebuild_strict,
325 allow_input_downcast=allow_input_downcast,
326 on_unused_input=on_unused_input,
327 profile=profile,
328 output_keys=output_keys,
329 )
330 return fn

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\compile\function\pfunc.py:367, in pfunc(params, outputs, mode, updates, givens, no_default_updates, accept_inplace, name, rebuild_strict, allow_input_downcast, profile, on_unused_input, output_keys, fgraph)
353 profile = ProfileStats(message=profile)
355 inputs, cloned_outputs = construct_pfunc_ins_and_outs(
356 params,
357 outputs,
(…)
364 fgraph=fgraph,
365 )
→ 367 return orig_function(
368 inputs,
369 cloned_outputs,
370 mode,
371 accept_inplace=accept_inplace,
372 name=name,
373 profile=profile,
374 on_unused_input=on_unused_input,
375 output_keys=output_keys,
376 fgraph=fgraph,
377 )

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\compile\function\types.py:1766, in orig_function(inputs, outputs, mode, accept_inplace, name, profile, on_unused_input, output_keys, fgraph)
1754 m = Maker(
1755 inputs,
1756 outputs,
(…)
1763 fgraph=fgraph,
1764 )
1765 with config.change_flags(compute_test_value=“off”):
→ 1766 fn = m.create(defaults)
1767 finally:
1768 t2 = time.perf_counter()

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\compile\function\types.py:1659, in FunctionMaker.create(self, input_storage, trustme, storage_map)
1656 start_import_time = pytensor.link.c.cmodule.import_time
1658 with config.change_flags(traceback__limit=config.traceback__compile_limit):
→ 1659 _fn, _i, _o = self.linker.make_thunk(
1660 input_storage=input_storage_lists, storage_map=storage_map
1661 )
1663 end_linker = time.perf_counter()
1665 linker_time = end_linker - start_linker

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\link\basic.py:254, in LocalLinker.make_thunk(self, input_storage, output_storage, storage_map, **kwargs)
247 def make_thunk(
248 self,
249 input_storage: Optional[“InputStorageType”] = None,
(…)
252 **kwargs,
253 ) → Tuple[“BasicThunkType”, “InputStorageType”, “OutputStorageType”]:
→ 254 return self.make_all(
255 input_storage=input_storage,
256 output_storage=output_storage,
257 storage_map=storage_map,
258 )[:3]

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\link\vm.py:1255, in VMLinker.make_all(self, profiler, input_storage, output_storage, storage_map)
1253 thunks[-1].lazy = False
1254 except Exception:
→ 1255 raise_with_op(fgraph, node)
1257 t1 = time.perf_counter()
1259 if self.profile:

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\link\utils.py:536, in raise_with_op(fgraph, node, thunk, exc_info, storage_map)
531 warnings.warn(
532 f"{exc_type} error does not allow us to add an extra error message"
533 )
534 # Some exception need extra parameter in inputs. So forget the
535 # extra long error message in that case.
→ 536 raise exc_value.with_traceback(exc_trace)

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\link\vm.py:1246, in VMLinker.make_all(self, profiler, input_storage, output_storage, storage_map)
1241 thunk_start = time.perf_counter()
1242 # no-recycling is done at each VM.call So there is
1243 # no need to cause duplicate c code by passing
1244 # no_recycling here.
1245 thunks.append(
→ 1246 node.op.make_thunk(node, storage_map, compute_map, , impl=impl)
1247 )
1248 linker_make_thunk_time[node] = time.perf_counter() - thunk_start
1249 if not hasattr(thunks[-1], “lazy”):
1250 # We don’t want all ops maker to think about lazy Ops.
1251 # So if they didn’t specify that its lazy or not, it isn’t.
1252 # If this member isn’t present, it will crash later.

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\scan\op.py:1526, in Scan.make_thunk(self, node, storage_map, compute_map, no_recycling, impl)
1523 if impl == “py”:
1524 raise MissingGXX
→ 1526 from . import scan_perform_ext
1528 cython_mintaps = np.asarray(self.mintaps, dtype=“int32”)
1530 n_outs = self.info.n_mit_mot + self.info.n_mit_sot + self.info.n_sit_sot

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\scan\scan_perform_ext.py:92
89 with open(cfile) as f:
90 code = f.read()
—> 92 cmodule.GCC_compiler.compile_str(
93 dirname, code, location=loc, preargs=preargs, hide_symbols=False
94 )
95 # Save version into the init.py file.
96 init_py = os.path.join(loc, “init.py”)

File ~\anaconda3\envs\pymc5_env\Lib\site-packages\pytensor\link\c\cmodule.py:2641, in GCC_compiler.compile_str(module_name, src_code, location, include_dirs, lib_dirs, libs, preargs, py_module, hide_symbols)
2633 print(
2634 “Check if package python-dev or python-devel is installed.”
2635 )
2637 # We replace ‘\n’ by ‘. ’ in the error message because when Python
2638 # prints the exception, having ‘\n’ in the text makes it more
2639 # difficult to read.
2640 # compile_stderr = compile_stderr.replace(“\n”, ". ")
→ 2641 raise CompileError(
2642 f"Compilation failed (return status={status}):\n{’ '.join(cmd)}\n{compile_stderr}"
2643 )
2644 elif config.cmodule__compilation_warning and compile_stderr:
2645 # Print errors just below the command line.
2646 print(compile_stderr

Does any model work? How did you install PyMC5? The official instructions are here: Installation — PyMC 5.0.2 documentation

Yep, everything else i’ve been using it for works

& yep followed those instructions

Working example of GARCH11:

a0 = 0.5
a1 = 0.3
b1 = 0.25

y = [rng.normal(loc=0,scale=a0)]
std = [a0]
for i in range(10000):
    std.append(np.sqrt(a0 + a1 * np.square(y[-1]) + b1 * np.square(std[-1])))
    y.append(rng.normal(loc=0,scale=std[-1]))
y_obs = np.array(y)

with pm.Model() as garch_model:
    alpha0 = pm.HalfNormal('alpha0',1);
    alpha1 = pm.Uniform('alpha1',0,1);
    beta1 = pm.Uniform('beta1',0,(1-alpha1))
    
    lik = pm.GARCH11("lik",alpha0,alpha1,beta1,0.5,observed=y_obs)

with garch_model:
    trace = pm.sample()

Nice. Must be something wrong with my setup/install then.

Okay, I implemented this with a nonzero mean, but I would love to know if I can write the scan function so it doesn’t return the full matrix (necessitating taking the diag):

I compute simulated data as follows:

import numpy as np
N = 25
omega = 0.5
alpha_1 = 0.8
beta_1 = 0.15
mu = 1.5

sig = [1.0]
y = [np.random.normal(mu,1.0)]
for i in range(1,N):
    sig.append(
        np.sqrt(
            omega + alpha_1*np.square(y[-1]) +beta_1*np.square(sig[-1])
        )
    )
    y.append(np.random.normal(mu, sig[-1]))
sig = np.array(sig)
y = np.array(y)

which computes data y from a normal distribution with mean mu and heteroscedastic variance sig.

The model I use (with scan) to recover the parameters is as follows:

with pm.Model() as garch_nzm:
# GARCH std
    mu = pm.Normal('mu',1.0,0.1)
    alpha0 = pm.Uniform('alpha0',0,1);
    alpha1 = pm.Uniform('alpha1',0,1);
    beta1 = pm.Uniform('beta1',0,(1-alpha1))

    obs_mean = y

    def step(PREV_Y, PREV_SIGMA, OMEGA, ALPHA1, BETA1):
        NEW_SIGMA =  at.sqrt(
            OMEGA + ALPHA1* at.square(PREV_Y) + BETA1 * at.square(PREV_SIGMA)
        )
        return NEW_SIGMA
    garch_all, updates = pytensor.scan(
        fn=step,
        sequences=[obs_mean],
        outputs_info=[at.ones_like(obs_mean,dtype=np.float64)],
        non_sequences=[alpha0, alpha1, beta1],
        strict=True,
    )
    garch_std = pm.Deterministic("garch_std", at.diag(garch_all))
    lik = pm.Normal(
        "kr_lik", mu=mu*at.ones_like(y), sigma=garch_std, observed=y
    )
    idata = pm.sample()

which doesn’t really give values that close to the original values for the parameters. It does seem to recover the data though…

I worry about the memory in the scan function though. Any suggestions? @ricardoV94 ?

CC @jessegrabowski may be more helpful than I :slight_smile:

I think there’s something off with how you’re implementing the model. The outputs_info should be a scalar or starters, and it doesn’t make sense to scan in the true data as epsilon_t. epsilon should be the difference between the mean and the prediction.

I worked on it a bit and made a gist here. I thought things were going well, but they got me in the second half. Maybe more eyes on the problem will help.

I fixed it, the examples should be good to go.

EDIT 2: I added a 2nd example with a full ARMA(1,1)-GARCH(1,1) process. Scan is awesome now, all hail @ricardoV94

4 Likes

@jessegrabowski Notebook looks slick. No idea why the paramerers are off, I guess it’s just an equally plausible configuration.

You won’t need to pass updates manually after Handle Scan in collect_default_updates · pymc-devs/pymc@a1744a8 · GitHub

After that PR I would also suggest using a CustomDist, as its nicer than the internal register_rv, but for now this is the only correct way.

1 Like