/*
 * Created on 08.04.2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author GerberDom
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */

/**
 * @author Dominik Wenger
 *
 * LU-Zerlegung eines Linearsystems
 * 
 */

import javax.swing.*;


public class LU_Zerlegung {

	public static void main(String[] args) {
		
		/**
		 * Einlesen der Anzahl Nachkommastellen
		 */
		String genauigkeit = JOptionPane.showInputDialog("Anzahl Nachkommastellen eingeben");
		
		int digits = Integer.parseInt(genauigkeit);
		
		/**
		 * Einlesen der Matrix-Grösse
		 */
		String size = JOptionPane.showInputDialog("Matrix-Grösse eingeben");
		
		int n = Integer.parseInt(size);
		
		double [][] A = new double[n][n];
		double [][] L = new double[n][n];
		double [][] U = new double[n][n];
		
		for(int i=0;i<A.length;i++){
			for(int j=0;j<A[i].length;j++){
				String fieldValue = JOptionPane.showInputDialog("Wert für Matrix A ["+(i+1)+","+(j+1)+"] eingeben");
				double value = Double.parseDouble(fieldValue);
				A[i][j] = value;
			}
		}
		
		/**
		 * Berechnung der Matrizen L und U
		 */
		U[0][0] = A[0][0];
		L[0][0] = 1.0;
		
		for(int j=2;j<=n;j++){
			U[0][j-1] = A[0][j-1];
			L[j-1][0] = A[j-1][0]/U[0][0];
			L[j-1][j-1] = 1.0;
		}
		
		for(int i=2;i<=n-1;i++){
			U[i-1][i-1] = A[i-1][i-1] - sum(L,U,i);
			for(int j=i+1;j<=n;j++){
				U[i-1][j-1] = A[i-1][j-1] - sum1(L,U,i,j);
				L[j-1][i-1] = 1.0/U[i-1][i-1] * (A[j-1][i-1] - sum2(L,U,i,j));
			}
		}
		
		U[n-1][n-1] = A[n-1][n-1] - sum(L,U,n);
		
		/**
		 * Ausgabe der Lösungsmatrizen auf die Konsole:
		 */
		
		System.out.println("");
		System.out.println(n+"x"+n+" Matrix");
		System.out.println("");
		
		for(int i=0;i<A.length;i++){
			for(int j=0;j<A[i].length;j++){
				InOut.print(A[i][j],5,digits);
				System.out.print(" ");
			}
			System.out.println("");
		}
		
		System.out.println("");
		System.out.println("L Matrix");
		System.out.println("");
		
		for(int i=0;i<L.length;i++){
			for(int j=0;j<L[i].length;j++){
				InOut.print(L[i][j],5,digits);
				System.out.print(" ");
			}
			System.out.println("");
		}
		
		System.out.println("");
		System.out.println("U Matrix");
		System.out.println("");
		
		for(int i=0;i<U.length;i++){
			for(int j=0;j<U[i].length;j++){
				InOut.print(U[i][j],5,digits);
				System.out.print(" ");
			}
			System.out.println("");
		}
		System.exit(0);
	}
	
	/**
	 * Method sum.
	 * @param L
	 * @param U
	 * @param n
	 * @return double
	 */
	private static double sum(double[][] L, double[][] U, int n) {
		double sum = 0;		
		for(int k=1;k<=n-1;k++){
			sum += L[n-1][k-1]*U[k-1][n-1];			
		}
		return sum;
	}

	/**
	 * Method sum1.
	 * @param L
	 * @param U
	 * @param i
	 * @param j
	 * @return double
	 */
	private static double sum1(double[][] L, double[][] U, int i, int j) {
		double sum = 0;
		for(int k=1;k<=(i-1);k++){
			sum += L[i-1][k-1]*U[k-1][j-1];			
		}
		return sum;
	}
	
	/**
	 * Method sum2.
	 * @param L
	 * @param U
	 * @param i
	 * @param j
	 * @return double
	 */
	private static double sum2(double[][] L, double[][] U, int i, int j) {
		double sum = 0;	
		for(int k=1;k<=(i-1);k++){
			sum += L[j-1][k-1]*U[k-1][i-1];			
		}
		return sum;
	}
}
