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