class_docstr: The trainer for LinUCB Contextual Bandit model.
  The model estimates a ridge regression (linear) and only supports dense features.
  We can have different number and identities of arms in each observation. The arms must
          have features to represent their semantic meaning.
  Instead of keeping track of cumulative values of `A` and `b`, we keep track of the average
      (cumulative divided by total weight) values.
  Reference: https://arxiv.org/pdf/1003.0146.pdf
  
  Args:
      policy: The policy to be trained. Its scorer has to be LinearRegressionUCB
docstr: Args:
      x: 2D tensor of shape (batch_size, dim)
      y: 2D tensor of shape (batch_size, 1)
      weight: 2D tensor of shape (batch_size, 1)
docstr_tok: ["Args",":","x",":","2D","tensor","of","shape","(","batch_size",",","dim",")","y",":","2D","tensor","of","shape","(","batch_size",",","1",")","weight",":","2D","tensor","of","shape","(","batch_size",",","1",")"]
code: def update_params(
      self,
      x: torch.Tensor,
      y: torch.Tensor,
      weight: Optional[torch.Tensor] = None,
  ):
      """
      Args:
          x: 2D tensor of shape (batch_size, dim)
          y: 2D tensor of shape (batch_size, 1)
          weight: 2D tensor of shape (batch_size, 1)
      """
      # weight is number of observations represented by each entry
      if weight is None:
          weight = torch.ones_like(y)
      weight = weight.float()
  
      batch_sum_weight = weight.sum()
      self.scorer.cur_num_obs += y.shape[0]
      self.scorer.cur_sum_weight += batch_sum_weight
      # update average values of A and b using observations from the batch
      self.scorer.cur_avg_A = (
          self.scorer.cur_avg_A
          * (1 - batch_sum_weight / self.scorer.cur_sum_weight)
          + torch.matmul(x.t(), x * weight) / self.scorer.cur_sum_weight
      )  # dim (DA*DC, DA*DC)
      self.scorer.cur_avg_b = (
          self.scorer.cur_avg_b
          * (1 - batch_sum_weight / self.scorer.cur_sum_weight)
          + torch.matmul(x.t(), y * weight).squeeze()
          / self.scorer.cur_sum_weight
      )
  
file_path: ReAgent/reagent/training/cb/linucb_trainer.py
imports: import logging
  from typing import Optional
  import torch
  from reagent.core.configuration import resolve_defaults
  from reagent.core.types import CBInput
  from reagent.gym.policies.policy import Policy
  from reagent.models.linear_regression import LinearRegressionUCB
  from reagent.training.cb.base_trainer import BaseCBTrainerWithEval
label_desc: Use image node_id 3 for calling the LinUCBTrainer obj's underlying member method code with example usage: obj.update_params(x, y, weight) without return types