Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/35/quantilespacing #38

Merged
merged 1 commit into from
Dec 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/notebooks/demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@
},
"outputs": [],
"source": [
"quantiles = P.quantize(percent=10.)\n",
"quants = np.array([0.01,0.02,0.03,0.04,0.05,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.95,0.96,0.97,0.98,0.99])\n",
"quantiles = P.quantize(quants=quants)#(percent=10.)\n",
"Q = qp.PDF(quantiles=quantiles)"
]
},
Expand Down
48 changes: 29 additions & 19 deletions qp/pdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import qp

<<<<<<< HEAD
class PDF(object):

def __init__(self, truth=None, quantiles=None, histogram=None,
Expand Down Expand Up @@ -37,8 +36,7 @@ def __init__(self, truth=None, quantiles=None, histogram=None,
self.initialized = 'histogram'
self.last = self.initialized

if vb and self.truth is None and self.quantiles is None
and self.histogram is None:
if vb and self.truth is None and self.quantiles is None and self.histogram is None:
print 'Warning: initializing a PDF object without inputs'
self.difs = None
self.mids = None
Expand Down Expand Up @@ -96,12 +94,14 @@ def integrate(self, limits):
"""
return None

def quantize(self, percent=1., number=None, vb=True):
def quantize(self, quants=None, percent=1., number=None, vb=True):
"""
Computes an array of evenly-spaced quantiles from the truth.

Parameters
----------
quants: ndarray, float
array of quantile locations as decimals
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see - you are punting the choice of quantpoints to the user. Fine! It would be good to come up with a good algorithm for setting the quantpoints, though.

percent: float
the separation of the requested quantiles, in percent
number: int
Expand All @@ -123,25 +123,34 @@ def quantize(self, percent=1., number=None, vb=True):
object stored in `self.truth`. This calculates the inverse CDF.
See `the Scipy docs <https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.rv_continuous.ppf.html#scipy.stats.rv_continuous.ppf>`_ for details.
"""
if number is not None:
# Compute the spacing of the quantiles:
quantum = 1.0 / float(number+1)
if quants is not None:
full_quants = np.append(np.array([0.]),quants)
full_quants = np.append(full_quants,np.array([1.]))
quantdifs = full_quants[1:]-full_quants[:-1]
assert np.sum(quantdifs)==1.
self.quantpoints = quants
else:
quantum = percent/100.0
# Over-write the number of quantiles:
number = np.ceil(100.0 / percent) - 1
assert number > 0

points = np.linspace(0.0+quantum, 1.0-quantum, number)
if vb: print("Calculating quantiles: ", points)
if number is not None:
# Compute the spacing of the quantiles:
quantum = 1.0 / float(number+1)
else:
quantum = percent/100.0
# Over-write the number of quantiles:
number = np.ceil(100.0 / percent) - 1
assert number > 0

self.quantpoints = np.linspace(0.0+quantum, 1.0-quantum, number)
if vb: print("Calculating quantiles: ", self.quantpoints)
if self.truth is not None:
self.quantiles = self.truth.ppf(points)
self.quantiles = self.truth.ppf(self.quantpoints)
else:
print('New quantiles can only be computed from a truth distribution in this version.')
return

if vb: print("Result: ", self.quantiles)
self.quantvals = self.evaluate(self.quantiles)
self.last = 'quantiles'
self.quantiles = (self.quantiles, self.quantvals)
return self.quantiles

def histogramize(self, binends=None, nbins=10, binrange=[0., 1.], vb=True):
Expand Down Expand Up @@ -222,9 +231,10 @@ def interpolate(self, using=None, vb=True):
if self.quantiles is None:
self.quantiles = self.quantize()

self.difs = self.quantiles[1:]-self.quantiles[:-1]
self.mids = (self.quantiles[1:]+self.quantiles[:-1])/2.
self.vals = (1.0/(len(self.quantiles)+1))/self.difs
#self.difs = self.quantiles[0][1:]-self.quantiles[0][:-1]
#self.mids = (self.quantiles[0][1:]+self.quantiles[0][:-1])/2.
self.mids = self.quantiles[0]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much neater! Feel free to remove the commented out parts, they're in the history.

self.vals = self.quantiles[1]#(1.0/(len(self.quantiles)+1))/self.difs

if using == 'histogram':
# First find the histogram if none exists:
Expand Down Expand Up @@ -300,7 +310,7 @@ def plot(self, limits, points=None):
plt.plot(x, self.truth.pdf(x), color='k', linestyle='-', lw=1.0, alpha=1.0, label='True PDF')

if self.quantiles is not None:
plt.vlines(self.quantiles, 0., 1., color='b', linestyle='--', lw=1.0, alpha=1., label='Quantiles')
plt.vlines(self.quantiles[0], np.zeros(len(self.quantiles[1])), self.quantiles[1], color='b', linestyle='--', lw=1.0, alpha=1., label='Quantiles')
if points is not None:
(grid, qinterpolated) = self.approximate(points, using='quantiles')
plt.plot(grid, qinterpolated, color='b', linestyle=':', lw=2.0, alpha=1.0, label='Quantile Interpolated PDF')
Expand Down