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  package org.hipparchus.optim.nonlinear.vector.leastsquares;
23  
24  import java.util.ArrayList;
25  
26  import org.hipparchus.analysis.MultivariateMatrixFunction;
27  import org.hipparchus.analysis.MultivariateVectorFunction;
28  import org.hipparchus.geometry.euclidean.twod.Vector2D;
29  
30  /**
31   * Class used in the tests.
32   */
33  class CircleVectorial {
34      private ArrayList<Vector2D> points;
35  
36      public CircleVectorial() {
37          points  = new ArrayList<Vector2D>();
38      }
39  
40      public void addPoint(double px, double py) {
41          points.add(new Vector2D(px, py));
42      }
43  
44      public int getN() {
45          return points.size();
46      }
47  
48      public double getRadius(Vector2D center) {
49          double r = 0;
50          for (Vector2D point : points) {
51              r += point.distance(center);
52          }
53          return r / points.size();
54      }
55  
56      public MultivariateVectorFunction getModelFunction() {
57          return new MultivariateVectorFunction() {
58              public double[] value(double[] params) {
59                  Vector2D center = new Vector2D(params[0], params[1]);
60                  double radius = getRadius(center);
61                  double[] residuals = new double[points.size()];
62                  for (int i = 0; i < residuals.length; i++) {
63                      residuals[i] = points.get(i).distance(center) - radius;
64                  }
65  
66                  return residuals;
67              }
68          };
69      }
70  
71      public MultivariateMatrixFunction getModelFunctionJacobian() {
72          return new MultivariateMatrixFunction() {
73              public double[][] value(double[] params) {
74                  final int n = points.size();
75                  final Vector2D center = new Vector2D(params[0], params[1]);
76  
77                  double dRdX = 0;
78                  double dRdY = 0;
79                  for (Vector2D pk : points) {
80                      double dk = pk.distance(center);
81                      dRdX += (center.getX() - pk.getX()) / dk;
82                      dRdY += (center.getY() - pk.getY()) / dk;
83                  }
84                  dRdX /= n;
85                  dRdY /= n;
86  
87                  // Jacobian of the radius residuals.
88                  double[][] jacobian = new double[n][2];
89                  for (int i = 0; i < n; i++) {
90                      final Vector2D pi = points.get(i);
91                      final double di = pi.distance(center);
92                      jacobian[i][0] = (center.getX() - pi.getX()) / di - dRdX;
93                      jacobian[i][1] = (center.getY() - pi.getY()) / di - dRdY;
94                  }
95  
96                  return jacobian;
97              }
98          };
99      }
100 }