Untitled
unknown
java
a year ago
13 kB
5
Indexable
Never
package pack; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.stream.IntStream; import static java.lang.Math.PI; import static java.lang.Math.abs; import static java.lang.Math.cos; import static java.lang.Math.sin; record Dot(double x, double y) { public String toString() { return "(x: %.5f, y: %.5f)".formatted(x, y); } } record Constant(double a, double b) { public String toString() { return "(leftBound: %.5f, rightBound: %.5f)".formatted(a, b); } } record BoundedFunPart( Function<Double, Double> func, Double leftBound, Double rightBound, boolean isLeftClosed, boolean isRightClosed ) { public Double getFuncValue(Double x) { return func.apply(x); } public boolean isInBounds(Double x) { if (abs(this.leftBound - x) < 0.000001 && !isLeftClosed) { return true; } else if (abs(this.rightBound - x) < 0.000001 && !isRightClosed) { return true; } else { return this.leftBound < x && x < this.rightBound; } } } class TableGenerator { private int PADDING_SIZE = 2; private String NEW_LINE = "\n"; private String TABLE_JOINT_SYMBOL = "+"; private String TABLE_V_SPLIT_SYMBOL = "|"; private String TABLE_H_SPLIT_SYMBOL = "-"; public String generateTable(List<String> headersList, List<List<String>> rowsList, int... overRiddenHeaderHeight) { StringBuilder stringBuilder = new StringBuilder(); int rowHeight = overRiddenHeaderHeight.length > 0 ? overRiddenHeaderHeight[0] : 1; Map<Integer, Integer> columnMaxWidthMapping = getMaximumWidhtofTable(headersList, rowsList); stringBuilder.append(NEW_LINE); stringBuilder.append(NEW_LINE); createRowLine(stringBuilder, headersList.size(), columnMaxWidthMapping); stringBuilder.append(NEW_LINE); for (int headerIndex = 0; headerIndex < headersList.size(); headerIndex++) { fillCell(stringBuilder, headersList.get(headerIndex), headerIndex, columnMaxWidthMapping); } stringBuilder.append(NEW_LINE); createRowLine(stringBuilder, headersList.size(), columnMaxWidthMapping); for (List<String> row : rowsList) { for (int i = 0; i < rowHeight; i++) { stringBuilder.append(NEW_LINE); } for (int cellIndex = 0; cellIndex < row.size(); cellIndex++) { fillCell(stringBuilder, row.get(cellIndex), cellIndex, columnMaxWidthMapping); } } stringBuilder.append(NEW_LINE); createRowLine(stringBuilder, headersList.size(), columnMaxWidthMapping); stringBuilder.append(NEW_LINE); stringBuilder.append(NEW_LINE); return stringBuilder.toString(); } private void fillSpace(StringBuilder stringBuilder, int length) { for (int i = 0; i < length; i++) { stringBuilder.append(" "); } } private void createRowLine(StringBuilder stringBuilder, int headersListSize, Map<Integer, Integer> columnMaxWidthMapping) { for (int i = 0; i < headersListSize; i++) { if (i == 0) { stringBuilder.append(TABLE_JOINT_SYMBOL); } for (int j = 0; j < columnMaxWidthMapping.get(i) + PADDING_SIZE * 2; j++) { stringBuilder.append(TABLE_H_SPLIT_SYMBOL); } stringBuilder.append(TABLE_JOINT_SYMBOL); } } private Map<Integer, Integer> getMaximumWidhtofTable(List<String> headersList, List<List<String>> rowsList) { Map<Integer, Integer> columnMaxWidthMapping = new HashMap<>(); for (int columnIndex = 0; columnIndex < headersList.size(); columnIndex++) { columnMaxWidthMapping.put(columnIndex, 0); } for (int columnIndex = 0; columnIndex < headersList.size(); columnIndex++) { if (headersList.get(columnIndex).length() > columnMaxWidthMapping.get(columnIndex)) { columnMaxWidthMapping.put(columnIndex, headersList.get(columnIndex).length()); } } for (List<String> row : rowsList) { for (int columnIndex = 0; columnIndex < row.size(); columnIndex++) { if (row.get(columnIndex).length() > columnMaxWidthMapping.get(columnIndex)) { columnMaxWidthMapping.put(columnIndex, row.get(columnIndex).length()); } } } for (int columnIndex = 0; columnIndex < headersList.size(); columnIndex++) { if (columnMaxWidthMapping.get(columnIndex) % 2 != 0) { columnMaxWidthMapping.put(columnIndex, columnMaxWidthMapping.get(columnIndex) + 1); } } return columnMaxWidthMapping; } private int getOptimumCellPadding(int cellIndex, int datalength, Map<Integer, Integer> columnMaxWidthMapping, int cellPaddingSize) { if (datalength % 2 != 0) { datalength++; } if (datalength < columnMaxWidthMapping.get(cellIndex)) { cellPaddingSize = cellPaddingSize + (columnMaxWidthMapping.get(cellIndex) - datalength) / 2; } return cellPaddingSize; } private void fillCell(StringBuilder stringBuilder, String cell, int cellIndex, Map<Integer, Integer> columnMaxWidthMapping) { int cellPaddingSize = getOptimumCellPadding(cellIndex, cell.length(), columnMaxWidthMapping, PADDING_SIZE); if (cellIndex == 0) { stringBuilder.append(TABLE_V_SPLIT_SYMBOL); } fillSpace(stringBuilder, cellPaddingSize); stringBuilder.append(cell); if (cell.length() % 2 != 0) { stringBuilder.append(" "); } fillSpace(stringBuilder, cellPaddingSize); stringBuilder.append(TABLE_V_SPLIT_SYMBOL); } } public class Computations { private static final int NUMBER_OF_NODES = 50; private final List<BoundedFunPart> functions; private final List<Integer> nodesNumber; private final Map<String, List<Dot>> pointsGrid; private final Map<String, List<Constant>> abCoefficientsGrid; private final Map<String, Double> steps; private final Map<String, List<Double>> approximatedValuesGrid; private final Double T; public Computations(List<BoundedFunPart> functions, Double T, List<Integer> nodesNumber) { this.functions = functions; this.nodesNumber = nodesNumber; this.T = T; this.pointsGrid = new HashMap<>(); this.steps = new HashMap<>(); this.abCoefficientsGrid = new HashMap<>(); this.approximatedValuesGrid = new HashMap<>(); solve(); } public void solve() { setPointsGrid(); findABCoefficients(); setApproximatedValuesGrid(); System.out.println("Узлы интерполирования"); nodesNumber.forEach(this::printPointsTable); System.out.println("Коэффициенты"); nodesNumber.forEach(this::printCoefficientsTable); System.out.println("Таблица результатов"); printApproximatedValuesTable(); } private void setPointsGrid() { for (Integer n : nodesNumber) { ArrayList<Dot> dots = new ArrayList<>(); double step = T / (2 * n); double currX = -T / 2; for (int i = 1; i <= 2 * n; i++) { for (var func : functions) { if (func.isInBounds(currX + step * i)) { dots.add(new Dot(currX + step * i, func.getFuncValue(currX + step * i))); } } } pointsGrid.put(n.toString(), dots); steps.put(n.toString(), step); } } private void findABCoefficients() { for (var n : nodesNumber) { ArrayList<Constant> coefficients = new ArrayList<>(); coefficients.add(new Constant(getAWithParams(n, 0)/2,getBWithParams(n, 0)/2)); for (int l = 1; l < n; l++) { coefficients.add(new Constant(getAWithParams(n, l),getBWithParams(n, l))); } coefficients.add(new Constant(getAWithParams(n, n)/2,getBWithParams(n, n)/2)); abCoefficientsGrid.put(n.toString(), coefficients); } } private Double getAWithParams(Integer n, int l) { List<Dot> dots = pointsGrid.get(n.toString()); Double sum = 0.0; for (var point : dots){ sum += point.y()* cos(2 * PI * l * point.x() / T); } return 2 * steps.get(n.toString()) * sum / T; } private Double getBWithParams(Integer n, int l) { List<Dot> dots = pointsGrid.get(n.toString()); Double sum = 0.0; for (var point : dots){ sum += point.y() * sin(2 * PI * l * point.x() / T); } return 2 * steps.get(n.toString()) * sum / T; } private Double evaluateApproximation(Double x, Integer n) { List<Constant> coefficients = abCoefficientsGrid.get(n.toString()); double sum = 0.0; int l = 0; for (var coef : coefficients) { sum += coef.a() * cos(l * 2 * PI * x / T) + coef.b()* sin(l * 2 * PI * x / T); l++; } return sum; } private void setApproximatedValuesGrid() { double step = T / NUMBER_OF_NODES; ArrayList<Double> xs = new ArrayList<>(); ArrayList<Double> ys = new ArrayList<>(); for (int i = 0; i < NUMBER_OF_NODES - 1; i++) { xs.add(-T/2 + i*step); for (var func : functions) { if (func.isInBounds(-T/2 + i*step)) { ys.add(func.getFuncValue(-T/2 + i*step)); } } } xs.add(T/2); ys.add(functions.get(functions.size() - 1).getFuncValue(T/2)); approximatedValuesGrid.put("X", xs); approximatedValuesGrid.put("Y", ys); for (var n : nodesNumber) { ArrayList<Double> approximated = new ArrayList<>(); for (int i = 0; i < NUMBER_OF_NODES; i++) { approximated.add(evaluateApproximation(xs.get(i), n)); } approximatedValuesGrid.put("n = " + n, approximated); } } private List<List<String>> mergeArrays(String[] left, String[] right) { return IntStream.range(0, left.length).mapToObj(i -> List.of(left[i], right[i])).toList(); } private void printPointsTable(Integer n) { List<Dot> dots = pointsGrid.get(n.toString()); String[] pointsX = new String[2 * n + 1]; String[] pointsY = new String[2 * n + 1]; pointsX[0] = "X"; pointsY[0] = "Y"; for (int i = 0; i < dots.size(); i++) { pointsX[i + 1] = String.format("%.5f", dots.get(i).x()); pointsY[i + 1] = String.format("%.5f", dots.get(i).y()); } var str = new TableGenerator().generateTable( List.of("X", "Y"), mergeArrays(pointsX, pointsY) ); System.out.println(str); } private void printCoefficientsTable(Integer n) { List<Constant> abCoefficients = abCoefficientsGrid.get(n.toString()); String[] coefficientsA = new String[n + 1]; String[] coefficientsB = new String[n + 1]; coefficientsA[0] = "al"; coefficientsB[0] = "bl"; for (int i = 1; i < abCoefficients.size(); i++) { coefficientsA[i] = String.format("%.5f", abCoefficients.get(i).a()); coefficientsB[i] = String.format("%.5f", abCoefficients.get(i).b()); } System.out.println("n = " + n + "; a0 = " + abCoefficients.get(0).a()); var str = new TableGenerator().generateTable( List.of("al", "bl"), mergeArrays(coefficientsA, coefficientsB) ); System.out.println(str); } private void printApproximatedValuesTable() { String[] headers = new String[2 + nodesNumber.size()]; String[][] data = new String[50][2 + nodesNumber.size()]; for (int i = 0; i < NUMBER_OF_NODES; i++) { String[] buffer = new String[2 + nodesNumber.size()]; buffer[0] = String.format("%.5f", approximatedValuesGrid.get("X").get(i)); headers[0] = "X"; buffer[1] = String.format("%.5f", approximatedValuesGrid.get("Y").get(i)); headers[1] = "Y"; for (int j = 1; j <= nodesNumber.size(); j++) { buffer[1 + j] = String.format("%.5f", approximatedValuesGrid.get("n = " + nodesNumber.get(j - 1)).get(i)); headers[1 + j] = "n = " + nodesNumber.get(j - 1); } data[i] = buffer; } var str = new TableGenerator().generateTable( List.of(headers), Arrays.stream(data).map(List::of).toList() ); System.out.println(str); } public static void main(String[] args) { var func = List.of( new BoundedFunPart(x -> -x, -PI / 2, 0.0, false, false), new BoundedFunPart(x -> x, 0.0, PI / 2, true, false) ); new Computations(func, PI, List.of(4, 8, 16)); } }