예제 #1
0
    def test_adaptive(self):
        """test for adaptive_step_size"""

        # compute numerical solution of the ODE
        operator = mdl.signaling_cascade(2).tt2qtt([[2] * 6] * 2,
                                                   [[2] * 6] * 2)
        initial_value = tt.unit(operator.row_dims, [0] * operator.order)
        initial_guess = tt.ones(operator.row_dims, [1] * operator.order,
                                ranks=self.rank).ortho_right()
        solution_ie, _ = ode.adaptive_step_size(operator,
                                                initial_value,
                                                initial_guess,
                                                300,
                                                step_size_first=1,
                                                second_method='two_step_Euler',
                                                progress=False)
        solution_tr, _ = ode.adaptive_step_size(
            operator,
            initial_value,
            initial_guess,
            300,
            step_size_first=1,
            second_method='trapezoidal_rule',
            progress=False)

        # compute norm of the derivatives at the final time step
        derivative_ie = (operator.dot(solution_ie[-1])).norm()
        derivative_tr = (operator.dot(solution_tr[-1])).norm()

        # check if converged to stationary distribution
        self.assertLess(derivative_ie, self.tol)
        self.assertLess(derivative_tr, self.tol)
예제 #2
0
    def test_errors(self):
        """test for error computations"""

        # compute numerical solution of the ODE
        operator = mdl.signaling_cascade(3).tt2qtt([[2] * 6] * 3,
                                                   [[2] * 6] * 3)
        initial_value = tt.unit(operator.row_dims, [0] * operator.order)
        initial_guess = tt.ones(operator.row_dims, [1] * operator.order,
                                ranks=self.rank).ortho_right()
        step_sizes = [0.1] * 10
        solution_ee = ode.explicit_euler(operator,
                                         initial_value,
                                         step_sizes,
                                         progress=False,
                                         max_rank=self.max_rank)
        solution_ie = ode.implicit_euler(operator,
                                         initial_value,
                                         initial_guess,
                                         step_sizes,
                                         progress=False)
        solution_tr = ode.trapezoidal_rule(operator,
                                           initial_value,
                                           initial_guess,
                                           step_sizes,
                                           progress=False)

        # compute errors
        errors_ee = ode.errors_expl_euler(operator, solution_ee, step_sizes)
        errors_ie = ode.errors_impl_euler(operator, solution_ie, step_sizes)
        errors_tr = ode.errors_trapezoidal(operator, solution_tr, step_sizes)

        # check if errors are smaller than tolerance
        self.assertLess(np.max(errors_ee), self.tol)
        self.assertLess(np.max(errors_ie), self.tol)
        self.assertLess(np.max(errors_tr), self.tol)
예제 #3
0
    def test_unit(self):
        """test unit tensor train"""

        # construct unit tensor train, convert to full format, and flatten
        t_unit = tt.unit(self.row_dims, [0] * self.order).full().flatten()

        # construct unit vector
        t_full = np.eye(np.int(np.prod(self.row_dims)), 1).T

        # compute relative error
        rel_err = np.linalg.norm(t_unit - t_full) / np.linalg.norm(t_full)

        # check if relative error is smaller than tolerance
        self.assertLess(rel_err, self.tol)
예제 #4
0
    def test_explicit_euler(self):
        """test for explicit Euler method"""

        # compute numerical solution of the ODE
        operator = mdl.signaling_cascade(2).tt2qtt([[2] * 6] * 2, [[2] * 6] * 2)
        initial_value = tt.unit(operator.row_dims, [0] * operator.order)
        step_sizes = [0.1] * 3000
        solution = ode.explicit_euler(operator, initial_value, step_sizes, progress=False, max_rank=self.max_rank)

        # compute norm of the derivatives at the final 10 time steps
        derivatives = []
        for i in range(10):
            derivatives.append((operator.dot(solution[-i - 1])).norm())

        # check if explicit Euler method converged to stationary distribution
        for i in range(10):
            self.assertLess(derivatives[i], self.tol)
예제 #5
0
    def test_implicit_euler(self):
        """test for implicit Euler method"""

        # compute numerical solution of the ODE
        operator = mdl.signaling_cascade(2).tt2qtt([[2] * 6] * 2,
                                                   [[2] * 6] * 2)
        initial_value = tt.unit(operator.row_dims, [0] * operator.order)
        initial_guess = tt.ones(operator.row_dims, [1] * operator.order,
                                ranks=self.rank).ortho_right()
        step_sizes = [1] * 300
        solution_als = ode.implicit_euler(operator,
                                          initial_value,
                                          initial_guess,
                                          step_sizes,
                                          tt_solver='als',
                                          progress=False)
        solution_mals = ode.implicit_euler(operator,
                                           initial_value,
                                           initial_guess,
                                           step_sizes,
                                           tt_solver='mals',
                                           max_rank=self.rank,
                                           progress=False)

        # compute norm of the derivatives at the final 10 time steps
        derivatives_als = []
        derivatives_mals = []
        for i in range(10):
            derivatives_als.append((operator.dot(solution_als[-i - 1])).norm())
            derivatives_mals.append(
                (operator.dot(solution_mals[-i - 1])).norm())

        # check if implicit Euler method converged to stationary distribution
        for i in range(10):
            self.assertLess(derivatives_als[i], self.tol)
            self.assertLess(derivatives_mals[i], self.tol)
예제 #6
0
    string_p_CO = '10^' + (p_CO_exp[i] >= 0) * '+' + str("%.1f" % p_CO_exp[i])
    string_method = ' ' * 9 + 'EVP' + ' ' * 9
    string_rank = (R[i] < 10) * ' ' + str(R[i]) + ' ' * 8
    string_closeness = str("%.2e" % (operator @ solution).norm()) + ' ' * 6
    string_time = (time.elapsed < 10) * ' ' + str("%.2f" % time.elapsed) + 's'
    print(string_p_CO + string_method + string_rank + string_closeness +
          string_time)

# apply adaptive step size scheme to the ODE to find the stationary distribution
# ------------------------------------------------------------------------------

for i in range(8, len(R)):

    # integrate ODE to approximate stationary distribution
    operator = mdl.co_oxidation(20, 10**(8 + p_CO_exp[i]))
    initial_value = tt.unit(operator.row_dims, [1] * operator.order)
    initial_guess = tt.ones(operator.row_dims, [1] * operator.order,
                            ranks=R[i]).ortho_left().ortho_right()
    with utl.timer() as time:
        solution = ode.adaptive_step_size(operator, initial_value,
                                          initial_guess, 100)

    # compute turn-over frequency of CO2 desorption
    tof.append(utl.two_cell_tof(solution[-1], [2, 1], 1.7e5))

    # print results
    string_p_CO = '10^' + (p_CO_exp[i] >= 0) * '+' + str("%.1f" % p_CO_exp[i])
    string_method = ' ' * 9 + 'IEM' + ' ' * 9
    string_rank = (R[i] < 10) * ' ' + str(R[i]) + ' ' * 8
    string_closeness = str("%.2e" % (operator @ solution[-1]).norm()) + ' ' * 6
    string_time = (time.elapsed < 10) * ' ' + str("%.2f" % time.elapsed) + 's'