code: def __basis(self, xi, p, compute_derivatives=False):
          
  
          if p == 0:
              return self.__basis0(xi)
          else:
              basis_p_minus_1 = self.__basis(xi, p - 1)
  
          first_term_numerator = xi - self.knot_vector[:-p]
          first_term_denominator = self.knot_vector[p:] - self.knot_vector[:-p]
  
          second_term_numerator = self.knot_vector[(p + 1):] - xi
          second_term_denominator = (self.knot_vector[(p + 1):] -
                                     self.knot_vector[1:-p])
  
  
          #Change numerator in last recursion if derivatives are desired
          if compute_derivatives and p == self.p:
  
              first_term_numerator = p
              second_term_numerator = -p
  
          #Disable divide by zero error because we check for it
          with np.errstate(divide='ignore', invalid='ignore'):
              first_term = np.where(first_term_denominator != 0.0,
                                    (first_term_numerator /
                                     first_term_denominator), 0.0)
              second_term = np.where(second_term_denominator != 0.0,
                                     (second_term_numerator /
                                      second_term_denominator), 0.0)
  
          return  (first_term[:-1] * basis_p_minus_1[:-1] +
                   second_term * basis_p_minus_1[1:])
docs: Recursive Cox - de Boor function (for internal use).
  
          Compute basis functions and optionally their first derivatives.