def test_OKID(self): for case in ['SISO', 'SIMO', 'MISO', 'MIMO']: inputs = util.load_array_text(join(join(self.test_dir, case), 'inputs.txt')) outputs = util.load_array_text(join(join(self.test_dir, case), 'outputs.txt')) (num_inputs, nt) = inputs.shape (num_outputs, nt2) = outputs.shape assert(nt2 == nt) Markovs_true = np.zeros((nt, num_outputs, num_inputs)) temp = util.load_array_text(join(join(self.test_dir, case), 'Markovs_Matlab_output1.txt')) temp = temp.reshape((num_inputs, -1)) num_Markovs_OKID = temp.shape[1] Markovs_Matlab = np.zeros((num_Markovs_OKID, num_outputs, num_inputs)) for iOut in range(num_outputs): data = util.load_array_text(join(join( self.test_dir, case), 'Markovs_Matlab_output%d.txt'%(iOut+1))) if num_inputs > 1: data = np.swapaxes(data, 0, 1) Markovs_Matlab[:,iOut,:] = data data = util.load_array_text(join(join( self.test_dir, case), 'Markovs_true_output%d.txt'%(iOut+1))) if num_inputs > 1: data = np.swapaxes(data, 0, 1) Markovs_true[:,iOut,:] = data Markovs_python = OKID(inputs, outputs, num_Markovs_OKID) if plot: PLT.figure(figsize=(14,10)) for output_num in range(num_outputs): for input_num in range(num_inputs): PLT.subplot(num_outputs, num_inputs, output_num*(num_inputs) + input_num + 1) PLT.hold(True) PLT.plot(Markovs_true[:,output_num,input_num],'k*-') PLT.plot(Markovs_Matlab[:,output_num,input_num],'b--') PLT.plot(Markovs_python[:,output_num,input_num],'r.') PLT.legend(['True', 'Matlab OKID', 'Python OKID']) PLT.title('Input %d to output %d'%(input_num+1, output_num+1)) PLT.show() #print 'Diff between matlab and python is',diff(Markovs_Matlab, Markovs_python) np.testing.assert_allclose(Markovs_python, Markovs_Matlab, atol=1e-3, rtol=1e-3) np.testing.assert_allclose(Markovs_python, Markovs_true[:num_Markovs_OKID], atol=1e-3, rtol=1e-3)
def test_load_save_array_text(self): """Test that can read/write text arrays""" rows = [1, 5, 20] cols = [1, 4, 5, 23] array_path = join(self.test_dir, 'test_array.txt') delimiters = [',', ' ', ';'] for delimiter in delimiters: for is_complex in [False, True]: for squeeze in [False, True]: for num_rows in rows: for num_cols in cols: # Generate real and complex arrays array = np.random.random((num_rows, num_cols)) if is_complex: array = array + (1j * np.random.random( (num_rows, num_cols))) # Check row and column vectors, no squeeze (1, 1) if squeeze and (num_rows > 1 or num_cols > 1): array = np.squeeze(array) util.save_array_text(array, array_path, delimiter=delimiter) array_read = util.load_array_text( array_path, delimiter=delimiter, is_complex=is_complex) if squeeze: array_read = np.squeeze(array_read) np.testing.assert_equal(array_read, array)
def test_put_gets(self): test_dir = 'DELETE_ME_test_files_pod' if not os.access('.', os.W_OK): raise RuntimeError('Cannot write to current directory') if not os.path.isdir(test_dir): _parallel.call_from_rank_zero(os.mkdir, test_dir) num_vecs = 10 num_states = 30 correlation_mat_true = _parallel.call_and_bcast( np.random.random, ((num_vecs, num_vecs))) eigen_vals_true = _parallel.call_and_bcast(np.random.random, num_vecs) eigen_vecs_true = _parallel.call_and_bcast(np.random.random, ((num_states, num_vecs))) my_POD = PODHandles(None, verbosity=0) my_POD.correlation_mat = correlation_mat_true my_POD.eigen_vals = eigen_vals_true my_POD.eigen_vecs = eigen_vecs_true _parallel.barrier() eigen_vecs_path = join(test_dir, 'eigen_vecs.txt') eigen_vals_path = join(test_dir, 'eigen_vals.txt') correlation_mat_path = join(test_dir, 'correlation.txt') my_POD.put_decomp(eigen_vecs_path, eigen_vals_path) my_POD.put_correlation_mat(correlation_mat_path) POD_load = PODHandles(None, verbosity=0) POD_load.get_decomp(eigen_vecs_path, eigen_vals_path) correlation_mat_loaded = util.load_array_text(correlation_mat_path) np.testing.assert_allclose(correlation_mat_loaded, correlation_mat_true) np.testing.assert_allclose(POD_load.eigen_vecs, eigen_vecs_true) np.testing.assert_allclose(POD_load.eigen_vals, eigen_vals_true)
def test_put_reduced_arrays(self): """Test putting reduced mats""" A_reduced_path = join(self.test_dir, 'A.txt') B_reduced_path = join(self.test_dir, 'B.txt') C_reduced_path = join(self.test_dir, 'C.txt') A = parallel.call_and_bcast(np.random.random, ((10, 10))) B = parallel.call_and_bcast(np.random.random, ((1, 10))) C = parallel.call_and_bcast(np.random.random, ((10, 2))) LTI_proj = lgp.LTIGalerkinProjectionBase() LTI_proj.A_reduced = A.copy() LTI_proj.B_reduced = B.copy() LTI_proj.C_reduced = C.copy() LTI_proj.put_model(A_reduced_path, B_reduced_path, C_reduced_path) np.testing.assert_equal(util.load_array_text(A_reduced_path), A) np.testing.assert_equal(util.load_array_text(B_reduced_path), B) np.testing.assert_equal(util.load_array_text(C_reduced_path), C)
def test_load_save_array_text(self): """Test that can read/write text matrices""" #tol = 1e-8 rows = [1, 5, 20] cols = [1, 4, 5, 23] mat_path = join(self.test_dir, 'test_matrix.txt') delimiters = [',', ' ', ';'] for delimiter in delimiters: for is_complex in [False, True]: for squeeze in [False, True]: for num_rows in rows: for num_cols in cols: mat_real = np.random.random((num_rows, num_cols)) if is_complex: mat_imag = np.random.random( (num_rows, num_cols)) mat = mat_real + 1J * mat_imag else: mat = mat_real # Check row and column vectors, no squeeze (1,1) if squeeze and (num_rows > 1 or num_cols > 1): mat = np.squeeze(mat) util.save_array_text(mat, mat_path, delimiter=delimiter) mat_read = util.load_array_text( mat_path, delimiter=delimiter, is_complex=is_complex) if squeeze: mat_read = np.squeeze(mat_read) np.testing.assert_allclose(mat_read, mat) #,rtol=tol)
def test_load_save_array_text(self): """Test that can read/write text matrices""" #tol = 1e-8 rows = [1, 5, 20] cols = [1, 4, 5, 23] mat_path = join(self.test_dir, 'test_matrix.txt') delimiters = [',', ' ', ';'] for delimiter in delimiters: for is_complex in [False, True]: for squeeze in [False, True]: for num_rows in rows: for num_cols in cols: mat_real = np.random.random((num_rows, num_cols)) if is_complex: mat_imag = np.random.random((num_rows, num_cols)) mat = mat_real + 1J*mat_imag else: mat = mat_real # Check row and column vectors, no squeeze (1,1) if squeeze and (num_rows > 1 or num_cols > 1): mat = np.squeeze(mat) util.save_array_text(mat, mat_path, delimiter=delimiter) mat_read = util.load_array_text(mat_path, delimiter=delimiter, is_complex=is_complex) if squeeze: mat_read = np.squeeze(mat_read) np.testing.assert_allclose(mat_read, mat)#,rtol=tol)
def test_load_save_array_text(self): """Test that can read/write text arrays""" rows = [1, 5, 20] cols = [1, 4, 5, 23] array_path = join(self.test_dir, 'test_array.txt') delimiters = [',', ' ', ';'] for delimiter in delimiters: for is_complex in [False, True]: for squeeze in [False, True]: for num_rows in rows: for num_cols in cols: # Generate real and complex arrays array = np.random.random((num_rows, num_cols)) if is_complex: array = array + ( 1j * np.random.random((num_rows, num_cols))) # Check row and column vectors, no squeeze (1, 1) if squeeze and (num_rows > 1 or num_cols > 1): array = np.squeeze(array) util.save_array_text( array, array_path, delimiter=delimiter) array_read = util.load_array_text( array_path, delimiter=delimiter, is_complex=is_complex) if squeeze: array_read = np.squeeze(array_read) np.testing.assert_equal(array_read, array)
def test_put_gets(self): test_dir = 'DELETE_ME_test_files_pod' if not os.access('.', os.W_OK): raise RuntimeError('Cannot write to current directory') if not os.path.isdir(test_dir): _parallel.call_from_rank_zero(os.mkdir, test_dir) num_vecs = 10 num_states = 30 correlation_mat_true = _parallel.call_and_bcast( np.random.random, ((num_vecs, num_vecs))) eigen_vals_true = _parallel.call_and_bcast( np.random.random, num_vecs) eigen_vecs_true = _parallel.call_and_bcast( np.random.random, ((num_states, num_vecs))) my_POD = PODHandles(None, verbosity=0) my_POD.correlation_mat = correlation_mat_true my_POD.eigen_vals = eigen_vals_true my_POD.eigen_vecs = eigen_vecs_true _parallel.barrier() eigen_vecs_path = join(test_dir, 'eigen_vecs.txt') eigen_vals_path = join(test_dir, 'eigen_vals.txt') correlation_mat_path = join(test_dir, 'correlation.txt') my_POD.put_decomp(eigen_vecs_path, eigen_vals_path) my_POD.put_correlation_mat(correlation_mat_path) POD_load = PODHandles(None, verbosity=0) POD_load.get_decomp(eigen_vecs_path, eigen_vals_path) correlation_mat_loaded = util.load_array_text(correlation_mat_path) np.testing.assert_allclose(correlation_mat_loaded, correlation_mat_true) np.testing.assert_allclose(POD_load.eigen_vecs, eigen_vecs_true) np.testing.assert_allclose(POD_load.eigen_vals, eigen_vals_true)
def test_compute_model(self): """ Test ROM Markov params similar to those given - generates data - assembles Hankel array - computes SVD - forms the ROM discrete arrays A, B, and C (D = 0) - Tests Markov parameters from ROM are approx. equal to full plant's """ num_time_steps = 40 num_states_plant = 12 num_states_model = num_states_plant // 3 for num_inputs in [1, 3]: for num_outputs in [1, 2]: for sample_interval in [1, 2, 4]: time_steps = make_time_steps(num_time_steps, sample_interval) A, B, C = util.drss(num_states_plant, num_inputs, num_outputs) my_ERA = era.ERA(verbosity=0) Markovs = util.impulse(A, B, C, time_steps[-1] + 1) Markovs = Markovs[time_steps] if sample_interval == 2: time_steps, Markovs =\ era.make_sampled_format(time_steps, Markovs) num_time_steps = time_steps.shape[0] A_path_computed = join(self.test_dir, 'A_computed.txt') B_path_computed = join(self.test_dir, 'B_computed.txt') C_path_computed = join(self.test_dir, 'C_computed.txt') A, B, C = my_ERA.compute_model(Markovs, num_states_model) my_ERA.put_model(A_path_computed, B_path_computed, C_path_computed) #sing_vals = my_ERA.sing_vals[:num_states_model] # Flatten vecs into 2D X and Y arrays: # [B AB A**PB A**(P+1)B ...] #direct_vecs_flat = direct_vecs.swapaxes(0,1).reshape( # (num_states_model,-1))) # Exact grammians from Lyapunov eqn solve #gram_cont = util.solve_Lyapunov(A, B*B.H) #gram_obs = util.solve_Lyapunov(A.H, C.H*C) #print(np.sort(np.linalg.eig(gram_cont)[0])[::-1]) #print(sing_vals) #np.testing.assert_allclose(gram_cont.diagonal(), # sing_vals, atol=.1, rtol=.1) #np.testing.assert_allclose(gram_obs.diagonal(), # sing_vals, atol=.1, rtol=.1) #np.testing.assert_allclose(np.sort(np.linalg.eig( # gram_cont)[0])[::-1], sing_vals, # atol=.1, rtol=.1) #np.testing.assert_allclose(np.sort(np.linalg.eig( # gram_obs)[0])[::-1], sing_vals, # atol=.1, rtol=.1) # Check that the diagonals are largest entry on each row #self.assertTrue((np.max(np.abs(gram_cont),axis=1) == # np.abs(gram_cont.diagonal())).all()) #self.assertTrue((np.max(np.abs(gram_obs),axis=1) == # np.abs(gram_obs.diagonal())).all()) # Check the ROM Markov params match the full plant's Markovs_model = np.zeros(Markovs.shape) for ti, tv in enumerate(time_steps): Markovs_model[ti] = C.dot( np.linalg.matrix_power(A, tv).dot(B)) #print( # 'Computing ROM Markov param at time step %d' % tv) """ import matplotlib.pyplot as PLT for input_num in range(num_inputs): PLT.figure() PLT.hold(True) for output_num in range(num_outputs): PLT.plot(time_steps[:50], # Markovs_model[:50, output_num,input_num], 'ko') PLT.plot(time_steps[:50],Markovs[:50, # output_num, input_num],'rx') PLT.plot(time_steps_dense[:50], # Markovs_dense[:50, output_num, input_num],'b--') PLT.title('input %d to outputs'%input_num) PLT.legend(['ROM','Plant','Dense plant']) PLT.show() """ np.testing.assert_allclose(Markovs_model.squeeze(), Markovs.squeeze(), rtol=0.5, atol=0.5) np.testing.assert_equal( util.load_array_text(A_path_computed), A) np.testing.assert_equal( util.load_array_text(B_path_computed), B) np.testing.assert_equal( util.load_array_text(C_path_computed), C)
def test_compute_model(self): """ Test ROM Markov params similar to those given when the reduced system has the same number of states as the full system. - generates data - assembles Hankel array - computes SVD - forms the ROM discrete arrays A, B, and C (D = 0) - Tests Markov parameters from ROM are approx. equal to full plant's Also, unrelated: - Tests that saved ROM mats are equal to those returned in memory """ # Set test tolerances (for infinity norm of transfer function # difference) tf_abs_tol = 1e-6 tf_rel_tol = 1e-4 # Set time parameters for discrete-time simulation dt = 0.1 num_time_steps = 1000 # Set size of plant and model. For test, don't reduce the system, just # check that it comes back close to the original plant. Also, note that # using more than 8 states causes poorly conditioned TF coeffs # (https://github.com/scipy/scipy/issues/2980) num_states_plant = 8 num_states_model = num_states_plant # Loop through different numbers of inputs, numbers of outputs, and # sampling intervals for num_inputs in [1, 3]: for num_outputs in [1, 2]: for sample_interval in [1, 2, 4]: # Define time steps at which to save data. These will be of # the form [0, 1, p, p + 1, 2p, 2p + 1, ...] where p is the # sample interval. time_steps = make_time_steps( num_time_steps, sample_interval) # # Create a state space system # A_plant, B_plant, C_plant = util.drss( # num_states_plant, num_inputs, num_outputs) A_plant = util.load_array_text( join(self.data_dir, 'A_in%d_out%d.txt') % ( num_inputs, num_outputs)) B_plant = util.load_array_text( join(self.data_dir, 'B_in%d_out%d.txt') % ( num_inputs, num_outputs)) C_plant = util.load_array_text( join(self.data_dir, 'C_in%d_out%d.txt') % ( num_inputs, num_outputs)) # Simulate an impulse response using the state space system. # This will generate Markov parameters at all timesteps [0, # 1, 2, 3, ...]. Only keep data at the desired time steps, # which are separated by a sampling interval (see above # comment). Markovs = util.impulse( A_plant, B_plant, C_plant, time_steps[-1] + 1)[time_steps] # Compute a model using ERA my_ERA = era.ERA(verbosity=0) A_model, B_model, C_model = my_ERA.compute_model( Markovs, num_states_model) # Save ERA model to disk A_path_computed = join(self.out_dir, 'A_computed.txt') B_path_computed = join(self.out_dir, 'B_computed.txt') C_path_computed = join(self.out_dir, 'C_computed.txt') my_ERA.put_model( A_path_computed, B_path_computed, C_path_computed) # Check normalized Markovs rtol = 1e-5 # 1e-6 atol = 1e-5 # 1e-10 Markovs_model = util.impulse( A_model, B_model, C_model, time_steps[-1] + 1)[time_steps] max_Markov = np.amax(Markovs) eigs_plant = np.linalg.eig(A_plant)[0] eigs_model = np.linalg.eig(A_model)[0] # print 'markovs shape', Markovs.shape # print 'max plant eig', np.abs(eigs_plant).max() # print 'max model eig', np.abs(eigs_model).max() # print 'max plant markov', max_Markov # print 'max model markov', np.amax(Markovs_model) # print 'markov diffs', ( # Markovs - Markovs_model).squeeze().max() ''' import matplotlib.pyplot as plt plt.figure() plt.semilogy(np.abs(Markovs).squeeze(), 'b') plt.semilogy(np.abs(Markovs_model).squeeze(), 'r--') plt.axis( [0, time_steps[-1], Markovs.min(), Markovs.max()]) ''' np.testing.assert_allclose( Markovs_model.squeeze(), Markovs.squeeze(), rtol=rtol, atol=atol) # plt.show() ''' # Use Scipy to check that transfer function of ERA model is # close to transfer function of full model. Do so by # computing the infinity norm (H_inf) of the difference # between the transfer functions. Since Scipy can't handle # MIMO transfer functions, loop through each input-output # pair individually. for input_idx in range(num_inputs): for output_idx in range(num_outputs): # Compute transfer functions tf_plant = scipy.signal.StateSpace( A_plant, B_plant[:, input_idx:input_idx + 1], C_plant[output_idx:output_idx + 1, :], 0, dt=dt).to_tf() tf_model = scipy.signal.StateSpace( A_model, B_model[:, input_idx:input_idx + 1], C_model[output_idx:output_idx + 1, :], 0, dt=dt).to_tf() tf_diff = util.sub_transfer_functions( tf_plant, tf_model, dt=dt) # Compute transfer function norms tf_plant_inf_norm = util.compute_inf_norm_discrete( tf_plant, dt) tf_diff_inf_norm = util.compute_inf_norm_discrete( tf_diff, dt) # Test values print 'err_frac', ( tf_diff_inf_norm / tf_plant_inf_norm) self.assertTrue( tf_diff_inf_norm / tf_plant_inf_norm < tf_rel_tol) ''' # Also test that saved reduced model mats are equal to those # returned in memory np.testing.assert_equal( util.load_array_text(A_path_computed), A_model) np.testing.assert_equal( util.load_array_text(B_path_computed), B_model) np.testing.assert_equal( util.load_array_text(C_path_computed), C_model)
def test_assemble_Hankel(self): """ Tests Hankel arrays are symmetric and accurate given Markov params ``[CB CAB CA**P CA**(P+1)B ...]``.""" rtol = 1e-10 atol = 1e-12 for num_inputs in [1, 3]: for num_outputs in [1, 2, 4]: for sample_interval in [1]: num_time_steps = 50 num_states = 8 # A, B, C = util.drss(num_states, num_inputs, num_outputs) time_steps = make_time_steps( num_time_steps, sample_interval) A = util.load_array_text( join(self.data_dir, 'A_in%d_out%d.txt') % ( num_inputs, num_outputs)) B = util.load_array_text( join(self.data_dir, 'B_in%d_out%d.txt') % ( num_inputs, num_outputs)) C = util.load_array_text( join(self.data_dir, 'C_in%d_out%d.txt') % ( num_inputs, num_outputs)) impulse_response = util.impulse(A, B, C, time_steps[-1] + 1) Markovs = impulse_response[time_steps] if sample_interval == 2: time_steps, Markovs = era.make_sampled_format( time_steps, Markovs) my_ERA = era.ERA(verbosity=0) my_ERA._set_Markovs(Markovs) my_ERA._assemble_Hankel() H = my_ERA.Hankel_array Hp = my_ERA.Hankel_array2 for row in range(my_ERA.mc): for col in range(my_ERA.mo): # Test values in H are accurate using that, roughly, # H[r,c] = C * A^(r+c) * B. np.testing.assert_allclose( H[row * num_outputs:(row + 1) * num_outputs, col * num_inputs:(col + 1) * num_inputs], C.dot( np.linalg.matrix_power( A, time_steps[(row + col) * 2]).dot( B)), rtol=rtol, atol=atol) # Test values in H are accurate using that, roughly, # Hp[r,c] = C * A^(r+c+1) * B. np.testing.assert_allclose( Hp[row * num_outputs:(row + 1) * num_outputs, col * num_inputs:(col + 1) * num_inputs], C.dot( np.linalg.matrix_power( A, time_steps[(row + col) * 2 + 1]).dot( B)), rtol=rtol, atol=atol) # Test H is block symmetric np.testing.assert_equal( H[row * num_outputs:(row + 1) * num_outputs, col * num_inputs:(col + 1) * num_inputs], H[col * num_outputs:(col + 1) * num_outputs, row * num_inputs:(row + 1) * num_inputs]) # Test Hp is block symmetric np.testing.assert_equal( Hp[row * num_outputs:(row + 1) * num_outputs, col * num_inputs:(col + 1) * num_inputs], Hp[col * num_outputs:(col + 1) * num_outputs, row * num_inputs:(row + 1) * num_inputs])
def test_puts_gets(self): if not os.access('.', os.W_OK): raise RuntimeError('Cannot write to current directory') test_dir = 'DELETE_ME_test_files_dmd' if not os.path.isdir(test_dir) and _parallel.is_rank_zero(): os.mkdir(test_dir) eigvals = _parallel.call_and_bcast(np.random.random, 5) R_low_order_eigvecs = _parallel.call_and_bcast(np.random.random, (10, 10)) L_low_order_eigvecs = _parallel.call_and_bcast(np.random.random, (10, 10)) correlation_mat_eigvals = _parallel.call_and_bcast(np.random.random, 5) correlation_mat_eigvecs = _parallel.call_and_bcast( np.random.random, (10, 10)) correlation_mat = _parallel.call_and_bcast(np.random.random, (10, 10)) cross_correlation_mat = _parallel.call_and_bcast( np.random.random, (10, 10)) spectral_coeffs = _parallel.call_and_bcast(np.random.random, 5) proj_coeffs = _parallel.call_and_bcast(np.random.random, 5) adv_proj_coeffs = _parallel.call_and_bcast(np.random.random, 5) my_DMD = DMDHandles(None, verbosity=0) my_DMD.eigvals = eigvals my_DMD.R_low_order_eigvecs = R_low_order_eigvecs my_DMD.L_low_order_eigvecs = L_low_order_eigvecs my_DMD.correlation_mat_eigvals = correlation_mat_eigvals my_DMD.correlation_mat_eigvecs = correlation_mat_eigvecs my_DMD.correlation_mat = correlation_mat my_DMD.cross_correlation_mat = cross_correlation_mat my_DMD.spectral_coeffs = spectral_coeffs my_DMD.proj_coeffs = proj_coeffs my_DMD.adv_proj_coeffs = adv_proj_coeffs eigvals_path = join(test_dir, 'dmd_eigvals.txt') R_low_order_eigvecs_path = join(test_dir, 'dmd_R_low_order_eigvecs.txt') L_low_order_eigvecs_path = join(test_dir, 'dmd_L_low_order_eigvecs.txt') correlation_mat_eigvals_path = join(test_dir, 'dmd_corr_mat_eigvals.txt') correlation_mat_eigvecs_path = join(test_dir, 'dmd_corr_mat_eigvecs.txt') correlation_mat_path = join(test_dir, 'dmd_corr_mat.txt') cross_correlation_mat_path = join(test_dir, 'dmd_cross_corr_mat.txt') spectral_coeffs_path = join(test_dir, 'dmd_spectral_coeffs.txt') proj_coeffs_path = join(test_dir, 'dmd_proj_coeffs.txt') adv_proj_coeffs_path = join(test_dir, 'dmd_adv_proj_coeffs.txt') my_DMD.put_decomp(eigvals_path, R_low_order_eigvecs_path, L_low_order_eigvecs_path, correlation_mat_eigvals_path, correlation_mat_eigvecs_path) my_DMD.put_correlation_mat(correlation_mat_path) my_DMD.put_cross_correlation_mat(cross_correlation_mat_path) my_DMD.put_spectral_coeffs(spectral_coeffs_path) my_DMD.put_proj_coeffs(proj_coeffs_path, adv_proj_coeffs_path) _parallel.barrier() DMD_load = DMDHandles(None, verbosity=0) DMD_load.get_decomp(eigvals_path, R_low_order_eigvecs_path, L_low_order_eigvecs_path, correlation_mat_eigvals_path, correlation_mat_eigvecs_path) correlation_mat_loaded = util.load_array_text(correlation_mat_path) cross_correlation_mat_loaded = util.load_array_text( cross_correlation_mat_path) spectral_coeffs_loaded = np.squeeze( np.array(util.load_array_text(spectral_coeffs_path))) proj_coeffs_loaded = np.squeeze( np.array(util.load_array_text(proj_coeffs_path))) adv_proj_coeffs_loaded = np.squeeze( np.array(util.load_array_text(adv_proj_coeffs_path))) np.testing.assert_allclose(DMD_load.eigvals, eigvals) np.testing.assert_allclose(DMD_load.R_low_order_eigvecs, R_low_order_eigvecs) np.testing.assert_allclose(DMD_load.L_low_order_eigvecs, L_low_order_eigvecs) np.testing.assert_allclose(DMD_load.correlation_mat_eigvals, correlation_mat_eigvals) np.testing.assert_allclose(DMD_load.correlation_mat_eigvecs, correlation_mat_eigvecs) np.testing.assert_allclose(correlation_mat_loaded, correlation_mat) np.testing.assert_allclose(cross_correlation_mat_loaded, cross_correlation_mat) np.testing.assert_allclose(spectral_coeffs_loaded, spectral_coeffs) np.testing.assert_allclose(proj_coeffs_loaded, proj_coeffs) np.testing.assert_allclose(adv_proj_coeffs_loaded, adv_proj_coeffs)
def test_compute_model(self): """ Test ROM Markov params similar to those given - generates data - assembles Hankel array - computes SVD - forms the ROM discrete arrays A, B, and C (D = 0) - Tests Markov parameters from ROM are approx. equal to full plant's """ num_time_steps = 40 num_states_plant = 12 num_states_model = num_states_plant // 3 for num_inputs in [1, 3]: for num_outputs in [1, 2]: for sample_interval in [1, 2, 4]: time_steps = make_time_steps( num_time_steps, sample_interval) A, B, C = util.drss( num_states_plant, num_inputs, num_outputs) my_ERA = era.ERA(verbosity=0) Markovs = util.impulse(A, B, C, time_steps[-1] + 1) Markovs = Markovs[time_steps] if sample_interval == 2: time_steps, Markovs =\ era.make_sampled_format(time_steps, Markovs) num_time_steps = time_steps.shape[0] A_path_computed = join(self.test_dir, 'A_computed.txt') B_path_computed = join(self.test_dir, 'B_computed.txt') C_path_computed = join(self.test_dir, 'C_computed.txt') A, B, C = my_ERA.compute_model(Markovs, num_states_model) my_ERA.put_model( A_path_computed, B_path_computed, C_path_computed) #sing_vals = my_ERA.sing_vals[:num_states_model] # Flatten vecs into 2D X and Y arrays: # [B AB A**PB A**(P+1)B ...] #direct_vecs_flat = direct_vecs.swapaxes(0,1).reshape( # (num_states_model,-1))) # Exact grammians from Lyapunov eqn solve #gram_cont = util.solve_Lyapunov(A, B*B.H) #gram_obs = util.solve_Lyapunov(A.H, C.H*C) #print(np.sort(np.linalg.eig(gram_cont)[0])[::-1]) #print(sing_vals) #np.testing.assert_allclose(gram_cont.diagonal(), # sing_vals, atol=.1, rtol=.1) #np.testing.assert_allclose(gram_obs.diagonal(), # sing_vals, atol=.1, rtol=.1) #np.testing.assert_allclose(np.sort(np.linalg.eig( # gram_cont)[0])[::-1], sing_vals, # atol=.1, rtol=.1) #np.testing.assert_allclose(np.sort(np.linalg.eig( # gram_obs)[0])[::-1], sing_vals, # atol=.1, rtol=.1) # Check that the diagonals are largest entry on each row #self.assertTrue((np.max(np.abs(gram_cont),axis=1) == # np.abs(gram_cont.diagonal())).all()) #self.assertTrue((np.max(np.abs(gram_obs),axis=1) == # np.abs(gram_obs.diagonal())).all()) # Check the ROM Markov params match the full plant's Markovs_model = np.zeros(Markovs.shape) for ti, tv in enumerate(time_steps): Markovs_model[ti] = C.dot( np.linalg.matrix_power(A, tv).dot( B)) #print( # 'Computing ROM Markov param at time step %d' % tv) """ import matplotlib.pyplot as PLT for input_num in range(num_inputs): PLT.figure() PLT.hold(True) for output_num in range(num_outputs): PLT.plot(time_steps[:50], # Markovs_model[:50, output_num,input_num], 'ko') PLT.plot(time_steps[:50],Markovs[:50, # output_num, input_num],'rx') PLT.plot(time_steps_dense[:50], # Markovs_dense[:50, output_num, input_num],'b--') PLT.title('input %d to outputs'%input_num) PLT.legend(['ROM','Plant','Dense plant']) PLT.show() """ np.testing.assert_allclose( Markovs_model.squeeze(), Markovs.squeeze(), rtol=0.5, atol=0.5) np.testing.assert_equal( util.load_array_text(A_path_computed), A) np.testing.assert_equal( util.load_array_text(B_path_computed), B) np.testing.assert_equal( util.load_array_text(C_path_computed), C)