1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math4.legacy.optim.nonlinear.scalar.gradient;
19
20 import java.util.ArrayList;
21
22 import org.apache.commons.geometry.euclidean.twod.Vector2D;
23 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
24 import org.apache.commons.math4.legacy.analysis.MultivariateVectorFunction;
25 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.ObjectiveFunction;
26 import org.apache.commons.math4.legacy.optim.nonlinear.scalar.ObjectiveFunctionGradient;
27
28
29
30
31 public class CircleScalar {
32 private ArrayList<Vector2D> points;
33
34 public CircleScalar() {
35 points = new ArrayList<>();
36 }
37
38 public void addPoint(double px, double py) {
39 points.add(Vector2D.of(px, py));
40 }
41
42 public double getRadius(Vector2D center) {
43 double r = 0;
44 for (Vector2D point : points) {
45 r += point.distance(center);
46 }
47 return r / points.size();
48 }
49
50 public ObjectiveFunction getObjectiveFunction() {
51 return new ObjectiveFunction(new MultivariateFunction() {
52 @Override
53 public double value(double[] params) {
54 Vector2D center = Vector2D.of(params[0], params[1]);
55 double radius = getRadius(center);
56 double sum = 0;
57 for (Vector2D point : points) {
58 double di = point.distance(center) - radius;
59 sum += di * di;
60 }
61 return sum;
62 }
63 });
64 }
65
66 public ObjectiveFunctionGradient getObjectiveFunctionGradient() {
67 return new ObjectiveFunctionGradient(new MultivariateVectorFunction() {
68 @Override
69 public double[] value(double[] params) {
70 Vector2D center = Vector2D.of(params[0], params[1]);
71 double radius = getRadius(center);
72
73 double dJdX = 0;
74 double dJdY = 0;
75 for (Vector2D pk : points) {
76 double dk = pk.distance(center);
77 dJdX += (center.getX() - pk.getX()) * (dk - radius) / dk;
78 dJdY += (center.getY() - pk.getY()) * (dk - radius) / dk;
79 }
80 dJdX *= 2;
81 dJdY *= 2;
82
83 return new double[] { dJdX, dJdY };
84 }
85 });
86 }
87 }