class_docstr: Univariate spline in the B-spline basis.
  
  .. math::
      S(x) = \sum_{j=0}^{n-1} c_j  B_{j, k; t}(x)
  
  where :math:`B_{j, k; t}` are B-spline basis functions of degree `k`
  and knots `t`.
  
  Parameters
  ----------
  t : ndarray, shape (n+k+1,)
      knots
  c : ndarray, shape (>=n, ...)
      spline coefficients
  k : int
      B-spline degree
  extrapolate : bool or 'periodic', optional
      whether to extrapolate beyond the base interval, ``t[k] .. t[n]``,
      or to return nans.
      If True, extrapolates the first and last polynomial pieces of b-spline
      functions active on the base interval.
      If 'periodic', periodic extrapolation is used.
      Default is True.
  axis : int, optional
      Interpolation axis. Default is zero.
  
  Attributes
  ----------
  t : ndarray
      knot vector
  c : ndarray
      spline coefficients
  k : int
      spline degree
  extrapolate : bool
      If True, extrapolates the first and last polynomial pieces of b-spline
      functions active on the base interval.
  axis : int
      Interpolation axis.
  tck : tuple
      A read-only equivalent of ``(self.t, self.c, self.k)``
  
  Notes
  -----
  B-spline basis elements are defined via
  
  .. math::
      B_{i, 0}(x) = 1, \textrm{if $t_i \le x < t_{i+1}$, otherwise $0$,}
  
      B_{i, k}(x) = \frac{x - t_i}{t_{i+k} - t_i} B_{i, k-1}(x)
               + \frac{t_{i+k+1} - x}{t_{i+k+1} - t_{i+1}} B_{i+1, k-1}(x)
  
  **Implementation details**
  
  - At least ``k+1`` coefficients are required for a spline of degree `k`,
    so that ``n >= k+1``. Additional coefficients, ``c[j]`` with
    ``j > n``, are ignored.
  
  - B-spline basis elements of degree `k` form a partition of unity on the
    *base interval*, ``t[k] <= x <= t[n]``.
  
  - Based on [1]_ and [2]_
  
  .. seealso:: :class:`scipy.interpolate.BSpline`
  
  References
  ----------
  .. [1] Tom Lyche and Knut Morken, Spline methods,
      http://www.uio.no/studier/emner/matnat/ifi/INF-MAT5340/v05/undervisningsmateriale/
  .. [2] Carl de Boor, A practical guide to splines, Springer, 2001.
docstr: Returns a design matrix as a CSR format sparse array.
  
  Parameters
  ----------
  x : array_like, shape (n,)
      Points to evaluate the spline at.
  t : array_like, shape (nt,)
      Sorted 1D array of knots.
  k : int
      B-spline degree.
  extrapolate : bool or 'periodic', optional
      Whether to extrapolate based on the first and last intervals
      or raise an error. If 'periodic', periodic extrapolation is used.
      Default is False.
  
  Returns
  -------
  design_matrix : `csr_matrix` object
      Sparse matrix in CSR format where each row contains all the basis
      elements of the input row (first row = basis elements of x[0],
      ..., last row = basis elements x[-1]).
  
  Notes
  -----
  In each row of the design matrix all the basis elements are evaluated
  at the certain point (first row - x[0], ..., last row - x[-1]).
  `nt` is a length of the vector of knots: as far as there are
  `nt - k - 1` basis elements, `nt` should be not less than `2 * k + 2`
  to have at least `k + 1` basis element.
  
  Out of bounds `x` raises a ValueError.
  
  .. note::
      This method returns a `csr_matrix` instance as CuPy still does not
      have `csr_array`.
  
  .. seealso:: :class:`scipy.interpolate.BSpline`
docstr_tok: ["Returns","a","design","matrix","as","a","CSR","format","sparse","array",".","Parameters","--","--","--","--","--","x",":","array_like",",","shape","(","n",",",")","Points","to","evaluate","the","spline","at",".","t",":","array_like",",","shape","(","nt",",",")","Sorted","1D","array","of","knots",".","k",":","int","B-spline","degree",".","extrapolate",":","bool","or","'periodic","'",",","optional","Whether","to","extrapolate","based","on","the","first","and","last","intervals","or","raise","an","error",".","If","'periodic","'",",","periodic","extrapolation","is","used",".","Default","is","False",".","Returns","--","--","--","-","design_matrix",":","`","csr_matrix","`","object","Sparse","matrix","in","CSR","format","where","each","row","contains","all","the","basis","elements","of","the","input","row","(","first","row","=","basis","elements","of","x","[","0","]",",","...",",","last","row","=","basis","elements","x","[","-1","]",")",".","Notes","--","--","-","In","each","row","of","the","design","matrix","all","the","basis","elements","are","evaluated","at","the","certain","point","(","first","row","-","x","[","0","]",",","...",",","last","row","-","x","[","-1","]",")",".","`","nt","`","is","a","length","of","the","vector","of","knots",":","as","far","as","there","are","`","nt","-","k","-","1","`","basis","elements",",","`","nt","`","should","be","not","less","than","`","2","*","k","+","2","`","to","have","at","least","`","k","+","1","`","basis","element",".","Out","of","bounds","`","x","`","raises","a","ValueError",".","..","note",":",":","This","method","returns","a","`","csr_matrix","`","instance","as","CuPy","still","does","not","have","`","csr_array","`",".","..","seealso",":",":",":","class",":","`","scipy.interpolate.BSpline","`"]
code: def design_matrix(cls, x, t, k, extrapolate=False):
      """
      Returns a design matrix as a CSR format sparse array.
  
      Parameters
      ----------
      x : array_like, shape (n,)
          Points to evaluate the spline at.
      t : array_like, shape (nt,)
          Sorted 1D array of knots.
      k : int
          B-spline degree.
      extrapolate : bool or 'periodic', optional
          Whether to extrapolate based on the first and last intervals
          or raise an error. If 'periodic', periodic extrapolation is used.
          Default is False.
  
      Returns
      -------
      design_matrix : `csr_matrix` object
          Sparse matrix in CSR format where each row contains all the basis
          elements of the input row (first row = basis elements of x[0],
          ..., last row = basis elements x[-1]).
  
      Notes
      -----
      In each row of the design matrix all the basis elements are evaluated
      at the certain point (first row - x[0], ..., last row - x[-1]).
      `nt` is a length of the vector of knots: as far as there are
      `nt - k - 1` basis elements, `nt` should be not less than `2 * k + 2`
      to have at least `k + 1` basis element.
  
      Out of bounds `x` raises a ValueError.
  
      .. note::
          This method returns a `csr_matrix` instance as CuPy still does not
          have `csr_array`.
  
      .. seealso:: :class:`scipy.interpolate.BSpline`
      """
      x = _as_float_array(x, True)
      t = _as_float_array(t, True)
  
      if extrapolate != "periodic":
          extrapolate = bool(extrapolate)
  
      if k < 0:
          raise ValueError("Spline order cannot be negative.")
      if t.ndim != 1 or np.any(t[1:] < t[:-1]):
          raise ValueError(
              f"Expect t to be a 1-D sorted array_like, but "
              f"got t={t}."
          )
      # There are `nt - k - 1` basis elements in a BSpline built on the
      # vector of knots with length `nt`, so to have at least `k + 1` basis
      # elements we need to have at least `2 * k + 2` elements in the vector
      # of knots.
      if len(t) < 2 * k + 2:
          raise ValueError(f"Length t is not enough for k={k}.")
  
      if extrapolate == "periodic":
          # With periodic extrapolation we map x to the segment
          # [t[k], t[n]].
          n = t.size - k - 1
          x = t[k] + (x - t[k]) % (t[n] - t[k])
          extrapolate = False
      elif not extrapolate and (
          (min(x) < t[k]) or (max(x) > t[t.shape[0] - k - 1])
      ):
          # Checks from `find_interval` function
          raise ValueError(f"Out of bounds w/ x = {x}.")
  
      # Compute number of non-zeros of final CSR array in order to determine
      # the dtype of indices and indptr of the CSR array.
      n = x.shape[0]
      nnz = n * (k + 1)
      if nnz < cupy.iinfo(cupy.int32).max:
          int_dtype = cupy.int32
      else:
          int_dtype = cupy.int64
      # Preallocate indptr and indices
      indices = cupy.empty(n * (k + 1), dtype=int_dtype)
      indptr = cupy.arange(0, (n + 1) * (k + 1), k + 1, dtype=int_dtype)
  
      # indptr is not passed to CUDA as it is already fully computed
      data, indices = _make_design_matrix(x, t, k, extrapolate, indices)
      return csr_matrix(
          (data, indices, indptr),
          shape=(x.shape[0], t.shape[0] - k - 1),
      )
  
imports: import operator
  import cupy
  from cupy._core import internal
  from cupy._core._scalar import get_typename
  from cupyx.scipy.sparse import csr_matrix
  import numpy
label_desc: Use image node_id 5 for calling the BSpline obj's underlying member method code with example usage: obj.design_matrix(cls, x, t, k, extrapolate) and returns: csr_matrix