JacobiSolver.java :  » Algebra » la4j » la4j » linear » Java Open Source

Java Open Source » Algebra » la4j 
la4j » la4j » linear » JacobiSolver.java
/*
 * Copyright 2011, Vladimir Kostyukov
 * 
 * This file is part of la4j project (http://la4j.googlecode.com)
 * 
 * Licensed 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 la4j.linear;

import la4j.err.LinearSystemException;
import la4j.matrix.Matrix;
import la4j.vector.Vector;

public class JacobiSolver implements LinearSystemSolver {
  
  private final static int MAX_ITERATIONS = 100000;

  @Override
  public Vector solve(LinearSystem linearSystem) throws LinearSystemException {
    
    Matrix a = linearSystem.coefficientsMatrix();
    Vector b = linearSystem.rightHandVector();
    
    if (!isMethodCanBeUsed(a)) {
      throw new LinearSystemException("method Jacobi can not be used");
    } else {

      Vector current = new Vector(linearSystem.variables());

      final int rows = a.rows();
      final int columns = a.columns();
      
      double aa[][] = a.toArrayCopy(); // get coefficients
      int iteration = 0;

      for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
          if (i != j) {
            aa[i][j] /= aa[i][i];
          }
        }
      }

      while (iteration < MAX_ITERATIONS && !linearSystem.isSolution(current)) {

        Vector next = new Vector(current.length());

        for (int i = 0; i < rows; i++) {
          double sum = b.get(i) / aa[i][i];
          for (int j = 0; j < columns; j++) {
            if (i != j) {
              sum -= aa[i][j] * current.get(j);
            }
          }

          next.set(i, sum);
        }

        current = next;

        iteration++;

      }

      if (iteration == MAX_ITERATIONS) {
        throw new LinearSystemException(
            "method Jacobi can not be used");
      }

      return current;
    }
  }

  private boolean isMethodCanBeUsed(Matrix a) {
    
    final int rows = a.rows();
    final int columns = a.columns();
    
    for (int i = 0; i < rows; i++) {
      double sum = 0;

      for (int j = 0; j < columns; j++) {
        if (i != j) {
          sum += Math.abs(a.get(i, j));
        }
      }

      if (sum > Math.abs(a.get(i, i)) - EPS) {
        return false;
      }
    }

    return true;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.