function reduceToHessenberg (arr, N, prec, type, findVectors, R) {
    const big = type === 'BigNumber'
    const cplx = type === 'Complex'

    const zero = big ? bignumber(0) : cplx ? complex(0) : 0

    if (big) { prec = bignumber(prec) }

    for (let i = 0; i < N - 2; i++) {
      // Find the largest subdiag element in the i-th col

      let maxIndex = 0
      let max = zero

      for (let j = i + 1; j < N; j++) {
        const el = arr[j][i]
        if (smaller(abs(max), abs(el))) {
          max = el
          maxIndex = j
        }
      }

      // This col is pivoted, no need to do anything
      if (smaller(abs(max), prec)) {
        continue
      }

      if (maxIndex !== i + 1) {
        // Interchange maxIndex-th and (i+1)-th row
        const tmp1 = arr[maxIndex]
        arr[maxIndex] = arr[i + 1]
        arr[i + 1] = tmp1

        // Interchange maxIndex-th and (i+1)-th column
        for (let j = 0; j < N; j++) {
          const tmp2 = arr[j][maxIndex]
          arr[j][maxIndex] = arr[j][i + 1]
          arr[j][i + 1] = tmp2
        }

        // keep track of transformations
        if (findVectors) {
          const tmp3 = R[maxIndex]
          R[maxIndex] = R[i + 1]
          R[i + 1] = tmp3
        }
      }

      // Reduce following rows and columns
      for (let j = i + 2; j < N; j++) {
        const n = divideScalar(arr[j][i], max)

        if (n === 0) {
          continue
        }

        // from j-th row subtract n-times (i+1)th row
        for (let k = 0; k < N; k++) {
          arr[j][k] = subtract(arr[j][k], multiplyScalar(n, arr[i + 1][k]))
        }

        // to (i+1)th column add n-times j-th column
        for (let k = 0; k < N; k++) {
          arr[k][i + 1] = addScalar(arr[k][i + 1], multiplyScalar(n, arr[k][j]))
        }

        // keep track of transformations
        if (findVectors) {
          for (let k = 0; k < N; k++) {
            R[j][k] = subtract(R[j][k], multiplyScalar(n, R[i + 1][k]))
          }
        }
      }
    }

    return R
  }
@param {number[][]} arr
@param {number} N
@param {number} prec
@param {'number'|'BigNumber'|'Complex'} type
@param {boolean} findVectors
@param {number[][]} R the row transformation matrix that will be modified