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