code: private static double startv(Matrix A, double[][] q, double[][] wptr, int step) {
          // get initial vector; default is random
          double rnm = Math.dot(wptr[0], wptr[0]);
          double[] r = wptr[0];
          for (int id = 0; id < 3; id++) {
              if (id > 0 || step > 0 || rnm == 0) {
                  for (int i = 0; i < r.length; i++) {
                      r[i] = Math.random() - 0.5;
                  }
              }
              Math.copy(wptr[0], wptr[3]);
  
              // apply operator to put r in range (essential if m singular)
              A.ax(wptr[3], wptr[0]);
              Math.copy(wptr[0], wptr[3]);
              rnm = Math.dot(wptr[0], wptr[3]);
              if (rnm > 0.0) {
                  break;
              }
          }
  
          // fatal error
          if (rnm <= 0.0) {
              logger.error("Lanczos method was unable to find a starting vector within range.");
              return -1;
          }
  
          if (step > 0) {
              for (int i = 0; i < step; i++) {
                  double t = Math.dot(wptr[3], q[i]);
                  Math.axpy(-t, q[i], wptr[0]);
              }
  
              // make sure q[step] is orthogonal to q[step-1]
              double t = Math.dot(wptr[4], wptr[0]);
              Math.axpy(-t, wptr[2], wptr[0]);
              Math.copy(wptr[0], wptr[3]);
              t = Math.dot(wptr[3], wptr[0]);
              if (t <= Math.EPSILON * rnm) {
                  t = 0.0;
              }
              rnm = t;
          }
  
          return Math.sqrt(rnm);
      }
docs: Generate a starting vector in r and returns |r|. It returns zero if the
  range is spanned, and throws exception if no starting vector within range
  of operator can be found.
  @param step   starting index for a Lanczos run