pep8 + updated wafo.stats packages

master
Per.Andreas.Brodtkorb 10 years ago
parent 629ed411c9
commit d308357c5b

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<projectDescription> <projectDescription>
<name>google_pywafo</name> <name>pywafo</name>
<comment></comment> <comment></comment>
<projects> <projects>
</projects> </projects>
@ -10,6 +10,16 @@
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>auto,full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/wafo_stats_tests.launch</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec> </buildSpec>
<natures> <natures>
<nature>org.python.pydev.pythonNature</nature> <nature>org.python.pydev.pythonNature</nature>

@ -3,8 +3,8 @@
<pydev_project> <pydev_project>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/google_pywafo/src</path> <path>/pywafo/src</path>
</pydev_pathproperty> </pydev_pathproperty>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property> <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property> <pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
</pydev_project> </pydev_project>

@ -1,4 +1,4 @@
Metadata-Version: 1.0 Metadata-Version: 1.1
Name: wafo Name: wafo
Version: 0.1.2 Version: 0.1.2
Summary: Statistical analysis and simulation of random waves and random loads Summary: Statistical analysis and simulation of random waves and random loads

@ -4,17 +4,19 @@ gendocwafo.py
manifest manifest
setup.py setup.py
setup_old.py setup_old.py
test_all.py
src/epydoc_wafo.prj src/epydoc_wafo.prj
src/Wafo.egg-info/PKG-INFO src/Wafo.egg-info/PKG-INFO
src/Wafo.egg-info/SOURCES.txt src/Wafo.egg-info/SOURCES.txt
src/Wafo.egg-info/dependency_links.txt src/Wafo.egg-info/dependency_links.txt
src/Wafo.egg-info/top_level.txt src/Wafo.egg-info/top_level.txt
src/wafo/MSO.py
src/wafo/MSPPT.py
src/wafo/SpecData1D.mm src/wafo/SpecData1D.mm
src/wafo/__init__.py src/wafo/__init__.py
src/wafo/bitwise.py src/wafo/bitwise.py
src/wafo/c_library.pyd src/wafo/c_library.pyd
src/wafo/c_library.so src/wafo/c_library.so
src/wafo/containers.py
src/wafo/cov2mod.pyd src/wafo/cov2mod.pyd
src/wafo/dctpack.py src/wafo/dctpack.py
src/wafo/definitions.py src/wafo/definitions.py
@ -28,6 +30,7 @@ src/wafo/info.py
src/wafo/integrate.py src/wafo/integrate.py
src/wafo/interpolate.py src/wafo/interpolate.py
src/wafo/kdetools.py src/wafo/kdetools.py
src/wafo/magic.py
src/wafo/meshgrid.py src/wafo/meshgrid.py
src/wafo/misc.py src/wafo/misc.py
src/wafo/mvn.pyd src/wafo/mvn.pyd
@ -39,20 +42,26 @@ src/wafo/objects.py
src/wafo/plotbackend.py src/wafo/plotbackend.py
src/wafo/polynomial.py src/wafo/polynomial.py
src/wafo/polynomial_old.py src/wafo/polynomial_old.py
src/wafo/pychip.py src/wafo/powerpoint.py
src/wafo/resize_problem.py
src/wafo/rindmod.pyd src/wafo/rindmod.pyd
src/wafo/rindmod.so src/wafo/rindmod.so
src/wafo/sg_filter.py src/wafo/sg_filter.py
src/wafo/version.py src/wafo/version.py
src/wafo/wafodata.py src/wafo/wafodata.py
src/wafo/wtraits.py
src/wafo/wtraits2.py
src/wafo/wtraits3.py
src/wafo.egg-info/SOURCES.txt src/wafo.egg-info/SOURCES.txt
src/wafo/covariance/__init__.py src/wafo/covariance/__init__.py
src/wafo/covariance/core.py src/wafo/covariance/core.py
src/wafo/data/__init__.py src/wafo/data/__init__.py
src/wafo/data/__init__.pyc
src/wafo/data/atlantic.dat src/wafo/data/atlantic.dat
src/wafo/data/gfaks89.dat src/wafo/data/gfaks89.dat
src/wafo/data/gfaksr89.dat src/wafo/data/gfaksr89.dat
src/wafo/data/info.py src/wafo/data/info.py
src/wafo/data/info.pyc
src/wafo/data/info.~py src/wafo/data/info.~py
src/wafo/data/japansea.dat src/wafo/data/japansea.dat
src/wafo/data/northsea.dat src/wafo/data/northsea.dat
@ -276,30 +285,47 @@ src/wafo/source/test_f90/types.f90
src/wafo/source/test_f90/types.mod src/wafo/source/test_f90/types.mod
src/wafo/spectrum/__init__.py src/wafo/spectrum/__init__.py
src/wafo/spectrum/core.py src/wafo/spectrum/core.py
src/wafo/spectrum/dispersion_relation.py
src/wafo/spectrum/models.py src/wafo/spectrum/models.py
src/wafo/spectrum/test/test_dispersion_relation.py
src/wafo/spectrum/test/test_models.py src/wafo/spectrum/test/test_models.py
src/wafo/spectrum/test/test_models.pyc
src/wafo/spectrum/test/test_specdata1d.py src/wafo/spectrum/test/test_specdata1d.py
src/wafo/spectrum/test/test_specdata1d.pyc
src/wafo/stats/__init__.py src/wafo/stats/__init__.py
src/wafo/stats/core.py src/wafo/stats/core.py
src/wafo/stats/distributions.py src/wafo/stats/distributions.py
src/wafo/stats/distributions_juli2010.py
src/wafo/stats/estimation.py src/wafo/stats/estimation.py
src/wafo/stats/kde_test.py
src/wafo/stats/misc.py src/wafo/stats/misc.py
src/wafo/stats/six.py
src/wafo/stats/sklearn_test.py
src/wafo/stats/twolumps.py
src/wafo/stats/tests/test_distributions.py src/wafo/stats/tests/test_distributions.py
src/wafo/stats/tests/test_estimation.py src/wafo/stats/tests/test_estimation.py
src/wafo/test/__init__.py src/wafo/test/__init__.py
src/wafo/test/__init__.pyc
src/wafo/test/test_gaussian.py src/wafo/test/test_gaussian.py
src/wafo/test/test_gaussian.pyc
src/wafo/test/test_kdetools.py src/wafo/test/test_kdetools.py
src/wafo/test/test_kdetools.pyc
src/wafo/test/test_misc.py src/wafo/test/test_misc.py
src/wafo/test/test_misc.pyc
src/wafo/test/test_objects.py src/wafo/test/test_objects.py
src/wafo/test/test_objects.pyc
src/wafo/transform/__init__.py src/wafo/transform/__init__.py
src/wafo/transform/core.py src/wafo/transform/core.py
src/wafo/transform/models.py src/wafo/transform/models.py
src/wafo/transform/models.~py src/wafo/transform/models.~py
src/wafo/transform/test/__init__.py src/wafo/transform/test/__init__.py
src/wafo/transform/test/__init__.pyc
src/wafo/transform/test/test_models.py src/wafo/transform/test/test_models.py
src/wafo/transform/test/test_models.pyc
src/wafo/transform/test/test_trdata.py src/wafo/transform/test/test_trdata.py
src/wafo/transform/test/test_trdata.pyc
src/wafo/wave_theory/__init__.py src/wafo/wave_theory/__init__.py
src/wafo/wave_theory/core.py src/wafo/wave_theory/core.py
src/wafo/wave_theory/dispersion_relation.py src/wafo/wave_theory/dispersion_relation.py
src/wafo/wave_theory/test/__init__.py
src/wafo/wave_theory/test/__init__.pyc
src/wafo/wave_theory/test/test_dispersion_relation.py
src/wafo/wave_theory/test/test_dispersion_relation.pyc

@ -1,26 +1,27 @@
from __future__ import division, print_function, absolute_import
from info import __doc__ from .info import __doc__
import misc from . import misc
import data from . import data
import demos from . import demos
import kdetools from . import kdetools
import objects from . import objects
import spectrum from . import spectrum
import transform from . import transform
import definitions from . import definitions
import polynomial from . import polynomial
import stats from . import stats
import interpolate from . import interpolate
import dctpack from . import dctpack
try: try:
import fig from . import fig
except ImportError: except ImportError:
print 'fig import only supported on Windows' print('fig import only supported on Windows')
try: try:
from wafo.version import version as __version__ from wafo.version import version as __version__
except ImportError: except ImportError:
__version__='nobuilt' __version__ = 'nobuilt'
from numpy.testing import Tester from numpy.testing import Tester
test = Tester().test test = Tester().test

@ -1,98 +1,104 @@
''' '''
Module extending the bitoperator capabilites of numpy Module extending the bitoperator capabilites of numpy
''' '''
from numpy import (bitwise_and, bitwise_or, #@UnresolvedImport from numpy import (bitwise_and, bitwise_or,
bitwise_not, binary_repr, #@UnresolvedImport @UnusedImport bitwise_not, binary_repr, # @UnusedImport
bitwise_xor, where, arange) #@UnresolvedImport @UnusedImport bitwise_xor, where, arange) # @UnusedImport
#import numpy as np __all__ = ['bitwise_and', 'bitwise_or', 'bitwise_not', 'binary_repr',
__all__ = ['bitwise_and', 'bitwise_or', 'bitwise_not', 'binary_repr', 'bitwise_xor', 'getbit', 'setbit', 'getbits', 'setbits']
'bitwise_xor', 'getbit', 'setbit', 'getbits', 'setbits']
def getbit(i, bit): def getbit(i, bit):
""" """
Get bit at specified position Get bit at specified position
Parameters Parameters
---------- ----------
i : array-like of uints, longs i : array-like of uints, longs
value to value to
bit : array-like of ints or longs bit : array-like of ints or longs
bit position between 0 and the number of bits in the uint class. bit position between 0 and the number of bits in the uint class.
Examples Examples
-------- --------
>>> import numpy as np >>> import numpy as np
>>> binary_repr(13) >>> binary_repr(13)
'1101' '1101'
>>> getbit(13,np.arange(3,-1,-1)) >>> getbit(13,np.arange(3,-1,-1))
array([1, 1, 0, 1]) array([1, 1, 0, 1])
>>> getbit(5, np.r_[0:4]) >>> getbit(5, np.r_[0:4])
array([1, 0, 1, 0]) array([1, 0, 1, 0])
""" """
return bitwise_and(i, 1 << bit) >> bit return bitwise_and(i, 1 << bit) >> bit
def getbits(i, numbits=8):
""" def getbits(i, numbits=8):
Returns bits of i in a list """
""" Returns bits of i in a list
return getbit(i, arange(0, numbits)) """
return getbit(i, arange(0, numbits))
def setbit(i, bit, value=1):
"""
Set bit at specified position def setbit(i, bit, value=1):
"""
Parameters Set bit at specified position
----------
i : array-like of uints, longs Parameters
value to ----------
bit : array-like of ints or longs i : array-like of uints, longs
bit position between 0 and the number of bits in the uint class. value to
value : array-like of 0 or 1 bit : array-like of ints or longs
value to set the bit to. bit position between 0 and the number of bits in the uint class.
value : array-like of 0 or 1
Examples value to set the bit to.
--------
Set bit fifth bit in the five bit binary binary representation of 9 (01001) Examples
yields 25 (11001) --------
>>> setbit(9,4) Set bit fifth bit in the five bit binary binary representation of 9 (01001)
array(25) yields 25 (11001)
""" >>> setbit(9,4)
val1 = 1 << bit array(25)
val0 = bitwise_not(val1) """
return where((value==0) & (i==i) & (bit==bit), bitwise_and(i, val0), val1 = 1 << bit
bitwise_or(i, val1)) val0 = bitwise_not(val1)
return where((value == 0) & (i == i) & (bit == bit), bitwise_and(i, val0),
def setbits(bitlist): bitwise_or(i, val1))
"""
Set bits of val to values in bitlist
def setbits(bitlist):
Example """
------- Set bits of val to values in bitlist
>>> setbits([1,1])
3 Example
>>> setbits([1,0]) -------
1 >>> setbits([1,1])
""" 3
# return bitlist[7]<<7 | bitlist[6]<<6 | bitlist[5]<<5 | bitlist[4]<<4 | \ >>> setbits([1,0])
# bitlist[3]<<3 | bitlist[2]<<2 | bitlist[1]<<1 | bitlist[0] 1
val = 0 """
for i, j in enumerate(bitlist): # return bitlist[7]<<7 | bitlist[6]<<6 | bitlist[5]<<5 | bitlist[4]<<4 | \
val |= j << i # bitlist[3]<<3 | bitlist[2]<<2 | bitlist[1]<<1 | bitlist[0]
return val val = 0
for i, j in enumerate(bitlist):
def test_docstrings(): val |= j << i
import doctest return val
doctest.testmod()
if __name__ == '__main__':
test_docstrings() def test_docstrings():
import doctest
# t = set(np.arange(8),1,1) print('Testing docstrings in %s' % __file__)
# t=get(0x84,np.arange(0,8)) doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
# t=getbyte(0x84)
# t=get(0x84,[0, 1, 2, 3, 4, 5, 6, 7]) if __name__ == '__main__':
# t=get(0x20, 6) test_docstrings()
# bit = [0 for i in range(8)]
# bit[7]=1 # t = set(np.arange(8),1,1)
# t = setbits(bit) # t=get(0x84,np.arange(0,8))
# print(hex(t)) # t=getbyte(0x84)
# t=get(0x84,[0, 1, 2, 3, 4, 5, 6, 7])
# t=get(0x20, 6)
# bit = [0 for i in range(8)]
# bit[7]=1
# t = setbits(bit)
# print(hex(t))

@ -1,34 +1,42 @@
import warnings import warnings
from graphutil import cltext from graphutil import cltext # @UnresolvedImport
from plotbackend import plotbackend from plotbackend import plotbackend
from time import gmtime, strftime from time import gmtime, strftime
import numpy as np import numpy as np
from scipy.integrate.quadrature import cumtrapz #@UnresolvedImport from scipy.integrate.quadrature import cumtrapz # @UnresolvedImport
from scipy import interpolate from scipy import interpolate
from scipy import integrate from scipy import integrate
__all__ = ['PlotData', 'AxisLabels'] __all__ = ['PlotData', 'AxisLabels']
def empty_copy(obj): def empty_copy(obj):
class Empty(obj.__class__): class Empty(obj.__class__):
def __init__(self): def __init__(self):
pass pass
newcopy = Empty() newcopy = Empty()
newcopy.__class__ = obj.__class__ newcopy.__class__ = obj.__class__
return newcopy return newcopy
def _set_seed(iseed): def _set_seed(iseed):
if iseed != None: if iseed is not None:
try: try:
np.random.set_state(iseed) np.random.set_state(iseed)
except: except:
np.random.seed(iseed) np.random.seed(iseed)
def now(): def now():
''' '''
Return current date and time as a string Return current date and time as a string
''' '''
return strftime("%a, %d %b %Y %H:%M:%S", gmtime()) return strftime("%a, %d %b %Y %H:%M:%S", gmtime())
class PlotData(object): class PlotData(object):
''' '''
Container class for data with interpolation and plotting methods Container class for data with interpolation and plotting methods
@ -48,7 +56,7 @@ class PlotData(object):
copy : return a copy of object copy : return a copy of object
eval_points : interpolate data at given points and return the result eval_points : interpolate data at given points and return the result
plot : plot data on given axis and the object handles plot : plot data on given axis and the object handles
Example Example
------- -------
>>> import numpy as np >>> import numpy as np
@ -66,6 +74,7 @@ class PlotData(object):
>>> h = d3.plot() >>> h = d3.plot()
''' '''
def __init__(self, data=None, args=None, *args2, **kwds): def __init__(self, data=None, args=None, *args2, **kwds):
self.data = data self.data = data
self.args = args self.args = args
@ -76,20 +85,20 @@ class PlotData(object):
self.plot_kwds_children = kwds.pop('plot_kwds_children', {}) self.plot_kwds_children = kwds.pop('plot_kwds_children', {})
self.plot_args = kwds.pop('plot_args', []) self.plot_args = kwds.pop('plot_args', [])
self.plot_kwds = kwds.pop('plot_kwds', {}) self.plot_kwds = kwds.pop('plot_kwds', {})
self.labels = AxisLabels(**kwds) self.labels = AxisLabels(**kwds)
if not self.plotter: if not self.plotter:
self.setplotter(kwds.get('plotmethod', None)) self.setplotter(kwds.get('plotmethod', None))
def copy(self): def copy(self):
newcopy = empty_copy(self) newcopy = empty_copy(self)
newcopy.__dict__.update(self.__dict__) newcopy.__dict__.update(self.__dict__)
return newcopy return newcopy
def eval_points(self, *points, **kwds): def eval_points(self, *points, **kwds):
''' '''
Interpolate data at points Interpolate data at points
Parameters Parameters
---------- ----------
points : ndarray of float, shape (..., ndim) points : ndarray of float, shape (..., ndim)
@ -98,9 +107,9 @@ class PlotData(object):
method : {'linear', 'nearest', 'cubic'} method : {'linear', 'nearest', 'cubic'}
Method of interpolation. One of Method of interpolation. One of
- ``nearest``: return the value at the data point closest to - ``nearest``: return the value at the data point closest to
the point of interpolation. the point of interpolation.
- ``linear``: tesselate the input point set to n-dimensional - ``linear``: tesselate the input point set to n-dimensional
simplices, and interpolate linearly on each simplex. simplices, and interpolate linearly on each simplex.
- ``cubic`` (1-D): return the value detemined from a cubic - ``cubic`` (1-D): return the value detemined from a cubic
spline. spline.
- ``cubic`` (2-D): return the value determined from a - ``cubic`` (2-D): return the value determined from a
@ -111,28 +120,30 @@ class PlotData(object):
convex hull of the input points. If not provided, then the convex hull of the input points. If not provided, then the
default is ``nan``. This option has no effect for the default is ``nan``. This option has no effect for the
'nearest' method. 'nearest' method.
Examples Examples
-------- --------
>>> import numpy as np >>> import numpy as np
>>> x = np.arange(-2, 2, 0.4) >>> x = np.arange(-2, 2, 0.4)
>>> xi = np.arange(-2, 2, 0.1) >>> xi = np.arange(-2, 2, 0.1)
>>> d = PlotData(np.sin(x), x, xlab='x', ylab='sin', title='sinus', plot_args=['r.']) >>> d = PlotData(np.sin(x), x, xlab='x', ylab='sin', title='sinus',
... plot_args=['r.'])
>>> di = PlotData(d.eval_points(xi), xi) >>> di = PlotData(d.eval_points(xi), xi)
>>> hi = di.plot() >>> hi = di.plot()
>>> h = d.plot() >>> h = d.plot()
See also See also
-------- --------
scipy.interpolate.griddata scipy.interpolate.griddata
''' '''
options = dict(method='linear') options = dict(method='linear')
options.update(**kwds) options.update(**kwds)
if isinstance(self.args, (list, tuple)): # Multidimensional data if isinstance(self.args, (list, tuple)): # Multidimensional data
ndim = len(self.args) ndim = len(self.args)
if ndim < 2: if ndim < 2:
msg = '''Unable to determine plotter-type, because len(self.args)<2. msg = '''
Unable to determine plotter-type, because len(self.args)<2.
If the data is 1D, then self.args should be a vector! If the data is 1D, then self.args should be a vector!
If the data is 2D, then length(self.args) should be 2. If the data is 2D, then length(self.args) should be 2.
If the data is 3D, then length(self.args) should be 3. If the data is 3D, then length(self.args) should be 3.
@ -140,10 +151,12 @@ class PlotData(object):
warnings.warn(msg) warnings.warn(msg)
else: else:
xi = np.meshgrid(*self.args) xi = np.meshgrid(*self.args)
return interpolate.griddata(xi, self.data.ravel(), points, **options) return interpolate.griddata(
else: #One dimensional data xi, self.data.ravel(), points, **options)
return interpolate.griddata(self.args, self.data, points, **options) else: # One dimensional data
return interpolate.griddata(
self.args, self.data, points, **options)
def integrate(self, a, b, **kwds): def integrate(self, a, b, **kwds):
''' '''
>>> x = np.linspace(0,5,60) >>> x = np.linspace(0,5,60)
@ -151,50 +164,58 @@ class PlotData(object):
>>> d.dataCI = np.vstack((d.data*.9,d.data*1.1)).T >>> d.dataCI = np.vstack((d.data*.9,d.data*1.1)).T
>>> d.integrate(0,np.pi/2, return_ci=True) >>> d.integrate(0,np.pi/2, return_ci=True)
array([ 0.99940055, 0.85543644, 1.04553343]) array([ 0.99940055, 0.85543644, 1.04553343])
''' '''
method = kwds.pop('method','trapz') method = kwds.pop('method', 'trapz')
fun = getattr(integrate, method) fun = getattr(integrate, method)
if isinstance(self.args, (list, tuple)): # Multidimensional data if isinstance(self.args, (list, tuple)): # Multidimensional data
raise NotImplementedError('integration for ndim>1 not implemented') raise NotImplementedError('integration for ndim>1 not implemented')
#ndim = len(self.args) #ndim = len(self.args)
#if ndim < 2: # if ndim < 2:
# msg = '''Unable to determine plotter-type, because len(self.args)<2. # msg = '''Unable to determine plotter-type, because
# len(self.args)<2.
# If the data is 1D, then self.args should be a vector! # If the data is 1D, then self.args should be a vector!
# If the data is 2D, then length(self.args) should be 2. # If the data is 2D, then length(self.args) should be 2.
# If the data is 3D, then length(self.args) should be 3. # If the data is 3D, then length(self.args) should be 3.
# Unless you fix this, the plot methods will not work!''' # Unless you fix this, the plot methods will not work!'''
# warnings.warn(msg) # warnings.warn(msg)
# else: # else:
# return interpolate.griddata(self.args, self.data.ravel(), **kwds) # return interpolate.griddata(self.args, self.data.ravel(), **kwds)
else: #One dimensional data else: # One dimensional data
return_ci = kwds.pop('return_ci', False) return_ci = kwds.pop('return_ci', False)
x = self.args x = self.args
ix = np.flatnonzero((a<x) & (x<b) ) ix = np.flatnonzero((a < x) & (x < b))
xi = np.hstack((a, x.take(ix), b)) xi = np.hstack((a, x.take(ix), b))
fi = np.hstack((self.eval_points(a),self.data.take(ix),self.eval_points(b))) fi = np.hstack(
(self.eval_points(a),
self.data.take(ix),
self.eval_points(b)))
res = fun(fi, xi, **kwds) res = fun(fi, xi, **kwds)
if return_ci: if return_ci:
return np.hstack((res, fun(self.dataCI[ix,:].T, xi[1:-1], **kwds))) return np.hstack(
return res (res, fun(self.dataCI[ix, :].T, xi[1:-1], **kwds)))
return res
def plot(self, *args, **kwds): def plot(self, *args, **kwds):
axis = kwds.pop('axis',None) axis = kwds.pop('axis', None)
if axis is None: if axis is None:
axis = plotbackend.gca() axis = plotbackend.gca()
tmp = None tmp = None
default_plotflag = self.plot_kwds.get('plotflag',None) default_plotflag = self.plot_kwds.get('plotflag', None)
plotflag = kwds.get('plotflag', default_plotflag) plotflag = kwds.get('plotflag', default_plotflag)
if not plotflag and self.children != None: if not plotflag and self.children is not None:
axis.hold('on') axis.hold('on')
tmp = [] tmp = []
child_args = kwds.pop('plot_args_children', tuple(self.plot_args_children)) child_args = kwds.pop(
'plot_args_children',
tuple(
self.plot_args_children))
child_kwds = dict(self.plot_kwds_children).copy() child_kwds = dict(self.plot_kwds_children).copy()
child_kwds.update(kwds.pop('plot_kwds_children', {})) child_kwds.update(kwds.pop('plot_kwds_children', {}))
child_kwds['axis'] = axis child_kwds['axis'] = axis
for child in self.children: for child in self.children:
tmp1 = child(*child_args, **child_kwds) tmp1 = child(*child_args, **child_kwds)
if tmp1 != None: if tmp1 is not None:
tmp.append(tmp1) tmp.append(tmp1)
if len(tmp) == 0: if len(tmp) == 0:
tmp = None tmp = None
@ -207,12 +228,14 @@ class PlotData(object):
def setplotter(self, plotmethod=None): def setplotter(self, plotmethod=None):
''' '''
Set plotter based on the data type data_1d, data_2d, data_3d or data_nd Set plotter based on the data type:
data_1d, data_2d, data_3d or data_nd
''' '''
if isinstance(self.args, (list, tuple)): # Multidimensional data if isinstance(self.args, (list, tuple)): # Multidimensional data
ndim = len(self.args) ndim = len(self.args)
if ndim < 2: if ndim < 2:
msg = '''Unable to determine plotter-type, because len(self.args)<2. msg = '''
Unable to determine plotter-type, because len(self.args)<2.
If the data is 1D, then self.args should be a vector! If the data is 1D, then self.args should be a vector!
If the data is 2D, then length(self.args) should be 2. If the data is 2D, then length(self.args) should be 2.
If the data is 3D, then length(self.args) should be 3. If the data is 3D, then length(self.args) should be 3.
@ -223,47 +246,57 @@ class PlotData(object):
else: else:
warnings.warn('Plotter method not implemented for ndim>2') warnings.warn('Plotter method not implemented for ndim>2')
else: #One dimensional data else: # One dimensional data
self.plotter = Plotter_1d(plotmethod) self.plotter = Plotter_1d(plotmethod)
def show(self): def show(self, *args, **kwds):
self.plotter.show() self.plotter.show(*args, **kwds)
__call__ = plot __call__ = plot
interpolate = eval_points interpolate = eval_points
class AxisLabels: class AxisLabels:
def __init__(self, title='', xlab='', ylab='', zlab='', **kwds): def __init__(self, title='', xlab='', ylab='', zlab='', **kwds):
self.title = title self.title = title
self.xlab = xlab self.xlab = xlab
self.ylab = ylab self.ylab = ylab
self.zlab = zlab self.zlab = zlab
def __repr__(self): def __repr__(self):
return self.__str__() return self.__str__()
def __str__(self): def __str__(self):
return '%s\n%s\n%s\n%s\n' % (self.title, self.xlab, self.ylab, self.zlab) return '%s\n%s\n%s\n%s\n' % (
self.title, self.xlab, self.ylab, self.zlab)
def copy(self): def copy(self):
newcopy = empty_copy(self) newcopy = empty_copy(self)
newcopy.__dict__.update(self.__dict__) newcopy.__dict__.update(self.__dict__)
return newcopy return newcopy
def labelfig(self, axis=None): def labelfig(self, axis=None):
if axis is None: if axis is None:
axis = plotbackend.gca() axis = plotbackend.gca()
try: try:
h = [] h = []
for fun, txt in zip(('set_title', 'set_xlabel','set_ylabel', 'set_ylabel'), for fun, txt in zip(
(self.title,self.xlab,self.ylab, self.zlab)): ('set_title', 'set_xlabel', 'set_ylabel', 'set_ylabel'),
(self.title, self.xlab, self.ylab, self.zlab)):
if txt: if txt:
if fun.startswith('set_title'): if fun.startswith('set_title'):
title0 = axis.get_title() title0 = axis.get_title()
txt = title0 +'\n' + txt if title0.lower().strip() != txt.lower().strip():
txt = title0 + '\n' + txt
h.append(getattr(axis, fun)(txt)) h.append(getattr(axis, fun)(txt))
return h return h
except: except:
pass pass
class Plotter_1d(object): class Plotter_1d(object):
""" """
Parameters Parameters
@ -280,6 +313,7 @@ class Plotter_1d(object):
step : stair-step plot step : stair-step plot
scatter : scatter plot scatter : scatter plot
""" """
def __init__(self, plotmethod='plot'): def __init__(self, plotmethod='plot'):
self.plotfun = None self.plotfun = None
if plotmethod is None: if plotmethod is None:
@ -290,12 +324,12 @@ class Plotter_1d(object):
# self.plotfun = getattr(plotbackend, plotmethod) # self.plotfun = getattr(plotbackend, plotmethod)
# except: # except:
# pass # pass
def show(self): def show(self, *args, **kwds):
plotbackend.show() plotbackend.show(*args, **kwds)
def plot(self, wdata, *args, **kwds): def plot(self, wdata, *args, **kwds):
axis = kwds.pop('axis',None) axis = kwds.pop('axis', None)
if axis is None: if axis is None:
axis = plotbackend.gca() axis = plotbackend.gca()
plotflag = kwds.pop('plotflag', False) plotflag = kwds.pop('plotflag', False)
@ -314,79 +348,95 @@ class Plotter_1d(object):
h1 = plotfun(*args1, **kwds) h1 = plotfun(*args1, **kwds)
h2 = wdata.labels.labelfig(axis) h2 = wdata.labels.labelfig(axis)
return h1, h2 return h1, h2
def _plot(self, axis, plotflag, wdata, *args, **kwds): def _plot(self, axis, plotflag, wdata, *args, **kwds):
x = wdata.args x = wdata.args
data = transformdata(x, wdata.data, plotflag) data = transformdata(x, wdata.data, plotflag)
dataCI = getattr(wdata, 'dataCI', ()) dataCI = getattr(wdata, 'dataCI', ())
h1 = plot1d(axis, x, data, dataCI, plotflag, *args, **kwds) h1 = plot1d(axis, x, data, dataCI, plotflag, *args, **kwds)
return h1 return h1
__call__ = plot __call__ = plot
def plot1d(axis, args, data, dataCI, plotflag, *varargin, **kwds): def plot1d(axis, args, data, dataCI, plotflag, *varargin, **kwds):
plottype = np.mod(plotflag, 10) plottype = np.mod(plotflag, 10)
if plottype == 0: # % No plotting if plottype == 0: # % No plotting
return [] return []
elif plottype == 1: elif plottype == 1:
H = axis.plot(args, data, *varargin, **kwds) H = axis.plot(args, data, *varargin, **kwds)
elif plottype == 2: elif plottype == 2:
H = axis.step(args, data, *varargin, **kwds) H = axis.step(args, data, *varargin, **kwds)
elif plottype == 3: elif plottype == 3:
H = axis.stem(args, data, *varargin, **kwds) H = axis.stem(args, data, *varargin, **kwds)
elif plottype == 4: elif plottype == 4:
H = axis.errorbar(args, data, yerr=[dataCI[:,0] - data, dataCI[:,1] - data], *varargin, **kwds) H = axis.errorbar(
elif plottype == 5: args,
data,
yerr=[
dataCI[
:,
0] - data,
dataCI[
:,
1] - data],
*varargin,
**kwds)
elif plottype == 5:
H = axis.bar(args, data, *varargin, **kwds) H = axis.bar(args, data, *varargin, **kwds)
elif plottype == 6: elif plottype == 6:
level = 0 level = 0
if np.isfinite(level): if np.isfinite(level):
H = axis.fill_between(args, data, level, *varargin, **kwds); H = axis.fill_between(args, data, level, *varargin, **kwds)
else: else:
H = axis.fill_between(args, data, *varargin, **kwds); H = axis.fill_between(args, data, *varargin, **kwds)
elif plottype==7: elif plottype == 7:
H = axis.plot(args, data, *varargin, **kwds) H = axis.plot(args, data, *varargin, **kwds)
H = axis.fill_between(args, dataCI[:,0], dataCI[:,1], alpha=0.2, color='r'); H = axis.fill_between(
args, dataCI[
:, 0], dataCI[
:, 1], alpha=0.2, color='r')
scale = plotscale(plotflag) scale = plotscale(plotflag)
logXscale = 'x' in scale logXscale = 'x' in scale
logYscale = 'y' in scale logYscale = 'y' in scale
logZscale = 'z' in scale logZscale = 'z' in scale
if logXscale: if logXscale:
axis.set(xscale='log') axis.set(xscale='log')
if logYscale: if logYscale:
axis.set(yscale='log') axis.set(yscale='log')
if logZscale: if logZscale:
axis.set(zscale='log') axis.set(zscale='log')
transFlag = np.mod(plotflag // 10, 10) transFlag = np.mod(plotflag // 10, 10)
logScale = logXscale or logYscale or logZscale logScale = logXscale or logYscale or logZscale
if logScale or (transFlag == 5 and not logScale): if logScale or (transFlag == 5 and not logScale):
ax = list(axis.axis()) ax = list(axis.axis())
fmax1 = data.max() fmax1 = data.max()
if transFlag == 5 and not logScale: if transFlag == 5 and not logScale:
ax[3] = 11 * np.log10(fmax1) ax[3] = 11 * np.log10(fmax1)
ax[2] = ax[3] - 40 ax[2] = ax[3] - 40
else: else:
ax[3] = 1.15 * fmax1; ax[3] = 1.15 * fmax1
ax[2] = ax[3] * 1e-4; ax[2] = ax[3] * 1e-4
axis.axis(ax) axis.axis(ax)
if np.any(dataCI) and plottype < 3: if np.any(dataCI) and plottype < 3:
axis.hold(True) axis.hold(True)
plot1d(axis, args, dataCI, (), plotflag, 'r--'); plot1d(axis, args, dataCI, (), plotflag, 'r--')
return H return H
def plotscale(plotflag): def plotscale(plotflag):
''' '''
Return plotscale from plotflag Return plotscale from plotflag
CALL scale = plotscale(plotflag) CALL scale = plotscale(plotflag)
plotflag = integer defining plotscale. plotflag = integer defining plotscale.
Let scaleId = floor(plotflag/100). Let scaleId = floor(plotflag/100).
If scaleId < 8 then: If scaleId < 8 then:
0 'linear' : Linear scale on all axes. 0 'linear' : Linear scale on all axes.
1 'xlog' : Log scale on x-axis. 1 'xlog' : Log scale on x-axis.
@ -400,16 +450,16 @@ def plotscale(plotflag):
if (mod(scaleId,10)>0) : Log scale on x-axis. if (mod(scaleId,10)>0) : Log scale on x-axis.
if (mod(floor(scaleId/10),10)>0) : Log scale on y-axis. if (mod(floor(scaleId/10),10)>0) : Log scale on y-axis.
if (mod(floor(scaleId/100),10)>0) : Log scale on z-axis. if (mod(floor(scaleId/100),10)>0) : Log scale on z-axis.
scale = string defining plotscale valid options are: scale = string defining plotscale valid options are:
'linear', 'xlog', 'ylog', 'xylog', 'zlog', 'xzlog', 'linear', 'xlog', 'ylog', 'xylog', 'zlog', 'xzlog',
'yzlog', 'xyzlog' 'yzlog', 'xyzlog'
Example Example
plotscale(100) % xlog plotscale(100) % xlog
plotscale(200) % xlog plotscale(200) % xlog
plotscale(1000) % ylog plotscale(1000) % ylog
See also plotscale See also plotscale
''' '''
scaleId = plotflag // 100 scaleId = plotflag // 100
@ -418,13 +468,22 @@ def plotscale(plotflag):
logYscaleId = (np.mod(scaleId // 10, 10) > 0) * 2 logYscaleId = (np.mod(scaleId // 10, 10) > 0) * 2
logZscaleId = (np.mod(scaleId // 100, 10) > 0) * 4 logZscaleId = (np.mod(scaleId // 100, 10) > 0) * 4
scaleId = logYscaleId + logXscaleId + logZscaleId scaleId = logYscaleId + logXscaleId + logZscaleId
scales = ['linear', 'xlog', 'ylog', 'xylog', 'zlog', 'xzlog', 'yzlog', 'xyzlog'] scales = [
'linear',
'xlog',
'ylog',
'xylog',
'zlog',
'xzlog',
'yzlog',
'xyzlog']
return scales[scaleId] return scales[scaleId]
def transformdata(x, f, plotflag): def transformdata(x, f, plotflag):
transFlag = np.mod(plotflag // 10, 10) transFlag = np.mod(plotflag // 10, 10)
if transFlag == 0: if transFlag == 0:
data = f data = f
elif transFlag == 1: elif transFlag == 1:
@ -438,11 +497,14 @@ def transformdata(x, f, plotflag):
data = -np.log1p(-cumtrapz(f, x)) data = -np.log1p(-cumtrapz(f, x))
else: else:
if any(f < 0): if any(f < 0):
raise ValueError('Invalid plotflag: Data or dataCI is negative, but must be positive') raise ValueError('Invalid plotflag: Data or dataCI is ' +
'negative, but must be positive')
data = 10 * np.log10(f) data = 10 * np.log10(f)
return data return data
class Plotter_2d(Plotter_1d): class Plotter_2d(Plotter_1d):
""" """
Parameters Parameters
---------- ----------
@ -458,11 +520,12 @@ class Plotter_2d(Plotter_1d):
if plotmethod is None: if plotmethod is None:
plotmethod = 'contour' plotmethod = 'contour'
super(Plotter_2d, self).__init__(plotmethod) super(Plotter_2d, self).__init__(plotmethod)
def _plot(self, axis, plotflag, wdata, *args, **kwds): def _plot(self, axis, plotflag, wdata, *args, **kwds):
h1 = plot2d(axis, wdata, plotflag, *args, **kwds) h1 = plot2d(axis, wdata, plotflag, *args, **kwds)
return h1 return h1
def plot2d(axis, wdata, plotflag, *args, **kwds): def plot2d(axis, wdata, plotflag, *args, **kwds):
f = wdata f = wdata
if isinstance(wdata.args, (list, tuple)): if isinstance(wdata.args, (list, tuple)):
@ -471,72 +534,83 @@ def plot2d(axis, wdata, plotflag, *args, **kwds):
args1 = tuple((wdata.args,)) + (wdata.data,) + args args1 = tuple((wdata.args,)) + (wdata.data,) + args
if plotflag in (1, 6, 7, 8, 9): if plotflag in (1, 6, 7, 8, 9):
isPL = False isPL = False
if hasattr(f, 'clevels') and len(f.clevels) > 0: # check if contour levels is submitted # check if contour levels is submitted
if hasattr(f, 'clevels') and len(f.clevels) > 0:
CL = f.clevels CL = f.clevels
isPL = hasattr(f, 'plevels') and f.plevels is not None isPL = hasattr(f, 'plevels') and f.plevels is not None
if isPL: if isPL:
PL = f.plevels # levels defines quantile levels? 0=no 1=yes PL = f.plevels # levels defines quantile levels? 0=no 1=yes
else: else:
dmax = np.max(f.data) dmax = np.max(f.data)
dmin = np.min(f.data) dmin = np.min(f.data)
CL = dmax - (dmax - dmin) * (1 - np.r_[0.01, 0.025, 0.05, 0.1, 0.2, 0.4, 0.5, 0.75]) CL = dmax - (dmax - dmin) * \
(1 - np.r_[0.01, 0.025, 0.05, 0.1, 0.2, 0.4, 0.5, 0.75])
clvec = np.sort(CL) clvec = np.sort(CL)
if plotflag in [1, 8, 9]: if plotflag in [1, 8, 9]:
h = axis.contour(*args1, levels=CL, **kwds); h = axis.contour(*args1, levels=CL, **kwds)
#else: # else:
# [cs hcs] = contour3(f.x{:},f.f,CL,sym); # [cs hcs] = contour3(f.x{:},f.f,CL,sym);
if plotflag in (1, 6): if plotflag in (1, 6):
ncl = len(clvec) ncl = len(clvec)
if ncl > 12: if ncl > 12:
ncl = 12 ncl = 12
warnings.warn('Only the first 12 levels will be listed in table.') warnings.warn(
'Only the first 12 levels will be listed in table.')
clvals = PL[:ncl] if isPL else clvec[:ncl] clvals = PL[:ncl] if isPL else clvec[:ncl]
unused_axcl = cltext(clvals, percent=isPL) # print contour level text unused_axcl = cltext(
clvals,
percent=isPL) # print contour level text
elif any(plotflag == [7, 9]): elif any(plotflag == [7, 9]):
axis.clabel(h) axis.clabel(h)
else: else:
axis.clabel(h) axis.clabel(h)
elif plotflag == 2: elif plotflag == 2:
h = axis.mesh(*args1, **kwds) h = axis.mesh(*args1, **kwds)
elif plotflag == 3: elif plotflag == 3:
h = axis.surf(*args1, **kwds) #shading interp % flat, faceted % surfc # shading interp % flat, faceted % surfc
elif plotflag == 4: h = axis.surf(*args1, **kwds)
elif plotflag == 4:
h = axis.waterfall(*args1, **kwds) h = axis.waterfall(*args1, **kwds)
elif plotflag == 5: elif plotflag == 5:
h = axis.pcolor(*args1, **kwds) #%shading interp % flat, faceted h = axis.pcolor(*args1, **kwds) # %shading interp % flat, faceted
elif plotflag == 10: elif plotflag == 10:
h = axis.contourf(*args1, **kwds) h = axis.contourf(*args1, **kwds)
axis.clabel(h) axis.clabel(h)
plotbackend.colorbar(h) plotbackend.colorbar(h)
else: else:
raise ValueError('unknown option for plotflag') raise ValueError('unknown option for plotflag')
#if any(plotflag==(2:5)) # if any(plotflag==(2:5))
# shading(shad); # shading(shad);
#end # end
# pass # pass
def test_plotdata(): def test_plotdata():
plotbackend.ioff() plotbackend.ioff()
x = np.arange(-2, 2, 0.4) x = np.arange(-2, 2, 0.4)
xi = np.arange(-2, 2, 0.1) xi = np.arange(-2, 2, 0.1)
d = PlotData(np.sin(x), x, xlab='x', ylab='sin', title='sinus', plot_args=['r.']) d = PlotData(np.sin(x), x, xlab='x', ylab='sin', title='sinus',
plot_args=['r.'])
di = PlotData(d.eval_points(xi, method='cubic'), xi) di = PlotData(d.eval_points(xi, method='cubic'), xi)
unused_hi = di.plot() unused_hi = di.plot()
unused_h = d.plot() unused_h = d.plot()
d.show() d.show()
def test_docstrings(): def test_docstrings():
import doctest import doctest
doctest.testmod() print('Testing docstrings in %s' % __file__)
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
def main(): def main():
pass pass
if __name__ == '__main__': if __name__ == '__main__':
test_docstrings() test_docstrings()
#test_plotdata() # test_plotdata()
#main() # main()

@ -2,6 +2,6 @@
Covariance package in WAFO Toolbox. Covariance package in WAFO Toolbox.
""" """
from core import * #CovData1D from core import * # CovData1D
#import models #import models
#import dispersion_relation import estimation

File diff suppressed because it is too large Load Diff

@ -3,10 +3,11 @@ from scipy.fftpack import dct as _dct
from scipy.fftpack import idct as _idct from scipy.fftpack import idct as _idct
__all__ = ['dct', 'idct', 'dctn', 'idctn'] __all__ = ['dct', 'idct', 'dctn', 'idctn']
def dct(x, type=2, n=None, axis=-1, norm='ortho'): #@ReservedAssignment
def dct(x, type=2, n=None, axis=-1, norm='ortho'): # @ReservedAssignment
''' '''
Return the Discrete Cosine Transform of arbitrary type sequence x. Return the Discrete Cosine Transform of arbitrary type sequence x.
Parameters Parameters
---------- ----------
x : array_like x : array_like
@ -19,90 +20,93 @@ def dct(x, type=2, n=None, axis=-1, norm='ortho'): #@ReservedAssignment
Axis over which to compute the transform. Axis over which to compute the transform.
norm : {None, 'ortho'}, optional norm : {None, 'ortho'}, optional
Normalization mode (see Notes). Default is 'ortho'. Normalization mode (see Notes). Default is 'ortho'.
Returns Returns
------- -------
y : ndarray of real y : ndarray of real
The transformed input array. The transformed input array.
See Also See Also
-------- --------
idct idct
Notes Notes
----- -----
For a single dimension array ``x``, ``dct(x, norm='ortho')`` is equal to For a single dimension array ``x``, ``dct(x, norm='ortho')`` is equal to
MATLAB ``dct(x)``. MATLAB ``dct(x)``.
There are theoretically 8 types of the DCT, only the first 3 types are There are theoretically 8 types of the DCT, only the first 3 types are
implemented in scipy. 'The' DCT generally refers to DCT type 2, and 'the' implemented in scipy. 'The' DCT generally refers to DCT type 2, and 'the'
Inverse DCT generally refers to DCT type 3. Inverse DCT generally refers to DCT type 3.
type I type I
~~~~~~ ~~~~~~
There are several definitions of the DCT-I; we use the following There are several definitions of the DCT-I; we use the following
(for ``norm=None``):: (for ``norm=None``)::
N-2 N-2
y[k] = x[0] + (-1)**k x[N-1] + 2 * sum x[n]*cos(pi*k*n/(N-1)) y[k] = x[0] + (-1)**k x[N-1] + 2 * sum x[n]*cos(pi*k*n/(N-1))
n=1 n=1
Only None is supported as normalization mode for DCT-I. Note also that the Only None is supported as normalization mode for DCT-I. Note also that the
DCT-I is only supported for input size > 1 DCT-I is only supported for input size > 1
type II type II
~~~~~~~ ~~~~~~~
There are several definitions of the DCT-II; we use the following There are several definitions of the DCT-II; we use the following
(for ``norm=None``):: (for ``norm=None``)::
N-1 N-1
y[k] = 2* sum x[n]*cos(pi*k*(2n+1)/(2*N)), 0 <= k < N. y[k] = 2* sum x[n]*cos(pi*k*(2n+1)/(2*N)), 0 <= k < N.
n=0 n=0
If ``norm='ortho'``, ``y[k]`` is multiplied by a scaling factor `f`:: If ``norm='ortho'``, ``y[k]`` is multiplied by a scaling factor `f`::
f = sqrt(1/(4*N)) if k = 0, f = sqrt(1/(4*N)) if k = 0,
f = sqrt(1/(2*N)) otherwise. f = sqrt(1/(2*N)) otherwise.
Which makes the corresponding matrix of coefficients orthonormal Which makes the corresponding matrix of coefficients orthonormal
(``OO' = Id``). (``OO' = Id``).
type III type III
~~~~~~~~ ~~~~~~~~
There are several definitions, we use the following There are several definitions, we use the following
(for ``norm=None``):: (for ``norm=None``)::
N-1 N-1
y[k] = x[0] + 2 * sum x[n]*cos(pi*(k+0.5)*n/N), 0 <= k < N. y[k] = x[0] + 2 * sum x[n]*cos(pi*(k+0.5)*n/N), 0 <= k < N.
n=1 n=1
or, for ``norm='ortho'`` and 0 <= k < N:: or, for ``norm='ortho'`` and 0 <= k < N::
N-1 N-1
y[k] = x[0] / sqrt(N) + sqrt(1/N) * sum x[n]*cos(pi*(k+0.5)*n/N) y[k] = x[0] / sqrt(N) + sqrt(1/N) * sum x[n]*cos(pi*(k+0.5)*n/N)
n=1 n=1
The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up The (unnormalized) DCT-III is the inverse of the (unnormalized) DCT-II, up
to a factor `2N`. The orthonormalized DCT-III is exactly the inverse of to a factor `2N`. The orthonormalized DCT-III is exactly the inverse of
the orthonormalized DCT-II. the orthonormalized DCT-II.
References References
---------- ----------
http://en.wikipedia.org/wiki/Discrete_cosine_transform http://en.wikipedia.org/wiki/Discrete_cosine_transform
'A Fast Cosine Transform in One and Two Dimensions', by J. Makhoul, `IEEE 'A Fast Cosine Transform in One and Two Dimensions', by J. Makhoul, `IEEE
Transactions on acoustics, speech and signal processing` vol. 28(1), Transactions on acoustics, speech and signal processing` vol. 28(1),
pp. 27-34, http://dx.doi.org/10.1109/TASSP.1980.1163351 (1980). pp. 27-34, http://dx.doi.org/10.1109/TASSP.1980.1163351 (1980).
''' '''
farr = np.asfarray farr = np.asfarray
if np.iscomplex(x).any(): if np.iscomplex(x).any():
return _dct(farr(x.real), type, n, axis, norm) + 1j*_dct(farr(x.imag), type, n, axis, norm) return _dct(farr(x.real), type, n, axis, norm) + \
1j * _dct(farr(x.imag), type, n, axis, norm)
else: else:
return _dct(farr(x), type, n, axis, norm) return _dct(farr(x), type, n, axis, norm)
def idct(x, type=2, n=None, axis=-1, norm='ortho'): #@ReservedAssignment
def idct(x, type=2, n=None, axis=-1, norm='ortho'): # @ReservedAssignment
''' '''
Return the Inverse Discrete Cosine Transform of an arbitrary type sequence. Return the Inverse Discrete Cosine Transform of an arbitrary type sequence.
@ -118,136 +122,142 @@ def idct(x, type=2, n=None, axis=-1, norm='ortho'): #@ReservedAssignment
Axis over which to compute the transform. Axis over which to compute the transform.
norm : {None, 'ortho'}, optional norm : {None, 'ortho'}, optional
Normalization mode (see Notes). Default is 'ortho'. Normalization mode (see Notes). Default is 'ortho'.
Returns Returns
------- -------
y : ndarray of real y : ndarray of real
The transformed input array. The transformed input array.
See Also See Also
-------- --------
dct dct
Notes Notes
----- -----
For a single dimension array `x`, ``idct(x, norm='ortho')`` is equal to For a single dimension array `x`, ``idct(x, norm='ortho')`` is equal to
matlab ``idct(x)``. matlab ``idct(x)``.
'The' IDCT is the IDCT of type 2, which is the same as DCT of type 3. 'The' IDCT is the IDCT of type 2, which is the same as DCT of type 3.
IDCT of type 1 is the DCT of type 1, IDCT of type 2 is the DCT of type 3, IDCT of type 1 is the DCT of type 1, IDCT of type 2 is the DCT of type 3,
and IDCT of type 3 is the DCT of type 2. For the definition of these types, and IDCT of type 3 is the DCT of type 2. For the definition of these types,
see `dct`. see `dct`.
''' '''
farr = np.asarray farr = np.asarray
if np.iscomplex(x).any(): if np.iscomplex(x).any():
return _idct(farr(x.real), type, n, axis, norm) + 1j*_idct(farr(x.imag), type, n, axis, norm) return _idct(farr(x.real), type, n, axis, norm) + \
1j * _idct(farr(x.imag), type, n, axis, norm)
else: else:
return _idct(farr(x), type, n, axis, norm) return _idct(farr(x), type, n, axis, norm)
def dctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
def dctn(x, type=2, axis=None, norm='ortho'): # @ReservedAssignment
''' '''
DCTN N-D discrete cosine transform. DCTN N-D discrete cosine transform.
Y = DCTN(X) returns the discrete cosine transform of X. The array Y is Y = DCTN(X) returns the discrete cosine transform of X. The array Y is
the same size as X and contains the discrete cosine transform the same size as X and contains the discrete cosine transform
coefficients. This transform can be inverted using IDCTN. coefficients. This transform can be inverted using IDCTN.
DCTN(X,axis) applies the DCTN operation across the dimension axis. DCTN(X,axis) applies the DCTN operation across the dimension axis.
Class Support Class Support
------------- -------------
Input array can be numeric or logical. The returned array is of class Input array can be numeric or logical. The returned array is of class
double. double.
Reference Reference
--------- ---------
Narasimha M. et al, On the computation of the discrete cosine Narasimha M. et al, On the computation of the discrete cosine
transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936. transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936.
Example Example
------- -------
RGB = imread('autumn.tif'); RGB = imread('autumn.tif');
I = rgb2gray(RGB); I = rgb2gray(RGB);
J = dctn(I); J = dctn(I);
imshow(log(abs(J)),[]), colormap(jet), colorbar imshow(log(abs(J)),[]), colormap(jet), colorbar
The commands below set values less than magnitude 10 in the DCT matrix The commands below set values less than magnitude 10 in the DCT matrix
to zero, then reconstruct the image using the inverse DCT. to zero, then reconstruct the image using the inverse DCT.
J(abs(J)<10) = 0; J(abs(J)<10) = 0;
K = idctn(J); K = idctn(J);
figure, imshow(I) figure, imshow(I)
figure, imshow(K,[0 255]) figure, imshow(K,[0 255])
See also See also
-------- --------
idctn, dct, idct idctn, dct, idct
''' '''
y = np.atleast_1d(x) y = np.atleast_1d(x)
shape0 = y.shape shape0 = y.shape
if axis is None: if axis is None:
y = y.squeeze() # Working across singleton dimensions is useless y = y.squeeze() # Working across singleton dimensions is useless
ndim = y.ndim ndim = y.ndim
isvector = max(shape0)==y.size isvector = max(shape0) == y.size
if isvector: if isvector:
if ndim==1: if ndim == 1:
y = np.atleast_2d(y) y = np.atleast_2d(y)
y = y.T y = y.T
elif y.shape[0]==1: elif y.shape[0] == 1:
if axis==0: if axis == 0:
return x return x
elif axis==1: elif axis == 1:
axis=0 axis = 0
y = y.T y = y.T
elif axis==1: elif axis == 1:
return y return y
if np.iscomplex(y).any(): if np.iscomplex(y).any():
y = dctn(y.real, type, axis, norm) + 1j*dctn(y.imag, type, axis, norm) y = dctn(y.real, type, axis, norm) + 1j * \
dctn(y.imag, type, axis, norm)
else: else:
y = np.asfarray(y) y = np.asfarray(y)
for dim in range(ndim): for dim in range(ndim):
y = y.transpose(np.roll(range(y.ndim), -1)) y = y.transpose(np.roll(range(y.ndim), -1))
#y = shiftdim(y,1) #y = shiftdim(y,1)
if axis is not None and dim!=axis: if axis is not None and dim != axis:
continue continue
y = _dct(y, type, norm=norm) y = _dct(y, type, norm=norm)
return y.reshape(shape0) return y.reshape(shape0)
def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
def idctn(x, type=2, axis=None, norm='ortho'): # @ReservedAssignment
y = np.atleast_1d(x) y = np.atleast_1d(x)
shape0 = y.shape shape0 = y.shape
if axis is None: if axis is None:
y = y.squeeze() # Working across singleton dimensions is useless y = y.squeeze() # Working across singleton dimensions is useless
ndim = y.ndim ndim = y.ndim
isvector = max(shape0)==y.size isvector = max(shape0) == y.size
if isvector: if isvector:
if ndim==1: if ndim == 1:
y = np.atleast_2d(y) y = np.atleast_2d(y)
y = y.T y = y.T
elif y.shape[0]==1: elif y.shape[0] == 1:
if axis==0: if axis == 0:
return x return x
elif axis==1: elif axis == 1:
axis=0 axis = 0
y = y.T y = y.T
elif axis==1: elif axis == 1:
return y return y
if np.iscomplex(y).any(): if np.iscomplex(y).any():
y = idctn(y.real, type, axis, norm) + 1j*idctn(y.imag, type, axis, norm) y = idctn(y.real, type, axis, norm) + 1j * \
idctn(y.imag, type, axis, norm)
else: else:
y = np.asfarray(y) y = np.asfarray(y)
for dim in range(ndim): for dim in range(ndim):
y = y.transpose(np.roll(range(y.ndim), -1)) y = y.transpose(np.roll(range(y.ndim), -1))
#y = shiftdim(y,1) #y = shiftdim(y,1)
if axis is not None and dim!=axis: if axis is not None and dim != axis:
continue continue
y = _idct(y, type, norm=norm) y = _idct(y, type, norm=norm)
return y.reshape(shape0) return y.reshape(shape0)
#def dct(x, n=None): # def dct(x, n=None):
# """ # """
# Discrete Cosine Transform # Discrete Cosine Transform
# #
@ -297,7 +307,7 @@ def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
# else: # else:
# return y # return y
# #
#def idct(x, n=None): # def idct(x, n=None):
# """ # """
# Inverse Discrete Cosine Transform # Inverse Discrete Cosine Transform
# #
@ -345,7 +355,8 @@ def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
# y[..., ::2] = yp[..., :n / 2] # y[..., ::2] = yp[..., :n / 2]
# y[..., ::-2] = yp[..., n / 2::] # y[..., ::-2] = yp[..., n / 2::]
# else: # else:
# yp = ifft(np.hstack((xx, np.zeros_like(xx[..., 0]), np.conj(xx[..., :0:-1])))) # yp = ifft(np.hstack((xx, np.zeros_like(xx[..., 0]),
# np.conj(xx[..., :0:-1]))))
# y = yp[..., :n] # y = yp[..., :n]
# #
# if real_x: # if real_x:
@ -353,41 +364,41 @@ def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
# else: # else:
# return y # return y
# #
#def dctn(y, axis=None, w=None): # def dctn(y, axis=None, w=None):
# ''' # '''
# DCTN N-D discrete cosine transform. # DCTN N-D discrete cosine transform.
# #
# Y = DCTN(X) returns the discrete cosine transform of X. The array Y is # Y = DCTN(X) returns the discrete cosine transform of X. The array Y is
# the same size as X and contains the discrete cosine transform # the same size as X and contains the discrete cosine transform
# coefficients. This transform can be inverted using IDCTN. # coefficients. This transform can be inverted using IDCTN.
# #
# DCTN(X,axis) applies the DCTN operation across the dimension axis. # DCTN(X,axis) applies the DCTN operation across the dimension axis.
# #
# Class Support # Class Support
# ------------- # -------------
# Input array can be numeric or logical. The returned array is of class # Input array can be numeric or logical. The returned array is of class
# double. # double.
# #
# Reference # Reference
# --------- # ---------
# Narasimha M. et al, On the computation of the discrete cosine # Narasimha M. et al, On the computation of the discrete cosine
# transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936. # transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936.
# #
# Example # Example
# ------- # -------
# RGB = imread('autumn.tif'); # RGB = imread('autumn.tif');
# I = rgb2gray(RGB); # I = rgb2gray(RGB);
# J = dctn(I); # J = dctn(I);
# imshow(log(abs(J)),[]), colormap(jet), colorbar # imshow(log(abs(J)),[]), colormap(jet), colorbar
# #
# The commands below set values less than magnitude 10 in the DCT matrix # The commands below set values less than magnitude 10 in the DCT matrix
# to zero, then reconstruct the image using the inverse DCT. # to zero, then reconstruct the image using the inverse DCT.
# #
# J(abs(J)<10) = 0; # J(abs(J)<10) = 0;
# K = idctn(J); # K = idctn(J);
# figure, imshow(I) # figure, imshow(I)
# figure, imshow(K,[0 255]) # figure, imshow(K,[0 255])
# #
# See also # See also
# -------- # --------
# idctn, dct, idct # idctn, dct, idct
@ -395,24 +406,24 @@ def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
# #
# y = np.atleast_1d(y) # y = np.atleast_1d(y)
# shape0 = y.shape # shape0 = y.shape
# #
# #
# if axis is None: # if axis is None:
# y = y.squeeze() # Working across singleton dimensions is useless # y = y.squeeze() # Working across singleton dimensions is useless
# dimy = y.ndim # dimy = y.ndim
# if dimy==1: # if dimy==1:
# y = np.atleast_2d(y) # y = np.atleast_2d(y)
# y = y.T # y = y.T
# # Some modifications are required if Y is a vector # Some modifications are required if Y is a vector
## if isvector(y): # if isvector(y):
## if y.shape[0]==1: # if y.shape[0]==1:
## if axis==0: # if axis==0:
## return y, None # return y, None
## elif axis==1: # elif axis==1:
## axis=0 # axis=0
## y = y.T ## y = y.T
## elif axis==1: # elif axis==1:
## return y, None # return y, None
# #
# if w is None: # if w is None:
# w = [0,] * dimy # w = [0,] * dimy
@ -420,19 +431,19 @@ def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
# if axis is not None and dim!=axis: # if axis is not None and dim!=axis:
# continue # continue
# n = (dimy==1)*y.size + (dimy>1)*shape0[dim] # n = (dimy==1)*y.size + (dimy>1)*shape0[dim]
# #w{dim} = exp(1i*(0:n-1)'*pi/2/n); # w{dim} = exp(1i*(0:n-1)'*pi/2/n);
# w[dim] = np.exp(1j * np.arange(n) * np.pi / (2 * n)) # w[dim] = np.exp(1j * np.arange(n) * np.pi / (2 * n))
# #
# # --- DCT algorithm --- # --- DCT algorithm ---
# if np.iscomplex(y).any(): # if np.iscomplex(y).any():
# y = dctn(np.real(y),axis,w) + 1j*dctn(np.imag(y),axis,w) # y = dctn(np.real(y),axis,w) + 1j*dctn(np.imag(y),axis,w)
# else: # else:
# for dim in range(dimy): # for dim in range(dimy):
# y = shiftdim(y,1) # y = shiftdim(y,1)
# if axis is not None and dim!=axis: # if axis is not None and dim!=axis:
# #y = shiftdim(y, 1) # y = shiftdim(y, 1)
# continue # continue
# siz = y.shape # siz = y.shape
# n = siz[-1] # n = siz[-1]
# y = y[...,np.r_[0:n:2, 2*int(n//2)-1:0:-2]] # y = y[...,np.r_[0:n:2, 2*int(n//2)-1:0:-2]]
# y = y.reshape((-1,n)) # y = y.reshape((-1,n))
@ -440,53 +451,53 @@ def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
# y = (np.fft.ifft(y, n=n, axis=1) * w[dim]).real # y = (np.fft.ifft(y, n=n, axis=1) * w[dim]).real
# y[:,0] = y[:,0]/np.sqrt(2) # y[:,0] = y[:,0]/np.sqrt(2)
# y = y.reshape(siz) # y = y.reshape(siz)
# #
# #end # end
# #end # end
# #
# return y.reshape(shape0), w # return y.reshape(shape0), w
# #
#def idctn(y, axis=None, w=None): # def idctn(y, axis=None, w=None):
# ''' # '''
# IDCTN N-D inverse discrete cosine transform. # IDCTN N-D inverse discrete cosine transform.
# X = IDCTN(Y) inverts the N-D DCT transform, returning the original # X = IDCTN(Y) inverts the N-D DCT transform, returning the original
# array if Y was obtained using Y = DCTN(X). # array if Y was obtained using Y = DCTN(X).
# #
# IDCTN(X,DIM) applies the IDCTN operation across the dimension DIM. # IDCTN(X,DIM) applies the IDCTN operation across the dimension DIM.
# #
# Class Support # Class Support
# ------------- # -------------
# Input array can be numeric or logical. The returned array is of class # Input array can be numeric or logical. The returned array is of class
# double. # double.
# #
# Reference # Reference
# --------- # ---------
# Narasimha M. et al, On the computation of the discrete cosine # Narasimha M. et al, On the computation of the discrete cosine
# transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936. # transform, IEEE Trans Comm, 26, 6, 1978, pp 934-936.
# #
# Example # Example
# ------- # -------
# RGB = imread('autumn.tif'); # RGB = imread('autumn.tif');
# I = rgb2gray(RGB); # I = rgb2gray(RGB);
# J = dctn(I); # J = dctn(I);
# imshow(log(abs(J)),[]), colormap(jet), colorbar # imshow(log(abs(J)),[]), colormap(jet), colorbar
# #
# The commands below set values less than magnitude 10 in the DCT matrix # The commands below set values less than magnitude 10 in the DCT matrix
# to zero, then reconstruct the image using the inverse DCT. # to zero, then reconstruct the image using the inverse DCT.
# #
# J(abs(J)<10) = 0; # J(abs(J)<10) = 0;
# K = idctn(J); # K = idctn(J);
# figure, imshow(I) # figure, imshow(I)
# figure, imshow(K,[0 255]) # figure, imshow(K,[0 255])
# #
# See also # See also
# -------- # --------
# dctn, idct, dct # dctn, idct, dct
# #
# -- Damien Garcia -- 2009/04, revised 2009/11 # -- Damien Garcia -- 2009/04, revised 2009/11
# website: <a # website: <a
# href="matlab:web('http://www.biomecardio.com')">www.BiomeCardio.com</a> # href="matlab:web('http://www.biomecardio.com')">www.BiomeCardio.com</a>
# #
# ---------- # ----------
# [Y,W] = IDCTN(X,DIM,W) uses and returns the weights which are used by # [Y,W] = IDCTN(X,DIM,W) uses and returns the weights which are used by
# the program. If IDCTN is required for several large arrays of same # the program. If IDCTN is required for several large arrays of same
@ -502,65 +513,64 @@ def idctn(x, type=2, axis=None, norm='ortho'): #@ReservedAssignment
# #
# y = np.atleast_1d(y) # y = np.atleast_1d(y)
# shape0 = y.shape # shape0 = y.shape
# #
# if axis is None: # if axis is None:
# y = y.squeeze() # Working across singleton dimensions is useless # y = y.squeeze() # Working across singleton dimensions is useless
# #
# dimy = y.ndim # dimy = y.ndim
# if dimy==1: # if dimy==1:
# y = np.atleast_2d(y) # y = np.atleast_2d(y)
# y = y.T # y = y.T
# # Some modifications are required if Y is a vector # Some modifications are required if Y is a vector
## if isvector(y): # if isvector(y):
## if y.shape[0]==1: # if y.shape[0]==1:
## if axis==0: # if axis==0:
## return y, None # return y, None
## elif axis==1: # elif axis==1:
## axis=0 # axis=0
## y = y.T ## y = y.T
## elif axis==1: # elif axis==1:
## return y, None # return y, None
## ##
# #
# #
# if w is None: # if w is None:
# w = [0,] * dimy # w = [0,] * dimy
# for dim in range(dimy): # for dim in range(dimy):
# if axis is not None and dim!=axis: # if axis is not None and dim!=axis:
# continue # continue
# n = (dimy==1)*y.size + (dimy>1)*shape0[dim] # n = (dimy==1)*y.size + (dimy>1)*shape0[dim]
# #w{dim} = exp(1i*(0:n-1)'*pi/2/n); # w{dim} = exp(1i*(0:n-1)'*pi/2/n);
# w[dim] = np.exp(1j * np.arange(n) * np.pi / (2 * n)) # w[dim] = np.exp(1j * np.arange(n) * np.pi / (2 * n))
# # --- IDCT algorithm --- # --- IDCT algorithm ---
# if np.iscomplex(y).any(): # if np.iscomplex(y).any():
# y = np.complex(idctn(np.real(y),axis,w),idctn(np.imag(y),axis,w)) # y = np.complex(idctn(np.real(y),axis,w),idctn(np.imag(y),axis,w))
# else: # else:
# for dim in range(dimy): # for dim in range(dimy):
# y = shiftdim(y,1) # y = shiftdim(y,1)
# if axis is not None and dim!=axis: # if axis is not None and dim!=axis:
# #y = shiftdim(y, 1) # y = shiftdim(y, 1)
# continue # continue
# siz = y.shape # siz = y.shape
# n = siz[-1] # n = siz[-1]
# #
# y = y.reshape((-1,n)) * w[dim] # y = y.reshape((-1,n)) * w[dim]
# y[:,0] = y[:,0]/np.sqrt(2) # y[:,0] = y[:,0]/np.sqrt(2)
# y = (np.fft.ifft(y, n=n, axis=1)).real # y = (np.fft.ifft(y, n=n, axis=1)).real
# y = y * np.sqrt(2*n) # y = y * np.sqrt(2*n)
# #
# I = np.empty(n,dtype=int) # I = np.empty(n,dtype=int)
# I.put(np.r_[0:n:2],np.r_[0:int(n//2)+np.remainder(n,2)]) # I.put(np.r_[0:n:2],np.r_[0:int(n//2)+np.remainder(n,2)])
# I.put(np.r_[1:n:2],np.r_[n-1:int(n//2)-1:-1]) # I.put(np.r_[1:n:2],np.r_[n-1:int(n//2)-1:-1])
# y = y[:,I] # y = y[:,I]
# #
# y = y.reshape(siz) # y = y.reshape(siz)
# #
# #
# y = y.reshape(shape0); # y = y.reshape(shape0);
# return y, w # return y, w
def no_leading_ones(x): def no_leading_ones(x):
first = 0 first = 0
for i, xi in enumerate(x): for i, xi in enumerate(x):
@ -568,43 +578,45 @@ def no_leading_ones(x):
first = i first = i
break break
return x[first:] return x[first:]
def shiftdim(x, n=None):
def shiftdim(x, n=None):
''' '''
Shift dimensions Shift dimensions
Parameters Parameters
---------- ----------
x : array x : array
n : int n : int
Notes Notes
----- -----
Shiftdim is handy for functions that intend to work along the first Shiftdim is handy for functions that intend to work along the first
non-singleton dimension of the array. non-singleton dimension of the array.
If n is None returns the array with the same number of elements as X but If n is None returns the array with the same number of elements as X but
with any leading singleton dimensions removed. with any leading singleton dimensions removed.
When n is positive, shiftdim shifts the dimensions to the left and wraps When n is positive, shiftdim shifts the dimensions to the left and wraps
the n leading dimensions to the end. the n leading dimensions to the end.
When n is negative, shiftdim shifts the dimensions to the right and pads When n is negative, shiftdim shifts the dimensions to the right and pads
with singletons. with singletons.
See also See also
-------- --------
reshape, squeeze reshape, squeeze
''' '''
if n is None: if n is None:
return x.reshape(no_leading_ones(x.shape)) return x.reshape(no_leading_ones(x.shape))
elif n>=0: elif n >= 0:
return x.transpose(np.roll(range(x.ndim), -n)) return x.transpose(np.roll(range(x.ndim), -n))
else: else:
return x.reshape((1,)*-n+x.shape) return x.reshape((1,) * -n + x.shape)
def test_dctn(): def test_dctn():
a = np.arange(12) #.reshape((3,-1)) a = np.arange(12) # .reshape((3,-1))
print('a = ', a) print('a = ', a)
print(' ') print(' ')
y = dct(a) y = dct(a)
@ -614,7 +626,7 @@ def test_dctn():
print('x = idct(y)') print('x = idct(y)')
print(x) print(x)
print(' ') print(' ')
# y1 = dct1(a) # y1 = dct1(a)
# x1 = idct1(y) # x1 = idct1(y)
# print('y1 = dct1(a)') # print('y1 = dct1(a)')
@ -622,7 +634,7 @@ def test_dctn():
# print('x1 = idct1(y)') # print('x1 = idct1(y)')
# print(x1) # print(x1)
# print(' ') # print(' ')
yn = dctn(a) yn = dctn(a)
xn = idctn(yn) xn = idctn(yn)
print('yn = dctn(a)') print('yn = dctn(a)')
@ -630,20 +642,21 @@ def test_dctn():
print('xn = idctn(yn)') print('xn = idctn(yn)')
print(xn) print(xn)
print(' ') print(' ')
# yn1 = dctn1(a) # yn1 = dctn1(a)
# xn1 = idctn1(yn1) # xn1 = idctn1(yn1)
# print('yn1 = dctn1(a)') # print('yn1 = dctn1(a)')
# print(yn1) # print(yn1)
# print('xn1 = idctn1(yn)') # print('xn1 = idctn1(yn)')
# print(xn1) # print(xn1)
def test_docstrings(): def test_docstrings():
import doctest import doctest
doctest.testmod() print('Testing docstrings in %s' % __file__)
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
if __name__ == '__main__': if __name__ == '__main__':
test_docstrings() test_docstrings()
#test_dctn() # test_dctn()

@ -1,296 +1,305 @@
""" """
WAFO defintions and numenclature WAFO defintions and numenclature
crossings : crossings :
cycle_pairs : cycle_pairs :
turning_points : turning_points :
wave_amplitudes : wave_amplitudes :
wave_periods : wave_periods :
waves : waves :
Examples Examples
-------- --------
In order to view the documentation do the following in an ipython window: In order to view the documentation do the following in an ipython window:
>>> import wafo.definitions as wd >>> import wafo.definitions as wd
>>> wd.crossings() >>> wd.crossings()
or or
>>> wd.crossings? >>> wd.crossings?
""" """
def wave_amplitudes():
r"""
Wave amplitudes and heights definitions and nomenclature def wave_amplitudes():
r"""
Definition of wave amplitudes and wave heights Wave amplitudes and heights definitions and nomenclature
---------------------------------------------
Definition of wave amplitudes and wave heights
<----- Direction of wave propagation ---------------------------------------------
<----- Direction of wave propagation
|..............c_..........|
| /| \ |
Hd | _/ | \ | Hu |..............c_..........|
M | / | \ | | /| \ |
/ \ | M / Ac | \_ | c_ Hd | _/ | \ | Hu
F \ | / \m/ | \ | / \ M | / | \ |
------d----|---u------------------d---|---u----d------ level v / \ | M / Ac | \_ | c_
\ | /| \ | / \L F \ | / \m/ | \ | / \
\_ | / | At \_|_/ ------d----|---u------------------d---|---u----d------ level v
\|/..| t \ | /| \ | / \L
t \_ | / | At \_|_/
\|/..| t
Parameters t
----------
Ac : crest amplitude Parameters
At : trough amplitude ----------
Hd : wave height as defined for down crossing waves Ac : crest amplitude
Hu : wave height as defined for up crossing waves At : trough amplitude
Hd : wave height as defined for down crossing waves
See also Hu : wave height as defined for up crossing waves
--------
waves, crossings, turning_points See also
""" --------
print(wave_amplitudes.__doc__) waves, crossings, turning_points
"""
def crossings(): print(wave_amplitudes.__doc__)
r"""
Level v crossing definitions and nomenclature
def crossings():
Definition of level v crossings r"""
------------------------------- Level v crossing definitions and nomenclature
M
. . M M Definition of level v crossings
. . . . . . -------------------------------
F d . . L M
-----------------------u-------d-------o----------------- level v . . M M
. . . . u . . . . . .
. m F d . . L
m -----------------------u-------d-------o----------------- level v
. . . . u
Let the letters 'm', 'M', 'F', 'L','d' and 'u' in the . m
figure above denote local minimum, maximum, first value, last m
value, down- and up-crossing, respectively. The remaining
sampled values are indicated with a '.'. Values that are identical Let the letters 'm', 'M', 'F', 'L','d' and 'u' in the
with v, but do not cross the level is indicated with the letter 'o'. figure above denote local minimum, maximum, first value, last
We have a level up-crossing at index, k, if value, down- and up-crossing, respectively. The remaining
sampled values are indicated with a '.'. Values that are identical
x(k) < v and v < x(k+1) with v, but do not cross the level is indicated with the letter 'o'.
or if We have a level up-crossing at index, k, if
x(k) == v and v < x(k+1) and x(r) < v for some di < r <= k-1
x(k) < v and v < x(k+1)
where di is the index to the previous downcrossing. or if
Similarly there is a level down-crossing at index, k, if x(k) == v and v < x(k+1) and x(r) < v for some di < r <= k-1
x(k) > v and v > x(k+1) where di is the index to the previous downcrossing.
or if Similarly there is a level down-crossing at index, k, if
x(k) == v and v > x(k+1) and x(r) > v for some ui < r <= k-1
x(k) > v and v > x(k+1)
where ui is the index to the previous upcrossing. or if
x(k) == v and v > x(k+1) and x(r) > v for some ui < r <= k-1
The first (F) value is a up crossing if x(1) = v and x(2) > v.
Similarly, it is a down crossing if x(1) = v and x(2) < v. where ui is the index to the previous upcrossing.
See also The first (F) value is a up crossing if x(1) = v and x(2) > v.
-------- Similarly, it is a down crossing if x(1) = v and x(2) < v.
wave_periods, waves, turning_points, findcross, findtp
""" See also
print(crossings.__doc__) --------
wave_periods, waves, turning_points, findcross, findtp
def cycle_pairs(): """
r""" print(crossings.__doc__)
Cycle pairs definitions and numenclature
Definition of Max2min and min2Max cycle pair def cycle_pairs():
-------------------------------------------- r"""
A min2Max cycle pair (mM) is defined as the pair of a minimum Cycle pairs definitions and numenclature
and the following Maximum. Similarly a Max2min cycle pair (Mm)
is defined as the pair of a Maximum and the following minimum. Definition of Max2min and min2Max cycle pair
(all turning points possibly rainflowfiltered before pairing into cycles.) --------------------------------------------
A min2Max cycle pair (mM) is defined as the pair of a minimum
See also and the following Maximum. Similarly a Max2min cycle pair (Mm)
-------- is defined as the pair of a Maximum and the following minimum.
turning_points (all turning points possibly rainflowfiltered before pairing into cycles.)
"""
print(cycle_pairs.__doc__) See also
--------
def wave_periods(): turning_points
r""" """
Wave periods (lengths) definitions and nomenclature print(cycle_pairs.__doc__)
Definition of wave periods (lengths)
------------------------------------ def wave_periods():
r"""
Wave periods (lengths) definitions and nomenclature
<----- Direction of wave propagation
Definition of wave periods (lengths)
<-------Tu---------> ------------------------------------
: :
<---Tc-----> :
: : : <------Tcc----> <----- Direction of wave propagation
M : c : : : :
/ \ : M / \_ : : c_ c <-------Tu--------->
F \ :/ \m/ \: :/ \ / \ : :
------d--------u----------d-------u----d--------u---d-------- level v <---Tc-----> :
\ / \ / :\_ _/: :\_ L : : : <------Tcc---->
\_ / \_t_/ : \t_/ : : \m/ M : c : : : :
\t/ : : : : / \ : M / \_ : : c_ c
: : <---Tt---> : F \ :/ \m/ \: :/ \ / \
<--------Ttt-------> : : ------d--------u----------d-------u----d--------u---d-------- level v
<-----Td-----> \ / \ / :\_ _/: :\_ L
Tu = Up crossing period \_ / \_t_/ : \t_/ : : \m/
Td = Down crossing period \t/ : : : :
Tc = Crest period, i.e., period between up crossing and : : <---Tt---> :
the next down crossing <--------Ttt-------> : :
Tt = Trough period, i.e., period between down crossing and <-----Td----->
the next up crossing Tu = Up crossing period
Ttt = Trough2trough period Td = Down crossing period
Tcc = Crest2crest period Tc = Crest period, i.e., period between up crossing and
the next down crossing
Tt = Trough period, i.e., period between down crossing and
<----- Direction of wave propagation the next up crossing
Ttt = Trough2trough period
<--Tcf-> Tuc Tcc = Crest2crest period
: : <-Tcb-> <->
M : c : : : :
/ \ : M / \_ c_ : : c <----- Direction of wave propagation
F \ :/ \m/ \ / \___: :/ \
------d---------u----------d---------u-------d--------u---d------ level v <--Tcf-> Tuc
:\_ / \ __/: \_ _/ \_ L : : <-Tcb-> <->
: \_ / \_t_/ : \t_/ \m/ M : c : : : :
: \t/ : : / \ : M / \_ c_ : : c
: : : : F \ :/ \m/ \ / \___: :/ \
<-Ttf-> <-Ttb-> ------d---------u----------d---------u-------d--------u---d------ level v
:\_ / \ __/: \_ _/ \_ L
: \_ / \_t_/ : \t_/ \m/
Tcf = Crest front period, i.e., period between up crossing and crest : \t/ : :
Tcb = Crest back period, i.e., period between crest and down crossing : : : :
Ttf = Trough front period, i.e., period between down crossing and trough <-Ttf-> <-Ttb->
Ttb = Trough back period, i.e., period between trough and up crossing
Also note that Tcf and Ttf can also be abbreviated by their crossing
marker, e.g. Tuc (u2c) and Tdt (d2t), respectively. Similar applies Tcf = Crest front period, i.e., period between up crossing and crest
to all the other wave periods and wave lengths. Tcb = Crest back period, i.e., period between crest and down crossing
Ttf = Trough front period, i.e., period between down crossing and trough
(The nomenclature for wave length is similar, just substitute T and Ttb = Trough back period, i.e., period between trough and up crossing
period with L and length, respectively) Also note that Tcf and Ttf can also be abbreviated by their crossing
marker, e.g. Tuc (u2c) and Tdt (d2t), respectively. Similar applies
<----- Direction of wave propagation to all the other wave periods and wave lengths.
<--TMm--> (The nomenclature for wave length is similar, just substitute T and
<-TmM-> : : period with L and length, respectively)
M : : M :
/ \ : M /:\_ : M_ M <----- Direction of wave propagation
F \ : / \m/ : \ : /: \ / \
\ : / : \ : / : \ / \ <--TMm-->
\ : / : \ : / : \_ _/ \_ L <-TmM-> : :
\_ : / : \_m_/ : \m_/ \m/ M : : M :
\m/ : : : : / \ : M /:\_ : M_ M
<-----TMM-----> <----Tmm-----> F \ : / \m/ : \ : /: \ / \
\ : / : \ : / : \ / \
\ : / : \ : / : \_ _/ \_ L
TmM = Period between minimum and the following Maximum \_ : / : \_m_/ : \m_/ \m/
TMm = Period between Maximum and the following minimum \m/ : : : :
TMM = Period between Maximum and the following Maximum <-----TMM-----> <----Tmm----->
Tmm = Period between minimum and the following minimum
See also TmM = Period between minimum and the following Maximum
-------- TMm = Period between Maximum and the following minimum
waves, TMM = Period between Maximum and the following Maximum
wave_amplitudes, Tmm = Period between minimum and the following minimum
crossings,
turning_points See also
""" --------
print(wave_periods.__doc__) waves,
def turning_points(): wave_amplitudes,
r""" crossings,
Turning points definitions and numenclature turning_points
"""
Definition of turningpoints print(wave_periods.__doc__)
---------------------------
<----- Direction of wave propagation
def turning_points():
M M r"""
/ \ .... M /:\_ M_ M Turning points definitions and numenclature
F \ | / \m/ : \ /: \ / \
\ h | / : \ / : \ / \ Definition of turningpoints
\ | / : \ / : \_ _/ \_ L ---------------------------
\_ | / : \_m_/ : \m_/ \m/ <----- Direction of wave propagation
\m/ : : : :
<------Mw-----> <-----mw-----> M M
/ \ .... M /:\_ M_ M
Local minimum or maximum are indicated with the F \ | / \m/ : \ /: \ / \
letters 'm' or 'M'. Turning points in this connection are all \ h | / : \ / : \ / \
local max (M) and min (m) and the last (L) value and the \ | / : \ / : \_ _/ \_ L
first (F) value if the first local extremum is a max. \_ | / : \_m_/ : \m_/ \m/
\m/ : : : :
(This choice is made in order to get the exact up-crossing intensity <------Mw-----> <-----mw----->
from rfc by mm2lc(tp2mm(rfc)) )
Local minimum or maximum are indicated with the
letters 'm' or 'M'. Turning points in this connection are all
See also local max (M) and min (m) and the last (L) value and the
-------- first (F) value if the first local extremum is a max.
waves,
crossings, (This choice is made in order to get the exact up-crossing intensity
cycle_pairs from rfc by mm2lc(tp2mm(rfc)) )
findtp
""" See also
print(turning_points.__doc__) --------
def waves(): waves,
r""" crossings,
Wave definitions and nomenclature cycle_pairs
findtp
Definition of trough and crest
------------------------------ """
A trough (t) is defined as the global minimum between a print(turning_points.__doc__)
level v down-crossing (d) and the next up-crossing (u)
and a crest (c) is defined as the global maximum between a
level v up-crossing and the following down-crossing. def waves():
r"""
Definition of down- and up -crossing waves Wave definitions and nomenclature
------------------------------------------
A level v-down-crossing wave (dw) is a wave from a Definition of trough and crest
down-crossing to the following down-crossing. ------------------------------
Similarly, a level v-up-crossing wave (uw) is a wave from an up-crossing A trough (t) is defined as the global minimum between a
to the next up-crossing. level v down-crossing (d) and the next up-crossing (u)
and a crest (c) is defined as the global maximum between a
Definition of trough and crest waves level v up-crossing and the following down-crossing.
------------------------------------
A trough-to-trough wave (tw) is a wave from a trough (t) to the Definition of down- and up -crossing waves
following trough. The crest-to-crest wave (cw) is defined similarly. ------------------------------------------
A level v-down-crossing wave (dw) is a wave from a
down-crossing to the following down-crossing.
Definition of min2min and Max2Max wave Similarly, a level v-up-crossing wave (uw) is a wave from an up-crossing
-------------------------------------- to the next up-crossing.
A min2min wave (mw) is defined starting from a minimum (m) and
ending in the following minimum. Definition of trough and crest waves
Similarly a Max2Max wave (Mw) is thus a wave from a maximum (M) ------------------------------------
to the next maximum (all waves optionally rainflow filtered). A trough-to-trough wave (tw) is a wave from a trough (t) to the
following trough. The crest-to-crest wave (cw) is defined similarly.
<----- Direction of wave propagation
Definition of min2min and Max2Max wave
<------Mw-----> <----mw----> --------------------------------------
M : : c : A min2min wave (mw) is defined starting from a minimum (m) and
/ \ M : / \_ : c_ c ending in the following minimum.
F \ / \m/ \ : /: \ /:\ Similarly a Max2Max wave (Mw) is thus a wave from a maximum (M)
------d--------u----------d-------u----d--------u---d------ level v to the next maximum (all waves optionally rainflow filtered).
\ /: \ : /: : :\_ _/ : :\_ L
\_ / : \_t_/ : : : \t_/ : : \m/ <----- Direction of wave propagation
\t/ <-------uw---------> : <-----dw----->
: : : :
<--------tw--------> <------cw-----> <------Mw-----> <----mw---->
M : : c :
(F=first value and L=last value). / \ M : / \_ : c_ c
F \ / \m/ \ : /: \ /:\
See also ------d--------u----------d-------u----d--------u---d------ level v
-------- \ /: \ : /: : :\_ _/ : :\_ L
turning_points, \_ / : \_t_/ : : : \t_/ : : \m/
crossings, \t/ <-------uw---------> : <-----dw----->
wave_periods : : : :
findtc, <--------tw--------> <------cw----->
findcross
""" (F=first value and L=last value).
print(waves.__doc__)
See also
--------
turning_points,
crossings,
wave_periods
findtc,
findcross
"""
print(waves.__doc__)

@ -1,17 +1,18 @@
from pylab import subplot, plot, title, savefig, figure, arange, sin, random #@UnresolvedImport # @UnresolvedImport
from pylab import subplot, plot, title, savefig, figure, arange, sin, random
from sg_filter import calc_coeff, smooth from sg_filter import calc_coeff, smooth
figure(figsize=(7,12)) figure(figsize=(7, 12))
# generate chirp signal # generate chirp signal
tvec = arange(0, 6.28, .02) tvec = arange(0, 6.28, .02)
signal = sin(tvec*(2.0+tvec)) signal = sin(tvec * (2.0 + tvec))
# add noise to signal # add noise to signal
noise = random.normal(size=signal.shape) noise = random.normal(size=signal.shape)
signal += (2000.+.15 * noise) signal += (2000. + .15 * noise)
# plot signal # plot signal
subplot(311) subplot(311)
@ -21,7 +22,7 @@ title('signal')
# smooth and plot signal # smooth and plot signal
subplot(312) subplot(312)
coeff = calc_coeff(8, 4) coeff = calc_coeff(8, 4)
s_signal = smooth(signal, coeff) s_signal = smooth(signal, coeff)
plot(s_signal) plot(s_signal)
title('smoothed signal') title('smoothed signal')
@ -36,8 +37,3 @@ title('smoothed derivative of signal')
# show plot # show plot
savefig("savitzky.png") savefig("savitzky.png")

@ -1,132 +1,138 @@
''' '''
Created on 20. jan. 2011 Created on 20. jan. 2011
@author: pab @author: pab
''' '''
import numpy as np import numpy as np
from numpy import exp from numpy import exp, meshgrid
from wafo.misc import meshgrid __all__ = ['peaks', 'humps', 'magic']
__all__ = ['peaks', 'humps', 'magic']
def magic(n): def magic(n):
''' '''
Return magic square for n of any orders > 2. Return magic square for n of any orders > 2.
A magic square has the property that the sum of every row and column, A magic square has the property that the sum of every row and column,
as well as both diagonals, is the same number. as well as both diagonals, is the same number.
Examples Examples
-------- --------
>>> magic(3) >>> magic(3)
array([[8, 1, 6], array([[8, 1, 6],
[3, 5, 7], [3, 5, 7],
[4, 9, 2]]) [4, 9, 2]])
>>> magic(4) >>> magic(4)
array([[16, 2, 3, 13], array([[16, 2, 3, 13],
[ 5, 11, 10, 8], [ 5, 11, 10, 8],
[ 9, 7, 6, 12], [ 9, 7, 6, 12],
[ 4, 14, 15, 1]]) [ 4, 14, 15, 1]])
>>> magic(6) >>> magic(6)
array([[35, 1, 6, 26, 19, 24], array([[35, 1, 6, 26, 19, 24],
[ 3, 32, 7, 21, 23, 25], [ 3, 32, 7, 21, 23, 25],
[31, 9, 2, 22, 27, 20], [31, 9, 2, 22, 27, 20],
[ 8, 28, 33, 17, 10, 15], [ 8, 28, 33, 17, 10, 15],
[30, 5, 34, 12, 14, 16], [30, 5, 34, 12, 14, 16],
[ 4, 36, 29, 13, 18, 11]]) [ 4, 36, 29, 13, 18, 11]])
''' '''
if (n<3): if (n < 3):
raise ValueError('n must be greater than 2.') raise ValueError('n must be greater than 2.')
if np.mod(n,2)==1: # odd order if np.mod(n, 2) == 1: # odd order
ix = np.arange(n) + 1 ix = np.arange(n) + 1
J, I = np.meshgrid(ix, ix) J, I = np.meshgrid(ix, ix)
A = np.mod(I + J - (n + 3) / 2, n) A = np.mod(I + J - (n + 3) / 2, n)
B = np.mod(I + 2 * J - 2, n) B = np.mod(I + 2 * J - 2, n)
M = n * A + B + 1 M = n * A + B + 1
elif np.mod(n,4)==0: # doubly even order elif np.mod(n, 4) == 0: # doubly even order
M = np.arange(1,n*n+1).reshape(n,n) M = np.arange(1, n * n + 1).reshape(n, n)
ix = np.mod(np.arange(n) + 1,4)//2 ix = np.mod(np.arange(n) + 1, 4) // 2
J, I = np.meshgrid(ix, ix) J, I = np.meshgrid(ix, ix)
iz = np.flatnonzero(I==J) iz = np.flatnonzero(I == J)
M.put(iz, n*n+1-M.flat[iz]) M.put(iz, n * n + 1 - M.flat[iz])
else: # singly even order else: # singly even order
p = n//2 p = n // 2
M0 = magic(p) M0 = magic(p)
M = np.hstack((np.vstack((M0, M0+3*p*p)),np.vstack((M0+2*p*p, M0+p*p)))) M = np.hstack((np.vstack((M0, M0 + 3 * p * p)),
np.vstack((M0 + 2 * p * p, M0 + p * p))))
if n>2:
k = (n-2)//4 if n > 2:
Jvec = np.hstack((np.arange(k), np.arange(n-k+1, n))) k = (n - 2) // 4
for i in range(p): Jvec = np.hstack((np.arange(k), np.arange(n - k + 1, n)))
for j in Jvec: for i in range(p):
temp = M[i][j] for j in Jvec:
M[i][j]=M[i+p][j] temp = M[i][j]
M[i+p][j] = temp M[i][j] = M[i + p][j]
M[i + p][j] = temp
i=k
j=0 i = k
temp = M[i][j]; j = 0
M[i][j] = M[i+p][j] temp = M[i][j]
M[i+p][j] = temp; M[i][j] = M[i + p][j]
M[i + p][j] = temp
j=i
temp=M[i+p][j] j = i
M[i+p][j]=M[i][j] temp = M[i + p][j]
M[i][j]=temp M[i + p][j] = M[i][j]
M[i][j] = temp
return M
return M
def peaks(x=None, y=None, n=51):
'''
Return the "well" known MatLab (R) peaks function def peaks(x=None, y=None, n=51):
evaluated in the [-3,3] x,y range '''
Return the "well" known MatLab (R) peaks function
Example evaluated in the [-3,3] x,y range
-------
>>> import matplotlib.pyplot as plt Example
>>> x,y,z = peaks() -------
>>> import matplotlib.pyplot as plt
h = plt.contourf(x,y,z) >>> x,y,z = peaks()
''' h = plt.contourf(x,y,z)
if x is None:
x = np.linspace(-3, 3, n) '''
if y is None: if x is None:
y = np.linspace(-3, 3, n) x = np.linspace(-3, 3, n)
if y is None:
[x1, y1] = meshgrid(x, y) y = np.linspace(-3, 3, n)
z = (3 * (1 - x1) ** 2 * exp(-(x1 ** 2) - (y1 + 1) ** 2) [x1, y1] = meshgrid(x, y)
- 10 * (x1 / 5 - x1 ** 3 - y1 ** 5) * exp(-x1 ** 2 - y1 ** 2)
- 1. / 3 * exp(-(x1 + 1) ** 2 - y1 ** 2)) z = (3 * (1 - x1) ** 2 * exp(-(x1 ** 2) - (y1 + 1) ** 2)
- 10 * (x1 / 5 - x1 ** 3 - y1 ** 5) * exp(-x1 ** 2 - y1 ** 2)
return x1, y1, z - 1. / 3 * exp(-(x1 + 1) ** 2 - y1 ** 2))
def humps(x=None): return x1, y1, z
'''
Computes a function that has three roots, and some humps.
def humps(x=None):
Example '''
------- Computes a function that has three roots, and some humps.
>>> import matplotlib.pyplot as plt
>>> x = np.linspace(0,1) Example
>>> y = humps(x) -------
>>> import matplotlib.pyplot as plt
h = plt.plot(x,y) >>> x = np.linspace(0,1)
''' >>> y = humps(x)
if x is None:
y = np.linspace(0, 1) h = plt.plot(x,y)
else: '''
y = np.asarray(x) if x is None:
y = np.linspace(0, 1)
return 1.0 / ((y - 0.3) ** 2 + 0.01) + 1.0 / ((y - 0.9) ** 2 + 0.04) + 2 * y - 5.2 else:
y = np.asarray(x)
def test_docstrings():
import doctest return 1.0 / ((y - 0.3) ** 2 + 0.01) + 1.0 / ((y - 0.9) ** 2 + 0.04) + \
doctest.testmod() 2 * y - 5.2
if __name__ == '__main__':
test_docstrings() def test_docstrings():
import doctest
print('Testing docstrings in %s' % __file__)
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
if __name__ == '__main__':
test_docstrings()

@ -1,282 +1,267 @@
''' '''
Created on 20. jan. 2011 Created on 20. jan. 2011
@author: pab @author: pab
license BSD license BSD
''' '''
from __future__ import division from __future__ import division
import warnings import warnings
import numpy as np import numpy as np
from wafo.plotbackend import plotbackend from wafo.plotbackend import plotbackend
from matplotlib import mlab from matplotlib import mlab
__all__ = ['cltext', 'epcolor', 'tallibing', 'test_docstrings'] __all__ = ['cltext', 'tallibing', 'test_docstrings']
_TALLIBING_GID = 'TALLIBING' _TALLIBING_GID = 'TALLIBING'
_CLTEXT_GID = 'CLTEXT' _CLTEXT_GID = 'CLTEXT'
def _matchfun(x, gidtxt):
if hasattr(x, 'get_gid'): def _matchfun(x, gidtxt):
return x.get_gid() == gidtxt if hasattr(x, 'get_gid'):
return False return x.get_gid() == gidtxt
return False
def delete_text_object(gidtxt, figure=None, axis=None, verbose=False):
'''
Delete all text objects matching the gidtxt if it exists def delete_text_object(gidtxt, figure=None, axis=None, verbose=False):
'''
Parameters Delete all text objects matching the gidtxt if it exists
----------
gidtxt : string Parameters
----------
figure, axis : objects gidtxt : string
current figure and current axis, respectively.
verbose : bool figure, axis : objects
If true print warnings when trying to delete non-existent objects current figure and current axis, respectively.
''' verbose : bool
if figure is None: If true print warnings when trying to delete non-existent objects
figure = plotbackend.gcf() '''
if axis is None: if figure is None:
axis = figure.gca() figure = plotbackend.gcf()
lmatchfun = lambda x : _matchfun(x, gidtxt) if axis is None:
objs = axis.findobj(lmatchfun) axis = figure.gca()
for obj in objs: lmatchfun = lambda x: _matchfun(x, gidtxt)
try: objs = axis.findobj(lmatchfun)
axis.texts.remove(obj) for obj in objs:
except: try:
if verbose: axis.texts.remove(obj)
warnings.warn('Tried to delete a non-existing %s from axis' % gidtxt) except:
objs = figure.findobj(lmatchfun) if verbose:
for obj in objs: warnings.warn(
try: 'Tried to delete a non-existing %s from axis' % gidtxt)
figure.texts.remove(obj) objs = figure.findobj(lmatchfun)
except: for obj in objs:
if verbose: try:
warnings.warn('Tried to delete a non-existing %s from figure' % gidtxt) figure.texts.remove(obj)
except:
def cltext(levels, percent=False, n=4, xs=0.036, ys=0.94, zs=0, figure=None, axis=None): if verbose:
''' warnings.warn(
Places contour level text in the current window 'Tried to delete a non-existing %s from figure' % gidtxt)
Parameters
---------- def cltext(levels, percent=False, n=4, xs=0.036, ys=0.94, zs=0, figure=None,
levels : vector axis=None):
contour levels or the corresponding percent which the '''
contour line encloses Places contour level text in the current window
percent : bool
False if levels are the actual contour levels (default) Parameters
True if levels are the corresponding percent which the ----------
contour line encloses levels : vector
n : integer contour levels or the corresponding percent which the
maximum N digits of precision (default 4) contour line encloses
figure, axis : objects percent : bool
current figure and current axis, respectively. False if levels are the actual contour levels (default)
default figure = plotbackend.gcf(), True if levels are the corresponding percent which the
axis = plotbackend.gca() contour line encloses
n : integer
Returns maximum N digits of precision (default 4)
------- figure, axis : objects
h = handles to the text objects. current figure and current axis, respectively.
default figure = plotbackend.gcf(),
axis = plotbackend.gca()
Notes
----- Returns
CLTEXT creates text objects in the current figure and prints -------
"Level curves at:" if percent is False and h = handles to the text objects.
"Level curves enclosing:" otherwise
and the contour levels or percent.
Notes
The handles to the lines of text may also be found by -----
h = findobj(gcf,'gid','CLTEXT','type','text'); CLTEXT creates text objects in the current figure and prints
h = findobj(gca,'gid','CLTEXT','type','text'); "Level curves at:" if percent is False and
To make the text objects follow the data in the axes set the units "Level curves enclosing:" otherwise
for the text objects 'data' by and the contour levels or percent.
set(h,'unit','data')
The handles to the lines of text may also be found by
Examples h = findobj(gcf,'gid','CLTEXT','type','text');
-------- h = findobj(gca,'gid','CLTEXT','type','text');
>>> import wafo.graphutil as wg To make the text objects follow the data in the axes set the units
>>> import wafo.demos as wd for the text objects 'data' by
>>> import pylab as plt set(h,'unit','data')
>>> x,y,z = wd.peaks();
>>> h = plt.contour(x,y,z) Examples
>>> h = wg.cltext(h.levels) --------
>>> plt.show() >>> import wafo.graphutil as wg
''' >>> import wafo.demos as wd
# TODO : Make it work like legend does (but without the box): include position options etc... >>> import pylab as plt
if figure is None: >>> x,y,z = wd.peaks();
figure = plotbackend.gcf() >>> h = plt.contour(x,y,z)
if axis is None: >>> h = wg.cltext(h.levels)
axis = figure.gca() >>> plt.show()
'''
clevels = np.atleast_1d(levels) # TODO : Make it work like legend does (but without the box): include
# position options etc...
if figure is None:
axpos = axis.get_position() figure = plotbackend.gcf()
xint = axpos.intervalx if axis is None:
yint = axpos.intervaly axis = figure.gca()
xss = xint[0] + xs * (xint[1] - xint[0]) clevels = np.atleast_1d(levels)
yss = yint[0] + ys * (yint[1] - yint[0])
axpos = axis.get_position()
# delete cltext object if it exists xint = axpos.intervalx
delete_text_object(_CLTEXT_GID, axis=axis) yint = axpos.intervaly
charHeight = 1.0 / 33.0 xss = xint[0] + xs * (xint[1] - xint[0])
delta_y = charHeight yss = yint[0] + ys * (yint[1] - yint[0])
if percent: # delete cltext object if it exists
titletxt = 'Level curves enclosing:'; delete_text_object(_CLTEXT_GID, axis=axis)
else:
titletxt = 'Level curves at:'; charHeight = 1.0 / 33.0
delta_y = charHeight
format_ = '%0.' + ('%d' % n) + 'g\n'
if percent:
cltxt = ''.join([format_ % level for level in clevels.tolist()]) titletxt = 'Level curves enclosing:'
else:
titleProp = dict(gid=_CLTEXT_GID, horizontalalignment='left', titletxt = 'Level curves at:'
verticalalignment='center', fontweight='bold', axes=axis) #
format_ = '%0.' + ('%d' % n) + 'g\n'
ha1 = figure.text(xss, yss, titletxt, **titleProp)
cltxt = ''.join([format_ % level for level in clevels.tolist()])
yss -= delta_y;
txtProp = dict(gid=_CLTEXT_GID, horizontalalignment='left', titleProp = dict(gid=_CLTEXT_GID, horizontalalignment='left',
verticalalignment='top', axes=axis) verticalalignment='center', fontweight='bold', axes=axis)
ha2 = figure.text(xss, yss, cltxt, **txtProp) ha1 = figure.text(xss, yss, titletxt, **titleProp)
plotbackend.draw_if_interactive()
return ha1, ha2 yss -= delta_y
txtProp = dict(gid=_CLTEXT_GID, horizontalalignment='left',
def tallibing(x, y, n, **kwds): verticalalignment='top', axes=axis)
'''
TALLIBING Display numbers on field-plot ha2 = figure.text(xss, yss, cltxt, **txtProp)
plotbackend.draw_if_interactive()
CALL h=tallibing(x,y,n,size,color) return ha1, ha2
x,y = position matrices
n = the corresponding matrix of the values to be written def tallibing(*args, **kwds):
(non-integers are rounded) '''
size = font size (optional) (default=8) TALLIBING Display numbers on field-plot
color = color of text (optional) (default='white')
h = column-vector of handles to TEXT objects CALL h=tallibing(x,y,n,size,color)
TALLIBING writes the numbers in a 2D array as text at the positions Parameters
given by the x and y coordinate matrices. ----------
When plotting binned results, the number of datapoints in each x, y : array
bin can be written on the bins in the plot. position matrices
n : array
Example corresponding matrix of the values to be written
------- (non-integers are rounded)
>>> import wafo.graphutil as wg mid_points : bool (default True)
>>> import wafo.demos as wd data-point-positions are in the middle of bins instead of the corners
>>> [x,y,z] = wd.peaks(n=20) size : int, (default=8)
>>> h0 = wg.epcolor(x,y,z) font size (optional)
>>> h1 = wg.tallibing(x,y,z) color : str, (default='white')
color of text (optional)
pcolor(x,y,z); shading interp;
Returns
See also -------
-------- h : list
text handles to TEXT objects
'''
TALLIBING writes the numbers in a 2D array as text at the positions
axis = kwds.pop('axis',None) given by the x and y coordinate matrices.
if axis is None: When plotting binned results, the number of datapoints in each
axis = plotbackend.gca() bin can be written on the bins in the plot.
x, y, n = np.atleast_1d(x, y, n) Example
if mlab.isvector(x) or mlab.isvector(y): -------
x, y = np.meshgrid(x,y) >>> import wafo.graphutil as wg
>>> import wafo.demos as wd
x = x.ravel() >>> [x,y,z] = wd.peaks(n=20)
y = y.ravel() >>> h0 = wg.pcolor(x,y,z)
n = n.ravel() >>> h1 = wg.tallibing(x,y,z)
n = np.round(n)
See also
# delete tallibing object if it exists --------
delete_text_object(_TALLIBING_GID, axis=axis) text
'''
txtProp = dict(gid=_TALLIBING_GID, size=8, color='w', horizontalalignment='center',
verticalalignment='center', fontweight='demi', axes=axis) axis = kwds.pop('axis', None)
if axis is None:
txtProp.update(**kwds) axis = plotbackend.gca()
h = []
for xi,yi, ni in zip(x,y,n): x, y, n = _parse_data(*args, **kwds)
if ni: if mlab.isvector(x) or mlab.isvector(y):
h.append(axis.text(xi, yi, str(ni), **txtProp)) x, y = np.meshgrid(x, y)
plotbackend.draw_if_interactive()
return h n = np.round(n)
def epcolor(*args, **kwds): # delete tallibing object if it exists
''' delete_text_object(_TALLIBING_GID, axis=axis)
Pseudocolor (checkerboard) plot with mid-bin positioning.
txtProp = dict(gid=_TALLIBING_GID, size=8, color='w',
h = epcolor(x,y,data) horizontalalignment='center',
verticalalignment='center', fontweight='demi', axes=axis)
[x,y]= the axes corresponding to the data-positions. Vectors or txtProp.update(**kwds)
matrices. If omitted, giving only data-matrix as inargument, the h = []
matrix-indices are used as axes. for xi, yi, ni in zip(x.ravel(), y.ravel(), n.ravel()):
data = data-matrix if ni:
h.append(axis.text(xi, yi, str(ni), **txtProp))
EPCOLOR make a checkerboard plot where the data-point-positions are in plotbackend.draw_if_interactive()
the middle of the bins instead of in the corners, and the last column return h
and row of data are used.
def _parse_data(*args, **kwds):
Example: nargin = len(args)
>>> import wafo.demos as wd data = np.atleast_2d(args[-1]).copy()
>>> import wafo.graphutil as wg M, N = data.shape
>>> x, y, z = wd.peaks(n=20) if nargin == 1:
>>> h = wg.epcolor(x,y,z) x = np.arange(N)
y = np.arange(M)
See also elif nargin == 3:
-------- x, y = np.atleast_1d(*args[:-1])
pylab.pcolor if min(x.shape) != 1:
''' x = x[0]
axis = kwds.pop('axis',None) if min(y.shape) != 1:
if axis is None: y = y[:, 0]
axis = plotbackend.gca() else:
midbin = kwds.pop('midbin', True) raise ValueError(
if not midbin: 'Requires 3 or 1 in arguments! (x,y,data) or (data)')
ret = axis.pcolor(*args,**kwds) if kwds.pop('mid_point', True):
plotbackend.draw_if_interactive() xx = _find_mid_points(x)
return ret yy = _find_mid_points(y)
return xx, yy, data
nargin = len(args) return x, y, data
data = np.atleast_2d(args[-1]).copy()
M, N = data.shape pcolor = plotbackend.pcolor
if nargin==1: pcolormesh = plotbackend.pcolormesh
x = np.arange(N)
y = np.arange(M)
elif nargin==3: def _find_mid_points(x):
x, y = np.atleast_1d(*args[:-1]) ''' Return points half way between all values of X and outside the
if min(x.shape)!=1: endpoints. The outer limits have same distance from X's endpoints as
x = x[0] the limits just inside.
if min(y.shape)!=1: '''
y = y[:,0] dx = np.diff(x) * 0.5
else: dx = np.hstack((dx, dx[-1]))
raise ValueError('pcolor takes 3 or 1 inarguments! (x,y,data) or (data)') return x + dx
xx = _findbins(x)
yy = _findbins(y) def test_docstrings():
ret = axis.pcolor(xx, yy, data, **kwds) import doctest
plotbackend.draw_if_interactive() print('Testing docstrings in %s' % __file__)
return ret doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
if __name__ == '__main__':
def _findbins(x): test_docstrings()
''' Return points half way between all values of X _and_ outside the
endpoints. The outer limits have same distance from X's endpoints as
the limits just inside.
'''
dx = np.diff(x) * 0.5
dx = np.hstack((dx, dx[-1]))
return np.hstack((x[0] - dx[0], x + dx))
def test_docstrings():
import doctest
doctest.testmod()
if __name__ == '__main__':
test_docstrings()

@ -1,9 +1,10 @@
""" """
WAFO WAFO
==== ====
WAFO is a toolbox Python routines for statistical analysis and simulation of random waves and random loads. WAFO is a toolbox Python routines for statistical analysis and simulation of
WAFO is freely redistributable software, see WAFO licence, cf. the GNU General Public License (GPL) and random waves and random loads.
contain tools for: WAFO is freely redistributable software, see WAFO licence, cf. the
GNU General Public License (GPL) and contain tools for:
Fatigue Analysis Fatigue Analysis
---------------- ----------------
@ -22,42 +23,42 @@ Statistics
-Kernel density estimation -Kernel density estimation
-Hidden markov models -Hidden markov models
WAFO consists of several subpackages and classes with short descriptions below. WAFO consists of several subpackages and classes with short descriptions given
below.
Classes: Classes:
TimeSeries - Data analysis of time series. Example: extraction of TimeSeries - Data analysis of time series. Example: extraction of
turning points, estimation of spectrum and covariance function. turning points, estimation of spectrum and covariance function.
Estimation transformation used in transformed Gaussian model. Estimation transformation used in transformed Gaussian model.
CovData - Computation of spectral functions, linear CovData - Computation of spectral functions, linear
and non-linear time series simulation. and non-linear time series simulation.
SpecData - Computation of spectral moments and covariance functions, linear SpecData - Computation of spectral moments and covariance functions, linear
and non-linear time series simulation. and non-linear time series simulation.
Ex: common spectra implemented, directional spectra, Ex: common spectra implemented, directional spectra,
bandwidth measures, exact distributions for wave characteristics. bandwidth measures, exact distributions for wave characteristics.
CyclePairs - Cycle counting, discretization, and crossings, calculation of
CyclePairs - Cycle counting, discretization, and crossings, calculation of
damage. Simulation of discrete Markov chains, switching Markov damage. Simulation of discrete Markov chains, switching Markov
chains, harmonic oscillator. Ex: Rainflow cycles and matrix, chains, harmonic oscillator. Ex: Rainflow cycles and matrix,
discretization of loads. Damage of a rainflow count or discretization of loads. Damage of a rainflow count or
matrix, damage matrix, S-N plot. matrix, damage matrix, S-N plot.
Subpackages: Subpackages:
TRANSFORM - Modelling with linear or transformed Gaussian waves. Ex: TRANSFORM - Modelling with linear or transformed Gaussian waves. Ex:
STATS - Statistical tools and extreme-value distributions. STATS - Statistical tools and extreme-value distributions.
Ex: generation of random numbers, estimation of parameters, Ex: generation of random numbers, estimation of parameters,
evaluation of pdf and cdf evaluation of pdf and cdf
KDETOOLS - Kernel-density estimation. KDETOOLS - Kernel-density estimation.
MISC - Miscellaneous routines. MISC - Miscellaneous routines.
DOCS - Documentation of toolbox, definitions. An overview is given DOCS - Documentation of toolbox, definitions. An overview is given
in the routine wafomenu. in the routine wafomenu.
DATA - Measurements from marine applications. DATA - Measurements from marine applications.
WAFO homepage: <http://www.maths.lth.se/matstat/wafo/> WAFO homepage: <http://www.maths.lth.se/matstat/wafo/>
On the WAFO home page you will find: On the WAFO home page you will find:
- The WAFO Tutorial - The WAFO Tutorial
- New versions of WAFO to download. - New versions of WAFO to download.
- Reported bugs. - Reported bugs.
- List of publications related to WAFO. - List of publications related to WAFO.
""" """

@ -797,15 +797,15 @@ def qrule(n, wfun=1, alpha=0, beta=0):
number of base points number of base points
wfun : integer wfun : integer
defining the weight function, p(x). (default wfun = 1) defining the weight function, p(x). (default wfun = 1)
1,11,21: p(x) = 1 a =-1, b = 1 Gauss-Legendre 1,11,21: p(x) = 1 a =-1, b = 1 Gauss-Legendre
2,12 : p(x) = exp(-x^2) a =-inf, b = inf Hermite 2,12 : p(x) = exp(-x^2) a =-inf, b = inf Hermite
3,13 : p(x) = x^alpha*exp(-x) a = 0, b = inf Laguerre 3,13 : p(x) = x^alpha*exp(-x) a = 0, b = inf Laguerre
4,14 : p(x) = (x-a)^alpha*(b-x)^beta a =-1, b = 1 Jacobi 4,14 : p(x) = (x-a)^alpha*(b-x)^beta a =-1, b = 1 Jacobi
5 : p(x) = 1/sqrt((x-a)*(b-x)), a =-1, b = 1 Chebyshev 1'st kind 5 : p(x) = 1/sqrt((x-a)*(b-x)), a =-1, b = 1 Chebyshev 1'st kind
6 : p(x) = sqrt((x-a)*(b-x)), a =-1, b = 1 Chebyshev 2'nd kind 6 : p(x) = sqrt((x-a)*(b-x)), a =-1, b = 1 Chebyshev 2'nd kind
7 : p(x) = sqrt((x-a)/(b-x)), a = 0, b = 1 7 : p(x) = sqrt((x-a)/(b-x)), a = 0, b = 1
8 : p(x) = 1/sqrt(b-x), a = 0, b = 1 8 : p(x) = 1/sqrt(b-x), a = 0, b = 1
9 : p(x) = sqrt(b-x), a = 0, b = 1 9 : p(x) = sqrt(b-x), a = 0, b = 1
Returns Returns
------- -------
@ -1428,8 +1428,8 @@ def qdemo(f, a, b):
formats = ['%4.0f, ', ] + ['%10.10f, ', ] * 6 formats = ['%4.0f, ', ] + ['%10.10f, ', ] * 6
formats[-1] = formats[-1].split(',')[0] formats[-1] = formats[-1].split(',')[0]
data = np.vstack((neval, qt, et, qs, es, qb, eb)).T data = np.vstack((neval, qt, et, qs, es, qb, eb)).T
print(' ftn Trapezoid Simpson''s Boole''s') print(' ftn Trapezoid Simpson''s Boole''s') # @IgnorePep8
print('evals approx error approx error approx error') print('evals approx error approx error approx error') # @IgnorePep8
for k in xrange(kmax): for k in xrange(kmax):
tmp = data[k].tolist() tmp = data[k].tolist()
@ -1437,8 +1437,8 @@ def qdemo(f, a, b):
# display results # display results
data = np.vstack((neval, qc, ec, qc2, ec2, qg, eg)).T data = np.vstack((neval, qc, ec, qc2, ec2, qg, eg)).T
print(' ftn Clenshaw Chebychev Gauss-L') print(' ftn Clenshaw Chebychev Gauss-L') # @IgnorePep8
print('evals approx error approx error approx error') print('evals approx error approx error approx error') # @IgnorePep8
for k in xrange(kmax): for k in xrange(kmax):
tmp = data[k].tolist() tmp = data[k].tolist()
print(''.join(fi % t for fi, t in zip(formats, tmp))) print(''.join(fi % t for fi, t in zip(formats, tmp)))
@ -1447,7 +1447,7 @@ def qdemo(f, a, b):
plt.xlabel('number of function evaluations') plt.xlabel('number of function evaluations')
plt.ylabel('error') plt.ylabel('error')
plt.legend( plt.legend(
('Trapezoid', 'Simpsons', 'Booles', 'Clenshaw', 'Chebychev', 'Gauss-L')) ('Trapezoid', 'Simpsons', 'Booles', 'Clenshaw', 'Chebychev', 'Gauss-L')) # @IgnorePep8
# ec3' # ec3'

@ -12,9 +12,9 @@
from __future__ import division from __future__ import division
import numpy as np import numpy as np
import scipy.signal import scipy.signal
import scipy.special as spec #import scipy.special as spec
import scipy.sparse as sp
import scipy.sparse.linalg # @UnusedImport import scipy.sparse.linalg # @UnusedImport
import scipy.sparse as sparse
from numpy.ma.core import ones, zeros, prod, sin from numpy.ma.core import ones, zeros, prod, sin
from numpy import diff, pi, inf # @UnresolvedImport from numpy import diff, pi, inf # @UnresolvedImport
from numpy.lib.shape_base import vstack from numpy.lib.shape_base import vstack
@ -546,7 +546,7 @@ class SmoothSpline(PPform):
else: else:
dx1 = 1. / dx dx1 = 1. / dx
D = sp.spdiags(var * ones(n), 0, n, n) # The variance D = sparse.spdiags(var * ones(n), 0, n, n) # The variance
u, p = self._compute_u(p, D, dydx, dx, dx1, n) u, p = self._compute_u(p, D, dydx, dx, dx1, n)
dx1.shape = (n - 1, -1) dx1.shape = (n - 1, -1)
@ -590,10 +590,10 @@ class SmoothSpline(PPform):
def _compute_u(self, p, D, dydx, dx, dx1, n): def _compute_u(self, p, D, dydx, dx, dx1, n):
if p is None or p != 0: if p is None or p != 0:
data = [dx[1:n - 1], 2 * (dx[:n - 2] + dx[1:n - 1]), dx[:n - 2]] data = [dx[1:n - 1], 2 * (dx[:n - 2] + dx[1:n - 1]), dx[:n - 2]]
R = sp.spdiags(data, [-1, 0, 1], n - 2, n - 2) R = sparse.spdiags(data, [-1, 0, 1], n - 2, n - 2)
if p is None or p < 1: if p is None or p < 1:
Q = sp.spdiags( Q = sparse.spdiags(
[dx1[:n - 2], -(dx1[:n - 2] + dx1[1:n - 1]), dx1[1:n - 1]], [dx1[:n - 2], -(dx1[:n - 2] + dx1[1:n - 1]), dx1[1:n - 1]],
[0, -1, -2], n, n - 2) [0, -1, -2], n, n - 2)
QDQ = (Q.T * D * Q) QDQ = (Q.T * D * Q)
@ -612,8 +612,8 @@ class SmoothSpline(PPform):
# Make sure it uses symmetric matrix solver # Make sure it uses symmetric matrix solver
ddydx = diff(dydx, axis=0) ddydx = diff(dydx, axis=0)
sp.linalg.use_solver(useUmfpack=True) #sp.linalg.use_solver(useUmfpack=True)
u = 2 * sp.linalg.spsolve((QQ + QQ.T), ddydx) u = 2 * sparse.linalg.spsolve((QQ + QQ.T), ddydx) # @UndefinedVariable
return u.reshape(n - 2, -1), p return u.reshape(n - 2, -1), p
@ -923,7 +923,7 @@ class StinemanInterp(object):
''' '''
def __init__(self, x, y, yp=None, method='parabola', monotone=False): def __init__(self, x, y, yp=None, method='parabola', monotone=False):
if yp is None: if yp is None:
yp = slopes(x, y, method, monotone) yp = slopes(x, y, method, monotone=monotone)
self.x = np.asarray(x, np.float_) self.x = np.asarray(x, np.float_)
self.y = np.asarray(y, np.float_) self.y = np.asarray(y, np.float_)
self.yp = np.asarray(yp, np.float_) self.yp = np.asarray(yp, np.float_)
@ -1058,7 +1058,8 @@ class Pchip(PiecewisePolynomial):
>>> h=plt.xlabel("X") >>> h=plt.xlabel("X")
>>> h=plt.ylabel("Y") >>> h=plt.ylabel("Y")
>>> h=plt.title("Comparing pypchip() vs. Scipy interp1d() vs. non-monotonic CHS") >>> txt = "Comparing pypchip() vs. Scipy interp1d() vs. non-monotonic CHS"
>>> h=plt.title(txt)
>>> legends = ["Data", "pypchip()", "interp1d","CHS", 'SI'] >>> legends = ["Data", "pypchip()", "interp1d","CHS", 'SI']
>>> h=plt.legend(legends, loc="upper left") >>> h=plt.legend(legends, loc="upper left")
>>> plt.show() >>> plt.show()
@ -1210,10 +1211,10 @@ def test_func():
_tck1, _u = interpolate.splprep([t, y], s=0) # @UndefinedVariable _tck1, _u = interpolate.splprep([t, y], s=0) # @UndefinedVariable
tck2 = interpolate.splrep(t, y, s=len(t), task=0) # @UndefinedVariable tck2 = interpolate.splrep(t, y, s=len(t), task=0) # @UndefinedVariable
# interpolate.spl # interpolate.spl
tck = interpolate.splmake(t, y, order=3, kind='smoothest', conds=None) # @UndefinedVariable tck = interpolate.splmake(t, y, order=3, kind='smoothest', conds=None)
self = interpolate.ppform.fromspline(*tck2) # @UndefinedVariable self = interpolate.ppform.fromspline(*tck2) # @UndefinedVariable
plt.plot(t, self(t)) plt.plot(t, self(t))
plt.show() plt.show('hold')
pass pass
@ -1238,12 +1239,13 @@ def test_pp():
def test_docstrings(): def test_docstrings():
import doctest import doctest
doctest.testmod() print('Testing docstrings in %s' % __file__)
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
if __name__ == '__main__': if __name__ == '__main__':
test_func() #test_func()
# test_doctstrings() # test_doctstrings()
# test_smoothing_spline() # test_smoothing_spline()
# compare_methods() #compare_methods()
#demo_monoticity() demo_monoticity()

@ -21,7 +21,7 @@ from scipy.ndimage.morphology import distance_transform_edt
from numpy import pi, sqrt, atleast_2d, exp, newaxis # @UnresolvedImport from numpy import pi, sqrt, atleast_2d, exp, newaxis # @UnresolvedImport
from wafo.misc import meshgrid, nextpow2, tranproc # , trangood from wafo.misc import meshgrid, nextpow2, tranproc # , trangood
from wafo.wafodata import PlotData from wafo.containers import PlotData
from wafo.dctpack import dct, dctn, idctn from wafo.dctpack import dct, dctn, idctn
from wafo.plotbackend import plotbackend as plt from wafo.plotbackend import plotbackend as plt
try: try:
@ -3984,7 +3984,8 @@ def kreg_demo3(x, y, fun1, hs=None, fun='hisj', plotlog=False):
eerr = np.abs((yiii - fiii)).std() + 0.5 * (df[:-1] * df[1:] < 0).sum() / n eerr = np.abs((yiii - fiii)).std() + 0.5 * (df[:-1] * df[1:] < 0).sum() / n
err = (fiii - fit).std() err = (fiii - fit).std()
f = kreg( f = kreg(
xiii, output='plotobj', title='%s err=%1.3f,eerr=%1.3f, n=%d, hs=%1.3f, hs1=%1.3f, hs2=%1.3f' % xiii, output='plotobj',
title='%s err=%1.3f,eerr=%1.3f, n=%d, hs=%1.3f, hs1=%1.3f, hs2=%1.3f' %
(fun, err, eerr, n, hs, hs1, hs2), plotflag=1) (fun, err, eerr, n, hs, hs1, hs2), plotflag=1)
#yi[yi==0] = 1.0/(c[c!=0].min()+4) #yi[yi==0] = 1.0/(c[c!=0].min()+4)
@ -4051,8 +4052,8 @@ def kreg_demo3(x, y, fun1, hs=None, fun='hisj', plotlog=False):
# Wilson score # Wilson score
den = 1 + (z0 ** 2. / ciii) den = 1 + (z0 ** 2. / ciii)
xc = (pi1 + (z0 ** 2) / (2 * ciii)) / den xc = (pi1 + (z0 ** 2) / (2 * ciii)) / den
halfwidth = ( halfwidth = (z0 * sqrt((pi1 * (1 - pi1) / ciii) +
z0 * sqrt((pi1 * (1 - pi1) / ciii) + (z0 ** 2 / (4 * (ciii ** 2))))) / den (z0 ** 2 / (4 * (ciii ** 2))))) / den
plo = (xc - halfwidth).clip(min=0) # wilson score plo = (xc - halfwidth).clip(min=0) # wilson score
pup = (xc + halfwidth).clip(max=1.0) # wilson score pup = (xc + halfwidth).clip(max=1.0) # wilson score
# pup = (pi + z0*np.sqrt(pi*(1-pi)/ciii)).clip(min=0,max=1) # dont use # pup = (pi + z0*np.sqrt(pi*(1-pi)/ciii)).clip(min=0,max=1) # dont use
@ -4061,14 +4062,18 @@ def kreg_demo3(x, y, fun1, hs=None, fun='hisj', plotlog=False):
#mi = kreg.eval_grid(x) #mi = kreg.eval_grid(x)
#sigma = (stineman_interp(x, xiii, pup)-stineman_interp(x, xiii, plo))/4 #sigma = (stineman_interp(x, xiii, pup)-stineman_interp(x, xiii, plo))/4
#aic = np.abs((y-mi)/sigma).std()+ 0.5*(df[:-1]*df[1:]<0).sum()/n #aic = np.abs((y-mi)/sigma).std()+ 0.5*(df[:-1]*df[1:]<0).sum()/n
#aic = np.abs((yiii-fiii)/(pup-plo)).std()+ 0.5*(df[:-1]*df[1:]<0).sum() + ((yiii-pup).clip(min=0)-(yiii-plo).clip(max=0)).sum() #aic = np.abs((yiii-fiii)/(pup-plo)).std() + \
# 0.5*(df[:-1]*df[1:]<0).sum() + \
# ((yiii-pup).clip(min=0)-(yiii-plo).clip(max=0)).sum()
k = (df[:-1] * df[1:] < 0).sum() # numpeaks k = (df[:-1] * df[1:] < 0).sum() # numpeaks
sigmai = (pup - plo) sigmai = (pup - plo)
aic = (((yiii - fiii) / sigmai) ** 2).sum() + 2 * k * (k + 1) / np.maximum(ni - k + 1, 1) + \ aic = (((yiii - fiii) / sigmai) ** 2).sum() + \
2 * k * (k + 1) / np.maximum(ni - k + 1, 1) + \
np.abs((yiii - pup).clip(min=0) - (yiii - plo).clip(max=0)).sum() np.abs((yiii - pup).clip(min=0) - (yiii - plo).clip(max=0)).sum()
#aic = (((yiii-fiii)/sigmai)**2).sum()+ 2*k*(k+1)/(ni-k+1) + np.abs((yiii-pup).clip(min=0)-(yiii-plo).clip(max=0)).sum() #aic = (((yiii-fiii)/sigmai)**2).sum()+ 2*k*(k+1)/(ni-k+1) + \
# np.abs((yiii-pup).clip(min=0)-(yiii-plo).clip(max=0)).sum()
#aic = averr + ((yiii-pup).clip(min=0)-(yiii-plo).clip(max=0)).sum() #aic = averr + ((yiii-pup).clip(min=0)-(yiii-plo).clip(max=0)).sum()
@ -4140,14 +4145,16 @@ def kreg_demo4(x, y, hs, hopt, alpha=0.05):
yi = np.where(c == 0, 0, c0 / c) yi = np.where(c == 0, 0, c0 / c)
f.children = [PlotData( f.children = [PlotData(
[plo, pup], xiii, plotmethod='fill_between', plot_kwds=dict(alpha=0.2, color='r')), [plo, pup], xiii, plotmethod='fill_between',
plot_kwds=dict(alpha=0.2, color='r')),
PlotData(yi, xi, plotmethod='scatter', plot_kwds=dict(color='r', s=5))] PlotData(yi, xi, plotmethod='scatter', plot_kwds=dict(color='r', s=5))]
yiii = interpolate.interp1d(xi, yi)(xiii) yiii = interpolate.interp1d(xi, yi)(xiii)
df = np.diff(fiii) df = np.diff(fiii)
k = (df[:-1] * df[1:] < 0).sum() # numpeaks k = (df[:-1] * df[1:] < 0).sum() # numpeaks
sigmai = (pup - plo) sigmai = (pup - plo)
aicc = (((yiii - fiii) / sigmai) ** 2).sum() + 2 * k * (k + 1) / np.maximum(ni - k + 1, 1) + \ aicc = (((yiii - fiii) / sigmai) ** 2).sum() + \
2 * k * (k + 1) / np.maximum(ni - k + 1, 1) + \
np.abs((yiii - pup).clip(min=0) - (yiii - plo).clip(max=0)).sum() np.abs((yiii - pup).clip(min=0) - (yiii - plo).clip(max=0)).sum()
f.aicc = aicc f.aicc = aicc
@ -4168,7 +4175,7 @@ def check_kreg_demo3():
for fun in ['hste', ]: for fun in ['hste', ]:
#@UnusedVariable #@UnusedVariable
hsmax, hs1, hs2 = _get_regression_smooting(x, y, fun=fun) hsmax, _hs1, _hs2 = _get_regression_smooting(x, y, fun=fun)
for hi in np.linspace(hsmax * 0.25, hsmax, 9): for hi in np.linspace(hsmax * 0.25, hsmax, 9):
plt.figure(k) plt.figure(k)
k += 1 k += 1
@ -4197,7 +4204,7 @@ def check_kreg_demo4():
hopt = sqrt(hopt1 * hopt2) hopt = sqrt(hopt1 * hopt2)
#hopt = _get_regression_smooting(x,y,fun='hos')[0] #hopt = _get_regression_smooting(x,y,fun='hos')[0]
# , 'hisj', 'hns', 'hstt' @UnusedVariable # , 'hisj', 'hns', 'hstt' @UnusedVariable
for j, fun in enumerate(['hste']): for _j, fun in enumerate(['hste']):
hsmax, _hs1, _hs2 = _get_regression_smooting(x, y, fun=fun) hsmax, _hs1, _hs2 = _get_regression_smooting(x, y, fun=fun)
fmax = kreg_demo4(x, y, hsmax + 0.1, hopt) fmax = kreg_demo4(x, y, hsmax + 0.1, hopt)
@ -4295,18 +4302,18 @@ def _get_regression_smooting(x, y, fun='hste'):
def empirical_bin_prb(x, y, hopt, color='r'): def empirical_bin_prb(x, y, hopt, color='r'):
''' '''
Returns empirical binomial probabiltity Returns empirical binomial probabiltity
Parameters Parameters
---------- ----------
x : ndarray x : ndarray
position ve position ve
y : ndarray y : ndarray
binomial response variable (zeros and ones) binomial response variable (zeros and ones)
Returns Returns
------- -------
P(x) : PlotData object P(x) : PlotData object
empirical probability empirical probability
''' '''
xmin, xmax = x.min(), x.max() xmin, xmax = x.min(), x.max()
ni = max(2 * int((xmax - xmin) / hopt) + 3, 5) ni = max(2 * int((xmax - xmin) / hopt) + 3, 5)
@ -4320,10 +4327,12 @@ def empirical_bin_prb(x, y, hopt, color='r'):
else: else:
c0 = np.zeros(xi.shape) c0 = np.zeros(xi.shape)
yi = np.where(c == 0, 0, c0 / c) yi = np.where(c == 0, 0, c0 / c)
return PlotData(yi, xi, plotmethod='scatter', plot_kwds=dict(color=color, s=5)) return PlotData(yi, xi, plotmethod='scatter',
plot_kwds=dict(color=color, s=5))
def smoothed_bin_prb(x, y, hs, hopt, alpha=0.05, color='r', label='', bin_prb=None): def smoothed_bin_prb(x, y, hs, hopt, alpha=0.05, color='r', label='',
bin_prb=None):
''' '''
Parameters Parameters
---------- ----------
@ -4379,14 +4388,16 @@ def smoothed_bin_prb(x, y, hs, hopt, alpha=0.05, color='r', label='', bin_prb=No
if label: if label:
f.plot_kwds['label'] = label f.plot_kwds['label'] = label
f.children = [PlotData( f.children = [PlotData(
[plo, pup], xiii, plotmethod='fill_between', plot_kwds=dict(alpha=0.2, color=color)), [plo, pup], xiii, plotmethod='fill_between',
plot_kwds=dict(alpha=0.2, color=color)),
bin_prb] bin_prb]
yiii = interpolate.interp1d(xi, yi)(xiii) yiii = interpolate.interp1d(xi, yi)(xiii)
df = np.diff(fiii) df = np.diff(fiii)
k = (df[:-1] * df[1:] < 0).sum() # numpeaks k = (df[:-1] * df[1:] < 0).sum() # numpeaks
sigmai = (pup - plo) sigmai = (pup - plo)
aicc = (((yiii - fiii) / sigmai) ** 2).sum() + 2 * k * (k + 1) / np.maximum(ni - k + 1, 1) + \ aicc = (((yiii - fiii) / sigmai) ** 2).sum() + \
2 * k * (k + 1) / np.maximum(ni - k + 1, 1) + \
np.abs((yiii - pup).clip(min=0) - (yiii - plo).clip(max=0)).sum() np.abs((yiii - pup).clip(min=0) - (yiii - plo).clip(max=0)).sum()
f.aicc = aicc f.aicc = aicc
@ -4400,7 +4411,7 @@ def smoothed_bin_prb(x, y, hs, hopt, alpha=0.05, color='r', label='', bin_prb=No
def regressionbin(x, y, alpha=0.05, color='r', label=''): def regressionbin(x, y, alpha=0.05, color='r', label=''):
''' '''
Return kernel regression estimate for binomial data Return kernel regression estimate for binomial data
Parameters Parameters
---------- ----------
x : arraylike x : arraylike
@ -4408,17 +4419,15 @@ def regressionbin(x, y, alpha=0.05, color='r', label=''):
y : arraylike y : arraylike
of 0 and 1 of 0 and 1
''' '''
# @UnusedVariable
hopt1, h1, h2 = _get_regression_smooting(x, y, fun='hos') hopt1, _h1, _h2 = _get_regression_smooting(x, y, fun='hos')
# @UnusedVariable hopt2, _h1, _h2 = _get_regression_smooting(x, y, fun='hste')
hopt2, h1, h2 = _get_regression_smooting(x, y, fun='hste')
hopt = sqrt(hopt1 * hopt2) hopt = sqrt(hopt1 * hopt2)
fbest = smoothed_bin_prb(x, y, hopt2 + 0.1, hopt, alpha, color, label) fbest = smoothed_bin_prb(x, y, hopt2 + 0.1, hopt, alpha, color, label)
bin_prb = fbest.children[-1] bin_prb = fbest.children[-1]
for fun in ['hste']: # , 'hisj', 'hns', 'hstt' for fun in ['hste']: # , 'hisj', 'hns', 'hstt'
#@UnusedVariable hsmax, _hs1, _hs2 = _get_regression_smooting(x, y, fun=fun)
hsmax, hs1, hs2 = _get_regression_smooting(x, y, fun=fun)
for hi in np.linspace(hsmax * 0.1, hsmax, 55): for hi in np.linspace(hsmax * 0.1, hsmax, 55):
f = smoothed_bin_prb(x, y, hi, hopt, alpha, color, label, bin_prb) f = smoothed_bin_prb(x, y, hi, hopt, alpha, color, label, bin_prb)
if f.aicc <= fbest.aicc: if f.aicc <= fbest.aicc:
@ -4479,8 +4488,8 @@ def kde_gauss_demo(n=50):
print(fmax / f2.data.max()) print(fmax / f2.data.max())
format_ = ''.join(('%g, ') * d) format_ = ''.join(('%g, ') * d)
format_ = 'hs0=%s hs1=%s hs2=%s' % (format_, format_, format_) format_ = 'hs0=%s hs1=%s hs2=%s' % (format_, format_, format_)
print( print(format_ % tuple(kde0.hs.tolist() +
format_ % tuple(kde0.hs.tolist() + kde1.tkde.hs.tolist() + kde2.hs.tolist())) kde1.tkde.hs.tolist() + kde2.hs.tolist()))
print('inc0 = %d, inc1 = %d, inc2 = %d' % (kde0.inc, kde1.inc, kde2.inc)) print('inc0 = %d, inc1 = %d, inc2 = %d' % (kde0.inc, kde1.inc, kde2.inc))

@ -1,136 +0,0 @@
import numpy as np
def meshgrid(*xi, **kwargs):
"""
Return coordinate matrices from one or more coordinate vectors.
Make N-D coordinate arrays for vectorized evaluations of
N-D scalar/vector fields over N-D grids, given
one-dimensional coordinate arrays x1, x2,..., xn.
Parameters
----------
x1, x2,..., xn : array_like
1-D arrays representing the coordinates of a grid.
indexing : 'xy' or 'ij' (optional)
cartesian ('xy', default) or matrix ('ij') indexing of output
sparse : True or False (default) (optional)
If True a sparse grid is returned in order to conserve memory.
copy : True (default) or False (optional)
If False a view into the original arrays are returned in order to
conserve memory. Please note that sparse=False, copy=False will likely
return non-contiguous arrays. Furthermore, more than one element of a
broadcasted array may refer to a single memory location. If you
need to write to the arrays, make copies first.
Returns
-------
X1, X2,..., XN : ndarray
For vectors `x1`, `x2`,..., 'xn' with lengths ``Ni=len(xi)`` ,
return ``(N1, N2, N3,...Nn)`` shaped arrays if indexing='ij'
or ``(N2, N1, N3,...Nn)`` shaped arrays if indexing='xy'
with the elements of `xi` repeated to fill the matrix along
the first dimension for `x1`, the second for `x2` and so on.
Notes
-----
This function supports both indexing conventions through the indexing
keyword argument. Giving the string 'ij' returns a meshgrid with matrix
indexing, while 'xy' returns a meshgrid with Cartesian indexing. The
difference is illustrated by the following code snippet:
xv, yv = meshgrid(x, y, sparse=False, indexing='ij')
for i in range(nx):
for j in range(ny):
# treat xv[i,j], yv[i,j]
xv, yv = meshgrid(x, y, sparse=False, indexing='xy')
for i in range(nx):
for j in range(ny):
# treat xv[j,i], yv[j,i]
See Also
--------
index_tricks.mgrid : Construct a multi-dimensional "meshgrid"
using indexing notation.
index_tricks.ogrid : Construct an open multi-dimensional "meshgrid"
using indexing notation.
Examples
--------
>>> nx, ny = (3, 2)
>>> x = np.linspace(0, 1, nx)
>>> y = np.linspace(0, 1, ny)
>>> xv, yv = meshgrid(x, y)
>>> xv
array([[ 0. , 0.5, 1. ],
[ 0. , 0.5, 1. ]])
>>> yv
array([[ 0., 0., 0.],
[ 1., 1., 1.]])
>>> xv, yv = meshgrid(x, y, sparse=True) # make sparse output arrays
>>> xv
array([[ 0. , 0.5, 1. ]])
>>> yv
array([[ 0.],
[ 1.]])
`meshgrid` is very useful to evaluate functions on a grid.
>>> x = np.arange(-5, 5, 0.1)
>>> y = np.arange(-5, 5, 0.1)
>>> xx, yy = meshgrid(x, y, sparse=True)
>>> z = np.sin(xx**2+yy**2)/(xx**2+yy**2)
>>> import matplotlib.pyplot as plt
>>> h = plt.contourf(x,y,z)
"""
copy_ = kwargs.get('copy', True)
args = np.atleast_1d(*xi)
ndim = len(args)
if not isinstance(args, list) or ndim < 2:
raise TypeError(
'meshgrid() takes 2 or more arguments (%d given)' % int(ndim > 0))
sparse = kwargs.get('sparse', False)
indexing = kwargs.get('indexing', 'xy')
s0 = (1,) * ndim
output = [x.reshape(s0[:i] + (-1,) + s0[i + 1::])
for i, x in enumerate(args)]
shape = [x.size for x in output]
if indexing == 'xy':
# switch first and second axis
output[0].shape = (1, -1) + (1,) * (ndim - 2)
output[1].shape = (-1, 1) + (1,) * (ndim - 2)
shape[0], shape[1] = shape[1], shape[0]
if sparse:
if copy_:
return [x.copy() for x in output]
else:
return output
else:
# Return the full N-D matrix (not only the 1-D vector)
if copy_:
mult_fact = np.ones(shape, dtype=int)
return [x * mult_fact for x in output]
else:
return np.broadcast_arrays(*output)
def ndgrid(*args, **kwargs):
"""
Same as calling meshgrid with indexing='ij' (see meshgrid for
documentation).
"""
kwargs['indexing'] = 'ij'
return meshgrid(*args, **kwargs)
if __name__ == '__main__':
import doctest
doctest.testmod()

File diff suppressed because it is too large Load Diff

@ -1,132 +1,144 @@
from operator import itemgetter as _itemgetter from operator import itemgetter as _itemgetter
from keyword import iskeyword as _iskeyword from keyword import iskeyword as _iskeyword
import sys as _sys import sys as _sys
def namedtuple(typename, field_names, verbose=False):
"""Returns a new subclass of tuple with named fields. def namedtuple(typename, field_names, verbose=False):
"""Returns a new subclass of tuple with named fields.
>>> Point = namedtuple('Point', 'x y')
>>> Point.__doc__ # docstring for the new class >>> Point = namedtuple('Point', 'x y')
'Point(x, y)' >>> Point.__doc__ # docstring for the new class
>>> p = Point(11, y=22) # instantiate with positional args or keywords 'Point(x, y)'
>>> p[0] + p[1] # indexable like a plain tuple >>> p = Point(11, y=22) # instantiate with positional args or keywords
33 >>> p[0] + p[1] # indexable like a plain tuple
>>> x, y = p # unpack like a regular tuple 33
>>> x, y >>> x, y = p # unpack like a regular tuple
(11, 22) >>> x, y
>>> p.x + p.y # fields also accessable by name (11, 22)
33 >>> p.x + p.y # fields also accessable by name
>>> d = p._asdict() # convert to a dictionary 33
>>> d['x'] >>> d = p._asdict() # convert to a dictionary
11 >>> d['x']
>>> Point(**d) # convert from a dictionary 11
Point(x=11, y=22) >>> Point(**d) # convert from a dictionary
>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields Point(x=11, y=22)
Point(x=100, y=22) >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
Point(x=100, y=22)
"""
"""
# Parse and validate the field names. Validation serves two purposes,
# generating informative error messages and preventing template injection attacks. # Parse and validate the field names. Validation serves two purposes,
if isinstance(field_names, basestring): # generating informative error messages and preventing template injection
field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas # attacks.
field_names = tuple(field_names) if isinstance(field_names, basestring):
for name in (typename,) + field_names: # names separated by whitespace and/or commas
if not min(c.isalnum() or c=='_' for c in name): field_names = field_names.replace(',', ' ').split()
raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name) field_names = tuple(field_names)
if _iskeyword(name): for name in (typename,) + field_names:
raise ValueError('Type names and field names cannot be a keyword: %r' % name) if not min(c.isalnum() or c == '_' for c in name):
if name[0].isdigit(): raise ValueError(
raise ValueError('Type names and field names cannot start with a number: %r' % name) 'Type names and field names can only contain alphanumeric ' +
seen_names = set() 'characters and underscores: %r' % name)
for name in field_names: if _iskeyword(name):
if name.startswith('_'): raise ValueError(
raise ValueError('Field names cannot start with an underscore: %r' % name) 'Type names and field names cannot be a keyword: %r' % name)
if name in seen_names: if name[0].isdigit():
raise ValueError('Encountered duplicate field name: %r' % name) raise ValueError('Type names and field names cannot start ' +
seen_names.add(name) 'with a number: %r' % name)
seen_names = set()
# Create and fill-in the class template for name in field_names:
numfields = len(field_names) if name.startswith('_'):
argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes raise ValueError(
reprtxt = ', '.join('%s=%%r' % name for name in field_names) 'Field names cannot start with an underscore: %r' % name)
dicttxt = ', '.join('%r: t[%d]' % (name, pos) for pos, name in enumerate(field_names)) if name in seen_names:
template = '''class %(typename)s(tuple): raise ValueError('Encountered duplicate field name: %r' % name)
'%(typename)s(%(argtxt)s)' \n seen_names.add(name)
__slots__ = () \n
_fields = %(field_names)r \n # Create and fill-in the class template
def __new__(cls, %(argtxt)s): numfields = len(field_names)
return tuple.__new__(cls, (%(argtxt)s)) \n # tuple repr without parens or quotes
@classmethod argtxt = repr(field_names).replace("'", "")[1:-1]
def _make(cls, iterable, new=tuple.__new__, len=len): reprtxt = ', '.join('%s=%%r' % name for name in field_names)
'Make a new %(typename)s object from a sequence or iterable' dicttxt = ', '.join('%r: t[%d]' % (name, pos)
result = new(cls, iterable) for pos, name in enumerate(field_names))
if len(result) != %(numfields)d: template = '''class %(typename)s(tuple):
raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result)) '%(typename)s(%(argtxt)s)' \n
return result \n __slots__ = () \n
def __repr__(self): _fields = %(field_names)r \n
return '%(typename)s(%(reprtxt)s)' %% self \n def __new__(cls, %(argtxt)s):
def _asdict(t): return tuple.__new__(cls, (%(argtxt)s)) \n
'Return a new dict which maps field names to their values' @classmethod
return {%(dicttxt)s} \n def _make(cls, iterable, new=tuple.__new__, len=len):
def _replace(self, **kwds): 'Make a new %(typename)s object from a sequence or iterable'
'Return a new %(typename)s object replacing specified fields with new values' result = new(cls, iterable)
result = self._make(map(kwds.pop, %(field_names)r, self)) if len(result) != %(numfields)d:
if kwds: raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result))
raise ValueError('Got unexpected field names: %%r' %% kwds.keys()) return result \n
return result \n\n''' % locals() def __repr__(self):
for i, name in enumerate(field_names): return '%(typename)s(%(reprtxt)s)' %% self \n
template += ' %s = property(itemgetter(%d))\n' % (name, i) def _asdict(t):
if verbose: 'Return a new dict which maps field names to their values'
print template return {%(dicttxt)s} \n
def _replace(self, **kwds):
# Execute the template string in a temporary namespace 'Return a new %(typename)s object replacing specified fields with new values'
namespace = dict(itemgetter=_itemgetter) result = self._make(map(kwds.pop, %(field_names)r, self))
try: if kwds:
exec template in namespace raise ValueError('Got unexpected field names: %%r' %% kwds.keys())
except SyntaxError, e: return result \n\n''' % locals()
raise SyntaxError(e.message + ':\n' + template) for i, name in enumerate(field_names):
result = namespace[typename] template += ' %s = property(itemgetter(%d))\n' % (name, i)
if verbose:
# For pickling to work, the __module__ variable needs to be set to the frame print template
# where the named tuple is created. Bypass this step in enviroments where
# sys._getframe is not defined (Jython for example). # Execute the template string in a temporary namespace
if hasattr(_sys, '_getframe'): namespace = dict(itemgetter=_itemgetter)
result.__module__ = _sys._getframe(1).f_globals['__name__'] try:
exec template in namespace
return result except SyntaxError, e:
raise SyntaxError(e.message + ':\n' + template)
result = namespace[typename]
# For pickling to work, the __module__ variable needs to be set to the
# frame where the named tuple is created. Bypass this step in enviroments
# where sys._getframe is not defined (Jython for example).
if __name__ == '__main__': if hasattr(_sys, '_getframe'):
# verify that instances can be pickled result.__module__ = _sys._getframe(1).f_globals['__name__']
from cPickle import loads, dumps
Point = namedtuple('Point', 'x, y', True) return result
p = Point(x=10, y=20)
assert p == loads(dumps(p))
if __name__ == '__main__':
# test and demonstrate ability to override methods # verify that instances can be pickled
class Point(namedtuple('Point', 'x y')): from cPickle import loads, dumps
@property Point = namedtuple('Point', 'x, y', True)
def hypot(self): p = Point(x=10, y=20)
return (self.x ** 2 + self.y ** 2) ** 0.5 assert p == loads(dumps(p))
def __str__(self):
return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) # test and demonstrate ability to override methods
class Point(namedtuple('Point', 'x y')):
for p in Point(3,4), Point(14,5), Point(9./7,6):
print p @property
def hypot(self):
class Point(namedtuple('Point', 'x y')): return (self.x ** 2 + self.y ** 2) ** 0.5
'Point class with optimized _make() and _replace() without error-checking'
_make = classmethod(tuple.__new__) def __str__(self):
def _replace(self, _map=map, **kwds): return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y,
return self._make(_map(kwds.get, ('x', 'y'), self)) self.hypot)
print Point(11, 22)._replace(x=100) for p in Point(3, 4), Point(14, 5), Point(9. / 7, 6):
print p
import doctest
TestResults = namedtuple('TestResults', 'failed attempted') class Point(namedtuple('Point', 'x y')):
print TestResults(*doctest.testmod()) '''Point class with optimized _make() and _replace()
without error-checking
'''
_make = classmethod(tuple.__new__)
def _replace(self, _map=map, **kwds):
return self._make(_map(kwds.get, ('x', 'y'), self))
print Point(11, 22)._replace(x=100)
import doctest
TestResults = namedtuple('TestResults', 'failed attempted')
print TestResults(*doctest.testmod())

File diff suppressed because it is too large Load Diff

@ -7,7 +7,7 @@ if False:
try: try:
from scitools import easyviz as plotbackend from scitools import easyviz as plotbackend
if verbose: if verbose:
print('wafo.wafodata: plotbackend is set to scitools.easyviz') print('wafo: plotbackend is set to scitools.easyviz')
except: except:
warnings.warn('wafo: Unable to load scitools.easyviz as plotbackend') warnings.warn('wafo: Unable to load scitools.easyviz as plotbackend')
plotbackend = None plotbackend = None
@ -16,7 +16,7 @@ else:
from matplotlib import pyplot as plotbackend from matplotlib import pyplot as plotbackend
plotbackend.interactive(True) plotbackend.interactive(True)
if verbose: if verbose:
print('wafo.wafodata: plotbackend is set to matplotlib.pyplot') print('wafo: plotbackend is set to matplotlib.pyplot')
except: except:
warnings.warn('wafo: Unable to load matplotlib.pyplot as plotbackend') warnings.warn('wafo: Unable to load matplotlib.pyplot as plotbackend')
plotbackend = None plotbackend = None

File diff suppressed because it is too large Load Diff

@ -1,303 +1,320 @@
''' '''
Created on 15. des. 2009 Created on 15. des. 2009
@author: pab @author: pab
''' '''
#import os #import os
#import sys #import sys
#import win32com #import win32com
#from win32com.client.selecttlb import EnumTlbs #from win32com.client.selecttlb import EnumTlbs
#typelib_mso = None #typelib_mso = None
#typelib_msppt = None #typelib_msppt = None
#for typelib in EnumTlbs(): # for typelib in EnumTlbs():
# d = typelib.desc.split(' ') # d = typelib.desc.split(' ')
# if d[0] == 'Microsoft' and d[1] == 'Office' and d[3] == 'Object' and d[4] == 'Library': # if d[0] == 'Microsoft' and d[1] == 'Office' and d[3] == 'Object' \
# typelib_mso = typelib # and d[4] == 'Library':
# if d[0] == 'Microsoft' and d[1] == 'PowerPoint' and d[3] == 'Object' and d[4] == 'Library': # typelib_mso = typelib
# typelib_msppt = typelib # if d[0] == 'Microsoft' and d[1] == 'PowerPoint' and d[3] == 'Object' \
#if hasattr(sys, 'frozen'): # If we're an .exe file # and d[4] == 'Library':
# win32com.__gen_path__ = os.path.dirname(sys.executable) # typelib_msppt = typelib
## win32com.__gen_path__ = os.environ['TEMP'] # if hasattr(sys, 'frozen'): # If we're an .exe file
#if win32com.client.gencache.is_readonly: # win32com.__gen_path__ = os.path.dirname(sys.executable)
# win32com.client.gencache.is_readonly = False ## win32com.__gen_path__ = os.environ['TEMP']
# win32com.client.gencache.Rebuild() # if win32com.client.gencache.is_readonly:
#MSPPT = win32com.client.gencache.EnsureModule(typelib_msppt.clsid, typelib_msppt.lcid, # win32com.client.gencache.is_readonly = False
# int(typelib_msppt.major), int(typelib_msppt.minor)) # win32com.client.gencache.Rebuild()
#MSO = win32com.client.gencache.EnsureModule(typelib_mso.clsid, typelib_mso.lcid, # MSPPT = win32com.client.gencache.EnsureModule(typelib_msppt.clsid,
# int(typelib_mso.major), int(typelib_mso.minor)) # typelib_msppt.lcid,
import os # int(typelib_msppt.major),
import warnings # int(typelib_msppt.minor))
import win32com.client # MSO = win32com.client.gencache.EnsureModule(typelib_mso.clsid,
import MSO # typelib_mso.lcid,
import MSPPT # int(typelib_mso.major), int(typelib_mso.minor))
from PIL import Image #@UnresolvedImport import os
import warnings
g = globals() import win32com.client
for c in dir(MSO.constants): import MSO
g[c] = getattr(MSO.constants, c) import MSPPT
for c in dir(MSPPT.constants): from PIL import Image # @UnresolvedImport
g[c] = getattr(MSPPT.constants, c)
g = globals()
class Powerpoint(object): for c in dir(MSO.constants):
def __init__(self, file_name=''): g[c] = getattr(MSO.constants, c)
for c in dir(MSPPT.constants):
self.application = win32com.client.Dispatch("Powerpoint.Application") g[c] = getattr(MSPPT.constants, c)
#self.application.Visible = True
self._visible = self.application.Visible
if file_name: class Powerpoint(object):
self.presentation = self.application.Presentations.Open(file_name)
else: def __init__(self, file_name=''):
self.presentation = self.application.Presentations.Add()
self.num_slides = 0 self.application = win32com.client.Dispatch("Powerpoint.Application")
# default picture width and height #self.application.Visible = True
self.default_width = 500 self._visible = self.application.Visible
self.default_height = 400 if file_name:
self.title_font = 'Arial' #'Boopee' self.presentation = self.application.Presentations.Open(file_name)
self.title_size = 36 else:
self.text_font = 'Arial' #'Boopee' self.presentation = self.application.Presentations.Add()
self.text_size = 20 self.num_slides = 0
self.footer = '' # default picture width and height
self.default_width = 500
def set_footer(self): self.default_height = 400
''' self.title_font = 'Arial' # 'Boopee'
Set Footer in SlideMaster and NotesMaster self.title_size = 36
''' self.text_font = 'Arial' # 'Boopee'
if self.footer: self.text_size = 20
if self.presentation.HasTitleMaster: self.footer = ''
TMHF = self.presentation.TitleMaster.HeadersFooters
TMHF.Footer.Text = self.footer def set_footer(self):
TMHF.Footer.Visible = True '''
Set Footer in SlideMaster and NotesMaster
SMHF = self.presentation.SlideMaster.HeadersFooters '''
SMHF.Footer.Text = self.footer if self.footer:
SMHF.Footer.Visible = True if self.presentation.HasTitleMaster:
SMHF.SlideNumber.Visible= True TMHF = self.presentation.TitleMaster.HeadersFooters
NMHF = self.presentation.NotesMaster.HeadersFooters TMHF.Footer.Text = self.footer
NMHF.Footer.Text = self.footer TMHF.Footer.Visible = True
NMHF.SlideNumber.Visible= True
for slide in self.presentation.Slides: SMHF = self.presentation.SlideMaster.HeadersFooters
shapes = slide.Shapes SMHF.Footer.Text = self.footer
for shape in shapes: SMHF.Footer.Visible = True
if shape.Name=='Footer': SMHF.SlideNumber.Visible = True
footer = shape NMHF = self.presentation.NotesMaster.HeadersFooters
break NMHF.Footer.Text = self.footer
else: NMHF.SlideNumber.Visible = True
footer = shapes.AddTextbox(msoTextOrientationHorizontal, Left=0, Top=510, Width=720, Height=28.875) #@UndefinedVariable for slide in self.presentation.Slides:
footer.Name = 'Footer' shapes = slide.Shapes
footer.TextFrame.TextRange.Text = self.footer for shape in shapes:
if shape.Name == 'Footer':
footer = shape
def add_title_slide(self, title, subtitle=''): break
self.num_slides +=1 else:
slide = self.presentation.Slides.Add(self.num_slides, MSPPT.constants.ppLayoutTitle) footer = shapes.AddTextbox(
msoTextOrientationHorizontal, # @UndefinedVariable
unused_title_id, unused_textbox_id = 1, 2 Left=0, Top=510, Width=720, Height=28.875)
for id_, title1 in enumerate([title, subtitle]): footer.Name = 'Footer'
titlerange = slide.Shapes(id_+1).TextFrame.TextRange footer.TextFrame.TextRange.Text = self.footer
titlerange.Text = title1
titlerange.Font.Name = self.title_font def add_title_slide(self, title, subtitle=''):
titlerange.Font.Size = self.title_size-id_*12 if self.title_size>22 else self.title_size self.num_slides += 1
slide = self.presentation.Slides.Add(
def add_slide(self, title='', texts='', notes='', image_file='', self.num_slides, MSPPT.constants.ppLayoutTitle)
maxlevel=None, left=220, width=-1, height=-1):
self.num_slides +=1 unused_title_id, unused_textbox_id = 1, 2
slide = self.presentation.Slides.Add(self.num_slides, MSPPT.constants.ppLayoutText) for id_, title1 in enumerate([title, subtitle]):
titlerange = slide.Shapes(id_ + 1).TextFrame.TextRange
self.add2slide(slide, title, texts, notes, image_file, maxlevel, left, width, height) titlerange.Text = title1
return slide titlerange.Font.Name = self.title_font
titlerange.Font.Size = self.title_size - id_ * \
def add2slide(self, slide, title='', texts='', notes='', image_file='', 12 if self.title_size > 22 else self.title_size
maxlevel=None, left=220, width=-1, height=-1, keep_aspect=True):
title_id, textbox_id = 1, 2 def add_slide(self, title='', texts='', notes='', image_file='',
if title: maxlevel=None, left=220, width=-1, height=-1):
titlerange = slide.Shapes(title_id).TextFrame.TextRange self.num_slides += 1
titlerange.Font.Name = self.title_font slide = self.presentation.Slides.Add(
titlerange.Text = title self.num_slides, MSPPT.constants.ppLayoutText)
titlerange.Font.Size = self.title_size
self.add2slide(slide, title, texts, notes, image_file, maxlevel, left,
if texts != '' and texts != ['']: width, height)
#textrange = slide.Shapes(textbox_id).TextFrame.TextRange return slide
self._add_text(slide, textbox_id, texts, maxlevel)
def add2slide(self, slide, title='', texts='', notes='', image_file='',
if image_file != '' and image_file != ['']: maxlevel=None, left=220, width=-1, height=-1,
if keep_aspect: keep_aspect=True):
im = Image.open(image_file) title_id, textbox_id = 1, 2
t_w, t_h = im.size if title:
if height<=0 and width<=0: titlerange = slide.Shapes(title_id).TextFrame.TextRange
if t_w*self.default_height < t_h*self.default_width: titlerange.Font.Name = self.title_font
height = self.default_height titlerange.Text = title
else: titlerange.Font.Size = self.title_size
width = self.default_width
if height<=0 and width: if texts != '' and texts != ['']:
height = t_h * width / t_w #textrange = slide.Shapes(textbox_id).TextFrame.TextRange
elif height and width <=0: self._add_text(slide, textbox_id, texts, maxlevel)
width = t_w * height / t_h
if image_file != '' and image_file != ['']:
slide.Shapes.AddPicture(FileName=image_file, LinkToFile=False, if keep_aspect:
SaveWithDocument=True, im = Image.open(image_file)
Left=left, Top=110, t_w, t_h = im.size
Width=width, Height=height) #400) if height <= 0 and width <= 0:
if notes != '' and notes != ['']: if t_w * self.default_height < t_h * self.default_width:
notespage = slide.NotesPage #.Shapes(2).TextFrame.TextRange height = self.default_height
self._add_text(notespage, 2, notes) else:
return slide width = self.default_width
if height <= 0 and width:
def _add_text(self, page, id, txt, maxlevel=None): #@ReservedAssignment height = t_h * width / t_w
page.Shapes(id).TextFrame.TextRange.Font.Name = self.text_font elif height and width <= 0:
width = t_w * height / t_h
if isinstance(txt, dict):
self._add_text_from_dict(page, id, txt, 1, maxlevel) slide.Shapes.AddPicture(FileName=image_file, LinkToFile=False,
elif isinstance(txt, (list, tuple)): SaveWithDocument=True,
self._add_text_from_list(page, id, txt, maxlevel) Left=left, Top=110,
else: Width=width, Height=height) # 400)
unused_tr = page.Shapes(id).TextFrame.TextRange.InsertAfter(txt) if notes != '' and notes != ['']:
unused_temp = page.Shapes(id).TextFrame.TextRange.InsertAfter('\r') notespage = slide.NotesPage # .Shapes(2).TextFrame.TextRange
self._add_text(notespage, 2, notes)
page.Shapes(id).TextFrame.TextRange.Font.Size = self.text_size return slide
def _add_text_from_dict(self, page, id, txt_dict, level, maxlevel=None): #@ReservedAssignment def _add_text(self, page, id, txt, maxlevel=None): # @ReservedAssignment
if maxlevel is None or level<=maxlevel: page.Shapes(id).TextFrame.TextRange.Font.Name = self.text_font
for name, subdict in txt_dict.iteritems():
tr = page.Shapes(id).TextFrame.TextRange.InsertAfter(name) if isinstance(txt, dict):
unused_temp = page.Shapes(id).TextFrame.TextRange.InsertAfter('\r') self._add_text_from_dict(page, id, txt, 1, maxlevel)
tr.IndentLevel = level elif isinstance(txt, (list, tuple)):
self._add_text_from_dict(page, id, subdict, min(level+1,5), maxlevel) self._add_text_from_list(page, id, txt, maxlevel)
else:
def _add_text_from_list(self, page, id, txt_list, maxlevel=None): #@ReservedAssignment unused_tr = page.Shapes(id).TextFrame.TextRange.InsertAfter(txt)
for txt in txt_list: unused_temp = page.Shapes(id).TextFrame.TextRange.InsertAfter('\r')
level = 1
while isinstance(txt, (list, tuple)): page.Shapes(id).TextFrame.TextRange.Font.Size = self.text_size
txt = txt[0]
level += 1 def _add_text_from_dict(self, page, id, txt_dict, # @ReservedAssignment
if maxlevel is None or level<=maxlevel: level, maxlevel=None):
tr = page.Shapes(id).TextFrame.TextRange.InsertAfter(txt) if maxlevel is None or level <= maxlevel:
unused_temp = page.Shapes(id).TextFrame.TextRange.InsertAfter('\r') for name, subdict in txt_dict.iteritems():
tr.IndentLevel = level tr = page.Shapes(id).TextFrame.TextRange.InsertAfter(name)
unused_temp = page.Shapes(
id).TextFrame.TextRange.InsertAfter('\r')
def save(self, fullfile=''): tr.IndentLevel = level
if fullfile: self._add_text_from_dict(
self.presentation.SaveAs(FileName=fullfile) page, id, subdict, min(level + 1, 5), maxlevel)
else:
self.presentation.Save() def _add_text_from_list(self, page, id, # @ReservedAssignment
txt_list, maxlevel=None):
for txt in txt_list:
def quit(self): #@ReservedAssignment level = 1
if self._visible: while isinstance(txt, (list, tuple)):
self.presentation.Close() txt = txt[0]
else: level += 1
self.application.Quit() if maxlevel is None or level <= maxlevel:
tr = page.Shapes(id).TextFrame.TextRange.InsertAfter(txt)
def quit_only_if_hidden(self): unused_temp = page.Shapes(
if not self._visible: id).TextFrame.TextRange.InsertAfter('\r')
self.application.Quit() tr.IndentLevel = level
def test_powerpoint(): def save(self, fullfile=''):
# Make powerpoint if fullfile:
self.presentation.SaveAs(FileName=fullfile)
ppt = Powerpoint() else:
#time. self.presentation.Save()
ppt.footer='This is the footer'
ppt.add_title_slide('Title', 'Per A.') def quit(self): # @ReservedAssignment
ppt.add_slide(title='alsfkasldk', texts='asdflaf', notes='asdfas') if self._visible:
ppt.set_footer() self.presentation.Close()
else:
def make_ppt(): self.application.Quit()
application = win32com.client.Dispatch("Powerpoint.Application")
application.Visible = True def quit_only_if_hidden(self):
presentation = application.Presentations.Add() if not self._visible:
slide1 = presentation.Slides.Add(1, MSPPT.constants.ppLayoutText) self.application.Quit()
# title = slide1.Shapes.AddTextBox(Type=msoTextOrientationHorizontal,Left=50, Top=10, Width=620, Height=70) def test_powerpoint():
# title.TextFrame.TextRange.Text = 'Overskrift' # Make powerpoint
ppt = Powerpoint()
title_id, textbox_id = 1,2 # time.
slide1.Shapes(title_id).TextFrame.TextRange.Text = 'Overskrift' ppt.footer = 'This is the footer'
#slide1.Shapes(title_id).TextFrame.Width = 190 ppt.add_title_slide('Title', 'Per A.')
ppt.add_slide(title='alsfkasldk', texts='asdflaf', notes='asdfas')
ppt.set_footer()
slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('Test')
unused_tr = slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('\r')
slide1.Shapes(textbox_id).TextFrame.TextRange.IndentLevel = 1 def make_ppt():
tr = slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('tests') application = win32com.client.Dispatch("Powerpoint.Application")
unused_tr0 = slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('\r') application.Visible = True
tr.IndentLevel=2 presentation = application.Presentations.Add()
tr1 = slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('test3') slide1 = presentation.Slides.Add(1, MSPPT.constants.ppLayoutText)
tr1.IndentLevel=3
#slide1.Shapes(textbox_id).TextFrame.TextRange.Text = 'Test \r test2' # title = slide1.Shapes.AddTextBox(Type=msoTextOrientationHorizontal,
# Left=50, Top=10, Width=620, Height=70)
# textbox = slide1.Shapes.AddTextBox(Type=msoTextOrientationHorizontal,Left=30, Top=100, Width=190, Height=400) # title.TextFrame.TextRange.Text = 'Overskrift'
# textbox.TextFrame.TextRange.Text = 'Test \r test2' title_id, textbox_id = 1, 2
#picbox = slide1.Shapes(picb_id) slide1.Shapes(title_id).TextFrame.TextRange.Text = 'Overskrift'
#slide1.Shapes(title_id).TextFrame.Width = 190
filename = r'c:\temp\data1_report1_and_2_Tr120_1.png'
slide1.Shapes.AddPicture(FileName=filename, LinkToFile=False, slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('Test')
SaveWithDocument=True, unused_tr = slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('\r')
Left=220, Top=100, Width=500, Height=420) slide1.Shapes(textbox_id).TextFrame.TextRange.IndentLevel = 1
tr = slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('tests')
slide1.NotesPage.Shapes(2).TextFrame.TextRange.Text = 'test' unused_tr0 = slide1.Shapes(
textbox_id).TextFrame.TextRange.InsertAfter('\r')
tr.IndentLevel = 2
tr1 = slide1.Shapes(textbox_id).TextFrame.TextRange.InsertAfter('test3')
# for shape in slide1.Shapes: tr1.IndentLevel = 3
# shape.TextFrame.TextRange.Text = 'Test \r test2' #slide1.Shapes(textbox_id).TextFrame.TextRange.Text = 'Test \r test2'
#slide1.Shapes.Titles.TextFrames.TestRange.Text
# shape = slide1.Shapes.AddShape(msoShapeRectangle, 300, 100, 400, 400) # textbox = slide1.Shapes.AddTextBox(Type=msoTextOrientationHorizontal,
# shape.TextFrame.TextRange.Text = 'Test \n test2' # Left=30, Top=100, Width=190, Height=400)
# shape.TextFrame.TextRange.Font.Size = 12 # textbox.TextFrame.TextRange.Text = 'Test \r test2'
#picbox = slide1.Shapes(picb_id)
#
# app = wx.PySimpleApp() filename = r'c:\temp\data1_report1_and_2_Tr120_1.png'
# dialog = wx.FileDialog(None, 'Choose image file', defaultDir=os.getcwd(), slide1.Shapes.AddPicture(FileName=filename, LinkToFile=False,
# wildcard='*.*', SaveWithDocument=True,
# style=wx.OPEN | wx.CHANGE_DIR | wx.MULTIPLE) Left=220, Top=100, Width=500, Height=420)
#
# if dialog.ShowModal() == wx.ID_OK: slide1.NotesPage.Shapes(2).TextFrame.TextRange.Text = 'test'
# files_or_paths = dialog.GetPaths()
# for filename in files_or_paths:
# slide1.Shapes.AddPicture(FileName=filename, LinkToFile=False, # for shape in slide1.Shapes:
# SaveWithDocument=True, # shape.TextFrame.TextRange.Text = 'Test \r test2'
# Left=100, Top=100, Width=200, Height=200) # slide1.Shapes.Titles.TextFrames.TestRange.Text
# dialog.Destroy() # shape = slide1.Shapes.AddShape(msoShapeRectangle, 300, 100, 400, 400)
#presentation.Save() # shape.TextFrame.TextRange.Text = 'Test \n test2'
#application.Quit() # shape.TextFrame.TextRange.Font.Size = 12
def rename_ppt(): #
root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2008b/plots' # app = wx.PySimpleApp()
# root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2008b/plots' # dialog = wx.FileDialog(None, 'Choose image file', defaultDir=os.getcwd(),
# root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2010a/plots' # wildcard='*.*',
# root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2010a/plots' # style=wx.OPEN | wx.CHANGE_DIR | wx.MULTIPLE)
#filename = r'mag_sweep_best_tsmps_ship_eff0-10.ppt' #
filenames = os.listdir(root) # if dialog.ShowModal() == wx.ID_OK:
prefix = 'TSMPSv2008b_' # files_or_paths = dialog.GetPaths()
#prefix = 'TSMPSv2010a_' # for filename in files_or_paths:
for filename in filenames: # slide1.Shapes.AddPicture(FileName=filename, LinkToFile=False,
if filename.endswith('.ppt'): # SaveWithDocument=True,
try: # Left=100, Top=100, Width=200, Height=200)
ppt = Powerpoint(os.path.join(root,filename)) # dialog.Destroy()
ppt.footer = prefix + filename # presentation.Save()
ppt.set_footer() # application.Quit()
ppt.save(os.path.join(root, ppt.footer)) def rename_ppt():
except: root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2008b/plots'
warnings.warn('Unable to load %s' % filename) # root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2008b/plots'
def load_file_into_ppt(): # root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2010a/plots'
root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2008b/plots' # root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2010a/plots'
# root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2008b/plots' #filename = r'mag_sweep_best_tsmps_ship_eff0-10.ppt'
# root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2010a/plots' filenames = os.listdir(root)
# root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2010a/plots' prefix = 'TSMPSv2008b_'
#filename = r'mag_sweep_best_tsmps_ship_eff0-10.ppt' #prefix = 'TSMPSv2010a_'
filenames = os.listdir(root) for filename in filenames:
prefix = 'TSMPSv2008b_' if filename.endswith('.ppt'):
#prefix = 'TSMPSv2010a_' try:
for filename in filenames: ppt = Powerpoint(os.path.join(root, filename))
if filename.startswith(prefix) and filename.endswith('.ppt'): ppt.footer = prefix + filename
try: ppt.set_footer()
unused_ppt = Powerpoint(os.path.join(root,filename)) ppt.save(os.path.join(root, ppt.footer))
except: except:
warnings.warn('Unable to load %s' % filename) warnings.warn('Unable to load %s' % filename)
if __name__ == '__main__':
#make_ppt()
#test_powerpoint() def load_file_into_ppt():
#load_file_into_ppt() root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2008b/plots'
rename_ppt() # root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2008b/plots'
# root = r'C:/pab/tsm_opeval/analysis_tsmps_mag_v2010a/plots'
# root = r'C:/pab/tsm_opeval/analysis_tsmps_aco_v2010a/plots'
#filename = r'mag_sweep_best_tsmps_ship_eff0-10.ppt'
filenames = os.listdir(root)
prefix = 'TSMPSv2008b_'
#prefix = 'TSMPSv2010a_'
for filename in filenames:
if filename.startswith(prefix) and filename.endswith('.ppt'):
try:
unused_ppt = Powerpoint(os.path.join(root, filename))
except:
warnings.warn('Unable to load %s' % filename)
if __name__ == '__main__':
# make_ppt()
# test_powerpoint()
# load_file_into_ppt()
rename_ppt()

File diff suppressed because it is too large Load Diff

@ -5,7 +5,7 @@ Spectrum package in WAFO Toolbox.
""" """
from core import * from core import *
#SpecData1D, SpecData2D, cltext #SpecData1D, SpecData2D, cltext
import models import models
from wafo.wave_theory import dispersion_relation from wafo.wave_theory import dispersion_relation

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,76 +1,133 @@
import unittest
import numpy as np import numpy as np
from wafo.spectrum.models import (Bretschneider, Jonswap, OchiHubble, Tmaspec,
Torsethaugen, McCormick, Wallop)
def test_bretschneider():
S = Bretschneider(Hm0=6.5, Tp=10)
vals = S((0, 1, 2, 3))
true_vals = np.array([0., 1.69350993, 0.06352698, 0.00844783])
assert((np.abs(vals - true_vals) < 1e-7).all())
def test_if_jonswap_with_gamma_one_equals_bretschneider():
S = Jonswap(Hm0=7, Tp=11, gamma=1)
vals = S((0, 1, 2, 3))
true_vals = np.array([0., 1.42694133, 0.05051648, 0.00669692])
assert((np.abs(vals - true_vals) < 1e-7).all())
w = np.linspace(0, 5)
S2 = Bretschneider(Hm0=7, Tp=11)
# JONSWAP with gamma=1 should be equal to Bretscneider:
assert(np.all(np.abs(S(w) - S2(w)) < 1.e-7))
def test_tmaspec():
S = Tmaspec(Hm0=7, Tp=11, gamma=1, h=10)
vals = S((0, 1, 2, 3))
true_vals = np.array([0., 0.70106233, 0.05022433, 0.00669692])
assert((np.abs(vals - true_vals) < 1e-7).all())
def test_torsethaugen():
S = Torsethaugen(Hm0=7, Tp=11, gamma=1, h=10)
vals = S((0, 1, 2, 3))
true_vals = np.array([0., 1.19989709, 0.05819794, 0.0093541])
assert((np.abs(vals - true_vals) < 1e-7).all())
vals = S.wind(range(4)) from wafo.spectrum.models import (Bretschneider, Jonswap, OchiHubble, Tmaspec,
true_vals = np.array([0., 1.13560528, 0.05529849, 0.00888989]) Torsethaugen, McCormick, Wallop, Spreading)
assert((np.abs(vals - true_vals) < 1e-7).all())
vals = S.swell(range(4))
true_vals = np.array([0., 0.0642918, 0.00289946, 0.00046421]) class TestCase(unittest.TestCase):
assert((np.abs(vals - true_vals) < 1e-7).all()) def assertListAlmostEqual(self, list1, list2, places=None, msg=None):
self.assertEqual(len(list1), len(list2))
for a, b in zip(list1, list2):
def test_ochihubble(): self.assertAlmostEqual(a, b, places, msg)
S = OchiHubble(par=2)
vals = S(range(4)) class TestSpectra(TestCase):
true_vals = np.array([0., 0.90155636, 0.04185445, 0.00583207]) def test_bretschneider(self):
assert((np.abs(vals - true_vals) < 1e-7).all()) S = Bretschneider(Hm0=6.5, Tp=10)
vals = S((0, 1, 2, 3)).tolist()
true_vals = [0., 1.69350993, 0.06352698, 0.00844783]
def test_mccormick(): self.assertListAlmostEqual(vals, true_vals)
S = McCormick(Hm0=6.5, Tp=10) def test_if_jonswap_with_gamma_one_equals_bretschneider(self):
vals = S(range(4)) S = Jonswap(Hm0=7, Tp=11, gamma=1)
true_vals = np.array([0., 1.87865908, 0.15050447, 0.02994663]) vals = S((0, 1, 2, 3))
assert((np.abs(vals - true_vals) < 1e-7).all()) true_vals = np.array([0., 1.42694133, 0.05051648, 0.00669692])
self.assertListAlmostEqual(vals, true_vals)
w = np.linspace(0, 5)
def test_wallop(): S2 = Bretschneider(Hm0=7, Tp=11)
# JONSWAP with gamma=1 should be equal to Bretscneider:
S = Wallop(Hm0=6.5, Tp=10) self.assertListAlmostEqual(S(w), S2(w))
vals = S(range(4))
true_vals = np.array([0.00000000e+00, 9.36921871e-01, 2.76991078e-03, def test_tmaspec(self):
7.72996150e-05]) S = Tmaspec(Hm0=7, Tp=11, gamma=1, h=10)
assert((np.abs(vals - true_vals) < 1e-7).all()) vals = S((0, 1, 2, 3))
true_vals = np.array([0., 0.70106233, 0.05022433, 0.00669692])
self.assertListAlmostEqual(vals, true_vals)
def test_torsethaugen(self):
S = Torsethaugen(Hm0=7, Tp=11, gamma=1, h=10)
vals = S((0, 1, 2, 3))
true_vals = np.array([0., 1.19989709, 0.05819794, 0.0093541])
self.assertListAlmostEqual(vals, true_vals)
vals = S.wind(range(4))
true_vals = np.array([0., 1.13560528, 0.05529849, 0.00888989])
self.assertListAlmostEqual(vals, true_vals)
vals = S.swell(range(4))
true_vals = np.array([0., 0.0642918, 0.00289946, 0.00046421])
self.assertListAlmostEqual(vals, true_vals)
def test_ochihubble(self):
S = OchiHubble(par=2)
vals = S(range(4))
true_vals = np.array([0., 0.90155636, 0.04185445, 0.00583207])
self.assertListAlmostEqual(vals, true_vals)
def test_mccormick(self):
S = McCormick(Hm0=6.5, Tp=10)
vals = S(range(4))
true_vals = np.array([0., 1.87865908, 0.15050447, 0.02994663])
self.assertListAlmostEqual(vals, true_vals)
def test_wallop(self):
S = Wallop(Hm0=6.5, Tp=10)
vals = S(range(4))
true_vals = np.array([0.00000000e+00, 9.36921871e-01, 2.76991078e-03,
7.72996150e-05])
self.assertListAlmostEqual(vals, true_vals)
class TestSpreading(TestCase):
def test_cos2s(self):
theta = np.linspace(0, 2 * np.pi)
d = Spreading(type='cos2s')
dvals = [[1.10168934e+00],
[1.03576796e+00],
[8.60302298e-01],
[6.30309013e-01],
[4.06280137e-01],
[2.29514882e-01],
[1.13052757e-01],
[4.82339343e-02],
[1.76754409e-02],
[5.50490020e-03],
[1.43800617e-03],
[3.09907242e-04],
[5.39672445e-05],
[7.39553743e-06],
[7.70796579e-07],
[5.84247670e-08],
[3.03264905e-09],
[9.91950201e-11],
[1.81442131e-12],
[1.55028269e-14],
[4.63223469e-17],
[2.90526245e-20],
[1.35842977e-24],
[3.26077455e-31],
[1.65021852e-45],
[1.65021852e-45],
[3.26077455e-31],
[1.35842977e-24],
[2.90526245e-20],
[4.63223469e-17],
[1.55028269e-14],
[1.81442131e-12],
[9.91950201e-11],
[3.03264905e-09],
[5.84247670e-08],
[7.70796579e-07],
[7.39553743e-06],
[5.39672445e-05],
[3.09907242e-04],
[1.43800617e-03],
[5.50490020e-03],
[1.76754409e-02],
[4.82339343e-02],
[1.13052757e-01],
[2.29514882e-01],
[4.06280137e-01],
[6.30309013e-01],
[8.60302298e-01],
[1.03576796e+00],
[1.10168934e+00]]
self.assertListAlmostEqual(d(theta)[0], dvals)
if __name__ == '__main__': if __name__ == '__main__':
# main() unittest.main()
import nose
nose.run()
#test_tmaspec()

@ -1,7 +1,9 @@
import wafo.spectrum.models as sm import wafo.spectrum.models as sm
import wafo.transform.models as wtm
import wafo.objects as wo
from wafo.spectrum import SpecData1D from wafo.spectrum import SpecData1D
import numpy as np import numpy as np
import unittest import unittest
def slow(f): def slow(f):
@ -18,11 +20,11 @@ class TestSpectrum(unittest.TestCase):
acfmat = S.tocov_matrix(nr=3, nt=256, dt=0.1) acfmat = S.tocov_matrix(nr=3, nt=256, dt=0.1)
vals = acfmat[:2, :] vals = acfmat[:2, :]
true_vals = np.array([[3.06073383, 0.0000000, -1.67748256, 0.], true_vals = np.array([[3.06073383, 0.0000000, -1.67748256, 0.],
[3.05235423, -0.1674357, -1.66811444, 0.18693242]]) [3.05235423, -0.1674357, -1.66811444,
0.18693242]])
self.assertTrue((np.abs(vals - true_vals) < 1e-7).all()) self.assertTrue((np.abs(vals - true_vals) < 1e-7).all())
def test_tocovdata(): def test_tocovdata():
Sj = sm.Jonswap() Sj = sm.Jonswap()
S = Sj.tospecdata() S = Sj.tospecdata()
@ -41,22 +43,25 @@ def test_to_t_pdf():
f = S.to_t_pdf(pdef='Tc', paramt=(0, 10, 51), speed=7, seed=100) f = S.to_t_pdf(pdef='Tc', paramt=(0, 10, 51), speed=7, seed=100)
vals = ['%2.3f' % val for val in f.data[:10]] vals = ['%2.3f' % val for val in f.data[:10]]
truevals = ['0.000', '0.014', '0.027', '0.040', truevals = ['0.000', '0.014', '0.027', '0.040',
'0.050', '0.059', '0.067', '0.072', '0.077', '0.081'] '0.050', '0.059', '0.067', '0.073', '0.077', '0.082']
for t, v in zip(truevals, vals):
assert(t == v)
# estimated error bounds # estimated error bounds
vals = ['%2.4f' % val for val in f.err[:10]] vals = ['%2.4f' % val for val in f.err[:10]]
truevals = ['0.0000', '0.0003', '0.0003', '0.0004', truevals = ['0.0000', '0.0003', '0.0003', '0.0004',
'0.0006', '0.0009', '0.0016', '0.0019', '0.0020', '0.0021'] '0.0006', '0.0008', '0.0016', '0.0019', '0.0020', '0.0021']
for t, v in zip(truevals, vals):
assert(t == v)
@slow @slow
def test_sim(): def test_sim():
Sj = sm.Jonswap() Sj = sm.Jonswap()
S = Sj.tospecdata() S = Sj.tospecdata()
ns = 100 #ns = 100
dt = .2 #dt = .2
x1 = S.sim(ns, dt=dt) #x1 = S.sim(ns, dt=dt)
import scipy.stats as st import scipy.stats as st
x2 = S.sim(20000, 20) x2 = S.sim(20000, 20)
@ -75,13 +80,11 @@ def test_sim_nl():
Sj = sm.Jonswap() Sj = sm.Jonswap()
S = Sj.tospecdata() S = Sj.tospecdata()
ns = 100 # ns = 100
dt = .2 # dt = .2
x1 = S.sim_nl(ns, dt=dt) # x1 = S.sim_nl(ns, dt=dt)
import numpy as np
import scipy.stats as st import scipy.stats as st
x2, x1 = S.sim_nl(ns=20000, cases=40) x2, _x1 = S.sim_nl(ns=20000, cases=40)
truth1 = [0, np.sqrt(S.moment(1)[0][0])] + S.stats_nl(moments='sk') truth1 = [0, np.sqrt(S.moment(1)[0][0])] + S.stats_nl(moments='sk')
truth1[-1] = truth1[-1] - 3 truth1[-1] = truth1[-1] - 3
@ -110,26 +113,22 @@ def test_stats_nl():
def test_testgaussian(): def test_testgaussian():
'''
>>> import wafo.spectrum.models as sm Hs = 7
>>> import wafo.transform.models as wtm Sj = sm.Jonswap(Hm0=Hs)
>>> import wafo.objects as wo S0 = Sj.tospecdata()
>>> Hs = 7 #ns =100; dt = .2
>>> Sj = sm.Jonswap(Hm0=Hs) #x1 = S0.sim(ns, dt=dt)
>>> S0 = Sj.tospecdata()
>>> ns =100; dt = .2 S = S0.copy()
>>> x1 = S0.sim(ns, dt=dt) me, _va, sk, ku = S.stats_nl(moments='mvsk')
S.tr = wtm.TrHermite(
>>> S = S0.copy() mean=me, sigma=Hs / 4, skew=sk, kurt=ku, ysigma=Hs / 4)
>>> me, va, sk, ku = S.stats_nl(moments='mvsk') ys = wo.mat2timeseries(S.sim(ns=2 ** 13))
>>> S.tr = wtm.TrHermite(mean=me, sigma=Hs/4, skew=sk, kurt=ku, ysigma=Hs/4) g0, _gemp = ys.trdata()
>>> ys = wo.mat2timeseries(S.sim(ns=2**13)) t0 = g0.dist2gauss()
>>> g0, gemp = ys.trdata() t1 = S0.testgaussian(ns=2 ** 13, t0=t0, cases=50)
>>> t0 = g0.dist2gauss() assert(sum(t1 > t0) < 5)
>>> t1 = S0.testgaussian(ns=2**13, t0=t0, cases=50)
>>> sum(t1>t0)<5
True
'''
def test_moment(): def test_moment():
@ -140,29 +139,28 @@ def test_moment():
true_txt = ['m0', 'm0tt'] true_txt = ['m0', 'm0tt']
for tv, v in zip(true_vals, vals): for tv, v in zip(true_vals, vals):
assert(tv == v) assert(tv == v)
for tv, v in zip(true_txt, txt):
assert(tv == v)
def test_nyquist_freq(): def test_nyquist_freq():
Sj = sm.Jonswap(Hm0=5) Sj = sm.Jonswap(Hm0=5)
S = Sj.tospecdata() # Make spectrum ob S = Sj.tospecdata() # Make spectrum ob
assert(S.nyquist_freq() == 3.0) assert(S.nyquist_freq() == 3.0)
def test_sampling_period(): def test_sampling_period():
Sj = sm.Jonswap(Hm0=5) Sj = sm.Jonswap(Hm0=5)
S = Sj.tospecdata() # Make spectrum ob S = Sj.tospecdata() # Make spectrum ob
assert(S.sampling_period() == 1.0471975511965976) assert(S.sampling_period() == 1.0471975511965976)
def test_normalize(): def test_normalize():
Sj = sm.Jonswap(Hm0=5) Sj = sm.Jonswap(Hm0=5)
S = Sj.tospecdata() # Make spectrum ob S = Sj.tospecdata() # Make spectrum ob
S.moment(2) S.moment(2)
([1.5614600345079888, 0.95567089481941048], ['m0', 'm0tt']) ([1.5614600345079888, 0.95567089481941048], ['m0', 'm0tt'])
vals, txt = S.moment(2) vals, _txt = S.moment(2)
true_vals = [1.5614600345079888, 0.95567089481941048] true_vals = [1.5614600345079888, 0.95567089481941048]
for tv, v in zip(true_vals, vals): for tv, v in zip(true_vals, vals):
assert(tv == v) assert(tv == v)
@ -171,7 +169,7 @@ def test_normalize():
Sn.normalize() Sn.normalize()
# Now the moments should be one # Now the moments should be one
new_vals, txt = Sn.moment(2) new_vals, _txt = Sn.moment(2)
for v in new_vals: for v in new_vals:
assert(np.abs(v - 1.0) < 1e-7) assert(np.abs(v - 1.0) < 1e-7)
@ -191,7 +189,7 @@ def test_characteristic():
[ 0.02834263, 0.0274645 , nan], [ 0.02834263, 0.0274645 , nan],
[ nan, nan, 0.01500249]]) [ nan, nan, 0.01500249]])
['Tm01', 'Tm02', 'Tm24'] ['Tm01', 'Tm02', 'Tm24']
>>> S.characteristic('Ss') # fact a string >>> S.characteristic('Ss') # fact a string
(array([ 0.04963112]), array([[ 2.63624782e-06]]), ['Ss']) (array([ 0.04963112]), array([[ 2.63624782e-06]]), ['Ss'])

@ -8,7 +8,7 @@ Statistical functions (:mod:`scipy.stats`)
This module contains a large number of probability distributions as This module contains a large number of probability distributions as
well as a growing library of statistical functions. well as a growing library of statistical functions.
Each included distribution is an instance of the class rv_continous: Each included distribution is an instance of the class rv_continuous:
For each given name the following methods are available: For each given name the following methods are available:
.. autosummary:: .. autosummary::
@ -77,7 +77,7 @@ Continuous distributions
exponweib -- Exponentiated Weibull exponweib -- Exponentiated Weibull
exponpow -- Exponential Power exponpow -- Exponential Power
f -- F (Snecdor F) f -- F (Snecdor F)
fatiguelife -- Fatigue Life (Birnbaum-Sanders) fatiguelife -- Fatigue Life (Birnbaum-Saunders)
fisk -- Fisk fisk -- Fisk
foldcauchy -- Folded Cauchy foldcauchy -- Folded Cauchy
foldnorm -- Folded Normal foldnorm -- Folded Normal
@ -149,6 +149,7 @@ Multivariate distributions
:toctree: generated/ :toctree: generated/
multivariate_normal -- Multivariate normal distribution multivariate_normal -- Multivariate normal distribution
dirichlet -- Dirichlet
Discrete distributions Discrete distributions
====================== ======================
@ -231,6 +232,7 @@ which work for masked arrays.
.. autosummary:: .. autosummary::
:toctree: generated/ :toctree: generated/
sigmaclip
threshold threshold
trimboth trimboth
trim1 trim1
@ -244,6 +246,7 @@ which work for masked arrays.
pointbiserialr pointbiserialr
kendalltau kendalltau
linregress linregress
theilslopes
.. autosummary:: .. autosummary::
:toctree: generated/ :toctree: generated/
@ -271,8 +274,10 @@ which work for masked arrays.
levene levene
shapiro shapiro
anderson anderson
anderson_ksamp
binom_test binom_test
fligner fligner
median_test
mood mood
.. autosummary:: .. autosummary::
@ -282,6 +287,8 @@ which work for masked arrays.
boxcox_normmax boxcox_normmax
boxcox_llf boxcox_llf
entropy
Contingency table functions Contingency table functions
=========================== ===========================
@ -344,3 +351,5 @@ __all__ = [s for s in dir() if not (s.startswith('_') or s.endswith('cython'))]
#import distributions #@Reimport #import distributions #@Reimport
#from wafo.stats.distributions import * #from wafo.stats.distributions import *
from numpy.testing import Tester
test = Tester().test

@ -16,8 +16,6 @@ def binned_statistic(x, values, statistic='mean',
each bin. This function allows the computation of the sum, mean, median, each bin. This function allows the computation of the sum, mean, median,
or other statistic of the values within each bin. or other statistic of the values within each bin.
.. versionadded:: 0.11.0
Parameters Parameters
---------- ----------
x : array_like x : array_like
@ -78,6 +76,8 @@ def binned_statistic(x, values, statistic='mean',
second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which *includes* second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which *includes*
4. 4.
.. versionadded:: 0.11.0
Examples Examples
-------- --------
>>> stats.binned_statistic([1, 2, 1, 2, 4], np.arange(5), statistic='mean', >>> stats.binned_statistic([1, 2, 1, 2, 4], np.arange(5), statistic='mean',
@ -116,8 +116,6 @@ def binned_statistic_2d(x, y, values, statistic='mean',
each bin. This function allows the computation of the sum, mean, median, each bin. This function allows the computation of the sum, mean, median,
or other statistic of the values within each bin. or other statistic of the values within each bin.
.. versionadded:: 0.11.0
Parameters Parameters
---------- ----------
x : (N,) array_like x : (N,) array_like
@ -175,6 +173,11 @@ def binned_statistic_2d(x, y, values, statistic='mean',
-------- --------
numpy.histogram2d, binned_statistic, binned_statistic_dd numpy.histogram2d, binned_statistic, binned_statistic_dd
Notes
-----
.. versionadded:: 0.11.0
""" """
# This code is based on np.histogram2d # This code is based on np.histogram2d
@ -203,8 +206,6 @@ def binned_statistic_dd(sample, values, statistic='mean',
each bin. This function allows the computation of the sum, mean, median, each bin. This function allows the computation of the sum, mean, median,
or other statistic of the values within each bin. or other statistic of the values within each bin.
.. versionadded:: 0.11.0
Parameters Parameters
---------- ----------
sample : array_like sample : array_like
@ -258,6 +259,11 @@ def binned_statistic_dd(sample, values, statistic='mean',
-------- --------
np.histogramdd, binned_statistic, binned_statistic_2d np.histogramdd, binned_statistic, binned_statistic_2d
Notes
-----
.. versionadded:: 0.11.0
""" """
if type(statistic) == str: if type(statistic) == str:
if statistic not in ['mean', 'median', 'count', 'sum', 'std']: if statistic not in ['mean', 'median', 'count', 'sum', 'std']:

File diff suppressed because it is too large Load Diff

@ -13,17 +13,10 @@ import numpy as np
import numpy.random as mtrand import numpy.random as mtrand
from ._distn_infrastructure import ( from ._distn_infrastructure import (
rv_discrete, _lazywhere, _ncx2_pdf, _ncx2_cdf) rv_discrete, _lazywhere, _ncx2_pdf, _ncx2_cdf, get_distribution_names)
__all__ = [
'binom', 'bernoulli', 'nbinom', 'geom', 'hypergeom',
'logser', 'poisson', 'planck', 'boltzmann', 'randint',
'zipf', 'dlaplace', 'skellam'
]
class binom_gen(rv_discrete): class binom_gen(rv_discrete):
"""A binomial discrete random variable. """A binomial discrete random variable.
%(before_notes)s %(before_notes)s
@ -41,7 +34,6 @@ class binom_gen(rv_discrete):
%(example)s %(example)s
""" """
def _rvs(self, n, p): def _rvs(self, n, p):
return mtrand.binomial(n, p, self._size) return mtrand.binomial(n, p, self._size)
@ -51,8 +43,8 @@ class binom_gen(rv_discrete):
def _logpmf(self, x, n, p): def _logpmf(self, x, n, p):
k = floor(x) k = floor(x)
combiln = (gamln(n + 1) - (gamln(k + 1) + gamln(n - k + 1))) combiln = (gamln(n+1) - (gamln(k+1) + gamln(n-k+1)))
return combiln + special.xlogy(k, p) + special.xlog1py(n - k, -p) return combiln + special.xlogy(k, p) + special.xlog1py(n-k, -p)
def _pmf(self, x, n, p): def _pmf(self, x, n, p):
return exp(self._logpmf(x, n, p)) return exp(self._logpmf(x, n, p))
@ -68,16 +60,19 @@ class binom_gen(rv_discrete):
def _ppf(self, q, n, p): def _ppf(self, q, n, p):
vals = ceil(special.bdtrik(q, n, p)) vals = ceil(special.bdtrik(q, n, p))
vals1 = vals - 1 vals1 = np.maximum(vals - 1, 0)
temp = special.bdtr(vals1, n, p) temp = special.bdtr(vals1, n, p)
return np.where(temp >= q, vals1, vals) return np.where(temp >= q, vals1, vals)
def _stats(self, n, p): def _stats(self, n, p, moments='mv'):
q = 1.0 - p q = 1.0 - p
mu = n * p mu = n * p
var = n * p * q var = n * p * q
g1 = (q - p) / sqrt(n * p * q) g1, g2 = None, None
g2 = (1.0 - 6 * p * q) / (n * p * q) if 's' in moments:
g1 = (q - p) / sqrt(var)
if 'k' in moments:
g2 = (1.0 - 6*p*q) / var
return mu, var, g1, g2 return mu, var, g1, g2
def _entropy(self, n, p): def _entropy(self, n, p):
@ -89,7 +84,6 @@ binom = binom_gen(name='binom')
class bernoulli_gen(binom_gen): class bernoulli_gen(binom_gen):
"""A Bernoulli discrete random variable. """A Bernoulli discrete random variable.
%(before_notes)s %(before_notes)s
@ -108,7 +102,6 @@ class bernoulli_gen(binom_gen):
%(example)s %(example)s
""" """
def _rvs(self, p): def _rvs(self, p):
return binom_gen._rvs(self, 1, p) return binom_gen._rvs(self, 1, p)
@ -140,7 +133,6 @@ bernoulli = bernoulli_gen(b=1, name='bernoulli')
class nbinom_gen(rv_discrete): class nbinom_gen(rv_discrete):
"""A negative binomial discrete random variable. """A negative binomial discrete random variable.
%(before_notes)s %(before_notes)s
@ -158,7 +150,6 @@ class nbinom_gen(rv_discrete):
%(example)s %(example)s
""" """
def _rvs(self, n, p): def _rvs(self, n, p):
return mtrand.negative_binomial(n, p, self._size) return mtrand.negative_binomial(n, p, self._size)
@ -174,7 +165,7 @@ class nbinom_gen(rv_discrete):
def _cdf(self, x, n, p): def _cdf(self, x, n, p):
k = floor(x) k = floor(x)
return special.betainc(n, k + 1, p) return special.betainc(n, k+1, p)
def _sf_skip(self, x, n, p): def _sf_skip(self, x, n, p):
# skip because special.nbdtrc doesn't work for 0<n<1 # skip because special.nbdtrc doesn't work for 0<n<1
@ -183,23 +174,22 @@ class nbinom_gen(rv_discrete):
def _ppf(self, q, n, p): def _ppf(self, q, n, p):
vals = ceil(special.nbdtrik(q, n, p)) vals = ceil(special.nbdtrik(q, n, p))
vals1 = (vals - 1).clip(0.0, np.inf) vals1 = (vals-1).clip(0.0, np.inf)
temp = self._cdf(vals1, n, p) temp = self._cdf(vals1, n, p)
return np.where(temp >= q, vals1, vals) return np.where(temp >= q, vals1, vals)
def _stats(self, n, p): def _stats(self, n, p):
Q = 1.0 / p Q = 1.0 / p
P = Q - 1.0 P = Q - 1.0
mu = n * P mu = n*P
var = n * P * Q var = n*P*Q
g1 = (Q + P) / sqrt(n * P * Q) g1 = (Q+P)/sqrt(n*P*Q)
g2 = (1.0 + 6 * P * Q) / (n * P * Q) g2 = (1.0 + 6*P*Q) / (n*P*Q)
return mu, var, g1, g2 return mu, var, g1, g2
nbinom = nbinom_gen(name='nbinom') nbinom = nbinom_gen(name='nbinom')
class geom_gen(rv_discrete): class geom_gen(rv_discrete):
"""A geometric discrete random variable. """A geometric discrete random variable.
%(before_notes)s %(before_notes)s
@ -217,7 +207,6 @@ class geom_gen(rv_discrete):
%(example)s %(example)s
""" """
def _rvs(self, p): def _rvs(self, p):
return mtrand.geometric(p, size=self._size) return mtrand.geometric(p, size=self._size)
@ -225,7 +214,7 @@ class geom_gen(rv_discrete):
return (p <= 1) & (p >= 0) return (p <= 1) & (p >= 0)
def _pmf(self, k, p): def _pmf(self, k, p):
return np.power(1 - p, k - 1) * p return np.power(1-p, k-1) * p
def _logpmf(self, k, p): def _logpmf(self, k, p):
return (k - 1) * log1p(-p) + log(p) return (k - 1) * log1p(-p) + log(p)
@ -247,17 +236,16 @@ class geom_gen(rv_discrete):
return np.where((temp >= q) & (vals > 0), vals - 1, vals) return np.where((temp >= q) & (vals > 0), vals - 1, vals)
def _stats(self, p): def _stats(self, p):
mu = 1.0 / p mu = 1.0/p
qr = 1.0 - p qr = 1.0-p
var = qr / p / p var = qr / p / p
g1 = (2.0 - p) / sqrt(qr) g1 = (2.0-p) / sqrt(qr)
g2 = np.polyval([1, -6, 6], p) / (1.0 - p) g2 = np.polyval([1, -6, 6], p)/(1.0-p)
return mu, var, g1, g2 return mu, var, g1, g2
geom = geom_gen(a=1, name='geom', longname="A geometric") geom = geom_gen(a=1, name='geom', longname="A geometric")
class hypergeom_gen(rv_discrete): class hypergeom_gen(rv_discrete):
"""A hypergeometric discrete random variable. """A hypergeometric discrete random variable.
The hypergeometric distribution models drawing objects from a bin. The hypergeometric distribution models drawing objects from a bin.
@ -277,6 +265,7 @@ class hypergeom_gen(rv_discrete):
Examples Examples
-------- --------
>>> from scipy.stats import hypergeom >>> from scipy.stats import hypergeom
>>> import matplotlib.pyplot as plt
Suppose we have a collection of 20 animals, of which 7 are dogs. Then if Suppose we have a collection of 20 animals, of which 7 are dogs. Then if
we want to know the probability of finding a given number of dogs if we we want to know the probability of finding a given number of dogs if we
@ -307,23 +296,22 @@ class hypergeom_gen(rv_discrete):
>>> R = hypergeom.rvs(M, n, N, size=10) >>> R = hypergeom.rvs(M, n, N, size=10)
""" """
def _rvs(self, M, n, N): def _rvs(self, M, n, N):
return mtrand.hypergeometric(n, M - n, N, size=self._size) return mtrand.hypergeometric(n, M-n, N, size=self._size)
def _argcheck(self, M, n, N): def _argcheck(self, M, n, N):
cond = rv_discrete._argcheck(self, M, n, N) cond = rv_discrete._argcheck(self, M, n, N)
cond &= (n <= M) & (N <= M) cond &= (n <= M) & (N <= M)
self.a = max(N - (M - n), 0) self.a = max(N-(M-n), 0)
self.b = min(n, N) self.b = min(n, N)
return cond return cond
def _logpmf(self, k, M, n, N): def _logpmf(self, k, M, n, N):
tot, good = M, n tot, good = M, n
bad = tot - good bad = tot - good
return gamln(good + 1) - gamln(good - k + 1) - gamln(k + 1) + \ return gamln(good+1) - gamln(good-k+1) - gamln(k+1) + gamln(bad+1) \
gamln(bad + 1) - gamln(bad - N + k + 1) - gamln(N - k + 1) - \ - gamln(bad-N+k+1) - gamln(N-k+1) - gamln(tot+1) + gamln(tot-N+1) \
gamln(tot + 1) + gamln(tot - N + 1) + gamln(N + 1) + gamln(N+1)
def _pmf(self, k, M, n, N): def _pmf(self, k, M, n, N):
# same as the following but numerically more precise # same as the following but numerically more precise
@ -333,19 +321,18 @@ class hypergeom_gen(rv_discrete):
def _stats(self, M, n, N): def _stats(self, M, n, N):
# tot, good, sample_size = M, n, N # tot, good, sample_size = M, n, N
# "wikipedia".replace('N', 'M').replace('n', 'N').replace('K', 'n') # "wikipedia".replace('N', 'M').replace('n', 'N').replace('K', 'n')
M, n, N = 1. * M, 1. * n, 1. * N M, n, N = 1.*M, 1.*n, 1.*N
m = M - n m = M - n
p = n / M p = n/M
mu = N * p mu = N*p
var = m * n * N * (M - N) * 1.0 / (M * M * (M - 1)) var = m*n*N*(M - N)*1.0/(M*M*(M-1))
g1 = (m - n) * (M - 2 * N) / (M - 2.0) * \ g1 = (m - n)*(M-2*N) / (M-2.0) * sqrt((M-1.0) / (m*n*N*(M-N)))
sqrt((M - 1.0) / (m * n * N * (M - N)))
g2 = M * (M + 1) - 6. * N * (M - N) - 6. * n * m g2 = M*(M+1) - 6.*N*(M-N) - 6.*n*m
g2 *= (M - 1) * M * M g2 *= (M-1)*M*M
g2 += 6. * n * N * (M - N) * m * (5. * M - 6) g2 += 6.*n*N*(M-N)*m*(5.*M-6)
g2 /= n * N * (M - N) * m * (M - 2.) * (M - 3.) g2 /= n * N * (M-N) * m * (M-2.) * (M-3.)
return mu, var, g1, g2 return mu, var, g1, g2
def _entropy(self, M, n, N): def _entropy(self, M, n, N):
@ -372,7 +359,6 @@ hypergeom = hypergeom_gen(name='hypergeom')
# FIXME: Fails _cdfvec # FIXME: Fails _cdfvec
class logser_gen(rv_discrete): class logser_gen(rv_discrete):
"""A Logarithmic (Log-Series, Series) discrete random variable. """A Logarithmic (Log-Series, Series) discrete random variable.
%(before_notes)s %(before_notes)s
@ -390,7 +376,6 @@ class logser_gen(rv_discrete):
%(example)s %(example)s
""" """
def _rvs(self, p): def _rvs(self, p):
# looks wrong for p>0.5, too few k=1 # looks wrong for p>0.5, too few k=1
# trying to use generic is worse, no k=1 at all # trying to use generic is worse, no k=1 at all
@ -405,22 +390,21 @@ class logser_gen(rv_discrete):
def _stats(self, p): def _stats(self, p):
r = log1p(-p) r = log1p(-p)
mu = p / (p - 1.0) / r mu = p / (p - 1.0) / r
mu2p = -p / r / (p - 1.0) ** 2 mu2p = -p / r / (p - 1.0)**2
var = mu2p - mu * mu var = mu2p - mu*mu
mu3p = -p / r * (1.0 + p) / (1.0 - p) ** 3 mu3p = -p / r * (1.0+p) / (1.0 - p)**3
mu3 = mu3p - 3 * mu * mu2p + 2 * mu ** 3 mu3 = mu3p - 3*mu*mu2p + 2*mu**3
g1 = mu3 / np.power(var, 1.5) g1 = mu3 / np.power(var, 1.5)
mu4p = -p / r * ( mu4p = -p / r * (
1.0 / (p - 1) ** 2 - 6 * p / (p - 1) ** 3 + 6 * p * p / (p - 1) ** 4) 1.0 / (p-1)**2 - 6*p / (p - 1)**3 + 6*p*p / (p-1)**4)
mu4 = mu4p - 4 * mu3p * mu + 6 * mu2p * mu * mu - 3 * mu ** 4 mu4 = mu4p - 4*mu3p*mu + 6*mu2p*mu*mu - 3*mu**4
g2 = mu4 / var ** 2 - 3.0 g2 = mu4 / var**2 - 3.0
return mu, var, g1, g2 return mu, var, g1, g2
logser = logser_gen(a=1, name='logser', longname='A logarithmic') logser = logser_gen(a=1, name='logser', longname='A logarithmic')
class poisson_gen(rv_discrete): class poisson_gen(rv_discrete):
"""A Poisson discrete random variable. """A Poisson discrete random variable.
%(before_notes)s %(before_notes)s
@ -438,12 +422,11 @@ class poisson_gen(rv_discrete):
%(example)s %(example)s
""" """
def _rvs(self, mu): def _rvs(self, mu):
return mtrand.poisson(mu, self._size) return mtrand.poisson(mu, self._size)
def _logpmf(self, k, mu): def _logpmf(self, k, mu):
Pk = k * log(mu) - gamln(k + 1) - mu Pk = k*log(mu)-gamln(k+1) - mu
return Pk return Pk
def _pmf(self, k, mu): def _pmf(self, k, mu):
@ -459,9 +442,9 @@ class poisson_gen(rv_discrete):
def _ppf(self, q, mu): def _ppf(self, q, mu):
vals = ceil(special.pdtrik(q, mu)) vals = ceil(special.pdtrik(q, mu))
vals1 = vals - 1 vals1 = np.maximum(vals - 1, 0)
temp = special.pdtr(vals1, mu) temp = special.pdtr(vals1, mu)
return np.where((temp >= q), vals1, vals) return np.where(temp >= q, vals1, vals)
def _stats(self, mu): def _stats(self, mu):
var = mu var = mu
@ -473,7 +456,6 @@ poisson = poisson_gen(name="poisson", longname='A Poisson')
class planck_gen(rv_discrete): class planck_gen(rv_discrete):
"""A Planck discrete exponential random variable. """A Planck discrete exponential random variable.
%(before_notes)s %(before_notes)s
@ -491,7 +473,6 @@ class planck_gen(rv_discrete):
%(example)s %(example)s
""" """
def _argcheck(self, lambda_): def _argcheck(self, lambda_):
if (lambda_ > 0): if (lambda_ > 0):
self.a = 0 self.a = 0
@ -513,27 +494,26 @@ class planck_gen(rv_discrete):
return - expm1(-lambda_ * (k + 1)) return - expm1(-lambda_ * (k + 1))
def _ppf(self, q, lambda_): def _ppf(self, q, lambda_):
vals = ceil(-1.0 / lambda_ * log1p(-q) - 1) vals = ceil(-1.0/lambda_ * log1p(-q)-1)
vals1 = (vals - 1).clip(self.a, np.inf) vals1 = (vals-1).clip(self.a, np.inf)
temp = self._cdf(vals1, lambda_) temp = self._cdf(vals1, lambda_)
return np.where(temp >= q, vals1, vals) return np.where(temp >= q, vals1, vals)
def _stats(self, lambda_): def _stats(self, lambda_):
mu = 1 / (exp(lambda_) - 1) mu = 1/(exp(lambda_)-1)
var = exp(-lambda_) / (expm1(-lambda_)) ** 2 var = exp(-lambda_)/(expm1(-lambda_))**2
g1 = 2 * cosh(lambda_ / 2.0) g1 = 2*cosh(lambda_/2.0)
g2 = 4 + 2 * cosh(lambda_) g2 = 4+2*cosh(lambda_)
return mu, var, g1, g2 return mu, var, g1, g2
def _entropy(self, lambda_): def _entropy(self, lambda_):
l = lambda_ l = lambda_
C = -expm1(-l) C = -expm1(-l)
return l * exp(-l) / C - log(C) return l*exp(-l)/C - log(C)
planck = planck_gen(name='planck', longname='A discrete exponential ') planck = planck_gen(name='planck', longname='A discrete exponential ')
class boltzmann_gen(rv_discrete): class boltzmann_gen(rv_discrete):
"""A Boltzmann (Truncated Discrete Exponential) random variable. """A Boltzmann (Truncated Discrete Exponential) random variable.
%(before_notes)s %(before_notes)s
@ -551,7 +531,6 @@ class boltzmann_gen(rv_discrete):
%(example)s %(example)s
""" """
def _pmf(self, k, lambda_, N): def _pmf(self, k, lambda_, N):
fact = (expm1(-lambda_)) / (expm1(-lambda_ * N)) fact = (expm1(-lambda_)) / (expm1(-lambda_ * N))
return fact * exp(-lambda_ * k) return fact * exp(-lambda_ * k)
@ -569,23 +548,21 @@ class boltzmann_gen(rv_discrete):
def _stats(self, lambda_, N): def _stats(self, lambda_, N):
z = exp(-lambda_) z = exp(-lambda_)
zN = exp(-lambda_ * N) zN = exp(-lambda_*N)
mu = z / (1.0 - z) - N * zN / (1 - zN) mu = z/(1.0-z)-N*zN/(1-zN)
var = z / (1.0 - z) ** 2 - N * N * zN / (1 - zN) ** 2 var = z/(1.0-z)**2 - N*N*zN/(1-zN)**2
trm = (1 - zN) / (1 - z) trm = (1-zN)/(1-z)
trm2 = (z * trm ** 2 - N * N * zN) trm2 = (z*trm**2 - N*N*zN)
g1 = z * (1 + z) * trm ** 3 - N ** 3 * zN * (1 + zN) g1 = z*(1+z)*trm**3 - N**3*zN*(1+zN)
g1 = g1 / trm2 ** (1.5) g1 = g1 / trm2**(1.5)
g2 = z * (1 + 4 * z + z * z) * \ g2 = z*(1+4*z+z*z)*trm**4 - N**4 * zN*(1+4*zN+zN*zN)
trm ** 4 - N ** 4 * zN * (1 + 4 * zN + zN * zN)
g2 = g2 / trm2 / trm2 g2 = g2 / trm2 / trm2
return mu, var, g1, g2 return mu, var, g1, g2
boltzmann = boltzmann_gen(name='boltzmann', boltzmann = boltzmann_gen(name='boltzmann',
longname='A truncated discrete exponential ') longname='A truncated discrete exponential ')
class randint_gen(rv_discrete): class randint_gen(rv_discrete):
"""A uniform discrete random variable. """A uniform discrete random variable.
%(before_notes)s %(before_notes)s
@ -606,7 +583,6 @@ class randint_gen(rv_discrete):
%(example)s %(example)s
""" """
def _argcheck(self, low, high): def _argcheck(self, low, high):
self.a = low self.a = low
self.b = high - 1 self.b = high - 1
@ -630,9 +606,9 @@ class randint_gen(rv_discrete):
m2, m1 = np.asarray(high), np.asarray(low) m2, m1 = np.asarray(high), np.asarray(low)
mu = (m2 + m1 - 1.0) / 2 mu = (m2 + m1 - 1.0) / 2
d = m2 - m1 d = m2 - m1
var = (d * d - 1) / 12.0 var = (d*d - 1) / 12.0
g1 = 0.0 g1 = 0.0
g2 = -6.0 / 5.0 * (d * d + 1.0) / (d * d - 1.0) g2 = -6.0/5.0 * (d*d + 1.0) / (d*d - 1.0)
return mu, var, g1, g2 return mu, var, g1, g2
def _rvs(self, low, high=None): def _rvs(self, low, high=None):
@ -648,9 +624,22 @@ randint = randint_gen(name='randint', longname='A discrete uniform '
'(random integer)') '(random integer)')
def harmonic(n,r):
return 1./n + special.polygamma(r-1, n)/special.gamma(r) + special.zeta(r, 1)
def H(n):
"""Returns the n-th harmonic number.
http://en.wikipedia.org/wiki/Harmonic_number
"""
# Euler-Mascheroni constant
gamma = 0.57721566490153286060651209008240243104215933593992
return gamma + special.digamma(n+1)
# FIXME: problems sampling. # FIXME: problems sampling.
class zipf_gen(rv_discrete): class zipf_gen(rv_discrete):
"""A Zipf discrete random variable. """A Zipf discrete random variable.
%(before_notes)s %(before_notes)s
@ -668,7 +657,6 @@ class zipf_gen(rv_discrete):
%(example)s %(example)s
""" """
def _rvs(self, a): def _rvs(self, a):
return mtrand.zipf(a, size=self._size) return mtrand.zipf(a, size=self._size)
@ -676,7 +664,7 @@ class zipf_gen(rv_discrete):
return a > 1 return a > 1
def _pmf(self, k, a): def _pmf(self, k, a):
Pk = 1.0 / special.zeta(a, 1) / k ** a Pk = 1.0 / special.zeta(a, 1) / k**a
return Pk return Pk
def _munp(self, n, a): def _munp(self, n, a):
@ -688,7 +676,6 @@ zipf = zipf_gen(a=1, name='zipf', longname='A Zipf')
class dlaplace_gen(rv_discrete): class dlaplace_gen(rv_discrete):
"""A Laplacian discrete random variable. """A Laplacian discrete random variable.
%(before_notes)s %(before_notes)s
@ -706,37 +693,35 @@ class dlaplace_gen(rv_discrete):
%(example)s %(example)s
""" """
def _pmf(self, k, a): def _pmf(self, k, a):
return tanh(a / 2.0) * exp(-a * abs(k)) return tanh(a/2.0) * exp(-a * abs(k))
def _cdf(self, x, a): def _cdf(self, x, a):
k = floor(x) k = floor(x)
f = lambda k, a: 1.0 - exp(-a * k) / (exp(a) + 1) f = lambda k, a: 1.0 - exp(-a * k) / (exp(a) + 1)
f2 = lambda k, a: exp(a * (k + 1)) / (exp(a) + 1) f2 = lambda k, a: exp(a * (k+1)) / (exp(a) + 1)
return _lazywhere(k >= 0, (k, a), f=f, f2=f2) return _lazywhere(k >= 0, (k, a), f=f, f2=f2)
def _ppf(self, q, a): def _ppf(self, q, a):
const = 1 + exp(a) const = 1 + exp(a)
vals = ceil(np.where(q < 1.0 / (1 + exp(-a)), log(q * const) / a - 1, vals = ceil(np.where(q < 1.0 / (1 + exp(-a)), log(q*const) / a - 1,
-log((1 - q) * const) / a)) -log((1-q) * const) / a))
vals1 = vals - 1 vals1 = vals - 1
return np.where(self._cdf(vals1, a) >= q, vals1, vals) return np.where(self._cdf(vals1, a) >= q, vals1, vals)
def _stats(self, a): def _stats(self, a):
ea = exp(a) ea = exp(a)
mu2 = 2. * ea / (ea - 1.) ** 2 mu2 = 2.*ea/(ea-1.)**2
mu4 = 2. * ea * (ea ** 2 + 10. * ea + 1.) / (ea - 1.) ** 4 mu4 = 2.*ea*(ea**2+10.*ea+1.) / (ea-1.)**4
return 0., mu2, 0., mu4 / mu2 ** 2 - 3. return 0., mu2, 0., mu4/mu2**2 - 3.
def _entropy(self, a): def _entropy(self, a):
return a / sinh(a) - log(tanh(a / 2.0)) return a / sinh(a) - log(tanh(a/2.0))
dlaplace = dlaplace_gen(a=-np.inf, dlaplace = dlaplace_gen(a=-np.inf,
name='dlaplace', longname='A discrete Laplacian') name='dlaplace', longname='A discrete Laplacian')
class skellam_gen(rv_discrete): class skellam_gen(rv_discrete):
"""A Skellam discrete random variable. """A Skellam discrete random variable.
%(before_notes)s %(before_notes)s
@ -762,29 +747,35 @@ class skellam_gen(rv_discrete):
%(example)s %(example)s
""" """
def _rvs(self, mu1, mu2): def _rvs(self, mu1, mu2):
n = self._size n = self._size
return mtrand.poisson(mu1, n) - mtrand.poisson(mu2, n) return mtrand.poisson(mu1, n) - mtrand.poisson(mu2, n)
def _pmf(self, x, mu1, mu2): def _pmf(self, x, mu1, mu2):
px = np.where(x < 0, px = np.where(x < 0,
_ncx2_pdf(2 * mu2, 2 * (1 - x), 2 * mu1) * 2, _ncx2_pdf(2*mu2, 2*(1-x), 2*mu1)*2,
_ncx2_pdf(2 * mu1, 2 * (1 + x), 2 * mu2) * 2) _ncx2_pdf(2*mu1, 2*(1+x), 2*mu2)*2)
# ncx2.pdf() returns nan's for extremely low probabilities # ncx2.pdf() returns nan's for extremely low probabilities
return px return px
def _cdf(self, x, mu1, mu2): def _cdf(self, x, mu1, mu2):
x = floor(x) x = floor(x)
px = np.where(x < 0, px = np.where(x < 0,
_ncx2_cdf(2 * mu2, -2 * x, 2 * mu1), _ncx2_cdf(2*mu2, -2*x, 2*mu1),
1 - _ncx2_cdf(2 * mu1, 2 * (x + 1), 2 * mu2)) 1-_ncx2_cdf(2*mu1, 2*(x+1), 2*mu2))
return px return px
def _stats(self, mu1, mu2): def _stats(self, mu1, mu2):
mean = mu1 - mu2 mean = mu1 - mu2
var = mu1 + mu2 var = mu1 + mu2
g1 = mean / sqrt((var) ** 3) g1 = mean / sqrt((var)**3)
g2 = 1 / var g2 = 1 / var
return mean, var, g1, g2 return mean, var, g1, g2
skellam = skellam_gen(a=-np.inf, name="skellam", longname='A Skellam') skellam = skellam_gen(a=-np.inf, name="skellam", longname='A Skellam')
# Collect names of classes and objects in this module.
pairs = list(globals().items())
_distn_names, _distn_gen_names = get_distribution_names(pairs, rv_discrete)
__all__ = _distn_names + _distn_gen_names

File diff suppressed because it is too large Load Diff

@ -0,0 +1,116 @@
"""
Sane parameters for stats.distributions.
"""
distcont = [
['alpha', (3.5704770516650459,)],
['anglit', ()],
['arcsine', ()],
['beta', (2.3098496451481823, 0.62687954300963677)],
['betaprime', (5, 6)],
['bradford', (0.29891359763170633,)],
['burr', (10.5, 4.3)],
['cauchy', ()],
['chi', (78,)],
['chi2', (55,)],
['cosine', ()],
['dgamma', (1.1023326088288166,)],
['dweibull', (2.0685080649914673,)],
['erlang', (10,)],
['expon', ()],
['exponpow', (2.697119160358469,)],
['exponweib', (2.8923945291034436, 1.9505288745913174)],
['f', (29, 18)],
['fatiguelife', (29,)], # correction numargs = 1
['fisk', (3.0857548622253179,)],
['foldcauchy', (4.7164673455831894,)],
['foldnorm', (1.9521253373555869,)],
['frechet_l', (3.6279911255583239,)],
['frechet_r', (1.8928171603534227,)],
['gamma', (1.9932305483800778,)],
['gausshyper', (13.763771604130699, 3.1189636648681431,
2.5145980350183019, 5.1811649903971615)], # veryslow
['genexpon', (9.1325976465418908, 16.231956600590632, 3.2819552690843983)],
['genextreme', (-0.1,)],
['gengamma', (4.4162385429431925, 3.1193091679242761)],
['genhalflogistic', (0.77274727809929322,)],
['genlogistic', (0.41192440799679475,)],
['genpareto', (0.1,)], # use case with finite moments
['gilbrat', ()],
['gompertz', (0.94743713075105251,)],
['gumbel_l', ()],
['gumbel_r', ()],
['halfcauchy', ()],
['halflogistic', ()],
['halfnorm', ()],
['hypsecant', ()],
['invgamma', (4.0668996136993067,)],
['invgauss', (0.14546264555347513,)],
['invweibull', (10.58,)],
['johnsonsb', (4.3172675099141058, 3.1837781130785063)],
['johnsonsu', (2.554395574161155, 2.2482281679651965)],
['ksone', (1000,)], # replace 22 by 100 to avoid failing range, ticket 956
['kstwobign', ()],
['laplace', ()],
['levy', ()],
['levy_l', ()],
['levy_stable', (0.35667405469844993,
-0.67450531578494011)], # NotImplementedError
# rvs not tested
['loggamma', (0.41411931826052117,)],
['logistic', ()],
['loglaplace', (3.2505926592051435,)],
['lognorm', (0.95368226960575331,)],
['lomax', (1.8771398388773268,)],
['maxwell', ()],
['mielke', (10.4, 3.6)],
['nakagami', (4.9673794866666237,)],
['ncf', (27, 27, 0.41578441799226107)],
['nct', (14, 0.24045031331198066)],
['ncx2', (21, 1.0560465975116415)],
['norm', ()],
['pareto', (2.621716532144454,)],
['pearson3', (0.1,)],
['powerlaw', (1.6591133289905851,)],
['powerlognorm', (2.1413923530064087, 0.44639540782048337)],
['powernorm', (4.4453652254590779,)],
['rayleigh', ()],
['rdist', (0.9,)], # feels also slow
['recipinvgauss', (0.63004267809369119,)],
['reciprocal', (0.0062309367010521255, 1.0062309367010522)],
['rice', (0.7749725210111873,)],
['semicircular', ()],
['t', (2.7433514990818093,)],
['triang', (0.15785029824528218,)],
['truncexpon', (4.6907725456810478,)],
['truncnorm', (-1.0978730080013919, 2.7306754109031979)],
['truncnorm', (0.1, 2.)],
['tukeylambda', (3.1321477856738267,)],
['uniform', ()],
['vonmises', (3.9939042581071398,)],
['vonmises_line', (3.9939042581071398,)],
['wald', ()],
['weibull_max', (2.8687961709100187,)],
['weibull_min', (1.7866166930421596,)],
['wrapcauchy', (0.031071279018614728,)]]
distdiscrete = [
['bernoulli',(0.3,)],
['binom', (5, 0.4)],
['boltzmann',(1.4, 19)],
['dlaplace', (0.8,)], # 0.5
['geom', (0.5,)],
['hypergeom',(30, 12, 6)],
['hypergeom',(21,3,12)], # numpy.random (3,18,12) numpy ticket:921
['hypergeom',(21,18,11)], # numpy.random (18,3,11) numpy ticket:921
['logser', (0.6,)], # reenabled, numpy ticket:921
['nbinom', (5, 0.5)],
['nbinom', (0.4, 0.4)], # from tickets: 583
['planck', (0.51,)], # 4.1
['poisson', (0.6,)],
['randint', (7, 31)],
['skellam', (15, 8)],
['zipf', (6.5,)]
]

@ -3,13 +3,13 @@
# #
from __future__ import division, print_function, absolute_import from __future__ import division, print_function, absolute_import
from scipy.misc import doccer
from functools import wraps
import numpy as np import numpy as np
import scipy.linalg import scipy.linalg
from scipy.misc import doccer
from scipy.special import gammaln
__all__ = ['multivariate_normal']
__all__ = ['multivariate_normal', 'dirichlet']
_LOG_2PI = np.log(2 * np.pi) _LOG_2PI = np.log(2 * np.pi)
@ -53,15 +53,24 @@ def _process_parameters(dim, mean, cov):
cov.shape = (1, 1) cov.shape = (1, 1)
if mean.ndim != 1 or mean.shape[0] != dim: if mean.ndim != 1 or mean.shape[0] != dim:
raise ValueError("Array 'mean' must be vector of length %d." % dim) raise ValueError("Array 'mean' must be a vector of length %d." % dim)
if cov.ndim == 0: if cov.ndim == 0:
cov = cov * np.eye(dim) cov = cov * np.eye(dim)
elif cov.ndim == 1: elif cov.ndim == 1:
cov = np.diag(cov) cov = np.diag(cov)
else: elif cov.ndim == 2 and cov.shape != (dim, dim):
if cov.shape != (dim, dim): rows, cols = cov.shape
raise ValueError("Array 'cov' must be at most two-dimensional," if rows != cols:
" but cov.ndim = %d" % cov.ndim) msg = ("Array 'cov' must be square if it is two dimensional,"
" but cov.shape = %s." % str(cov.shape))
else:
msg = ("Dimension mismatch: array 'cov' is of shape %s,"
" but 'mean' is a vector of length %d.")
msg = msg % (str(cov.shape), len(mean))
raise ValueError(msg)
elif cov.ndim > 2:
raise ValueError("Array 'cov' must be at most two-dimensional,"
" but cov.ndim = %d" % cov.ndim)
return dim, mean, cov return dim, mean, cov
@ -97,6 +106,41 @@ def _squeeze_output(out):
return out return out
def _eigvalsh_to_eps(spectrum, cond=None, rcond=None):
"""
Determine which eigenvalues are "small" given the spectrum.
This is for compatibility across various linear algebra functions
that should agree about whether or not a Hermitian matrix is numerically
singular and what is its numerical matrix rank.
This is designed to be compatible with scipy.linalg.pinvh.
Parameters
----------
spectrum : 1d ndarray
Array of eigenvalues of a Hermitian matrix.
cond, rcond : float, optional
Cutoff for small eigenvalues.
Singular values smaller than rcond * largest_eigenvalue are
considered zero.
If None or -1, suitable machine precision is used.
Returns
-------
eps : float
Magnitude cutoff for numerical negligibility.
"""
if rcond is not None:
cond = rcond
if cond in [None, -1]:
t = spectrum.dtype.char.lower()
factor = {'f': 1E3, 'd': 1E6}
cond = factor[t] * np.finfo(t).eps
eps = cond * np.max(abs(spectrum))
return eps
def _pinv_1d(v, eps=1e-5): def _pinv_1d(v, eps=1e-5):
""" """
A helper function for computing the pseudoinverse. A helper function for computing the pseudoinverse.
@ -106,7 +150,7 @@ def _pinv_1d(v, eps=1e-5):
v : iterable of numbers v : iterable of numbers
This may be thought of as a vector of eigenvalues or singular values. This may be thought of as a vector of eigenvalues or singular values.
eps : float eps : float
Elements of v smaller than eps are considered negligible. Values with magnitude no greater than eps are considered negligible.
Returns Returns
------- -------
@ -114,97 +158,101 @@ def _pinv_1d(v, eps=1e-5):
A vector of pseudo-inverted numbers. A vector of pseudo-inverted numbers.
""" """
return np.array([0 if abs(x) < eps else 1/x for x in v], dtype=float) return np.array([0 if abs(x) <= eps else 1/x for x in v], dtype=float)
def _psd_pinv_decomposed_log_pdet(mat, cond=None, rcond=None, class _PSD(object):
lower=True, check_finite=True):
""" """
Compute a decomposition of the pseudo-inverse and the logarithm of Compute coordinated functions of a symmetric positive semidefinite matrix.
the pseudo-determinant of a symmetric positive semi-definite
matrix. This class addresses two issues. Firstly it allows the pseudoinverse,
the logarithm of the pseudo-determinant, and the rank of the matrix
The pseudo-determinant of a matrix is defined as the product of to be computed using one call to eigh instead of three.
the non-zero eigenvalues, and coincides with the usual determinant Secondly it allows these functions to be computed in a way
for a full matrix. that gives mutually compatible results.
All of the functions are computed with a common understanding as to
which of the eigenvalues are to be considered negligibly small.
The functions are designed to coordinate with scipy.linalg.pinvh()
but not necessarily with np.linalg.det() or with np.linalg.matrix_rank().
Parameters Parameters
---------- ----------
mat : array_like M : 2d array-like
Input array of shape (`m`, `n`) Symmetric positive semidefinite matrix.
cond, rcond : float or None cond, rcond : float, optional
Cutoff for 'small' singular values. Cutoff for small eigenvalues.
Eigenvalues smaller than ``rcond*largest_eigenvalue`` Singular values smaller than rcond * largest_eigenvalue are
are considered zero. considered zero.
If None or -1, suitable machine precision is used. If None or -1, suitable machine precision is used.
lower : bool, optional lower : bool, optional
Whether the pertinent array data is taken from the lower or upper Whether the pertinent array data is taken from the lower
triangle of `mat`. (Default: lower) or upper triangle of M. (Default: lower)
check_finite : boolean, optional check_finite : bool, optional
Whether to check that the input matrix contains only finite numbers. Whether to check that the input matrices contain only finite
Disabling may give a performance gain, but may result in problems numbers. Disabling may give a performance gain, but may result
(crashes, non-termination) if the inputs do contain infinities or NaNs. in problems (crashes, non-termination) if the inputs do contain
infinities or NaNs.
allow_singular : bool, optional
Whether to allow a singular matrix. (Default: True)
Returns Notes
------- -----
M : array_like The arguments are similar to those of scipy.linalg.pinvh().
The pseudo-inverse of the input matrix is np.dot(M, M.T).
log_pdet : float
Logarithm of the pseudo-determinant of the matrix.
""" """
# Compute the symmetric eigendecomposition.
# The input covariance matrix is required to be real symmetric
# and positive semidefinite which implies that its eigenvalues
# are all real and non-negative,
# but clip them anyway to avoid numerical issues.
# TODO: the code to set cond/rcond is identical to that in
# scipy.linalg.{pinvh, pinv2} and if/when this function is subsumed
# into scipy.linalg it should probably be shared between all of
# these routines.
# Note that eigh takes care of array conversion, chkfinite,
# and assertion that the matrix is square.
s, u = scipy.linalg.eigh(mat, lower=lower, check_finite=check_finite)
if rcond is not None: def __init__(self, M, cond=None, rcond=None, lower=True,
cond = rcond check_finite=True, allow_singular=True):
if cond in [None, -1]: # Compute the symmetric eigendecomposition.
t = u.dtype.char.lower() # Note that eigh takes care of array conversion, chkfinite,
factor = {'f': 1E3, 'd': 1E6} # and assertion that the matrix is square.
cond = factor[t] * np.finfo(t).eps s, u = scipy.linalg.eigh(M, lower=lower, check_finite=check_finite)
eps = cond * np.max(abs(s))
eps = _eigvalsh_to_eps(s, cond, rcond)
if np.min(s) < -eps: if np.min(s) < -eps:
raise ValueError('the covariance matrix must be positive semidefinite') raise ValueError('the input matrix must be positive semidefinite')
d = s[s > eps]
s_pinv = _pinv_1d(s, eps) if len(d) < len(s) and not allow_singular:
U = np.multiply(u, np.sqrt(s_pinv)) raise np.linalg.LinAlgError('singular matrix')
log_pdet = np.sum(np.log(s[s > eps])) s_pinv = _pinv_1d(s, eps)
U = np.multiply(u, np.sqrt(s_pinv))
return U, log_pdet
# Initialize the eagerly precomputed attributes.
self.rank = len(d)
_doc_default_callparams = \ self.U = U
"""mean : array_like, optional self.log_pdet = np.sum(np.log(d))
# Initialize an attribute to be lazily computed.
self._pinv = None
@property
def pinv(self):
if self._pinv is None:
self._pinv = np.dot(self.U, self.U.T)
return self._pinv
_doc_default_callparams = """\
mean : array_like, optional
Mean of the distribution (default zero) Mean of the distribution (default zero)
cov : array_like, optional cov : array_like, optional
Covariance matrix of the distribution (default one) Covariance matrix of the distribution (default one)
allow_singular : bool, optional
Whether to allow a singular covariance matrix. (Default: False)
""" """
_doc_callparams_note = \ _doc_callparams_note = \
"""Setting the parameter `mean` to `None` is equivalent to having `mean` """Setting the parameter `mean` to `None` is equivalent to having `mean`
be the zero-vector. The parameter `cov` can be a scalar, in which case be the zero-vector. The parameter `cov` can be a scalar, in which case
the covariance matrix is the identity times that value, a vector of the covariance matrix is the identity times that value, a vector of
diagonal entries for the covariance matrix, or a two-dimensional diagonal entries for the covariance matrix, or a two-dimensional
array_like. array_like.
""" """
_doc_frozen_callparams = "" _doc_frozen_callparams = ""
_doc_frozen_callparams_note = \ _doc_frozen_callparams_note = \
"""See class definition for a detailed description of parameters.""" """See class definition for a detailed description of parameters."""
docdict_params = { docdict_params = {
'_doc_default_callparams': _doc_default_callparams, '_doc_default_callparams': _doc_default_callparams,
@ -224,15 +272,13 @@ class multivariate_normal_gen(object):
The `mean` keyword specifies the mean. The `cov` keyword specifies the The `mean` keyword specifies the mean. The `cov` keyword specifies the
covariance matrix. covariance matrix.
.. versionadded:: 0.14.0
Methods Methods
------- -------
pdf(x, mean=None, cov=1) pdf(x, mean=None, cov=1, allow_singular=False)
Probability density function. Probability density function.
logpdf(x, mean=None, cov=1) logpdf(x, mean=None, cov=1, allow_singular=False)
Log of the probability density function. Log of the probability density function.
rvs(mean=None, cov=1) rvs(mean=None, cov=1, allow_singular=False, size=1)
Draw random samples from a multivariate normal distribution. Draw random samples from a multivariate normal distribution.
entropy() entropy()
Compute the differential entropy of the multivariate normal. Compute the differential entropy of the multivariate normal.
@ -247,8 +293,8 @@ class multivariate_normal_gen(object):
and covariance parameters, returning a "frozen" multivariate normal and covariance parameters, returning a "frozen" multivariate normal
random variable: random variable:
rv = multivariate_normal(mean=None, scale=1) rv = multivariate_normal(mean=None, cov=1, allow_singular=False)
- Frozen object with the same methods but holding the given - Frozen object with the same methods but holding the given
mean and covariance fixed. mean and covariance fixed.
Notes Notes
@ -269,8 +315,11 @@ class multivariate_normal_gen(object):
where :math:`\mu` is the mean, :math:`\Sigma` the covariance matrix, where :math:`\mu` is the mean, :math:`\Sigma` the covariance matrix,
and :math:`k` is the dimension of the space where :math:`x` takes values. and :math:`k` is the dimension of the space where :math:`x` takes values.
.. versionadded:: 0.14.0
Examples Examples
-------- --------
>>> import matplotlib.pyplot as plt
>>> from scipy.stats import multivariate_normal >>> from scipy.stats import multivariate_normal
>>> x = np.linspace(0, 5, 10, endpoint=False) >>> x = np.linspace(0, 5, 10, endpoint=False)
>>> y = multivariate_normal.pdf(x, mean=2.5, cov=0.5); y >>> y = multivariate_normal.pdf(x, mean=2.5, cov=0.5); y
@ -294,16 +343,17 @@ class multivariate_normal_gen(object):
def __init__(self): def __init__(self):
self.__doc__ = doccer.docformat(self.__doc__, docdict_params) self.__doc__ = doccer.docformat(self.__doc__, docdict_params)
def __call__(self, mean=None, cov=1): def __call__(self, mean=None, cov=1, allow_singular=False):
""" """
Create a frozen multivariate normal distribution. Create a frozen multivariate normal distribution.
See `multivariate_normal_frozen` for more information. See `multivariate_normal_frozen` for more information.
""" """
return multivariate_normal_frozen(mean, cov) return multivariate_normal_frozen(mean, cov,
allow_singular=allow_singular)
def _logpdf(self, x, mean, prec_U, log_det_cov): def _logpdf(self, x, mean, prec_U, log_det_cov, rank):
""" """
Parameters Parameters
---------- ----------
@ -317,6 +367,8 @@ class multivariate_normal_gen(object):
is the precision matrix, i.e. inverse of the covariance matrix. is the precision matrix, i.e. inverse of the covariance matrix.
log_det_cov : float log_det_cov : float
Logarithm of the determinant of the covariance matrix Logarithm of the determinant of the covariance matrix
rank : int
Rank of the covariance matrix.
Notes Notes
----- -----
@ -324,12 +376,11 @@ class multivariate_normal_gen(object):
called directly; use 'logpdf' instead. called directly; use 'logpdf' instead.
""" """
dim = x.shape[-1]
dev = x - mean dev = x - mean
maha = np.sum(np.square(np.dot(dev, prec_U)), axis=-1) maha = np.sum(np.square(np.dot(dev, prec_U)), axis=-1)
return -0.5 * (dim * _LOG_2PI + log_det_cov + maha) return -0.5 * (rank * _LOG_2PI + log_det_cov + maha)
def logpdf(self, x, mean, cov): def logpdf(self, x, mean, cov, allow_singular=False):
""" """
Log of the multivariate normal probability density function. Log of the multivariate normal probability density function.
@ -351,11 +402,11 @@ class multivariate_normal_gen(object):
""" """
dim, mean, cov = _process_parameters(None, mean, cov) dim, mean, cov = _process_parameters(None, mean, cov)
x = _process_quantiles(x, dim) x = _process_quantiles(x, dim)
prec_U, log_det_cov = _psd_pinv_decomposed_log_pdet(cov) psd = _PSD(cov, allow_singular=allow_singular)
out = self._logpdf(x, mean, prec_U, log_det_cov) out = self._logpdf(x, mean, psd.U, psd.log_pdet, psd.rank)
return _squeeze_output(out) return _squeeze_output(out)
def pdf(self, x, mean, cov): def pdf(self, x, mean, cov, allow_singular=False):
""" """
Multivariate normal probability density function. Multivariate normal probability density function.
@ -377,8 +428,8 @@ class multivariate_normal_gen(object):
""" """
dim, mean, cov = _process_parameters(None, mean, cov) dim, mean, cov = _process_parameters(None, mean, cov)
x = _process_quantiles(x, dim) x = _process_quantiles(x, dim)
prec_U, log_det_cov = _psd_pinv_decomposed_log_pdet(cov) psd = _PSD(cov, allow_singular=allow_singular)
out = np.exp(self._logpdf(x, mean, prec_U, log_det_cov)) out = np.exp(self._logpdf(x, mean, psd.U, psd.log_pdet, psd.rank))
return _squeeze_output(out) return _squeeze_output(out)
def rvs(self, mean=None, cov=1, size=1): def rvs(self, mean=None, cov=1, size=1):
@ -425,13 +476,14 @@ class multivariate_normal_gen(object):
""" """
dim, mean, cov = _process_parameters(None, mean, cov) dim, mean, cov = _process_parameters(None, mean, cov)
return 1/2 * np.log(np.linalg.det(2 * np.pi * np.e * cov)) return 0.5 * np.log(np.linalg.det(2 * np.pi * np.e * cov))
multivariate_normal = multivariate_normal_gen() multivariate_normal = multivariate_normal_gen()
class multivariate_normal_frozen(object): class multivariate_normal_frozen(object):
def __init__(self, mean=None, cov=1): def __init__(self, mean=None, cov=1, allow_singular=False):
""" """
Create a frozen multivariate normal distribution. Create a frozen multivariate normal distribution.
@ -441,6 +493,9 @@ class multivariate_normal_frozen(object):
Mean of the distribution (default zero) Mean of the distribution (default zero)
cov : array_like, optional cov : array_like, optional
Covariance matrix of the distribution (default one) Covariance matrix of the distribution (default one)
allow_singular : bool, optional
If this flag is True then tolerate a singular
covariance matrix (default False).
Examples Examples
-------- --------
@ -456,13 +511,13 @@ class multivariate_normal_frozen(object):
""" """
self.dim, self.mean, self.cov = _process_parameters(None, mean, cov) self.dim, self.mean, self.cov = _process_parameters(None, mean, cov)
self.prec_U, self._log_det_cov = _psd_pinv_decomposed_log_pdet(self.cov) self.cov_info = _PSD(self.cov, allow_singular=allow_singular)
self._mnorm = multivariate_normal_gen() self._mnorm = multivariate_normal_gen()
def logpdf(self, x): def logpdf(self, x):
x = _process_quantiles(x, self.dim) x = _process_quantiles(x, self.dim)
out = self._mnorm._logpdf(x, self.mean, self.prec_U, self._log_det_cov) out = self._mnorm._logpdf(x, self.mean, self.cov_info.U,
self.cov_info.log_pdet, self.cov_info.rank)
return _squeeze_output(out) return _squeeze_output(out)
def pdf(self, x): def pdf(self, x):
@ -481,7 +536,9 @@ class multivariate_normal_frozen(object):
Entropy of the multivariate normal distribution Entropy of the multivariate normal distribution
""" """
return 1/2 * (self.dim * (_LOG_2PI + 1) + self._log_det_cov) log_pdet = self.cov_info.log_pdet
rank = self.cov_info.rank
return 0.5 * (rank * (_LOG_2PI + 1) + log_pdet)
# Set frozen generator docstrings from corresponding docstrings in # Set frozen generator docstrings from corresponding docstrings in
@ -491,3 +548,337 @@ for name in ['logpdf', 'pdf', 'rvs']:
method_frozen = multivariate_normal_frozen.__dict__[name] method_frozen = multivariate_normal_frozen.__dict__[name]
method_frozen.__doc__ = doccer.docformat(method.__doc__, docdict_noparams) method_frozen.__doc__ = doccer.docformat(method.__doc__, docdict_noparams)
method.__doc__ = doccer.docformat(method.__doc__, docdict_params) method.__doc__ = doccer.docformat(method.__doc__, docdict_params)
_dirichlet_doc_default_callparams = """\
alpha : array_like
The concentration parameters. The number of entries determines the
dimensionality of the distribution.
"""
_dirichlet_doc_frozen_callparams = ""
_dirichlet_doc_frozen_callparams_note = \
"""See class definition for a detailed description of parameters."""
dirichlet_docdict_params = {
'_dirichlet_doc_default_callparams': _dirichlet_doc_default_callparams,
}
dirichlet_docdict_noparams = {
'_dirichlet_doc_default_callparams': _dirichlet_doc_frozen_callparams,
}
def _dirichlet_check_parameters(alpha):
alpha = np.asarray(alpha)
if np.min(alpha) <= 0:
raise ValueError("All parameters must be greater than 0")
elif alpha.ndim != 1:
raise ValueError("Parameter vector 'a' must be one dimensional, " +
"but a.shape = %s." % str(alpha.shape))
return alpha
def _dirichlet_check_input(alpha, x):
x = np.asarray(x)
if x.shape[0] + 1 != alpha.shape[0] and x.shape[0] != alpha.shape[0]:
raise ValueError("Vector 'x' must have one entry less then the" +
" parameter vector 'a', but alpha.shape = " +
"%s and " % alpha.shape +
"x.shape = %s." % x.shape)
if x.shape[0] != alpha.shape[0]:
xk = np.array([1 - np.sum(x, 0)])
if xk.ndim == 1:
x = np.append(x, xk)
elif xk.ndim == 2:
x = np.vstack((x, xk))
else:
raise ValueError("The input must be one dimensional or a two "
"dimensional matrix containing the entries.")
if np.min(x) < 0:
raise ValueError("Each entry in 'x' must be greater or equal zero.")
if np.max(x) > 1:
raise ValueError("Each entry in 'x' must be smaller or equal one.")
if (np.abs(np.sum(x, 0) - 1.0) > 10e-10).any():
raise ValueError("The input vector 'x' must lie within the normal " +
"simplex. but sum(x)=%f." % np.sum(x, 0))
return x
def _lnB(alpha):
r"""
Internal helper function to compute the log of the useful quotient
.. math::
B(\alpha) = \frac{\prod_{i=1}{K}\Gamma(\alpha_i)}{\Gamma\left(\sum_{i=1}^{K}\alpha_i\right)}
Parameters
----------
%(_dirichlet_doc_default_callparams)s
Returns
-------
B : scalar
Helper quotient, internal use only
"""
return np.sum(gammaln(alpha)) - gammaln(np.sum(alpha))
class dirichlet_gen(object):
r"""
A Dirichlet random variable.
The `alpha` keyword specifies the concentration parameters of the
distribution.
.. versionadded:: 0.15.0
Methods
-------
pdf(x, alpha)
Probability density function.
logpdf(x, alpha)
Log of the probability density function.
rvs(alpha, size=1)
Draw random samples from a Dirichlet distribution.
mean(alpha)
The mean of the Dirichlet distribution
var(alpha)
The variance of the Dirichlet distribution
entropy(alpha)
Compute the differential entropy of the multivariate normal.
Parameters
----------
x : array_like
Quantiles, with the last axis of `x` denoting the components.
%(_dirichlet_doc_default_callparams)s
Alternatively, the object may be called (as a function) to fix
concentration parameters, returning a "frozen" Dirichlet
random variable:
rv = dirichlet(alpha)
- Frozen object with the same methods but holding the given
concentration parameters fixed.
Notes
-----
Each :math:`\alpha` entry must be positive. The distribution has only
support on the simplex defined by
.. math::
\sum_{i=1}^{K} x_i \le 1
The probability density function for `dirichlet` is
.. math::
f(x) = \frac{1}{\mathrm{B}(\boldsymbol\alpha)} \prod_{i=1}^K x_i^{\alpha_i - 1}
where
.. math::
\mathrm{B}(\boldsymbol\alpha) = \frac{\prod_{i=1}^K \Gamma(\alpha_i)}{\Gamma\bigl(\sum_{i=1}^K \alpha_i\bigr)}
and :math:`\boldsymbol\alpha=(\alpha_1,\ldots,\alpha_K)`, the
concentration parameters and :math:`K` is the dimension of the space
where :math:`x` takes values.
"""
def __init__(self):
self.__doc__ = doccer.docformat(self.__doc__, dirichlet_docdict_params)
def __call__(self, alpha):
return dirichlet_frozen(alpha)
def _logpdf(self, x, alpha):
"""
Parameters
----------
x : ndarray
Points at which to evaluate the log of the probability
density function
%(_dirichlet_doc_default_callparams)s
Notes
-----
As this function does no argument checking, it should not be
called directly; use 'logpdf' instead.
"""
lnB = _lnB(alpha)
return - lnB + np.sum((np.log(x.T) * (alpha - 1)).T, 0)
def logpdf(self, x, alpha):
"""
Log of the Dirichlet probability density function.
Parameters
----------
x : array_like
Quantiles, with the last axis of `x` denoting the components.
%(_dirichlet_doc_default_callparams)s
Returns
-------
pdf : ndarray
Log of the probability density function evaluated at `x`
"""
alpha = _dirichlet_check_parameters(alpha)
x = _dirichlet_check_input(alpha, x)
out = self._logpdf(x, alpha)
return _squeeze_output(out)
def pdf(self, x, alpha):
"""
The Dirichlet probability density function.
Parameters
----------
x : array_like
Quantiles, with the last axis of `x` denoting the components.
%(_dirichlet_doc_default_callparams)s
Returns
-------
pdf : ndarray
The probability density function evaluated at `x`
"""
alpha = _dirichlet_check_parameters(alpha)
x = _dirichlet_check_input(alpha, x)
out = np.exp(self._logpdf(x, alpha))
return _squeeze_output(out)
def mean(self, alpha):
"""
Compute the mean of the dirichlet distribution.
Parameters
----------
%(_dirichlet_doc_default_callparams)s
Returns
-------
mu : scalar
Mean of the Dirichlet distribution
"""
alpha = _dirichlet_check_parameters(alpha)
out = alpha / (np.sum(alpha))
return _squeeze_output(out)
def var(self, alpha):
"""
Compute the variance of the dirichlet distribution.
Parameters
----------
%(_dirichlet_doc_default_callparams)s
Returns
-------
v : scalar
Variance of the Dirichlet distribution
"""
alpha = _dirichlet_check_parameters(alpha)
alpha0 = np.sum(alpha)
out = (alpha * (alpha0 - alpha)) / ((alpha0 * alpha0) * (alpha0 + 1))
return out
def entropy(self, alpha):
"""
Compute the differential entropy of the dirichlet distribution.
Parameters
----------
%(_dirichlet_doc_default_callparams)s
Returns
-------
h : scalar
Entropy of the Dirichlet distribution
"""
alpha = _dirichlet_check_parameters(alpha)
alpha0 = np.sum(alpha)
lnB = _lnB(alpha)
K = alpha.shape[0]
out = lnB + (alpha0 - K) * scipy.special.psi(alpha0) - np.sum(
(alpha - 1) * scipy.special.psi(alpha))
return _squeeze_output(out)
def rvs(self, alpha, size=1):
"""
Draw random samples from a Dirichlet distribution.
Parameters
----------
%(_dirichlet_doc_default_callparams)s
size : integer, optional
Number of samples to draw (default 1).
Returns
-------
rvs : ndarray or scalar
Random variates of size (`size`, `N`), where `N` is the
dimension of the random variable.
"""
alpha = _dirichlet_check_parameters(alpha)
return np.random.dirichlet(alpha, size=size)
dirichlet = dirichlet_gen()
class dirichlet_frozen(object):
def __init__(self, alpha):
self.alpha = _dirichlet_check_parameters(alpha)
self._dirichlet = dirichlet_gen()
def logpdf(self, x):
return self._dirichlet.logpdf(x, self.alpha)
def pdf(self, x):
return self._dirichlet.pdf(x, self.alpha)
def mean(self):
return self._dirichlet.mean(self.alpha)
def var(self):
return self._dirichlet.var(self.alpha)
def entropy(self):
return self._dirichlet.entropy(self.alpha)
def rvs(self, size=1):
return self._dirichlet.rvs(self.alpha, size)
# Set frozen generator docstrings from corresponding docstrings in
# multivariate_normal_gen and fill in default strings in class docstrings
for name in ['logpdf', 'pdf', 'rvs', 'mean', 'var', 'entropy']:
method = dirichlet_gen.__dict__[name]
method_frozen = dirichlet_frozen.__dict__[name]
method_frozen.__doc__ = doccer.docformat(
method.__doc__, dirichlet_docdict_noparams)
method.__doc__ = doccer.docformat(method.__doc__, dirichlet_docdict_params)

@ -0,0 +1,54 @@
"""Functions copypasted from newer versions of numpy.
"""
from __future__ import division, print_function, absolute_import
import warnings
import numpy as np
from scipy.lib._version import NumpyVersion
if NumpyVersion(np.__version__) > '1.7.0.dev':
_assert_warns = np.testing.assert_warns
else:
def _assert_warns(warning_class, func, *args, **kw):
r"""
Fail unless the given callable throws the specified warning.
This definition is copypasted from numpy 1.9.0.dev.
The version in earlier numpy returns None.
Parameters
----------
warning_class : class
The class defining the warning that `func` is expected to throw.
func : callable
The callable to test.
*args : Arguments
Arguments passed to `func`.
**kwargs : Kwargs
Keyword arguments passed to `func`.
Returns
-------
The value returned by `func`.
"""
with warnings.catch_warnings(record=True) as l:
warnings.simplefilter('always')
result = func(*args, **kw)
if not len(l) > 0:
raise AssertionError("No warning raised when calling %s"
% func.__name__)
if not l[0].category is warning_class:
raise AssertionError("First warning for %s is not a "
"%s( is %s)" % (func.__name__, warning_class, l[0]))
return result
if NumpyVersion(np.__version__) >= '1.6.0':
count_nonzero = np.count_nonzero
else:
def count_nonzero(a):
return (a != 0).sum()

@ -246,9 +246,9 @@ def chi2_contingency(observed, correction=True, lambda_=None):
if np.any(expected == 0): if np.any(expected == 0):
# Include one of the positions where expected is zero in # Include one of the positions where expected is zero in
# the exception message. # the exception message.
zeropos = list(np.where(expected == 0)[0]) zeropos = list(zip(*np.where(expected == 0)))[0]
raise ValueError("The internally computed table of expected " raise ValueError("The internally computed table of expected "
"frequencies has a zero element at %s." % zeropos) "frequencies has a zero element at %s." % (zeropos,))
# The degrees of freedom # The degrees of freedom
dof = expected.size - sum(expected.shape) + expected.ndim - 1 dof = expected.size - sum(expected.shape) + expected.ndim - 1

@ -1,6 +1,6 @@
from __future__ import division from __future__ import division
import warnings import warnings
from wafo.wafodata import PlotData from wafo.containers import PlotData
from wafo.misc import findextrema from wafo.misc import findextrema
from scipy import special from scipy import special
import numpy as np import numpy as np

@ -7,7 +7,19 @@
# #
from __future__ import division, print_function, absolute_import from __future__ import division, print_function, absolute_import
from ._distn_infrastructure import entropy, rv_discrete, rv_continuous from ._distn_infrastructure import (entropy, rv_discrete, rv_continuous,
rv_frozen)
from . import _continuous_distns
from . import _discrete_distns
from ._continuous_distns import * from ._continuous_distns import *
from ._discrete_distns import * from ._discrete_distns import *
# For backwards compatibility e.g. pymc expects distributions.__all__.
__all__ = ['entropy', 'rv_discrete', 'rv_continuous']
# Add only the distribution names, not the *_gen names.
__all__ += _continuous_distns._distn_names
__all__ += _discrete_distns._distn_names

@ -7,10 +7,11 @@ Distributions
Author: Per A. Brodtkorb 2008 Author: Per A. Brodtkorb 2008
''' '''
from __future__ import division from __future__ import division, absolute_import
import warnings import warnings
from wafo.plotbackend import plotbackend
from wafo.misc import ecross, findcross from ..plotbackend import plotbackend
from ..misc import ecross, findcross
import numdifftools # @UnresolvedImport import numdifftools # @UnresolvedImport
@ -27,12 +28,10 @@ from numpy import (
from numpy import flatnonzero as nonzero from numpy import flatnonzero as nonzero
__all__ = [ __all__ = ['Profile', 'FitDistribution']
'Profile', 'FitDistribution'
]
floatinfo = np.finfo(float) floatinfo = np.finfo(float)
# arr = atleast_1d
arr = asarray arr = asarray
all = alltrue # @ReservedAssignment all = alltrue # @ReservedAssignment
@ -77,7 +76,8 @@ class rv_frozen(object):
def __init__(self, dist, *args, **kwds): def __init__(self, dist, *args, **kwds):
self.dist = dist self.dist = dist
args, loc, scale = dist._parse_args(*args, **kwds) args, loc, scale = dist._parse_args(*args, **kwds)
if len(args) == dist.numargs - 2: # isinstance(dist, rv_continuous): if len(args) == dist.numargs - 2: #
# if isinstance(dist, rv_continuous):
self.par = args + (loc, scale) self.par = args + (loc, scale)
else: # rv_discrete else: # rv_discrete
self.par = args + (loc,) self.par = args + (loc,)
@ -152,7 +152,7 @@ class Profile(object):
with ML or MPS estimated distribution parameters. with ML or MPS estimated distribution parameters.
**kwds : named arguments with keys **kwds : named arguments with keys
i : scalar integer i : scalar integer
defining which distribution parameter to keep fixed in the defining which distribution parameter to keep fixed in the
profiling process (default first non-fixed parameter) profiling process (default first non-fixed parameter)
pmin, pmax : real scalars pmin, pmax : real scalars
Interval for either the parameter, phat(i), prb, or x, used in the Interval for either the parameter, phat(i), prb, or x, used in the
@ -283,27 +283,25 @@ class Profile(object):
self._par = phatv.copy() self._par = phatv.copy()
# Set up variable to profile and _local_link function # Set up variable to profile and _local_link function
self.profile_x = not self.x == None self.profile_x = self.x is not None
self.profile_logSF = not (self.logSF == None or self.profile_x) self.profile_logSF = not (self.logSF is None or self.profile_x)
self.profile_par = not (self.profile_x or self.profile_logSF) self.profile_par = not (self.profile_x or self.profile_logSF)
if self.link == None: if self.link is None:
self.link = self.fit_dist.dist.link self.link = self.fit_dist.dist.link
if self.profile_par: if self.profile_par:
self._local_link = lambda fix_par, par: fix_par self._local_link = self._par_link
self.xlabel = 'phat(%d)' % self.i_fixed self.xlabel = 'phat(%d)' % self.i_fixed
p_opt = self._par[self.i_fixed] p_opt = self._par[self.i_fixed]
elif self.profile_x: elif self.profile_x:
self.logSF = fit_dist.logsf(self.x) self.logSF = fit_dist.logsf(self.x)
self._local_link = lambda fix_par, par: self.link( self._local_link = self._x_link
fix_par, self.logSF, par, self.i_fixed)
self.xlabel = 'x' self.xlabel = 'x'
p_opt = self.x p_opt = self.x
elif self.profile_logSF: elif self.profile_logSF:
p_opt = self.logSF p_opt = self.logSF
self.x = fit_dist.isf(exp(p_opt)) self.x = fit_dist.isf(exp(p_opt))
self._local_link = lambda fix_par, par: self.link( self._local_link = self._logSF_link
self.x, fix_par, par, self.i_fixed)
self.xlabel = 'log(SF)' self.xlabel = 'log(SF)'
else: else:
raise ValueError( raise ValueError(
@ -315,6 +313,15 @@ class Profile(object):
phatfree = phatv[self.i_free].copy() phatfree = phatv[self.i_free].copy()
self._set_profile(phatfree, p_opt) self._set_profile(phatfree, p_opt)
def _par_link(self, fix_par, par):
return fix_par
def _x_link(self, fix_par, par):
return self.link(fix_par, self.logSF, par, self.i_fixed)
def _logSF_link(self, fix_par, par):
return self.link(self.x, fix_par, par, self.i_fixed)
def _correct_Lmax(self, Lmax): def _correct_Lmax(self, Lmax):
if Lmax > self.Lmax: # foundNewphat = True if Lmax > self.Lmax: # foundNewphat = True
warnings.warn( warnings.warn(
@ -386,7 +393,7 @@ class Profile(object):
''' '''
linspace = numpy.linspace linspace = numpy.linspace
if self.pmin == None or self.pmax == None: if self.pmin is None or self.pmax is None:
pvar = self._get_variance() pvar = self._get_variance()
@ -395,12 +402,12 @@ class Profile(object):
p_crit = (-norm_ppf(self.alpha / 2.0) * p_crit = (-norm_ppf(self.alpha / 2.0) *
sqrt(numpy.ravel(pvar)) * 1.5) sqrt(numpy.ravel(pvar)) * 1.5)
if self.pmin == None: if self.pmin is None:
self.pmin = self._search_pmin(phatfree0, self.pmin = self._search_pmin(phatfree0,
p_opt - 5.0 * p_crit, p_opt) p_opt - 5.0 * p_crit, p_opt)
p_crit_low = (p_opt - self.pmin) / 5 p_crit_low = (p_opt - self.pmin) / 5
if self.pmax == None: if self.pmax is None:
self.pmax = self._search_pmax(phatfree0, self.pmax = self._search_pmax(phatfree0,
p_opt + 5.0 * p_crit, p_opt) p_opt + 5.0 * p_crit, p_opt)
p_crit_up = (self.pmax - p_opt) / 5 p_crit_up = (self.pmax - p_opt) / 5
@ -526,66 +533,20 @@ class Profile(object):
''' '''
if axis is None: if axis is None:
axis = plotbackend.gca() axis = plotbackend.gca()
p_ci = self.get_bounds(self.alpha) p_ci = self.get_bounds(self.alpha)
axis.plot( axis.plot(
self.args, self.data, self.args, self.data,
self.args[[0, -1]], [self.Lmax, ] * 2, 'r--', self.args[[0, -1]], [self.Lmax, ] * 2, 'r--',
self.args[[0, -1]], [self.alpha_cross_level, ] * 2, 'r--') self.args[[0, -1]], [self.alpha_cross_level, ] * 2, 'r--')
axis.vlines(p_ci, ymin=axis.get_ylim()[0], axis.vlines(p_ci, ymin=axis.get_ylim()[0],
ymax=self.Lmax, #self.alpha_cross_level, ymax=self.Lmax, # self.alpha_cross_level,
color='r', linestyles='--') color='r', linestyles='--')
axis.set_title(self.title) axis.set_title(self.title)
axis.set_ylabel(self.ylabel) axis.set_ylabel(self.ylabel)
axis.set_xlabel(self.xlabel) axis.set_xlabel(self.xlabel)
def _discretize_adaptive(fun, a, b, tol=0.005, n=5):
'''
Automatic discretization of function, adaptive gridding.
'''
tiny = floatinfo.tiny
n += (np.mod(n, 2) == 0) # make sure n is odd
x = np.linspace(a, b, n)
fx = fun(x)
n2 = (n - 1) / 2
erri = np.hstack((np.zeros((n2, 1)), np.ones((n2, 1)))).ravel()
err = erri.max()
err0 = np.inf
# while (err != err0 and err > tol and n < nmax):
for j in range(50):
if err != err0 and np.any(erri > tol):
err0 = err
# find top errors
I, = np.where(erri > tol)
# double the sample rate in intervals with the most error
y = (np.vstack(((x[I] + x[I - 1]) / 2,
(x[I + 1] + x[I]) / 2)).T).ravel()
fy = fun(y)
fy0 = np.interp(y, x, fx)
erri = 0.5 * (abs((fy0 - fy) / (abs(fy0 + fy) + tiny)))
err = erri.max()
x = np.hstack((x, y))
I = x.argsort()
x = x[I]
erri = np.hstack((zeros(len(fx)), erri))[I]
fx = np.hstack((fx, fy))[I]
else:
break
else:
warnings.warn('Recursion level limit reached j=%d' % j)
return x, fx
# class to fit given distribution to data
class FitDistribution(rv_frozen): class FitDistribution(rv_frozen):
''' '''
@ -846,7 +807,7 @@ class FitDistribution(rv_frozen):
optimizer = kwds.get('optimizer', optimize.fmin) optimizer = kwds.get('optimizer', optimize.fmin)
# convert string to function in scipy.optimize # convert string to function in scipy.optimize
if (not callable(optimizer) and if (not callable(optimizer) and
isinstance(optimizer, (str, unicode))): isinstance(optimizer, (str, unicode))):
if not optimizer.startswith('fmin_'): if not optimizer.startswith('fmin_'):
optimizer = "fmin_" + optimizer optimizer = "fmin_" + optimizer
if optimizer == 'fmin_': if optimizer == 'fmin_':
@ -867,7 +828,7 @@ class FitDistribution(rv_frozen):
def _compute_cov(self): def _compute_cov(self):
'''Compute covariance '''Compute covariance
''' '''
somefixed = (self.par_fix != None) and any(isfinite(self.par_fix)) somefixed = (self.par_fix is not None) and any(isfinite(self.par_fix))
# H1 = numpy.asmatrix(self.dist.hessian_nnlf(self.par, self.data)) # H1 = numpy.asmatrix(self.dist.hessian_nnlf(self.par, self.data))
H = numpy.asmatrix(self.dist.hessian_nlogps(self.par, self.data)) H = numpy.asmatrix(self.dist.hessian_nlogps(self.par, self.data))
self.H = H self.H = H
@ -1000,7 +961,7 @@ class FitDistribution(rv_frozen):
self.plotresprb() self.plotresprb()
fixstr = '' fixstr = ''
if not self.par_fix == None: if self.par_fix is not None:
numfix = len(self.i_fixed) numfix = len(self.i_fixed)
if numfix > 0: if numfix > 0:
format0 = ', '.join(['%d'] * numfix) format0 = ', '.join(['%d'] * numfix)
@ -1160,7 +1121,7 @@ class FitDistribution(rv_frozen):
n = len(x) n = len(x)
np1 = n + 1 np1 = n + 1
if unknown_numpar == None: if unknown_numpar is None:
k = len(theta) k = len(theta)
else: else:
k = unknown_numpar k = unknown_numpar
@ -1184,7 +1145,7 @@ def test_doctstrings():
def test1(): def test1():
import wafo.stats as ws import wafo.stats as ws
dist = ws.weibull_min dist = ws.weibull_min
#dist = ws.bradford # dist = ws.bradford
R = dist.rvs(0.3, size=1000) R = dist.rvs(0.3, size=1000)
phat = FitDistribution(dist, R, method='ml') phat = FitDistribution(dist, R, method='ml')

@ -93,6 +93,10 @@ class gaussian_kde(object):
high_bounds. high_bounds.
kde.integrate_kde(other_kde) : float kde.integrate_kde(other_kde) : float
Integrate two kernel density estimates multiplied together. Integrate two kernel density estimates multiplied together.
kde.pdf(points) : ndarray
Alias for ``kde.evaluate(points)``.
kde.logpdf(points) : ndarray
Equivalent to ``np.log(kde.evaluate(points))``.
kde.resample(size=None) : ndarray kde.resample(size=None) : ndarray
Randomly sample a dataset from the estimated pdf. Randomly sample a dataset from the estimated pdf.
kde.set_bandwidth(bw_method='scott') : None kde.set_bandwidth(bw_method='scott') : None
@ -106,7 +110,6 @@ class gaussian_kde(object):
to provide a different method, or set it through a call to to provide a different method, or set it through a call to
`kde.set_bandwidth`. `kde.set_bandwidth`.
Notes Notes
----- -----
Bandwidth selection strongly influences the estimate obtained from the KDE Bandwidth selection strongly influences the estimate obtained from the KDE
@ -122,7 +125,7 @@ class gaussian_kde(object):
with ``n`` the number of data points and ``d`` the number of dimensions. with ``n`` the number of data points and ``d`` the number of dimensions.
Silverman's Rule [2]_, implemented as `silverman_factor`, is:: Silverman's Rule [2]_, implemented as `silverman_factor`, is::
n * (d + 2) / 4.)**(-1. / (d + 4)). (n * (d + 2) / 4.)**(-1. / (d + 4)).
Good general descriptions of kernel density estimation can be found in [1]_ Good general descriptions of kernel density estimation can be found in [1]_
and [2]_, the mathematics for this multi-dimensional implementation can be and [2]_, the mathematics for this multi-dimensional implementation can be
@ -388,11 +391,12 @@ class gaussian_kde(object):
large = other large = other
sum_cov = small.covariance + large.covariance sum_cov = small.covariance + large.covariance
sum_cov_chol = linalg.cho_factor(sum_cov)
result = 0.0 result = 0.0
for i in range(small.n): for i in range(small.n):
mean = small.dataset[:, i, newaxis] mean = small.dataset[:, i, newaxis]
diff = large.dataset - mean diff = large.dataset - mean
tdiff = dot(linalg.inv(sum_cov), diff) tdiff = linalg.cho_solve(sum_cov_chol, diff)
energies = sum(diff * tdiff, axis=0) / 2.0 energies = sum(diff * tdiff, axis=0) / 2.0
result += sum(exp(-energies), axis=0) result += sum(exp(-energies), axis=0)
@ -511,3 +515,27 @@ class gaussian_kde(object):
self.covariance = self._data_covariance * self.factor**2 self.covariance = self._data_covariance * self.factor**2
self.inv_cov = self._data_inv_cov / self.factor**2 self.inv_cov = self._data_inv_cov / self.factor**2
self._norm_factor = sqrt(linalg.det(2*pi*self.covariance)) * self.n self._norm_factor = sqrt(linalg.det(2*pi*self.covariance)) * self.n
def pdf(self, x):
"""
Evaluate the estimated pdf on a provided set of points.
Notes
-----
This is an alias for `gaussian_kde.evaluate`. See the ``evaluate``
docstring for more details.
"""
return self.evaluate(x)
def logpdf(self, x):
"""
Evaluate the log of the estimated pdf on a provided set of points.
Notes
-----
See `gaussian_kde.evaluate` for more details; this method simply
returns ``np.log(gaussian_kde.evaluate(x))``.
"""
return np.log(self.evaluate(x))

File diff suppressed because it is too large Load Diff

@ -24,13 +24,9 @@ is a relatively new package, some API changes are still possible.
f_value_wilks_lambda f_value_wilks_lambda
find_repeats find_repeats
friedmanchisquare friedmanchisquare
gmean
hmean
kendalltau kendalltau
kendalltau_seasonal kendalltau_seasonal
kruskalwallis kruskalwallis
kruskalwallis
ks_twosamp
ks_twosamp ks_twosamp
kurtosis kurtosis
kurtosistest kurtosistest
@ -80,3 +76,4 @@ from __future__ import division, print_function, absolute_import
from .mstats_basic import * from .mstats_basic import *
from .mstats_extras import * from .mstats_extras import *
from scipy.stats import gmean, hmean

File diff suppressed because it is too large Load Diff

@ -1,15 +1,12 @@
""" """
Additional statistics functions, with support to MA. Additional statistics functions with support for masked arrays.
:author: Pierre GF Gerard-Marchant
:contact: pierregm_at_uga_edu
:date: $Date: 2007-10-29 17:18:13 +0200 (Mon, 29 Oct 2007) $
:version: $Id: morestats.py 3473 2007-10-29 15:18:13Z jarrod.millman $
""" """
from __future__ import division, print_function, absolute_import
__author__ = "Pierre GF Gerard-Marchant" # Original author (2007): Pierre GF Gerard-Marchant
__docformat__ = "restructuredtext en"
from __future__ import division, print_function, absolute_import
__all__ = ['compare_medians_ms', __all__ = ['compare_medians_ms',
@ -19,6 +16,7 @@ __all__ = ['compare_medians_ms',
'rsh', 'rsh',
'trimmed_mean_ci',] 'trimmed_mean_ci',]
import numpy as np import numpy as np
from numpy import float_, int_, ndarray from numpy import float_, int_, ndarray
@ -30,9 +28,6 @@ from . import mstats_basic as mstats
from scipy.stats.distributions import norm, beta, t, binom from scipy.stats.distributions import norm, beta, t, binom
#####--------------------------------------------------------------------------
#---- --- Quantiles ---
#####--------------------------------------------------------------------------
def hdquantiles(data, prob=list([.25,.5,.75]), axis=None, var=False,): def hdquantiles(data, prob=list([.25,.5,.75]), axis=None, var=False,):
""" """
Computes quantile estimates with the Harrell-Davis method. Computes quantile estimates with the Harrell-Davis method.
@ -65,14 +60,14 @@ def hdquantiles(data, prob=list([.25,.5,.75]), axis=None, var=False,):
xsorted = np.squeeze(np.sort(data.compressed().view(ndarray))) xsorted = np.squeeze(np.sort(data.compressed().view(ndarray)))
# Don't use length here, in case we have a numpy scalar # Don't use length here, in case we have a numpy scalar
n = xsorted.size n = xsorted.size
#.........
hd = np.empty((2,len(prob)), float_) hd = np.empty((2,len(prob)), float_)
if n < 2: if n < 2:
hd.flat = np.nan hd.flat = np.nan
if var: if var:
return hd return hd
return hd[0] return hd[0]
#.........
v = np.arange(n+1) / float(n) v = np.arange(n+1) / float(n)
betacdf = beta.cdf betacdf = beta.cdf
for (i,p) in enumerate(prob): for (i,p) in enumerate(prob):
@ -89,7 +84,7 @@ def hdquantiles(data, prob=list([.25,.5,.75]), axis=None, var=False,):
hd[1, prob == 0] = hd[1, prob == 1] = np.nan hd[1, prob == 0] = hd[1, prob == 1] = np.nan
return hd return hd
return hd[0] return hd[0]
# Initialization & checks --------- # Initialization & checks
data = ma.array(data, copy=False, dtype=float_) data = ma.array(data, copy=False, dtype=float_)
p = np.array(prob, copy=False, ndmin=1) p = np.array(prob, copy=False, ndmin=1)
# Computes quantiles along axis (or globally) # Computes quantiles along axis (or globally)
@ -97,12 +92,11 @@ def hdquantiles(data, prob=list([.25,.5,.75]), axis=None, var=False,):
result = _hd_1D(data, p, var) result = _hd_1D(data, p, var)
else: else:
if data.ndim > 2: if data.ndim > 2:
raise ValueError("Array 'data' must be at most two dimensional, but got data.ndim = %d" % data.ndim) raise ValueError("Array 'data' must be at most two dimensional, "
"but got data.ndim = %d" % data.ndim)
result = ma.apply_along_axis(_hd_1D, axis, data, p, var) result = ma.apply_along_axis(_hd_1D, axis, data, p, var)
#
return ma.fix_invalid(result, copy=False)
#.............................................................................. return ma.fix_invalid(result, copy=False)
def hdmedian(data, axis=-1, var=False): def hdmedian(data, axis=-1, var=False):
@ -124,7 +118,6 @@ def hdmedian(data, axis=-1, var=False):
return result.squeeze() return result.squeeze()
#..............................................................................
def hdquantiles_sd(data, prob=list([.25,.5,.75]), axis=None): def hdquantiles_sd(data, prob=list([.25,.5,.75]), axis=None):
""" """
The standard error of the Harrell-Davis quantile estimates by jackknife. The standard error of the Harrell-Davis quantile estimates by jackknife.
@ -153,10 +146,10 @@ def hdquantiles_sd(data, prob=list([.25,.5,.75]), axis=None):
hdsd = np.empty(len(prob), float_) hdsd = np.empty(len(prob), float_)
if n < 2: if n < 2:
hdsd.flat = np.nan hdsd.flat = np.nan
#.........
vv = np.arange(n) / float(n-1) vv = np.arange(n) / float(n-1)
betacdf = beta.cdf betacdf = beta.cdf
#
for (i,p) in enumerate(prob): for (i,p) in enumerate(prob):
_w = betacdf(vv, (n+1)*p, (n+1)*(1-p)) _w = betacdf(vv, (n+1)*p, (n+1)*(1-p))
w = _w[1:] - _w[:-1] w = _w[1:] - _w[:-1]
@ -166,7 +159,7 @@ def hdquantiles_sd(data, prob=list([.25,.5,.75]), axis=None):
mx_var = np.array(mx_.var(), copy=False, ndmin=1) * n / float(n-1) mx_var = np.array(mx_.var(), copy=False, ndmin=1) * n / float(n-1)
hdsd[i] = float(n-1) * np.sqrt(np.diag(mx_var).diagonal() / float(n)) hdsd[i] = float(n-1) * np.sqrt(np.diag(mx_var).diagonal() / float(n))
return hdsd return hdsd
# Initialization & checks --------- # Initialization & checks
data = ma.array(data, copy=False, dtype=float_) data = ma.array(data, copy=False, dtype=float_)
p = np.array(prob, copy=False, ndmin=1) p = np.array(prob, copy=False, ndmin=1)
# Computes quantiles along axis (or globally) # Computes quantiles along axis (or globally)
@ -174,15 +167,12 @@ def hdquantiles_sd(data, prob=list([.25,.5,.75]), axis=None):
result = _hdsd_1D(data, p) result = _hdsd_1D(data, p)
else: else:
if data.ndim > 2: if data.ndim > 2:
raise ValueError("Array 'data' must be at most two dimensional, but got data.ndim = %d" % data.ndim) raise ValueError("Array 'data' must be at most two dimensional, "
"but got data.ndim = %d" % data.ndim)
result = ma.apply_along_axis(_hdsd_1D, axis, data, p) result = ma.apply_along_axis(_hdsd_1D, axis, data, p)
#
return ma.fix_invalid(result, copy=False).ravel()
return ma.fix_invalid(result, copy=False).ravel()
#####--------------------------------------------------------------------------
#---- --- Confidence intervals ---
#####--------------------------------------------------------------------------
def trimmed_mean_ci(data, limits=(0.2,0.2), inclusive=(True,True), def trimmed_mean_ci(data, limits=(0.2,0.2), inclusive=(True,True),
alpha=0.05, axis=None): alpha=0.05, axis=None):
@ -198,9 +188,9 @@ def trimmed_mean_ci(data, limits=(0.2,0.2), inclusive=(True,True),
Tuple of the percentages to cut on each side of the array, with respect Tuple of the percentages to cut on each side of the array, with respect
to the number of unmasked data, as floats between 0. and 1. If ``n`` to the number of unmasked data, as floats between 0. and 1. If ``n``
is the number of unmasked data before trimming, then is the number of unmasked data before trimming, then
(``n`` * `limits[0]`)th smallest data and (``n`` * `limits[1]`)th (``n * limits[0]``)th smallest data and (``n * limits[1]``)th
largest data are masked. The total number of unmasked data after largest data are masked. The total number of unmasked data after
trimming is ``n`` * (1. - sum(`limits`)). trimming is ``n * (1. - sum(limits))``.
The value of one limit can be set to None to indicate an open interval. The value of one limit can be set to None to indicate an open interval.
Defaults to (0.2, 0.2). Defaults to (0.2, 0.2).
@ -234,8 +224,6 @@ def trimmed_mean_ci(data, limits=(0.2,0.2), inclusive=(True,True),
tppf = t.ppf(1-alpha/2.,df) tppf = t.ppf(1-alpha/2.,df)
return np.array((tmean - tppf*tstde, tmean+tppf*tstde)) return np.array((tmean - tppf*tstde, tmean+tppf*tstde))
#..............................................................................
def mjci(data, prob=[0.25,0.5,0.75], axis=None): def mjci(data, prob=[0.25,0.5,0.75], axis=None):
""" """
@ -258,7 +246,7 @@ def mjci(data, prob=[0.25,0.5,0.75], axis=None):
n = data.size n = data.size
prob = (np.array(p) * n + 0.5).astype(int_) prob = (np.array(p) * n + 0.5).astype(int_)
betacdf = beta.cdf betacdf = beta.cdf
#
mj = np.empty(len(prob), float_) mj = np.empty(len(prob), float_)
x = np.arange(1,n+1, dtype=float_) / n x = np.arange(1,n+1, dtype=float_) / n
y = x - 1./n y = x - 1./n
@ -269,10 +257,12 @@ def mjci(data, prob=[0.25,0.5,0.75], axis=None):
C2 = np.dot(W,data**2) C2 = np.dot(W,data**2)
mj[i] = np.sqrt(C2 - C1**2) mj[i] = np.sqrt(C2 - C1**2)
return mj return mj
#
data = ma.array(data, copy=False) data = ma.array(data, copy=False)
if data.ndim > 2: if data.ndim > 2:
raise ValueError("Array 'data' must be at most two dimensional, but got data.ndim = %d" % data.ndim) raise ValueError("Array 'data' must be at most two dimensional, "
"but got data.ndim = %d" % data.ndim)
p = np.array(prob, copy=False, ndmin=1) p = np.array(prob, copy=False, ndmin=1)
# Computes quantiles along axis (or globally) # Computes quantiles along axis (or globally)
if (axis is None): if (axis is None):
@ -280,8 +270,6 @@ def mjci(data, prob=[0.25,0.5,0.75], axis=None):
else: else:
return ma.apply_along_axis(_mjci_1D, axis, data, p) return ma.apply_along_axis(_mjci_1D, axis, data, p)
#..............................................................................
def mquantiles_cimj(data, prob=[0.25,0.50,0.75], alpha=0.05, axis=None): def mquantiles_cimj(data, prob=[0.25,0.50,0.75], alpha=0.05, axis=None):
""" """
@ -308,7 +296,6 @@ def mquantiles_cimj(data, prob=[0.25,0.50,0.75], alpha=0.05, axis=None):
return (xq - z * smj, xq + z * smj) return (xq - z * smj, xq + z * smj)
#.............................................................................
def median_cihs(data, alpha=0.05, axis=None): def median_cihs(data, alpha=0.05, axis=None):
""" """
Computes the alpha-level confidence interval for the median of the data. Computes the alpha-level confidence interval for the median of the data.
@ -353,12 +340,11 @@ def median_cihs(data, alpha=0.05, axis=None):
result = _cihs_1D(data.compressed(), alpha) result = _cihs_1D(data.compressed(), alpha)
else: else:
if data.ndim > 2: if data.ndim > 2:
raise ValueError("Array 'data' must be at most two dimensional, but got data.ndim = %d" % data.ndim) raise ValueError("Array 'data' must be at most two dimensional, "
"but got data.ndim = %d" % data.ndim)
result = ma.apply_along_axis(_cihs_1D, axis, data, alpha) result = ma.apply_along_axis(_cihs_1D, axis, data, alpha)
#
return result
#.............................................................................. return result
def compare_medians_ms(group_1, group_2, axis=None): def compare_medians_ms(group_1, group_2, axis=None):
@ -453,14 +439,13 @@ def rsh(data, points=None):
points = data points = data
else: else:
points = np.array(points, copy=False, ndmin=1) points = np.array(points, copy=False, ndmin=1)
if data.ndim != 1: if data.ndim != 1:
raise AttributeError("The input array should be 1D only !") raise AttributeError("The input array should be 1D only !")
n = data.count() n = data.count()
r = idealfourths(data, axis=None) r = idealfourths(data, axis=None)
h = 1.2 * (r[-1]-r[0]) / n**(1./5) h = 1.2 * (r[-1]-r[0]) / n**(1./5)
nhi = (data[:,None] <= points[None,:] + h).sum(0) nhi = (data[:,None] <= points[None,:] + h).sum(0)
nlo = (data[:,None] < points[None,:] - h).sum(0) nlo = (data[:,None] < points[None,:] - h).sum(0)
return (nhi-nlo) / (2.*n*h) return (nhi-nlo) / (2.*n*h)
###############################################################################

File diff suppressed because it is too large Load Diff

@ -6,12 +6,11 @@ import warnings
import numpy as np import numpy as np
import numpy.testing as npt import numpy.testing as npt
#from scipy.lib._version import NumpyVersion from scipy.lib._version import NumpyVersion
from scipy import stats from wafo import stats
#NUMPY_BELOW_1_7 = NumpyVersion(np.__version__) < '1.7.0' NUMPY_BELOW_1_7 = NumpyVersion(np.__version__) < '1.7.0'
NUMPY_BELOW_1_7 = np.__version__ < '1.7.0'
def check_normalization(distfn, args, distname): def check_normalization(distfn, args, distname):
@ -27,7 +26,7 @@ def check_normalization(distfn, args, distname):
normalization_expect = distfn.expect(lambda x: 1, args=args) normalization_expect = distfn.expect(lambda x: 1, args=args)
npt.assert_allclose(normalization_expect, 1.0, atol=atol, rtol=rtol, npt.assert_allclose(normalization_expect, 1.0, atol=atol, rtol=rtol,
err_msg=distname, verbose=True) err_msg=distname, verbose=True)
normalization_cdf = distfn.cdf(distfn.b, *args) normalization_cdf = distfn.cdf(distfn.b, *args)
npt.assert_allclose(normalization_cdf, 1.0) npt.assert_allclose(normalization_cdf, 1.0)
@ -38,48 +37,47 @@ def check_moment(distfn, arg, m, v, msg):
m2 = distfn.moment(2, *arg) m2 = distfn.moment(2, *arg)
if not np.isinf(m): if not np.isinf(m):
npt.assert_almost_equal(m1, m, decimal=10, err_msg=msg + npt.assert_almost_equal(m1, m, decimal=10, err_msg=msg +
' - 1st moment') ' - 1st moment')
else: # or np.isnan(m1), else: # or np.isnan(m1),
npt.assert_(np.isinf(m1), npt.assert_(np.isinf(m1),
msg + ' - 1st moment -infinite, m1=%s' % str(m1)) msg + ' - 1st moment -infinite, m1=%s' % str(m1))
if not np.isinf(v): if not np.isinf(v):
npt.assert_almost_equal(m2 - m1 * m1, v, decimal=10, err_msg=msg + npt.assert_almost_equal(m2 - m1 * m1, v, decimal=10, err_msg=msg +
' - 2ndt moment') ' - 2ndt moment')
else: # or np.isnan(m2), else: # or np.isnan(m2),
npt.assert_(np.isinf(m2), npt.assert_(np.isinf(m2),
msg + ' - 2nd moment -infinite, m2=%s' % str(m2)) msg + ' - 2nd moment -infinite, m2=%s' % str(m2))
def check_mean_expect(distfn, arg, m, msg): def check_mean_expect(distfn, arg, m, msg):
if np.isfinite(m): if np.isfinite(m):
m1 = distfn.expect(lambda x: x, arg) m1 = distfn.expect(lambda x: x, arg)
npt.assert_almost_equal(m1, m, decimal=5, err_msg=msg + npt.assert_almost_equal(m1, m, decimal=5, err_msg=msg +
' - 1st moment (expect)') ' - 1st moment (expect)')
def check_var_expect(distfn, arg, m, v, msg): def check_var_expect(distfn, arg, m, v, msg):
if np.isfinite(v): if np.isfinite(v):
m2 = distfn.expect(lambda x: x * x, arg) m2 = distfn.expect(lambda x: x*x, arg)
npt.assert_almost_equal(m2, v + m * m, decimal=5, err_msg=msg + npt.assert_almost_equal(m2, v + m*m, decimal=5, err_msg=msg +
' - 2st moment (expect)') ' - 2st moment (expect)')
def check_skew_expect(distfn, arg, m, v, s, msg): def check_skew_expect(distfn, arg, m, v, s, msg):
if np.isfinite(s): if np.isfinite(s):
m3e = distfn.expect(lambda x: np.power(x - m, 3), arg) m3e = distfn.expect(lambda x: np.power(x-m, 3), arg)
npt.assert_almost_equal(m3e, s * np.power(v, 1.5), npt.assert_almost_equal(m3e, s * np.power(v, 1.5),
decimal=5, err_msg=msg + ' - skew') decimal=5, err_msg=msg + ' - skew')
else: else:
npt.assert_(np.isnan(s)) npt.assert_(np.isnan(s))
def check_kurt_expect(distfn, arg, m, v, k, msg): def check_kurt_expect(distfn, arg, m, v, k, msg):
if np.isfinite(k): if np.isfinite(k):
m4e = distfn.expect(lambda x: np.power(x - m, 4), arg) m4e = distfn.expect(lambda x: np.power(x-m, 4), arg)
npt.assert_allclose( npt.assert_allclose(m4e, (k + 3.) * np.power(v, 2), atol=1e-5, rtol=1e-5,
m4e, (k + 3.) * np.power(v, 2), atol=1e-5, rtol=1e-5, err_msg=msg + ' - kurtosis')
err_msg=msg + ' - kurtosis')
else: else:
npt.assert_(np.isnan(k)) npt.assert_(np.isnan(k))
@ -106,7 +104,7 @@ def check_edge_support(distfn, args):
npt.assert_equal(distfn.logsf(x, *args), [0.0, -np.inf]) npt.assert_equal(distfn.logsf(x, *args), [0.0, -np.inf])
if isinstance(distfn, stats.rv_discrete): if isinstance(distfn, stats.rv_discrete):
x = [distfn.a - 1, distfn.b] x = [distfn.a-1, distfn.b]
npt.assert_equal(distfn.ppf([0.0, 1.0], *args), x) npt.assert_equal(distfn.ppf([0.0, 1.0], *args), x)
npt.assert_equal(distfn.isf([0.0, 1.0], *args), x[::-1]) npt.assert_equal(distfn.isf([0.0, 1.0], *args), x[::-1])
@ -116,7 +114,7 @@ def check_edge_support(distfn, args):
def check_named_args(distfn, x, shape_args, defaults, meths): def check_named_args(distfn, x, shape_args, defaults, meths):
# Check calling w/ named arguments. ## Check calling w/ named arguments.
# check consistency of shapes, numargs and _parse signature # check consistency of shapes, numargs and _parse signature
signature = inspect.getargspec(distfn._parse_args) signature = inspect.getargspec(distfn._parse_args)
@ -124,8 +122,7 @@ def check_named_args(distfn, x, shape_args, defaults, meths):
npt.assert_(signature.keywords is None) npt.assert_(signature.keywords is None)
npt.assert_(signature.defaults == defaults) npt.assert_(signature.defaults == defaults)
# self, a, b, loc=0, scale=1 shape_argnames = signature.args[1:-len(defaults)] # self, a, b, loc=0, scale=1
shape_argnames = signature.args[1:-len(defaults)]
if distfn.shapes: if distfn.shapes:
shapes_ = distfn.shapes.replace(',', ' ').split() shapes_ = distfn.shapes.replace(',', ' ').split()
else: else:
@ -144,7 +141,7 @@ def check_named_args(distfn, x, shape_args, defaults, meths):
k.update({names.pop(): a.pop()}) k.update({names.pop(): a.pop()})
v = [meth(x, *a, **k) for meth in meths] v = [meth(x, *a, **k) for meth in meths]
npt.assert_array_equal(vals, v) npt.assert_array_equal(vals, v)
if not 'n' in k.keys(): if 'n' not in k.keys():
# `n` is first parameter of moment(), so can't be used as named arg # `n` is first parameter of moment(), so can't be used as named arg
with warnings.catch_warnings(): with warnings.catch_warnings():
warnings.simplefilter("ignore", UserWarning) warnings.simplefilter("ignore", UserWarning)
@ -154,3 +151,4 @@ def check_named_args(distfn, x, shape_args, defaults, meths):
# unknown arguments should not go through: # unknown arguments should not go through:
k.update({'kaboom': 42}) k.update({'kaboom': 42})
npt.assert_raises(TypeError, distfn.cdf, x, **k) npt.assert_raises(TypeError, distfn.cdf, x, **k)

@ -1,4 +1,5 @@
from __future__ import division, print_function, absolute_import from __future__ import division, print_function, absolute_import
import numpy as np import numpy as np
from numpy.testing import assert_array_almost_equal, run_module_suite from numpy.testing import assert_array_almost_equal, run_module_suite
from scipy.stats import \ from scipy.stats import \
@ -19,7 +20,7 @@ class TestBinnedStatistic(object):
x = self.x x = self.x
v = self.v v = self.v
count1, edges1, _bc = binned_statistic(x, v, 'count', bins=10) count1, edges1, bc = binned_statistic(x, v, 'count', bins=10)
count2, edges2 = np.histogram(x, bins=10) count2, edges2 = np.histogram(x, bins=10)
assert_array_almost_equal(count1, count2) assert_array_almost_equal(count1, count2)
@ -29,7 +30,7 @@ class TestBinnedStatistic(object):
x = self.x x = self.x
v = self.v v = self.v
sum1, edges1, _bc = binned_statistic(x, v, 'sum', bins=10) sum1, edges1, bc = binned_statistic(x, v, 'sum', bins=10)
sum2, edges2 = np.histogram(x, bins=10, weights=v) sum2, edges2 = np.histogram(x, bins=10, weights=v)
assert_array_almost_equal(sum1, sum2) assert_array_almost_equal(sum1, sum2)
@ -39,8 +40,8 @@ class TestBinnedStatistic(object):
x = self.x x = self.x
v = self.v v = self.v
stat1, edges1, _bc = binned_statistic(x, v, 'mean', bins=10) stat1, edges1, bc = binned_statistic(x, v, 'mean', bins=10)
stat2, edges2, _bc = binned_statistic(x, v, np.mean, bins=10) stat2, edges2, bc = binned_statistic(x, v, np.mean, bins=10)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(edges1, edges2) assert_array_almost_equal(edges1, edges2)
@ -49,8 +50,8 @@ class TestBinnedStatistic(object):
x = self.x x = self.x
v = self.v v = self.v
stat1, edges1, _bc = binned_statistic(x, v, 'std', bins=10) stat1, edges1, bc = binned_statistic(x, v, 'std', bins=10)
stat2, edges2, _bc = binned_statistic(x, v, np.std, bins=10) stat2, edges2, bc = binned_statistic(x, v, np.std, bins=10)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(edges1, edges2) assert_array_almost_equal(edges1, edges2)
@ -59,8 +60,8 @@ class TestBinnedStatistic(object):
x = self.x x = self.x
v = self.v v = self.v
stat1, edges1, _bc = binned_statistic(x, v, 'median', bins=10) stat1, edges1, bc = binned_statistic(x, v, 'median', bins=10)
stat2, edges2, _bc = binned_statistic(x, v, np.median, bins=10) stat2, edges2, bc = binned_statistic(x, v, np.median, bins=10)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(edges1, edges2) assert_array_almost_equal(edges1, edges2)
@ -69,7 +70,7 @@ class TestBinnedStatistic(object):
x = self.x[:20] x = self.x[:20]
v = self.v[:20] v = self.v[:20]
count1, _edges1, bc = binned_statistic(x, v, 'count', bins=3) count1, edges1, bc = binned_statistic(x, v, 'count', bins=3)
bc2 = np.array([3, 2, 1, 3, 2, 3, 3, 3, 3, 1, 1, 3, 3, 1, 2, 3, 1, bc2 = np.array([3, 2, 1, 3, 2, 3, 3, 3, 3, 1, 1, 3, 3, 1, 2, 3, 1,
1, 2, 1]) 1, 2, 1])
@ -86,7 +87,7 @@ class TestBinnedStatistic(object):
mean, bins, _ = binned_statistic(x[:15], data[:15]) mean, bins, _ = binned_statistic(x[:15], data[:15])
mean_range, bins_range, _ = binned_statistic(x, data, range=[(0, 14)]) mean_range, bins_range, _ = binned_statistic(x, data, range=[(0, 14)])
mean_range2, bins_range2, _ = binned_statistic(x, data, range=[(0, 14)]) mean_range2, bins_range2, _ = binned_statistic(x, data, range=(0, 14))
assert_array_almost_equal(mean, mean_range) assert_array_almost_equal(mean, mean_range)
assert_array_almost_equal(bins, bins_range) assert_array_almost_equal(bins, bins_range)
@ -98,8 +99,7 @@ class TestBinnedStatistic(object):
y = self.y y = self.y
v = self.v v = self.v
count1, binx1, biny1, _bc = binned_statistic_2d(x, y, v, 'count', count1, binx1, biny1, bc = binned_statistic_2d(x, y, v, 'count', bins=5)
bins=5)
count2, binx2, biny2 = np.histogram2d(x, y, bins=5) count2, binx2, biny2 = np.histogram2d(x, y, bins=5)
assert_array_almost_equal(count1, count2) assert_array_almost_equal(count1, count2)
@ -111,7 +111,7 @@ class TestBinnedStatistic(object):
y = self.y y = self.y
v = self.v v = self.v
sum1, binx1, biny1, _bc = binned_statistic_2d(x, y, v, 'sum', bins=5) sum1, binx1, biny1, bc = binned_statistic_2d(x, y, v, 'sum', bins=5)
sum2, binx2, biny2 = np.histogram2d(x, y, bins=5, weights=v) sum2, binx2, biny2 = np.histogram2d(x, y, bins=5, weights=v)
assert_array_almost_equal(sum1, sum2) assert_array_almost_equal(sum1, sum2)
@ -123,8 +123,8 @@ class TestBinnedStatistic(object):
y = self.y y = self.y
v = self.v v = self.v
stat1, binx1, biny1, _b = binned_statistic_2d(x, y, v, 'mean', bins=5) stat1, binx1, biny1, bc = binned_statistic_2d(x, y, v, 'mean', bins=5)
stat2, binx2, biny2, _b = binned_statistic_2d(x, y, v, np.mean, bins=5) stat2, binx2, biny2, bc = binned_statistic_2d(x, y, v, np.mean, bins=5)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(binx1, binx2) assert_array_almost_equal(binx1, binx2)
@ -135,8 +135,8 @@ class TestBinnedStatistic(object):
y = self.y y = self.y
v = self.v v = self.v
stat1, binx1, biny1, _bc = binned_statistic_2d(x, y, v, 'std', bins=5) stat1, binx1, biny1, bc = binned_statistic_2d(x, y, v, 'std', bins=5)
stat2, binx2, biny2, _bc = binned_statistic_2d(x, y, v, np.std, bins=5) stat2, binx2, biny2, bc = binned_statistic_2d(x, y, v, np.std, bins=5)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(binx1, binx2) assert_array_almost_equal(binx1, binx2)
@ -147,9 +147,8 @@ class TestBinnedStatistic(object):
y = self.y y = self.y
v = self.v v = self.v
stat1, binx1, biny1, _ = binned_statistic_2d(x, y, v, 'median', bins=5) stat1, binx1, biny1, bc = binned_statistic_2d(x, y, v, 'median', bins=5)
stat2, binx2, biny2, _ = binned_statistic_2d(x, y, v, np.median, stat2, binx2, biny2, bc = binned_statistic_2d(x, y, v, np.median, bins=5)
bins=5)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(binx1, binx2) assert_array_almost_equal(binx1, binx2)
@ -160,8 +159,7 @@ class TestBinnedStatistic(object):
y = self.y[:20] y = self.y[:20]
v = self.v[:20] v = self.v[:20]
count1, _binx1, _biny1, bc = binned_statistic_2d(x, y, v, 'count', count1, binx1, biny1, bc = binned_statistic_2d(x, y, v, 'count', bins=3)
bins=3)
bc2 = np.array([17, 11, 6, 16, 11, 17, 18, 17, 17, 7, 6, 18, 16, bc2 = np.array([17, 11, 6, 16, 11, 17, 18, 17, 17, 7, 6, 18, 16,
6, 11, 16, 6, 6, 11, 8]) 6, 11, 16, 6, 6, 11, 8])
@ -175,7 +173,7 @@ class TestBinnedStatistic(object):
X = self.X X = self.X
v = self.v v = self.v
count1, edges1, _bc = binned_statistic_dd(X, v, 'count', bins=3) count1, edges1, bc = binned_statistic_dd(X, v, 'count', bins=3)
count2, edges2 = np.histogramdd(X, bins=3) count2, edges2 = np.histogramdd(X, bins=3)
assert_array_almost_equal(count1, count2) assert_array_almost_equal(count1, count2)
@ -185,7 +183,7 @@ class TestBinnedStatistic(object):
X = self.X X = self.X
v = self.v v = self.v
sum1, edges1, _bc = binned_statistic_dd(X, v, 'sum', bins=3) sum1, edges1, bc = binned_statistic_dd(X, v, 'sum', bins=3)
sum2, edges2 = np.histogramdd(X, bins=3, weights=v) sum2, edges2 = np.histogramdd(X, bins=3, weights=v)
assert_array_almost_equal(sum1, sum2) assert_array_almost_equal(sum1, sum2)
@ -195,8 +193,8 @@ class TestBinnedStatistic(object):
X = self.X X = self.X
v = self.v v = self.v
stat1, edges1, _bc = binned_statistic_dd(X, v, 'mean', bins=3) stat1, edges1, bc = binned_statistic_dd(X, v, 'mean', bins=3)
stat2, edges2, _bc = binned_statistic_dd(X, v, np.mean, bins=3) stat2, edges2, bc = binned_statistic_dd(X, v, np.mean, bins=3)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(edges1, edges2) assert_array_almost_equal(edges1, edges2)
@ -205,8 +203,8 @@ class TestBinnedStatistic(object):
X = self.X X = self.X
v = self.v v = self.v
stat1, edges1, _bc = binned_statistic_dd(X, v, 'std', bins=3) stat1, edges1, bc = binned_statistic_dd(X, v, 'std', bins=3)
stat2, edges2, _bc = binned_statistic_dd(X, v, np.std, bins=3) stat2, edges2, bc = binned_statistic_dd(X, v, np.std, bins=3)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(edges1, edges2) assert_array_almost_equal(edges1, edges2)
@ -215,8 +213,8 @@ class TestBinnedStatistic(object):
X = self.X X = self.X
v = self.v v = self.v
stat1, edges1, _bc = binned_statistic_dd(X, v, 'median', bins=3) stat1, edges1, bc = binned_statistic_dd(X, v, 'median', bins=3)
stat2, edges2, _bc = binned_statistic_dd(X, v, np.median, bins=3) stat2, edges2, bc = binned_statistic_dd(X, v, np.median, bins=3)
assert_array_almost_equal(stat1, stat2) assert_array_almost_equal(stat1, stat2)
assert_array_almost_equal(edges1, edges2) assert_array_almost_equal(edges1, edges2)
@ -225,7 +223,7 @@ class TestBinnedStatistic(object):
X = self.X[:20] X = self.X[:20]
v = self.v[:20] v = self.v[:20]
count1, _edges1, bc = binned_statistic_dd(X, v, 'count', bins=3) count1, edges1, bc = binned_statistic_dd(X, v, 'count', bins=3)
bc2 = np.array([63, 33, 86, 83, 88, 67, 57, 33, 42, 41, 82, 83, 92, bc2 = np.array([63, 33, 86, 83, 88, 67, 57, 33, 42, 41, 82, 83, 92,
32, 36, 91, 43, 87, 81, 81]) 32, 36, 91, 43, 87, 81, 81])
@ -237,5 +235,4 @@ class TestBinnedStatistic(object):
if __name__ == "__main__": if __name__ == "__main__":
#unittest.main()
run_module_suite() run_module_suite()

@ -13,6 +13,8 @@ from wafo.stats.tests.common_tests import (check_normalization, check_moment,
check_entropy, check_private_entropy, NUMPY_BELOW_1_7, check_entropy, check_private_entropy, NUMPY_BELOW_1_7,
check_edge_support, check_named_args) check_edge_support, check_named_args)
from wafo.stats._distr_params import distcont
""" """
Test all continuous distributions. Test all continuous distributions.
@ -26,98 +28,6 @@ not for numerically exact results.
DECIMAL = 5 # specify the precision of the tests # increased from 0 to 5 DECIMAL = 5 # specify the precision of the tests # increased from 0 to 5
distcont = [
['alpha', (3.5704770516650459,)],
['anglit', ()],
['arcsine', ()],
['beta', (2.3098496451481823, 0.62687954300963677)],
['betaprime', (5, 6)],
['bradford', (0.29891359763170633,)],
['burr', (10.5, 4.3)],
['cauchy', ()],
['chi', (78,)],
['chi2', (55,)],
['cosine', ()],
['dgamma', (1.1023326088288166,)],
['dweibull', (2.0685080649914673,)],
['erlang', (10,)],
['expon', ()],
['exponpow', (2.697119160358469,)],
['exponweib', (2.8923945291034436, 1.9505288745913174)],
['f', (29, 18)],
['fatiguelife', (29,)], # correction numargs = 1
['fisk', (3.0857548622253179,)],
['foldcauchy', (4.7164673455831894,)],
['foldnorm', (1.9521253373555869,)],
['frechet_l', (3.6279911255583239,)],
['frechet_r', (1.8928171603534227,)],
['gamma', (1.9932305483800778,)],
['gausshyper', (13.763771604130699, 3.1189636648681431,
2.5145980350183019, 5.1811649903971615)], # veryslow
['genexpon', (9.1325976465418908, 16.231956600590632, 3.2819552690843983)],
['genextreme', (-0.1,)],
['gengamma', (4.4162385429431925, 3.1193091679242761)],
['genhalflogistic', (0.77274727809929322,)],
['genlogistic', (0.41192440799679475,)],
['genpareto', (0.1,)], # use case with finite moments
['gilbrat', ()],
['gompertz', (0.94743713075105251,)],
['gumbel_l', ()],
['gumbel_r', ()],
['halfcauchy', ()],
['halflogistic', ()],
['halfnorm', ()],
['hypsecant', ()],
['invgamma', (4.0668996136993067,)],
['invgauss', (0.14546264555347513,)],
['invweibull', (10.58,)],
['johnsonsb', (4.3172675099141058, 3.1837781130785063)],
['johnsonsu', (2.554395574161155, 2.2482281679651965)],
['ksone', (1000,)], # replace 22 by 100 to avoid failing range, ticket 956
['kstwobign', ()],
['laplace', ()],
['levy', ()],
['levy_l', ()],
# ['levy_stable', (0.35667405469844993,
# -0.67450531578494011)], #NotImplementedError
# rvs not tested
['loggamma', (0.41411931826052117,)],
['logistic', ()],
['loglaplace', (3.2505926592051435,)],
['lognorm', (0.95368226960575331,)],
['lomax', (1.8771398388773268,)],
['maxwell', ()],
['mielke', (10.4, 3.6)],
['nakagami', (4.9673794866666237,)],
['ncf', (27, 27, 0.41578441799226107)],
['nct', (14, 0.24045031331198066)],
['ncx2', (21, 1.0560465975116415)],
['norm', ()],
['pareto', (2.621716532144454,)],
['pearson3', (0.1,)],
['powerlaw', (1.6591133289905851,)],
['powerlognorm', (2.1413923530064087, 0.44639540782048337)],
['powernorm', (4.4453652254590779,)],
['rayleigh', ()],
['rdist', (0.9,)], # feels also slow
['recipinvgauss', (0.63004267809369119,)],
['reciprocal', (0.0062309367010521255, 1.0062309367010522)],
['rice', (0.7749725210111873,)],
['semicircular', ()],
['t', (2.7433514990818093,)],
['triang', (0.15785029824528218,)],
['truncexpon', (4.6907725456810478,)],
['truncnorm', (-1.0978730080013919, 2.7306754109031979)],
['truncnorm', (0.1, 2.)],
['tukeylambda', (3.1321477856738267,)],
['uniform', ()],
['vonmises', (3.9939042581071398,)],
['vonmises_line', (3.9939042581071398,)],
['wald', ()],
['weibull_max', (2.8687961709100187,)],
['weibull_min', (1.7866166930421596,)],
['wrapcauchy', (0.031071279018614728,)]]
## Last four of these fail all around. Need to be checked ## Last four of these fail all around. Need to be checked
distcont_extra = [ distcont_extra = [
['betaprime', (100, 86)], ['betaprime', (100, 86)],
@ -159,7 +69,7 @@ distmissing = ['wald', 'gausshyper', 'genexpon', 'rv_continuous',
'johnsonsb', 'truncexpon', 'rice', 'invgauss', 'invgamma', 'johnsonsb', 'truncexpon', 'rice', 'invgauss', 'invgamma',
'powerlognorm'] 'powerlognorm']
distmiss = [[dist, args] for dist, args in distcont if dist in distmissing] distmiss = [[dist,args] for dist,args in distcont if dist in distmissing]
distslow = ['rdist', 'gausshyper', 'recipinvgauss', 'ksone', 'genexpon', distslow = ['rdist', 'gausshyper', 'recipinvgauss', 'ksone', 'genexpon',
'vonmises', 'vonmises_line', 'mielke', 'semicircular', 'vonmises', 'vonmises_line', 'mielke', 'semicircular',
'cosine', 'invweibull', 'powerlognorm', 'johnsonsu', 'kstwobign'] 'cosine', 'invweibull', 'powerlognorm', 'johnsonsu', 'kstwobign']
@ -182,11 +92,12 @@ def _silence_fp_errors(func):
def test_cont_basic(): def test_cont_basic():
# this test skips slow distributions # this test skips slow distributions
with warnings.catch_warnings(): with warnings.catch_warnings():
# warnings.filterwarnings('ignore', warnings.filterwarnings('ignore', category=integrate.IntegrationWarning)
# category=integrate.IntegrationWarning)
for distname, arg in distcont[:]: for distname, arg in distcont[:]:
if distname in distslow: if distname in distslow:
continue continue
if distname is 'levy_stable':
continue
distfn = getattr(stats, distname) distfn = getattr(stats, distname)
np.random.seed(765456) np.random.seed(765456)
sn = 500 sn = 500
@ -231,19 +142,21 @@ def test_cont_basic():
yield knf(distname == 'truncnorm')(check_ppf_private), distfn, \ yield knf(distname == 'truncnorm')(check_ppf_private), distfn, \
arg, distname arg, distname
@npt.dec.slow @npt.dec.slow
def test_cont_basic_slow(): def test_cont_basic_slow():
# same as above for slow distributions # same as above for slow distributions
with warnings.catch_warnings(): with warnings.catch_warnings():
# warnings.filterwarnings('ignore', warnings.filterwarnings('ignore', category=integrate.IntegrationWarning)
# category=integrate.IntegrationWarning)
for distname, arg in distcont[:]: for distname, arg in distcont[:]:
if distname not in distslow: if distname not in distslow:
continue continue
if distname is 'levy_stable':
continue
distfn = getattr(stats, distname) distfn = getattr(stats, distname)
np.random.seed(765456) np.random.seed(765456)
sn = 500 sn = 500
rvs = distfn.rvs(size=sn, *arg) rvs = distfn.rvs(size=sn,*arg)
sm = rvs.mean() sm = rvs.mean()
sv = rvs.var() sv = rvs.var()
m, v = distfn.stats(*arg) m, v = distfn.stats(*arg)
@ -287,12 +200,13 @@ def test_cont_basic_slow():
@npt.dec.slow @npt.dec.slow
def test_moments(): def test_moments():
with warnings.catch_warnings(): with warnings.catch_warnings():
# warnings.filterwarnings('ignore', warnings.filterwarnings('ignore', category=integrate.IntegrationWarning)
# category=integrate.IntegrationWarning)
knf = npt.dec.knownfailureif knf = npt.dec.knownfailureif
fail_normalization = set(['vonmises', 'ksone']) fail_normalization = set(['vonmises', 'ksone'])
fail_higher = set(['vonmises', 'ksone', 'ncf']) fail_higher = set(['vonmises', 'ksone', 'ncf'])
for distname, arg in distcont[:]: for distname, arg in distcont[:]:
if distname is 'levy_stable':
continue
distfn = getattr(stats, distname) distfn = getattr(stats, distname)
m, v, s, k = distfn.stats(*arg, moments='mvsk') m, v, s, k = distfn.stats(*arg, moments='mvsk')
cond1, cond2 = distname in fail_normalization, distname in fail_higher cond1, cond2 = distname in fail_normalization, distname in fail_higher
@ -316,130 +230,125 @@ def check_sample_meanvar_(distfn, arg, m, v, sm, sv, sn, msg):
check_sample_var(sv, sn, v) check_sample_var(sv, sn, v)
def check_sample_mean(sm, v, n, popmean): def check_sample_mean(sm,v,n, popmean):
# from stats.stats.ttest_1samp(a, popmean): # from stats.stats.ttest_1samp(a, popmean):
# Calculates the t-obtained for the independent samples T-test on ONE group # Calculates the t-obtained for the independent samples T-test on ONE group
# of scores a, given a population mean. # of scores a, given a population mean.
# #
# Returns: t-value, two-tailed prob # Returns: t-value, two-tailed prob
df = n - 1 df = n-1
svar = ((n - 1) * v) / float(df) # looks redundant svar = ((n-1)*v) / float(df) # looks redundant
t = (sm - popmean) / np.sqrt(svar * (1.0 / n)) t = (sm-popmean) / np.sqrt(svar*(1.0/n))
prob = stats.betai(0.5 * df, 0.5, df / (df + t * t)) prob = stats.betai(0.5*df, 0.5, df/(df+t*t))
# return t,prob # return t,prob
npt.assert_(prob > 0.01, 'mean fail, t,prob = %f, %f, m, sm=%f,%f' % npt.assert_(prob > 0.01, 'mean fail, t,prob = %f, %f, m, sm=%f,%f' %
(t, prob, popmean, sm)) (t, prob, popmean, sm))
def check_sample_var(sv, n, popvar): def check_sample_var(sv,n, popvar):
# two-sided chisquare test for sample variance equal to hypothesized # two-sided chisquare test for sample variance equal to hypothesized variance
# variance df = n-1
df = n - 1 chi2 = (n-1)*popvar/float(popvar)
chi2 = (n - 1) * popvar / float(popvar) pval = stats.chisqprob(chi2,df)*2
pval = stats.chisqprob(chi2, df) * 2 npt.assert_(pval > 0.01, 'var fail, t, pval = %f, %f, v, sv=%f, %f' %
npt.assert_(pval > 0.01, 'var fail, t, pval = %f, %f, v, sv=%f, %f' % (chi2,pval,popvar,sv))
(chi2, pval, popvar, sv))
def check_cdf_ppf(distfn,arg,msg):
def check_cdf_ppf(distfn, arg, msg):
values = [0.001, 0.5, 0.999] values = [0.001, 0.5, 0.999]
npt.assert_almost_equal(distfn.cdf(distfn.ppf(values, *arg), *arg), npt.assert_almost_equal(distfn.cdf(distfn.ppf(values, *arg), *arg),
values, decimal=DECIMAL, err_msg=msg + values, decimal=DECIMAL, err_msg=msg +
' - cdf-ppf roundtrip') ' - cdf-ppf roundtrip')
def check_sf_isf(distfn, arg, msg): def check_sf_isf(distfn,arg,msg):
npt.assert_almost_equal(distfn.sf(distfn.isf([0.1, 0.5, 0.9], *arg), *arg), npt.assert_almost_equal(distfn.sf(distfn.isf([0.1,0.5,0.9], *arg), *arg),
[0.1, 0.5, 0.9], decimal=DECIMAL, err_msg=msg + [0.1,0.5,0.9], decimal=DECIMAL, err_msg=msg +
' - sf-isf roundtrip') ' - sf-isf roundtrip')
npt.assert_almost_equal(distfn.cdf([0.1, 0.9], *arg), npt.assert_almost_equal(distfn.cdf([0.1,0.9], *arg),
1.0 - distfn.sf([0.1, 0.9], *arg), 1.0-distfn.sf([0.1,0.9], *arg),
decimal=DECIMAL, err_msg=msg + decimal=DECIMAL, err_msg=msg +
' - cdf-sf relationship') ' - cdf-sf relationship')
def check_pdf(distfn, arg, msg): def check_pdf(distfn, arg, msg):
# compares pdf at median with numerical derivative of cdf # compares pdf at median with numerical derivative of cdf
median = distfn.ppf(0.5, *arg) median = distfn.ppf(0.5, *arg)
eps = 1e-6 eps = 1e-6
pdfv = distfn.pdf(median, *arg) pdfv = distfn.pdf(median, *arg)
if (pdfv < 1e-4) or (pdfv > 1e4): if (pdfv < 1e-4) or (pdfv > 1e4):
# avoid checking a case where pdf is close to zero or huge # avoid checking a case where pdf is close to zero or huge (singularity)
# (singularity) median = median + 0.1
median = median + 0.1 pdfv = distfn.pdf(median, *arg)
pdfv = distfn.pdf(median, *arg) cdfdiff = (distfn.cdf(median + eps, *arg) -
cdfdiff = (distfn.cdf(median + eps, *arg) - distfn.cdf(median - eps, *arg))/eps/2.0
distfn.cdf(median - eps, *arg)) / eps / 2.0 # replace with better diff and better test (more points),
# replace with better diff and better test (more points), # actually, this works pretty well
# actually, this works pretty well npt.assert_almost_equal(pdfv, cdfdiff,
npt.assert_almost_equal(pdfv, cdfdiff, decimal=DECIMAL, decimal=DECIMAL, err_msg=msg + ' - cdf-pdf relationship')
err_msg=msg + ' - cdf-pdf relationship')
def check_pdf_logpdf(distfn, args, msg):
def check_pdf_logpdf(distfn, args, msg): # compares pdf at several points with the log of the pdf
# compares pdf at several points with the log of the pdf points = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8])
points = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]) vals = distfn.ppf(points, *args)
vals = distfn.ppf(points, *args) pdf = distfn.pdf(vals, *args)
pdf = distfn.pdf(vals, *args) logpdf = distfn.logpdf(vals, *args)
logpdf = distfn.logpdf(vals, *args) pdf = pdf[pdf != 0]
pdf = pdf[pdf != 0] logpdf = logpdf[np.isfinite(logpdf)]
logpdf = logpdf[np.isfinite(logpdf)] npt.assert_almost_equal(np.log(pdf), logpdf, decimal=7, err_msg=msg + " - logpdf-log(pdf) relationship")
npt.assert_almost_equal(np.log(pdf), logpdf, decimal=7,
err_msg=msg + " - logpdf-log(pdf) relationship")
def check_sf_logsf(distfn, args, msg):
# compares sf at several points with the log of the sf
def check_sf_logsf(distfn, args, msg): points = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8])
# compares sf at several points with the log of the sf vals = distfn.ppf(points, *args)
points = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]) sf = distfn.sf(vals, *args)
vals = distfn.ppf(points, *args) logsf = distfn.logsf(vals, *args)
sf = distfn.sf(vals, *args) sf = sf[sf != 0]
logsf = distfn.logsf(vals, *args) logsf = logsf[np.isfinite(logsf)]
sf = sf[sf != 0] npt.assert_almost_equal(np.log(sf), logsf, decimal=7, err_msg=msg + " - logsf-log(sf) relationship")
logsf = logsf[np.isfinite(logsf)]
npt.assert_almost_equal(np.log(sf), logsf, decimal=7,
err_msg=msg + " - logsf-log(sf) relationship") def check_cdf_logcdf(distfn, args, msg):
# compares cdf at several points with the log of the cdf
points = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8])
def check_cdf_logcdf(distfn, args, msg): vals = distfn.ppf(points, *args)
# compares cdf at several points with the log of the cdf cdf = distfn.cdf(vals, *args)
points = np.array([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8]) logcdf = distfn.logcdf(vals, *args)
vals = distfn.ppf(points, *args) cdf = cdf[cdf != 0]
cdf = distfn.cdf(vals, *args) logcdf = logcdf[np.isfinite(logcdf)]
logcdf = distfn.logcdf(vals, *args) npt.assert_almost_equal(np.log(cdf), logcdf, decimal=7, err_msg=msg + " - logcdf-log(cdf) relationship")
cdf = cdf[cdf != 0]
logcdf = logcdf[np.isfinite(logcdf)]
npt.assert_almost_equal(np.log(cdf), logcdf, decimal=7, def check_distribution_rvs(dist, args, alpha, rvs):
err_msg=msg + " - logcdf-log(cdf) relationship") # test from scipy.stats.tests
# this version reuses existing random variables
D,pval = stats.kstest(rvs, dist, args=args, N=1000)
def check_distribution_rvs(dist, args, alpha, rvs): if (pval < alpha):
# test from scipy.stats.tests D,pval = stats.kstest(dist,'',args=args, N=1000)
# this version reuses existing random variables npt.assert_(pval > alpha, "D = " + str(D) + "; pval = " + str(pval) +
D, pval = stats.kstest(rvs, dist, args=args, N=1000) "; alpha = " + str(alpha) + "\nargs = " + str(args))
if (pval < alpha):
D, pval = stats.kstest(dist, '', args=args, N=1000)
npt.assert_(pval > alpha, "D = " + str(D) + "; pval = " + str(pval) + def check_vecentropy(distfn, args):
"; alpha = " + str(alpha) + "\nargs = " + str(args)) npt.assert_equal(distfn.vecentropy(*args), distfn._entropy(*args))
def check_vecentropy(distfn, args): @npt.dec.skipif(NUMPY_BELOW_1_7)
npt.assert_equal(distfn.vecentropy(*args), distfn._entropy(*args)) def check_loc_scale(distfn, arg, m, v, msg):
loc, scale = 10.0, 10.0
mt, vt = distfn.stats(loc=loc, scale=scale, *arg)
@npt.dec.skipif(NUMPY_BELOW_1_7) npt.assert_allclose(m*scale + loc, mt)
def check_loc_scale(distfn, arg, m, v, msg): npt.assert_allclose(v*scale*scale, vt)
loc, scale = 10.0, 10.0
mt, vt = distfn.stats(loc=loc, scale=scale, *arg)
npt.assert_allclose(m * scale + loc, mt) def check_ppf_private(distfn, arg, msg):
npt.assert_allclose(v * scale * scale, vt) #fails by design for truncnorm self.nb not defined
ppfs = distfn._ppf(np.array([0.1, 0.5, 0.9]), *arg)
npt.assert_(not np.any(np.isnan(ppfs)), msg + 'ppf private is nan')
def check_ppf_private(distfn, arg, msg):
# fails by design for truncnorm self.nb not defined
ppfs = distfn._ppf(np.array([0.1, 0.5, 0.9]), *arg) if __name__ == "__main__":
npt.assert_(not np.any(np.isnan(ppfs)), msg + 'ppf private is nan') npt.run_module_suite()
if __name__ == "__main__":
npt.run_module_suite()

@ -2,37 +2,17 @@ from __future__ import division, print_function, absolute_import
import numpy.testing as npt import numpy.testing as npt
import numpy as np import numpy as np
try: from scipy.lib.six import xrange
from wafo.stats.six import xrange
except:
pass
from wafo import stats from wafo import stats
from wafo.stats.tests.common_tests import (check_normalization, check_moment, from wafo.stats.tests.common_tests import (check_normalization, check_moment,
check_mean_expect, check_mean_expect,
check_var_expect, check_skew_expect, check_kurt_expect, check_var_expect, check_skew_expect, check_kurt_expect,
check_entropy, check_private_entropy, check_edge_support, check_entropy, check_private_entropy, check_edge_support,
check_named_args) check_named_args)
from wafo.stats._distr_params import distdiscrete
knf = npt.dec.knownfailureif knf = npt.dec.knownfailureif
distdiscrete = [
['bernoulli', (0.3, )],
['binom', (5, 0.4)],
['boltzmann', (1.4, 19)],
['dlaplace', (0.8,)], # 0.5
['geom', (0.5,)],
['hypergeom', (30, 12, 6)],
['hypergeom', (21, 3, 12)], # numpy.random (3,18,12) numpy ticket:921
['hypergeom', (21, 18, 11)], # numpy.random (18,3,11) numpy ticket:921
['logser', (0.6,)], # reenabled, numpy ticket:921
['nbinom', (5, 0.5)],
['nbinom', (0.4, 0.4)], # from tickets: 583
['planck', (0.51,)], # 4.1
['poisson', (0.6,)],
['randint', (7, 31)],
['skellam', (15, 8)],
['zipf', (6.5,)]
]
def test_discrete_basic(): def test_discrete_basic():
for distname, arg in distdiscrete: for distname, arg in distdiscrete:
@ -40,7 +20,7 @@ def test_discrete_basic():
np.random.seed(9765456) np.random.seed(9765456)
rvs = distfn.rvs(size=2000, *arg) rvs = distfn.rvs(size=2000, *arg)
supp = np.unique(rvs) supp = np.unique(rvs)
#_m, v = distfn.stats(*arg) m, v = distfn.stats(*arg)
yield check_cdf_ppf, distfn, arg, supp, distname + ' cdf_ppf' yield check_cdf_ppf, distfn, arg, supp, distname + ' cdf_ppf'
yield check_pmf_cdf, distfn, arg, distname yield check_pmf_cdf, distfn, arg, distname
@ -56,7 +36,7 @@ def test_discrete_basic():
if distname in seen: if distname in seen:
continue continue
seen.add(distname) seen.add(distname)
distfn = getattr(stats, distname) distfn = getattr(stats,distname)
locscale_defaults = (0,) locscale_defaults = (0,)
meths = [distfn.pmf, distfn.logpmf, distfn.cdf, distfn.logcdf, meths = [distfn.pmf, distfn.logpmf, distfn.cdf, distfn.logcdf,
distfn.logsf] distfn.logsf]
@ -74,7 +54,7 @@ def test_discrete_basic():
def test_moments(): def test_moments():
for distname, arg in distdiscrete: for distname, arg in distdiscrete:
distfn = getattr(stats, distname) distfn = getattr(stats,distname)
m, v, s, k = distfn.stats(*arg, moments='mvsk') m, v, s, k = distfn.stats(*arg, moments='mvsk')
yield check_normalization, distfn, arg, distname yield check_normalization, distfn, arg, distname
@ -84,13 +64,13 @@ def test_moments():
yield check_var_expect, distfn, arg, m, v, distname yield check_var_expect, distfn, arg, m, v, distname
yield check_skew_expect, distfn, arg, m, v, s, distname yield check_skew_expect, distfn, arg, m, v, s, distname
cond = distname in ['zipf'] cond = False #distname in ['zipf']
msg = distname + ' fails kurtosis' msg = distname + ' fails kurtosis'
yield knf(cond, msg)(check_kurt_expect), distfn, arg, m, v, k, distname yield knf(cond, msg)(check_kurt_expect), distfn, arg, m, v, k, distname
# frozen distr moments # frozen distr moments
yield check_moment_frozen, distfn, arg, m, 1 yield check_moment_frozen, distfn, arg, m, 1
yield check_moment_frozen, distfn, arg, v + m * m, 2 yield check_moment_frozen, distfn, arg, v+m*m, 2
def check_cdf_ppf(distfn, arg, supp, msg): def check_cdf_ppf(distfn, arg, supp, msg):
@ -108,7 +88,7 @@ def check_cdf_ppf(distfn, arg, supp, msg):
def check_pmf_cdf(distfn, arg, distname): def check_pmf_cdf(distfn, arg, distname):
startind = np.int(distfn.ppf(0.01, *arg) - 1) startind = np.int(distfn.ppf(0.01, *arg) - 1)
index = list(range(startind, startind + 10)) index = list(range(startind, startind + 10))
cdfs, pmfs_cum = distfn.cdf(index, *arg), distfn.pmf(index, *arg).cumsum() cdfs, pmfs_cum = distfn.cdf(index,*arg), distfn.pmf(index, *arg).cumsum()
atol, rtol = 1e-10, 1e-10 atol, rtol = 1e-10, 1e-10
if distname == 'skellam': # ncx2 accuracy if distname == 'skellam': # ncx2 accuracy
@ -158,7 +138,7 @@ def check_discrete_chisquare(distfn, arg, rvs, alpha, msg):
""" """
n = len(rvs) n = len(rvs)
nsupp = 20 nsupp = 20
wsupp = 1.0 / nsupp wsupp = 1.0/nsupp
# construct intervals with minimum mass 1/nsupp # construct intervals with minimum mass 1/nsupp
# intervals are left-half-open as in a cdf difference # intervals are left-half-open as in a cdf difference
@ -167,30 +147,30 @@ def check_discrete_chisquare(distfn, arg, rvs, alpha, msg):
distsupp = [max(distfn.a, -1000)] distsupp = [max(distfn.a, -1000)]
distmass = [] distmass = []
for ii in distsupport: for ii in distsupport:
current = distfn.cdf(ii, *arg) current = distfn.cdf(ii,*arg)
if current - last >= wsupp - 1e-14: if current - last >= wsupp-1e-14:
distsupp.append(ii) distsupp.append(ii)
distmass.append(current - last) distmass.append(current - last)
last = current last = current
if current > (1 - wsupp): if current > (1-wsupp):
break break
if distsupp[-1] < distfn.b: if distsupp[-1] < distfn.b:
distsupp.append(distfn.b) distsupp.append(distfn.b)
distmass.append(1 - last) distmass.append(1-last)
distsupp = np.array(distsupp) distsupp = np.array(distsupp)
distmass = np.array(distmass) distmass = np.array(distmass)
# convert intervals to right-half-open as required by histogram # convert intervals to right-half-open as required by histogram
histsupp = distsupp + 1e-8 histsupp = distsupp+1e-8
histsupp[0] = distfn.a histsupp[0] = distfn.a
# find sample frequencies and perform chisquare test # find sample frequencies and perform chisquare test
freq, _hsupp = np.histogram(rvs, histsupp) freq,hsupp = np.histogram(rvs,histsupp)
#cdfs = distfn.cdf(distsupp, *arg) cdfs = distfn.cdf(distsupp,*arg)
(_chis, pval) = stats.chisquare(np.array(freq), n * distmass) (chis,pval) = stats.chisquare(np.array(freq),n*distmass)
npt.assert_(pval > alpha, 'chisquare - test for %s' npt.assert_(pval > alpha, 'chisquare - test for %s'
' at arg = %s with pval = %s' % (msg, str(arg), str(pval))) ' at arg = %s with pval = %s' % (msg,str(arg),str(pval)))
def check_scale_docstring(distfn): def check_scale_docstring(distfn):

File diff suppressed because it is too large Load Diff

@ -33,6 +33,7 @@ failing_fits = [
'tukeylambda', 'tukeylambda',
'vonmises', 'vonmises',
'wrapcauchy', 'wrapcauchy',
'levy_stable'
] ]
# Don't run the fit test on these: # Don't run the fit test on these:
@ -45,14 +46,15 @@ skip_fit = [
def test_cont_fit(): def test_cont_fit():
# this tests the closeness of the estimated parameters to the true # this tests the closeness of the estimated parameters to the true
# parameters with fit method of continuous distributions # parameters with fit method of continuous distributions
# Note: slow, some distributions don't converge with sample size <= 10000 # Note: is slow, some distributions don't converge with sample size <= 10000
for distname, arg in distcont: for distname, arg in distcont:
if distname not in skip_fit: if distname not in skip_fit:
yield check_cont_fit, distname, arg yield check_cont_fit, distname,arg
def check_cont_fit(distname, arg): def check_cont_fit(distname,arg):
options = dict(method='mps', floc=0.)
if distname in failing_fits: if distname in failing_fits:
# Skip failing fits unless overridden # Skip failing fits unless overridden
xfail = True xfail = True
@ -62,16 +64,18 @@ def check_cont_fit(distname, arg):
pass pass
if xfail: if xfail:
msg = "Fitting %s doesn't work reliably yet" % distname msg = "Fitting %s doesn't work reliably yet" % distname
msg += " [Set environment variable SCIPY_XFAIL=1 to run this " + \ msg += " [Set environment variable SCIPY_XFAIL=1 to run this test nevertheless.]"
"test nevertheless.]" #dec.knownfailureif(True, msg)(lambda: None)()
dec.knownfailureif(True, msg)(lambda: None)() options['floc']=0.
options['fscale']=1.
# print('Testing %s' % distname)
distfn = getattr(stats, distname) distfn = getattr(stats, distname)
truearg = np.hstack([arg, [0.0, 1.0]]) truearg = np.hstack([arg,[0.0,1.0]])
diffthreshold = np.max(np.vstack([ diffthreshold = np.max(np.vstack([truearg*thresh_percent,
truearg * thresh_percent, np.ones(distfn.numargs+2)*thresh_min]),0)
np.ones(distfn.numargs + 2) * thresh_min]), 0)
for fit_size in fit_sizes: for fit_size in fit_sizes:
# Note that if a fit succeeds, the other fit_sizes are skipped # Note that if a fit succeeds, the other fit_sizes are skipped
@ -79,16 +83,17 @@ def check_cont_fit(distname, arg):
with np.errstate(all='ignore'): with np.errstate(all='ignore'):
rvs = distfn.rvs(size=fit_size, *arg) rvs = distfn.rvs(size=fit_size, *arg)
#phat = distfn.fit2(rvs) # phat = distfn.fit2(rvs)
phat = distfn.fit2(rvs, method='mps')
phat = distfn.fit2(rvs, **options)
est = phat.par est = phat.par
#est = distfn.fit(rvs) # start with default values #est = distfn.fit(rvs) # start with default values
diff = est - truearg diff = est - truearg
# threshold for location # threshold for location
diffthreshold[-2] = np.max([np.abs(rvs.mean()) * thresh_percent, diffthreshold[-2] = np.max([np.abs(rvs.mean())*thresh_percent,thresh_min])
thresh_min])
if np.any(np.isnan(est)): if np.any(np.isnan(est)):
raise AssertionError('nan returned in fit') raise AssertionError('nan returned in fit')

@ -180,5 +180,23 @@ def test_kde_integer_input():
assert_array_almost_equal(kde(x1), y_expected, decimal=6) assert_array_almost_equal(kde(x1), y_expected, decimal=6)
def test_pdf_logpdf():
np.random.seed(1)
n_basesample = 50
xn = np.random.randn(n_basesample)
# Default
gkde = stats.gaussian_kde(xn)
xs = np.linspace(-15, 12, 25)
pdf = gkde.evaluate(xs)
pdf2 = gkde.pdf(xs)
assert_almost_equal(pdf, pdf2, decimal=12)
logpdf = np.log(pdf)
logpdf2 = gkde.logpdf(xs)
assert_almost_equal(logpdf, logpdf2, decimal=12)
if __name__ == "__main__": if __name__ == "__main__":
run_module_suite() run_module_suite()

@ -9,9 +9,8 @@ import warnings
import numpy as np import numpy as np
from numpy.random import RandomState from numpy.random import RandomState
from numpy.testing import (TestCase, run_module_suite, assert_array_equal, from numpy.testing import (TestCase, run_module_suite, assert_array_equal,
assert_almost_equal, assert_array_less, assert_almost_equal, assert_array_less, assert_array_almost_equal,
assert_array_almost_equal, assert_raises, assert_, assert_raises, assert_, assert_allclose, assert_equal, dec, assert_warns)
assert_allclose, assert_equal, dec)
from wafo import stats from wafo import stats
@ -37,20 +36,19 @@ g10 = [0.991, 0.995, 0.984, 0.994, 0.997, 0.997, 0.991, 0.998, 1.004, 0.997]
class TestShapiro(TestCase): class TestShapiro(TestCase):
def test_basic(self): def test_basic(self):
x1 = [0.11, 7.87, 4.61, 10.14, 7.95, 3.14, 0.46, x1 = [0.11,7.87,4.61,10.14,7.95,3.14,0.46,
4.43, 0.21, 4.75, 0.71, 1.52, 3.24, 4.43,0.21,4.75,0.71,1.52,3.24,
0.93, 0.42, 4.97, 9.53, 4.55, 0.47, 6.66] 0.93,0.42,4.97,9.53,4.55,0.47,6.66]
w, pw = stats.shapiro(x1) w,pw = stats.shapiro(x1)
assert_almost_equal(w, 0.90047299861907959, 6) assert_almost_equal(w,0.90047299861907959,6)
assert_almost_equal(pw, 0.042089745402336121, 6) assert_almost_equal(pw,0.042089745402336121,6)
x2 = [1.36, 1.14, 2.92, 2.55, 1.46, 1.06, 5.27, -1.11, x2 = [1.36,1.14,2.92,2.55,1.46,1.06,5.27,-1.11,
3.48, 1.10, 0.88, -0.51, 1.46, 0.52, 6.20, 1.69, 3.48,1.10,0.88,-0.51,1.46,0.52,6.20,1.69,
0.08, 3.67, 2.81, 3.49] 0.08,3.67,2.81,3.49]
w, pw = stats.shapiro(x2) w,pw = stats.shapiro(x2)
assert_almost_equal(w, 0.9590270, 6) assert_almost_equal(w,0.9590270,6)
assert_almost_equal(pw, 0.52460, 3) assert_almost_equal(pw,0.52460,3)
def test_bad_arg(self): def test_bad_arg(self):
# Length of x is less than 3. # Length of x is less than 3.
@ -59,25 +57,24 @@ class TestShapiro(TestCase):
class TestAnderson(TestCase): class TestAnderson(TestCase):
def test_normal(self): def test_normal(self):
rs = RandomState(1234567890) rs = RandomState(1234567890)
x1 = rs.standard_exponential(size=50) x1 = rs.standard_exponential(size=50)
x2 = rs.standard_normal(size=50) x2 = rs.standard_normal(size=50)
A, crit, _sig = stats.anderson(x1) A,crit,sig = stats.anderson(x1)
assert_array_less(crit[:-1], A) assert_array_less(crit[:-1], A)
A, crit, _sig = stats.anderson(x2) A,crit,sig = stats.anderson(x2)
assert_array_less(A, crit[-2:]) assert_array_less(A, crit[-2:])
def test_expon(self): def test_expon(self):
rs = RandomState(1234567890) rs = RandomState(1234567890)
x1 = rs.standard_exponential(size=50) x1 = rs.standard_exponential(size=50)
x2 = rs.standard_normal(size=50) x2 = rs.standard_normal(size=50)
A, crit, _sig = stats.anderson(x1, 'expon') A,crit,sig = stats.anderson(x1,'expon')
assert_array_less(A, crit[-2:]) assert_array_less(A, crit[-2:])
olderr = np.seterr(all='ignore') olderr = np.seterr(all='ignore')
try: try:
A, crit, _sig = stats.anderson(x2, 'expon') A,crit,sig = stats.anderson(x2,'expon')
finally: finally:
np.seterr(**olderr) np.seterr(**olderr)
assert_(A > crit[-1]) assert_(A > crit[-1])
@ -86,34 +83,150 @@ class TestAnderson(TestCase):
assert_raises(ValueError, stats.anderson, [1], dist='plate_of_shrimp') assert_raises(ValueError, stats.anderson, [1], dist='plate_of_shrimp')
class TestAndersonKSamp(TestCase):
def test_example1a(self):
# Example data from Scholz & Stephens (1987), originally
# published in Lehmann (1995, Nonparametrics, Statistical
# Methods Based on Ranks, p. 309)
# Pass a mixture of lists and arrays
t1 = [38.7, 41.5, 43.8, 44.5, 45.5, 46.0, 47.7, 58.0]
t2 = np.array([39.2, 39.3, 39.7, 41.4, 41.8, 42.9, 43.3, 45.8])
t3 = np.array([34.0, 35.0, 39.0, 40.0, 43.0, 43.0, 44.0, 45.0])
t4 = np.array([34.0, 34.8, 34.8, 35.4, 37.2, 37.8, 41.2, 42.8])
assert_warns(UserWarning, stats.anderson_ksamp, (t1, t2, t3, t4),
midrank=False)
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message='approximate p-value')
Tk, tm, p = stats.anderson_ksamp((t1, t2, t3, t4), midrank=False)
assert_almost_equal(Tk, 4.449, 3)
assert_array_almost_equal([0.4985, 1.3237, 1.9158, 2.4930, 3.2459],
tm, 4)
assert_almost_equal(p, 0.0021, 4)
def test_example1b(self):
# Example data from Scholz & Stephens (1987), originally
# published in Lehmann (1995, Nonparametrics, Statistical
# Methods Based on Ranks, p. 309)
# Pass arrays
t1 = np.array([38.7, 41.5, 43.8, 44.5, 45.5, 46.0, 47.7, 58.0])
t2 = np.array([39.2, 39.3, 39.7, 41.4, 41.8, 42.9, 43.3, 45.8])
t3 = np.array([34.0, 35.0, 39.0, 40.0, 43.0, 43.0, 44.0, 45.0])
t4 = np.array([34.0, 34.8, 34.8, 35.4, 37.2, 37.8, 41.2, 42.8])
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message='approximate p-value')
Tk, tm, p = stats.anderson_ksamp((t1, t2, t3, t4), midrank=True)
assert_almost_equal(Tk, 4.480, 3)
assert_array_almost_equal([0.4985, 1.3237, 1.9158, 2.4930, 3.2459],
tm, 4)
assert_almost_equal(p, 0.0020, 4)
def test_example2a(self):
# Example data taken from an earlier technical report of
# Scholz and Stephens
# Pass lists instead of arrays
t1 = [194, 15, 41, 29, 33, 181]
t2 = [413, 14, 58, 37, 100, 65, 9, 169, 447, 184, 36, 201, 118]
t3 = [34, 31, 18, 18, 67, 57, 62, 7, 22, 34]
t4 = [90, 10, 60, 186, 61, 49, 14, 24, 56, 20, 79, 84, 44, 59, 29,
118, 25, 156, 310, 76, 26, 44, 23, 62]
t5 = [130, 208, 70, 101, 208]
t6 = [74, 57, 48, 29, 502, 12, 70, 21, 29, 386, 59, 27]
t7 = [55, 320, 56, 104, 220, 239, 47, 246, 176, 182, 33]
t8 = [23, 261, 87, 7, 120, 14, 62, 47, 225, 71, 246, 21, 42, 20, 5,
12, 120, 11, 3, 14, 71, 11, 14, 11, 16, 90, 1, 16, 52, 95]
t9 = [97, 51, 11, 4, 141, 18, 142, 68, 77, 80, 1, 16, 106, 206, 82,
54, 31, 216, 46, 111, 39, 63, 18, 191, 18, 163, 24]
t10 = [50, 44, 102, 72, 22, 39, 3, 15, 197, 188, 79, 88, 46, 5, 5, 36,
22, 139, 210, 97, 30, 23, 13, 14]
t11 = [359, 9, 12, 270, 603, 3, 104, 2, 438]
t12 = [50, 254, 5, 283, 35, 12]
t13 = [487, 18, 100, 7, 98, 5, 85, 91, 43, 230, 3, 130]
t14 = [102, 209, 14, 57, 54, 32, 67, 59, 134, 152, 27, 14, 230, 66,
61, 34]
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message='approximate p-value')
Tk, tm, p = stats.anderson_ksamp((t1, t2, t3, t4, t5, t6, t7, t8,
t9, t10, t11, t12, t13, t14),
midrank=False)
assert_almost_equal(Tk, 3.288, 3)
assert_array_almost_equal([0.5990, 1.3269, 1.8052, 2.2486, 2.8009],
tm, 4)
assert_almost_equal(p, 0.0041, 4)
def test_example2b(self):
# Example data taken from an earlier technical report of
# Scholz and Stephens
t1 = [194, 15, 41, 29, 33, 181]
t2 = [413, 14, 58, 37, 100, 65, 9, 169, 447, 184, 36, 201, 118]
t3 = [34, 31, 18, 18, 67, 57, 62, 7, 22, 34]
t4 = [90, 10, 60, 186, 61, 49, 14, 24, 56, 20, 79, 84, 44, 59, 29,
118, 25, 156, 310, 76, 26, 44, 23, 62]
t5 = [130, 208, 70, 101, 208]
t6 = [74, 57, 48, 29, 502, 12, 70, 21, 29, 386, 59, 27]
t7 = [55, 320, 56, 104, 220, 239, 47, 246, 176, 182, 33]
t8 = [23, 261, 87, 7, 120, 14, 62, 47, 225, 71, 246, 21, 42, 20, 5,
12, 120, 11, 3, 14, 71, 11, 14, 11, 16, 90, 1, 16, 52, 95]
t9 = [97, 51, 11, 4, 141, 18, 142, 68, 77, 80, 1, 16, 106, 206, 82,
54, 31, 216, 46, 111, 39, 63, 18, 191, 18, 163, 24]
t10 = [50, 44, 102, 72, 22, 39, 3, 15, 197, 188, 79, 88, 46, 5, 5, 36,
22, 139, 210, 97, 30, 23, 13, 14]
t11 = [359, 9, 12, 270, 603, 3, 104, 2, 438]
t12 = [50, 254, 5, 283, 35, 12]
t13 = [487, 18, 100, 7, 98, 5, 85, 91, 43, 230, 3, 130]
t14 = [102, 209, 14, 57, 54, 32, 67, 59, 134, 152, 27, 14, 230, 66,
61, 34]
with warnings.catch_warnings():
warnings.filterwarnings('ignore', message='approximate p-value')
Tk, tm, p = stats.anderson_ksamp((t1, t2, t3, t4, t5, t6, t7, t8,
t9, t10, t11, t12, t13, t14),
midrank=True)
assert_almost_equal(Tk, 3.294, 3)
assert_array_almost_equal([0.5990, 1.3269, 1.8052, 2.2486, 2.8009],
tm, 4)
assert_almost_equal(p, 0.0041, 4)
def test_not_enough_samples(self):
assert_raises(ValueError, stats.anderson_ksamp, np.ones(5))
def test_no_distinct_observations(self):
assert_raises(ValueError, stats.anderson_ksamp,
(np.ones(5), np.ones(5)))
def test_empty_sample(self):
assert_raises(ValueError, stats.anderson_ksamp, (np.ones(5), []))
class TestAnsari(TestCase): class TestAnsari(TestCase):
def test_small(self): def test_small(self):
x = [1, 2, 3, 3, 4] x = [1,2,3,3,4]
y = [3, 2, 6, 1, 6, 1, 4, 1] y = [3,2,6,1,6,1,4,1]
W, pval = stats.ansari(x, y) W, pval = stats.ansari(x,y)
assert_almost_equal(W, 23.5, 11) assert_almost_equal(W,23.5,11)
assert_almost_equal(pval, 0.13499256881897437, 11) assert_almost_equal(pval,0.13499256881897437,11)
def test_approx(self): def test_approx(self):
ramsay = np.array((111, 107, 100, 99, 102, 106, 109, 108, 104, 99, ramsay = np.array((111, 107, 100, 99, 102, 106, 109, 108, 104, 99,
101, 96, 97, 102, 107, 113, 116, 113, 110, 98)) 101, 96, 97, 102, 107, 113, 116, 113, 110, 98))
parekh = np.array((107, 108, 106, 98, 105, 103, 110, 105, 104, 100, parekh = np.array((107, 108, 106, 98, 105, 103, 110, 105, 104,
96, 108, 103, 104, 114, 114, 113, 108, 106, 99)) 100, 96, 108, 103, 104, 114, 114, 113, 108, 106, 99))
with warnings.catch_warnings(): with warnings.catch_warnings():
warnings.filterwarnings('ignore', warnings.filterwarnings('ignore',
message="Ties preclude use of exact " + message="Ties preclude use of exact statistic.")
"statistic.")
W, pval = stats.ansari(ramsay, parekh) W, pval = stats.ansari(ramsay, parekh)
assert_almost_equal(W, 185.5, 11) assert_almost_equal(W,185.5,11)
assert_almost_equal(pval, 0.18145819972867083, 11) assert_almost_equal(pval,0.18145819972867083,11)
def test_exact(self): def test_exact(self):
W, pval = stats.ansari([1, 2, 3, 4], [15, 5, 20, 8, 10, 12]) W,pval = stats.ansari([1,2,3,4],[15,5,20,8,10,12])
assert_almost_equal(W, 10.0, 11) assert_almost_equal(W,10.0,11)
assert_almost_equal(pval, 0.533333333333333333, 7) assert_almost_equal(pval,0.533333333333333333,7)
def test_bad_arg(self): def test_bad_arg(self):
assert_raises(ValueError, stats.ansari, [], [1]) assert_raises(ValueError, stats.ansari, [], [1])
@ -125,8 +238,8 @@ class TestBartlett(TestCase):
def test_data(self): def test_data(self):
args = [g1, g2, g3, g4, g5, g6, g7, g8, g9, g10] args = [g1, g2, g3, g4, g5, g6, g7, g8, g9, g10]
T, pval = stats.bartlett(*args) T, pval = stats.bartlett(*args)
assert_almost_equal(T, 20.78587342806484, 7) assert_almost_equal(T,20.78587342806484,7)
assert_almost_equal(pval, 0.0136358632781, 7) assert_almost_equal(pval,0.0136358632781,7)
def test_bad_arg(self): def test_bad_arg(self):
# Too few args raises ValueError. # Too few args raises ValueError.
@ -138,15 +251,14 @@ class TestLevene(TestCase):
def test_data(self): def test_data(self):
args = [g1, g2, g3, g4, g5, g6, g7, g8, g9, g10] args = [g1, g2, g3, g4, g5, g6, g7, g8, g9, g10]
W, pval = stats.levene(*args) W, pval = stats.levene(*args)
assert_almost_equal(W, 1.7059176930008939, 7) assert_almost_equal(W,1.7059176930008939,7)
assert_almost_equal(pval, 0.0990829755522, 7) assert_almost_equal(pval,0.0990829755522,7)
def test_trimmed1(self): def test_trimmed1(self):
# Test that center='trimmed' gives the same result as center='mean' # Test that center='trimmed' gives the same result as center='mean'
# when proportiontocut=0. # when proportiontocut=0.
W1, pval1 = stats.levene(g1, g2, g3, center='mean') W1, pval1 = stats.levene(g1, g2, g3, center='mean')
W2, pval2 = stats.levene( W2, pval2 = stats.levene(g1, g2, g3, center='trimmed', proportiontocut=0.0)
g1, g2, g3, center='trimmed', proportiontocut=0.0)
assert_almost_equal(W1, W2) assert_almost_equal(W1, W2)
assert_almost_equal(pval1, pval2) assert_almost_equal(pval1, pval2)
@ -157,10 +269,8 @@ class TestLevene(TestCase):
x2 = np.random.permutation(x) x2 = np.random.permutation(x)
# Use center='trimmed' # Use center='trimmed'
W0, _pval0 = stats.levene(x, y, center='trimmed', W0, pval0 = stats.levene(x, y, center='trimmed', proportiontocut=0.125)
proportiontocut=0.125) W1, pval1 = stats.levene(x2, y, center='trimmed', proportiontocut=0.125)
W1, pval1 = stats.levene(
x2, y, center='trimmed', proportiontocut=0.125)
# Trim the data here, and use center='mean' # Trim the data here, and use center='mean'
W2, pval2 = stats.levene(x[1:-1], y[1:-1], center='mean') W2, pval2 = stats.levene(x[1:-1], y[1:-1], center='mean')
# Result should be the same. # Result should be the same.
@ -169,21 +279,21 @@ class TestLevene(TestCase):
assert_almost_equal(pval1, pval2) assert_almost_equal(pval1, pval2)
def test_equal_mean_median(self): def test_equal_mean_median(self):
x = np.linspace(-1, 1, 21) x = np.linspace(-1,1,21)
np.random.seed(1234) np.random.seed(1234)
x2 = np.random.permutation(x) x2 = np.random.permutation(x)
y = x ** 3 y = x**3
W1, pval1 = stats.levene(x, y, center='mean') W1, pval1 = stats.levene(x, y, center='mean')
W2, pval2 = stats.levene(x2, y, center='median') W2, pval2 = stats.levene(x2, y, center='median')
assert_almost_equal(W1, W2) assert_almost_equal(W1, W2)
assert_almost_equal(pval1, pval2) assert_almost_equal(pval1, pval2)
def test_bad_keyword(self): def test_bad_keyword(self):
x = np.linspace(-1, 1, 21) x = np.linspace(-1,1,21)
assert_raises(TypeError, stats.levene, x, x, portiontocut=0.1) assert_raises(TypeError, stats.levene, x, x, portiontocut=0.1)
def test_bad_center_value(self): def test_bad_center_value(self):
x = np.linspace(-1, 1, 21) x = np.linspace(-1,1,21)
assert_raises(ValueError, stats.levene, x, x, center='trim') assert_raises(ValueError, stats.levene, x, x, center='trim')
def test_too_few_args(self): def test_too_few_args(self):
@ -193,16 +303,16 @@ class TestLevene(TestCase):
class TestBinomP(TestCase): class TestBinomP(TestCase):
def test_data(self): def test_data(self):
pval = stats.binom_test(100, 250) pval = stats.binom_test(100,250)
assert_almost_equal(pval, 0.0018833009350757682, 11) assert_almost_equal(pval,0.0018833009350757682,11)
pval = stats.binom_test(201, 405) pval = stats.binom_test(201,405)
assert_almost_equal(pval, 0.92085205962670713, 11) assert_almost_equal(pval,0.92085205962670713,11)
pval = stats.binom_test([682, 243], p=3.0 / 4) pval = stats.binom_test([682,243],p=3.0/4)
assert_almost_equal(pval, 0.38249155957481695, 11) assert_almost_equal(pval,0.38249155957481695,11)
def test_bad_len_x(self): def test_bad_len_x(self):
# Length of x must be 1 or 2. # Length of x must be 1 or 2.
assert_raises(ValueError, stats.binom_test, [1, 2, 3]) assert_raises(ValueError, stats.binom_test, [1,2,3])
def test_bad_n(self): def test_bad_n(self):
# len(x) is 1, but n is invalid. # len(x) is 1, but n is invalid.
@ -218,10 +328,10 @@ class TestBinomP(TestCase):
class TestFindRepeats(TestCase): class TestFindRepeats(TestCase):
def test_basic(self): def test_basic(self):
a = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 5] a = [1,2,3,4,1,2,3,4,1,2,5]
res, nums = stats.find_repeats(a) res,nums = stats.find_repeats(a)
assert_array_equal(res, [1, 2, 3, 4]) assert_array_equal(res,[1,2,3,4])
assert_array_equal(nums, [3, 3, 2, 2]) assert_array_equal(nums,[3,3,2,2])
def test_empty_result(self): def test_empty_result(self):
# Check that empty arrays are returned when there are no repeats. # Check that empty arrays are returned when there are no repeats.
@ -236,16 +346,14 @@ class TestFligner(TestCase):
def test_data(self): def test_data(self):
# numbers from R: fligner.test in package stats # numbers from R: fligner.test in package stats
x1 = np.arange(5) x1 = np.arange(5)
assert_array_almost_equal(stats.fligner(x1, x1 ** 2), assert_array_almost_equal(stats.fligner(x1,x1**2),
(3.2282229927203536, 0.072379187848207877), (3.2282229927203536, 0.072379187848207877), 11)
11)
def test_trimmed1(self): def test_trimmed1(self):
# Test that center='trimmed' gives the same result as center='mean' # Test that center='trimmed' gives the same result as center='mean'
# when proportiontocut=0. # when proportiontocut=0.
Xsq1, pval1 = stats.fligner(g1, g2, g3, center='mean') Xsq1, pval1 = stats.fligner(g1, g2, g3, center='mean')
Xsq2, pval2 = stats.fligner( Xsq2, pval2 = stats.fligner(g1, g2, g3, center='trimmed', proportiontocut=0.0)
g1, g2, g3, center='trimmed', proportiontocut=0.0)
assert_almost_equal(Xsq1, Xsq2) assert_almost_equal(Xsq1, Xsq2)
assert_almost_equal(pval1, pval2) assert_almost_equal(pval1, pval2)
@ -253,8 +361,7 @@ class TestFligner(TestCase):
x = [1.2, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 100.0] x = [1.2, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 100.0]
y = [0.0, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 200.0] y = [0.0, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 200.0]
# Use center='trimmed' # Use center='trimmed'
Xsq1, pval1 = stats.fligner( Xsq1, pval1 = stats.fligner(x, y, center='trimmed', proportiontocut=0.125)
x, y, center='trimmed', proportiontocut=0.125)
# Trim the data here, and use center='mean' # Trim the data here, and use center='mean'
Xsq2, pval2 = stats.fligner(x[1:-1], y[1:-1], center='mean') Xsq2, pval2 = stats.fligner(x[1:-1], y[1:-1], center='mean')
# Result should be the same. # Result should be the same.
@ -267,7 +374,7 @@ class TestFligner(TestCase):
# errors) there are not. This difference leads to differences in the # errors) there are not. This difference leads to differences in the
# third significant digit of W. # third significant digit of W.
# #
# def test_equal_mean_median(self): #def test_equal_mean_median(self):
# x = np.linspace(-1,1,21) # x = np.linspace(-1,1,21)
# y = x**3 # y = x**3
# W1, pval1 = stats.fligner(x, y, center='mean') # W1, pval1 = stats.fligner(x, y, center='mean')
@ -276,11 +383,11 @@ class TestFligner(TestCase):
# assert_almost_equal(pval1, pval2) # assert_almost_equal(pval1, pval2)
def test_bad_keyword(self): def test_bad_keyword(self):
x = np.linspace(-1, 1, 21) x = np.linspace(-1,1,21)
assert_raises(TypeError, stats.fligner, x, x, portiontocut=0.1) assert_raises(TypeError, stats.fligner, x, x, portiontocut=0.1)
def test_bad_center_value(self): def test_bad_center_value(self):
x = np.linspace(-1, 1, 21) x = np.linspace(-1,1,21)
assert_raises(ValueError, stats.fligner, x, x, center='trim') assert_raises(ValueError, stats.fligner, x, x, center='trim')
def test_bad_num_args(self): def test_bad_num_args(self):
@ -289,13 +396,11 @@ class TestFligner(TestCase):
class TestMood(TestCase): class TestMood(TestCase):
def test_mood(self): def test_mood(self):
# numbers from R: mood.test in package stats # numbers from R: mood.test in package stats
x1 = np.arange(5) x1 = np.arange(5)
assert_array_almost_equal(stats.mood(x1, x1 ** 2), assert_array_almost_equal(stats.mood(x1, x1**2),
(-1.3830857299399906, 0.16663858066771478), (-1.3830857299399906, 0.16663858066771478), 11)
11)
def test_mood_order_of_args(self): def test_mood_order_of_args(self):
# z should change sign when the order of arguments changes, pvalue # z should change sign when the order of arguments changes, pvalue
@ -308,24 +413,24 @@ class TestMood(TestCase):
assert_array_almost_equal([z1, p1], [-z2, p2]) assert_array_almost_equal([z1, p1], [-z2, p2])
def test_mood_with_axis_none(self): def test_mood_with_axis_none(self):
# Test with axis = None, compare with results from R #Test with axis = None, compare with results from R
x1 = [-0.626453810742332, 0.183643324222082, -0.835628612410047, x1 = [-0.626453810742332, 0.183643324222082, -0.835628612410047,
1.59528080213779, 0.329507771815361, -0.820468384118015, 1.59528080213779, 0.329507771815361, -0.820468384118015,
0.487429052428485, 0.738324705129217, 0.575781351653492, 0.487429052428485, 0.738324705129217, 0.575781351653492,
-0.305388387156356, 1.51178116845085, 0.389843236411431, -0.305388387156356, 1.51178116845085, 0.389843236411431,
-0.621240580541804, -2.2146998871775, 1.12493091814311, -0.621240580541804, -2.2146998871775, 1.12493091814311,
-0.0449336090152309, -0.0161902630989461, 0.943836210685299, -0.0449336090152309, -0.0161902630989461, 0.943836210685299,
0.821221195098089, 0.593901321217509] 0.821221195098089, 0.593901321217509]
x2 = [-0.896914546624981, 0.184849184646742, 1.58784533120882, x2 = [-0.896914546624981, 0.184849184646742, 1.58784533120882,
-1.13037567424629, -0.0802517565509893, 0.132420284381094, -1.13037567424629, -0.0802517565509893, 0.132420284381094,
0.707954729271733, -0.23969802417184, 1.98447393665293, 0.707954729271733, -0.23969802417184, 1.98447393665293,
-0.138787012119665, 0.417650750792556, 0.981752777463662, -0.138787012119665, 0.417650750792556, 0.981752777463662,
-0.392695355503813, -1.03966897694891, 1.78222896030858, -0.392695355503813, -1.03966897694891, 1.78222896030858,
-2.31106908460517, 0.878604580921265, 0.035806718015226, -2.31106908460517, 0.878604580921265, 0.035806718015226,
1.01282869212708, 0.432265154539617, 2.09081920524915, 1.01282869212708, 0.432265154539617, 2.09081920524915,
-1.19992581964387, 1.58963820029007, 1.95465164222325, -1.19992581964387, 1.58963820029007, 1.95465164222325,
0.00493777682814261, -2.45170638784613, 0.477237302613617, 0.00493777682814261, -2.45170638784613, 0.477237302613617,
-0.596558168631403, 0.792203270299649, 0.289636710177348] -0.596558168631403, 0.792203270299649, 0.289636710177348]
x1 = np.array(x1) x1 = np.array(x1)
@ -387,8 +492,7 @@ class TestMood(TestCase):
stats.mood(slice1, slice2)) stats.mood(slice1, slice2))
def test_mood_bad_arg(self): def test_mood_bad_arg(self):
# Raise ValueError when the sum of the lengths of the args is less than # Raise ValueError when the sum of the lengths of the args is less than 3
# 3
assert_raises(ValueError, stats.mood, [1], []) assert_raises(ValueError, stats.mood, [1], [])
@ -406,7 +510,7 @@ class TestProbplot(TestCase):
assert_allclose(osr, np.sort(x)) assert_allclose(osr, np.sort(x))
assert_allclose(osm, osm_expected) assert_allclose(osm, osm_expected)
_res, res_fit = stats.probplot(x, fit=True) res, res_fit = stats.probplot(x, fit=True)
res_fit_expected = [1.05361841, 0.31297795, 0.98741609] res_fit_expected = [1.05361841, 0.31297795, 0.98741609]
assert_allclose(res_fit, res_fit_expected) assert_allclose(res_fit, res_fit_expected)
@ -423,7 +527,7 @@ class TestProbplot(TestCase):
assert_allclose(osr1, osr2) assert_allclose(osr1, osr2)
assert_allclose(osr1, osr3) assert_allclose(osr1, osr3)
# Check giving (loc, scale) params for normal distribution # Check giving (loc, scale) params for normal distribution
_osm, _osr = stats.probplot(x, sparams=(), fit=False) osm, osr = stats.probplot(x, sparams=(), fit=False)
def test_dist_keyword(self): def test_dist_keyword(self):
np.random.seed(12345) np.random.seed(12345)
@ -437,9 +541,7 @@ class TestProbplot(TestCase):
assert_raises(AttributeError, stats.probplot, x, dist=[]) assert_raises(AttributeError, stats.probplot, x, dist=[])
class custom_dist(object): class custom_dist(object):
"""Some class that looks just enough like a distribution.""" """Some class that looks just enough like a distribution."""
def ppf(self, q): def ppf(self, q):
return stats.norm.ppf(q, loc=2) return stats.norm.ppf(q, loc=2)
@ -482,8 +584,8 @@ class TestProbplot(TestCase):
def test_wilcoxon_bad_arg(): def test_wilcoxon_bad_arg():
# Raise ValueError when two args of different lengths are given or # Raise ValueError when two args of different lengths are given or
# zero_method is unknown. # zero_method is unknown.
assert_raises(ValueError, stats.wilcoxon, [1], [1, 2]) assert_raises(ValueError, stats.wilcoxon, [1], [1,2])
assert_raises(ValueError, stats.wilcoxon, [1, 2], [1, 2], "dummy") assert_raises(ValueError, stats.wilcoxon, [1,2], [1,2], "dummy")
def test_mvsdist_bad_arg(): def test_mvsdist_bad_arg():
@ -519,7 +621,7 @@ class TestBoxcox_llf(TestCase):
x = stats.norm.rvs(size=10000, loc=10) x = stats.norm.rvs(size=10000, loc=10)
lmbda = 1 lmbda = 1
llf = stats.boxcox_llf(lmbda, x) llf = stats.boxcox_llf(lmbda, x)
llf_expected = -x.size / 2. * np.log(np.sum(x.std() ** 2)) llf_expected = -x.size / 2. * np.log(np.sum(x.std()**2))
assert_allclose(llf, llf_expected) assert_allclose(llf, llf_expected)
def test_array_like(self): def test_array_like(self):
@ -553,7 +655,7 @@ class TestBoxcox(TestCase):
xt = stats.boxcox(x, lmbda=1) xt = stats.boxcox(x, lmbda=1)
assert_allclose(xt, x - 1) assert_allclose(xt, x - 1)
xt = stats.boxcox(x, lmbda=-1) xt = stats.boxcox(x, lmbda=-1)
assert_allclose(xt, 1 - 1 / x) assert_allclose(xt, 1 - 1/x)
xt = stats.boxcox(x, lmbda=0) xt = stats.boxcox(x, lmbda=0)
assert_allclose(xt, np.log(x)) assert_allclose(xt, np.log(x))
@ -569,8 +671,8 @@ class TestBoxcox(TestCase):
np.random.seed(1245) np.random.seed(1245)
lmbda = 2.5 lmbda = 2.5
x = stats.norm.rvs(loc=10, size=50000) x = stats.norm.rvs(loc=10, size=50000)
x_inv = (x * lmbda + 1) ** (-lmbda) x_inv = (x * lmbda + 1)**(-lmbda)
_xt, maxlog = stats.boxcox(x_inv) xt, maxlog = stats.boxcox(x_inv)
assert_almost_equal(maxlog, -1 / lmbda, decimal=2) assert_almost_equal(maxlog, -1 / lmbda, decimal=2)
@ -601,18 +703,17 @@ class TestBoxcox(TestCase):
class TestBoxcoxNormmax(TestCase): class TestBoxcoxNormmax(TestCase):
def setUp(self): def setUp(self):
np.random.seed(12345) np.random.seed(12345)
self.x = stats.loggamma.rvs(5, size=50) + 5 self.x = stats.loggamma.rvs(5, size=50) + 5
def test_pearsonr(self): def test_pearsonr(self):
maxlog = stats.boxcox_normmax(self.x) maxlog = stats.boxcox_normmax(self.x)
assert_allclose(maxlog, 1.804465325046) assert_allclose(maxlog, 1.804465, rtol=1e-6)
def test_mle(self): def test_mle(self):
maxlog = stats.boxcox_normmax(self.x, method='mle') maxlog = stats.boxcox_normmax(self.x, method='mle')
assert_allclose(maxlog, 1.758101454114) assert_allclose(maxlog, 1.758101, rtol=1e-6)
# Check that boxcox() uses 'mle' # Check that boxcox() uses 'mle'
_, maxlog_boxcox = stats.boxcox(self.x) _, maxlog_boxcox = stats.boxcox(self.x)
@ -620,11 +721,10 @@ class TestBoxcoxNormmax(TestCase):
def test_all(self): def test_all(self):
maxlog_all = stats.boxcox_normmax(self.x, method='all') maxlog_all = stats.boxcox_normmax(self.x, method='all')
assert_allclose(maxlog_all, [1.804465325046, 1.758101454114]) assert_allclose(maxlog_all, [1.804465, 1.758101], rtol=1e-6)
class TestBoxcoxNormplot(TestCase): class TestBoxcoxNormplot(TestCase):
def setUp(self): def setUp(self):
np.random.seed(7654321) np.random.seed(7654321)
self.x = stats.loggamma.rvs(5, size=500) + 5 self.x = stats.loggamma.rvs(5, size=500) + 5
@ -662,9 +762,8 @@ class TestBoxcoxNormplot(TestCase):
class TestCircFuncs(TestCase): class TestCircFuncs(TestCase):
def test_circfuncs(self): def test_circfuncs(self):
x = np.array([355, 5, 2, 359, 10, 350]) x = np.array([355,5,2,359,10,350])
M = stats.circmean(x, high=360) M = stats.circmean(x, high=360)
Mval = 0.167690146 Mval = 0.167690146
assert_allclose(M, Mval, rtol=1e-7) assert_allclose(M, Mval, rtol=1e-7)
@ -678,7 +777,7 @@ class TestCircFuncs(TestCase):
assert_allclose(S, Sval, rtol=1e-7) assert_allclose(S, Sval, rtol=1e-7)
def test_circfuncs_small(self): def test_circfuncs_small(self):
x = np.array([20, 21, 22, 18, 19, 20.5, 19.2]) x = np.array([20,21,22,18,19,20.5,19.2])
M1 = x.mean() M1 = x.mean()
M2 = stats.circmean(x, high=360) M2 = stats.circmean(x, high=360)
assert_allclose(M2, M1, rtol=1e-5) assert_allclose(M2, M1, rtol=1e-5)
@ -692,9 +791,9 @@ class TestCircFuncs(TestCase):
assert_allclose(S2, S1, rtol=1e-4) assert_allclose(S2, S1, rtol=1e-4)
def test_circmean_axis(self): def test_circmean_axis(self):
x = np.array([[355, 5, 2, 359, 10, 350], x = np.array([[355,5,2,359,10,350],
[351, 7, 4, 352, 9, 349], [351,7,4,352,9,349],
[357, 9, 8, 358, 4, 356]]) [357,9,8,358,4,356]])
M1 = stats.circmean(x, high=360) M1 = stats.circmean(x, high=360)
M2 = stats.circmean(x.ravel(), high=360) M2 = stats.circmean(x.ravel(), high=360)
assert_allclose(M1, M2, rtol=1e-14) assert_allclose(M1, M2, rtol=1e-14)
@ -704,13 +803,13 @@ class TestCircFuncs(TestCase):
assert_allclose(M1, M2, rtol=1e-14) assert_allclose(M1, M2, rtol=1e-14)
M1 = stats.circmean(x, high=360, axis=0) M1 = stats.circmean(x, high=360, axis=0)
M2 = [stats.circmean(x[:, i], high=360) for i in range(x.shape[1])] M2 = [stats.circmean(x[:,i], high=360) for i in range(x.shape[1])]
assert_allclose(M1, M2, rtol=1e-14) assert_allclose(M1, M2, rtol=1e-14)
def test_circvar_axis(self): def test_circvar_axis(self):
x = np.array([[355, 5, 2, 359, 10, 350], x = np.array([[355,5,2,359,10,350],
[351, 7, 4, 352, 9, 349], [351,7,4,352,9,349],
[357, 9, 8, 358, 4, 356]]) [357,9,8,358,4,356]])
V1 = stats.circvar(x, high=360) V1 = stats.circvar(x, high=360)
V2 = stats.circvar(x.ravel(), high=360) V2 = stats.circvar(x.ravel(), high=360)
@ -721,13 +820,13 @@ class TestCircFuncs(TestCase):
assert_allclose(V1, V2, rtol=1e-11) assert_allclose(V1, V2, rtol=1e-11)
V1 = stats.circvar(x, high=360, axis=0) V1 = stats.circvar(x, high=360, axis=0)
V2 = [stats.circvar(x[:, i], high=360) for i in range(x.shape[1])] V2 = [stats.circvar(x[:,i], high=360) for i in range(x.shape[1])]
assert_allclose(V1, V2, rtol=1e-11) assert_allclose(V1, V2, rtol=1e-11)
def test_circstd_axis(self): def test_circstd_axis(self):
x = np.array([[355, 5, 2, 359, 10, 350], x = np.array([[355,5,2,359,10,350],
[351, 7, 4, 352, 9, 349], [351,7,4,352,9,349],
[357, 9, 8, 358, 4, 356]]) [357,9,8,358,4,356]])
S1 = stats.circstd(x, high=360) S1 = stats.circstd(x, high=360)
S2 = stats.circstd(x.ravel(), high=360) S2 = stats.circstd(x.ravel(), high=360)
@ -738,11 +837,11 @@ class TestCircFuncs(TestCase):
assert_allclose(S1, S2, rtol=1e-11) assert_allclose(S1, S2, rtol=1e-11)
S1 = stats.circstd(x, high=360, axis=0) S1 = stats.circstd(x, high=360, axis=0)
S2 = [stats.circstd(x[:, i], high=360) for i in range(x.shape[1])] S2 = [stats.circstd(x[:,i], high=360) for i in range(x.shape[1])]
assert_allclose(S1, S2, rtol=1e-11) assert_allclose(S1, S2, rtol=1e-11)
def test_circfuncs_array_like(self): def test_circfuncs_array_like(self):
x = [355, 5, 2, 359, 10, 350] x = [355,5,2,359,10,350]
assert_allclose(stats.circmean(x, high=360), 0.167690146, rtol=1e-7) assert_allclose(stats.circmean(x, high=360), 0.167690146, rtol=1e-7)
assert_allclose(stats.circvar(x, high=360), 42.51955609, rtol=1e-7) assert_allclose(stats.circvar(x, high=360), 42.51955609, rtol=1e-7)
assert_allclose(stats.circstd(x, high=360), 6.520702116, rtol=1e-7) assert_allclose(stats.circstd(x, high=360), 6.520702116, rtol=1e-7)
@ -803,5 +902,108 @@ def test_wilcoxon_tie():
assert_allclose(p, expected_p, rtol=1e-6) assert_allclose(p, expected_p, rtol=1e-6)
class TestMedianTest(TestCase):
def test_bad_n_samples(self):
# median_test requires at least two samples.
assert_raises(ValueError, stats.median_test, [1, 2, 3])
def test_empty_sample(self):
# Each sample must contain at least one value.
assert_raises(ValueError, stats.median_test, [], [1, 2, 3])
def test_empty_when_ties_ignored(self):
# The grand median is 1, and all values in the first argument are
# equal to the grand median. With ties="ignore", those values are
# ignored, which results in the first sample being (in effect) empty.
# This should raise a ValueError.
assert_raises(ValueError, stats.median_test,
[1, 1, 1, 1], [2, 0, 1], [2, 0], ties="ignore")
def test_empty_contingency_row(self):
# The grand median is 1, and with the default ties="below", all the
# values in the samples are counted as being below the grand median.
# This would result a row of zeros in the contingency table, which is
# an error.
assert_raises(ValueError, stats.median_test, [1, 1, 1], [1, 1, 1])
# With ties="above", all the values are counted as above the
# grand median.
assert_raises(ValueError, stats.median_test, [1, 1, 1], [1, 1, 1],
ties="above")
def test_bad_ties(self):
assert_raises(ValueError, stats.median_test, [1, 2, 3], [4, 5], ties="foo")
def test_bad_keyword(self):
assert_raises(TypeError, stats.median_test, [1, 2, 3], [4, 5], foo="foo")
def test_simple(self):
x = [1, 2, 3]
y = [1, 2, 3]
stat, p, med, tbl = stats.median_test(x, y)
# The median is floating point, but this equality test should be safe.
assert_equal(med, 2.0)
assert_array_equal(tbl, [[1, 1], [2, 2]])
# The expected values of the contingency table equal the contingency table,
# so the statistic should be 0 and the p-value should be 1.
assert_equal(stat, 0)
assert_equal(p, 1)
def test_ties_options(self):
# Test the contingency table calculation.
x = [1, 2, 3, 4]
y = [5, 6]
z = [7, 8, 9]
# grand median is 5.
# Default 'ties' option is "below".
stat, p, m, tbl = stats.median_test(x, y, z)
assert_equal(m, 5)
assert_equal(tbl, [[0, 1, 3], [4, 1, 0]])
stat, p, m, tbl = stats.median_test(x, y, z, ties="ignore")
assert_equal(m, 5)
assert_equal(tbl, [[0, 1, 3], [4, 0, 0]])
stat, p, m, tbl = stats.median_test(x, y, z, ties="above")
assert_equal(m, 5)
assert_equal(tbl, [[0, 2, 3], [4, 0, 0]])
def test_basic(self):
# median_test calls chi2_contingency to compute the test statistic
# and p-value. Make sure it hasn't screwed up the call...
x = [1, 2, 3, 4, 5]
y = [2, 4, 6, 8]
stat, p, m, tbl = stats.median_test(x, y)
assert_equal(m, 4)
assert_equal(tbl, [[1, 2], [4, 2]])
exp_stat, exp_p, dof, e = stats.chi2_contingency(tbl)
assert_allclose(stat, exp_stat)
assert_allclose(p, exp_p)
stat, p, m, tbl = stats.median_test(x, y, lambda_=0)
assert_equal(m, 4)
assert_equal(tbl, [[1, 2], [4, 2]])
exp_stat, exp_p, dof, e = stats.chi2_contingency(tbl, lambda_=0)
assert_allclose(stat, exp_stat)
assert_allclose(p, exp_p)
stat, p, m, tbl = stats.median_test(x, y, correction=False)
assert_equal(m, 4)
assert_equal(tbl, [[1, 2], [4, 2]])
exp_stat, exp_p, dof, e = stats.chi2_contingency(tbl, correction=False)
assert_allclose(stat, exp_stat)
assert_allclose(p, exp_p)
if __name__ == "__main__": if __name__ == "__main__":
run_module_suite() run_module_suite()

File diff suppressed because it is too large Load Diff

@ -4,22 +4,34 @@ Test functions for multivariate normal distributions.
""" """
from __future__ import division, print_function, absolute_import from __future__ import division, print_function, absolute_import
from numpy.testing import (assert_almost_equal, from numpy.testing import (
run_module_suite, assert_allclose, assert_equal, assert_raises) assert_allclose,
assert_almost_equal,
assert_array_almost_equal,
assert_equal,
assert_raises,
run_module_suite,
)
import numpy import numpy
import numpy as np import numpy as np
import scipy.linalg import scipy.linalg
#import wafo.stats._multivariate from wafo.stats._multivariate import _PSD, _lnB
from wafo.stats import multivariate_normal from wafo.stats import multivariate_normal
from wafo.stats import dirichlet, beta
from wafo.stats import norm from wafo.stats import norm
from wafo.stats._multivariate import _psd_pinv_decomposed_log_pdet
from scipy.integrate import romb from scipy.integrate import romb
def test_input_shape():
mu = np.arange(3)
cov = np.identity(2)
assert_raises(ValueError, multivariate_normal.pdf, (0, 1), mu, cov)
assert_raises(ValueError, multivariate_normal.pdf, (0, 1, 2), mu, cov)
def test_scalar_values(): def test_scalar_values():
np.random.seed(1234) np.random.seed(1234)
@ -47,6 +59,63 @@ def test_logpdf():
assert_allclose(d1, np.log(d2)) assert_allclose(d1, np.log(d2))
def test_rank():
# Check that the rank is detected correctly.
np.random.seed(1234)
n = 4
mean = np.random.randn(n)
for expected_rank in range(1, n + 1):
s = np.random.randn(n, expected_rank)
cov = np.dot(s, s.T)
distn = multivariate_normal(mean, cov, allow_singular=True)
assert_equal(distn.cov_info.rank, expected_rank)
def _sample_orthonormal_matrix(n):
M = np.random.randn(n, n)
u, s, v = scipy.linalg.svd(M)
return u
def test_degenerate_distributions():
for n in range(1, 5):
x = np.random.randn(n)
for k in range(1, n + 1):
# Sample a small covariance matrix.
s = np.random.randn(k, k)
cov_kk = np.dot(s, s.T)
# Embed the small covariance matrix into a larger low rank matrix.
cov_nn = np.zeros((n, n))
cov_nn[:k, :k] = cov_kk
# Define a rotation of the larger low rank matrix.
u = _sample_orthonormal_matrix(n)
cov_rr = np.dot(u, np.dot(cov_nn, u.T))
y = np.dot(u, x)
# Check some identities.
distn_kk = multivariate_normal(np.zeros(k), cov_kk,
allow_singular=True)
distn_nn = multivariate_normal(np.zeros(n), cov_nn,
allow_singular=True)
distn_rr = multivariate_normal(np.zeros(n), cov_rr,
allow_singular=True)
assert_equal(distn_kk.cov_info.rank, k)
assert_equal(distn_nn.cov_info.rank, k)
assert_equal(distn_rr.cov_info.rank, k)
pdf_kk = distn_kk.pdf(x[:k])
pdf_nn = distn_nn.pdf(x)
pdf_rr = distn_rr.pdf(y)
assert_allclose(pdf_kk, pdf_nn)
assert_allclose(pdf_kk, pdf_rr)
logpdf_kk = distn_kk.logpdf(x[:k])
logpdf_nn = distn_nn.logpdf(x)
logpdf_rr = distn_rr.logpdf(y)
assert_allclose(logpdf_kk, logpdf_nn)
assert_allclose(logpdf_kk, logpdf_rr)
def test_large_pseudo_determinant(): def test_large_pseudo_determinant():
# Check that large pseudo-determinants are handled appropriately. # Check that large pseudo-determinants are handled appropriately.
@ -67,11 +136,12 @@ def test_large_pseudo_determinant():
# np.linalg.slogdet is only available in numpy 1.6+ # np.linalg.slogdet is only available in numpy 1.6+
# but scipy currently supports numpy 1.5.1. # but scipy currently supports numpy 1.5.1.
#assert_allclose(np.linalg.slogdet(cov[:npos, :npos]), (1, large_total_log)) # assert_allclose(np.linalg.slogdet(cov[:npos, :npos]),
# (1, large_total_log))
# Check the pseudo-determinant. # Check the pseudo-determinant.
U, log_pdet = _psd_pinv_decomposed_log_pdet(cov) psd = _PSD(cov)
assert_allclose(log_pdet, large_total_log) assert_allclose(psd.log_pdet, large_total_log)
def test_broadcasting(): def test_broadcasting():
@ -111,7 +181,7 @@ def test_marginalization():
# yield a 1D Gaussian # yield a 1D Gaussian
mean = np.array([2.5, 3.5]) mean = np.array([2.5, 3.5])
cov = np.array([[.5, 0.2], [0.2, .6]]) cov = np.array([[.5, 0.2], [0.2, .6]])
n = 2**8 + 1 # Number of samples n = 2 ** 8 + 1 # Number of samples
delta = 6 / (n - 1) # Grid spacing delta = 6 / (n - 1) # Grid spacing
v = np.linspace(0, 6, n) v = np.linspace(0, 6, n)
@ -126,8 +196,8 @@ def test_marginalization():
margin_y = romb(pdf, delta, axis=1) margin_y = romb(pdf, delta, axis=1)
# Compare with standard normal distribution # Compare with standard normal distribution
gauss_x = norm.pdf(v, loc=mean[0], scale=cov[0, 0]**0.5) gauss_x = norm.pdf(v, loc=mean[0], scale=cov[0, 0] ** 0.5)
gauss_y = norm.pdf(v, loc=mean[1], scale=cov[1, 1]**0.5) gauss_y = norm.pdf(v, loc=mean[1], scale=cov[1, 1] ** 0.5)
assert_allclose(margin_x, gauss_x, rtol=1e-2, atol=1e-2) assert_allclose(margin_x, gauss_x, rtol=1e-2, atol=1e-2)
assert_allclose(margin_y, gauss_y, rtol=1e-2, atol=1e-2) assert_allclose(margin_y, gauss_y, rtol=1e-2, atol=1e-2)
@ -160,33 +230,43 @@ def test_pseudodet_pinv():
# Set cond so that the lowest eigenvalue is below the cutoff # Set cond so that the lowest eigenvalue is below the cutoff
cond = 1e-5 cond = 1e-5
U, log_pdet = _psd_pinv_decomposed_log_pdet(cov, cond) psd = _PSD(cov, cond=cond)
pinv = np.dot(U, U.T) psd_pinv = _PSD(psd.pinv, cond=cond)
_, log_pdet_pinv = _psd_pinv_decomposed_log_pdet(pinv, cond)
# Check that the log pseudo-determinant agrees with the sum # Check that the log pseudo-determinant agrees with the sum
# of the logs of all but the smallest eigenvalue # of the logs of all but the smallest eigenvalue
assert_allclose(log_pdet, np.sum(np.log(s[:-1]))) assert_allclose(psd.log_pdet, np.sum(np.log(s[:-1])))
# Check that the pseudo-determinant of the pseudo-inverse # Check that the pseudo-determinant of the pseudo-inverse
# agrees with 1 / pseudo-determinant # agrees with 1 / pseudo-determinant
assert_allclose(-log_pdet, log_pdet_pinv) assert_allclose(-psd.log_pdet, psd_pinv.log_pdet)
def test_exception_nonsquare_cov(): def test_exception_nonsquare_cov():
cov = [[1, 2, 3], [4, 5, 6]] cov = [[1, 2, 3], [4, 5, 6]]
assert_raises(ValueError, _psd_pinv_decomposed_log_pdet, cov) assert_raises(ValueError, _PSD, cov)
def test_exception_nonfinite_cov(): def test_exception_nonfinite_cov():
cov_nan = [[1, 0], [0, np.nan]] cov_nan = [[1, 0], [0, np.nan]]
assert_raises(ValueError, _psd_pinv_decomposed_log_pdet, cov_nan) assert_raises(ValueError, _PSD, cov_nan)
cov_inf = [[1, 0], [0, np.inf]] cov_inf = [[1, 0], [0, np.inf]]
assert_raises(ValueError, _psd_pinv_decomposed_log_pdet, cov_inf) assert_raises(ValueError, _PSD, cov_inf)
def test_exception_non_psd_cov(): def test_exception_non_psd_cov():
cov = [[1, 0], [0, -1]] cov = [[1, 0], [0, -1]]
assert_raises(ValueError, _psd_pinv_decomposed_log_pdet, cov) assert_raises(ValueError, _PSD, cov)
def test_exception_singular_cov():
np.random.seed(1234)
x = np.random.randn(5)
mean = np.random.randn(5)
cov = np.ones((5, 5))
e = np.linalg.LinAlgError
assert_raises(e, multivariate_normal, mean, cov)
assert_raises(e, multivariate_normal.pdf, x, mean, cov)
assert_raises(e, multivariate_normal.logpdf, x, mean, cov)
def test_R_values(): def test_R_values():
@ -216,6 +296,14 @@ def test_R_values():
assert_allclose(pdf, r_pdf, atol=1e-10) assert_allclose(pdf, r_pdf, atol=1e-10)
def test_multivariate_normal_rvs_zero_covariance():
mean = np.zeros(2)
covariance = np.zeros((2, 2))
model = multivariate_normal(mean, covariance, allow_singular=True)
sample = model.rvs()
assert_equal(sample, [0, 0])
def test_rvs_shape(): def test_rvs_shape():
# Check that rvs parses the mean and covariance correctly, and returns # Check that rvs parses the mean and covariance correctly, and returns
# an array of the right shape # an array of the right shape
@ -267,9 +355,131 @@ def test_entropy():
# Compare entropy with manually computed expression involving # Compare entropy with manually computed expression involving
# the sum of the logs of the eigenvalues of the covariance matrix # the sum of the logs of the eigenvalues of the covariance matrix
eigs = np.linalg.eig(cov)[0] eigs = np.linalg.eig(cov)[0]
desired = 1/2 * (n * (np.log(2*np.pi) + 1) + np.sum(np.log(eigs))) desired = 1 / 2 * (n * (np.log(2 * np.pi) + 1) + np.sum(np.log(eigs)))
assert_almost_equal(desired, rv.entropy()) assert_almost_equal(desired, rv.entropy())
def test_lnB():
alpha = np.array([1, 1, 1])
desired = .5 # e^lnB = 1/2 for [1, 1, 1]
assert_almost_equal(np.exp(_lnB(alpha)), desired)
def test_frozen_dirichlet():
np.random.seed(2846)
n = np.random.randint(1, 32)
alpha = np.random.uniform(10e-10, 100, n)
d = dirichlet(alpha)
assert_equal(d.var(), dirichlet.var(alpha))
assert_equal(d.mean(), dirichlet.mean(alpha))
assert_equal(d.entropy(), dirichlet.entropy(alpha))
num_tests = 10
for i in range(num_tests):
x = np.random.uniform(10e-10, 100, n)
x /= np.sum(x)
assert_equal(d.pdf(x[:-1]), dirichlet.pdf(x[:-1], alpha))
assert_equal(d.logpdf(x[:-1]), dirichlet.logpdf(x[:-1], alpha))
def test_simple_values():
alpha = np.array([1, 1])
d = dirichlet(alpha)
assert_almost_equal(d.mean(), 0.5)
assert_almost_equal(d.var(), 1. / 12.)
b = beta(1, 1)
assert_almost_equal(d.mean(), b.mean())
assert_almost_equal(d.var(), b.var())
def test_K_and_K_minus_1_calls_equal():
# Test that calls with K and K-1 entries yield the same results.
np.random.seed(2846)
n = np.random.randint(1, 32)
alpha = np.random.uniform(10e-10, 100, n)
d = dirichlet(alpha)
num_tests = 10
for i in range(num_tests):
x = np.random.uniform(10e-10, 100, n)
x /= np.sum(x)
assert_almost_equal(d.pdf(x[:-1]), d.pdf(x))
def test_multiple_entry_calls():
# Test that calls with multiple x vectors as matrix work
np.random.seed(2846)
n = np.random.randint(1, 32)
alpha = np.random.uniform(10e-10, 100, n)
d = dirichlet(alpha)
num_tests = 10
num_multiple = 5
xm = None
for i in range(num_tests):
for m in range(num_multiple):
x = np.random.uniform(10e-10, 100, n)
x /= np.sum(x)
if xm is not None:
xm = np.vstack((xm, x))
else:
xm = x
rm = d.pdf(xm.T)
rs = None
for xs in xm:
r = d.pdf(xs)
if rs is not None:
rs = np.append(rs, r)
else:
rs = r
assert_array_almost_equal(rm, rs)
def test_2D_dirichlet_is_beta():
np.random.seed(2846)
alpha = np.random.uniform(10e-10, 100, 2)
d = dirichlet(alpha)
b = beta(alpha[0], alpha[1])
num_tests = 10
for i in range(num_tests):
x = np.random.uniform(10e-10, 100, 2)
x /= np.sum(x)
assert_almost_equal(b.pdf(x), d.pdf([x]))
assert_almost_equal(b.mean(), d.mean()[0])
assert_almost_equal(b.var(), d.var()[0])
def test_dimensions_mismatch():
# Regression test for GH #3493. Check that setting up a PDF with a mean of
# length M and a covariance matrix of size (N, N), where M != N, raises a
# ValueError with an informative error message.
mu = np.array([0.0, 0.0])
sigma = np.array([[1.0]])
assert_raises(ValueError, multivariate_normal, mu, sigma)
# A simple check that the right error message was passed along. Checking
# that the entire message is there, word for word, would be somewhat
# fragile, so we just check for the leading part.
try:
multivariate_normal(mu, sigma)
except ValueError as e:
msg = "Dimension mismatch"
assert_equal(str(e)[:len(msg)], msg)
if __name__ == "__main__": if __name__ == "__main__":
run_module_suite() run_module_suite()

@ -8,13 +8,15 @@
""" """
from __future__ import division, print_function, absolute_import from __future__ import division, print_function, absolute_import
import sys
import warnings import warnings
from collections import namedtuple from collections import namedtuple
from numpy.testing import TestCase, assert_, assert_equal, \ from numpy.testing import (TestCase, assert_, assert_equal,
assert_almost_equal, assert_array_almost_equal, assert_array_equal, \ assert_almost_equal, assert_array_almost_equal,
assert_approx_equal, assert_raises, run_module_suite, \ assert_array_equal, assert_approx_equal,
assert_allclose, dec assert_raises, run_module_suite, assert_allclose,
dec)
import numpy.ma.testutils as mat import numpy.ma.testutils as mat
from numpy import array, arange, float32, float64, power from numpy import array, arange, float32, float64, power
import numpy as np import numpy as np
@ -170,6 +172,14 @@ class TestNanFunc(TestCase):
m = stats.nanmedian(self.X) m = stats.nanmedian(self.X)
assert_approx_equal(m, np.median(self.X)) assert_approx_equal(m, np.median(self.X))
def test_nanmedian_axis(self):
# Check nanmedian with axis
X = self.X.reshape(3,3)
m = stats.nanmedian(X, axis=0)
assert_equal(m, np.median(X, axis=0))
m = stats.nanmedian(X, axis=1)
assert_equal(m, np.median(X, axis=1))
def test_nanmedian_some(self): def test_nanmedian_some(self):
# Check nanmedian when some values only are nan. # Check nanmedian when some values only are nan.
m = stats.nanmedian(self.Xsome) m = stats.nanmedian(self.Xsome)
@ -177,8 +187,21 @@ class TestNanFunc(TestCase):
def test_nanmedian_all(self): def test_nanmedian_all(self):
# Check nanmedian when all values are nan. # Check nanmedian when all values are nan.
m = stats.nanmedian(self.Xall) with warnings.catch_warnings(record=True) as w:
assert_(np.isnan(m)) warnings.simplefilter('always')
m = stats.nanmedian(self.Xall)
assert_(np.isnan(m))
assert_equal(len(w), 1)
assert_(issubclass(w[0].category, RuntimeWarning))
def test_nanmedian_all_axis(self):
# Check nanmedian when all values are nan.
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
m = stats.nanmedian(self.Xall.reshape(3,3), axis=1)
assert_(np.isnan(m).all())
assert_equal(len(w), 3)
assert_(issubclass(w[0].category, RuntimeWarning))
def test_nanmedian_scalars(self): def test_nanmedian_scalars(self):
# Check nanmedian for scalar inputs. See ticket #1098. # Check nanmedian for scalar inputs. See ticket #1098.
@ -449,6 +472,11 @@ class TestFisherExact(TestCase):
res.append(stats.fisher_exact(table, alternative="greater")[1]) res.append(stats.fisher_exact(table, alternative="greater")[1])
assert_allclose(res, pval, atol=0, rtol=1e-7) assert_allclose(res, pval, atol=0, rtol=1e-7)
def test_gh3014(self):
# check if issue #3014 has been fixed.
# before, this would have risen a ValueError
odds, pvalue = stats.fisher_exact([[1, 2], [9, 84419233]])
class TestCorrSpearmanr(TestCase): class TestCorrSpearmanr(TestCase):
""" W.II.D. Compute a correlation matrix on all the variables. """ W.II.D. Compute a correlation matrix on all the variables.
@ -601,9 +629,12 @@ def test_kendalltau():
assert_approx_equal(res[1], expected[1]) assert_approx_equal(res[1], expected[1])
# with only ties in one or both inputs # with only ties in one or both inputs
assert_(np.all(np.isnan(stats.kendalltau([2,2,2], [2,2,2])))) assert_equal(stats.kendalltau([2,2,2], [2,2,2]), (np.nan, np.nan))
assert_(np.all(np.isnan(stats.kendalltau([2,0,2], [2,2,2])))) assert_equal(stats.kendalltau([2,0,2], [2,2,2]), (np.nan, np.nan))
assert_(np.all(np.isnan(stats.kendalltau([2,2,2], [2,0,2])))) assert_equal(stats.kendalltau([2,2,2], [2,0,2]), (np.nan, np.nan))
# empty arrays provided as input
assert_equal(stats.kendalltau([], []), (np.nan, np.nan))
# check two different sort methods # check two different sort methods
assert_approx_equal(stats.kendalltau(x1, x2, initial_lexsort=False)[1], assert_approx_equal(stats.kendalltau(x1, x2, initial_lexsort=False)[1],
@ -718,6 +749,21 @@ class TestRegression(TestCase):
assert_(not np.isnan(res[4])) # stderr should stay finite assert_(not np.isnan(res[4])) # stderr should stay finite
def test_theilslopes():
# Basic slope test.
slope, intercept, lower, upper = stats.theilslopes([0,1,1])
assert_almost_equal(slope, 0.5)
assert_almost_equal(intercept, 0.5)
# Test of confidence intervals.
x = [1, 2, 3, 4, 10, 12, 18]
y = [9, 15, 19, 20, 45, 55, 78]
slope, intercept, lower, upper = stats.theilslopes(y, x, 0.07)
assert_almost_equal(slope, 4)
assert_almost_equal(upper, 4.38, decimal=2)
assert_almost_equal(lower, 3.71, decimal=2)
class TestHistogram(TestCase): class TestHistogram(TestCase):
# Tests that histogram works as it should, and keeps old behaviour # Tests that histogram works as it should, and keeps old behaviour
# #
@ -1032,9 +1078,23 @@ class TestScoreatpercentile(TestCase):
assert_equal(scoreatperc(np.array([1, 10, 100]), 50, limit=(1, 10), assert_equal(scoreatperc(np.array([1, 10, 100]), 50, limit=(1, 10),
interpolation_method='higher'), 10) interpolation_method='higher'), 10)
def test_sequence(self): def test_sequence_per(self):
x = arange(8) * 0.5 x = arange(8) * 0.5
assert_equal(stats.scoreatpercentile(x, [0, 100, 50]), [0, 3.5, 1.75]) expected = np.array([0, 3.5, 1.75])
res = stats.scoreatpercentile(x, [0, 100, 50])
assert_allclose(res, expected)
assert_(isinstance(res, np.ndarray))
# Test with ndarray. Regression test for gh-2861
assert_allclose(stats.scoreatpercentile(x, np.array([0, 100, 50])),
expected)
# Also test combination of 2-D array, axis not None and array-like per
res2 = stats.scoreatpercentile(np.arange(12).reshape((3,4)),
np.array([0, 1, 100, 100]), axis=1)
expected2 = array([[0, 4, 8],
[0.03, 4.03, 8.03],
[3, 7, 11],
[3, 7, 11]])
assert_allclose(res2, expected2)
def test_axis(self): def test_axis(self):
scoreatperc = stats.scoreatpercentile scoreatperc = stats.scoreatpercentile
@ -1054,6 +1114,11 @@ class TestScoreatpercentile(TestCase):
assert_raises(ValueError, stats.scoreatpercentile, [1], 101) assert_raises(ValueError, stats.scoreatpercentile, [1], 101)
assert_raises(ValueError, stats.scoreatpercentile, [1], -1) assert_raises(ValueError, stats.scoreatpercentile, [1], -1)
def test_empty(self):
assert_equal(stats.scoreatpercentile([], 50), np.nan)
assert_equal(stats.scoreatpercentile(np.array([[], []]), 50), np.nan)
assert_equal(stats.scoreatpercentile([], [50, 99]), [np.nan, np.nan])
class TestItemfreq(object): class TestItemfreq(object):
a = [5, 7, 1, 2, 1, 5, 7] * 10 a = [5, 7, 1, 2, 1, 5, 7] * 10
@ -1089,7 +1154,7 @@ class TestItemfreq(object):
bb = np.array(list(zip(b, b)), dt) bb = np.array(list(zip(b, b)), dt)
v = stats.itemfreq(aa) v = stats.itemfreq(aa)
# Arrays don't compare equal because v[:,0] is object array # Arrays don't compare equal because v[:,0] is object array
assert_equal(v[2, 0], bb[2]) assert_equal(tuple(v[2, 0]), tuple(bb[2]))
class TestMode(TestCase): class TestMode(TestCase):
@ -1099,6 +1164,71 @@ class TestMode(TestCase):
assert_almost_equal(vals[0][0],6) assert_almost_equal(vals[0][0],6)
assert_almost_equal(vals[1][0],3) assert_almost_equal(vals[1][0],3)
def test_axes(self):
data1 = [10,10,30,40]
data2 = [10,10,10,10]
data3 = [20,10,20,20]
data4 = [30,30,30,30]
data5 = [40,30,30,30]
arr = np.array([data1, data2, data3, data4, data5])
vals = stats.mode(arr, axis=None)
assert_almost_equal(vals[0],np.array([30]))
assert_almost_equal(vals[1],np.array([8]))
vals = stats.mode(arr, axis=0)
assert_almost_equal(vals[0],np.array([[10,10,30,30]]))
assert_almost_equal(vals[1],np.array([[2,3,3,2]]))
vals = stats.mode(arr, axis=1)
assert_almost_equal(vals[0],np.array([[10],[10],[20],[30],[30]]))
assert_almost_equal(vals[1],np.array([[2],[4],[3],[4],[3]]))
def test_strings(self):
data1 = ['rain', 'showers', 'showers']
vals = stats.mode(data1)
expected = ['showers']
assert_equal(vals[0][0], 'showers')
assert_equal(vals[1][0], 2)
@dec.knownfailureif(sys.version_info > (3,), 'numpy github issue 641')
def test_mixed_objects(self):
objects = [10, True, np.nan, 'hello', 10]
arr = np.empty((5,), dtype=object)
arr[:] = objects
vals = stats.mode(arr)
assert_equal(vals[0][0], 10)
assert_equal(vals[1][0], 2)
def test_objects(self):
"""Python objects must be sortable (le + eq) and have ne defined
for np.unique to work. hash is for set.
"""
class Point(object):
def __init__(self, x):
self.x = x
def __eq__(self, other):
return self.x == other.x
def __ne__(self, other):
return self.x != other.x
def __lt__(self, other):
return self.x < other.x
def __hash__(self):
return hash(self.x)
points = [Point(x) for x in [1,2,3,4,3,2,2,2]]
arr = np.empty((8,), dtype=object)
arr[:] = points
assert len(set(points)) == 4
assert_equal(np.unique(arr).shape, (4,))
vals = stats.mode(arr)
assert_equal(vals[0][0], Point(2))
assert_equal(vals[1][0], 4)
class TestVariability(TestCase): class TestVariability(TestCase):
@ -1120,7 +1250,7 @@ class TestVariability(TestCase):
# y = stats.sem(self.shoes[0]) # y = stats.sem(self.shoes[0])
# assert_approx_equal(y,0.775177399) # assert_approx_equal(y,0.775177399)
y = stats.sem(self.testcase) y = stats.sem(self.testcase)
assert_approx_equal(y,0.6454972244) assert_approx_equal(y, 0.6454972244)
n = len(self.testcase) n = len(self.testcase)
assert_allclose(stats.sem(self.testcase, ddof=0) * np.sqrt(n/(n-2)), assert_allclose(stats.sem(self.testcase, ddof=0) * np.sqrt(n/(n-2)),
stats.sem(self.testcase, ddof=2)) stats.sem(self.testcase, ddof=2))
@ -1660,7 +1790,8 @@ def test_chisquare_masked_arrays():
# Empty arrays: # Empty arrays:
# A data set with length 0 returns a masked scalar. # A data set with length 0 returns a masked scalar.
chisq, p = stats.chisquare(np.ma.array([])) with np.errstate(invalid='ignore'):
chisq, p = stats.chisquare(np.ma.array([]))
assert_(isinstance(chisq, np.ma.MaskedArray)) assert_(isinstance(chisq, np.ma.MaskedArray))
assert_equal(chisq.shape, ()) assert_equal(chisq.shape, ())
assert_(chisq.mask) assert_(chisq.mask)
@ -1675,7 +1806,8 @@ def test_chisquare_masked_arrays():
# empty3.T is an array containing 3 data sets, each with length 0, # empty3.T is an array containing 3 data sets, each with length 0,
# so an array of size (3,) is returned, with all values masked. # so an array of size (3,) is returned, with all values masked.
chisq, p = stats.chisquare(empty3.T) with np.errstate(invalid='ignore'):
chisq, p = stats.chisquare(empty3.T)
assert_(isinstance(chisq, np.ma.MaskedArray)) assert_(isinstance(chisq, np.ma.MaskedArray))
assert_equal(chisq.shape, (3,)) assert_equal(chisq.shape, (3,))
assert_(np.all(chisq.mask)) assert_(np.all(chisq.mask))
@ -1694,39 +1826,39 @@ def test_power_divergence_against_cressie_read_data():
11, 13.952, 11, 13.952,
14, 12.831, 14, 12.831,
17, 11.800, 17, 11.800,
5, 10.852, 5, 10.852,
11, 9.9796, 11, 9.9796,
10, 9.1777, 10, 9.1777,
4, 8.4402, 4, 8.4402,
8, 7.7620, 8, 7.7620,
10, 7.1383, 10, 7.1383,
7, 6.5647, 7, 6.5647,
9, 6.0371, 9, 6.0371,
11, 5.5520, 11, 5.5520,
3, 5.1059, 3, 5.1059,
6, 4.6956, 6, 4.6956,
1, 4.3183, 1, 4.3183,
1, 3.9713, 1, 3.9713,
4, 3.6522, 4, 3.6522,
]).reshape(-1, 2) ]).reshape(-1, 2)
table5 = np.array([ table5 = np.array([
# lambda, statistic # lambda, statistic
-10.0, 72.2e3, -10.0, 72.2e3,
-5.0, 28.9e1, -5.0, 28.9e1,
-3.0, 65.6, -3.0, 65.6,
-2.0, 40.6, -2.0, 40.6,
-1.5, 34.0, -1.5, 34.0,
-1.0, 29.5, -1.0, 29.5,
-0.5, 26.5, -0.5, 26.5,
0.0, 24.6, 0.0, 24.6,
0.5, 23.4, 0.5, 23.4,
0.67, 23.1, 0.67, 23.1,
1.0, 22.7, 1.0, 22.7,
1.5, 22.6, 1.5, 22.6,
2.0, 22.9, 2.0, 22.9,
3.0, 24.8, 3.0, 24.8,
5.0, 35.5, 5.0, 35.5,
10.0, 21.4e1, 10.0, 21.4e1,
]).reshape(-1, 2) ]).reshape(-1, 2)
for lambda_, expected_stat in table5: for lambda_, expected_stat in table5:
@ -2622,22 +2754,25 @@ class TestSigamClip(object):
class TestFOneWay(TestCase): class TestFOneWay(TestCase):
def test_trivial(self): def test_trivial(self):
# A trivial test of stats.f_oneway, with F=0. # A trivial test of stats.f_oneway, with F=0.
F, p = stats.f_oneway([0,2], [0,2]) F, p = stats.f_oneway([0,2], [0,2])
assert_equal(F, 0.0) assert_equal(F, 0.0)
def test_basic(self): def test_basic(self):
# A test of stats.f_oneway, with F=2.
F, p = stats.f_oneway([0,2], [2,4])
# Despite being a floating point calculation, this data should # Despite being a floating point calculation, this data should
# result in F being exactly 2.0. # result in F being exactly 2.0.
F, p = stats.f_oneway([0,2], [2,4])
assert_equal(F, 2.0) assert_equal(F, 2.0)
def test_large_integer_array(self):
a = np.array([655, 788], dtype=np.uint16)
b = np.array([789, 772], dtype=np.uint16)
F, p = stats.f_oneway(a, b)
assert_almost_equal(F, 0.77450216931805538)
class TestKruskal(TestCase):
class TestKruskal(TestCase):
def test_simple(self): def test_simple(self):
x = [1] x = [1]
y = [2] y = [2]

@ -18,7 +18,7 @@ def test_tukeylambda_stats_known_exact():
# lambda = 0 # lambda = 0
var = tukeylambda_variance(0) var = tukeylambda_variance(0)
assert_allclose(var, np.pi ** 2 / 3, atol=1e-12) assert_allclose(var, np.pi**2 / 3, atol=1e-12)
kurt = tukeylambda_kurtosis(0) kurt = tukeylambda_kurtosis(0)
assert_allclose(kurt, 1.2, atol=1e-10) assert_allclose(kurt, 1.2, atol=1e-10)
@ -26,7 +26,7 @@ def test_tukeylambda_stats_known_exact():
var = tukeylambda_variance(0.5) var = tukeylambda_variance(0.5)
assert_allclose(var, 4 - np.pi, atol=1e-12) assert_allclose(var, 4 - np.pi, atol=1e-12)
kurt = tukeylambda_kurtosis(0.5) kurt = tukeylambda_kurtosis(0.5)
desired = (5. / 3 - np.pi / 2) / (np.pi / 4 - 1) ** 2 - 3 desired = (5./3 - np.pi/2) / (np.pi/4 - 1)**2 - 3
assert_allclose(kurt, desired, atol=1e-10) assert_allclose(kurt, desired, atol=1e-10)
# lambda = 1 # lambda = 1

@ -297,9 +297,11 @@ def test_hygfz():
assert_almost_equal(1.0464328112173522, hygfz(0.1, 0.2, 0.3, 0.5)) assert_almost_equal(1.0464328112173522, hygfz(0.1, 0.2, 0.3, 0.5))
assert_almost_equal(1.2027034401166194, hygfz(0.1, 0.2, 0.3, 0.95)) assert_almost_equal(1.2027034401166194, hygfz(0.1, 0.2, 0.3, 0.95))
#assert_equal(1.661006238211309e-07, hygfz(5, -300, 10, 0.5)) #assert_equal(1.661006238211309e-07, hygfz(5, -300, 10, 0.5))
assert_equal(0.118311386286, hygfz(0.5, -99.0, 1.5, 0.5625)) #assert_equal(0.118311386286, hygfz(0.5, -99.0, 1.5, 0.5625))
assert_equal(0.0965606007742, hygfz(0.5, -149.0, 1.5, 0.5625)) #assert_equal(0.0965606007742, hygfz(0.5, -149.0, 1.5, 0.5625))
assert_equal(0.49234384000963544+0.60513406166123973j, hygfz(1, 1, 4, 3+4j)) #assert_equal(0.49234384000963544 + 0.60513406166123973j,
# hygfz(1, 1, 4, 3 + 4j))
def test_common_shape(): def test_common_shape():
A = np.ones((4, 1)) A = np.ones((4, 1))

@ -2,5 +2,6 @@
Transform package in WAFO Toolbox. Transform package in WAFO Toolbox.
""" """
from core import * from .core import *
import models from . import models
from . import estimation

@ -1,209 +1,221 @@
''' '''
''' '''
from __future__ import division from __future__ import division
#import numpy as np #import numpy as np
from numpy import trapz, sqrt, linspace #@UnresolvedImport from numpy import trapz, sqrt, linspace # @UnresolvedImport
from wafo.wafodata import PlotData from wafo.containers import PlotData
from wafo.misc import tranproc #, trangood from wafo.misc import tranproc # , trangood
__all__ = ['TrData', 'TrCommon'] __all__ = ['TrData', 'TrCommon']
class TrCommon(object):
""" class TrCommon(object):
<generic> transformation model, g.
"""
Information about the moments of the process can be obtained by site <generic> transformation model, g.
specific data, laboratory measurements or by resort to theoretical models.
Information about the moments of the process can be obtained by site
Assumption specific data, laboratory measurements or by resort to theoretical models.
----------
The Gaussian process, Y, distributed N(0,1) is related to the Assumption
non-Gaussian process, X, by Y = g(X). ----------
The Gaussian process, Y, distributed N(0,1) is related to the
Methods non-Gaussian process, X, by Y = g(X).
-------
dist2gauss : Returns a measure of departure from the Gaussian model, i.e., Methods
int (g(x)-xn)**2 dx where int. limits are given by X. -------
dat2gauss : Transform non-linear data to Gaussian scale dist2gauss : Returns a measure of departure from the Gaussian model, i.e.,
gauss2dat : Transform Gaussian data to non-linear scale int (g(x)-xn)**2 dx where int. limits are given by X.
dat2gauss : Transform non-linear data to Gaussian scale
Member variables gauss2dat : Transform Gaussian data to non-linear scale
----------------
mean, sigma, skew, kurt : real, scalar Member variables
mean, standard-deviation, skewness and kurtosis, respectively, of the ----------------
non-Gaussian process. Default mean=0, sigma=1, skew=0.16, kurt=3.04. mean, sigma, skew, kurt : real, scalar
skew=kurt-3=0 for a Gaussian process. mean, standard-deviation, skewness and kurtosis, respectively, of the
""" non-Gaussian process. Default mean=0, sigma=1, skew=0.16, kurt=3.04.
skew=kurt-3=0 for a Gaussian process.
def __init__(self, mean=0.0, var=1.0, skew=0.16, kurt=3.04, *args, **kwds): """
sigma = kwds.get('sigma',None)
if sigma is None: def __init__(self, mean=0.0, var=1.0, skew=0.16, kurt=3.04, *args, **kwds):
sigma = sqrt(var) sigma = kwds.get('sigma', None)
self.mean = mean if sigma is None:
self.sigma = sigma sigma = sqrt(var)
self.skew = skew self.mean = mean
self.kurt = kurt self.sigma = sigma
# Mean and std in the Gaussian world: self.skew = skew
self.ymean = kwds.get('ymean', 0e0) self.kurt = kurt
self.ysigma = kwds.get('ysigma', 1e0) # Mean and std in the Gaussian world:
self.ymean = kwds.get('ymean', 0e0)
def __call__(self, x, *xi): self.ysigma = kwds.get('ysigma', 1e0)
return self._dat2gauss(x, *xi)
def __call__(self, x, *xi):
def dist2gauss(self, x=None, xnmin=-5, xnmax=5, n=513): return self._dat2gauss(x, *xi)
"""
Return a measure of departure from the Gaussian model. def dist2gauss(self, x=None, xnmin=-5, xnmax=5, n=513):
"""
Parameters Return a measure of departure from the Gaussian model.
----------
x : vector (default sigma*linspace(xnmin,xnmax,n)+mean) Parameters
xnmin : real, scalar ----------
minimum on normalized scale x : vector (default sigma*linspace(xnmin,xnmax,n)+mean)
xnmax : real, scalar xnmin : real, scalar
maximum on normalized scale minimum on normalized scale
n : integer, scalar xnmax : real, scalar
number of evaluation points maximum on normalized scale
n : integer, scalar
number of evaluation points
Returns
-------
t0 : real, scalar Returns
a measure of departure from the Gaussian model calculated as -------
trapz((xn-g(x))**2., xn) where int. limits is given by X. t0 : real, scalar
""" a measure of departure from the Gaussian model calculated as
if x is None: trapz((xn-g(x))**2., xn) where int. limits is given by X.
xn = linspace(xnmin, xnmax, n) """
x = self.sigma*xn+self.mean if x is None:
else: xn = linspace(xnmin, xnmax, n)
xn = (x-self.mean)/self.sigma x = self.sigma * xn + self.mean
else:
yn = (self._dat2gauss(x)-self.ymean)/self.ysigma xn = (x - self.mean) / self.sigma
t0 = trapz((xn-yn)**2., xn)
return t0 yn = (self._dat2gauss(x) - self.ymean) / self.ysigma
t0 = trapz((xn - yn) ** 2., xn)
def gauss2dat(self, y, *yi): return t0
"""
Transforms Gaussian data, y, to non-linear scale. def gauss2dat(self, y, *yi):
"""
Parameters Transforms Gaussian data, y, to non-linear scale.
----------
y, y1,..., yn : array-like Parameters
input vectors with Gaussian data values, where yi is the i'th time ----------
derivative of y. (n<=4) y, y1,..., yn : array-like
Returns input vectors with Gaussian data values, where yi is the i'th time
------- derivative of y. (n<=4)
x, x1,...,xn : array-like Returns
transformed data to a non-linear scale -------
x, x1,...,xn : array-like
See also transformed data to a non-linear scale
--------
dat2gauss See also
tranproc --------
""" dat2gauss
return self._gauss2dat(y, *yi) tranproc
def _gauss2dat(self, y, *yi): """
pass return self._gauss2dat(y, *yi)
def dat2gauss(self, x, *xi):
""" def _gauss2dat(self, y, *yi):
Transforms non-linear data, x, to Gaussian scale. pass
Parameters def dat2gauss(self, x, *xi):
---------- """
x, x1,...,xn : array-like Transforms non-linear data, x, to Gaussian scale.
input vectors with non-linear data values, where xi is the i'th time
derivative of x. (n<=4) Parameters
Returns ----------
------- x, x1,...,xn : array-like
y, y1,...,yn : array-like input vectors with non-linear data values, where xi is the i'th
transformed data to a Gaussian scale time derivative of x. (n<=4)
Returns
See also -------
-------- y, y1,...,yn : array-like
gauss2dat transformed data to a Gaussian scale
tranproc.
""" See also
return self._dat2gauss(x, *xi) --------
def _dat2gauss(self, x, *xi): gauss2dat
pass tranproc.
"""
class TrData(PlotData, TrCommon): return self._dat2gauss(x, *xi)
__doc__ = TrCommon.__doc__.split('mean')[0].replace('<generic>','Data' #@ReservedAssignment
) + """ def _dat2gauss(self, x, *xi):
data : array-like pass
Gaussian values, Y
args : array-like
non-Gaussian values, X class TrData(PlotData, TrCommon):
ymean, ysigma : real, scalars (default ymean=0, ysigma=1) __doc__ = TrCommon.__doc__.split('mean')[0].replace('<generic>',
mean and standard-deviation, respectively, of the process in Gaussian world. 'Data') + """
mean, sigma : real, scalars data : array-like
mean and standard-deviation, respectively, of the non-Gaussian process. Gaussian values, Y
Default: args : array-like
mean = self.gauss2dat(ymean), non-Gaussian values, X
sigma = (self.gauss2dat(ysigma)-self.gauss2dat(-ysigma))/2 ymean, ysigma : real, scalars (default ymean=0, ysigma=1)
mean and standard-deviation, respectively, of the process in Gaussian
Example world.
------- mean, sigma : real, scalars
Construct a linear transformation model mean and standard-deviation, respectively, of the non-Gaussian process.
>>> import numpy as np Default:
>>> import wafo.transform as wt mean = self.gauss2dat(ymean),
>>> sigma = 5; mean = 1 sigma = (self.gauss2dat(ysigma)-self.gauss2dat(-ysigma))/2
>>> u = np.linspace(-5,5); x = sigma*u+mean; y = u
>>> g = wt.TrData(y,x) Example
>>> g.mean -------
array([ 1.]) Construct a linear transformation model
>>> g.sigma >>> import numpy as np
array([ 5.]) >>> import wafo.transform as wt
>>> sigma = 5; mean = 1
>>> g = wt.TrData(y,x,mean=1,sigma=5) >>> u = np.linspace(-5,5); x = sigma*u+mean; y = u
>>> g.mean >>> g = wt.TrData(y,x)
1 >>> g.mean
>>> g.sigma array([ 1.])
5 >>> g.sigma
>>> g.dat2gauss(1,2,3) array([ 5.])
[array([ 0.]), array([ 0.4]), array([ 0.6])]
>>> g = wt.TrData(y,x,mean=1,sigma=5)
Check that the departure from a Gaussian model is zero >>> g.mean
>>> g.dist2gauss() < 1e-16 1
True >>> g.sigma
""" 5
def __init__(self, *args, **kwds): >>> g.dat2gauss(1,2,3)
options = dict(title='Transform', [array([ 0.]), array([ 0.4]), array([ 0.6])]
xlab='x', ylab='g(x)',
plot_args=['r'], Check that the departure from a Gaussian model is zero
plot_args_children=['g--'],) >>> g.dist2gauss() < 1e-16
options.update(**kwds) True
super(TrData, self).__init__(*args, **options) """
self.ymean = kwds.get('ymean', 0e0)
self.ysigma = kwds.get('ysigma', 1e0) def __init__(self, *args, **kwds):
self.mean = kwds.get('mean', None) options = dict(title='Transform',
self.sigma = kwds.get('sigma', None) xlab='x', ylab='g(x)',
plot_args=['r'],
if self.mean is None: plot_args_children=['g--'],)
#self.mean = np.mean(self.args) # options.update(**kwds)
self.mean = self.gauss2dat(self.ymean) super(TrData, self).__init__(*args, **options)
if self.sigma is None: self.ymean = kwds.get('ymean', 0e0)
yp = self.ymean+self.ysigma self.ysigma = kwds.get('ysigma', 1e0)
ym = self.ymean-self.ysigma self.mean = kwds.get('mean', None)
self.sigma = (self.gauss2dat(yp)-self.gauss2dat(ym))/2. self.sigma = kwds.get('sigma', None)
self.children = [PlotData((self.args-self.mean)/self.sigma, self.args)] if self.mean is None:
#self.mean = np.mean(self.args) #
def trdata(self): self.mean = self.gauss2dat(self.ymean)
return self if self.sigma is None:
yp = self.ymean + self.ysigma
def _gauss2dat(self, y, *yi): ym = self.ymean - self.ysigma
return tranproc(self.data, self.args, y, *yi) self.sigma = (self.gauss2dat(yp) - self.gauss2dat(ym)) / 2.
def _dat2gauss(self, x, *xi): self.children = [
return tranproc(self.args, self.data, x, *xi) PlotData((self.args - self.mean) / self.sigma, self.args)]
def main(): def trdata(self):
pass return self
if __name__ == '__main__': def _gauss2dat(self, y, *yi):
if True: #False : # return tranproc(self.data, self.args, y, *yi)
import doctest
doctest.testmod() def _dat2gauss(self, x, *xi):
else: return tranproc(self.args, self.data, x, *xi)
main()
class EstimateTransform(object):
pass
def main():
pass
if __name__ == '__main__':
if True: # False : #
import doctest
doctest.testmod()
else:
main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,206 +1,210 @@
""" """
Dispersion relation module Dispersion relation module
-------------------------- --------------------------
k2w - Translates from wave number to frequency k2w - Translates from wave number to frequency
w2k - Translates from frequency to wave number w2k - Translates from frequency to wave number
""" """
import warnings import warnings
#import numpy as np #import numpy as np
from numpy import (atleast_1d, sqrt, ones_like, zeros_like, arctan2, where, tanh, any, #@UnresolvedImport from numpy import (atleast_1d, sqrt, ones_like, zeros_like, arctan2, where,
sin, cos, sign, inf, flatnonzero, finfo, cosh, abs) #@UnresolvedImport tanh, any, sin, cos, sign, inf,
flatnonzero, finfo, cosh, abs)
__all__ = ['k2w', 'w2k']
__all__ = ['k2w', 'w2k']
def k2w(k1, k2=0e0, h=inf, g=9.81, u1=0e0, u2=0e0):
''' Translates from wave number to frequency
using the dispersion relation def k2w(k1, k2=0e0, h=inf, g=9.81, u1=0e0, u2=0e0):
''' Translates from wave number to frequency
Parameters using the dispersion relation
----------
k1 : array-like Parameters
wave numbers [rad/m]. ----------
k2 : array-like, optional k1 : array-like
second dimension wave number wave numbers [rad/m].
h : real scalar, optional k2 : array-like, optional
water depth [m]. second dimension wave number
g : real scalar, optional h : real scalar, optional
acceleration of gravity, see gravity water depth [m].
u1, u2 : real scalars, optional g : real scalar, optional
current velocity [m/s] along dimension 1 and 2. acceleration of gravity, see gravity
note: when u1!=0 | u2!=0 then theta is not calculated correctly u1, u2 : real scalars, optional
current velocity [m/s] along dimension 1 and 2.
Returns note: when u1!=0 | u2!=0 then theta is not calculated correctly
-------
w : ndarray Returns
angular frequency [rad/s]. -------
theta : ndarray w : ndarray
direction [rad]. angular frequency [rad/s].
theta : ndarray
Dispersion relation direction [rad].
-------------------
w = sqrt(g*K*tanh(K*h)) ( 0 < w < inf) Dispersion relation
theta = arctan2(k2,k1) (-pi < theta < pi) -------------------
where w = sqrt(g*K*tanh(K*h)) ( 0 < w < inf)
K = sqrt(k1**2+k2**2) theta = arctan2(k2,k1) (-pi < theta < pi)
where
The shape of w and theta is the common shape of k1 and k2 according to the K = sqrt(k1**2+k2**2)
numpy broadcasting rules.
The shape of w and theta is the common shape of k1 and k2 according to the
See also numpy broadcasting rules.
--------
w2k See also
--------
Example w2k
-------
>>> from numpy import arange Example
>>> import wafo.spectrum.dispersion_relation as wsd -------
>>> wsd.k2w(arange(0.01,.5,0.2))[0] >>> from numpy import arange
array([ 0.3132092 , 1.43530485, 2.00551739]) >>> import wafo.wave_theory.dispersion_relation as wsd
>>> wsd.k2w(arange(0.01,.5,0.2),h=20)[0] >>> wsd.k2w(arange(0.01,.5,0.2))[0]
array([ 0.13914927, 1.43498213, 2.00551724]) array([ 0.3132092 , 1.43530485, 2.00551739])
''' >>> wsd.k2w(arange(0.01,.5,0.2),h=20)[0]
array([ 0.13914927, 1.43498213, 2.00551724])
k1i, k2i, hi, gi, u1i, u2i = atleast_1d(k1, k2, h, g, u1, u2) '''
if k1i.size == 0: k1i, k2i, hi, gi, u1i, u2i = atleast_1d(k1, k2, h, g, u1, u2)
return zeros_like(k1i)
ku1 = k1i*u1i if k1i.size == 0:
ku2 = k2i*u2i return zeros_like(k1i)
ku1 = k1i * u1i
theta = arctan2(k2, k1) ku2 = k2i * u2i
k = sqrt(k1i**2+k2i**2) theta = arctan2(k2, k1)
w = where(k>0, ku1+ku2+sqrt(gi*k*tanh(k*hi)), 0.0)
k = sqrt(k1i ** 2 + k2i ** 2)
cond = (w<0) w = where(k > 0, ku1 + ku2 + sqrt(gi * k * tanh(k * hi)), 0.0)
if any(cond):
txt0 = ''' cond = (w < 0)
Waves and current are in opposite directions if any(cond):
making some of the frequencies negative. txt0 = '''
Here we are forcing the negative frequencies to zero. Waves and current are in opposite directions
''' making some of the frequencies negative.
warnings.warn(txt0) Here we are forcing the negative frequencies to zero.
w = where(cond, 0.0, w) # force w to zero '''
warnings.warn(txt0)
return w, theta w = where(cond, 0.0, w) # force w to zero
def w2k(w, theta=0.0, h=inf, g=9.81, count_limit=100): return w, theta
'''
Translates from frequency to wave number
using the dispersion relation def w2k(w, theta=0.0, h=inf, g=9.81, count_limit=100):
'''
Parameters Translates from frequency to wave number
---------- using the dispersion relation
w : array-like
angular frequency [rad/s]. Parameters
theta : array-like, optional ----------
direction [rad]. w : array-like
h : real scalar, optional angular frequency [rad/s].
water depth [m]. theta : array-like, optional
g : real scalar or array-like of size 2. direction [rad].
constant of gravity [m/s**2] or 3D normalizing constant h : real scalar, optional
water depth [m].
Returns g : real scalar or array-like of size 2.
------- constant of gravity [m/s**2] or 3D normalizing constant
k1, k2 : ndarray
wave numbers [rad/m] along dimension 1 and 2. Returns
-------
Description k1, k2 : ndarray
----------- wave numbers [rad/m] along dimension 1 and 2.
Uses Newton Raphson method to find the wave number k in the dispersion relation
w**2= g*k*tanh(k*h). Description
The solution k(w) => k1 = k(w)*cos(theta) -----------
k2 = k(w)*sin(theta) Uses Newton Raphson method to find the wave number k in the dispersion
The size of k1,k2 is the common shape of w and theta according to numpy relation
broadcasting rules. If w or theta is scalar it functions as a constant w**2= g*k*tanh(k*h).
matrix of the same shape as the other. The solution k(w) => k1 = k(w)*cos(theta)
k2 = k(w)*sin(theta)
Example The size of k1,k2 is the common shape of w and theta according to numpy
------- broadcasting rules. If w or theta is scalar it functions as a constant
>>> import pylab as plb matrix of the same shape as the other.
>>> import wafo.spectrum.dispersion_relation as wsd
>>> w = plb.linspace(0,3); Example
>>> h = plb.plot(w,w2k(w)[0]) -------
>>> wsd.w2k(range(4))[0] >>> import pylab as plb
array([ 0. , 0.1019368 , 0.4077472 , 0.91743119]) >>> import wafo.wave_theory.dispersion_relation as wsd
>>> wsd.w2k(range(4),h=20)[0] >>> w = plb.linspace(0,3);
array([ 0. , 0.10503601, 0.40774726, 0.91743119]) >>> h = plb.plot(w,w2k(w)[0])
>>> wsd.w2k(range(4))[0]
>>> plb.close('all') array([ 0. , 0.1019368 , 0.4077472 , 0.91743119])
>>> wsd.w2k(range(4),h=20)[0]
See also array([ 0. , 0.10503601, 0.40774726, 0.91743119])
--------
k2w >>> plb.close('all')
'''
wi, th, hi, gi = atleast_1d(w, theta, h, g) See also
--------
if wi.size == 0: k2w
return zeros_like(wi) '''
wi, th, hi, gi = atleast_1d(w, theta, h, g)
k = 1.0*sign(wi)*wi**2.0 / gi[0] # deep water
if (hi > 10. ** 25).all(): if wi.size == 0:
k2 = k*sin(th)*gi[0]/gi[-1] #size np x nf return zeros_like(wi)
k1 = k*cos(th)
return k1, k2 k = 1.0 * sign(wi) * wi ** 2.0 / gi[0] # deep water
if (hi > 10. ** 25).all():
k2 = k * sin(th) * gi[0] / gi[-1] # size np x nf
if gi.size > 1: k1 = k * cos(th)
txt0 = ''' return k1, k2
Finite depth in combination with 3D normalization (len(g)=2) is not implemented yet.
''' if gi.size > 1:
raise ValueError(txt0) raise ValueError('Finite depth in combination with 3D normalization' +
' (len(g)=2) is not implemented yet.')
find = flatnonzero find = flatnonzero
eps = finfo(float).eps eps = finfo(float).eps
oshape = k.shape oshape = k.shape
wi, k, hi = wi.ravel(), k.ravel(), hi.ravel() wi, k, hi = wi.ravel(), k.ravel(), hi.ravel()
# Newton's Method # Newton's Method
# Permit no more than count_limit iterations. # Permit no more than count_limit iterations.
hi = hi * ones_like(k) hi = hi * ones_like(k)
hn = zeros_like(k) hn = zeros_like(k)
ix = find((wi<0) | (0<wi)) ix = find((wi < 0) | (0 < wi))
# Break out of the iteration loop for three reasons: # Break out of the iteration loop for three reasons:
# 1) the last update is very small (compared to x) # 1) the last update is very small (compared to x)
# 2) the last update is very small (compared to sqrt(eps)) # 2) the last update is very small (compared to sqrt(eps))
# 3) There are more than 100 iterations. This should NEVER happen. # 3) There are more than 100 iterations. This should NEVER happen.
count = 0 count = 0
while (ix.size>0 and count < count_limit): while (ix.size > 0 and count < count_limit):
ki = k[ix] ki = k[ix]
kh = ki * hi[ix] kh = ki * hi[ix]
hn[ix] = (ki*tanh(kh)-wi[ix]**2.0/gi)/(tanh(kh)+kh/(cosh(kh)**2.0)) hn[ix] = (ki * tanh(kh) - wi[ix] ** 2.0 / gi) / \
knew = ki - hn[ix] (tanh(kh) + kh / (cosh(kh) ** 2.0))
# Make sure that the current guess is not zero. knew = ki - hn[ix]
# When Newton's Method suggests steps that lead to zero guesses # Make sure that the current guess is not zero.
# take a step 9/10ths of the way to zero: # When Newton's Method suggests steps that lead to zero guesses
ksmall = find(abs(knew)==0) # take a step 9/10ths of the way to zero:
if ksmall.size>0: ksmall = find(abs(knew) == 0)
knew[ksmall] = ki[ksmall] / 10.0 if ksmall.size > 0:
hn[ix[ksmall]] = ki[ksmall]-knew[ksmall] knew[ksmall] = ki[ksmall] / 10.0
hn[ix[ksmall]] = ki[ksmall] - knew[ksmall]
k[ix] = knew
# disp(['Iteration ',num2str(count),' Number of points left: ' num2str(length(ix)) ]), k[ix] = knew
# disp(['Iteration ',num2str(count),' Number of points left: '
ix = find((abs(hn) > sqrt(eps)*abs(k)) * abs(hn) > sqrt(eps)) # num2str(length(ix)) ]),
count += 1
ix = find((abs(hn) > sqrt(eps) * abs(k)) * abs(hn) > sqrt(eps))
if count == count_limit: count += 1
txt1 = ''' W2K did not converge.
The maximum error in the last step was: %13.8f''' % max(hn[ix]) if count == count_limit:
warnings.warn(txt1) warnings.warn('W2K did not converge. The maximum error in the ' +
'last step was: %13.8f' % max(hn[ix]))
k.shape = oshape
k.shape = oshape
k2 = k*sin(th)
k1 = k*cos(th) k2 = k * sin(th)
return k1, k2 k1 = k * cos(th)
return k1, k2
def main():
import doctest
doctest.testmod() def test_docstrings():
import doctest
if __name__ == '__main__': print('Testing docstrings in %s' % __file__)
main() doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)
if __name__ == '__main__':
test_docstrings()

@ -1,31 +1,35 @@
''' '''
Created on 19. juli 2010 Created on 19. juli 2010
@author: pab @author: pab
''' '''
import numpy as np import numpy as np
from wafo.wave_theory.dispersion_relation import w2k,k2w #@UnusedImport from wafo.wave_theory.dispersion_relation import w2k, k2w # @UnusedImport
def test_k2w_infinite_water_depth():
vals = k2w(np.arange(0.01,.5,0.2))[0] def test_k2w_infinite_water_depth():
true_vals = np.array([ 0.3132092 , 1.43530485, 2.00551739]) vals = k2w(np.arange(0.01, .5, 0.2))[0]
assert((np.abs(vals-true_vals)<1e-7).all()) true_vals = np.array([0.3132092, 1.43530485, 2.00551739])
assert((np.abs(vals - true_vals) < 1e-7).all())
def test_k2w_finite_water_depth():
vals = k2w(np.arange(0.01,.5,0.2),h=20)[0]
true_vals = np.array([ 0.13914927, 1.43498213, 2.00551724]) def test_k2w_finite_water_depth():
assert((np.abs(vals-true_vals)<1e-7).all()) vals = k2w(np.arange(0.01, .5, 0.2), h=20)[0]
true_vals = np.array([0.13914927, 1.43498213, 2.00551724])
def test_w2k_infinite_water_depth(): assert((np.abs(vals - true_vals) < 1e-7).all())
vals = w2k(range(4))[0]
true_vals = np.array([ 0. , 0.1019368 , 0.4077472 , 0.91743119])
assert((np.abs(vals-true_vals)<1e-7).all()) def test_w2k_infinite_water_depth():
vals = w2k(range(4))[0]
def test_w2k_finite_water_depth(): true_vals = np.array([0., 0.1019368, 0.4077472, 0.91743119])
vals = w2k(range(4),h=20)[0] assert((np.abs(vals - true_vals) < 1e-7).all())
true_vals = np.array([ 0. , 0.10503601, 0.40774726, 0.91743119])
assert((np.abs(vals-true_vals)<1e-7).all())
def test_w2k_finite_water_depth():
if __name__ == '__main__': vals = w2k(range(4), h=20)[0]
import nose true_vals = np.array([0., 0.10503601, 0.40774726, 0.91743119])
nose.run() assert((np.abs(vals - true_vals) < 1e-7).all())
if __name__ == '__main__':
import nose
nose.run()

Loading…
Cancel
Save