in botorch/models/pairwise_gp.py [0:0]
def _util_newton_updates(self, dp, x0, max_iter=1, xtol=None) -> Tensor:
r"""Make `max_iter` newton updates on utility.
This is used in `forward` to calculate and fill in gradient into tensors.
Instead of doing utility -= H^-1 @ g, use substition method.
See more explanation in _update_utility_derived_values.dd
By default only need to run one iteration just to fill the the gradients.
Args:
dp: (Transformed) datapoints.
x0: A `batch_size x n` dimension tensor, initial values.
max_iter: Max number of iterations.
xtol: Stop creteria. If `None`, do not stop until
finishing `max_iter` updates.
"""
xtol = float("-Inf") if xtol is None else xtol
D, DT, ch, ci = (
self.D,
self.DT,
self.covar_chol,
self.covar_inv,
)
covar = self.covar
diff = float("Inf")
i = 0
x = x0
eye = None
while i < max_iter and diff > xtol:
hl = self._hess_likelihood_f_sum(x, D, DT)
cov_hl = covar @ hl
if eye is None:
eye = torch.eye(
cov_hl.size(-1),
dtype=dp.dtype,
device=dp.device,
).expand(cov_hl.shape)
cov_hl = cov_hl + eye # add 1 to cov_hl
g = self._grad_posterior_f(x, dp, D, DT, ch, ci)
cov_g = covar @ g.unsqueeze(-1)
x_update = torch.linalg.solve(cov_hl, cov_g).squeeze(-1)
x_next = x - x_update
diff = torch.norm(x - x_next)
x = x_next
i += 1
return x