View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.optim.nonlinear.scalar.gradient;
24  
25  import java.util.ArrayList;
26  
27  import org.hipparchus.analysis.MultivariateFunction;
28  import org.hipparchus.analysis.MultivariateVectorFunction;
29  import org.hipparchus.geometry.euclidean.twod.Vector2D;
30  import org.hipparchus.optim.nonlinear.scalar.ObjectiveFunction;
31  import org.hipparchus.optim.nonlinear.scalar.ObjectiveFunctionGradient;
32  
33  /**
34   * Class used in the tests.
35   */
36  public class CircleScalar {
37      private ArrayList<Vector2D> points;
38  
39      public CircleScalar() {
40          points  = new ArrayList<Vector2D>();
41      }
42  
43      public void addPoint(double px, double py) {
44          points.add(new Vector2D(px, py));
45      }
46  
47      public double getRadius(Vector2D center) {
48          double r = 0;
49          for (Vector2D point : points) {
50              r += point.distance(center);
51          }
52          return r / points.size();
53      }
54  
55      public ObjectiveFunction getObjectiveFunction() {
56          return new ObjectiveFunction(new MultivariateFunction() {
57                  public double value(double[] params)  {
58                      Vector2D center = new Vector2D(params[0], params[1]);
59                      double radius = getRadius(center);
60                      double sum = 0;
61                      for (Vector2D point : points) {
62                          double di = point.distance(center) - radius;
63                          sum += di * di;
64                      }
65                      return sum;
66                  }
67              });
68      }
69  
70      public ObjectiveFunctionGradient getObjectiveFunctionGradient() {
71          return new ObjectiveFunctionGradient(new MultivariateVectorFunction() {
72                  public double[] value(double[] params) {
73                      Vector2D center = new Vector2D(params[0], params[1]);
74                      double radius = getRadius(center);
75                      // gradient of the sum of squared residuals
76                      double dJdX = 0;
77                      double dJdY = 0;
78                      for (Vector2D pk : points) {
79                          double dk = pk.distance(center);
80                          dJdX += (center.getX() - pk.getX()) * (dk - radius) / dk;
81                          dJdY += (center.getY() - pk.getY()) * (dk - radius) / dk;
82                      }
83                      dJdX *= 2;
84                      dJdY *= 2;
85  
86                      return new double[] { dJdX, dJdY };
87                  }
88              });
89      }
90  }