diff --git a/.idea/misc.xml b/.idea/misc.xml
index a165cb3..cbb200f 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/project.iml b/.idea/project.iml
index 47baa8c..d34aa22 100644
--- a/.idea/project.iml
+++ b/.idea/project.iml
@@ -6,5 +6,14 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/in.txt b/in.txt
new file mode 100644
index 0000000..dc67031
--- /dev/null
+++ b/in.txt
@@ -0,0 +1,4 @@
+3 4
+1+2i -1.5-1.1i 2.12 91+5i
+-1+3i 1.2+3.5i -3.3 1+15i
+12.31 1.3-5i 12.3i -78.3i
\ No newline at end of file
diff --git a/out.txt b/out.txt
new file mode 100644
index 0000000..f6b6cdc
--- /dev/null
+++ b/out.txt
@@ -0,0 +1,3 @@
+6.7334-22.9975i
+-1.7976+2.084i
+15.6994+7.396i
\ No newline at end of file
diff --git a/src/solver/AugmentedMatrix.java b/src/solver/AugmentedMatrix.java
new file mode 100644
index 0000000..434d636
--- /dev/null
+++ b/src/solver/AugmentedMatrix.java
@@ -0,0 +1,151 @@
+package solver;
+
+import java.util.ArrayList;
+import java.util.InputMismatchException;
+import java.util.Scanner;
+
+
+public class AugmentedMatrix {
+ private Row[] matrix;
+ private String decimalPattern = "#.####";
+
+ // We don't always need swapHistory, so method which uses this field must check whether it is initialized or not.
+ private ArrayList swapHistory;
+
+
+ AugmentedMatrix(Complex[][] matrix) {
+ setMatrix(matrix);
+ }
+
+ AugmentedMatrix() {}
+
+ public void readMatrix(Scanner scanner) throws InputMismatchException {
+ int n = scanner.nextInt();
+ int m = scanner.nextInt();
+ matrix = new Row[n];
+ for (int i = 0; i < n; i++) {
+ matrix[i] = new Row(m);
+ for (int j = 0; j < m; j++) {
+ this.set(i, j, new Complex(scanner.next()));
+ }
+ }
+ }
+
+ public void set(int i, int j, Complex value) {
+ matrix[i].set(j, value);
+ }
+
+ public Complex get(int i, int j) {
+ return matrix[i].get(j);
+ }
+
+
+ public String fancyPrint(String decimalPattern) {
+ if(decimalPattern == null) {
+ decimalPattern = this.decimalPattern;
+ }
+ StringBuilder sb = new StringBuilder();
+ Complex[] row;
+ for (int i = 0; i < matrix.length; i++) {
+ row = matrix[i].getRow();
+ sb.append("[");
+ for(int j =0; j < row.length; j++) {
+ row[j].setDecimalPattern(decimalPattern);
+ sb.append(row[j].toString());
+ sb.append(", ");
+ }
+ sb.delete(sb.length()-2, sb.length());
+ sb.append("]");
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public String toString() {
+ return fancyPrint(null);
+ }
+
+ public void swapRows(int firstRowIndex, int secondRowIndex) {
+ Row temp = matrix[firstRowIndex];
+ matrix[firstRowIndex] = matrix[secondRowIndex];
+ matrix[secondRowIndex] = temp;
+ }
+
+ private void addSwapHistoryEntry(int prevIndex, int nextIndex) {
+ // Initialization check
+ if(swapHistory==null) {
+ swapHistory = new ArrayList<>();
+ }
+ swapHistory.add(new SwapInfo(prevIndex, nextIndex));
+ }
+
+ public void clearSwapHistory() {
+ swapHistory.clear();
+ }
+
+ public void swapColumns(int firstColumnIndex, int secondColumnIndex) {
+ swapColumns(firstColumnIndex, secondColumnIndex, true);
+ }
+
+ public void swapColumns(int firstColumnIndex, int secondColumnIndex, boolean writeLog) {
+ Complex coeff1, coeff2;
+ for(Row row : matrix) {
+ coeff1 = row.get(firstColumnIndex);
+ coeff2 = row.get(secondColumnIndex);
+ row.set(firstColumnIndex, coeff2);
+ row.set(secondColumnIndex, coeff1);
+ }
+ if(writeLog) {
+ addSwapHistoryEntry(firstColumnIndex, secondColumnIndex);
+ }
+ }
+
+ public ArrayList getSwapHistory() {
+ return swapHistory;
+ }
+
+ public Complex[][] getMatrixCopy() {
+ Complex[][] copy = new Complex[matrix.length][];
+ for(int i = 0; i < matrix.length; i++) {
+ copy[i] = matrix[i].getRow();
+ }
+ return copy;
+ }
+
+ public void setMatrix(Complex[][] matrix) {
+ this.matrix = new Row[matrix.length];
+ for(int i = 0; i < matrix.length; i++) {
+ this.matrix[i] = new Row(matrix[i]);
+ }
+ }
+
+ public Row getRow(int index) {
+ return this.matrix[index];
+ }
+
+ public Row getColumnCopy(int index) {
+ int rows = size()[0]; // Number of rows
+ Row col = new Row(rows);
+ for(int i = 0; i < rows; i++) {
+ col.set(i, matrix[i].get(index));
+ }
+ return col;
+ }
+
+
+
+ /**
+ * Get dimensions of Augmented matrix
+ * @return size()[0] - number of rows, size()[1] - number of columns
+ */
+ public int[] size() {
+ int[] size = new int[2];
+ size[0] = matrix.length;
+ // Consider that all rows have the same size, according to the class initialization
+ size[1] = matrix[0].size();
+ return size;
+ }
+
+
+}
diff --git a/src/solver/Complex.java b/src/solver/Complex.java
new file mode 100644
index 0000000..ec4fa58
--- /dev/null
+++ b/src/solver/Complex.java
@@ -0,0 +1,123 @@
+package solver;
+
+import java.text.DecimalFormat;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Complex {
+ private final double re;
+ private final double im;
+ private String decimalPattern = "#.####";
+
+ public static final Complex ZERO = new Complex(0, 0);
+
+ public Complex(double real, double imag) {
+ this.re = real;
+ this.im = imag;
+ }
+
+ public Complex(String str) {
+ Complex cmp = parseComplex(str);
+ this.re = cmp.re;
+ this.im = cmp.im;
+ }
+
+ public Complex(Complex b) {
+ this.re = b.re;
+ this.im = b.im;
+ }
+
+ @Override
+ public boolean equals(Object x) {
+ if (x == null) return false;
+ if (this.getClass() != x.getClass()) return false;
+ Complex that = (Complex) x;
+ return (this.re == that.re) && (this.im == that.im);
+ }
+
+
+
+ public Complex add(Complex b) {
+ Complex a = this;
+ double real = a.re + b.re;
+ double imag = a.im + b.im;
+ return new Complex(real, imag);
+ }
+
+ public Complex subtract(Complex b) {
+ Complex a = this;
+ double real = a.re - b.re;
+ double imag = a.im - b.im;
+ return new Complex(real, imag);
+ }
+
+ public Complex multiply(Complex b) {
+ Complex a = this;
+ double real = a.re * b.re - a.im * b.im;
+ double imag = a.im * b.re + a.re * b.im;
+ return new Complex(real, imag);
+ }
+
+ public Complex reciprocal() {
+ Complex a = this;
+ double denominator = a.re * a.re + a.im * a.im;
+ double real = a.re / denominator;
+ double imag = - a.im / denominator;
+ return new Complex(real, imag);
+ }
+
+ public Complex divide(Complex b) {
+ Complex a = this;
+ return a.multiply(b.reciprocal());
+ }
+
+ public static Complex parseComplex(String inp) {
+ Pattern imagPattern = Pattern.compile("([+-]?\\d+(\\.?\\d+)?([eE][+-]?\\d)?[i|I])|([+-]?[i|I](\\d+(\\.?\\d+)?)?([eE][+-]?\\d)?)");
+
+ // My numerous attempts, i leave it here)
+
+ // Pattern realPattern = Pattern.compile("([+-]?(?!i|I)?\\d++(\\.?\\d++)?([eE][+-]?\\d)?(?!i|I))");
+ // Pattern realPattern = Pattern.compile("(?!(([+-]?\\d+(\\.?\\d+)?([eE][+-]?\\d)?[i|I])))");
+ // Matcher re = realPattern.matcher(inp);
+ // re.find();
+ // System.out.printf("Re: " + re.group() + " ");
+
+
+ Matcher im = imagPattern.matcher(inp);
+ String impart, repart;
+ try {
+ im.find();
+ impart = im.group();
+ } catch (IllegalStateException e) {
+ impart = ""; // If a repart or impart is blank it will be zero
+ }
+ repart = inp.replace(impart, ""); // It is easier than finding/creating regexp pattern to find real part
+
+ if(impart.equals("+i") || impart.equals("+I") || impart.equals("i") || impart.equals("I")) {
+ impart = "1i";
+ } else if(impart.equals("-i") || impart.equals("-I")) {
+ impart = "-1i";
+ }
+
+ double rep = repart.isBlank() ? 0 : Double.parseDouble(repart);
+ double imp = impart.isBlank() ? 0 : Double.parseDouble(impart.replaceAll("i|I", ""));
+
+ return new Complex(rep, imp);
+ }
+
+ public void setDecimalPattern(String pattern) {
+ this.decimalPattern = pattern;
+ }
+
+ @Override
+ public String toString() {
+ String ans;
+ DecimalFormat f = new DecimalFormat(decimalPattern);
+ if (im == 0) return f.format(re) + "";
+ if (re == 0) return f.format(im) + "i";
+ if (im < 0) return f.format(re) + "-" + f.format(-im) + "i";
+ return f.format(re) + "+" + f.format(im) + "i";
+ }
+
+
+}
diff --git a/src/solver/LinearEquationSolver.java b/src/solver/LinearEquationSolver.java
new file mode 100644
index 0000000..2a82b70
--- /dev/null
+++ b/src/solver/LinearEquationSolver.java
@@ -0,0 +1,296 @@
+package solver;
+
+import java.util.ArrayList;
+
+
+enum SystemType {
+ NO_SOLUTIONS,
+ SINGLE_SOLUTION,
+ INFINITE_NUMBER_OF_SOLUTIONS,
+ UNKNOWN_ERROR
+}
+
+public class LinearEquationSolver {
+ private AugmentedMatrix matrix;
+ private StringBuilder logs;
+ private String result;
+ private SystemType resultType;
+ private String decimalPattern = "#.#####";
+
+ LinearEquationSolver(AugmentedMatrix matrix) {
+ this.matrix = new AugmentedMatrix(matrix.getMatrixCopy());
+ this.logs = new StringBuilder();
+ }
+
+ /**
+ * It is step 1 of solving System of Linear Equations: transforming matrix to upper triangular form
+ */
+ private void transformToUpperTriangularForm() {
+ Row currentRow; Complex currentCoefficient;
+ Row nextRow; Complex nextCoefficient;
+ Complex multiplicator;
+ int n = matrix.size()[0]; // number of rows
+ int m = matrix.size()[1]; // number of cols
+ int rowNum, colNum;
+ // If there are no special cases, then rowNum = colNum (transforming to diagonal form)
+ for(rowNum = 0, colNum = 0; rowNum < n && colNum < m-1; rowNum++, colNum++) {
+ currentRow = matrix.getRow(rowNum);
+ currentCoefficient = currentRow.get(colNum);
+
+
+ // Search for the row with non-zero coefficent
+ int columnOffset = 0; boolean foundInColumn = false;
+ Complex coeff; int innerColNum = colNum;
+ while(currentCoefficient.equals(Complex.ZERO) && innerColNum < m-1) {
+
+ // If a current coefficient is zero, then we should find row with non-zero coefficient below
+ if (currentCoefficient.equals(Complex.ZERO)) {
+ foundInColumn = false;
+ int nextRowNum;
+ for (nextRowNum = rowNum; nextRowNum < n; nextRowNum++) {
+ coeff = matrix.getRow(nextRowNum).get(innerColNum);
+ if (!coeff.equals(Complex.ZERO)) {
+ // Found row with non-zero i-th coefficient
+ foundInColumn = true;
+ break;
+ }
+ }
+
+ if(foundInColumn) {
+ // We should swap rows
+ // These variables can be equal if previous column was filled with zeros,
+ // but on this column this row have non-zero coefficient
+ if(rowNum != nextRowNum) {
+ this.matrix.swapRows(rowNum, nextRowNum);
+ logMessage(String.format("R%d <-> R%d", rowNum, nextRowNum));
+ }
+ // If innerColNum != colNum -> we found non-zero coefficient in other column, we should swap columns
+ if(innerColNum != colNum) {
+ matrix.swapColumns(colNum, innerColNum);
+ logMessage(String.format("C%d <-> C%d", colNum, innerColNum));
+ }
+ // Update currentRow and currentCoefficient variables after all swaps
+ currentRow = matrix.getRow(rowNum); // rowNum after swap references to nextRowNum
+ currentCoefficient = currentRow.get(colNum);
+ break;
+ } else {
+ innerColNum++;
+ }
+
+ }
+
+ }
+
+ // If after all (full search of non-zero coefficient in whole matrix) we have zero-coefficient
+ // We should end up with matrix processing - matrix already transformed
+ if(currentCoefficient.equals(Complex.ZERO)) {
+ return;
+ }
+
+ // Make coefficient equal to one by dividing entire row by this coefficient
+ if(!currentCoefficient.equals(new Complex(1, 0))) {
+ currentRow.divide(currentCoefficient);
+ logMessage(String.format("R%d / %s -> R%d", rowNum, currentCoefficient.toString(), rowNum));
+ }
+
+ // Perform actions to zero coefficients in other rows
+ for(int j = rowNum + 1; j < n; j++) {
+ nextRow = matrix.getRow(j);
+ nextCoefficient = nextRow.get(colNum);
+ currentCoefficient = currentRow.get(colNum); // it must always be equal to one
+ // nextCoefficient should be zero
+ if(!nextCoefficient.equals(Complex.ZERO)) {
+ multiplicator = nextCoefficient.divide(currentCoefficient).multiply(new Complex(-1, 0));
+ nextRow.add(currentRow.multiply(multiplicator, false));
+ logMessage(String.format("%s * R%d + R%d -> R%d", multiplicator.toString(), rowNum, j, j));
+ }
+ }
+ }
+ }
+
+ /**
+ * It is step 2 of solving System of Linear Equations: reduction of non-diagonal members of upper triangular form of matrix
+ */
+ private void reduceNonDiagonalCoefficients() {
+ // Start from the end
+ int rowNum, colNum, nextRowNum;
+ int n = matrix.size()[0];
+ int coefficientIndex = -1;
+ Complex currentCoefficient, nextCoefficient, multiplicator;
+ Row row; Row nextRow;
+ for(rowNum = n-1; rowNum >= 0; rowNum--) {
+
+ // Find first non-zero element
+ row = matrix.getRow(rowNum);
+ for(int i = 0; i < row.size()-1; i++) {
+ if(!row.get(i).equals(Complex.ZERO)) {
+ coefficientIndex = i;
+ break;
+ }
+ }
+
+
+ // If entire row filled with zeros - stop processing, go to the next iteration
+ if(coefficientIndex == -1) {
+ continue;
+ }
+
+ // Start subtracting this row from rows above
+ for(nextRowNum = rowNum - 1; nextRowNum >= 0; nextRowNum--) {
+ currentCoefficient = row.get(coefficientIndex);
+ nextRow = matrix.getRow(nextRowNum);
+ nextCoefficient = nextRow.get(coefficientIndex);
+ if (!nextCoefficient.equals(Complex.ZERO)) {
+ multiplicator = nextCoefficient.divide(currentCoefficient).multiply(new Complex(-1, 0));
+ nextRow.add(row.multiply(multiplicator, false));
+ logMessage(String.format("%s * R%d + R%d -> R%d", multiplicator.toString(), rowNum, nextRowNum, nextRowNum));
+ }
+ }
+
+ }
+ }
+
+
+ /**
+ * It is step 3 of solving System of Linear Equations: checking for number of solutions
+ *
+ * In this method it is essential that matrix has a pseudo-diagonal form (after 1st and 2nd steps were completed)
+ *
+ * @return SystemType enum
+ */
+ private SystemType checkResult() {
+ // Checking for no solution
+ int rowNum, index;
+ int n = matrix.size()[0]; // number of rows
+ int m = matrix.size()[1]; // number of columns
+ Row currentRow;
+ for(rowNum = n-1; rowNum >=0; rowNum--) {
+ currentRow = matrix.getRow(rowNum);
+ if(currentRow.isZeroFilled()) {
+ continue; // Zero rows are insignificant for us
+ }
+
+ // Getting first non-zero element
+ index = currentRow.getIndexOfFirstNonZeroElement();
+
+ // If first non-zero element located in a last column - the system is inconsistent
+ if(index == m-1) {
+ return SystemType.NO_SOLUTIONS;
+ }
+
+ // Check for infinite number of solutions
+
+ // We look at last non-trivial row and get the matrix[i][j] first non-zero element, if j - is last column of
+ // non-augmented matrix - then we have single solution, if j - is not the last column of the non-augmented
+ // matrix - there is infinite number of solutions
+ // Example:
+ // 1 0 0 | 4 1 0 0 | 4
+ // 0 1 0 | 5 0 1 0 | 5
+ // 0 0 0 | 0 0 0 1 | 0
+ // 0 0 0 | 0 0 0 0 | 0
+ // INFINITE SOLUTIONS SINGLE SOLUTION
+ int cols = m -1; // number of columns of non-augmented matrix
+ if(index+1 != cols) {
+ return SystemType.INFINITE_NUMBER_OF_SOLUTIONS;
+ }
+
+ // All other ways were considered -> only one variant
+ // We have single solution
+ return SystemType.SINGLE_SOLUTION;
+ }
+
+ return SystemType.UNKNOWN_ERROR;
+ }
+
+ /**
+ * It is step 4 of solving System of Linear Equations: get original columns' order in matrix by looking at swap history
+ *
+ * Look at swap history and do reverse actions in desc order to get original column positions.
+ */
+ public void revokeColumnsSwap() {
+ int[] reversedSwapIndexes;
+ ArrayList swapHistory = matrix.getSwapHistory();
+ try {
+ for (int i = swapHistory.size() - 1; i >= 0; i--) {
+ reversedSwapIndexes = swapHistory.get(i).getReversedSwapInfo();
+ matrix.swapColumns(reversedSwapIndexes[0], reversedSwapIndexes[1], false);
+ logMessage(String.format("Reverse: C%d <-> C%d", reversedSwapIndexes[0], reversedSwapIndexes[1]));
+ }
+ matrix.clearSwapHistory();
+ } catch(NullPointerException e) {
+ // Ignore:
+ // It means that we haven't swapped any columns and swapHistory is not initialized yet
+ // (we do not initialize swapHistory to preserve memory, i know that in general this is possibly stupid =) )
+ return;
+ }
+ }
+
+ private void transformToDiagonalForm() {
+ transformToUpperTriangularForm();
+ reduceNonDiagonalCoefficients();
+ resultType = checkResult();
+ revokeColumnsSwap();
+ }
+
+ private void logMessage(String msg) {
+ // System.out.println(msg);
+ logs.append(msg);
+ logs.append("\n");
+ }
+
+ /**
+ * Get coefficients of single solution
+ *
+ * @return solution - array of coefficients
+ */
+ private Complex[] getSingleSolution() {
+ int n = matrix.size()[0]; // Number of rows
+ int m = matrix.size()[1]; // Number of columns of augmented matrix
+ Complex[] solution = new Complex[m-1];
+ int solutionIndex;
+ for(int rowNum = 0; rowNum < n; rowNum++) {
+ if(matrix.getRow(rowNum).isZeroFilled()) {
+ continue;
+ }
+
+ solutionIndex = matrix.getRow(rowNum).getIndexOfFirstNonZeroElement();
+ solution[solutionIndex] = matrix.getRow(rowNum).get(m-1);
+ }
+ return solution;
+ }
+
+ public String getLogs() {
+ return this.logs.toString();
+ }
+
+ public String getResult() {
+ return result;
+ }
+
+
+ public LinearEquationSolver solve() {
+ transformToDiagonalForm();
+ switch(resultType) {
+ case NO_SOLUTIONS:
+ result = "No solutions";
+ return this;
+ case INFINITE_NUMBER_OF_SOLUTIONS:
+ result = "Infinite solutions";
+ return this;
+ case SINGLE_SOLUTION:
+ Complex[] res = getSingleSolution();
+ StringBuilder sb = new StringBuilder();
+ for(Complex coefficient: res) {
+ sb.append(coefficient.toString());
+ sb.append("\n");
+ }
+ sb.deleteCharAt(sb.length()-1);
+ result = sb.toString();
+ }
+ return this;
+ }
+
+ public AugmentedMatrix getMatrix() {
+ return matrix;
+ }
+}
diff --git a/src/solver/Main.java b/src/solver/Main.java
index 4404714..74b9ca1 100644
--- a/src/solver/Main.java
+++ b/src/solver/Main.java
@@ -1,7 +1,106 @@
package solver;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.InputMismatchException;
+import java.util.Scanner;
+
public class Main {
+
+ static String getHelp() {
+ String helpMsg = "This program is intended to solve Linear Equations with any amount of variables using Gauss-Jordan Elimination. \n\n" +
+ "Options: " +
+ "\n\t * -in [pathToFile] reads file with the first number - number of equations and variables, and augmented matrix of linear equation" +
+ "\n\t * -out [pathToFile] writes results to the output file " +
+ "\n\t * -h shows help information " +
+ "\n\nExample: \njava Solver -in in.txt -out out.txt" +
+ "\n\nExample of in.txt:\n" +
+ "3\n" +
+ "1 1 2 9\n" +
+ "2 4 -3 1\n" +
+ "3 6 -5 0";
+ return helpMsg;
+ }
+
+ /**
+ * Program should start with necessary options -in [pathToFileWithMatrix] and -out [pathToOutputFile]
+ * Example: > java Solver -in in.txt -out out.txt
+ * @param args
+ */
public static void main(String[] args) {
- System.out.print("Hello world!");
+ // Getting and handling console parameters
+ String inputFile="";
+ String outputFile="";
+ for(int i = 0; i < args.length; i++) {
+ try {
+ switch (args[i]) {
+ case "-in":
+ inputFile = args[i + 1];
+ break;
+ case "-out":
+ outputFile = args[i + 1];
+ break;
+ case "-h" :
+ System.out.println(getHelp());
+ return;
+
+ }
+ } catch (ArrayIndexOutOfBoundsException e) {
+ System.err.println("Invalid command line options, use '-h' option to see help");
+ return;
+ }
+ }
+
+ if(inputFile.isEmpty() || outputFile.isEmpty()) {
+ System.err.println("Invalid command line options, use '-h' option to see help");
+ return;
+ }
+
+ System.out.println("Input File: " + inputFile + "\nOutput File: " + outputFile);
+
+ // Working with input file
+ File file = new File(inputFile);
+ AugmentedMatrix matrix = new AugmentedMatrix();
+ try(Scanner fileScanner = new Scanner(file);) {
+ matrix.readMatrix(fileScanner);
+ } catch(FileNotFoundException e) {
+ System.out.println("File: " + file.getAbsolutePath() + " doesn't exist");
+ return;
+ } catch (InputMismatchException e) {
+ System.err.println("Invalid structure of input file: " + file.getAbsolutePath());
+ return;
+ }
+
+ if(matrix.size()[0] == 0 || matrix.size()[1] == 0) {
+ System.err.println("Invalid structure of input file: " + file.getAbsolutePath());
+ return;
+ }
+
+ // Input matrix output
+ System.out.println("Input matrix:");
+ System.out.println(matrix);
+
+
+ // Solving equation
+ System.out.println("Start solving linear equation.");
+ LinearEquationSolver solver = new LinearEquationSolver(matrix);
+ String res = solver.solve().getResult();
+ System.out.println("Rows manipulation:");
+ System.out.println(solver.getLogs());
+
+ System.out.println("Resulting matrix:");
+ System.out.println(solver.getMatrix());
+
+ System.out.println("The solution is: (" + res.replaceAll("\n", ", ") + ")");
+
+ // Output writing
+ try(FileWriter fileWriter = new FileWriter(outputFile)) {
+ fileWriter.write(res);
+ System.out.println("Saved to " + outputFile);
+ } catch(IOException e) {
+ System.err.println("Result cannot be written to the output file, please try other output file");
+ }
}
}
\ No newline at end of file
diff --git a/src/solver/Row.java b/src/solver/Row.java
new file mode 100644
index 0000000..dfca440
--- /dev/null
+++ b/src/solver/Row.java
@@ -0,0 +1,106 @@
+package solver;
+
+import java.util.Arrays;
+
+public class Row {
+ private Complex[] row;
+
+ Row(Complex[] row) {
+ setRow(row);
+ }
+
+ Row(int m) {
+ row = new Complex[m];
+ }
+
+
+ Row divide(Complex v) {
+ if(v.equals(Complex.ZERO)){
+ throw new java.lang.ArithmeticException("Division by zero");
+ }
+ for(int i = 0; i < row.length; i++) {
+ row[i] = row[i].divide(v);
+ }
+ return this;
+ }
+
+ Row multiply(Complex v, boolean inplace) {
+ Row curRow;
+ if(inplace) {
+ curRow = this;
+ } else {
+ curRow = new Row(row.length);
+ }
+ for(int i = 0; i < row.length; i++) {
+ curRow.set(i, row[i].multiply(v));
+ }
+ return curRow;
+ }
+
+ Row multiply(Complex v) {
+ return multiply(v, true);
+ }
+
+ Row subtract(Row row) {
+ for(int i = 0; i < this.row.length; i++) {
+ this.row[i] = this.row[i].subtract(row.get(i));
+ }
+ return this;
+ }
+
+ Row add(Row row) {
+ return add(row, true);
+ }
+
+ Row add(Row nextRow, boolean inplace) {
+ Row curRow;
+ if(inplace) {
+ curRow = this;
+ } else {
+ curRow = new Row(row.length);
+ }
+ for(int i = 0; i < row.length; i++) {
+ curRow.set(i, curRow.get(i).add(nextRow.get(i)));
+ }
+ return curRow;
+ }
+
+ public Complex[] getRow() {
+ return Arrays.copyOf(row, row.length);
+ }
+
+ public void setRow(Complex[] row) {
+ this.row = Arrays.copyOf(row, row.length);
+ }
+
+ public void set(int j, Complex value) {
+ this.row[j] = new Complex(value);
+ }
+
+ public Complex get(int j) {
+ return this.row[j];
+ }
+
+ public boolean isZeroFilled() {
+ for(int i = 0; i < row.length; i++) {
+ if( !row[i].equals(Complex.ZERO)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public int getIndexOfFirstNonZeroElement() {
+ for(int i = 0; i < row.length; i++) {
+ if(!row[i].equals(Complex.ZERO) ) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public int size() {
+ return this.row.length;
+ }
+}
diff --git a/src/solver/SwapInfo.java b/src/solver/SwapInfo.java
new file mode 100644
index 0000000..7c65dc2
--- /dev/null
+++ b/src/solver/SwapInfo.java
@@ -0,0 +1,19 @@
+package solver;
+
+public class SwapInfo {
+ private int prevIndex;
+ private int nextIndex;
+
+ SwapInfo(int prevIndex, int nextIndex) {
+ this.prevIndex = prevIndex;
+ this.nextIndex = nextIndex;
+ }
+
+ public int[] getSwapInfo() {
+ return new int[]{prevIndex, nextIndex};
+ }
+
+ public int[] getReversedSwapInfo() {
+ return new int[]{nextIndex, prevIndex};
+ }
+}