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.
328 lines
9.9 KiB
Python
328 lines
9.9 KiB
Python
import wafo.plotbackend.plotbackend as plt
|
|
import numpy as np
|
|
|
|
# pyreport -o chapter2.html chapter2.py
|
|
|
|
#! CHAPTER2 Modelling random loads and stochastic waves
|
|
#!=======================================================
|
|
#!
|
|
#! Chapter2 contains the commands used in Chapter 2 of the tutorial and
|
|
#! present some tools for analysis of random functions with
|
|
#! respect to their correlation, spectral and distributional properties.
|
|
#! The presentation is divided into three examples:
|
|
#!
|
|
#! Example1 is devoted to estimation of different parameters in the model.
|
|
#! Example2 deals with spectral densities and
|
|
#! Example3 presents the use of WAFO to simulate samples of a Gaussian
|
|
#! process.
|
|
#!
|
|
#! Some of the commands are edited for fast computation.
|
|
#!
|
|
#! Section 2.1 Introduction and preliminary analysis
|
|
#!====================================================
|
|
#! Example 1: Sea data
|
|
#!----------------------
|
|
#! Observed crossings compared to the expected for Gaussian signals
|
|
|
|
import wafo
|
|
import wafo.objects as wo
|
|
xx = wafo.data.sea()
|
|
me = xx[:, 1].mean()
|
|
sa = xx[:, 1].std()
|
|
xx[:, 1] -= me
|
|
ts = wo.mat2timeseries(xx)
|
|
tp = ts.turning_points()
|
|
|
|
cc = tp.cycle_pairs()
|
|
lc = cc.level_crossings()
|
|
lc.plot()
|
|
plt.show()
|
|
|
|
#! Average number of upcrossings per time unit
|
|
#!----------------------------------------------
|
|
#! Next we compute the mean frequency as the average number of upcrossings
|
|
#! per time unit of the mean level (= 0); this may require interpolation in the
|
|
#! crossing intensity curve, as follows.
|
|
T = xx[:, 0].max() - xx[:, 0].min()
|
|
f0 = np.interp(0, lc.args, lc.data, 0) / T # zero up-crossing frequency
|
|
print('f0 = %g' % f0)
|
|
|
|
#! Turningpoints and irregularity factor
|
|
#!----------------------------------------
|
|
|
|
fm = len(tp.data) / (2 * T) # frequency of maxima
|
|
alfa = f0 / fm # approx Tm24/Tm02
|
|
|
|
print('fm = %g, alpha = %g, ' % (fm, alfa))
|
|
|
|
#! Visually examine data
|
|
#!------------------------
|
|
#! We finish this section with some remarks about the quality
|
|
#! of the measured data. Especially sea surface measurements can be
|
|
#! of poor quality. We shall now check the quality of the dataset {\tt xx}.
|
|
#! It is always good practice to visually examine the data
|
|
#! before the analysis to get an impression of the quality,
|
|
#! non-linearities and narrow-bandedness of the data.
|
|
#! First we shall plot the data and zoom in on a specific region.
|
|
#! A part of sea data is visualized with the following commands
|
|
plt.clf()
|
|
ts.plot_wave('k-', tp, '*', nfig=1, nsub=1)
|
|
|
|
plt.axis([0, 2, -2, 2])
|
|
plt.show()
|
|
|
|
#! Finding possible spurious points
|
|
#!------------------------------------
|
|
#! However, if the amount of data is too large for visual examinations one
|
|
#! could use the following criteria to find possible spurious points. One
|
|
#! must be careful using the criteria for extremevalue analysis, because
|
|
#! it might remove extreme waves that are OK and not spurious.
|
|
|
|
import wafo.misc as wm
|
|
dt = ts.sampling_period()
|
|
# dt = np.diff(xx[:2,0])
|
|
dcrit = 5 * dt
|
|
ddcrit = 9.81 / 2 * dt * dt
|
|
zcrit = 0
|
|
inds, indg = wm.findoutliers(ts.data, zcrit, dcrit, ddcrit, verbose=True)
|
|
|
|
#! Section 2.2 Frequency Modeling of Load Histories
|
|
#!----------------------------------------------------
|
|
#! Periodogram: Raw spectrum
|
|
#!
|
|
plt.clf()
|
|
Lmax = 9500
|
|
S = ts.tospecdata(L=Lmax)
|
|
S.plot()
|
|
plt.axis([0, 5, 0, 0.7])
|
|
plt.show()
|
|
|
|
#! Calculate moments
|
|
#!-------------------
|
|
mom, text = S.moment(nr=4)
|
|
print('sigma = %g, m0 = %g' % (sa, np.sqrt(mom[0])))
|
|
|
|
#! Section 2.2.1 Random functions in Spectral Domain - Gaussian processes
|
|
#!--------------------------------------------------------------------------
|
|
#! Smoothing of spectral estimate
|
|
#!----------------------------------
|
|
#! By decreasing Lmax the spectrum estimate becomes smoother.
|
|
|
|
plt.clf()
|
|
Lmax0 = 200
|
|
Lmax1 = 50
|
|
S1 = ts.tospecdata(L=Lmax0)
|
|
S2 = ts.tospecdata(L=Lmax1)
|
|
S1.plot('-.')
|
|
S2.plot()
|
|
plt.show()
|
|
|
|
#! Estimated autocovariance
|
|
#!----------------------------
|
|
#! Obviously knowing the spectrum one can compute the covariance
|
|
#! function. The following code will compute the covariance for the
|
|
#! unimodal spectral density S1 and compare it with estimated
|
|
#! covariance of the signal xx.
|
|
plt.clf()
|
|
Lmax = 85
|
|
R1 = S1.tocovdata(nr=1)
|
|
Rest = ts.tocovdata(lag=Lmax)
|
|
R1.plot('.')
|
|
Rest.plot()
|
|
plt.axis([0, 25, -0.1, 0.25])
|
|
plt.show()
|
|
|
|
#! We can see in Figure below that the covariance function corresponding to
|
|
#! the spectral density S2 significantly differs from the one estimated
|
|
#! directly from data.
|
|
#! It can be seen in Figure above that the covariance corresponding to S1
|
|
#! agrees much better with the estimated covariance function
|
|
|
|
plt.clf()
|
|
R2 = S2.tocovdata(nr=1)
|
|
R2.plot('.')
|
|
Rest.plot()
|
|
plt.show()
|
|
|
|
#! Section 2.2.2 Transformed Gaussian models
|
|
#!-------------------------------------------
|
|
#! We begin with computing skewness and kurtosis
|
|
#! for the data set xx and compare it with the second order wave approximation
|
|
#! proposed by Winterstein:
|
|
import wafo.stats as ws
|
|
rho3 = ws.skew(xx[:, 1])
|
|
rho4 = ws.kurtosis(xx[:, 1])
|
|
|
|
sk, ku = S1.stats_nl(moments='sk')
|
|
|
|
#! Comparisons of 3 transformations
|
|
plt.clf()
|
|
import wafo.transform.models as wtm
|
|
gh = wtm.TrHermite(mean=me, sigma=sa, skew=sk, kurt=ku).trdata()
|
|
g = wtm.TrLinear(mean=me, sigma=sa).trdata() # Linear transformation
|
|
glc, gemp = lc.trdata(mean=me, sigma=sa)
|
|
|
|
glc.plot('b-') # Transf. estimated from level-crossings
|
|
gh.plot('b-.') # Hermite Transf. estimated from moments
|
|
g.plot('r')
|
|
plt.grid('on')
|
|
plt.show()
|
|
|
|
#! Test Gaussianity of a stochastic process
|
|
#!------------------------------------------
|
|
#! TESTGAUSSIAN simulates e(g(u)-u) = int (g(u)-u)^2 du for Gaussian processes
|
|
#! given the spectral density, S. The result is plotted if test0 is given.
|
|
#! This is useful for testing if the process X(t) is Gaussian.
|
|
#! If 95% of TEST1 is less than TEST0 then X(t) is not Gaussian at a 5% level.
|
|
#!
|
|
#! As we see from the figure below: none of the simulated values of test1 is
|
|
#! above 1.00. Thus the data significantly departs from a Gaussian distribution.
|
|
plt.clf()
|
|
test0 = glc.dist2gauss()
|
|
#! the following test takes time
|
|
N = len(xx)
|
|
test1 = S1.testgaussian(ns=N, cases=50, test0=test0)
|
|
is_gaussian = sum(test1 > test0) > 5
|
|
print(is_gaussian)
|
|
plt.show()
|
|
|
|
#! Normalplot of data xx
|
|
#!------------------------
|
|
#! indicates that the underlying distribution has a "heavy" upper tail and a
|
|
#! "light" lower tail.
|
|
plt.clf()
|
|
import pylab
|
|
ws.probplot(ts.data.ravel(), dist='norm', plot=pylab)
|
|
plt.show()
|
|
#! Section 2.2.3 Spectral densities of sea data
|
|
#!-----------------------------------------------
|
|
#! Example 2: Different forms of spectra
|
|
#!
|
|
import wafo.spectrum.models as wsm
|
|
plt.clf()
|
|
Hm0 = 7
|
|
Tp = 11
|
|
spec = wsm.Jonswap(Hm0=Hm0, Tp=Tp).tospecdata()
|
|
spec.plot()
|
|
plt.show()
|
|
|
|
#! Directional spectrum and Encountered directional spectrum
|
|
#! Directional spectrum
|
|
plt.clf()
|
|
D = wsm.Spreading('cos2s')
|
|
Sd = D.tospecdata2d(spec)
|
|
Sd.plot()
|
|
plt.show()
|
|
|
|
|
|
##!Encountered directional spectrum
|
|
##!---------------------------------
|
|
#clf()
|
|
#Se = spec2spec(Sd,'encdir',0,10);
|
|
#plotspec(Se), hold on
|
|
#plotspec(Sd,1,'--'), hold off
|
|
##!wafostamp('','(ER)')
|
|
#disp('Block = 17'),pause(pstate)
|
|
#
|
|
##!#! Frequency spectra
|
|
#clf
|
|
#Sd1 =spec2spec(Sd,'freq');
|
|
#Sd2 = spec2spec(Se,'enc');
|
|
#plotspec(spec), hold on
|
|
#plotspec(Sd1,1,'.'),
|
|
#plotspec(Sd2),
|
|
##!wafostamp('','(ER)')
|
|
#hold off
|
|
#disp('Block = 18'),pause(pstate)
|
|
#
|
|
##!#! Wave number spectrum
|
|
#clf
|
|
#Sk = spec2spec(spec,'k1d')
|
|
#Skd = spec2spec(Sd,'k1d')
|
|
#plotspec(Sk), hold on
|
|
#plotspec(Skd,1,'--'), hold off
|
|
##!wafostamp('','(ER)')
|
|
#disp('Block = 19'),pause(pstate)
|
|
#
|
|
##!#! Effect of waterdepth on spectrum
|
|
#clf
|
|
#plotspec(spec,1,'--'), hold on
|
|
#S20 = spec;
|
|
#S20.S = S20.S.*phi1(S20.w,20);
|
|
#S20.h = 20;
|
|
#plotspec(S20), hold off
|
|
##!wafostamp('','(ER)')
|
|
#disp('Block = 20'),pause(pstate)
|
|
#
|
|
##!#! Section 2.3 Simulation of transformed Gaussian process
|
|
##!#! Example 3: Simulation of random sea
|
|
##! The reconstruct function replaces the spurious points of seasurface by
|
|
##! simulated data on the basis of the remaining data and a transformed Gaussian
|
|
##! process. As noted previously one must be careful using the criteria
|
|
##! for finding spurious points when reconstructing a dataset, because
|
|
##! these criteria might remove the highest and steepest waves as we can see
|
|
##! in this plot where the spurious points is indicated with a '+' sign:
|
|
##!
|
|
#clf
|
|
#[y, grec] = reconstruct(xx,inds);
|
|
#waveplot(y,'-',xx(inds,:),'+',1,1)
|
|
#axis([0 inf -inf inf])
|
|
##!wafostamp('','(ER)')
|
|
#disp('Block = 21'),pause(pstate)
|
|
#
|
|
##! Compare transformation (grec) from reconstructed (y)
|
|
##! with original (glc) from (xx)
|
|
#clf
|
|
#trplot(g), hold on
|
|
#plot(gemp(:,1),gemp(:,2))
|
|
#plot(glc(:,1),glc(:,2),'-.')
|
|
#plot(grec(:,1),grec(:,2)), hold off
|
|
#disp('Block = 22'),pause(pstate)
|
|
#
|
|
##!#!
|
|
#clf
|
|
#L = 200;
|
|
#x = dat2gaus(y,grec);
|
|
#Sx = dat2spec(x,L);
|
|
#disp('Block = 23'),pause(pstate)
|
|
#
|
|
##!#!
|
|
#clf
|
|
#dt = spec2dt(Sx)
|
|
#Ny = fix(2*60/dt) #! = 2 minutes
|
|
#Sx.tr = grec;
|
|
#ysim = spec2sdat(Sx,Ny);
|
|
#waveplot(ysim,'-')
|
|
##!wafostamp('','(CR)')
|
|
#disp('Block = 24'),pause(pstate)
|
|
#
|
|
#! Estimated spectrum compared to Torsethaugen spectrum
|
|
#!-------------------------------------------------------
|
|
|
|
plt.clf()
|
|
fp = 1.1
|
|
dw = 0.01
|
|
H0 = S1.characteristic('Hm0')[0]
|
|
St = wsm.Torsethaugen(Hm0=H0,Tp=2*np.pi/fp).tospecdata(np.arange(0,5+dw/2,dw))
|
|
S1.plot()
|
|
St.plot('-.')
|
|
plt.axis([0, 6, 0, 0.4])
|
|
plt.show()
|
|
|
|
|
|
#! Transformed Gaussian model compared to Gaussian model
|
|
#!--------------------------------------------------------
|
|
dt = St.sampling_period()
|
|
va, sk, ku = St.stats_nl(moments='vsk')
|
|
#sa = sqrt(va)
|
|
gh = wtm.TrHermite(mean=me, sigma=sa, skew=sk, kurt=ku, ysigma=sa)
|
|
|
|
ysim_t = St.sim(ns=240, dt=0.5)
|
|
xsim_t = ysim_t.copy()
|
|
xsim_t[:,1] = gh.gauss2dat(ysim_t[:,1])
|
|
|
|
ts_y = wo.mat2timeseries(ysim_t)
|
|
ts_x = wo.mat2timeseries(xsim_t)
|
|
ts_y.plot_wave(sym1='r.', ts=ts_x, sym2='b', sigma=sa, nsub=5, nfig=1)
|
|
plt.show()
|