Пример #1
0
  def test_extra_time_points(self):
    """Tests the extra time points of the step back method."""
    dtype = np.float64
    min_x, max_x, size = dtype(0.0), dtype(1.0), 21
    np_grid = np.linspace(min_x, max_x, num=size)
    grid_spec = grids.uniform_grid([min_x], [max_x], [size], dtype=dtype)
    r = dtype(0.03)

    def transform_fn(state):
      return tf.where(state.time <= 1.0, state.value_grid, payoff_fn(state))

    def kernel(state):
      return state.value_grid * tf.exp(-r * state.time_step)

    def payoff_fn(state):
      return tf.maximum(state.coordinate_grid.grid, 0.5)

    bgs = grid_stepper.BackwardGridStepper(
        2.0, kernel, grid_spec, time_step=0.3, dtype=dtype)
    bgs.transform_values(payoff_fn)  # At time 2.
    expected_final_vals = np.maximum(np_grid, 0.5)
    expected_initial_values = expected_final_vals * np.exp(-r * 1)
    bgs.step_back_to_time(
        0.0,
        value_transform_fn=transform_fn,
        extra_time_points=[1.3, 1.5, 1.0, 3.0])
    initial_state = self.evaluate(bgs.state())
    self.assertArrayNear(expected_initial_values, initial_state.value_grid,
                         1e-10)
    self.assertEqual(0.0, initial_state.time)
Пример #2
0
  def test_grid_stepper_basic(self):
    dtype = np.float64
    min_x, max_x, size = dtype(0.0), dtype(1.0), 21
    np_grid = np.linspace(min_x, max_x, num=size)
    grid_spec = grids.uniform_grid([min_x], [max_x], [size], dtype=dtype)
    r = dtype(0.03)

    def kernel(state):
      return state.value_grid * tf.exp(-r * state.time_step)

    def time_step_fn(state):
      del state
      return tf.constant(0.1, dtype=dtype)

    def payoff_fn(state):
      return tf.maximum(state.coordinate_grid.grid, 0.5)

    bgs = grid_stepper.BackwardGridStepper(
        2.0, kernel, grid_spec, time_step_fn=time_step_fn, dtype=dtype)
    bgs.transform_values(payoff_fn)  # At time 2.
    bgs.step_back_to_time(dtype(0.13))
    intermediate_state = self.evaluate(bgs.state())
    bgs.step_back_to_time(dtype(0.0))
    initial_state = self.evaluate(bgs.state())
    expected_final_vals = np.maximum(np_grid, 0.5)
    expected_intermediate_values = expected_final_vals * np.exp(-r * (2 - 0.13))
    expected_initial_values = expected_final_vals * np.exp(-r * 2)
    self.assertArrayNear(expected_intermediate_values,
                         intermediate_state.value_grid, 1e-10)
    self.assertEqual(0.13, intermediate_state.time)
    self.assertArrayNear(expected_initial_values, initial_state.value_grid,
                         1e-10)
    self.assertEqual(0.0, initial_state.time)
Пример #3
0
  def test_value_transform_fn(self):
    """Tests the value transform functionality of the step back method."""
    dtype = np.float64
    min_x, max_x, size = dtype(0.0), dtype(1.0), 21
    np_grid = np.linspace(min_x, max_x, num=size)
    grid_spec = grids.uniform_grid([min_x], [max_x], [size], dtype=dtype)
    r = dtype(0.03)

    multipliers = np.linspace(0.1, 1.1, num=size)

    def transform_fn(state):
      return state.value_grid * multipliers.reshape([-1, 1])

    def kernel(state):
      return state.value_grid * tf.exp(-r * state.time_step)

    def payoff_fn(state):
      return tf.maximum(state.coordinate_grid.grid, 0.5)

    bgs = grid_stepper.BackwardGridStepper(
        2.0, kernel, grid_spec, time_step=0.5, dtype=dtype)
    bgs.transform_values(payoff_fn)  # At time 2.
    expected_final_vals = np.maximum(np_grid, 0.5)
    expected_initial_values = (
        expected_final_vals * np.exp(-r * 2) * (multipliers**4))
    bgs.step_back_to_time(0.0, value_transform_fn=transform_fn)
    initial_state = self.evaluate(bgs.state())
    self.assertArrayNear(expected_initial_values, initial_state.value_grid,
                         1e-10)
    self.assertEqual(0.0, initial_state.time)
Пример #4
0
  def test_step_back(self):
    """Tests the step_back method."""
    dtype = np.float64
    min_x, max_x, size = dtype(0.0), dtype(1.0), 21
    grid_spec = grids.uniform_grid([min_x], [max_x], [size], dtype=dtype)
    r = dtype(0.03)

    def kernel(state):
      return state.value_grid * tf.exp(-r * state.time_step)

    def time_step_fn(state):
      """A non-constant time step."""
      # Returns the first element of the harmonic sequence which is smaller
      # than the current time floored by 0.01. If the current time is t,
      # then returns tf.max(1/tf.ceil(1/t), 0.01).
      return tf.maximum(dtype(0.01), 1. / tf.ceil(1. / state.time))

    def payoff_fn(state):
      return tf.maximum(state.coordinate_grid.grid, 0.5)

    bgs = grid_stepper.BackwardGridStepper(
        1.9, kernel, grid_spec, time_step_fn=time_step_fn, dtype=dtype)
    bgs.transform_values(payoff_fn)  # At time 1.9.

    # Calls step back and checks that the time of the grid changes to 0.9.
    bgs.step_back()
    state_1 = self.evaluate(bgs.state())
    self.assertTrue(state_1.time, 0.9)
    # Also check that the next time step is correctly populated. It should be
    # 0.5 now.
    self.assertTrue(state_1.time_step, 0.5)
    # Step back again and check that the time step is correctly applied.
    bgs.step_back()
    state_2 = self.evaluate(bgs.state())
    self.assertTrue(state_2.time, 0.4)
Пример #5
0
 def test_uniform_grid_1d(self):
     dtype = np.float64
     min_x, max_x, size = dtype(0.0), dtype(1.0), 21
     np_grid = np.linspace(min_x, max_x, num=size)
     grid_spec = self.evaluate(
         grids.uniform_grid([min_x], [max_x], [size], dtype=dtype))
     self.assertEqual(grid_spec.dim, 1)
     grid = grid_spec.grid
     self.assertEqual(grid.shape, tuple([21, 1]))
     self.assertArrayNear(np.squeeze(grid), np_grid, 1e-10)
     self.assertEqual(grid.dtype, dtype)
Пример #6
0
    def test_nonconst_time_step(self):
        dtype = np.float64
        min_x, max_x, size = dtype(0.0), dtype(1.0), 21
        np_grid = np.linspace(min_x, max_x, num=size)
        grid_spec = grids.uniform_grid([min_x], [max_x], [size], dtype=dtype)
        r = dtype(0.03)

        def kernel(state):
            return state.value_grid * tf.exp(-r * state.time_step)

        def time_step_fn(state):
            """A non-constant time step."""
            # Returns the first element of the harmonic sequence which is smaller
            # than the current time floored by 0.01. If the current time is t,
            # then returns tf.max(1/tf.math.ceil(1/t), 0.01).
            return tf.maximum(dtype(0.01), 1. / tf.math.ceil(1. / state.time))

        def payoff_fn(state):
            return tf.maximum(state.coordinate_grid.grid, 0.5)

        bgs = pde.BackwardGridStepper(1.9,
                                      kernel,
                                      grid_spec,
                                      time_step_fn=time_step_fn,
                                      dtype=dtype)
        bgs.transform_values(payoff_fn)  # At time 1.9.
        bgs.step_back_to_time(dtype(0.13))
        intermediate_state = self.evaluate(bgs.state())
        bgs.step_back_to_time(dtype(0.0))
        initial_state = self.evaluate(bgs.state())
        expected_final_vals = np.maximum(np_grid, 0.5)
        expected_intermediate_values = expected_final_vals * np.exp(
            -r * (1.9 - 0.13))
        expected_initial_values = expected_final_vals * np.exp(-r * 1.9)
        self.assertArrayNear(expected_intermediate_values,
                             intermediate_state.value_grid, 1e-10)
        self.assertEqual(0.13, intermediate_state.time)
        self.assertArrayNear(expected_initial_values, initial_state.value_grid,
                             1e-10)
        self.assertEqual(0.0, initial_state.time)
Пример #7
0
 def test_uniform_grid_2d(self):
     dtype = np.float64
     min_x, max_x, sizes = [0.0, 1.0], [3.0, 5.0], [11, 21]
     grid_spec = self.evaluate(
         grids.uniform_grid(min_x, max_x, sizes, dtype=dtype))
     self.assertEqual(grid_spec.dim, 2)
     grid = grid_spec.grid
     self.assertEqual(grid.shape, tuple([11, 21, 2]))
     self.assertEqual(grid.dtype, dtype)
     grid_marks = []
     for i in range(2):
         grid_marks.append(np.linspace(min_x[i], max_x[i], num=sizes[i]))
     np_grid = np.stack(np.meshgrid(*grid_marks, indexing='ij'), axis=-1)
     self.assertArrayNear(grid.reshape([-1]), np_grid.reshape([-1]), 1e-10)
     locs = grid_spec.locations
     self.assertEqual(len(locs), 2)
     self.assertArrayNear(locs[0], grid_marks[0], 1e-10)
     self.assertArrayNear(locs[1], grid_marks[1], 1e-10)
     dxs = grid_spec.deltas
     self.assertEqual(len(dxs), 2)
     self.assertArrayNear(dxs[0].reshape([-1]), [0.3], 1e-10)
     self.assertArrayNear(dxs[1].reshape([-1]), [0.2], 1e-10)