Untitled
unknown
java
2 years ago
13 kB
11
Indexable
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));
}
}
Editor is loading...