コード例 #1
0
ファイル: vanderpol-edmd.py プロジェクト: stanleybak/llol
def main():
    'main entry point'

    Timers.tic('total')

    sim_data = SingleSimulationData()
    sim_data.tmax = 6.5
    sim_data.npoints = 100
    sim_data.init = [1.4, 2.4]
    sim_data.plot = True

    s = Settings()
    s.der_func = der_func
    s.dims = 2
    s.data_source = sim_data

    koop = Koopman(s)

    koop.make_approx()

    koop.plot_approx(sim_data.init, sim_data.npoints, max_norm=10)

    koop.save_plot('vanderpol.png')

    Timers.toc('total')
    Timers.print_stats()
コード例 #2
0
ファイル: koopman.py プロジェクト: stanleybak/llol
    def make_approx(self):
        'make the linear approximation according to the settings'

        Timers.tic('make_approx')

        self.eobs_func = self.make_eobs_func()

        x_mat, y_mat = self.settings.data_source.make_data(
            self.settings.der_func, self.eobs_func)

        # do regression
        self.do_regression(x_mat, y_mat)

        Timers.toc('make_approx')
コード例 #3
0
ファイル: koopman.py プロジェクト: stanleybak/llol
    def plot_approx(self,
                    init,
                    npoints,
                    xdim=0,
                    ydim=1,
                    col='k-',
                    label='eDMD Approx',
                    max_norm=float('inf')):
        'plot the approximation'

        Timers.tic('plot_approx')

        xs = []
        ys = []

        init = np.array(init, dtype=float)
        init.shape = (self.settings.dims, 1)

        estate = self.eobs_func(init)

        xs.append(estate[xdim])
        ys.append(estate[ydim])

        print(f"estate shape: {estate.shape}, a_mat shape: {self.a_mat.shape}")

        for step in range(npoints):
            Timers.tic('dot')
            estate = np.dot(self.a_mat, estate)
            Timers.toc('dot')

            x = estate[xdim]
            y = estate[ydim]

            if np.linalg.norm([x, y]) > max_norm:
                print(
                    f"Approximation was bad at step {step} (plotting stopped prematurely)"
                )
                break

            xs.append(x)
            ys.append(y)

        plt.plot(xs, ys, col, label=label)

        Timers.toc('plot_approx')
コード例 #4
0
ファイル: koopman.py プロジェクト: stanleybak/llol
        def eobs_func(state_mat):
            'returns a matrix of extended observations based on the passed-in state matrix'

            # work with rows because it's faster
            state_mat = state_mat.T.copy()

            Timers.tic('eobs_func')

            eobs_mat = np.zeros((state_mat.shape[1], output_dims), dtype=float)

            print(f"eobs shape: {eobs_mat.shape}")

            for state, eobs in zip(state_mat, eobs_mat):
                index = 0

                # original
                if s.include_original_vars:
                    for i in range(n):
                        eobs[index] = state[i]
                        index += 1

                # power basis
                if s.power_order is not None:
                    for iterator in s.power_order**n:
                        val = 1

                        temp = iterator

                        # extract the iterator for each dimension
                        for dim_num in range(n):
                            deg = temp % s.power_order
                            temp = temp // s.power_order

                            val *= state[dim_num]**deg

                        eobs[index] = val
                        index += 1

            Timers.toc('eobs_func')

            return eobs_mat.transpose().copy()
コード例 #5
0
ファイル: koopman.py プロジェクト: stanleybak/llol
    def do_regression(self, x1, x2):
        '''do regression on the x and y matrices

        This produces self.a_mat
        '''

        Timers.tic('regression')

        if self.settings.pseudo_inverse_method == Settings.DIRECT:
            Timers.tic('pinv')
            x_pseudo = np.linalg.pinv(x1)
            Timers.toc('pinv')
            Timers.tic('dot')
            self.a_mat = np.dot(x2, x_pseudo)
            Timers.toc('dot')

            print(
                f"after regression, x1 shape: {x1.shape}, x2 shape: {x2.shape}, a_mat shape: {self.a_mat.shape}"
            )
        else:
            raise RuntimeError(
                f"Unimplemented pesudo-inverse method: {self.pseudo_inverse_methods}"
            )

        Timers.toc('regression')
コード例 #6
0
ファイル: data_source.py プロジェクト: stanleybak/llol
    def make_data(self, der_func, eobs_func):
        '''generate the data for regression

        der_func is a derivative function given a single state
        eobs_func converts a matrix of states to a matrix of (extended) observations

        returns (x_mat, y_mat) where the regression problem is y_mat = A * x_mat

        each column of x_mat / y_mat is one set of state vectors
        '''

        Timers.tic('make_data')

        n = len(self.init)

        times = np.linspace(0, self.tmax, self.npoints)

        def der(state, _):
            'derivative function (reversed args for odeint)'

            return der_func(state)

        Timers.tic('odeint')
        sol = odeint(der, self.init, times).T
        Timers.toc('odeint')

        assert sol.shape[0] == n
        assert sol.shape[1] == self.npoints

        if self.plot:
            Timers.tic('plot')
            xs = [data[self.plot_xdim] for data in sol.T]
            ys = [data[self.plot_ydim] for data in sol.T]

            plt.plot(xs, ys, self.plot_color, label=self.plot_label)
            Timers.toc('plot')

        # extend observations
        mat = eobs_func(sol)

        x_mat = mat[:-1]
        y_mat = mat[1:]

        Timers.toc('make_data')

        return x_mat, y_mat