package funcparams;

import java.io.*;
import java.util.*;

 interface Functions {

  double calculate(double x, double y, double z);
}

class functionf implements Functions {

  public double calculate(double x, double y, double z){

    return ( (7 - 2 * y * y) / 5 + x) / 2;
  }
}

class functiong implements Functions {

  public double calculate(double x, double y, double z){

    return ( ( (10 - (2 * x + 3) * x * x) / 3) + 2 * z - x) / 3;
  }
}

class functionh implements Functions {

  public double calculate(double x, double y, double z){

    return (x + y) / 2;
  }
}

class functionx implements Functions {

  double tempMatrix[][];
  double tempVector[];

  public functionx(double matrix[][], double vector[]) {

    tempMatrix = matrix;
    tempVector = vector;
  }

  public double calculate(double x, double y, double z) {

    return (tempVector[0] - tempMatrix[0][1] * y - tempMatrix[0][2] * z) /
        tempMatrix[0][0];
  }
}

class functiony implements Functions {

  double tempMatrix[][];
  double tempVector[];

  public functiony(double matrix[][], double vector[]) {

    tempMatrix = matrix;
    tempVector = vector;
  }

  public double calculate(double x, double y, double z) {

    return (tempVector[1] - tempMatrix[1][0] * x - tempMatrix[1][2] * z) /
        tempMatrix[1][1];
  }
}

class functionz implements Functions {

  double tempMatrix[][];
  double tempVector[];

  public functionz(double matrix[][], double vector[]) {

    tempMatrix = matrix;
    tempVector = vector;
  }

  public double calculate(double x, double y, double z) {

    return (tempVector[2] - tempMatrix[2][0] * x - tempMatrix[2][1] * y) /
        tempMatrix[2][2];
  }
}

public class funcparams {

  static double matrix[][];
  static double vector[];

  public static void main(String[] args) {

    try {readInMatrixAndVector();}
    catch (Exception e) {e.printStackTrace();}

    functionf f = new functionf();
    functiong g = new functiong();
    functionh h = new functionh();

    functionx x = new functionx(matrix, vector);
    functiony y = new functiony(matrix, vector);
    functionz z = new functionz(matrix, vector);

    fixer(f,g,h,0,1,2);
    printMatrix();
    fixer(x,y,z,1,2,3);
  }

  public static void fixer(Functions a, Functions b, Functions c,
                           double i, double j, double k) {

    System.out.println("Starting fixpoint iteration");

    for(int m = 1; m <= 200; m++) {

      System.out.println("(n=" + m + ") --> i = " + i + " j = " + j +
                         " k = " + k);

      i = a.calculate(i,j,k);
      j = b.calculate(i,j,k);
      k = c.calculate(i,j,k);
    }

    System.out.println("Iteration finished");
  }

  public static void readInMatrixAndVector() throws Exception {

    String currentLine;
    StringTokenizer tokenizer;

    matrix = new double[3][3];
    vector = new double[3];

    int y = 0;

    Double vectorStringToDouble;

    try {

      FileReader fileReader = new FileReader("input.txt");
      BufferedReader bufferedReader = new BufferedReader(fileReader);

      while ((currentLine = bufferedReader.readLine()) != null) {

        tokenizer = new StringTokenizer(currentLine);

        for (int x = 0; x < 3; x++) {

          matrix[y][x] = Double.parseDouble(tokenizer.nextToken());
        }

        vector[y] = Double.parseDouble(tokenizer.nextToken());

        y++;
      }
    }

    catch(Exception e) {

      e.printStackTrace();
    }
  }

  public static void printMatrix() {

    for(int x = 0; x < 3; x++) {
      for(int y = 0; y < 3; y++)
        System.out.println("A[" + x + "][" + y + "] = " + matrix[x][y]);
    }

    for(int x = 0; x < 3; x++)
      System.out.println("B[" + x + "] = " + vector[x]);
  }
}
