You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.1 KiB
Python
156 lines
4.1 KiB
Python
import numpy as np
|
|
import numpy.linalg as L
|
|
import scipy.interpolate
|
|
import scipy.linalg
|
|
|
|
__docformat__ = 'restructuredtext'
|
|
|
|
def recipr(X):
|
|
"""
|
|
Return the reciprocal of an array, setting all entries less than or
|
|
equal to 0 to 0. Therefore, it presumes that X should be positive in
|
|
general.
|
|
"""
|
|
x = np.maximum(np.asarray(X).astype(np.float64), 0)
|
|
return np.greater(x, 0.) / (x + np.less_equal(x, 0.))
|
|
|
|
def mad(a, c=0.6745, axis=0):
|
|
"""
|
|
Median Absolute Deviation:
|
|
|
|
median(abs(a - median(a))) / c
|
|
|
|
"""
|
|
|
|
_shape = a.shape
|
|
a.shape = np.product(a.shape,axis=0)
|
|
m = np.median(np.fabs(a - np.median(a))) / c
|
|
a.shape = _shape
|
|
return m
|
|
|
|
def recipr0(X):
|
|
"""
|
|
Return the reciprocal of an array, setting all entries equal to 0
|
|
as 0. It does not assume that X should be positive in
|
|
general.
|
|
"""
|
|
test = np.equal(np.asarray(X), 0)
|
|
return np.where(test, 0, 1. / X)
|
|
|
|
def clean0(matrix):
|
|
"""
|
|
Erase columns of zeros: can save some time in pseudoinverse.
|
|
"""
|
|
colsum = np.add.reduce(matrix**2, 0)
|
|
val = [matrix[:,i] for i in np.flatnonzero(colsum)]
|
|
return np.array(np.transpose(val))
|
|
|
|
def rank(X, cond=1.0e-12):
|
|
"""
|
|
Return the rank of a matrix X based on its generalized inverse,
|
|
not the SVD.
|
|
"""
|
|
X = np.asarray(X)
|
|
if len(X.shape) == 2:
|
|
D = scipy.linalg.svdvals(X)
|
|
return int(np.add.reduce(np.greater(D / D.max(), cond).astype(np.int32)))
|
|
else:
|
|
return int(not np.alltrue(np.equal(X, 0.)))
|
|
|
|
def fullrank(X, r=None):
|
|
"""
|
|
Return a matrix whose column span is the same as X.
|
|
|
|
If the rank of X is known it can be specified as r -- no check
|
|
is made to ensure that this really is the rank of X.
|
|
|
|
"""
|
|
|
|
if r is None:
|
|
r = rank(X)
|
|
|
|
V, D, U = L.svd(X, full_matrices=0)
|
|
order = np.argsort(D)
|
|
order = order[::-1]
|
|
value = []
|
|
for i in range(r):
|
|
value.append(V[:,order[i]])
|
|
return np.asarray(np.transpose(value)).astype(np.float64)
|
|
|
|
class StepFunction:
|
|
"""
|
|
A basic step function: values at the ends are handled in the simplest
|
|
way possible: everything to the left of x[0] is set to ival; everything
|
|
to the right of x[-1] is set to y[-1].
|
|
|
|
Examples
|
|
--------
|
|
>>> from numpy import arange
|
|
>>> from nipy.fixes.scipy.stats.models.utils import StepFunction
|
|
>>>
|
|
>>> x = arange(20)
|
|
>>> y = arange(20)
|
|
>>> f = StepFunction(x, y)
|
|
>>>
|
|
>>> print f(3.2)
|
|
3.0
|
|
>>> print f([[3.2,4.5],[24,-3.1]])
|
|
[[ 3. 4.]
|
|
[ 19. 0.]]
|
|
"""
|
|
|
|
def __init__(self, x, y, ival=0., sorted=False):
|
|
|
|
_x = np.asarray(x)
|
|
_y = np.asarray(y)
|
|
|
|
if _x.shape != _y.shape:
|
|
raise ValueError, 'in StepFunction: x and y do not have the same shape'
|
|
if len(_x.shape) != 1:
|
|
raise ValueError, 'in StepFunction: x and y must be 1-dimensional'
|
|
|
|
self.x = np.hstack([[-np.inf], _x])
|
|
self.y = np.hstack([[ival], _y])
|
|
|
|
if not sorted:
|
|
asort = np.argsort(self.x)
|
|
self.x = np.take(self.x, asort, 0)
|
|
self.y = np.take(self.y, asort, 0)
|
|
self.n = self.x.shape[0]
|
|
|
|
def __call__(self, time):
|
|
|
|
tind = np.searchsorted(self.x, time) - 1
|
|
_shape = tind.shape
|
|
return self.y[tind]
|
|
|
|
def ECDF(values):
|
|
"""
|
|
Return the ECDF of an array as a step function.
|
|
"""
|
|
x = np.array(values, copy=True)
|
|
x.sort()
|
|
x.shape = np.product(x.shape,axis=0)
|
|
n = x.shape[0]
|
|
y = (np.arange(n) + 1.) / n
|
|
return StepFunction(x, y)
|
|
|
|
def monotone_fn_inverter(fn, x, vectorized=True, **keywords):
|
|
"""
|
|
Given a monotone function x (no checking is done to verify monotonicity)
|
|
and a set of x values, return an linearly interpolated approximation
|
|
to its inverse from its values on x.
|
|
"""
|
|
|
|
if vectorized:
|
|
y = fn(x, **keywords)
|
|
else:
|
|
y = []
|
|
for _x in x:
|
|
y.append(fn(_x, **keywords))
|
|
y = np.array(y)
|
|
|
|
a = np.argsort(y)
|
|
|
|
return scipy.interpolate.interp1d(y[a], x[a])
|