code: def to_product_form(self):
          
          if self._sa_pair:
              ns = self.num_states
              na = self.a_indices.max() + 1
              R = np.full((ns, na), -np.inf)
              R[self.s_indices, self.a_indices] = self.R
              Q = np.zeros((ns, na, ns))
              if self._sparse:
                  _fill_dense_Q(self.s_indices, self.a_indices,
                                self.Q.toarray(), Q)
              else:
                  _fill_dense_Q(self.s_indices, self.a_indices, self.Q, Q)
              return DiscreteDP(R, Q, self.beta)
          else:
              return self
docs: Convert this instance of `DiscreteDP` to the "product" form.
  
          The product form uses the version of the init method taking
          `R`, `Q` and `beta`.
  
          Parameters
          ----------
  
          Returns
          -------
          ddp_sa : DiscreteDP
              The correspnoding DiscreteDP instance in product form
  
          Notes
          -----
          If this instance is already in product form then it is returned
          un-modified