diff --git a/.idea/misc.xml b/.idea/misc.xml
index a165cb3..df60b67 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/src/inr.txt b/src/inr.txt
new file mode 100644
index 0000000..16176d8
--- /dev/null
+++ b/src/inr.txt
@@ -0,0 +1,4 @@
+3 3
+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/src/plan.txt b/src/plan.txt
new file mode 100644
index 0000000..1a17dd1
--- /dev/null
+++ b/src/plan.txt
@@ -0,0 +1,60 @@
+На этой стадии нужно написать программу, которая
+1.считывает коэффициенты системы линейных уравнений из файла.
+1.1 Первая строка содержит N - число переменных и уравнений.
+1.2 Каждая последующая строка - N+1 чисел - N коэффициентов уравнения,
+ и последнее число - правая часть уравнения - константа.
+2.решает систему линейных уравнений
+3.записывает ответ в другой файл.
+3.1 В файл должны быть записаны только ответы, разделенные "\n".
+4.пути к файлам следует передавать как аргументы командной строки.
+5.Весь процесс решения/преобразований со строками должен быть выведен на консоль.
+6.Постарайтесь создать различные классы такие как: Matrix, Row, LinearEquation.
+Пример вывода: The lines which start with > represent the user input.
+
+> java Solver -in in.txt -out out.txt
+Start solving the equation.
+Rows manipulation:
+-2 * R1 + R2 -> R2
+-3 * R1 + R3 -> R3
+0.5 * R2 -> R2
+-3 * R2 + R3 -> R3
+-2 * R3 -> R3
+3.5 * R3 + R2 -> R2
+-2 * R3 + R1 -> R1
+-1 * R2 + R1 -> R1
+The solution is: (1.0, 2.0, 3.0)
+Saved to file out.txt
+
+Алгоритм преобразований.
+1.Обнулить все коэффициенты первого столбца кроме первого, он должен стать = 1.
+2.Последовательно обнулить все коэффициенты второго и последующего столбцов
+пока в последней строке все коэффициенты не обнулятся кроме последнего столбца.
+3.Вторая часть алгоритма - обнулять коэффициенты выше диагонали,
+начиная с последней строки до первой.
+4.После этих преобразований решением уравнений будет правая часть матрицы.
+Стадия 4.
+Может быть случай, когда коэффициент, на который мы будем умножать будет равен 0.
+Поэтому перед операцией умножения нужно проверить, коэффициент на равенство 0.
+Если нужно искать ненулевой элемент ниже и правее.
+1. Если ненулевой элемент ниже, то нужно переставить строки местами
+2. Если ниже все элементы нулевые, то продолжаем искать правее
+от элемента. Если находим, переставляем столбцы,строки.
+Состояние столбцов/строк до перестановки необходимо запомнить,
+чтобы после реализации вернуть все на место в исходном порядке и
+вывести решение в нужном порядке. В общей сложности может быть
+много перестановок.
+Если ненулевой элмент не находится ниже и правее, то ищется
+ненулевой элемент по всей левой части матрицы и при нахождении
+переставляем соответствущие строки и столбцы.
+Если ненулевой элемент не найден, первая часть алгоритма завершается.
+
+После этого проверяем на количество решений.
+1. все коэффициенты левой части нулевые, п.ч. ненулевая - нет решений.
+2. если количество ненулевых элементов на главной диагонали
+совпадает с количеством уравнений (в п.ч. не нули) - одно решение
+3. если на главной дигонали есть нулевые элементы + в п.ч.нули
+-> бесконечно много решений.
+C1,C2,C3(1<->2)C2,C1,C3(1<->3)C3,C1,C2
+colMove[1]=3
+colMove[2]=1
+colMove[3]=2
diff --git a/src/solver/ComplexNumber.java b/src/solver/ComplexNumber.java
new file mode 100644
index 0000000..f740c8e
--- /dev/null
+++ b/src/solver/ComplexNumber.java
@@ -0,0 +1,135 @@
+package solver;
+
+public class ComplexNumber {
+
+ public void set(double re, double im) {
+ this.re = re;
+ this.im = im;
+ }
+
+ private double re;//действительная часть
+ private double im;//мнимая часть
+
+ public double getRe() {
+ return re;
+ }
+
+ public double getIm() {
+ return im;
+ }
+
+ public ComplexNumber(double re, double im) {
+ this.re = re;
+ this.im = im;
+ }
+
+ public ComplexNumber(ComplexNumber n){
+ this.re = n.re;
+ this.im = n.im;
+ }
+
+ public ComplexNumber(String number) throws ParsingArrayException {
+ try {
+ if (number==null) {
+ this.re = 0;
+ this.im = 0;
+ } else if (!number.contains("i")) {
+ this.re = Double.parseDouble(number);
+ this.im = 0;
+ } else {
+ boolean firstPositive = true;
+ boolean secondPositive = true;
+ if (number.charAt(0) == '-') // See if first expr is negative
+ firstPositive = false;
+ if (number.substring(1).contains("-"))
+ secondPositive = false;
+ String[] split = number.split("[+-]");
+ if (split[0].equals("")) { // Handle expr beginning with `-`
+ split[0] = split[1];
+ if (split[0].contains("i")) {
+ split[0] = "0";
+ secondPositive = firstPositive;
+ }
+ if (split.length>2) split[1] = split[2];
+ }
+ double realPart = 0;
+ double imgPart = 0;
+ if (split[0].contains("i")) // Assumes input is not empty
+ imgPart = Double.parseDouble((firstPositive ? "+" : "-") +
+ split[0].substring(0,split[0].length() - 1));
+ else
+ realPart = Double.parseDouble((firstPositive ? "+" : "-") + split[0]);
+ if (split.length > 1) { // Parse second part of expr if it exists
+ if (split[1].contains("i"))
+ imgPart = Double.parseDouble((secondPositive ? "+" : "-") +
+ split[1].substring(0,split[1].length() - 1));
+ else
+ realPart = Double.parseDouble((secondPositive ? "+" : "-") + split[1]);
+ }
+ this.re = realPart;
+ this.im = imgPart;
+ }
+ } catch (NumberFormatException e) {
+ throw new ParsingArrayException(String.format("The string '%s' cannot be parsed as complex number", number),
+ e);
+ }
+ }
+
+ public static ComplexNumber sAdd(ComplexNumber n1, ComplexNumber n2){
+ return new ComplexNumber(n2.re+n1.re, n1.im+n2.im);
+ }
+
+ public void add(ComplexNumber n){
+ this.re+=n.re;
+ this.im+=n.im;
+ }
+
+ public void mult(ComplexNumber n){
+ //(a+bi)(c+di) = (ac−bd) + (ad+bc)i;
+ this.re=this.re*n.re-this.im*n.im;
+ this.im=this.re*n.im+this.im*n.re;
+ }
+
+ public static ComplexNumber mult(ComplexNumber n1, ComplexNumber n2){
+ //(a+bi)(c+di) = (ac−bd) + (ad+bc)i;
+ double re;
+ double im;
+ re=n1.re*n2.re-n1.im*n2.im;
+ im=n1.re*n2.im+n1.im*n2.re;
+ return new ComplexNumber(re,im);
+ }
+
+ public void div(ComplexNumber n){
+ //a+bi/c+di = (ac+bd)/(c^2+d^2)+(bc-ad)/((c^2+d^2))i
+ double a= this.re;
+ double b =this.im;
+ double c= n.re;
+ double d= n.im;
+ this.re = (a*c+b*d)/(c*c+d*d);
+ this.im = (b*c-a*d)/(c*c+d*d);
+ }
+
+ public static ComplexNumber div(ComplexNumber n1,ComplexNumber n2){
+ //a+bi/c+di = (ac+bd)/(c^2+d^2)+(bc-ad)/((c^2+d^2))i
+ double a= n1.re;
+ double b =n1.im;
+ double c= n2.re;
+ double d= n2.im;
+ double re = (a*c+b*d)/(c*c+d*d);
+ double im = (b*c-a*d)/((c*c+d*d));
+ return new ComplexNumber(re, im);
+ }
+
+ @Override
+ public String toString() {
+ return (re==0&&im==0)?"0":(re==0?"":String.format("%-5.3f",re))+((im>0&&re!=0)?"+":"")+(im==0?"":String.format("%-5.3fi ",im));
+ }
+
+ public static boolean compareComplex(ComplexNumber n1, ComplexNumber n2){
+ return Matrix.compareDouble(n1.getRe(),n2.getRe()) && Matrix.compareDouble(n1.getIm(),n2.getIm());
+ }
+
+ public static boolean compareComplexToDouble(ComplexNumber n1, double n2){
+ return Matrix.compareDouble(n1.getRe(),n2) && Matrix.compareDouble(n1.getIm(),0);
+ }
+}
diff --git a/src/solver/InvalidDataFileFormat.java b/src/solver/InvalidDataFileFormat.java
new file mode 100644
index 0000000..589a023
--- /dev/null
+++ b/src/solver/InvalidDataFileFormat.java
@@ -0,0 +1,7 @@
+package solver;
+
+public class InvalidDataFileFormat extends Exception{
+ public InvalidDataFileFormat(String msg, Exception cause) {
+ super(msg, cause);
+ }
+}
diff --git a/src/solver/Main.java b/src/solver/Main.java
index 4404714..53d26cb 100644
--- a/src/solver/Main.java
+++ b/src/solver/Main.java
@@ -1,7 +1,142 @@
package solver;
+import java.io.File;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
public class Main {
- public static void main(String[] args) {
- System.out.print("Hello world!");
+ static String inFile;
+ static String outFile;
+ public static void main(String[] args) throws InvalidDataFileFormat {
+ //get_in_file
+ if (args.length!=4) {
+ System.out.println("Invalid comand-line arguments");
+ return;
+ }
+
+ for (int i = 0; i < args.length; i+=2) {
+ if (args[i].equalsIgnoreCase("-in"))
+ inFile = args[i+1];
+ else if (args[i].equalsIgnoreCase("-out"))
+ outFile = args[i+1];
+ }
+ try {
+ List lines = Files.readAllLines( Paths.get(inFile));
+ int n=0,v=0;
+ int k=0;
+ try {
+ for (String s:lines.get(0).split("\\s")) {
+ if (k==0)
+ n = Integer.parseInt(s);//количество строк - уравнений
+ else
+ v = Integer.parseInt(s);//количество столбцов - переменных
+ k++;
+ }
+ if (v==0) v=n;
+ }
+ catch (NumberFormatException e){
+ throw new InvalidDataFileFormat(
+ //String.format("The string '%s' cannot be parsed as an array of numbers", s),
+ String.format("Incorrect data file format, '%s' cannot be parsed as two numbers", lines.get(0)),
+ e);
+ }
+ lines.remove(0);
+ if (lines.size() != n) {
+ throw new InvalidDataFileFormat("Incorrect data file format, count of data rows isn't equal n", null);
+ }
+ System.out.println("Start solving the equation.\n" +
+ "Rows manipulation:");
+ Matrix m;
+ boolean isComplex = false;
+ for (String s : lines) {
+ if (s.contains("i")){
+ isComplex = true;
+ break;
+ }
+ }
+ if (isComplex) {
+ Matrix.isComplx = true;
+ m = new iMatrix(n, v);
+ }
+ else
+ m = new Matrix(n,v);
+
+ for (String line : lines) {
+ m.addRow(lines.indexOf(line), line);
+ }
+ String manipulation;
+// m.otladka = true;
+ m.print();
+ for (int i = 0; i < m.M; i++) {
+ while (true)
+ {
+ //manipulation = m.rows[i].transform1(i);
+ manipulation = m.getRows(i).transform1(i);
+ if (!manipulation.equals("")) {
+ System.out.println(manipulation);
+ m.print();
+ if (!manipulation.contains("<->")) break;
+ } else break;
+ };
+
+ for (int j = i+1; j < m.N; j++) {
+// manipulation = m.rows[j].transform0(i, m.rows[i]);
+ manipulation = m.getRows(j). transform0(i, m.getRows(i));
+ if (!manipulation.equals("")) {
+ System.out.println(manipulation);
+ m.print();
+ }
+ }
+ }
+ int check = m.checkSolution();
+
+ String result="";
+ switch (check) {
+ case 0: {
+ result = "Infinite solutions";
+ System.out.println(result);
+ break;
+ }
+ case -1: {
+ result = "No solutions";
+ System.out.println(result);
+ break;
+ }
+ case 1: {
+ System.out.println("-------");
+ for (int i = m.N - 1; i >= 0; i--) {
+ for (int j = i - 1; j >= 0; j--) {
+// manipulation = m.rows[j].transform0(i, m.rows[i]);
+ manipulation = m.getRows(j).transform0(i, m.getRows(i));
+ if (!manipulation.equals("")) {
+ System.out.println(manipulation);
+ m.print();
+ }
+ }
+ }
+ result = m.printSolution();
+ break;
+ }
+ default:break;
+ }
+ File file = new File(outFile);
+ try (FileWriter writer = new FileWriter(file)) {
+ writer.write(result);
+ System.out.printf("Saved to file %s\n",outFile);
+ } catch (IOException e) {
+ System.out.printf("File writing error %s", e.getMessage());
+ }
+
+ }
+ catch (IOException e){
+ System.out.println("File reading error: " + inFile);
+ }
+ catch (InvalidDataFileFormat | ParsingArrayException e){
+ System.out.println(e.getMessage());
+ }
}
}
\ No newline at end of file
diff --git a/src/solver/Matrix.java b/src/solver/Matrix.java
new file mode 100644
index 0000000..9f14b71
--- /dev/null
+++ b/src/solver/Matrix.java
@@ -0,0 +1,190 @@
+package solver;
+
+class Pos{
+ int x;
+ int y;
+
+ public Pos(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ public String toString(){
+ return this.x+","+this.y;
+ }
+}
+
+public class Matrix {
+ public static boolean isComplx = false;
+ public static final double threshold = 0.000001;
+ int N;//количество строк
+ int M;//количество столбцов
+
+ Row[] rows;
+
+ int[] colMove;
+ int iteration = 0;
+ protected boolean isComplex = false;
+ protected boolean colsSwaped = false;
+
+ public boolean otladka = false;
+
+ public static boolean compareDouble(double d1, double d2){
+ return (Math.abs(d1 - d2) < threshold);
+ }
+
+ public Matrix(int n, int m) {
+ N = n;
+ M = m;
+ if (!isComplx)
+ rows = new Row[n];
+ colMove = new int[m];//сюда будем записывать перемещения столбов
+ for (int i = 0; i < M; i++)
+ this.colMove[i] = i;
+ }
+
+ public Row getRows(int index) {
+ return this.rows[index];
+ }
+
+ public void addRow(int index, String str) throws ParsingArrayException {
+ this.rows[index] = new Row(index+1, M+1, this);
+ this.rows[index].fillRow(str);
+ }
+
+ public void print(){
+ if (!otladka) return;
+ /*for (Row r:this.rows) {
+ System.out.println(r);
+ }*/
+ for (int i = 0; i < this.N; i++) {
+ System.out.println(this.getRows(i));
+ }
+ }
+
+ public String printSolution(){
+ if (colsSwaped) return printSolution1();
+ String sOut = "The solution is: (";
+ String result="";
+ String s;
+ /*for (Row r:this.rows) {
+ s =r.getColStr(this.M);
+ result+=s+"\n";
+ sOut += s+", ";
+ }*/
+ for (int i = 0; i < this.N; i++) {
+ s= this.getRows(i).getColStr(this.M);
+ result+=s+"\n";
+ sOut += s+", ";
+ }
+ System.out.println(sOut.replaceAll(",\\s$", ")"));
+ return result;
+ }
+
+ private String printSolution1(){
+ String sOut = "The solution is: (";
+ String[] d= new String[colMove.length];
+ String result="";
+ for (int i = 0; i < colMove.length; i++) {
+ d[colMove[i]]=this.rows[i].getColStr(this.M);
+ }
+ for (int i = 0; i < colMove.length; i++) {
+ result+=d[i]+"\n";
+ sOut += d[i]+", ";
+ }
+ System.out.println(sOut.replaceAll(",\\s$", ")"));
+ return result;
+ }
+
+ public String swapRows(int src, int dest){
+ try {
+ Row r1 = this.rows[src];
+ Row r2 = this.rows[dest];
+ iteration++;
+ String result = String.format("%d: %s<->%s", iteration, r1.getName(), r2.getName());
+ Row tmp;
+ tmp = this.rows[dest];
+ this.rows[dest] = this.rows[src];
+ this.rows[src] = tmp;
+ this.rows[src].setMoved(true, src + 1);
+ this.rows[dest].setMoved(true, dest + 1);
+ return result;
+ }
+ catch (Exception e){
+ System.out.println(String.format("SwapRow(src=%d,dest=%d)",src,dest));
+ throw e;
+ }
+ }
+
+
+ public String swapColumns(int src, int dest){
+ for (Row r:this.rows) {
+ r.swapCells(src,dest);
+ }
+ int tmp =this.colMove[dest];
+ this.colMove[dest] = this.colMove[src];
+ this.colMove[src] = tmp;
+ iteration++;
+ colsSwaped = true;
+ return String.format("%d; C%d<->C%d",iteration, src,dest);
+ }
+
+ public int findNonZeroBelow(int col, Row rowBelow){
+ for (int i = rowBelow.getRowNum()/*-1+1*/; i < N; i++) {
+ //if (this.rows[i].getCol(col)!=0) return i;
+ if (!compareDouble(this.rows[i].getCol(col),0)) return i;
+ }
+ return -1;
+ }
+
+ public int findNonZeroRighter(int colAfterIndex, Row row){
+ for (int j = colAfterIndex+1; j < M; j++) {
+// if (row.getCol(j)!=0) return j;
+ if (!compareDouble(row.getCol(j),0)) return j;
+ }
+ return -1;
+ }
+
+ public Pos findNonZeroEverywhere(int colAfterIndex, Row rowBelow){
+ int fromRow=0;
+ if (rowBelow == null) fromRow = 0;
+ else fromRow = rowBelow.getRowNum();
+ for (int i = fromRow; i < N; i++) {
+ for (int j = colAfterIndex+1; j < M; j++) {
+// if (this.rows[i].getCol(j)!=0) return new Pos(i,j);
+ if (!compareDouble(this.rows[i].getCol(j),0)) return new Pos(i,j);
+ }
+ }
+ return null;
+ }
+
+ public Pos getNumberOfZeroRows(){
+ //в ч запишем количество нулевых строк,
+ //в y количество нулевых строк с ненулевой правой частью
+ Pos result= new Pos(0,0);
+ int cnt0 =0, cnt1 =0;
+ for (Row r:this.rows) {
+ cnt0=0;
+ for (int i = 0; i < M+1; i++) {
+ //if (r.getCol(i)!=0) {
+ if (!compareDouble(r.getCol(i),0)){
+ if (i==M) result.y++;
+ break;
+ }
+ cnt0++;
+ }
+ if (cnt0==M+1) result.x++;
+ }
+ return result;
+ }
+
+ public int checkSolution(){
+ Pos zeroRowsCnt = this.getNumberOfZeroRows();
+ if (otladka)
+ System.out.println(zeroRowsCnt);
+ if (zeroRowsCnt.y>0) return -1;//no solutions
+ int cntEq = this.N-zeroRowsCnt.x;//количество ненулевых уравнений
+ if (cntEq==this.M) return 1;//one solution
+ if (cntEq -1)
+ return this.owner.swapRows(this.rowNum-1,nonZeroInd);
+ nonZeroInd = this.owner.findNonZeroRighter(index,this);
+ if (nonZeroInd > -1)
+ return this.owner.swapColumns(index,nonZeroInd);
+ //поиск по всей матрице
+ Pos pos = this.owner.findNonZeroEverywhere(index,this);
+ if (pos == null) return "";
+ return this.owner.swapColumns(index,pos.y)+";"+
+ this.owner.swapRows(this.rowNum-1, pos.x);
+ }
+ double koef = 1/this.data[index];
+ this.mult(koef);
+ this.data[index] = 1;
+// return String.format("%-8.2f %n",koef) +" * "+this.getName()+" -> "+this.getName();
+ return String.format("%d: %.2f * %s -> %s",++this.owner.iteration, koef,this.getName(),this.getName());
+ }
+
+ public String transform0(int index, Row r){
+ if (Matrix.compareDouble(this.data[index],0)) return "";//"already transformed0";
+ double koef = -1 * this.data[index];
+ this.add(r,koef);
+ this.data[index] = 0;
+ this.owner.iteration++;
+// return koef + " * "+ r.getName() + " + "+ this.getName()+" -> "+this.getName();
+ return String.format("%d: %.3f * %s + %s -> %s",this.owner.iteration, koef,r.getName(),this.getName(),this.getName());
+ }
+
+ public double getCol(int index){
+ return (double) this.data[index];
+ }
+
+ public String getColStr(int index){
+ return Double.toString(this.data[index]);
+ }
+
+ public void fillRow(String s) throws ParsingArrayException {
+ String[] str = s.split("\\s+");
+ try {
+ if (str.length!=this.colCnt)
+ throw new ParsingArrayException(
+ String.format("The string '%s' cannot be parsed correctly. It has to contain %d numbers", s, this.colCnt+1),
+ null);
+ for (int i = 0; i < str.length; i++) {
+ if (!isComplex)
+ this.data[i] = Double.parseDouble(str[i]);
+ /*else
+ this.iData[i] = new ComplexNumber(str[i]);*/
+ }
+ } catch(NumberFormatException e){
+ throw new ParsingArrayException(
+ String.format("The string '%s' cannot be parsed as an array of numbers", s),
+ e);
+ }
+ catch (ArrayIndexOutOfBoundsException e){
+ throw new ParsingArrayException(
+ String.format("The string '%s' cannot be parsed correctly, count of numbers is incorrect", s),
+ e);
+ }
+ }
+
+ public String toString() {
+ String s="";
+ if (!isComplex)
+ for (double d:this.data) {
+ s +=String.format("%-10.3f ",d);
+ //s +=String.format("%.3f ",d);
+ };
+ /*else {
+ for (ComplexNumber iDat : iData) {
+ s +=iDat.toString();
+ }
+ }*/
+ return " "+this.getName()+((this.getOldRowNum()!=this.getRowNum())?String.format("(%d)",this.getOldRowNum()):"")+": "+ s.trim();
+ }
+
+ public boolean isMoved() {
+ return isMoved;
+ }
+
+ public void setMoved(boolean moved, int newRow) {
+ isMoved = moved;
+ if (moved) {
+ /*if (this.oldRowNum == this.rowNum) {
+ this.oldRowNum = rowNum;
+ }*/
+ this.rowNum = newRow;
+ }
+ if (this.rowNum == this.oldRowNum) isMoved = false;
+ }
+
+ public void swapCells(int src, int dest){
+ if (!isComplex) {
+ double tmp;
+ tmp = this.data[dest];
+ this.data[dest] = this.data[src];
+ this.data[src] = tmp;
+ } /*else {
+ ComplexNumber tmp;
+ tmp = this.iData[dest];
+ this.iData[dest] = this.iData[src];
+ this.iData[src] = tmp;
+ }*/
+ }
+}
diff --git a/src/solver/iMatrix.java b/src/solver/iMatrix.java
new file mode 100644
index 0000000..4af733b
--- /dev/null
+++ b/src/solver/iMatrix.java
@@ -0,0 +1,73 @@
+package solver;
+
+public class iMatrix extends Matrix {
+ iRow[] rows;
+
+ public iMatrix(int n, int m) {
+ super(n,m);
+ this.isComplex = true;
+ isComplx = true;
+ rows = new iRow[n];
+ }
+
+ public iRow getRows(int index) {
+ return this.rows[index];
+ }
+
+ /*public void print(){
+ if (!otladka) return;
+ for (iRow r:this.rows) {
+ System.out.println(r);
+ }
+ }*/
+
+ public void addRow(int index, String str) throws ParsingArrayException {
+ this.rows[index] = new iRow(index+1, M+1, this);
+ this.rows[index].fillRow(str);
+ }
+
+ public int findNonZeroBelow(int col, iRow rowBelow){
+ for (int i = rowBelow.getRowNum()/*-1+1*/; i < N; i++) {
+ if (!ComplexNumber.compareComplexToDouble(this.rows[i].getColComplex(col),0)) return i;
+ }
+ return -1;
+ }
+
+ public int findNonZeroRighter(int colAfterIndex, iRow row){
+ for (int j = colAfterIndex+1; j < M; j++) {
+ if (!ComplexNumber.compareComplexToDouble(row.getColComplex(j),0)) return j;
+ }
+ return -1;
+ }
+
+ public Pos findNonZeroEverywhere(int colAfterIndex, iRow rowBelow){
+ int fromRow=0;
+ if (rowBelow == null) fromRow = 0;
+ else fromRow = rowBelow.getRowNum();
+ for (int i = fromRow; i < N; i++) {
+ for (int j = colAfterIndex+1; j < M; j++) {
+ if (!ComplexNumber.compareComplexToDouble(this.rows[i].getColComplex(j),0)) return new Pos(i,j);
+ }
+ }
+ return null;
+ }
+
+ public Pos getNumberOfZeroRows(){
+ //в ч запишем количество нулевых строк,
+ //в y количество нулевых строк с ненулевой правой частью
+ Pos result= new Pos(0,0);
+ int cnt0 =0, cnt1 =0;
+ for (iRow r:this.rows) {
+ cnt0=0;
+ for (int i = 0; i < M+1; i++) {
+ if (!ComplexNumber.compareComplexToDouble(r.getColComplex(i),0)){
+ if (i==M) result.y++;
+ break;
+ }
+ cnt0++;
+ }
+ if (cnt0==M+1) result.x++;
+ }
+ return result;
+ }
+}
diff --git a/src/solver/iRow.java b/src/solver/iRow.java
new file mode 100644
index 0000000..b82877d
--- /dev/null
+++ b/src/solver/iRow.java
@@ -0,0 +1,116 @@
+package solver;
+
+public class iRow extends Row {
+ private ComplexNumber[] iData;
+ //private iMatrix owner;
+
+ public iRow(int rowNum, int colCnt, iMatrix owner) {
+ super(rowNum, colCnt, owner);
+ this.isComplex=true;
+ this.iData = new ComplexNumber[colCnt];
+ }
+
+ public void mult(ComplexNumber koef){
+ for (int i = 0; i < iData.length; i++) {
+ iData[i].mult(koef);
+ }
+ }
+
+ public void div(ComplexNumber koef){
+ for (int i = 0; i < iData.length; i++) {
+ iData[i].div(koef);
+ }
+ }
+
+
+ public void add(iRow r, ComplexNumber koef){
+ for (int i = 0; i < iData.length; i++) {
+ iData[i].add(ComplexNumber.mult(r.iData[i],koef));
+ //data[i]+=koef*r.data[i];
+ }
+ }
+
+ public void fillRow(String s) throws ParsingArrayException {
+ String[] str = s.split("\\s+");
+ try {
+ if (str.length!=this.colCnt)
+ throw new ParsingArrayException(
+ String.format("The string '%s' cannot be parsed correctly. It has to contain %d numbers", s, this.colCnt+1),
+ null);
+ for (int i = 0; i < str.length; i++) {
+ /*if (!isComplex)
+ this.data[i] = Double.parseDouble(str[i]);
+ else*/
+ this.iData[i] = new ComplexNumber(str[i]);
+ }
+ } catch(NumberFormatException e){
+ throw new ParsingArrayException(
+ String.format("The string '%s' cannot be parsed as an array of numbers", s),
+ e);
+ }
+ catch (ArrayIndexOutOfBoundsException e){
+ throw new ParsingArrayException(
+ String.format("The string '%s' cannot be parsed correctly, count of numbers is incorrect", s),
+ e);
+ }
+ }
+
+ public String transform1(int index){
+ if (ComplexNumber.compareComplexToDouble(this.iData[index],1)) return "";//"already transformed1";
+ if (ComplexNumber.compareComplexToDouble(this.iData[index],0)){
+ int nonZeroInd = this.owner.findNonZeroBelow(index,this);
+ if (nonZeroInd > -1)
+ return this.owner.swapRows(this.rowNum-1,nonZeroInd);
+ nonZeroInd = this.owner.findNonZeroRighter(index,this);
+ if (nonZeroInd > -1)
+ return this.owner.swapColumns(index,nonZeroInd);
+ //поиск по всей матрице
+ Pos pos = this.owner.findNonZeroEverywhere(index,this);
+ if (pos == null) return "";
+ return this.owner.swapColumns(index,pos.y)+";"+
+ this.owner.swapRows(this.rowNum-1, pos.x);
+ }
+ //ComplexNumber koef = 1/this.iData[index];
+ //ComplexNumber koef = ComplexNumber.div(new ComplexNumber(1,0),this.iData[index]);
+ ComplexNumber koef = new ComplexNumber(this.iData[index]);
+ String koefStr = koef.toString();
+// this.mult(koef);
+ this.div(koef);
+ this.iData[index].set(1,0);
+// return String.format("%-8.2f %n",koef) +" * "+this.getName()+" -> "+this.getName();
+ return String.format("%d: %s / %s -> %s",++this.owner.iteration, this.getName(), koefStr,this.getName());
+ }
+
+ public String transform0(int index, Row r){
+ if (ComplexNumber.compareComplexToDouble(this.iData[index],0)) return "";//"already transformed0";
+ //double koef = -1 * this.iData[index];
+ ComplexNumber koef = ComplexNumber.mult(new ComplexNumber(-1,0),this.iData[index]);
+ String koefStr = koef.toString();
+ this.add((iRow)r,koef);
+ this.iData[index].set(0,0);
+ this.owner.iteration++;
+ return String.format("%d: %s* %s + %s -> %s",this.owner.iteration, koefStr,r.getName(),this.getName(),this.getName());
+ }
+
+ public String toString() {
+ String s="";
+ /*if (!isComplex)
+ for (double d:this.data) {
+ s +=String.format("%-10.3f ",d);
+ //s +=String.format("%.3f ",d);
+ };
+ else {*/
+ for (ComplexNumber iDat : iData) {
+ s +=iDat.toString()+" ";
+ }
+ return " "+this.getName()+((this.getOldRowNum()!=this.getRowNum())?String.format("(%d)",this.getOldRowNum()):"")+": "+ s.trim();
+ }
+
+ public String getColStr(int index){
+ return this.iData[index].toString();
+ }
+
+ public ComplexNumber getColComplex(int index){
+ return this.iData[index];
+ }
+}