lab3
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package ru.lionarius;
|
package ru.lionarius;
|
||||||
|
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,6 +15,29 @@ public class IntegralCalculator {
|
|||||||
*/
|
*/
|
||||||
private final double accuracy;
|
private final double accuracy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback to track the progress of the integration.
|
||||||
|
* The callback is called at least twice: once at the beginning, and once at the end of computation.
|
||||||
|
* Takes the current step and the total number of steps.
|
||||||
|
*/
|
||||||
|
private final BiConsumer<Long, Long> progressCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an {@link IntegralCalculator} with the specified accuracy and an optional progress callback.
|
||||||
|
* The progress callback is invoked at each step of the integration process.
|
||||||
|
*
|
||||||
|
* @param accuracy The desired accuracy for the integral calculation.
|
||||||
|
* @param progressCallback A callback function to track progress. Can be null.
|
||||||
|
* @throws IllegalArgumentException if the accuracy is less than or equal to zero.
|
||||||
|
*/
|
||||||
|
public IntegralCalculator(double accuracy, BiConsumer<Long, Long> progressCallback) {
|
||||||
|
if (accuracy <= 0.0)
|
||||||
|
throw new IllegalArgumentException("accuracy must be a positive number");
|
||||||
|
|
||||||
|
this.accuracy = accuracy;
|
||||||
|
this.progressCallback = progressCallback;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an {@link IntegralCalculator} with the specified accuracy.
|
* Constructs an {@link IntegralCalculator} with the specified accuracy.
|
||||||
*
|
*
|
||||||
@@ -21,10 +45,7 @@ public class IntegralCalculator {
|
|||||||
* @throws IllegalArgumentException if the accuracy is less than or equal to zero.
|
* @throws IllegalArgumentException if the accuracy is less than or equal to zero.
|
||||||
*/
|
*/
|
||||||
public IntegralCalculator(double accuracy) {
|
public IntegralCalculator(double accuracy) {
|
||||||
if (accuracy <= 0.0)
|
this(accuracy, null);
|
||||||
throw new IllegalArgumentException("accuracy must be a positive number");
|
|
||||||
|
|
||||||
this.accuracy = accuracy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,8 +67,12 @@ public class IntegralCalculator {
|
|||||||
* @return The estimated value of the definite integral.
|
* @return The estimated value of the definite integral.
|
||||||
*/
|
*/
|
||||||
public double calculate(Function<Double, Double> function, double lowerBound, double upperBound) {
|
public double calculate(Function<Double, Double> function, double lowerBound, double upperBound) {
|
||||||
if (lowerBound == upperBound)
|
if (lowerBound == upperBound) {
|
||||||
|
this.callProgressCallback(0, 1);
|
||||||
|
this.callProgressCallback(1, 1);
|
||||||
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
var invert = false;
|
var invert = false;
|
||||||
if (lowerBound > upperBound) {
|
if (lowerBound > upperBound) {
|
||||||
@@ -61,15 +86,33 @@ public class IntegralCalculator {
|
|||||||
var n = (long) Math.ceil((upperBound - lowerBound) / this.accuracy);
|
var n = (long) Math.ceil((upperBound - lowerBound) / this.accuracy);
|
||||||
var h = (upperBound - lowerBound) / n;
|
var h = (upperBound - lowerBound) / n;
|
||||||
|
|
||||||
|
this.callProgressCallback(0, n);
|
||||||
|
|
||||||
var sum = (function.apply(lowerBound) + function.apply(upperBound)) / 2;
|
var sum = (function.apply(lowerBound) + function.apply(upperBound)) / 2;
|
||||||
for (var i = 1L; i < n; i++)
|
for (var i = 1L; i < n; i++) {
|
||||||
sum += function.apply(lowerBound + h * i);
|
sum += function.apply(lowerBound + h * i);
|
||||||
|
|
||||||
|
this.callProgressCallback(i, n);
|
||||||
|
}
|
||||||
|
|
||||||
sum *= h;
|
sum *= h;
|
||||||
|
|
||||||
if (invert)
|
if (invert)
|
||||||
sum = -sum;
|
sum = -sum;
|
||||||
|
|
||||||
|
this.callProgressCallback(n, n);
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the progress callback, if provided.
|
||||||
|
*
|
||||||
|
* @param current The current step in the integration process.
|
||||||
|
* @param total The total number of steps in the integration process.
|
||||||
|
*/
|
||||||
|
private void callProgressCallback(long current, long total) {
|
||||||
|
if (this.progressCallback != null)
|
||||||
|
this.progressCallback.accept(current, total);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,24 @@ public class Main {
|
|||||||
Function<Double, Double> function = x -> Math.sin(x) * x;
|
Function<Double, Double> function = x -> Math.sin(x) * x;
|
||||||
var lowerBound = 0.0;
|
var lowerBound = 0.0;
|
||||||
var upperBound = 1.0;
|
var upperBound = 1.0;
|
||||||
double[] accuracies = {0.001, 0.00001, 0.0000001, 0.000000001};
|
double[] accuracies = {0.001, 0.00001, 0.0000001, 0.000000001, 0.000000001};
|
||||||
|
var threads = new Thread[accuracies.length];
|
||||||
|
|
||||||
for (var accuracy : accuracies) {
|
for (var i = 0; i < accuracies.length; i++) {
|
||||||
var calculator = new IntegralCalculator(accuracy);
|
final var accuracy = accuracies[i];
|
||||||
|
var thread = new Thread(() -> {
|
||||||
|
var calculator = new IntegralCalculator(
|
||||||
|
accuracy,
|
||||||
|
(current, total) -> {
|
||||||
|
if (current % (total / 15) != 0)
|
||||||
|
return;
|
||||||
|
System.out.printf(
|
||||||
|
"[%s] Progress: %.2f%%%n",
|
||||||
|
Thread.currentThread().getName(),
|
||||||
|
(current * 100.0 / total)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
var startTime = System.nanoTime();
|
var startTime = System.nanoTime();
|
||||||
|
|
||||||
@@ -18,7 +32,23 @@ public class Main {
|
|||||||
|
|
||||||
var totalTime = System.nanoTime() - startTime;
|
var totalTime = System.nanoTime() - startTime;
|
||||||
|
|
||||||
System.out.printf("Calculated value: %.15f | Accuracy: %e | Time: %.9fms%n", value, accuracy, totalTime / 1_000_000.0);
|
System.out.printf(
|
||||||
|
"[%s] Calculated value: %.15f | Accuracy: %e | Time: %.9fms%n",
|
||||||
|
Thread.currentThread().getName(),
|
||||||
|
value,
|
||||||
|
accuracy,
|
||||||
|
totalTime / 1_000_000.0
|
||||||
|
);
|
||||||
|
});
|
||||||
|
threads[i] = thread;
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (var thread : threads)
|
||||||
|
thread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user