def simulate(true_model, npp=1024, Ntr=1, add_noise=False): print() print(f'Nonlinear parameters:', f'{len(true_model.nlx.active) + len(true_model.nly.active)}') print(f'Parameters to estimate: {true_model.npar}') # set non-active coefficients to zero. Note order of input matters idx = np.setdiff1d(np.arange(true_model.E.size), true_model.nlx.active) idy = np.setdiff1d(np.arange(true_model.F.size), true_model.nly.active) true_model.E.flat[idx] = 0 true_model.F.flat[idy] = 0 # get predictable random numbers. https://dilbert.com/strip/2001-10-25 np.random.seed(10) # shape of u from multisine: (R,P*npp) u, lines, freq = multisine(N=npp, P=P, R=R, lines=kind, rms=RMSu) # Transient: Add Ntr periods before the start of each realization. To # generate steady state data. T1 = np.r_[npp * Ntr, np.r_[0:(R - 1) * P * npp + 1:P * npp]] _, yorig, _ = true_model.simulate(u.ravel(), T1=T1) u = u.reshape((R, P, npp)).transpose((2, 0, 1))[:, None] # (npp,m,R,P) y = yorig.reshape((R, P, npp, p)).transpose((2, 3, 0, 1)) # Add colored noise to the output. randn generate white noise if add_noise: np.random.seed(10) noise = 1e-3 * np.std(y[:, -1, -1]) * np.random.randn(*y.shape) # Do some filtering to get colored noise noise[1:-2] += noise[2:-1] y += noise return {'y': y, 'u': u, 'lines': lines, 'freq': freq}
def simulate(true_model, npp=1024, Ntr=1, Rest=2, add_noise=False): print() print(f'Nonlinear parameters:', f'{len(true_model.nlx.active) + len(true_model.nly.active)}') print(f'Parameters to estimate: {true_model.npar}') # set non-active coefficients to zero. Note order of input matters idx = np.setdiff1d(np.arange(true_model.E.size), true_model.nlx.active) idy = np.setdiff1d(np.arange(true_model.F.size), true_model.nly.active) true_model.E.flat[idx] = 0 true_model.F.flat[idy] = 0 # get predictable random numbers. https://dilbert.com/strip/2001-10-25 np.random.seed(10) # shape of u from multisine: (R,P*npp) u, lines, freq = multisine(N=npp, P=P, R=R, lines=kind, rms=RMSu) # Transient: Add Ntr periods before the start of each realization. To # generate steady state data. T1 = np.r_[npp * Ntr, np.r_[0:(R - 1) * P * npp + 1:P * npp]] _, yorig, _ = true_model.simulate(u.ravel(), T1=T1) u = u.reshape((R, P, npp)).transpose((2, 0, 1))[:, None] # (npp,m,R,P) y = yorig.reshape((R, P, npp, p)).transpose((2, 3, 0, 1)) # Add colored noise to the output. randn generate white noise if add_noise: np.random.seed(10) noise = 1e-3 * np.std(y[:, -1, -1]) * np.random.randn(*y.shape) # Do some filtering to get colored noise noise[1:-2] += noise[2:-1] y += noise ## START of Identification ## # partitioning the data. Use last period of two last realizations. # test for performance testing and val for model selection utest = u[:, :, -1, -1] ytest = y[:, :, -1, -1] uval = u[:, :, -2, -1] yval = y[:, :, -2, -1] # all other realizations are used for estimation uest = u[..., :Rest, :] yest = y[..., :Rest, :] # noise estimate over periods. This sets the performace limit for the # estimated model covY = covariance(yest) # create signal object sig = Signal(uest, yest, fs=fs) sig.lines = lines # plot periodicity for one realization to verify data is steady state # sig.periodicity() # Calculate BLA, total- and noise distortion. Used for subspace # identification sig.bla() # average signal over periods. Used for training of PNLSS model um, ym = sig.average() return Data(sig, uest, yest, uval, yval, utest, ytest, um, ym, covY, freq, lines, npp, Ntr)
nldof = np.argwhere(w).item() ndof = M.shape[0] # Fixed contact and free natural frequencies (rad/s). om_fixed = data['om_fixed'].squeeze() om_free = data['om_free'].squeeze() #data2 = loadmat('data/b4_A1_up1_ms_full.mat') #u = data2['u'].squeeze() #freq = data2['freq'].squeeze() #fs = data2['fs'].item() #dt = 1/fs #nsint = len(u) #Ntint = nsint np.random.seed(0) u, lines, freq = multisine(f0, f1, N=Ntint, fs=fsint, R=R, P=P) fext = np.zeros((nsint, ndof)) nls = NLS(Tanhdryfriction(eps=eps, w=w, kt=muN)) sys = Newmark(M, C, K, nls) for A in Avec: fext[:, fdof] = A * u.ravel() print(f'Newmark started with ns: {nsint}, A: {A}') try: x, xd, xdd = sys.integrate(fext, dt, x0=None, v0=None, sensitivity=False) if scan: np.savez(f'data/scan_A{A}.npz',
# excitation signal RMSu = 0.05 # Root mean square value for the input signal npp = 2048 # Number of samples R = 3 # Number of phase realizations (one for validation and one for # testing) P = 3 # Number of periods kind = 'Odd' # 'Full','Odd','SpecialOdd', or 'RandomOdd': kind of multisine m = D.shape[1] # number of inputs p = C.shape[0] # number of outputs fs = 1 # normalized sampling rate Ntr = 2 if True: # get predictable random numbers. https://dilbert.com/strip/2001-10-25 np.random.seed(10) # shape of u from multisine: (R,P*npp) u, lines, freq = multisine(N=npp, P=P, R=R, lines=kind, rms=RMSu) # if multiple input is required, this will copy u m times # Transient: Add one period before the start of each realization. To generate # steady state data. T1 = np.r_[npp * Ntr, np.r_[0:(R - 1) * P * npp + 1:P * npp]] _, yorig, _ = true_model.simulate(u.ravel(), T1=T1) print(norm(yorig)) u = u.reshape((R, P, npp)).transpose((2, 0, 1))[:, None] # (npp,m,R,P) y = yorig.reshape((R, P, npp, p), order='C').transpose((2, 3, 0, 1)) #y = yorig.reshape((R,P,npp)).transpose((2,0,1))[:,None] # or in F order: # y2 = yorig.reshape((npp,P,R,p),order='F').transpose((0,3,2,1)) # Add colored noise to the output. randn generate white noise
# euler discretization Ed[ndof + nldof] = -muN * dt dmodel = NLSS(dsys.A, dsys.B, dsys.C, dsys.D, Ed, Fd, dt=dsys.dt) dmodel.add_nl(nlx=nlx, nly=nly) # newmark nls = nmNLS(nmTanhdryfriction(eps=eps, w=w, kt=muN)) nls = nmNLS(nmPolynomial(exp=exponent, w=w, k=muN)) # nls = None sys = Newmark(M, C, K, nls) nm = False np.random.seed(0) ud, linesd, freqd = multisine(f1, f2, N=nppint, fs=fsint, R=R, P=P) fext = np.zeros((nsint, ndof)) for A in Avec: print(f'Discrete started with ns: {nsint}, A: {A}, R: {R}, P: {P}, ' f'upsamp: {upsamp}, eps:{eps}') # Transient: Add periods before the start of each realization. To generate # steady state data. T1 = np.r_[npp * Ntr, np.r_[0:(R - 1) * P * nppint + 1:P * nppint]] fext[:, fdof] = A * ud.ravel() _, yd, xd = dmodel.simulate(fext, T1=T1) yc, xc, uc, linesc = simulate_cont(cmodel, A, tc) try: ynm, ydnm, yddnm = sys.integrate(fext, dt,
pol1 = Polynomial(w=[1, 0], exp=3, k=mu1) pol2 = Polynomial(w=[0, 1], exp=3, k=mu2) nls = NLS([pol1, pol2]) #nls = NLS() f0 = 1e-4 / 2 / np.pi f1 = 5 / 2 / np.pi fs = 10 T = 100 ns = fs * T t = np.arange(ns) / fs # t = np.linspace(0, T, T*fs, endpoint=False) u = chirp(t, f0=f0, f1=f1, t1=T, method='linear') u, lines, freq = multisine(f0, f1, N=1024, fs=fs, R=4, P=4) ns = 1024 * 4 * 4 t = np.arange(ns) / fs fdof = 0 fext = np.zeros((ns, ndof)) fext[:, fdof] = u.ravel() sys = Newmark(M, C, K, nls) dt = t[1] - t[0] x, xd, xdd = sys.integrate(fext, dt, x0=0, v0=0, sensitivity=False) plt.figure() plt.plot(t, x, label=r'$x_1$') #plt.plot(t, x, '-r', label=r'$x_2$') plt.xlabel('Time (t)') plt.ylabel('Displacement (m)')
plt.ylabel('Amplitude (dB)') plt.title(f'Phase realization {i+1}') plt.subplot(2,2,3+i) plt.plot(np.angle(U),'+') plt.xlabel('Frequency line') plt.ylabel('Phase (rad)') plt.title(f'Phase realization {i+1}') # Generate two realizations of a full multisine with 1000 samples and # excitation up to one third of the Nyquist frequency N = 1000 # One thousand samples kind = 'full' # Full multisine f2 = round(N//6) # Excitation up to one sixth of the sample frequency R = 2 # Two phase realizations u, lines, freq = multisine(f2=f2,N=N,lines=kind,R=R) # Check spectra plot(u) # The two realizations have the same amplitude spectrum, but different phase # realizations (uniformly distributed between [-π,π)) # Generate a random odd multisine where the excited odd lines are split in # groups of three consecutive lines and where one line is randomly chosen in # each group to be a detection line (i.e. without excitation) N = 1000 kind = 'oddrandom' f2 = round(N//6) R = 1 # One out of three consecutive odd lines is randomly selected to be a detection line ngroup = 3 u1,lines, freq = multisine(f2=f2,N=N,lines=kind,R=R,ngroup=ngroup)