gt:             for (int i = 0; i < m; ++i) {
context: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.commons.math.linear;
  
  import org.apache.commons.math.exception.MaxCountExceededException;
  import org.apache.commons.math.exception.DimensionMismatchException;
  import org.apache.commons.math.exception.util.LocalizedFormats;
  import org.apache.commons.math.util.MathUtils;
  import org.apache.commons.math.util.FastMath;
  
  /**
   * Calculates the eigen decomposition of a real <strong>symmetric</strong>
   * matrix.
   * <p>
   * The eigen decomposition of matrix A is a set of two matrices: V and D such
   * that A = V D V<sup>T</sup>. A, V and D are all m &times; m matrices.
   * </p>
   * <p>
   * As of 2.0, this class supports only <strong>symmetric</strong> matrices, and
   * hence computes only real realEigenvalues. This implies the D matrix returned
   * by {@link #getD()} is always diagonal and the imaginary values returned
   * {@link #getImagEigenvalue(int)} and {@link #getImagEigenvalues()} are always
   * null.
   * </p>
   * <p>
   * When called with a {@link RealMatrix} argument, this implementation only uses
   * the upper part of the matrix, the part below the diagonal is not accessed at
   * all.
   * </p>
   * <p>
   * This implementation is based on the paper by A. Drubrulle, R.S. Martin and
   * J.H. Wilkinson 'The Implicit QL Algorithm' in Wilksinson and Reinsch (1971)
   * Handbook for automatic computation, vol. 2, Linear algebra, Springer-Verlag,
   * New-York
   * </p>
   * @version $Revision$ $Date$
   * @since 2.0
   */
  public class EigenDecompositionImpl implements EigenDecomposition {
  
      /** Maximum number of iterations accepted in the implicit QL transformation */
      private byte maxIter = 30;
  
      /** Main diagonal of the tridiagonal matrix. */
      private double[] main;
  
      /** Secondary diagonal of the tridiagonal matrix. */
      private double[] secondary;
  
      /**
       * Transformer to tridiagonal (may be null if matrix is already
       * tridiagonal).
       */
      private TriDiagonalTransformer transformer;
  
      /** Real part of the realEigenvalues. */
      private double[] realEigenvalues;
  
      /** Imaginary part of the realEigenvalues. */
      private double[] imagEigenvalues;
  
      /** Eigenvectors. */
      private ArrayRealVector[] eigenvectors;
  
      /** Cached value of V. */
      private RealMatrix cachedV;
  
      /** Cached value of D. */
      private RealMatrix cachedD;
  
      /** Cached value of Vt. */
      private RealMatrix cachedVt;
  
      /**
       * Calculates the eigen decomposition of the given symmetric matrix.
       *
       * @param matrix Matrix to decompose. It <em>must</em> be symmetric.
       * @param splitTolerance Dummy parameter (present for backward
       * compatibility only).
       * @throws NonSymmetricMatrixException if the matrix is not symmetric.
       * @throws MaxCountExceededException if the algorithm fails to converge.
       */
      public EigenDecompositionImpl(final RealMatrix matrix,
                                    final double splitTolerance)  {
          if (isSymmetric(matrix, true)) {
              transformToTridiagonal(matrix);
              findEigenVectors(transformer.getQ().getData());
          }
      }
  
      /**
       * Calculates the eigen decomposition of the symmetric tridiagonal
       * matrix.  The Householder matrix is assumed to be the identity matrix.
       *
       * @param main Main diagonal of the symmetric triadiagonal form
       * @param secondary Secondary of the tridiagonal form
       * @param splitTolerance Dummy parameter (present for backward
       * compatibility only).
       * @throws MaxCountExceededException if the algorithm fails to converge.
       */
      public EigenDecompositionImpl(final double[] main,final double[] secondary,
                                    final double splitTolerance) {
          this.main      = main.clone();
          this.secondary = secondary.clone();
          transformer    = null;
          final int size=main.length;
          double[][] z = new double[size][size];
          for (int i=0;i<size;i++) {
              z[i][i]=1.0;
          }
          findEigenVectors(z);
      }
  
      /**
       * Check if a matrix is symmetric.
       *
       * @param matrix Matrix to check.
       * @param raiseException If {@code true}, the method will throw an
       * exception if {@code matrix} is not symmetric.
       * @return {@code true} if {@code matrix} is symmetric.
       * @throws NonSymmetricMatrixException if the matrix is not symmetric and
       * {@code raiseException} is {@code true}.
       */
      private boolean isSymmetric(final RealMatrix matrix,
                                  boolean raiseException) {
          final int rows = matrix.getRowDimension();
          final int columns = matrix.getColumnDimension();
          final double eps = 10 * rows * columns * MathUtils.EPSILON;
          for (int i = 0; i < rows; ++i) {
              for (int j = i + 1; j < columns; ++j) {
                  final double mij = matrix.getEntry(i, j);
                  final double mji = matrix.getEntry(j, i);
                  if (FastMath.abs(mij - mji) >
                      (FastMath.max(FastMath.abs(mij), FastMath.abs(mji)) * eps)) {
                      if (raiseException) {
                          throw new NonSymmetricMatrixException(i, j, eps);
                      }
                      return false;
                  }
              }
          }
          return true;
      }
  
      /** {@inheritDoc} */
      public RealMatrix getV() {
  
          if (cachedV == null) {
              final int m = eigenvectors.length;
              cachedV = MatrixUtils.createRealMatrix(m, m);
              for (int k = 0; k < m; ++k) {
                  cachedV.setColumnVector(k, eigenvectors[k]);
              }
          }
          // return the cached matrix
          return cachedV;
  
      }
  
      /** {@inheritDoc} */
      public RealMatrix getD() {
          if (cachedD == null) {
              // cache the matrix for subsequent calls
              cachedD = MatrixUtils.createRealDiagonalMatrix(realEigenvalues);
          }
          return cachedD;
      }
  
      /** {@inheritDoc} */
      public RealMatrix getVT() {
  
          if (cachedVt == null) {
              final int m = eigenvectors.length;
              cachedVt = MatrixUtils.createRealMatrix(m, m);
              for (int k = 0; k < m; ++k) {
                  cachedVt.setRowVector(k, eigenvectors[k]);
              }
  
          }
  
          // return the cached matrix
          return cachedVt;
      }
  
      /** {@inheritDoc} */
      public double[] getRealEigenvalues() {
          return realEigenvalues.clone();
      }
  
      /** {@inheritDoc} */
      public double getRealEigenvalue(final int i) {
          return realEigenvalues[i];
      }
  
      /** {@inheritDoc} */
      public double[] getImagEigenvalues() {
          return imagEigenvalues.clone();
      }
  
      /** {@inheritDoc} */
      public double getImagEigenvalue(final int i) {
          return imagEigenvalues[i];
      }
  
      /** {@inheritDoc} */
      public RealVector getEigenvector(final int i) {
          return eigenvectors[i].copy();
      }
  
      /**
       * Return the determinant of the matrix
       * @return determinant of the matrix
       */
      public double getDeterminant() {
          double determinant = 1;
          for (double lambda : realEigenvalues) {
              determinant *= lambda;
          }
          return determinant;
      }
  
      /** {@inheritDoc} */
      public DecompositionSolver getSolver() {
          return new Solver(realEigenvalues, imagEigenvalues, eigenvectors);
      }
  
      /** Specialized solver. */
      private static class Solver implements DecompositionSolver {
  
          /** Real part of the realEigenvalues. */
          private double[] realEigenvalues;
  
          /** Imaginary part of the realEigenvalues. */
          private double[] imagEigenvalues;
  
          /** Eigenvectors. */
          private final ArrayRealVector[] eigenvectors;
  
          /**
           * Build a solver from decomposed matrix.
           * @param realEigenvalues
           *            real parts of the eigenvalues
           * @param imagEigenvalues
           *            imaginary parts of the eigenvalues
           * @param eigenvectors
           *            eigenvectors
           */
          private Solver(final double[] realEigenvalues,
                  final double[] imagEigenvalues,
                  final ArrayRealVector[] eigenvectors) {
              this.realEigenvalues = realEigenvalues;
              this.imagEigenvalues = imagEigenvalues;
              this.eigenvectors = eigenvectors;
          }
  
          /**
           * Solve the linear equation A &times; X = B for symmetric matrices A.
           * <p>
           * This method only find exact linear solutions, i.e. solutions for
           * which ||A &times; X - B|| is exactly 0.
           * </p>
           * @param b Right-hand side of the equation A &times; X = B
           * @return a Vector X that minimizes the two norm of A &times; X - B
           * @throws DimensionMismatchException if the matrices dimensions do not match.
           * @throws SingularMatrixException if the decomposed matrix is singular.
           */
          public double[] solve(final double[] b) {
  
              if (!isNonSingular()) {
                  throw new SingularMatrixException();
              }
  
              final int m = realEigenvalues.length;
              if (b.length != m) {
                  throw new DimensionMismatchException(b.length, m);
              }
  
              final double[] bp = new double[m];
              for (int i = 0; i < m; ++i) {
                  final ArrayRealVector v = eigenvectors[i];
                  final double[] vData = v.getDataRef();
                  final double s = v.dotProduct(b) / realEigenvalues[i];
                  for (int j = 0; j < m; ++j) {
                      bp[j] += s * vData[j];
                  }
              }
  
              return bp;
  
          }
  
          /**
           * Solve the linear equation A &times; X = B for symmetric matrices A.
           * <p>
           * This method only find exact linear solutions, i.e. solutions for
           * which ||A &times; X - B|| is exactly 0.
           * </p>
           * @param b Right-hand side of the equation A &times; X = B
           * @return a Vector X that minimizes the two norm of A &times; X - B
           * @throws DimensionMismatchException if the matrices dimensions do not match.
           * @throws SingularMatrixException if the decomposed matrix is singular.
           */
          public RealVector solve(final RealVector b) {
              if (!isNonSingular()) {
                  throw new SingularMatrixException();
              }
  
              final int m = realEigenvalues.length;
              if (b.getDimension() != m) {
                  throw new DimensionMismatchException(b.getDimension(), m);
              }
  
              final double[] bp = new double[m];
  