zlanhf function

double zlanhf(
  1. String NORM,
  2. String TRANSR,
  3. String UPLO,
  4. int N,
  5. Array<Complex> A_,
  6. Array<double> WORK_,
)

Implementation

double zlanhf(
  final String NORM,
  final String TRANSR,
  final String UPLO,
  final int N,
  final Array<Complex> A_,
  final Array<double> WORK_,
) {
  final A = A_.having(offset: zeroIndexedArrayOffset);
  final WORK = WORK_.having(offset: zeroIndexedArrayOffset);
  const ONE = 1.0, ZERO = 0.0;
  int I, J, IFM, ILU, NOE, N1, K = 0, L, LDA;
  double VALUE = 0, AA, TEMP;
  final SCALE = Box(0.0), S = Box(0.0);

  if (N == 0) {
    return 0;
  } else if (N == 1) {
    return A[0].abs();
  }

  // set noe = 1 if n is odd. if n is even set noe=0

  NOE = 1;
  if ((N % 2) == 0) NOE = 0;

  // set ifm = 0 when form='C' or 'c' and 1 otherwise

  IFM = 1;
  if (lsame(TRANSR, 'C')) IFM = 0;

  // set ilu = 0 when uplo='U or 'u' and 1 otherwise

  ILU = 1;
  if (lsame(UPLO, 'U')) ILU = 0;

  // set lda = (n+1)/2 when ifm = 0
  // set lda = n when ifm = 1 and noe = 1
  // set lda = n+1 when ifm = 1 and noe = 0

  if (IFM == 1) {
    if (NOE == 1) {
      LDA = N;
    } else {
      // noe=0
      LDA = N + 1;
    }
  } else {
    // ifm=0
    LDA = (N + 1) ~/ 2;
  }

  if (lsame(NORM, 'M')) {
    // Find max(abs(A(i,j))).

    K = (N + 1) ~/ 2;
    VALUE = ZERO;
    if (NOE == 1) {
      // n is odd & n = k + k - 1
      if (IFM == 1) {
        // A is n by k
        if (ILU == 1) {
          // uplo ='L'
          J = 0;
          // -> L(0,0)
          TEMP = A[J + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          for (I = 1; I <= N - 1; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          for (J = 1; J <= K - 1; J++) {
            for (I = 0; I <= J - 2; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = J - 1;
            // L(k+j,k+j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I = J;
            // -> L(j,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = J + 1; I <= N - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
        } else {
          // uplo = 'U'
          for (J = 0; J <= K - 2; J++) {
            for (I = 0; I <= K + J - 2; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = K + J - 1;
            // -> U(i,i)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I++;
            // =k+j; i -> U(j,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = K + J + 1; I <= N - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
          for (I = 0; I <= N - 2; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            // j=k-1
          }
          // i=n-1 -> U(n-1,n-1)
          TEMP = A[I + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
        }
      } else {
        // xpose case; A is k by n
        if (ILU == 1) {
          // uplo ='L'
          for (J = 0; J <= K - 2; J++) {
            for (I = 0; I <= J - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = J;
            TEMP = A[I + J * LDA].real.abs();
            // L(i,i)
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I = J + 1;
            TEMP = A[I + J * LDA].real.abs();
            // L(j+k,j+k)
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = J + 2; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
          J = K - 1;
          for (I = 0; I <= K - 2; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          I = K - 1;
          // -> L(i,i) is at A(i,j)
          TEMP = A[I + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          for (J = K; J <= N - 1; J++) {
            for (I = 0; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
        } else {
          // uplo = 'U'
          for (J = 0; J <= K - 2; J++) {
            for (I = 0; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
          J = K - 1;
          // -> U(j,j) is at A(0,j)
          TEMP = A[(0 + J * LDA)].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          for (I = 1; I <= K - 1; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          for (J = K; J <= N - 1; J++) {
            for (I = 0; I <= J - K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = J - K;
            // -> U(i,i) at A(i,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I = J - K + 1;
            // U(j,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = J - K + 2; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
        }
      }
    } else {
      // n is even & k = n/2
      if (IFM == 1) {
        // A is n+1 by k
        if (ILU == 1) {
          // uplo ='L'
          J = 0;
          // -> L(k,k) & j=1 -> L(0,0)
          TEMP = A[J + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          TEMP = A[J + 1 + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          for (I = 2; I <= N; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          for (J = 1; J <= K - 1; J++) {
            for (I = 0; I <= J - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = J;
            // L(k+j,k+j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I = J + 1;
            // -> L(j,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = J + 2; I <= N; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
        } else {
          // uplo = 'U'
          for (J = 0; J <= K - 2; J++) {
            for (I = 0; I <= K + J - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = K + J;
            // -> U(i,i)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I++;
            // =k+j+1; i -> U(j,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = K + J + 2; I <= N; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
          for (I = 0; I <= N - 2; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            // j=k-1
          }
          // i=n-1 -> U(n-1,n-1)
          TEMP = A[I + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          I = N;
          // -> U(k-1,k-1)
          TEMP = A[I + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
        }
      } else {
        // xpose case; A is k by n+1
        if (ILU == 1) {
          // uplo ='L'
          J = 0;
          // -> L(k,k) at A(0,0)
          TEMP = A[J + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          for (I = 1; I <= K - 1; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          for (J = 1; J <= K - 1; J++) {
            for (I = 0; I <= J - 2; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = J - 1;
            // L(i,i)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I = J;
            // L(j+k,j+k)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = J + 1; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
          J = K;
          for (I = 0; I <= K - 2; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          I = K - 1;
          // -> L(i,i) is at A(i,j)
          TEMP = A[I + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          for (J = K + 1; J <= N; J++) {
            for (I = 0; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
        } else {
          // uplo = 'U'
          for (J = 0; J <= K - 1; J++) {
            for (I = 0; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
          J = K;
          // -> U(j,j) is at A(0,j)
          TEMP = A[0 + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          for (I = 1; I <= K - 1; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          for (J = K + 1; J <= N - 1; J++) {
            for (I = 0; I <= J - K - 2; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
            I = J - K - 1;
            // -> U(i,i) at A(i,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            I = J - K;
            // U(j,j)
            TEMP = A[I + J * LDA].real.abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            for (I = J - K + 1; I <= K - 1; I++) {
              TEMP = A[I + J * LDA].abs();
              if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
            }
          }
          J = N;
          for (I = 0; I <= K - 2; I++) {
            TEMP = A[I + J * LDA].abs();
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
          I = K - 1;
          // U(k,k) at A(i,j)
          TEMP = A[I + J * LDA].real.abs();
          if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
        }
      }
    }
  } else if ((lsame(NORM, 'I')) || (lsame(NORM, 'O')) || (NORM == '1')) {
    // Find normI(A) ( = norm1(A), since A is Hermitian).

    if (IFM == 1) {
      // A is 'N'
      K = N ~/ 2;
      if (NOE == 1) {
        // n is odd & A is n by (n+1)/2
        if (ILU == 0) {
          // uplo = 'U'
          for (I = 0; I <= K - 1; I++) {
            WORK[I] = ZERO;
          }
          for (J = 0; J <= K; J++) {
            S.value = ZERO;
            for (I = 0; I <= K + J - 1; I++) {
              AA = A[I + J * LDA].abs();
              // -> A(i,j+k)
              S.value += AA;
              WORK[I] += AA;
            }
            AA = A[I + J * LDA].real.abs();
            // -> A(j+k,j+k)
            WORK[J + K] = S.value + AA;
            if (I == K + K) break;
            I++;
            AA = A[I + J * LDA].real.abs();
            // -> A(j,j)
            WORK[J] += AA;
            S.value = ZERO;
            for (L = J + 1; L <= K - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // -> A(l,j)
              S.value += AA;
              WORK[L] += AA;
            }
            WORK[J] += S.value;
          }
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        } else {
          // ilu = 1 & uplo = 'L'
          K++;
          // k=(n+1)/2 for n odd and ilu=1
          for (I = K; I <= N - 1; I++) {
            WORK[I] = ZERO;
          }
          for (J = K - 1; J >= 0; J--) {
            S.value = ZERO;
            for (I = 0; I <= J - 2; I++) {
              AA = A[I + J * LDA].abs();
              // -> A(j+k,i+k)
              S.value += AA;
              WORK[I + K] += AA;
            }
            if (J > 0) {
              AA = A[I + J * LDA].real.abs();
              // -> A(j+k,j+k)
              S.value += AA;
              WORK[I + K] += S.value;
              // i=j
              I++;
            }
            AA = A[I + J * LDA].real.abs();
            // -> A(j,j)
            WORK[J] = AA;
            S.value = ZERO;
            for (L = J + 1; L <= N - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // -> A(l,j)
              S.value += AA;
              WORK[L] += AA;
            }
            WORK[J] += S.value;
          }
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        }
      } else {
        // n is even & A is n+1 by k = n/2
        if (ILU == 0) {
          // uplo = 'U'
          for (I = 0; I <= K - 1; I++) {
            WORK[I] = ZERO;
          }
          for (J = 0; J <= K - 1; J++) {
            S.value = ZERO;
            for (I = 0; I <= K + J - 1; I++) {
              AA = A[I + J * LDA].abs();
              // -> A(i,j+k)
              S.value += AA;
              WORK[I] += AA;
            }
            AA = A[I + J * LDA].real.abs();
            // -> A(j+k,j+k)
            WORK[J + K] = S.value + AA;
            I++;
            AA = A[I + J * LDA].real.abs();
            // -> A(j,j)
            WORK[J] += AA;
            S.value = ZERO;
            for (L = J + 1; L <= K - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // -> A(l,j)
              S.value += AA;
              WORK[L] += AA;
            }
            WORK[J] += S.value;
          }
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        } else {
          // ilu = 1 & uplo = 'L'
          for (I = K; I <= N - 1; I++) {
            WORK[I] = ZERO;
          }
          for (J = K - 1; J >= 0; J--) {
            S.value = ZERO;
            for (I = 0; I <= J - 1; I++) {
              AA = A[I + J * LDA].abs();
              // -> A(j+k,i+k)
              S.value += AA;
              WORK[I + K] += AA;
            }
            AA = A[I + J * LDA].real.abs();
            // -> A(j+k,j+k)
            S.value += AA;
            WORK[I + K] += S.value;
            // i=j
            I++;
            AA = A[I + J * LDA].real.abs();
            // -> A(j,j)
            WORK[J] = AA;
            S.value = ZERO;
            for (L = J + 1; L <= N - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // -> A(l,j)
              S.value += AA;
              WORK[L] += AA;
            }
            WORK[J] += S.value;
          }
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        }
      }
    } else {
      // ifm=0
      K = N ~/ 2;
      if (NOE == 1) {
        // n is odd & A is (n+1)/2 by n
        if (ILU == 0) {
          // uplo = 'U'
          N1 = K;
          // n/2
          K++;
          // k is the row size and lda
          for (I = N1; I <= N - 1; I++) {
            WORK[I] = ZERO;
          }
          for (J = 0; J <= N1 - 1; J++) {
            S.value = ZERO;
            for (I = 0; I <= K - 1; I++) {
              AA = A[I + J * LDA].abs();
              // A(j,n1+i)
              WORK[I + N1] += AA;
              S.value += AA;
            }
            WORK[J] = S.value;
          }
          // j=n1=k-1 is special
          S.value = A[0 + J * LDA].real;
          // A(k-1,k-1)
          for (I = 1; I <= K - 1; I++) {
            AA = A[I + J * LDA].abs();
            // A(k-1,i+n1)
            WORK[I + N1] += AA;
            S.value += AA;
          }
          WORK[J] += S.value;
          for (J = K; J <= N - 1; J++) {
            S.value = ZERO;
            for (I = 0; I <= J - K - 1; I++) {
              AA = A[I + J * LDA].abs();
              // A(i,j-k)
              WORK[I] += AA;
              S.value += AA;
            }
            // i=j-k
            AA = A[I + J * LDA].real.abs();
            // A(j-k,j-k)
            S.value += AA;
            WORK[J - K] += S.value;
            I++;
            S.value = A[I + J * LDA].real.abs();
            // A(j,j)
            for (L = J + 1; L <= N - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // A(j,l)
              WORK[L] += AA;
              S.value += AA;
            }
            WORK[J] += S.value;
          }
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        } else {
          // ilu=1 & uplo = 'L'
          K++;
          // k=(n+1)/2 for n odd and ilu=1
          for (I = K; I <= N - 1; I++) {
            WORK[I] = ZERO;
          }
          for (J = 0; J <= K - 2; J++) {
            // process
            S.value = ZERO;
            for (I = 0; I <= J - 1; I++) {
              AA = A[I + J * LDA].abs();
              // A(j,i)
              WORK[I] += AA;
              S.value += AA;
            }
            AA = A[I + J * LDA].real.abs();
            // i=j so process of A(j,j)
            S.value += AA;
            WORK[J] = S.value;
            // is initialised here
            I++;
            // i=j process A(j+k,j+k)
            AA = A[I + J * LDA].real.abs();
            S.value = AA;
            for (L = K + J + 1; L <= N - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // A(l,k+j)
              S.value += AA;
              WORK[L] += AA;
            }
            WORK[K + J] += S.value;
          }
          // j=k-1 is special :process col A(k-1,0:k-1)
          S.value = ZERO;
          for (I = 0; I <= K - 2; I++) {
            AA = A[I + J * LDA].abs();
            // A(k,i)
            WORK[I] += AA;
            S.value += AA;
          }
          // i=k-1
          AA = A[I + J * LDA].real.abs();
          // A(k-1,k-1)
          S.value += AA;
          WORK[I] = S.value;
          // done with col j=k+1
          for (J = K; J <= N - 1; J++) {
            // process col j of A = A(j,0:k-1)
            S.value = ZERO;
            for (I = 0; I <= K - 1; I++) {
              AA = A[I + J * LDA].abs();
              // A(j,i)
              WORK[I] += AA;
              S.value += AA;
            }
            WORK[J] += S.value;
          }
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        }
      } else {
        // n is even & A is k=n/2 by n+1
        if (ILU == 0) {
          // uplo = 'U'
          for (I = K; I <= N - 1; I++) {
            WORK[I] = ZERO;
          }
          for (J = 0; J <= K - 1; J++) {
            S.value = ZERO;
            for (I = 0; I <= K - 1; I++) {
              AA = A[I + J * LDA].abs();
              // A(j,i+k)
              WORK[I + K] += AA;
              S.value += AA;
            }
            WORK[J] = S.value;
          }
          // j=k
          AA = A[0 + J * LDA].real;
          // A(k,k)
          S.value = AA;
          for (I = 1; I <= K - 1; I++) {
            AA = A[I + J * LDA].abs();
            // A(k,k+i)
            WORK[I + K] += AA;
            S.value += AA;
          }
          WORK[J] += S.value;
          for (J = K + 1; J <= N - 1; J++) {
            S.value = ZERO;
            for (I = 0; I <= J - 2 - K; I++) {
              AA = A[I + J * LDA].abs();
              // A(i,j-k-1)
              WORK[I] += AA;
              S.value += AA;
            }
            // i=j-1-k
            AA = A[I + J * LDA].real.abs();
            // A(j-k-1,j-k-1)
            S.value += AA;
            WORK[J - K - 1] += S.value;
            I++;
            AA = A[I + J * LDA].real.abs();
            // A(j,j)
            S.value = AA;
            for (L = J + 1; L <= N - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // A(j,l)
              WORK[L] += AA;
              S.value += AA;
            }
            WORK[J] += S.value;
          }
          // j=n
          S.value = ZERO;
          for (I = 0; I <= K - 2; I++) {
            AA = A[I + J * LDA].abs();
            // A(i,k-1)
            WORK[I] += AA;
            S.value += AA;
          }
          // i=k-1
          AA = A[I + J * LDA].real.abs();
          // A(k-1,k-1)
          S.value += AA;
          WORK[I] += S.value;
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        } else {
          // ilu=1 & uplo = 'L'
          for (I = K; I <= N - 1; I++) {
            WORK[I] = ZERO;
          }
          // j=0 is special :process col A(k:n-1,k)
          S.value = A[0].real.abs();
          // A(k,k)
          for (I = 1; I <= K - 1; I++) {
            AA = A[I].abs();
            // A(k+i,k)
            WORK[I + K] += AA;
            S.value += AA;
          }
          WORK[K] += S.value;
          for (J = 1; J <= K - 1; J++) {
            // process
            S.value = ZERO;
            for (I = 0; I <= J - 2; I++) {
              AA = A[I + J * LDA].abs();
              // A(j-1,i)
              WORK[I] += AA;
              S.value += AA;
            }
            AA = A[I + J * LDA].real.abs();
            // i=j-1 so process of A(j-1,j-1)
            S.value += AA;
            WORK[J - 1] = S.value;
            // is initialised here
            I++;
            // i=j process A(j+k,j+k)
            AA = A[I + J * LDA].real.abs();
            S.value = AA;
            for (L = K + J + 1; L <= N - 1; L++) {
              I++;
              AA = A[I + J * LDA].abs();
              // A(l,k+j)
              S.value += AA;
              WORK[L] += AA;
            }
            WORK[K + J] += S.value;
          }
          // j=k is special :process col A(k,0:k-1)
          S.value = ZERO;
          for (I = 0; I <= K - 2; I++) {
            AA = A[I + J * LDA].abs();
            // A(k,i)
            WORK[I] += AA;
            S.value += AA;
          }

          // i=k-1
          AA = A[I + J * LDA].real.abs();
          // A(k-1,k-1)
          S.value += AA;
          WORK[I] = S.value;
          // done with col j=k+1
          for (J = K + 1; J <= N; J++) {
            // process col j-1 of A = A(j-1,0:k-1)
            S.value = ZERO;
            for (I = 0; I <= K - 1; I++) {
              AA = A[I + J * LDA].abs();
              // A(j-1,i)
              WORK[I] += AA;
              S.value += AA;
            }
            WORK[J - 1] += S.value;
          }
          VALUE = WORK[0];
          for (I = 1; I <= N - 1; I++) {
            TEMP = WORK[I];
            if (VALUE < TEMP || disnan(TEMP)) VALUE = TEMP;
          }
        }
      }
    }
  } else if ((lsame(NORM, 'F')) || (lsame(NORM, 'E'))) {
    // Find normF(A).

    K = (N + 1) ~/ 2;
    SCALE.value = ZERO;
    S.value = ONE;
    if (NOE == 1) {
      // n is odd
      if (IFM == 1) {
        // A is normal & A is n by k
        if (ILU == 0) {
          // A is upper
          for (J = 0; J <= K - 3; J++) {
            zlassq(K - J - 2, A(K + J + 1 + J * LDA), 1, SCALE, S);
            // L at A(k,0)
          }
          for (J = 0; J <= K - 1; J++) {
            zlassq(K + J - 1, A(0 + J * LDA), 1, SCALE, S);
            // trap U at A(0,0)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          L = K - 1;
          // -> U(k,k) at A(k-1,0)
          for (I = 0; I <= K - 2; I++) {
            AA = A[L].real;
            // U(k+i,k+i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // U(i,i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
          AA = A[L].real;
          // U(n-1,n-1)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
        } else {
          // ilu=1 & A is lower
          for (J = 0; J <= K - 1; J++) {
            zlassq(N - J - 1, A(J + 1 + J * LDA), 1, SCALE, S);
            // trap L at A(0,0)
          }
          for (J = 1; J <= K - 2; J++) {
            zlassq(J, A(0 + (1 + J) * LDA), 1, SCALE, S);
            // U at A(0,1)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          AA = A[0].real;
          // L(0,0) at A(0,0)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
          L = LDA;
          // -> L(k,k) at A(0,1)
          for (I = 1; I <= K - 1; I++) {
            AA = A[L].real;
            // L(k-1+i,k-1+i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // L(i,i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
        }
      } else {
        // A is xpose & A is k by n
        if (ILU == 0) {
          // A**H is upper
          for (J = 1; J <= K - 2; J++) {
            zlassq(J, A(0 + (K + J) * LDA), 1, SCALE, S);
            // U at A(0,k)
          }
          for (J = 0; J <= K - 2; J++) {
            zlassq(K, A(0 + J * LDA), 1, SCALE, S);
            // k by k-1 rect. at A(0,0)
          }
          for (J = 0; J <= K - 2; J++) {
            zlassq(K - J - 1, A(J + 1 + (J + K - 1) * LDA), 1, SCALE, S);
            // L at A(0,k-1)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          L = 0 + K * LDA - LDA;
          // -> U(k-1,k-1) at A(0,k-1)
          AA = A[L].real;
          // U(k-1,k-1)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
          L += LDA;
          // -> U(0,0) at A(0,k)
          for (J = K; J <= N - 1; J++) {
            AA = A[L].real;
            // -> U(j-k,j-k)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // -> U(j,j)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
        } else {
          // A**H is lower
          for (J = 1; J <= K - 1; J++) {
            zlassq(J, A(0 + J * LDA), 1, SCALE, S);
            // U at A(0,0)
          }
          for (J = K; J <= N - 1; J++) {
            zlassq(K, A(0 + J * LDA), 1, SCALE, S);
            // k by k-1 rect. at A(0,k)
          }
          for (J = 0; J <= K - 3; J++) {
            zlassq(K - J - 2, A(J + 2 + J * LDA), 1, SCALE, S);
            // L at A(1,0)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          L = 0;
          // -> L(0,0) at A(0,0)
          for (I = 0; I <= K - 2; I++) {
            AA = A[L].real;
            // L(i,i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // L(k+i,k+i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
          // L-> k-1 + (k-1)*lda or L(k-1,k-1) at A(k-1,k-1)
          AA = A[L].real;
          // L(k-1,k-1) at A(k-1,k-1)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
        }
      }
    } else {
      // n is even
      if (IFM == 1) {
        // A is normal
        if (ILU == 0) {
          // A is upper
          for (J = 0; J <= K - 2; J++) {
            zlassq(K - J - 1, A(K + J + 2 + J * LDA), 1, SCALE, S);
            // L at A(k+1,0)
          }
          for (J = 0; J <= K - 1; J++) {
            zlassq(K + J, A(0 + J * LDA), 1, SCALE, S);
            // trap U at A(0,0)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          L = K;
          // -> U(k,k) at A(k,0)
          for (I = 0; I <= K - 1; I++) {
            AA = A[L].real;
            // U(k+i,k+i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // U(i,i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
        } else {
          // ilu=1 & A is lower
          for (J = 0; J <= K - 1; J++) {
            zlassq(N - J - 1, A(J + 2 + J * LDA), 1, SCALE, S);
            // trap L at A(1,0)
          }
          for (J = 1; J <= K - 1; J++) {
            zlassq(J, A(0 + J * LDA), 1, SCALE, S);
            // U at A(0,0)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          L = 0;
          // -> L(k,k) at A(0,0)
          for (I = 0; I <= K - 1; I++) {
            AA = A[L].real;
            // L(k-1+i,k-1+i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // L(i,i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
        }
      } else {
        // A is xpose
        if (ILU == 0) {
          // A**H is upper
          for (J = 1; J <= K - 1; J++) {
            zlassq(J, A(0 + (K + 1 + J) * LDA), 1, SCALE, S);
            // U at A(0,k+1)
          }
          for (J = 0; J <= K - 1; J++) {
            zlassq(K, A(0 + J * LDA), 1, SCALE, S);
            // k by k rect. at A(0,0)
          }
          for (J = 0; J <= K - 2; J++) {
            zlassq(K - J - 1, A(J + 1 + (J + K) * LDA), 1, SCALE, S);
            // L at A(0,k)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          L = 0 + K * LDA;
          // -> U(k,k) at A(0,k)
          AA = A[L].real;
          // U(k,k)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
          L += LDA;
          // -> U(0,0) at A(0,k+1)
          for (J = K + 1; J <= N - 1; J++) {
            AA = A[L].real;
            // -> U(j-k-1,j-k-1)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // -> U(j,j)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
          // L=k-1+n*lda
          // -> U(k-1,k-1) at A(k-1,n)
          AA = A[L].real;
          // U(k,k)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
        } else {
          // A**H is lower
          for (J = 1; J <= K - 1; J++) {
            zlassq(J, A(0 + (J + 1) * LDA), 1, SCALE, S);
            // U at A(0,1)
          }
          for (J = K + 1; J <= N; J++) {
            zlassq(K, A(0 + J * LDA), 1, SCALE, S);
            // k by k rect. at A(0,k+1)
          }
          for (J = 0; J <= K - 2; J++) {
            zlassq(K - J - 1, A(J + 1 + J * LDA), 1, SCALE, S);
            // L at A(0,0)
          }
          S.value += S.value;
          // double s for the off diagonal elements
          L = 0;
          // -> L(k,k) at A(0,0)
          AA = A[L].real;
          // L(k,k) at A(0,0)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
          L = LDA;
          // -> L(0,0) at A(0,1)
          for (I = 0; I <= K - 2; I++) {
            AA = A[L].real;
            // L(i,i)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            AA = A[L + 1].real;
            // L(k+i+1,k+i+1)
            if (AA != ZERO) {
              if (SCALE.value < AA) {
                S.value = ONE + S.value * pow(SCALE.value / AA, 2);
                SCALE.value = AA;
              } else {
                S.value += pow(AA / SCALE.value, 2);
              }
            }
            L += LDA + 1;
          }
          // L-> k - 1 + k*lda or L(k-1,k-1) at A(k-1,k)
          AA = A[L].real;
          // L(k-1,k-1) at A(k-1,k)
          if (AA != ZERO) {
            if (SCALE.value < AA) {
              S.value = ONE + S.value * pow(SCALE.value / AA, 2);
              SCALE.value = AA;
            } else {
              S.value += pow(AA / SCALE.value, 2);
            }
          }
        }
      }
    }
    VALUE = SCALE.value * sqrt(S.value);
  }

  return VALUE;
}