class_docstr: Field-Weighted Factorization Machine base class.
class_docstr_tok: ["Field-Weighted","Factorization","Machine","base","class","."]
code: def _update_latents(
      self, x, g_loss
  ):  # also updates interaction weights as both updates depends of each other
      # For notational convenience
      v, w_int, field = (
          self.latents,
          self.interaction_weights,
          self._field,
      )
      l1, l2, sign = self.l1_latent, self.l2_latent, utils.math.sign
  
      # Precompute feature independent sum for time efficiency
      precomputed_sum = {
          f"{j1}_{f}": sum(
              v[j2][f] * xj2 * w_int[field(j1) + field(j2)]
              for j2, xj2 in x.items()
          )
          for j1, xj1 in x.items()
          for f in range(self.n_factors)
      }
  
      # Calculate each latent and interaction weights gradients before updating any of them
      latent_gradients = {}
      for j, xj in x.items():
          latent_gradients[j] = {
              f: g_loss
              * (
                  xj * precomputed_sum[f"{j}_{f}"]
                  - v[j][f] * xj * w_int[field(j) + field(j)] ** 2
              )
              + l1 * sign(v[j][f])
              + l2 * v[j][f]
              for f in range(self.n_factors)
          }
  
      int_gradients = {
          field(j1)
          + field(j2): g_loss * (x[j1] * x[j2] * np.dot(v[j1], v[j2]))
          for j1, j2 in itertools.combinations(x.keys(), 2)
      }
  
      # Finally update the latent and interaction weights
      for j in x.keys():
          self.latents[j] = self.latent_optimizer.step(
              w=v[j], g=latent_gradients[j]
          )
  
      self.int_weights = self.int_weight_optimizer.step(
          w=w_int, g=int_gradients
      )
  
imports: from __future__ import annotations
  import collections
  import functools
  import itertools
  import numpy
  from river import base, optim, utils
  from .base import BaseFM
label_desc: Use image node_id 8 for calling the FwFM obj's underlying member method code with example usage: obj._update_latents(x, g_loss) without return types