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)
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)
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)
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)
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)
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'