-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module type="JAVA_MODULE" version="4" /> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>org.example</groupId> | ||
<artifactId>calc-test3</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
|
||
<properties> | ||
<maven.compiler.source>11</maven.compiler.source> | ||
<maven.compiler.target>11</maven.compiler.target> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.la4j</groupId> | ||
<artifactId>la4j</artifactId> | ||
<version>0.6.0</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package mathcalc.group343.stepyrev; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import mathcalc.group343.stepyrev.solver.MechanicalQuadraturesSolver; | ||
import mathcalc.group343.stepyrev.util.MatrixUtil; | ||
import mathcalc.group343.stepyrev.util.PrettyPrinter; | ||
|
||
public class Application { | ||
|
||
private static final Double A = 0d; | ||
private static final Double B = 1d; | ||
private static final Double X = (A + B) / 2; | ||
|
||
private static final Integer MAX_N = 11; | ||
private static final Integer MAX_A = 10; | ||
|
||
private static MechanicalQuadraturesSolver solver; | ||
private static List<Double> accurateSolution; | ||
|
||
private static PrettyPrinter printer = new PrettyPrinter(System.out); | ||
|
||
public static void main(String[] args) { | ||
solver = new MechanicalQuadraturesSolver(); | ||
performProcess(); | ||
} | ||
|
||
private static void performProcess() { | ||
int nDegree = 1; | ||
int alphaDegree; | ||
double alpha; | ||
int n; | ||
String[][] table = new String[MAX_N][MAX_A]; | ||
table[0][0] = "n, alpha"; | ||
|
||
while (nDegree < MAX_N) { | ||
alphaDegree = 1; | ||
n = 10 * nDegree; | ||
table[nDegree][0] = String.valueOf(n); | ||
|
||
while (alphaDegree < MAX_A) { | ||
table[0][alphaDegree] = String.format("10^(-%d)", alphaDegree); | ||
alpha = Math.pow(10, -alphaDegree); | ||
accurateSolution = getAccurateSolution(n); | ||
List<Double> foundSolution = solver.getSolution(A, B, X, n, alpha); | ||
Double difNorm = MatrixUtil.countNorm(foundSolution, accurateSolution); | ||
table[nDegree][alphaDegree] = String.valueOf(difNorm); | ||
alphaDegree += 1; | ||
} | ||
|
||
nDegree += 1; | ||
} | ||
|
||
printer.print(table); | ||
} | ||
|
||
private static List<Double> getAccurateSolution(int n) { | ||
List<Double> solution = new ArrayList<>(); | ||
for (int i = 0; i < n; i++) { | ||
solution.add(1d); | ||
} | ||
|
||
return solution; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package mathcalc.group343.stepyrev.solver; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import org.la4j.Matrix; | ||
|
||
/** | ||
* Класс, предназначенный для нахождения решения систем с матрицами вида Ax = b методом Гаусса. | ||
*/ | ||
public class GaussSystemSolver { | ||
|
||
private Integer MATRIX_SIZE; | ||
|
||
/** | ||
* Метод, который находит решение системы алгоритмом Гаусса | ||
* | ||
* @param matrix -- матрица системы, заданная в виде массива Double | ||
* @return -- решение системы | ||
*/ | ||
public List<Double> findSolution(Matrix matrix) { | ||
this.MATRIX_SIZE = matrix.rows(); | ||
Matrix triangleSystem = performRightProgress(matrix); | ||
return performReverseProgress(triangleSystem); | ||
} | ||
|
||
/** | ||
* Метод, который осуществляет прямой ход алгоритма Гаусса. | ||
* | ||
* @param matrix -- матрица системы, заданная в виде массива Double | ||
* @return -- верхнетреугольную матрицу | ||
*/ | ||
public Matrix performRightProgress(Matrix matrix) { | ||
subtractPrevious(matrix); | ||
return matrix; | ||
} | ||
|
||
/** | ||
* Метод, который осуществляет обратный ход алгоритма Гаусса. | ||
* | ||
* @param triangleMatrix -- матрица А, заданная в виде массива Double | ||
* @return -- решения системы | ||
*/ | ||
public List<Double> performReverseProgress(Matrix triangleMatrix) { | ||
List<Double> solutions = new ArrayList<>(); | ||
Double solution; | ||
for (int i = MATRIX_SIZE - 1; i >= 0; i--) { | ||
solution = 0D; | ||
for (int j = i + 1; j < MATRIX_SIZE; j++) { | ||
solution -= triangleMatrix.get(i, j) * solutions.get(MATRIX_SIZE - j - 1); | ||
} | ||
|
||
solution += triangleMatrix.get(i, MATRIX_SIZE); | ||
solutions.add(solution); | ||
} | ||
|
||
Collections.reverse(solutions); // меняем местами x1 и x2 | ||
return solutions; | ||
} | ||
|
||
/** | ||
* Метод, в котором каждый элемент матрицы выше диагонали делится на диагональный элемент. Этот | ||
* процесс используется в прямом ходе алгоритма Гаусса. | ||
* | ||
* @param matrix -- матрица системы | ||
*/ | ||
private void divideByDiagonal(Matrix matrix, int stringNumber) { | ||
Double tmp = matrix.get(stringNumber, stringNumber); | ||
for (int i = 0; i < MATRIX_SIZE + 1; i++) { | ||
Double curElem = matrix.get(stringNumber, i); // a[stringNumber][j] | ||
curElem = curElem / tmp; | ||
matrix.set(stringNumber, i, curElem); | ||
} | ||
} | ||
|
||
/** | ||
* Метод, в котором из текущей строки вычитается предыдущая. Этот процесс используется в прямом | ||
* ходе алгоритма Гаусса. | ||
* | ||
* @param matrix -- матрица системы | ||
*/ | ||
private void subtractPrevious(Matrix matrix) { | ||
Double tmp = 0D; | ||
for (int k = 0; k < MATRIX_SIZE; k++) { | ||
divideByDiagonal(matrix, k); | ||
for (int i = k + 1; i < MATRIX_SIZE; i++) { | ||
tmp = matrix.get(i, k); // a[i][k] | ||
for (int j = k; j < MATRIX_SIZE + 1; j++) { | ||
Double curElem = matrix.get(i, j); // a[i][j] | ||
Double prevElem = matrix.get(k, j); // a[k][j] | ||
curElem = curElem - prevElem * tmp; | ||
matrix.set(i, j, curElem); | ||
} | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package mathcalc.group343.stepyrev.solver; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import mathcalc.group343.stepyrev.util.Function; | ||
|
||
/** | ||
* Класс, который вычисляет значения интеграла методом прямоугольников. | ||
*/ | ||
public class IntegralRectangleSolver { | ||
|
||
private double A; | ||
private double H; | ||
private double M; | ||
private double X; | ||
|
||
public IntegralRectangleSolver(double a, double h, double m, double x) { | ||
A = a; | ||
H = h; | ||
M = m; | ||
X = x; | ||
} | ||
|
||
/** | ||
* Метод, который возвращает коэффициенты разложения интеграла методом прямоугольников. | ||
*/ | ||
public List<Double> getIntegralCoefs() { | ||
double alpha = A + H / 2; | ||
List<Double> integralCoefs = new ArrayList<>(); | ||
for (int k = 1; k <= M; k++) { | ||
integralCoefs.add(Function.getValue(X, alpha + (k - 1) * H)); | ||
} | ||
|
||
return integralCoefs; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package mathcalc.group343.stepyrev.solver; | ||
|
||
import java.util.List; | ||
import mathcalc.group343.stepyrev.util.Function; | ||
import mathcalc.group343.stepyrev.util.MatrixUtil; | ||
import org.la4j.Matrix; | ||
import org.la4j.matrix.dense.Basic2DMatrix; | ||
|
||
/** | ||
* Класс, который реализует метод механических квадратур. | ||
*/ | ||
public class MechanicalQuadraturesSolver { | ||
|
||
private IntegralRectangleSolver integralSolver; | ||
private double A; | ||
private double B; | ||
private Double X; | ||
private Integer N; | ||
private Double H; | ||
private Double alpha; | ||
|
||
private Matrix matrixC; | ||
private Matrix matrixU; | ||
|
||
/** | ||
* Метод, который реализует метод механических квадратур. | ||
*/ | ||
public List<Double> getSolution(Double a, Double b, Double x, Integer n, Double alpha) { | ||
this.A = a; | ||
this.B = b; | ||
this.X = x; | ||
this.N = n; | ||
this.H = Math.abs(b - a) / N; | ||
this.alpha = alpha; | ||
|
||
integralSolver = new IntegralRectangleSolver(A, H, N, X); | ||
List<Double> coefs = integralSolver.getIntegralCoefs(); | ||
matrixC = initMatrixC(coefs); | ||
|
||
Matrix leftPart = countLeftPart(); | ||
Matrix rightPart = countRightPart(); | ||
|
||
GaussSystemSolver solver = new GaussSystemSolver(); | ||
Matrix augmentedMatrix = MatrixUtil.uniteMatrices(leftPart, rightPart); | ||
|
||
return solver.findSolution(augmentedMatrix); | ||
} | ||
|
||
/** | ||
* Метод, который инициализирует матрицу C, U. | ||
*/ | ||
private Matrix initMatrixC(List<Double> coefs) { | ||
Matrix matrix = new Basic2DMatrix(N, N); | ||
matrixU = new Basic2DMatrix(N, 1); | ||
|
||
for (int j = 0; j < N; j++) { | ||
double xJ = X + j * H; | ||
double sum = 0d; | ||
for (int k = 0; k < N; k++) { | ||
double dJK = j == k ? 1 : 0; | ||
double aK = coefs.get(k); | ||
double xK = X + k * H; | ||
double hJK = Function.getValue(xJ, xK); | ||
dJK -= aK * hJK; | ||
matrix.set(j, k, dJK); | ||
sum += dJK; | ||
} | ||
|
||
matrixU.set(j, 0, sum); | ||
} | ||
|
||
return matrix; | ||
} | ||
|
||
/** Метод, который вычисляет левую часть в уравнении (C*C + aE)Z = C*U. */ | ||
private Matrix countLeftPart() { | ||
Matrix matrixCTranspose = matrixC.transpose(); | ||
Matrix result = matrixCTranspose.multiply(matrixC); | ||
Matrix identityMatrix = MatrixUtil.getIdentityMatrix(matrixC.rows()); | ||
result = result.add(identityMatrix.multiply(alpha)); | ||
return result; | ||
} | ||
|
||
/** Метод, который вычисляет правую часть в уравнении (C*C + aE)Z = C*U. */ | ||
private Matrix countRightPart() { | ||
Matrix matrixCTranspose = matrixC.transpose(); | ||
return matrixCTranspose.multiply(matrixU); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package mathcalc.group343.stepyrev.util; | ||
|
||
/** Класс, который реализует функцию 1 / (10 - x - s). */ | ||
public class Function { | ||
|
||
/** Метод, который возвращает значение функции 1 / (10 - x - s) в точке x, s. */ | ||
public static double getValue(double x, double s) { | ||
return 1 / (10 - x - s); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package mathcalc.group343.stepyrev.util; | ||
|
||
/** Класс, который реализует пару из точки и значения функции, вычисленное в ней. */ | ||
public class FunctionPoint { | ||
// точка x | ||
private final Double value; | ||
// значение f(x) | ||
private final Double functionValue; | ||
|
||
public FunctionPoint(Double value, Double functionValue) { | ||
this.value = value; | ||
this.functionValue = functionValue; | ||
} | ||
|
||
public Double getValue() { | ||
return value; | ||
} | ||
|
||
public Double getFunctionValue() { | ||
return functionValue; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package mathcalc.group343.stepyrev.util; | ||
|
||
import java.util.List; | ||
import org.la4j.Matrix; | ||
import org.la4j.matrix.dense.Basic2DMatrix; | ||
|
||
public class MatrixUtil { | ||
|
||
private static PrettyPrinter printer = new PrettyPrinter(System.out); | ||
|
||
/** | ||
* Метод, которые объединяет объединяет матрицу A и b. | ||
* | ||
* @param matrix -- матрица А | ||
* @param rightPart -- матрица b | ||
* @return -- объединенная матрица | ||
*/ | ||
public static Matrix uniteMatrices( | ||
Matrix matrix, Matrix rightPart) { | ||
Matrix copyMatrix = new Basic2DMatrix(matrix.rows(), matrix.columns() + 1); | ||
for (int i = 0; i < matrix.rows(); i++) { | ||
for (int j = 0; j < matrix.columns(); j++) { | ||
double value = matrix.get(i, j); | ||
copyMatrix.set(i, j, value); | ||
} | ||
} | ||
|
||
for (int i = 0; i < matrix.rows(); i++) { | ||
double elem = rightPart.get(i, 0); | ||
copyMatrix.set(i, matrix.rows(), elem); | ||
} | ||
|
||
return copyMatrix; | ||
} | ||
|
||
/** | ||
* Метод, который печатает матрицу. | ||
*/ | ||
public static void printMatrix(Matrix matrix) { | ||
int size = matrix.rows(); | ||
String[][] table = new String[size][size]; | ||
for (int i = 0; i < size; i++) { | ||
for (int j = 0; j < size; j++) { | ||
table[i][j] = String.valueOf(matrix.get(i, j)); | ||
} | ||
} | ||
|
||
printer.print(table); | ||
System.out.println(""); | ||
} | ||
|
||
/** | ||
* Метод, который печатает вектор. | ||
*/ | ||
public static void printVector(Matrix vector) { | ||
int size = vector.columns(); | ||
String[][] table = new String[size][1]; | ||
for (int i = 0; i < size; i++) { | ||
table[i][0] = String.valueOf(vector.get(0, i)); | ||
} | ||
|
||
printer.print(table); | ||
System.out.println(""); | ||
} | ||
|
||
/** Метод, который возвращает единичную матрицу заданного размера. */ | ||
public static Matrix getIdentityMatrix(int size) { | ||
Matrix matrix = new Basic2DMatrix(size, size); | ||
for (int i = 0; i < size; i++) { | ||
matrix.set(i, i, 1); | ||
} | ||
|
||
return matrix; | ||
} | ||
|
||
public static Double countNorm(List<Double> fstVector, List<Double> sndVector) { | ||
Matrix fstMatrix = convertToMatrix(fstVector); | ||
Matrix sndMatrix = convertToMatrix(sndVector); | ||
Matrix difMatrix = fstMatrix.subtract(sndMatrix); | ||
return Math.abs(difMatrix.norm()); | ||
} | ||
|
||
private static Matrix convertToMatrix(List<Double> vector) { | ||
Matrix matrix = new Basic2DMatrix(vector.size(), 1); | ||
for (int i = 0; i < vector.size(); i++) { | ||
matrix.set(i, 0, vector.get(i)); | ||
} | ||
|
||
return matrix; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package mathcalc.group343.stepyrev.util; | ||
|
||
import static java.lang.String.format; | ||
|
||
import java.io.PrintStream; | ||
|
||
public final class PrettyPrinter { | ||
|
||
private static final char BORDER_KNOT = '+'; | ||
private static final char HORIZONTAL_BORDER = '-'; | ||
private static final char VERTICAL_BORDER = '|'; | ||
|
||
private static final String DEFAULT_AS_NULL = "(NULL)"; | ||
|
||
private final PrintStream out; | ||
private final String asNull; | ||
|
||
public PrettyPrinter(PrintStream out) { | ||
this(out, DEFAULT_AS_NULL); | ||
} | ||
|
||
public PrettyPrinter(PrintStream out, String asNull) { | ||
if (out == null) { | ||
throw new IllegalArgumentException("No print stream provided"); | ||
} | ||
if (asNull == null) { | ||
throw new IllegalArgumentException("No NULL-value placeholder provided"); | ||
} | ||
this.out = out; | ||
this.asNull = asNull; | ||
} | ||
|
||
public void print(String[][] table) { | ||
if (table == null) { | ||
throw new IllegalArgumentException("No tabular data provided"); | ||
} | ||
if (table.length == 0) { | ||
return; | ||
} | ||
final int[] widths = new int[getMaxColumns(table)]; | ||
adjustColumnWidths(table, widths); | ||
printPreparedTable(table, widths, getHorizontalBorder(widths)); | ||
} | ||
|
||
private void printPreparedTable(String[][] table, int widths[], String horizontalBorder) { | ||
final int lineLength = horizontalBorder.length(); | ||
out.println(horizontalBorder); | ||
for (final String[] row : table) { | ||
if (row != null) { | ||
out.println(getRow(row, widths, lineLength)); | ||
out.println(horizontalBorder); | ||
} | ||
} | ||
} | ||
|
||
private String getRow(String[] row, int[] widths, int lineLength) { | ||
final StringBuilder builder = new StringBuilder(lineLength).append(VERTICAL_BORDER); | ||
final int maxWidths = widths.length; | ||
for (int i = 0; i < maxWidths; i++) { | ||
builder.append(padRight(getCellValue(safeGet(row, i, null)), widths[i])) | ||
.append(VERTICAL_BORDER); | ||
} | ||
return builder.toString(); | ||
} | ||
|
||
private String getHorizontalBorder(int[] widths) { | ||
final StringBuilder builder = new StringBuilder(256); | ||
builder.append(BORDER_KNOT); | ||
for (final int w : widths) { | ||
for (int i = 0; i < w; i++) { | ||
builder.append(HORIZONTAL_BORDER); | ||
} | ||
builder.append(BORDER_KNOT); | ||
} | ||
return builder.toString(); | ||
} | ||
|
||
private int getMaxColumns(String[][] rows) { | ||
int max = 0; | ||
for (final String[] row : rows) { | ||
if (row != null && row.length > max) { | ||
max = row.length; | ||
} | ||
} | ||
return max; | ||
} | ||
|
||
private void adjustColumnWidths(String[][] rows, int[] widths) { | ||
for (final String[] row : rows) { | ||
if (row != null) { | ||
for (int c = 0; c < widths.length; c++) { | ||
final String cv = getCellValue(safeGet(row, c, asNull)); | ||
final int l = cv.length(); | ||
if (widths[c] < l) { | ||
widths[c] = l; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private static String padRight(String s, int n) { | ||
return format("%1$-" + n + "s", s); | ||
} | ||
|
||
private static String safeGet(String[] array, int index, String defaultValue) { | ||
return index < array.length ? array[index] : defaultValue; | ||
} | ||
|
||
private String getCellValue(Object value) { | ||
return value == null ? asNull : value.toString(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Main-Class: mathcalc.group343.stepyrev.Application | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Manifest-Version: 1.0 | ||
Main-Class: mathcalc.group343.stepyrev.Application | ||
|