def test_newton_order_one(self, dtype): jacobian_mat = tf.constant([[-1.]], dtype=dtype) real_dtype = abs(jacobian_mat).dtype bdf_coefficient = tf.constant(-0.1850, dtype=dtype) first_order_newton_coefficient = 1. / (1. - bdf_coefficient) step_size = tf.constant(0.01, dtype=real_dtype) unitary, upper = bdf_util.newton_qr(jacobian_mat, first_order_newton_coefficient, step_size) backward_differences = tf.constant( [[1.], [-1.], [0.], [0.], [0.], [0.]], dtype=dtype) ode_fn_vec = lambda time, state: -state order = tf.constant(1, dtype=tf.int32) time = tf.constant(0., dtype=real_dtype) tol = tf.constant(1e-6, dtype=real_dtype) # The equation we are trying to solve with Newton's method is linear. # Therefore, we should observe exact convergence after one iteration. An # additional iteration is required to obtain an accurate error estimate, # making the total number of iterations 2. max_num_newton_iters = 2 converged, next_backward_difference, next_state, _ = bdf_util.newton( backward_differences, max_num_newton_iters, first_order_newton_coefficient, ode_fn_vec, order, step_size, time, tol, unitary, upper) self.assertEqual(self.evaluate(converged), True) state = backward_differences[0, :] step_size_cast = tf.cast(step_size, dtype=dtype) exact_next_state = ( (1. - bdf_coefficient) * state + bdf_coefficient) / (1. + step_size_cast - bdf_coefficient) self.assertAllClose(self.evaluate(next_backward_difference), self.evaluate(exact_next_state)) self.assertAllClose(self.evaluate(next_state), self.evaluate(exact_next_state))
def update_factorization(): return bdf_util.newton_qr( jacobian_mat, newton_coefficients_array.read(order), step_size)