Skip to content

Commit

Permalink
pull from master
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-baier committed Jan 10, 2025
2 parents 557bf6c + 4143344 commit 9ca56ed
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 97 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/ci_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-13]
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12']

steps:
- name: Checkout repository
Expand Down Expand Up @@ -53,6 +53,7 @@ jobs:
- name: Test with pytest
run: make test
- name: Codecov
if: runner.os != 'macOS'
uses: codecov/codecov-action@v3
#with:
# fail_ci_if_error: true
Expand Down Expand Up @@ -121,7 +122,7 @@ jobs:
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Download wheel/dist from build
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4.1.7
with:
name: dist
path: dist
Expand Down
94 changes: 94 additions & 0 deletions enterprise_extensions/checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import time
import numpy as np

from enterprise_extensions import models


class CompareTimingModels():
"""
Compare difference between the usual and marginalized timing models.
After instantiating, the __call__() method can be used for sampling for any number of points.
To see the results, use the results() method.
:param psrs: Pulsar object containing pulsars from model
:param model_name: String name of model to test. Model must be defined in enterprise_extensions.models.
:param abs_tol: absolute tolerance for error between timing models (default 1e-3), set to None to bypass errors
:param rel_tol: relative tolerance for error between timing models (default 1e-6), set to None to bypass errors
:param dense: use the dense cholesky algorithm over sparse
"""

def __init__(self, psrs, model_name='model_1', abs_tol=1e-3, rel_tol=1e-6, dense=True, **kwargs):
model = getattr(models, model_name)
self.abs_tol = abs_tol
self.rel_tol = rel_tol
if dense:
self.pta_marg = model(psrs, tm_marg=True, dense_like=True, **kwargs) # marginalized model
else:
self.pta_marg = model(psrs, tm_marg=True, **kwargs) # marginalized model
self.pta_norm = model(psrs, **kwargs) # normal model
self.tm_correction = 0
for psr in psrs:
self.tm_correction -= 0.5 * np.log(1e40) * psr.Mmat.shape[1]
self.abs_err = []
self.rel_err = []
self.count = 0

def check_timing(self, number=10_000):
print('Timing sample creation...')
start = time.time()
for __ in range(number):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
end = time.time()
sample_time = end - start
print('Sampling {0} points took {1} seconds.'.format(number, sample_time))

print('Timing MarginalizedTimingModel...')
start = time.time()
for __ in range(number):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
self.pta_marg.get_lnlikelihood(x0)
end = time.time()
time_marg = end - start - sample_time # remove sampling time from total time taken
print('Sampling {0} points took {1} seconds.'.format(number, time_marg))

print('Timing TimingModel...')
start = time.time()
for __ in range(number):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
self.pta_norm.get_lnlikelihood(x0)
end = time.time()
time_norm = end - start - sample_time # remove sampling time from total time taken
print('Sampling {0} points took {1} seconds.'.format(number, time_norm))

res = time_norm / time_marg
print('MarginalizedTimingModel is {0} times faster than TimingModel after {1} points.'.format(res, number))
return res

def get_sample_point(self):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
return x0

def __call__(self, x0):
res_norm = self.pta_norm.get_lnlikelihood(x0)
res_marg = self.pta_marg.get_lnlikelihood(x0)
abs_err = np.abs(res_marg - res_norm)
rel_err = abs_err / res_norm
self.abs_err.append(abs_err)
self.rel_err.append(rel_err)
self.count += 1
if self.abs_tol is not None and abs_err > self.abs_tol:
abs_raise = 'Absolute error is {0} at {1} which is larger than abs_tol of {2}.'.format(
abs_err, x0, self.abs_tol)
raise ValueError(abs_raise)
elif self.rel_tol is not None and rel_err > self.rel_tol:
rel_raise = 'Relative error is {0} at {1} which is larger than rel_tol of {2}.'.format(
rel_err, x0, self.rel_tol)
raise ValueError(rel_raise)
return res_norm

def results(self):
print('Number of points evaluated:', self.count)
print('Maximum absolute error:', np.max(self.abs_err))
print('Maximum relative error:', np.max(self.rel_err))
return self.abs_err, self.rel_err
6 changes: 3 additions & 3 deletions enterprise_extensions/empirical_distr.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
sklearn_available=True
except ModuleNotFoundError:
sklearn_available=False
from scipy.interpolate import interp1d, interp2d
from scipy.interpolate import interp1d, RegularGridInterpolator

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -173,9 +173,9 @@ def __init__(self, param_names, samples, minvals=None, maxvals=None, bandwidth=0
xvals = np.linspace(minvals[0], maxvals[0], num=nbins)
yvals = np.linspace(minvals[1], maxvals[1], num=nbins)
self._Nbins = [yvals.size for ii in range(xvals.size)]
scores = np.array([self.kde.score(np.array([xvals[ii], yvals[jj]]).reshape((1, 2))) for ii in range(xvals.size) for jj in range(yvals.size)])
scores = np.array([self.kde.score(np.array([xvals[ii], yvals[jj]]).reshape((1, 2))) for ii in range(xvals.size) for jj in range(yvals.size)]).reshape(len(xvals), len(yvals))
# interpolate within prior
self._logpdf = interp2d(xvals, yvals, scores, kind='linear', fill_value=-1000)
self._logpdf = RegularGridInterpolator((xvals, yvals), scores, method='linear', bounds_error=False, fill_value=-1000)

def draw(self):
params = self.kde.sample(1).T
Expand Down
92 changes: 0 additions & 92 deletions enterprise_extensions/model_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-

import time

import matplotlib.pyplot as plt
import numpy as np
Expand All @@ -11,7 +10,6 @@
except ImportError:
from emcee.autocorr import integrated_time as acor

from enterprise_extensions import models

# Log-spaced frequncies

Expand Down Expand Up @@ -294,93 +292,3 @@ def mask_filter(psr, mask):
psr._planetssb = psr.planetssb[mask, :, :]

psr.sort_data()


class CompareTimingModels():
"""
Compare difference between the usual and marginalized timing models.
After instantiating, the __call__() method can be used for sampling for any number of points.
To see the results, use the results() method.
:param psrs: Pulsar object containing pulsars from model
:param model_name: String name of model to test. Model must be defined in enterprise_extensions.models.
:param abs_tol: absolute tolerance for error between timing models (default 1e-3), set to None to bypass errors
:param rel_tol: relative tolerance for error between timing models (default 1e-6), set to None to bypass errors
:param dense: use the dense cholesky algorithm over sparse
"""

def __init__(self, psrs, model_name='model_1', abs_tol=1e-3, rel_tol=1e-6, dense=True, **kwargs):
model = getattr(models, model_name)
self.abs_tol = abs_tol
self.rel_tol = rel_tol
if dense:
self.pta_marg = model(psrs, tm_marg=True, dense_like=True, **kwargs) # marginalized model
else:
self.pta_marg = model(psrs, tm_marg=True, **kwargs) # marginalized model
self.pta_norm = model(psrs, **kwargs) # normal model
self.tm_correction = 0
for psr in psrs:
self.tm_correction -= 0.5 * np.log(1e40) * psr.Mmat.shape[1]
self.abs_err = []
self.rel_err = []
self.count = 0

def check_timing(self, number=10_000):
print('Timing sample creation...')
start = time.time()
for __ in range(number):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
end = time.time()
sample_time = end - start
print('Sampling {0} points took {1} seconds.'.format(number, sample_time))

print('Timing MarginalizedTimingModel...')
start = time.time()
for __ in range(number):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
self.pta_marg.get_lnlikelihood(x0)
end = time.time()
time_marg = end - start - sample_time # remove sampling time from total time taken
print('Sampling {0} points took {1} seconds.'.format(number, time_marg))

print('Timing TimingModel...')
start = time.time()
for __ in range(number):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
self.pta_norm.get_lnlikelihood(x0)
end = time.time()
time_norm = end - start - sample_time # remove sampling time from total time taken
print('Sampling {0} points took {1} seconds.'.format(number, time_norm))

res = time_norm / time_marg
print('MarginalizedTimingModel is {0} times faster than TimingModel after {1} points.'.format(res, number))
return res

def get_sample_point(self):
x0 = np.hstack([p.sample() for p in self.pta_marg.params])
return x0

def __call__(self, x0):
res_norm = self.pta_norm.get_lnlikelihood(x0)
res_marg = self.pta_marg.get_lnlikelihood(x0)
abs_err = np.abs(res_marg - res_norm)
rel_err = abs_err / res_norm
self.abs_err.append(abs_err)
self.rel_err.append(rel_err)
self.count += 1
if self.abs_tol is not None and abs_err > self.abs_tol:
abs_raise = 'Absolute error is {0} at {1} which is larger than abs_tol of {2}.'.format(
abs_err, x0, self.abs_tol)
raise ValueError(abs_raise)
elif self.rel_tol is not None and rel_err > self.rel_tol:
rel_raise = 'Relative error is {0} at {1} which is larger than rel_tol of {2}.'.format(
rel_err, x0, self.rel_tol)
raise ValueError(rel_raise)
return res_norm

def results(self):
print('Number of points evaluated:', self.count)
print('Maximum absolute error:', np.max(self.abs_err))
print('Maximum relative error:', np.max(self.rel_err))
return self.abs_err, self.rel_err

0 comments on commit 9ca56ed

Please sign in to comment.