Fixed cmat2nt for kind=1

master
pbrod 9 years ago
parent 790e21f1f4
commit 9addf9f855

@ -1187,7 +1187,14 @@ def _findrfc(y, h):
return ind, ix
def nt2cmat(nt, kind=11):
def _raise_kind_error(kind):
if kind in (-1, 0):
raise NotImplementedError('kind = {} not yet implemented'.format(kind))
else:
raise ValueError('kind = {}: not a valid value of kind'.format(kind))
def nt2cmat(nt, kind=1):
"""
Return cycle matrix from a counting distribution.
@ -1216,6 +1223,12 @@ def nt2cmat(nt, kind=11):
... [ 0., 0., 0., 0.]])
>>> nt = cmat2nt(cmat0)
>>> np.allclose(nt,
... [[ 0., 0., 0., 0.],
... [ 20., 15., 9., 0.],
... [ 28., 23., 16., 0.],
... [ 32., 27., 20., 0.]])
True
>>> cmat = nt2cmat(nt)
>>> np.allclose(cmat, [[ 0., 5., 6., 9.],
... [ 0., 0., 1., 7.],
@ -1227,35 +1240,29 @@ def nt2cmat(nt, kind=11):
--------
cmat2nt
"""
n = len(nt) # Number of discrete levels
cmat = np.zeros((n, n))
if kind == 1:
I = np.r_[0:n-1]
J = np.r_[1:n]
cmat[I, J] = nt[I+1, J-1] - nt[I, J-1] - nt[I+1, J] + nt[I, J]
c = nt[I+1][:, J-1] - nt[I][:, J-1] - nt[I+1][:, J] + nt[I][:, J]
c2 = np.vstack((c, np.zeros((n-1))))
cmat = np.hstack((np.zeros((n, 1)), c2))
elif kind == 11: # same as def=1 but using for-loop
cmat = np.zeros((n, n))
j = np.r_[1:n]
for i in range(n-1):
cmat[i, j] = nt[i+1, j-1] - nt[i, j-1] - nt[i+1, j] + nt[i, j]
elif kind == 0:
raise NotImplementedError('kind == 0 not yet implemented')
elif kind == -1:
raise NotImplementedError('kind == -1 not yet implemented')
else:
raise ValueError('kind = {}: not a valid value of kind'.format(kind))
_raise_kind_error(kind)
return cmat
def cmat2nt(cmat, kind=11):
def cmat2nt(cmat, kind=1):
"""
CMAT2NT Calculates a counting distribution from a cycle matrix.
CALL: NT = cmat2nt(F,def);
NT = Counting distribution. [nxn]
Parameters
----------
cmat = Cycle matrix. [nxn]
kind = 1: causes peaks to be projected upwards and troughs
downwards to the closest discrete level (default).
@ -1263,11 +1270,34 @@ def cmat2nt(cmat, kind=11):
the closest discrete level.
= -1: causes peaks to be projected downwards and the
troughs upwards to the closest discrete level.
Returns
-------
NT: n x n array
Counting distribution.
Example
-------
F = round(triu(rand(4),1)*10)
NT = cmat2nt(F)
>>> import numpy as np
>>> cmat0 = np.round(np.triu(np.random.rand(4, 4), 1)*10)
>>> cmat0 = np.array([[ 0., 5., 6., 9.],
... [ 0., 0., 1., 7.],
... [ 0., 0., 0., 4.],
... [ 0., 0., 0., 0.]])
>>> nt = cmat2nt(cmat0, kind=11)
>>> np.allclose(nt,
... [[ 0., 0., 0., 0.],
... [ 20., 15., 9., 0.],
... [ 28., 23., 16., 0.],
... [ 32., 27., 20., 0.]])
True
>>> cmat = nt2cmat(nt, kind=11)
>>> np.allclose(cmat, [[ 0., 5., 6., 9.],
... [ 0., 0., 1., 7.],
... [ 0., 0., 0., 4.],
... [ 0., 0., 0., 0.]])
True
See also
--------
@ -1275,21 +1305,18 @@ def cmat2nt(cmat, kind=11):
"""
n = len(cmat) # Number of discrete levels
nt = zeros((n, n))
if kind == 1:
nt[1:n, :n-1] = np.fliplr(np.cumsum(np.fliplr(np.cumsum(cmat[:-1,
1:])),
axis=1))
csum = np.cumsum
flip = np.fliplr
nt[1:n, :n-1] = flip(csum(flip(csum(cmat[:-1, 1:], axis=0)), axis=1))
elif kind == 11: # same as def=1 but using for-loop
# j = np.r_[1:n]
for i in range(1, n):
for j in range(n-1):
nt[i, j] = np.sum(np.sum(cmat[:i, j+1:n]))
elif kind == 0:
raise NotImplementedError('kind == 0 not yet implemented')
elif kind == -1:
raise NotImplementedError('kind == -1 not yet implemented')
nt[i, j] = np.sum(cmat[:i, j+1:n])
else:
raise ValueError('kind = {}: not a valid value of kind'.format(kind))
_raise_kind_error(kind)
return nt
@ -1564,57 +1591,7 @@ def mctp2rfc(fmM, fMm=None):
return f_rfc
def rfcfilter(x, h, method=0):
"""
Rainflow filter a signal.
Parameters
-----------
x : vector
Signal. [nx1]
h : real, scalar
Threshold for rainflow filter.
method : scalar, integer
0 : removes cycles with range < h. (default)
1 : removes cycles with range <= h.
Returns
--------
y = Rainflow filtered signal.
Examples:
---------
# 1. Filtered signal y is the turning points of x.
>>> import wafo.data as data
>>> import wafo.misc as wm
>>> x = data.sea()
>>> y = wm.rfcfilter(x[:,1], h=0, method=1)
>>> np.all(np.abs(y[0:5]-np.array([-1.2004945 , 0.83950546, -0.09049454,
... -0.02049454, -0.09049454]))<1e-7)
True
>>> y.shape
(2172,)
# 2. This removes all rainflow cycles with range less than 0.5.
>>> y1 = wm.rfcfilter(x[:,1], h=0.5)
>>> y1.shape
(863,)
>>> np.all(np.abs(y1[0:5]-np.array([-1.2004945 , 0.83950546, -0.43049454,
... 0.34950546, -0.51049454]))<1e-7)
True
>>> ind = wm.findtp(x[:,1], h=0.5)
>>> y2 = x[ind,1]
>>> y2[0:5]
array([-1.2004945 , 0.83950546, -0.43049454, 0.34950546, -0.51049454])
>>> y2[-5::]
array([ 0.83950546, -0.64049454, 0.65950546, -1.0004945 , 0.91950546])
See also
--------
findrfc
"""
# TODO merge rfcfilter and findrfc
y = atleast_1d(x).ravel()
def _findrfc2(y, h, method):
n = len(y)
t = zeros(n, dtype=np.int)
j = 0
@ -1622,18 +1599,18 @@ def rfcfilter(x, h, method=0):
y0 = y[t0]
z0 = 0
def aleb(a, b):
def a_le_b(a, b):
return a <= b
def altb(a, b):
def a_lt_b(a, b):
return a < b
if method == 0:
cmpfun1 = aleb
cmpfun2 = altb
cmpfun1 = a_le_b
cmpfun2 = a_lt_b
else:
cmpfun1 = altb
cmpfun2 = aleb
cmpfun1 = a_lt_b
cmpfun2 = a_le_b
# The rainflow filter
for tim1, yi in enumerate(y[1::]):
@ -1683,7 +1660,62 @@ def rfcfilter(x, h, method=0):
if cmpfun1(h, abs(y0 - y[t[j]])):
j += 1
t[j] = t0
return y[t[:j + 1]]
return t[:j + 1]
def rfcfilter(x, h, method=0):
"""
Rainflow filter a signal.
Parameters
-----------
x : vector
Signal. [nx1]
h : real, scalar
Threshold for rainflow filter.
method : scalar, integer
0 : removes cycles with range < h. (default)
1 : removes cycles with range <= h.
Returns
--------
y = Rainflow filtered signal.
Examples:
---------
# 1. Filtered signal y is the turning points of x.
>>> import wafo.data as data
>>> import wafo.misc as wm
>>> x = data.sea()
>>> y = wm.rfcfilter(x[:,1], h=0, method=1)
>>> np.all(np.abs(y[0:5]-np.array([-1.2004945 , 0.83950546, -0.09049454,
... -0.02049454, -0.09049454]))<1e-7)
True
>>> y.shape
(2172,)
# 2. This removes all rainflow cycles with range less than 0.5.
>>> y1 = wm.rfcfilter(x[:,1], h=0.5)
>>> y1.shape
(863,)
>>> np.all(np.abs(y1[0:5]-np.array([-1.2004945 , 0.83950546, -0.43049454,
... 0.34950546, -0.51049454]))<1e-7)
True
>>> ind = wm.findtp(x[:,1], h=0.5)
>>> y2 = x[ind,1]
>>> y2[0:5]
array([-1.2004945 , 0.83950546, -0.43049454, 0.34950546, -0.51049454])
>>> y2[-5::]
array([ 0.83950546, -0.64049454, 0.65950546, -1.0004945 , 0.91950546])
See also
--------
findrfc
"""
# TODO merge rfcfilter and findrfc
y = atleast_1d(x).ravel()
ix = _findrfc2(y, h, method)
return y[ix]
def findtp(x, h=0.0, kind=None):

Loading…
Cancel
Save