code: def _spline_fit(X):
      breaks = np.array([0, len(X) / 2 - 1, len(X) - 1])
      h0 = np.array([breaks[1] - breaks[0], breaks[2] - breaks[1]])
      h_copy = np.array([h0[0], h0[1], h0[0], h0[1]])
      hl = np.array([h_copy[3], h_copy[2], h_copy[1]])
      hr = np.array([h_copy[0], h_copy[1], h_copy[2]])
  
      hlCS = np.zeros(3)
      hlCS[0] = hl[0]
      for i in range(1, 3):
          hlCS[i] = hlCS[i - 1] + hl[i]
  
      bl = np.zeros(3)
      for i in range(3):
          bl[i] = breaks[0] - hlCS[i]
  
      hrCS = np.zeros(3)
      hrCS[0] = hr[0]
      for i in range(1, 3):
          hrCS[i] = hrCS[i - 1] + hr[i]
  
      br = np.zeros(3)
      for i in range(3):
          br[i] = breaks[2] - hrCS[i]
  
      breaksExt = np.zeros(9)
      for i in range(3):
          breaksExt[i] = bl[2 - i]
          breaksExt[i + 3] = breaks[i]
          breaksExt[i + 6] = br[i]
  
      hExt = np.zeros(8)
      for i in range(8):
          hExt[i] = breaksExt[i + 1] - breaksExt[i]
  
      coeffs = np.zeros((32, 4))
      for i in range(0, 32, 4):
          coeffs[i][0] = 1
  
      ii = np.zeros((4, 8), dtype=np.int32)
      for i in range(8):
          ii[0][i] = i
          ii[1][i] = min(1 + i, 7)
          ii[2][i] = min(2 + i, 7)
          ii[3][i] = min(3 + i, 7)
  
      H = np.zeros(32)
      for i in range(32):
          H[i] = hExt[ii[i % 4][int(i / 4)]]
  
      for k in range(1, 4):
          for j in range(k):
              for u in range(32):
                  coeffs[u][j] *= H[u] / (k - j)
  
          Q = np.zeros((4, 8))
          for u in range(32):
              for m in range(4):
                  Q[u % 4][int(u / 4)] += coeffs[u][m]
  
          for u in range(8):
              for m in range(1, 4):
                  Q[m][u] += Q[m - 1][u]
  
          for u in range(32):
              if u % 4 > 0:
                  coeffs[u][k] = Q[u % 4 - 1][int(u / 4)]
  
          fmax = np.zeros(32)
          for i in range(8):
              for j in range(4):
                  fmax[i * 4 + j] = Q[3][i]
  
          for j in range(k + 1):
              for u in range(32):
                  coeffs[u][j] /= fmax[u]
  
          for i in range(29):
              for j in range(k + 1):
                  coeffs[i][j] -= coeffs[3 + i][j]
  
          for i in range(0, 32, 4):
              coeffs[i][k] = 0
  
      scale = np.ones(32)
      for k in range(3):
          for i in range(32):
              scale[i] /= H[i]
  
          for i in range(32):
              coeffs[i][3 - (k + 1)] *= scale[i]
  
      jj = np.zeros((4, 2), dtype=np.int32)
      for i in range(4):
          for j in range(2):
              if i == 0:
                  jj[i][j] = 4 * (1 + j)
              else:
                  jj[i][j] = 3
  
      for i in range(1, 4):
          for j in range(2):
              jj[i][j] += jj[i - 1][j]
  
      coeffs_out = np.zeros((8, 4))
      for i in range(8):
          coeffs_out[i] = coeffs[jj[i % 4][int(i / 4)] - 1]
  
      xsB = np.zeros(len(X) * 4)
      indexB = np.zeros(len(xsB), dtype=np.int32)
      breakInd = 1
      for i in range(len(X)):
          if i >= breaks[1] and breakInd < 2:
              breakInd += 1
  
          for j in range(4):
              xsB[i * 4 + j] = i - breaks[breakInd - 1]
              indexB[i * 4 + j] = j + (breakInd - 1) * 4
  
      vB = np.zeros(len(xsB))
      for i in range(len(xsB)):
          vB[i] = coeffs_out[indexB[i]][0]
  
      for i in range(1, 4):
          for j in range(len(xsB)):
              vB[j] = vB[j] * xsB[j] + coeffs_out[indexB[j]][i]
  
      A = np.zeros(len(X) * 5)
      breakInd = 0
      for i in range(len(xsB)):
          if i / 4 >= breaks[1]:
              breakInd = 1
          A[i % 4 + breakInd + int(i / 4) * 5] = vB[i]
  
      AT = np.zeros(len(A))
      ATA = np.zeros(25)
      ATb = np.zeros(5)
      for i in range(len(X)):
          for j in range(5):
              AT[j * len(X) + i] = A[i * 5 + j]
  
      for i in range(5):
          for j in range(5):
              for k in range(len(X)):
                  ATA[i * 5 + j] += AT[i * len(X) + k] * A[k * 5 + j]
  
      for i in range(5):
          for k in range(len(X)):
              ATb[i] += AT[i * len(X) + k] * X[k]
  
      AElim = np.zeros((5, 5))
      for i in range(5):
          n = i * 5
          AElim[i] = ATA[n : n + 5]
  
      for i in range(5):
          for j in range(i + 1, 5):
              factor = AElim[j][i] / AElim[i][i]
              ATb[j] = ATb[j] - factor * ATb[i]
  
              for k in range(i, 5):
                  AElim[j][k] = AElim[j][k] - factor * AElim[i][k]
  
      x = np.zeros(5)
      for i in range(4, -1, -1):
          bMinusATemp = ATb[i]
          for j in range(i + 1, 5):
              bMinusATemp -= x[j] * AElim[i][j]
  
          x[i] = bMinusATemp / AElim[i][i]
  
      C = np.zeros((5, 8))
      for i in range(32):
          C[int(i % 4 + int(i / 4) % 2)][int(i / 4)] = coeffs_out[
              i % 8
          ][int(i / 8)]
  
      coeffs_spline = np.zeros((2, 4))
      for j in range(8):
          coefc = int(j / 2)
          coefr = j % 2
          for i in range(5):
              coeffs_spline[coefr][coefc] += C[i][j] * x[i]
  
      y_out = np.zeros(len(X))
      for i in range(len(X)):
          second_half = 0 if i < breaks[1] else 1
          y_out[i] = coeffs_spline[second_half][0]
  
      for i in range(1, 4):
          for j in range(len(X)):
              second_half = 0 if j < breaks[1] else 1
              y_out[j] = (
                  y_out[j] * (j - breaks[1] * second_half)
                  + coeffs_spline[second_half][i]
              )
  
      return y_out
  
imports: import math
  import numpy
  from sktime.utils.numba.njit import njit
label_desc: Use image node_id 13 for calling a global function with example usage: _spline_fit(X) and returns: y_out