示例#1
0
    def test_compute_modes(self):
        """Test building of modes."""
        vec_array = _parallel.call_and_bcast(np.random.random, 
            ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.vec_handles):
                handle.put(np.array(vec_array[:, vec_index]).squeeze())
        
        # Compute DMD directly from data, for a sequential dataset
        ritz_vals, ritz_vecs, build_coeffs, mode_norms =\
            self._helper_compute_DMD_from_data(vec_array[:, :-1],
            vec_array[:, 1:], util.InnerProductBlock(np.vdot))
 
        # Check direct computation against modred   
        _parallel.barrier()
        self._helper_check_modes(ritz_vecs, build_coeffs, self.vec_handles)

        # Generate data for a non-sequential dataset
        adv_vec_array = _parallel.call_and_bcast(np.random.random, 
            ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.adv_vec_handles):
                handle.put(np.array(adv_vec_array[:, vec_index]).squeeze())

        # Compute DMD directly from data, for a non-sequential dataset
        ritz_vals, ritz_vecs, build_coeffs, mode_norms =\
            self._helper_compute_DMD_from_data(vec_array, 
                adv_vec_array, util.InnerProductBlock(np.vdot))
 
        # Check direct computation against modred   
        _parallel.barrier()
        self._helper_check_modes(ritz_vecs, build_coeffs, self.vec_handles)
示例#2
0
    def test_compute_spectrum(self):
        """Test DMD spectrum"""
        rtol = 1e-10
        atol = 1e-16

        # Define an array of vectors, with corresponding handles
        vec_array = _parallel.call_and_bcast(
            np.random.random, ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.vec_handles):
                handle.put(np.array(vec_array[:, vec_index]).squeeze())

        # Check that spectral coefficients computed using adjoints match those
        # computed using a pseudoinverse.  Perform the decomp only once using
        # the DMD object, so that the spectral coefficients are computed from
        # the same data, but in two different ways.
        _parallel.barrier()
        self.my_DMD.compute_decomp(self.vec_handles)
        spectral_coeffs_computed = self.my_DMD.compute_spectrum()
        spectral_coeffs_true = self._helper_compute_DMD_from_data(
            vec_array, util.InnerProductBlock(np.vdot))[2]
        self._helper_test_1D_array_to_sign(spectral_coeffs_true,
                                           spectral_coeffs_computed,
                                           rtol=rtol,
                                           atol=atol)

        # Create more data, to check a non-sequential dataset
        adv_vec_array = _parallel.call_and_bcast(
            np.random.random, ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.adv_vec_handles):
                handle.put(np.array(adv_vec_array[:, vec_index]).squeeze())

        # Check that spectral coefficients computed using adjoints match those
        # computed using a pseudoinverse
        _parallel.barrier()
        self.my_DMD.compute_decomp(self.vec_handles,
                                   adv_vec_handles=self.adv_vec_handles)
        spectral_coeffs_computed = self.my_DMD.compute_spectrum()
        spectral_coeffs_true = self._helper_compute_DMD_from_data(
            vec_array,
            util.InnerProductBlock(np.vdot),
            adv_vec_array=adv_vec_array)[2]
        self._helper_test_1D_array_to_sign(spectral_coeffs_true,
                                           spectral_coeffs_computed,
                                           rtol=rtol,
                                           atol=atol)
示例#3
0
    def _helper_check_decomp(self,
                             vec_array,
                             vec_handles,
                             adv_vec_array=None,
                             adv_vec_handles=None,
                             max_num_eigvals=None):
        # Set tolerance.
        tol = 1e-10

        # Compute reference DMD values
        (eigvals_true, R_low_order_eigvecs_true, L_low_order_eigvecs_true,
         correlation_mat_eigvals_true,
         correlation_mat_eigvecs_true) = (self._helper_compute_DMD_from_data(
             vec_array,
             util.InnerProductBlock(np.vdot),
             adv_vec_array=adv_vec_array,
             max_num_eigvals=max_num_eigvals))[3:-1]

        # Compute DMD using modred
        (eigvals_returned, R_low_order_eigvecs_returned,
         L_low_order_eigvecs_returned, correlation_mat_eigvals_returned,
         correlation_mat_eigvecs_returned) = self.my_DMD.compute_decomp(
             vec_handles,
             adv_vec_handles=adv_vec_handles,
             max_num_eigvals=max_num_eigvals)

        # Test that matrices were correctly computed.  For build coeffs, check
        # column by column, as it is ok to be off by a negative sign.
        np.testing.assert_allclose(self.my_DMD.eigvals, eigvals_true, rtol=tol)
        self._helper_test_mat_to_sign(self.my_DMD.R_low_order_eigvecs,
                                      R_low_order_eigvecs_true,
                                      rtol=tol)
        self._helper_test_mat_to_sign(self.my_DMD.L_low_order_eigvecs,
                                      L_low_order_eigvecs_true,
                                      rtol=tol)
        np.testing.assert_allclose(self.my_DMD.correlation_mat_eigvals,
                                   correlation_mat_eigvals_true,
                                   rtol=tol)
        self._helper_test_mat_to_sign(self.my_DMD.correlation_mat_eigvecs,
                                      correlation_mat_eigvecs_true,
                                      rtol=tol)

        # Test that matrices were correctly returned
        np.testing.assert_allclose(eigvals_returned, eigvals_true, rtol=tol)
        self._helper_test_mat_to_sign(R_low_order_eigvecs_returned,
                                      R_low_order_eigvecs_true,
                                      rtol=tol)
        self._helper_test_mat_to_sign(L_low_order_eigvecs_returned,
                                      L_low_order_eigvecs_true,
                                      rtol=tol)
        np.testing.assert_allclose(correlation_mat_eigvals_returned,
                                   correlation_mat_eigvals_true,
                                   rtol=tol)
        self._helper_test_mat_to_sign(correlation_mat_eigvecs_returned,
                                      correlation_mat_eigvecs_true,
                                      rtol=tol)
示例#4
0
    def test_compute_decomp(self):
        """Test DMD decomposition (ritz values, build coefficients, mode
        norms)"""    
        # Define an array of vectors, with corresponding handles
        vec_array = _parallel.call_and_bcast(np.random.random, 
            ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.vec_handles):
                handle.put(np.array(vec_array[:, vec_index]).squeeze())

        # Compute DMD directly from data, for a sequential dataset
        ritz_vals, ritz_vecs, build_coeffs, mode_norms =\
            self._helper_compute_DMD_from_data(vec_array[:, :-1],
            vec_array[:, 1:], util.InnerProductBlock(np.vdot))

        # Check modred against direct computation, for a sequential dataset
        _parallel.barrier()
        self._helper_check_decomp(ritz_vals, build_coeffs, mode_norms,
            self.vec_handles)

        # np.w create more data, to check a non-sequential dataset
        adv_vec_array = _parallel.call_and_bcast(np.random.random, 
            ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.adv_vec_handles):
                handle.put(np.array(adv_vec_array[:, vec_index]).squeeze())

        # Compute DMD directly from data, for a non-sequential dataset
        ritz_vals, ritz_vecs, build_coeffs, mode_norms =\
            self._helper_compute_DMD_from_data(vec_array, 
                adv_vec_array, util.InnerProductBlock(np.vdot))

        # Check modred against direct computation, for a non-sequential dataset
        _parallel.barrier()
        self._helper_check_decomp(ritz_vals, build_coeffs, mode_norms,
            self.vec_handles, adv_vec_handles=self.adv_vec_handles)

        # Check that if mismatched sets of handles are passed in, an error is
        # raised.
        self.assertRaises(ValueError, self.my_DMD.compute_decomp,
            self.vec_handles, self.adv_vec_handles[:-1])
示例#5
0
    def test_compute_proj_coeffs(self):
        rtol = 1e-10
        atol = 1e-13  # Sometimes fails if tol too high

        # Define an array of vectors, with corresponding handles
        vec_array = _parallel.call_and_bcast(
            np.random.random, ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.vec_handles):
                handle.put(np.array(vec_array[:, vec_index]).squeeze())

        # Check the spectral coefficient values.  Sometimes the values in the
        # projections are not just scaled by -1 column-wise, but element-wise.
        # So just test that the projection coefficients differ by sign at most,
        # element-wise.
        _parallel.barrier()
        self.my_DMD.compute_decomp(self.vec_handles)
        proj_coeffs, adv_proj_coeffs = self.my_DMD.compute_proj_coeffs()
        adj_modes = self._helper_compute_DMD_from_data(
            vec_array, util.InnerProductBlock(np.vdot))[-1]
        proj_coeffs_true = np.dot(adj_modes.conj().T, vec_array[:, :-1])
        adv_proj_coeffs_true = np.dot(adj_modes.conj().T, vec_array[:, 1:])
        np.testing.assert_allclose(np.abs(proj_coeffs / proj_coeffs_true),
                                   np.ones(proj_coeffs.shape),
                                   rtol=rtol,
                                   atol=atol)
        np.testing.assert_allclose(np.abs(adv_proj_coeffs /
                                          adv_proj_coeffs_true),
                                   np.ones(adv_proj_coeffs.shape),
                                   rtol=rtol,
                                   atol=atol)

        # Create more data, to check a non-sequential dataset
        adv_vec_array = _parallel.call_and_bcast(
            np.random.random, ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.adv_vec_handles):
                handle.put(np.array(adv_vec_array[:, vec_index]).squeeze())

        # Check the spectral coefficient values.  Sometimes the values in the
        # projections are not just scaled by -1 column-wise, but element-wise.
        # So just test that the projection coefficients differ by sign at most,
        # element-wise.
        _parallel.barrier()
        self.my_DMD.compute_decomp(self.vec_handles,
                                   adv_vec_handles=self.adv_vec_handles)
        adj_modes = self._helper_compute_DMD_from_data(
            vec_array,
            util.InnerProductBlock(np.vdot),
            adv_vec_array=adv_vec_array)[-1]
        proj_coeffs, adv_proj_coeffs = self.my_DMD.compute_proj_coeffs()
        proj_coeffs_true = np.dot(adj_modes.conj().T, vec_array)
        adv_proj_coeffs_true = np.dot(adj_modes.conj().T, adv_vec_array)
        np.testing.assert_allclose(np.abs(proj_coeffs / proj_coeffs_true),
                                   np.ones(proj_coeffs.shape),
                                   rtol=rtol,
                                   atol=atol)
        np.testing.assert_allclose(np.abs(adv_proj_coeffs /
                                          adv_proj_coeffs_true),
                                   np.ones(adv_proj_coeffs.shape),
                                   rtol=rtol,
                                   atol=atol)
示例#6
0
    def test_compute_modes(self):
        """Test building of modes."""
        # Generate path names for saving modes to disk
        mode_path = join(self.test_dir, 'dmd_mode_%03d.pkl')

        ### SEQUENTIAL DATASET ###
        # Generate data
        seq_vec_array = _parallel.call_and_bcast(
            np.random.random, ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, handle in enumerate(self.vec_handles):
                handle.put(np.array(seq_vec_array[:, vec_index]).squeeze())

        # Compute DMD directly from data
        (modes_exact, modes_proj, spectral_coeffs, eigvals,
         R_low_order_eigvecs, L_low_order_eigvecs, correlation_mat_eigvals,
         correlation_mat_eigvecs) = self._helper_compute_DMD_from_data(
             seq_vec_array, util.InnerProductBlock(np.vdot))[:-1]

        # Set the build_coeffs attribute of an empty DMD object each time, so
        # that the modred computation uses the same coefficients as the direct
        # computation.
        _parallel.barrier()
        self.my_DMD.eigvals = eigvals
        self.my_DMD.R_low_order_eigvecs = R_low_order_eigvecs
        self.my_DMD.correlation_mat_eigvals = correlation_mat_eigvals
        self.my_DMD.correlation_mat_eigvecs = correlation_mat_eigvecs

        # Generate mode paths for saving modes to disk
        seq_mode_path_list = [mode_path % i for i in range(eigvals.size)]
        seq_mode_indices = range(len(seq_mode_path_list))

        # Compute modes by passing in handles
        self.my_DMD.compute_exact_modes(
            seq_mode_indices,
            [V.VecHandlePickle(path) for path in seq_mode_path_list],
            adv_vec_handles=self.vec_handles[1:])
        self._helper_check_modes(modes_exact, seq_mode_path_list)
        self.my_DMD.compute_proj_modes(
            seq_mode_indices,
            [V.VecHandlePickle(path) for path in seq_mode_path_list],
            vec_handles=self.vec_handles)
        self._helper_check_modes(modes_proj, seq_mode_path_list)

        # Compute modes without passing in handles, so first set full
        # sequential dataset as vec_handles.
        self.my_DMD.vec_handles = self.vec_handles
        self.my_DMD.compute_exact_modes(
            seq_mode_indices,
            [V.VecHandlePickle(path) for path in seq_mode_path_list])
        self._helper_check_modes(modes_exact, seq_mode_path_list)
        self.my_DMD.compute_proj_modes(
            seq_mode_indices,
            [V.VecHandlePickle(path) for path in seq_mode_path_list])
        self._helper_check_modes(modes_proj, seq_mode_path_list)

        # For exact modes, also compute by setting adv_vec_handles
        self.my_DMD.vec_handles = None
        self.my_DMD.adv_vec_handles = self.vec_handles[1:]
        self.my_DMD.compute_exact_modes(
            seq_mode_indices,
            [V.VecHandlePickle(path) for path in seq_mode_path_list])
        self._helper_check_modes(modes_exact, seq_mode_path_list)

        ### NONSEQUENTIAL DATA ###
        # Generate data
        vec_array = _parallel.call_and_bcast(
            np.random.random, ((self.num_states, self.num_vecs)))
        adv_vec_array = _parallel.call_and_bcast(
            np.random.random, ((self.num_states, self.num_vecs)))
        if _parallel.is_rank_zero():
            for vec_index, (handle, adv_handle) in enumerate(
                    zip(self.vec_handles, self.adv_vec_handles)):
                handle.put(np.array(vec_array[:, vec_index]).squeeze())
                adv_handle.put(np.array(adv_vec_array[:, vec_index]).squeeze())

        # Compute DMD directly from data
        (modes_exact, modes_proj, spectral_coeffs, eigvals,
         R_low_order_eigvecs, L_low_order_eigvecs, correlation_mat_eigvals,
         correlation_mat_eigvecs) = self._helper_compute_DMD_from_data(
             vec_array,
             util.InnerProductBlock(np.vdot),
             adv_vec_array=adv_vec_array)[:-1]

        # Set the build_coeffs attribute of an empty DMD object each time, so
        # that the modred computation uses the same coefficients as the direct
        # computation.
        _parallel.barrier()
        self.my_DMD.eigvals = eigvals
        self.my_DMD.R_low_order_eigvecs = R_low_order_eigvecs
        self.my_DMD.correlation_mat_eigvals = correlation_mat_eigvals
        self.my_DMD.correlation_mat_eigvecs = correlation_mat_eigvecs

        # Generate mode paths for saving modes to disk
        mode_path_list = [mode_path % i for i in range(eigvals.size)]
        mode_indices = range(len(mode_path_list))

        # Compute modes by passing in handles
        self.my_DMD.compute_exact_modes(
            mode_indices, [V.VecHandlePickle(path) for path in mode_path_list],
            adv_vec_handles=self.adv_vec_handles)
        self._helper_check_modes(modes_exact, mode_path_list)
        self.my_DMD.compute_proj_modes(
            mode_indices, [V.VecHandlePickle(path) for path in mode_path_list],
            vec_handles=self.vec_handles)
        self._helper_check_modes(modes_proj, mode_path_list)

        # Compute modes without passing in handles, so first set full
        # sequential dataset as vec_handles.
        self.my_DMD.vec_handles = self.vec_handles
        self.my_DMD.adv_vec_handles = self.adv_vec_handles
        self.my_DMD.compute_exact_modes(
            mode_indices, [V.VecHandlePickle(path) for path in mode_path_list])
        self._helper_check_modes(modes_exact, mode_path_list)
        self.my_DMD.compute_proj_modes(
            mode_indices, [V.VecHandlePickle(path) for path in mode_path_list])
        self._helper_check_modes(modes_proj, mode_path_list)