def plot(res, data, p): figs = {} lines = data.lines freq = data.freq Pest = data.yest.shape[3] # result on validation data N = len(data.yval) freq = np.arange(N) / N * fs plottime = res.val_err plotfreq = np.fft.fft(plottime, axis=0) / np.sqrt(N) plt.figure() plt.plot(freq[lines], db(plotfreq[lines, p]), '.') plt.plot(freq[lines], db(np.sqrt(Pest * data.covY[lines, p, p].squeeze() / N)), '.') plt.xlabel('Frequency') plt.ylabel('Output (errors) (dB)') plt.legend(('Output', ) + res.descrip + ('Noise', )) plt.title(f'Validation results p:{p}') figs['val_data'] = (plt.gcf(), plt.gca()) # optimization path for NLSS plt.figure() plt.plot(db(res.nl_errvec)) imin = np.argmin(res.nl_errvec) plt.scatter(imin, db(res.nl_errvec[imin])) plt.xlabel('Successful iteration number') plt.ylabel('Validation error [dB]') plt.title('Selection of the best model on a separate data set') figs['pnlss_path'] = (plt.gcf(), plt.gca()) return figs
def plot_bla(res, data, p): figs = {} lines = data.lines freq = data.freq npp, _, R, P = data.yest.shape # BLA plot. We can estimate nonlinear distortion # total and noise distortion averaged over P periods and M realizations # total distortion level includes nonlinear and noise distortion plt.figure() # When comparing distortion(variance, proportional to power) with # G(propertional to amplitude(field)), there is two definations for dB: # dB for power: Lp = 10 log10(P). # dB for field quantity: Lf = 10 log10(F²) # Alternative calc: bla_noise = db(np.abs(sig.covGn[:,pp,pp])*R, 'power') # if the signal is noise-free, fix noise so we see it in plot bla_noise = db(np.sqrt(np.abs(data.sig.covGn[:, p, p]) * R)) bla_noise[bla_noise < -150] = -150 try: # in case R=1 bla_tot = db(np.sqrt(np.abs(data.sig.covG[:, p, p]) * R)) bla_tot[bla_tot < -150] = -150 except TypeError: bla_tot = [np.nan] * len(lines) plt.plot(freq[lines], db(np.abs(data.sig.G[:, p, 0]))) plt.plot(freq[lines], bla_noise, 's') plt.plot(freq[lines], bla_tot, '*') plt.xlabel('Frequency (Hz)') plt.ylabel('magnitude (dB)') plt.title(f'Estimated BLA and nonlinear distortion p: {p}') plt.legend(('BLA FRF', 'Noise Distortion', 'Total Distortion')) # plt.gca().set_ylim(bottom=-150) figs['bla'] = (plt.gcf(), plt.gca()) return figs
def calc_model(model): # calculate statistic from loaded models db_val = db(rms2(model['val_err'])) db_est = db(rms(model['est_err'])) mean = db_val.mean(1) std = db_val.std(1) best = db_val.min(1) idx = np.argmin(db_val, axis=1) d = {'descrip': model['descrip'], 'db':db_val, 'mean': mean, 'std': std, 'best': best, 'idx':idx, 'opt_path':model['opt_path'], 'db_est':db_est, 'val_err':model['val_err'], 'models':model['models']} return d
def opt_path(*data, descrip='', samefig=False): # optimization path if not samefig: plt.figure() data = data if isinstance(data[0], list) else [data] for j, errs in enumerate(data): for err in (errs): plt.plot(db(err)) imin = np.argmin(err) plt.scatter(imin, db(err[imin])) plt.xlabel('Successful iteration number') plt.ylabel('Validation error [dB]') plt.xlim([0,50]) plt.title(f'Selection of the best model on a separate data set: {descrip}') figs[f'{descrip}_path'] = (plt.gcf(), plt.gca())
def plot_path(res, data, p): figs = {} plt.figure() for desc, err in res.errvec.items(): if len(err) == 0: continue # optimization path for NLSS plt.plot(db(err), label=desc) imin = np.argmin(err) plt.scatter(imin, db(err[imin])) plt.xlabel('Successful iteration number') plt.ylabel('Validation error [dB]') plt.title('Selection of the best model on a separate data set') plt.legend() figs['path'] = (plt.gcf(), plt.gca()) return figs
def plot_val(res, data, p): figs = {} lines = data.lines freq = data.freq Pest = data.yest.shape[3] # result on validation data N = len(data.yval) freq = np.arange(N) / N * fs plottime = res.val_err plotfreq = np.fft.fft(plottime, axis=0) / np.sqrt(N) plt.figure() plt.plot(freq[lines], db(plotfreq[lines, p]), '.') plt.plot(freq[lines], db(np.sqrt(Pest * data.covY[lines, p, p].squeeze() / N)), '.') plt.xlabel('Frequency') plt.ylabel('Output (errors) (dB)') plt.legend(('Output', ) + res.descrip + ('Noise', )) plt.title(f'Validation results p:{p}') figs['val_error'] = (plt.gcf(), plt.gca()) return figs
def plot(sig): plt.figure() for i, u in enumerate(sig): U = np.fft.fft(u) plt.subplot(2,2,1+i) plt.plot(db(U),'+') plt.xlabel('Frequency line') 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}')
dt, x0=None, v0=None, sensitivity=False) if scan: np.savez(f'data/scan_A{A}.npz', x=x, freq=freq, Ntint=Ntint, fdof=fdof, nldof=nldof) # plot frf for forcing and tanh node Y = np.fft.fft(x[-Ntint:, [fdof, nldof]], axis=0) nfd = Y.shape[0] // 2 plt.figure() plt.plot(freq[:nfd], db(np.abs(Y[:nfd]))) plt.xlim([0, 50]) plt.xlabel('Frequency (Hz)') plt.ylabel('Amplitude (dB)') plt.legend(['Force dof', 'nl dof']) plt.minorticks_on() plt.grid(which='both') plt.savefig(f'fig/nm_b{benchmark}_A{A}_fft_comp_n{fdof}.png') except ValueError as e: print(f'Newmark integration failed with error {e}. For A: {A}') # We need to reshape into (npp,m,R,P) fext = fext.reshape(R, P, Ntint, ndof).transpose(2, 3, 0, 1) # fext.shape = (Ntint,P,R,ndof) x = x.reshape(R, P, Ntint, ndof).transpose(2, 3, 0, 1) xd = xd.reshape(R, P, Ntint, ndof).transpose(2, 3, 0, 1)
plt.figure() plt.plot(est_err[:, pp]) plt.xlabel('Time index') plt.ylabel('Output (errors)') plt.legend(('Output', ) + descrip) plt.title(f'Estimation results p:{pp}') figs['estimation_error'] = (plt.gcf(), plt.gca()) # result on validation data N = len(yval) freq = np.arange(N) / N * fs plottime = val_err plotfreq = np.fft.fft(plottime, axis=0) / np.sqrt(N) nfd = plotfreq.shape[0] plt.figure() plt.plot(freq[lines], db(plotfreq[lines, pp]), '.') plt.plot(freq[lines], db(np.sqrt(Pest * covY[lines, pp, pp].squeeze() / N)), '.') plt.xlabel('Frequency') plt.ylabel('Output (errors) (dB)') plt.legend(('Output', ) + descrip + ('Noise', )) plt.title(f'Validation results p:{pp}') figs['val_data'] = (plt.gcf(), plt.gca()) # result on test data N = len(ytest) freq = np.arange(N) / N * fs plottime = test_err plotfreq = np.fft.fft(plottime, axis=0) / np.sqrt(N) nfd = plotfreq.shape[0] plt.figure()
dt, x0=None, v0=None, sensitivity=False) Ynm = np.fft.fft(ynm[-nppint:, [fdof, nldof]], axis=0) nm = True except ValueError as e: print(f'Discrete stepping failed with error {e}. For A: {A}') #if scan: # plot frf for forcing and tanh node Yd = np.fft.fft(yd[-nppint:, [fdof, nldof]], axis=0) Yc = np.fft.fft(yc[-nppint:, [fdof, nldof]], axis=0) nfd = Yd.shape[0] // 2 plt.figure() plt.plot(freqd[:nfd], db(np.abs(Yd[:nfd]))) if nm: plt.plot(freqd[:nfd], db(np.abs(Ynm[:nfd]))) nm = False plt.plot(freqc[:nfd], db(np.abs(Yc[:nfd]))) plt.xlim([0, 50]) plt.ylim(bottom=-150) plt.xlabel('Frequency (Hz)') plt.ylabel('Amplitude (dB)') plt.legend([ 'd: Force dof', 'd: nl dof', 'nm: Force dof', 'nm: nl dof', 'c: Force dof', 'c: nl dof' ]) plt.title(f'A: {A}') plt.minorticks_on() plt.grid(which='both')
plt.plot(est_err[::resamp]) plt.xlabel('Time index') plt.ylabel('Output (errors)') plt.legend(('Output', ) + descrip) plt.title('Estimation results') figs['estimation_error'] = (plt.gcf(), plt.gca()) # result on validation data resamp = 2 plt.figure() plottime = val_err N = plottime.shape[0] freq = np.arange(N) / N * fs plotfreq = np.fft.fft(plottime, axis=0) / np.sqrt(N) nfd = plotfreq.shape[0] plt.plot(freq[1:nfd // 2:resamp], db(plotfreq[1:nfd // 2:resamp]), '.') #plt.ylim([-110,10]) plt.xlim((0, 300)) plt.xlabel('Frequency') plt.ylabel('Output (errors) (dB)') plt.legend(('Output', ) + descrip + ('Noise', )) plt.title('Validation results') figs['val_data'] = (plt.gcf(), plt.gca()) # result on test data resamp = 2 plt.figure() plottime = test_err N = plottime.shape[0] freq = np.arange(N) / N * fs plotfreq = np.fft.fft(plottime, axis=0) / np.sqrt(N)
natfreq = modal['wn'] dampfreq = modal['wd'] damping = modal['zeta'] nw = min(len(natfreq), 8) print('Undamped ω: {}'.format(natfreq[:nw]*sca)) print('damped ω: {}'.format(dampfreq[:nw]*sca)) print('damping: {}'.format(damping[:nw])) return modal # FRF frf = FRF(nlin, fmin=1e-3, fmax=5/2/np.pi) frf_freq, frf_H = frf.periodic() print('## linear identified at low level') print_modal(fnsi_lin) print('## linear identified at high level') print_modal(fnsi2) print('## nonlinear identified at high level') print_modal(fnsi) fH1, ax = plt.subplots() ax.plot(frf_freq*sca, db(np.abs(frf_H[dof])), '-.k', label='From signal') plot_linfrf(fnsi_lin, dof, sca=sca, fig=fH1, ax=ax, label='lin low level') plot_linfrf(fnsi, dof, sca=sca, fig=fH1, ax=ax, label='nl high level') plot_linfrf(fnsi2, dof, sca=sca, fig=fH1, ax=ax, ls='--', label='lin high level') # ax.set_title(''); ax.legend_ = None ax.legend() plt.show()
plt.plot(est_err[::resamp]) plt.xlabel('Time index') plt.ylabel('Output (errors)') plt.legend(['Output'] + descrip) plt.title('Estimation results') figs['estimation_error'] = (plt.gcf(), plt.gca()) # result on validation data resamp = 1 plt.figure() plottime = val_err N = plottime.shape[0] freq = np.arange(N) / N * fs plotfreq = np.fft.fft(plottime, axis=0) / np.sqrt(N**2) nfd = plotfreq.shape[0] plt.plot(freq[:nfd // 2:resamp], db(plotfreq[:nfd // 2:resamp]), '.') plt.plot(freq[:nfd // 2:resamp], db(noise[:nfd // 2:resamp] / N), 'k.') plt.xlim((5, 150)) plt.ylim((-160, -80)) plt.xlabel('Frequency') plt.ylabel('Output (errors) (dB)') plt.legend(['Output'] + descrip + ['Noise']) plt.title('Validation results') figs['val_data'] = (plt.gcf(), plt.gca()) # result on test data resamp = 30 plt.figure() plottime = test_err N = plottime.shape[0] freq = np.arange(N) / N * fs
plt.figure() plt.plot(freq[lines], coef) #plt.ylim([0.9e8, 1.1e8]) plt.xlabel('Frequency (Hz)') plt.ylabel(f'Real part of the NL coefficient (N/m^{exp})') # subspace ID sig.bla() #linmodel1 = Subspace(sig) #linmodel1.estimate(n=n, r=r, weight=False, bd_method=bd_method) #linmodel2 = deepcopy(linmodel1) #linmodel2.optimize(weight=False, info=1) plt.figure() plt.plot(freq[lines], db(np.abs(sig.G[:,0,0]))) ## DEBUG STUFF #from pyvib.subspace import bd_nr, output_costfcn, frf_jacobian, jacobian_freq #from scipy.io import loadmat #data = loadmat('test.mat') #U = data['E'].T #Y = data['Y'].T #lines = data['flines'].squeeze() #A = data['A'].astype(float) #C = data['C'].astype(float) #N = data['N'].item() #theta = data['theta'].squeeze().astype(int) #freq = lines/N
print(f'rms error est:\n {rms(est_err[:,1:])}\ndb: {db(rms(est_err[:,1:]))}') print(f'rms error val:\n {rms(val_err[:,1:])}\ndb: {db(rms(val_err[:,1:]))}') print(f'rms error test:\n {rms(test_err[:,1:])}\ndb: {db(rms(test_err[:,1:]))}') if savedata: fname = 'boucwen_lin.pkl' if len(models) > 1: fname = f'boucwen_W_{weight}_full' with open(fname + '.pkl', 'wb') as f: pickler = pickle.Pickler(f) data = {'models':models, 'opt_path':opt_path, 'est_err':est_err, 'val_err':val_err, 'test_err':test_err, 'descrip':descrip} pickler.dump(data) data = np.vstack([rms(est_err[:,1:]), rms(val_err[:,1:]), rms(test_err[:,1:])]) data = np.char.mod("%4.2f",db(data)) data = np.vstack([descrip, data]).T np.savetxt(fname + '.csv', data,fmt='%12s, %s, %s, %s',header='type, est, val, test') ## Plots ## # store figure handle for saving the figures later figs = {} # plt.ion() # linear and nonlinear model error resamp = 20 plt.figure() plt.plot(est_err[::resamp]) plt.xlabel('Time index') plt.ylabel('Output (errors)')
plt.ion() # linear and nonlinear model error resamp = 1 plt.figure() plt.plot(ym[::resamp]) plt.plot(ym[::resamp] - ylin[::resamp]) plt.plot(ym[::resamp] - ynlin[::resamp]) plt.xlabel('Time index') plt.ylabel('Output (errors)') plt.legend(('output', 'linear error', 'PNLSS error')) plt.title('Estimation results') figs['estimation_error'] = (plt.gcf(), plt.gca()) # optimization path for PNLSS plt.figure() plt.plot(db(nl_errvec)) imin = np.argmin(nl_errvec) plt.scatter(imin, db(nl_errvec[imin])) plt.xlabel('Successful iteration number') plt.ylabel('Validation error [dB]') plt.title('Selection of the best model on a separate data set') figs['pnlss_path'] = (plt.gcf(), plt.gca()) # result on validation data plt.figure() N = len(yval) resamp = 1 freq = np.arange(N) / N * fs # plot only for the DOF with the nonlinear connection plottime = np.hstack((yval, yval - ylval, yval - ynlval))[:, 6] plotfreq = np.fft.fft(plottime, axis=0) / sqrt(N)
# extract relevant val error. So we don't pollute plot with unneeded data data = [] descrip = [] extract_val_err(fnsid,[0,1,2,4,5]) extract_val_err(pnlssd, [2]) data = np.array(data) yval = yval_raw[:,:,40,-1] plt.figure() N = len(yval) freq = np.arange(N)/N*fs plottime = np.hstack((yval, data.T)) plotfreq = np.fft.fft(plottime, axis=0)/np.sqrt(N) nfd = plotfreq.shape[0] plt.plot(freq[lines], db(plotfreq[lines]), '.') plt.plot(freq[lines], db(noise[lines] / np.sqrt(N)), 'k.') plt.ylim([-110,10]) plt.xlabel('Frequency') plt.ylabel('Output (errors) (dB)') plt.legend(['Output'] + descrip + ['Noise']) plt.title(f'Validation results') figs[f'val_data'] = (plt.gcf(), plt.gca()) # # result on estimation data # resamp = 1 # plt.figure() # plt.plot(est_err) # plt.xlabel('Time index') # plt.ylabel('Output (errors)')