Skip to content

Commit

Permalink
TST: Improve coverage of recursions
Browse files Browse the repository at this point in the history
Ensure defensive code works as expected
  • Loading branch information
bashtage committed Jun 11, 2018
1 parent 858c1b8 commit bf90aec
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 21 deletions.
62 changes: 59 additions & 3 deletions arch/tests/univariate/test_recursions.py
Expand Up @@ -8,8 +8,10 @@
from numpy.testing import assert_almost_equal

import arch.univariate.recursions_python as recpy

try:
import arch.univariate.recursions as rec_cython

missing_extension = False
except ImportError:
missing_extension = True
Expand All @@ -21,6 +23,7 @@

try:
import numba # noqa

missing_numba = False
except ImportError:
missing_numba = True
Expand Down Expand Up @@ -107,6 +110,18 @@ def test_garch(self):
assert_almost_equal(sigma2_numba, sigma2)
assert_almost_equal(sigma2_python, sigma2)

parameters = np.array([.1, -.4, .3, .2])
recpy.garch_recursion_python(parameters, fresids, sresids, sigma2, 1,
1, 1, T, backcast, self.var_bounds)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

parameters = np.array([.1, .4, 3, 2])
recpy.garch_recursion_python(parameters, fresids, sresids, sigma2, 1,
1, 1, T, backcast, self.var_bounds)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

def test_harch(self):
T, resids, = self.T, self.resids
sigma2, backcast = self.sigma2, self.backcast
Expand All @@ -124,6 +139,18 @@ def test_harch(self):
assert_almost_equal(sigma2_numba, sigma2)
assert_almost_equal(sigma2_python, sigma2)

parameters = np.array([-.1, -.4, .3, .2])
recpy.harch_recursion_python(parameters, resids, sigma2, lags, T,
backcast, self.var_bounds)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

parameters = np.array([.1, 4e8, 3, 2])
recpy.harch_recursion_python(parameters, resids, sigma2, lags, T,
backcast, self.var_bounds)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

def test_arch(self):
T, resids, = self.T, self.resids
sigma2, backcast = self.sigma2, self.backcast
Expand All @@ -142,6 +169,18 @@ def test_arch(self):
assert_almost_equal(sigma2_numba, sigma2)
assert_almost_equal(sigma2_python, sigma2)

parameters = np.array([-.1, -.4, .3, .2])
recpy.arch_recursion_python(parameters, resids, sigma2, p, T,
backcast, self.var_bounds)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

parameters = np.array([.1, 4e8, 3, 2])
recpy.arch_recursion_python(parameters, resids, sigma2, p, T,
backcast, self.var_bounds)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

def test_garch_power_1(self):
T, resids, = self.T, self.resids
sigma2, backcast = self.sigma2, self.backcast
Expand Down Expand Up @@ -254,7 +293,8 @@ def test_bounds(self):
rec.harch_recursion(parameters, resids, sigma2, lags, T, backcast,
self.var_bounds)
assert_almost_equal(sigma2_python, sigma2)
assert (sigma2 >= self.var_bounds[:, 1]).all()
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

parameters = np.array([-1e100, .4, .3, .2])
recpy.harch_recursion(parameters, resids, sigma2, lags, T, backcast,
Expand All @@ -275,7 +315,8 @@ def test_bounds(self):
rec.garch_recursion(parameters, fresids, sresids, sigma2, 1, 1,
1, T, backcast, self.var_bounds)
assert_almost_equal(sigma2_python, sigma2)
assert (sigma2 >= self.var_bounds[:, 1]).all()
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

parameters = np.array([-1e100, .4, .3, .2])
recpy.garch_recursion(parameters, fresids, sresids, sigma2,
Expand All @@ -293,7 +334,8 @@ def test_bounds(self):
rec.arch_recursion(parameters, resids, sigma2, 3, T, backcast,
self.var_bounds)
assert_almost_equal(sigma2_python, sigma2)
assert (sigma2 >= self.var_bounds[:, 1]).all()
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

parameters = np.array([-1e100, .4, .3, .2])
recpy.arch_recursion(parameters, resids, sigma2, 3, T, backcast,
Expand Down Expand Up @@ -341,6 +383,20 @@ def test_egarch(self):
sigma2[t] = np.exp(lnsigma2[t])
assert_almost_equal(sigma2_python, sigma2)

parameters = np.array([-100.0, 0.1, -0.1, 0.95])
recpy.egarch_recursion_python(parameters, resids, sigma2, p, o, q,
nobs, backcast, var_bounds, lnsigma2,
std_resids, abs_std_resids)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

parameters = np.array([0.0, 0.1, -0.1, 9.5])
recpy.egarch_recursion_python(parameters, resids, sigma2, p, o, q,
nobs, backcast, var_bounds, lnsigma2,
std_resids, abs_std_resids)
assert np.all(sigma2 >= self.var_bounds[:, 0])
assert np.all(sigma2 <= 2 * self.var_bounds[:, 1])

@pytest.mark.skipif(missing_numba or missing_extension, reason='numba not installed')
def test_garch_performance(self):
garch_setup = """
Expand Down
16 changes: 8 additions & 8 deletions arch/tests/utility/test_array.py
Expand Up @@ -98,6 +98,11 @@ def test_parse_dataframe(self):
assert_equal(out[1], np.arange(10.0))
assert_equal(out[0], ['y'])

out = parse_dataframe(None, 'name')
assert out[0] == ['name']
assert isinstance(out[1], np.ndarray)
assert out[1].shape == (0,)

def test_implicit_constant(self):
x = self.rng.standard_normal((1000, 2))
assert not implicit_constant(x)
Expand All @@ -119,10 +124,7 @@ class A(object):
class B(A):
pass

ds = """
Docstring
"""
assert_equal(B.__doc__, ds)
assert_equal(B.__doc__, A.__doc__)

def test_date_to_index(self):
dr = date_range('20000101', periods=3000, freq='W')
Expand Down Expand Up @@ -235,8 +237,7 @@ def test_find_index(self):
assert_equal(find_index(series, '2000-01-01'), 0)
assert_equal(find_index(series, series.index[0]), 0)
assert_equal(find_index(series, series.index[3000]), 3000)
assert_equal(find_index(series, series.index[3000].to_pydatetime()),
3000)
assert_equal(find_index(series, series.index[3000].to_pydatetime()), 3000)
npy_date = np.datetime64(series.index[3000].to_pydatetime())
found_loc = find_index(series, npy_date)
assert_equal(found_loc, 3000)
Expand All @@ -249,8 +250,7 @@ def test_find_index(self):
assert_equal(find_index(df, df.index[0]), 0)
assert_equal(find_index(df, df.index[3000]), 3000)
assert_equal(find_index(df, df.index[3000].to_pydatetime()), 3000)
found_loc = find_index(df,
np.datetime64(df.index[3000].to_pydatetime()))
found_loc = find_index(df, np.datetime64(df.index[3000].to_pydatetime()))
assert_equal(found_loc, 3000)
with pytest.raises(ValueError):
find_index(df, 'bad-date')
Expand Down
5 changes: 3 additions & 2 deletions arch/univariate/recursions_python.py
Expand Up @@ -4,11 +4,12 @@
python setup.py install --no-binary
"""
from __future__ import absolute_import, division
from arch.compat.python import range

from arch.compat.numba import jit
from arch.compat.python import range

from numpy import log
import numpy as np
from numpy import log

__all__ = ['harch_recursion', 'arch_recursion', 'garch_recursion',
'egarch_recursion']
Expand Down
10 changes: 2 additions & 8 deletions arch/utility/array.py
Expand Up @@ -147,10 +147,7 @@ def date_to_index(date, date_index):
try:
date = np.datetime64(to_datetime(date, errors='coerce'))
except (ValueError, TypeError):
try:
date = np.datetime64(to_datetime(date, coerce=True))
except (ValueError, TypeError):
raise ValueError('date:' + orig_date + ' cannot be parsed to a date.')
raise ValueError('date:' + orig_date + ' cannot be parsed to a date.')

date_index = np.asarray(date_index)

Expand Down Expand Up @@ -212,10 +209,7 @@ def find_index(s, index):
"""
if isinstance(index, (int, long, np.int, np.int64)):
return index
try:
date_index = to_datetime(index, errors='coerce')
except TypeError:
date_index = to_datetime(index, coerce=True)
date_index = to_datetime(index, errors='coerce')

if date_index is NaT:
raise ValueError(index + ' cannot be converted to datetime')
Expand Down

0 comments on commit bf90aec

Please sign in to comment.