code: def _get_cyclic_f(knots):
      """Returns mapping of cyclic cubic spline values to 2nd derivatives.
  
      .. note:: See 'Generalized Additive Models', Simon N. Wood, 2006, pp 146-147
  
      :param knots: The 1-d array knots used for cubic spline parametrization,
       must be sorted in ascending order.
      :return: A 2-d array mapping cyclic cubic spline values at
       knots to second derivatives.
      """
      h = knots[1:] - knots[:-1]
      n = knots.size - 1
      b = np.zeros((n, n))
      d = np.zeros((n, n))
  
      b[0, 0] = (h[n - 1] + h[0]) / 3.0
      b[0, n - 1] = h[n - 1] / 6.0
      b[n - 1, 0] = h[n - 1] / 6.0
  
      d[0, 0] = -1.0 / h[0] - 1.0 / h[n - 1]
      d[0, n - 1] = 1.0 / h[n - 1]
      d[n - 1, 0] = 1.0 / h[n - 1]
  
      for i in range(1, n):
          b[i, i] = (h[i - 1] + h[i]) / 3.0
          b[i, i - 1] = h[i - 1] / 6.0
          b[i - 1, i] = h[i - 1] / 6.0
  
          d[i, i] = -1.0 / h[i - 1] - 1.0 / h[i]
          d[i, i - 1] = 1.0 / h[i - 1]
          d[i - 1, i] = 1.0 / h[i - 1]
  
      return np.linalg.solve(b, d)
  
imports: import numpy
  from patsy.util import have_pandas, atleast_2d_column_default, no_pickling, assert_no_pickling, safe_string_eq
  from patsy.state import stateful_transform
label_desc: Use image node_id 5 for calling a global function with example usage: _get_cyclic_f(knots) and returns: np