circle.addPoint(110, -20);
circle.addPoint(35, 15);
circle.addPoint(45, 97);
final double[] start = {98.680, 47.345};
Optimum optimum = optimizer.optimize(builder(circle).start(start).build());
Assert.assertTrue(optimum.getEvaluations() < 10);
double rms = optimum.getRMS();
Assert.assertEquals(1.768262623567235, FastMath.sqrt(circle.getN()) * rms, TOl);
Vector2D center = new Vector2D(optimum.getPoint().getEntry(0), optimum.getPoint().getEntry(1));
Assert.assertEquals(69.96016176931406, circle.getRadius(center), 1e-6);
Assert.assertEquals(96.07590211815305, center.getX(), 1e-6);
Assert.assertEquals(48.13516790438953, center.getY(), 1e-6);
double[][] cov = optimum.getCovariances(1e-14).getData();
Assert.assertEquals(1.839, cov[0][0], 0.001);
Assert.assertEquals(0.731, cov[0][1], 0.001);
Assert.assertEquals(cov[0][1], cov[1][0], 1e-14);
Assert.assertEquals(0.786, cov[1][1], 0.001);
// add perfect measurements and check formal errors are reduced
double r = circle.getRadius(center);
for (double d = 0; d < 2 * FastMath.PI; d += 0.01) {
circle.addPoint(center.getX() + r * FastMath.cos(d), center.getY() + r * FastMath.sin(d));
}
double[] weights = new double[circle.getN()];
Arrays.fill(weights, 2);
optimum = optimizer.optimize(
builder(circle).weight(new DiagonalMatrix(weights)).start(start).build());
cov = optimum.getCovariances(1e-14).getData();
Assert.assertEquals(0.0016, cov[0][0], 0.001);
Assert.assertEquals(3.2e-7, cov[0][1], 1e-9);
Assert.assertEquals(cov[0][1], cov[1][0], 1e-14);
Assert.assertEquals(0.0016, cov[1][1], 0.001);
}