From 8d6e214f254c655f7128a6669eb49d306634cc02 Mon Sep 17 00:00:00 2001
From: Tanya Cheremkhina <53428519+tcheremkhina@users.noreply.github.com>
Date: Mon, 12 Apr 2021 21:41:28 +0300
Subject: [PATCH] FastestDescent & ConjugateGradientMethod
FastestDescent and ConjugateGradientMethod implemented. Need check
---
Lab1/Lab1.iml | 11 +++
Lab2/.idea/.gitignore | 8 ++
Lab2/.idea/misc.xml | 6 ++
Lab2/.idea/modules.xml | 8 ++
Lab2/.idea/vcs.xml | 6 ++
Lab2/Lab2.iml | 11 +++
Lab2/src/RunMethod.java | 18 ++--
Lab2/src/elements/MyFunction.java | 1 -
Lab2/src/elements/Vector.java | 22 ++++-
Lab2/src/methods/ConjugateGradientMethod.java | 37 ++++++++
Lab2/src/methods/Dichotomy.java | 39 ++++++++
Lab2/src/methods/FastestDescent.java | 39 ++++++++
Lab2/src/methods/GradientDescent.java | 3 +-
Lab2/src/methods/Method.java | 15 ++++
.../result/DefaultIterationResult.java | 69 ++++++++++++++
Lab2/src/methods/result/IterationResult.java | 6 ++
.../result/ParabolaIterationResult.java | 90 +++++++++++++++++++
Lab2/src/methods/result/Result.java | 60 +++++++++++++
18 files changed, 440 insertions(+), 9 deletions(-)
create mode 100644 Lab1/Lab1.iml
create mode 100644 Lab2/.idea/.gitignore
create mode 100644 Lab2/.idea/misc.xml
create mode 100644 Lab2/.idea/modules.xml
create mode 100644 Lab2/.idea/vcs.xml
create mode 100644 Lab2/Lab2.iml
create mode 100644 Lab2/src/methods/ConjugateGradientMethod.java
create mode 100644 Lab2/src/methods/Dichotomy.java
create mode 100644 Lab2/src/methods/FastestDescent.java
create mode 100644 Lab2/src/methods/Method.java
create mode 100644 Lab2/src/methods/result/DefaultIterationResult.java
create mode 100644 Lab2/src/methods/result/IterationResult.java
create mode 100644 Lab2/src/methods/result/ParabolaIterationResult.java
create mode 100644 Lab2/src/methods/result/Result.java
diff --git a/Lab1/Lab1.iml b/Lab1/Lab1.iml
new file mode 100644
index 0000000..c90834f
--- /dev/null
+++ b/Lab1/Lab1.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Lab2/.idea/.gitignore b/Lab2/.idea/.gitignore
new file mode 100644
index 0000000..d897254
--- /dev/null
+++ b/Lab2/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/../../../../../../../../:\Users\Tanya Cheremkhina\Documents\GitHub\Met-opt\Lab2\.idea/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/Lab2/.idea/misc.xml b/Lab2/.idea/misc.xml
new file mode 100644
index 0000000..c07f4d8
--- /dev/null
+++ b/Lab2/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Lab2/.idea/modules.xml b/Lab2/.idea/modules.xml
new file mode 100644
index 0000000..dd47d37
--- /dev/null
+++ b/Lab2/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Lab2/.idea/vcs.xml b/Lab2/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/Lab2/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Lab2/Lab2.iml b/Lab2/Lab2.iml
new file mode 100644
index 0000000..c90834f
--- /dev/null
+++ b/Lab2/Lab2.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Lab2/src/RunMethod.java b/Lab2/src/RunMethod.java
index 44a8203..1210027 100644
--- a/Lab2/src/RunMethod.java
+++ b/Lab2/src/RunMethod.java
@@ -1,23 +1,31 @@
import elements.MyFunction;
import elements.Vector;
+import methods.ConjugateGradientMethod;
import methods.GradientDescent;
+import methods.FastestDescent;
import java.util.List;
public class RunMethod {
public static void main(final String[] args) {
- final GradientDescent method = new GradientDescent(0.01);
+ final GradientDescent gradientDescent = new GradientDescent(0.01);
+ final FastestDescent fastestDescent = new FastestDescent(0.01);
+ final ConjugateGradientMethod conjugateGradientMethod = new ConjugateGradientMethod();
final MyFunction function = new MyFunction(
list -> {
final double first = list.get(0), second = list.get(1);
- return first * first + second * second + second;
+ return first * first + 40 * second * second + second;
},
List.of(
list -> 2 * list.get(0),
- list -> 2 * list.get(1) + 1.
+ list -> 80 * list.get(1) + 1.
)
);
- final Vector x = new Vector(List.of(3., -4.));
- method.calc(function, x);
+ final Vector x = new Vector(List.of(1., 1.));
+ gradientDescent.calc(function, x);
+ System.out.println("-----------------------");
+ fastestDescent.calc(function, x);
+ System.out.println("-----------------------");
+ conjugateGradientMethod.calc(function, x);
}
}
diff --git a/Lab2/src/elements/MyFunction.java b/Lab2/src/elements/MyFunction.java
index 7d7671d..e9c031e 100644
--- a/Lab2/src/elements/MyFunction.java
+++ b/Lab2/src/elements/MyFunction.java
@@ -1,7 +1,6 @@
package elements;
import java.util.List;
-import java.util.function.DoubleUnaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
diff --git a/Lab2/src/elements/Vector.java b/Lab2/src/elements/Vector.java
index 7465b99..ad7ea62 100644
--- a/Lab2/src/elements/Vector.java
+++ b/Lab2/src/elements/Vector.java
@@ -2,7 +2,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.function.DoubleUnaryOperator;
import java.util.stream.Collectors;
public class Vector {
@@ -24,6 +23,14 @@ public Vector multiply(final double mul) {
);
}
+ public Vector negate() {
+ final List value = new ArrayList<>();
+ for (int i = 0; i < point.size(); ++i) {
+ value.add(-point.get(i));
+ }
+ return new Vector(value);
+ }
+
public Vector subtract(final Vector vector) {
final List value = new ArrayList<>();
for (int i = 0; i < point.size(); ++i) {
@@ -32,10 +39,23 @@ public Vector subtract(final Vector vector) {
return new Vector(value);
}
+ public Vector add(final Vector vector) {
+ final List value = new ArrayList<>();
+ for (int i = 0; i < point.size(); ++i) {
+ value.add(point.get(i) + vector.point.get(i));
+ }
+ return new Vector(value);
+ }
+
+
public double abs() {
return Math.sqrt(point.stream().reduce(0., (arg1, arg2) -> arg1 + arg2 * arg2));
}
+ public double absSqr() {
+ return point.stream().reduce(0., (arg1, arg2) -> arg1 + arg2 * arg2);
+ }
+
@Override
public String toString() {
return "Vector{" +
diff --git a/Lab2/src/methods/ConjugateGradientMethod.java b/Lab2/src/methods/ConjugateGradientMethod.java
new file mode 100644
index 0000000..2e24936
--- /dev/null
+++ b/Lab2/src/methods/ConjugateGradientMethod.java
@@ -0,0 +1,37 @@
+package methods;
+
+import elements.MyFunction;
+import elements.Vector;
+import methods.result.IterationResult;
+import methods.result.Result;
+
+import java.util.function.DoubleUnaryOperator;
+
+public class ConjugateGradientMethod {
+
+ public void calc(final MyFunction function, Vector x) {
+ Vector gradientFX = function.applyGradient(x);
+ Double fx = null;
+ Vector p = function.applyGradient(x).negate();
+ System.out.println("gradient abs: " + gradientFX.abs());
+ for (int cnt = 0; cnt <= x.getPoint().size(); cnt++) {
+ Vector finalGradientFX = gradientFX;
+ Vector finalX = x;
+ DoubleUnaryOperator fAlpha = alpha -> function.applyFunction(finalX.subtract(finalGradientFX.multiply(alpha)));
+ Method extends IterationResult> method = new Dichotomy(1e-9);
+ Result extends IterationResult> result = method.calcAllIterations(fAlpha, 0, 100);
+ double alpha = result.getPoint();
+
+ Vector xNext = x.add(p.multiply(alpha));
+ double beta = function.applyGradient(xNext).absSqr() / function.applyGradient(x).absSqr();
+ Vector pNext = function.applyGradient(xNext).negate().add(p.multiply(beta));
+ x = xNext;
+ p = pNext;
+ fx = function.applyFunction(x);
+ gradientFX = function.applyGradient(x);
+ System.out.println(String.format("%s val: %.10f", x, fx));
+ System.out.println("gradient abs: " + gradientFX.abs());
+ }
+ System.out.println(String.format("Result:\n%s val: %.10f", x, fx));
+ }
+}
diff --git a/Lab2/src/methods/Dichotomy.java b/Lab2/src/methods/Dichotomy.java
new file mode 100644
index 0000000..7c88a18
--- /dev/null
+++ b/Lab2/src/methods/Dichotomy.java
@@ -0,0 +1,39 @@
+package methods;
+
+import methods.result.DefaultIterationResult;
+import methods.result.Result;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.DoubleUnaryOperator;
+
+public class Dichotomy implements Method {
+ private final double epsilon;
+ private final double delta;
+
+ public Dichotomy(double epsilon) {
+ this.epsilon = epsilon;
+ this.delta = epsilon / 2;
+ }
+
+ @Override
+ public Result calcAllIterations(DoubleUnaryOperator f, double a, double b) {
+ double x1, x2, e = (b - a) / 2;
+ List results = new ArrayList<>();
+ while (compare(e, epsilon)) {
+ x1 = (a + b - delta) / 2;
+ x2 = (a + b + delta) / 2;
+ double f1 = f.applyAsDouble(x1);
+ double f2 = f.applyAsDouble(x2);
+ results.add(new DefaultIterationResult(a, b, x1, x2, f1, f2));
+ if (compare(f2, f1)) {
+ b = x2;
+ } else {
+ a = x1;
+ }
+ e = (b - a) / 2;
+ }
+ return new Result<>((a + b) / 2, f.applyAsDouble((a + b) / 2), results);
+ }
+
+}
diff --git a/Lab2/src/methods/FastestDescent.java b/Lab2/src/methods/FastestDescent.java
new file mode 100644
index 0000000..347b16a
--- /dev/null
+++ b/Lab2/src/methods/FastestDescent.java
@@ -0,0 +1,39 @@
+package methods;
+
+import elements.MyFunction;
+import elements.Vector;
+import methods.Dichotomy;
+import methods.result.IterationResult;
+import methods.result.Result;
+
+import java.util.function.DoubleUnaryOperator;
+import java.util.function.UnaryOperator;
+
+
+public class FastestDescent {
+ private final double epsilon;
+
+ public FastestDescent(final double epsilon) {
+ this.epsilon = epsilon;
+ }
+
+ public void calc(final MyFunction function, Vector x) {
+ Vector gradientFX = function.applyGradient(x);
+ Double fx = null;
+ System.out.println("gradient abs: " + gradientFX.abs());
+ while (epsilon < gradientFX.abs()) {
+ Vector finalGradientFX = gradientFX;
+ Vector finalX = x;
+ DoubleUnaryOperator fAlpha = alpha -> function.applyFunction(finalX.subtract(finalGradientFX.multiply(alpha)));
+ Method extends IterationResult> method = new Dichotomy(epsilon);
+ Result extends IterationResult> result = method.calcAllIterations(fAlpha, 0, 100);
+ double alpha = result.getPoint();
+ x = x.subtract(gradientFX.multiply(alpha));
+ fx = function.applyFunction(x);
+ gradientFX = function.applyGradient(x);
+ System.out.println(String.format("%s val: %.10f", x, fx));
+ System.out.println("gradient abs: " + gradientFX.abs());
+ }
+ System.out.println(String.format("Result:\n%s val: %.10f", x, fx));
+ }
+}
diff --git a/Lab2/src/methods/GradientDescent.java b/Lab2/src/methods/GradientDescent.java
index 7c5fbef..95938e4 100644
--- a/Lab2/src/methods/GradientDescent.java
+++ b/Lab2/src/methods/GradientDescent.java
@@ -1,7 +1,7 @@
package methods;
-import elements.MyFunction;
import elements.Vector;
+import elements.MyFunction;
public class GradientDescent {
private final double epsilon;
@@ -30,7 +30,6 @@ public void calc(final MyFunction function, Vector x) {
System.out.println(String.format("%s val: %.10f", x, fx));
System.out.println("gradient abs: " + gradientFX.abs());
}
-
System.out.println(String.format("Result:\n%s val: %.10f", x, fx));
}
}
diff --git a/Lab2/src/methods/Method.java b/Lab2/src/methods/Method.java
new file mode 100644
index 0000000..326e945
--- /dev/null
+++ b/Lab2/src/methods/Method.java
@@ -0,0 +1,15 @@
+package methods;
+
+import methods.result.IterationResult;
+import methods.result.Result;
+
+import java.util.function.DoubleUnaryOperator;
+
+public interface Method {
+
+ Result calcAllIterations(DoubleUnaryOperator f, double a, double b);
+
+ default boolean compare(double x, double y) {
+ return x - y >= 0;
+ }
+}
diff --git a/Lab2/src/methods/result/DefaultIterationResult.java b/Lab2/src/methods/result/DefaultIterationResult.java
new file mode 100644
index 0000000..cdfb5d9
--- /dev/null
+++ b/Lab2/src/methods/result/DefaultIterationResult.java
@@ -0,0 +1,69 @@
+package methods.result;
+
+public class DefaultIterationResult implements IterationResult {
+ private final double a;
+ private final double b;
+ private final double x1;
+ private final double x2;
+
+ private final double fx1;
+ private final double fx2;
+
+ public DefaultIterationResult(double a, double b, double x1, double x2, double fx1, double fx2) {
+ this.a = a;
+ this.b = b;
+ this.x1 = x1;
+ this.x2 = x2;
+ this.fx1 = fx1;
+ this.fx2 = fx2;
+ }
+
+ public double getA() {
+ return a;
+ }
+
+ public double getB() {
+ return b;
+ }
+
+ public double getX1() {
+ return x1;
+ }
+
+ public double getX2() {
+ return x2;
+ }
+
+ public double getFx1() {
+ return fx1;
+ }
+
+ public double getFx2() {
+ return fx2;
+ }
+
+ public String tableArgs() {
+ return "A & B & X1 & X2 & F(X1) & F(X2) & B - A";
+ }
+
+ public String asTable() {
+ return String.format("%.7f & %.7f & %.7f & %.7f & %.7f & %.7f & %.7f",
+ getA(),
+ getB(),
+ getX1(),
+ getX2(),
+ getFx1(),
+ getFx2(),
+ getB() - getA());
+ }
+
+ public String toString() {
+ return String.format("%.16f %.16f %.16f %.16f %.16f %.16f",
+ getA(),
+ getB(),
+ getX1(),
+ getX2(),
+ getFx1(),
+ getFx2());
+ }
+}
diff --git a/Lab2/src/methods/result/IterationResult.java b/Lab2/src/methods/result/IterationResult.java
new file mode 100644
index 0000000..0dcc033
--- /dev/null
+++ b/Lab2/src/methods/result/IterationResult.java
@@ -0,0 +1,6 @@
+package methods.result;
+
+public interface IterationResult {
+ String asTable();
+ String tableArgs();
+}
diff --git a/Lab2/src/methods/result/ParabolaIterationResult.java b/Lab2/src/methods/result/ParabolaIterationResult.java
new file mode 100644
index 0000000..599587b
--- /dev/null
+++ b/Lab2/src/methods/result/ParabolaIterationResult.java
@@ -0,0 +1,90 @@
+package methods.result;
+
+
+public class ParabolaIterationResult implements IterationResult {
+ private final double x1;
+ private final double x2;
+ private final double x3;
+
+ private final double fx1;
+ private final double fx2;
+ private final double fx3;
+
+ private final double minX;
+ private final double fMinX;
+
+ public ParabolaIterationResult(double x1, double x2, double x3, double minX,
+ double fx1, double fx2, double fx3, double fMinX) {
+ this.x1 = x1;
+ this.x2 = x2;
+ this.x3 = x3;
+ this.fx1 = fx1;
+ this.fx2 = fx2;
+ this.fx3 = fx3;
+ this.minX = minX;
+ this.fMinX = fMinX;
+ }
+
+ public double getX1() {
+ return x1;
+ }
+
+ public double getX2() {
+ return x2;
+ }
+
+ public double getX3() {
+ return x3;
+ }
+
+ public double getFx1() {
+ return fx1;
+ }
+
+ public double getFx2() {
+ return fx2;
+ }
+
+ public double getFx3() {
+ return fx3;
+ }
+
+ public double getMinX() {
+ return minX;
+ }
+
+ public double getfMinX() {
+ return fMinX;
+ }
+
+ public String tableArgs() {
+ return "X1 & X2 & X3 & F(X1) & F(X2) & F(X3) & Minimal X & F(Minimal) & X3 - X1";
+ }
+
+ public String asTable() {
+ return String.format("%.7f & %.7f & %.7f & %.7f & %.7f & %.7f & %.7f & %.7f & %.7f",
+ getX1(),
+ getX2(),
+ getX3(),
+ getFx1(),
+ getFx2(),
+ getFx3(),
+ getMinX(),
+ getfMinX(),
+ getX3() - getX1()
+ );
+ }
+
+ public String toString() {
+ return String.format("%.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f",
+ getX1(),
+ getX2(),
+ getX3(),
+ getFx1(),
+ getFx2(),
+ getFx3(),
+ getMinX(),
+ getfMinX()
+ );
+ }
+}
\ No newline at end of file
diff --git a/Lab2/src/methods/result/Result.java b/Lab2/src/methods/result/Result.java
new file mode 100644
index 0000000..c77feec
--- /dev/null
+++ b/Lab2/src/methods/result/Result.java
@@ -0,0 +1,60 @@
+package methods.result;
+
+
+import java.util.List;
+
+public class Result {
+ private final double point;
+
+ private final double value;
+
+ private final List iterations;
+
+ public Result(double ans, double value, List iterations) {
+ this.point = ans;
+ this.value = value;
+ this.iterations = iterations;
+ }
+
+ public double getPoint() {
+ return point;
+ }
+
+ public double getValue() {
+ return value;
+ }
+
+ public List getIterations() {
+ return iterations;
+ }
+
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(
+ String.format("Результат: точка: [ %.10f ], value [ %.10f ]\nКоличество итераций: %d\n",
+ getPoint(),
+ getValue(),
+ getIterations().size())
+ );
+ for (IterationResult result : getIterations()) {
+ stringBuilder.append(result.asTable()).append('\n');
+ }
+ return stringBuilder.toString();
+ }
+ public String asTable() {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append(
+ String.format("Результат: точка: [ %.10f ], value [ %.10f ]\nКоличество итераций: %d\n",
+ getPoint(),
+ getValue(),
+ getIterations().size())
+ ).append("\\begin{tabular}[b]{| l | l | l | l | l | l | l | l | l |}")
+ .append("\\hline\n").append(getIterations().get(0).tableArgs()).append("\\\\\\hline\n");
+
+ for (IterationResult result : getIterations()) {
+ stringBuilder.append(result.asTable()).append("\\\\\n");
+ }
+ stringBuilder.append("\\hline\n\\end{tabular}");
+ return stringBuilder.toString();
+ }
+}