class_docstr: Maintains state between `page_trend_test` executions
class_docstr_tok: ["Maintains","state","between","`","page_trend_test","`","executions"]
docstr: Recursive function to evaluate p(l, k, n); see [5] Equation 1
docstr_tok: ["Recursive","function","to","evaluate","p","(","l",",","k",",","n",")",";","see","[","5","]","Equation","1"]
code: def pmf(self, l, n):
      """Recursive function to evaluate p(l, k, n); see [5] Equation 1"""
  
      if n not in self.all_pmfs:
          self.all_pmfs[n] = {}
      if self.k not in self.all_pmfs[n]:
          self.all_pmfs[n][self.k] = {}
  
      # Cache results to avoid repeating calculation. Initially this was
      # written with lru_cache, but this seems faster? Also, we could add
      # an option to save this for future lookup.
      if l in self.all_pmfs[n][self.k]:
          return self.all_pmfs[n][self.k][l]
  
      if n == 1:
          ps = self.p_l_k_1()  # [5] Equation 6
          ls = range(self.a, self.b + 1)
          # not fast, but we'll only be here once
          self.all_pmfs[n][self.k] = {l: p for l, p in zip(ls, ps)}
          return self.all_pmfs[n][self.k][l]
  
      p = 0
      low = max(l - (n - 1) * self.b, self.a)  # [5] Equation 2
      high = min(l - (n - 1) * self.a, self.b)
  
      # [5] Equation 1
      for t in range(low, high + 1):
          p1 = self.pmf(l - t, n - 1)
          p2 = self.pmf(t, 1)
          p += p1 * p2
      self.all_pmfs[n][self.k][l] = p
      return p
  
file_path: catboost/contrib/python/scipy/py3/scipy/stats/_page_trend_test.py
imports: from itertools import permutations
  import numpy
  import math
  from ._continuous_distns import norm
  import scipy.stats
  from dataclasses import make_dataclass
label_desc: Use image node_id 5 for calling the _PageL obj's underlying member method code with example usage: obj.pmf(l, n) and returns: p, self, self