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.analysis.UnivariateFunction; 25 import org.apache.commons.math3.stat.regression.SimpleRegression; 26 import org.apache.commons.math3.optim.nonlinear.vector.ModelFunction; 27 import org.apache.commons.math3.optim.nonlinear.vector.ModelFunctionJacobian; 28 29 /** 30 * Class that models a straight line defined as {@code y = a x + b}. 31 * The parameters of problem are: 32 * <ul> 33 * <li>{@code a}</li> 34 * <li>{@code b}</li> 35 * </ul> 36 * The model functions are: 37 * <ul> 38 * <li>for each pair (a, b), the y-coordinate of the line.</li> 39 * </ul> 40 */ 41 @Deprecated 42 class StraightLineProblem { 43 /** Cloud of points assumed to be fitted by a straight line. */ 44 private final ArrayList<double[]> points; 45 /** Error (on the y-coordinate of the points). */ 46 private final double sigma; 47 48 /** 49 * @param error Assumed error for the y-coordinate. 50 */ StraightLineProblem(double error)51 public StraightLineProblem(double error) { 52 points = new ArrayList<double[]>(); 53 sigma = error; 54 } 55 addPoint(double px, double py)56 public void addPoint(double px, double py) { 57 points.add(new double[] { px, py }); 58 } 59 60 /** 61 * @return the list of x-coordinates. 62 */ x()63 public double[] x() { 64 final double[] v = new double[points.size()]; 65 for (int i = 0; i < points.size(); i++) { 66 final double[] p = points.get(i); 67 v[i] = p[0]; // x-coordinate. 68 } 69 70 return v; 71 } 72 73 /** 74 * @return the list of y-coordinates. 75 */ y()76 public double[] y() { 77 final double[] v = new double[points.size()]; 78 for (int i = 0; i < points.size(); i++) { 79 final double[] p = points.get(i); 80 v[i] = p[1]; // y-coordinate. 81 } 82 83 return v; 84 } 85 target()86 public double[] target() { 87 return y(); 88 } 89 weight()90 public double[] weight() { 91 final double weight = 1 / (sigma * sigma); 92 final double[] w = new double[points.size()]; 93 for (int i = 0; i < points.size(); i++) { 94 w[i] = weight; 95 } 96 97 return w; 98 } 99 getModelFunction()100 public ModelFunction getModelFunction() { 101 return new ModelFunction(new MultivariateVectorFunction() { 102 public double[] value(double[] params) { 103 final Model line = new Model(params[0], params[1]); 104 105 final double[] model = new double[points.size()]; 106 for (int i = 0; i < points.size(); i++) { 107 final double[] p = points.get(i); 108 model[i] = line.value(p[0]); 109 } 110 111 return model; 112 } 113 }); 114 } 115 116 public ModelFunctionJacobian getModelFunctionJacobian() { 117 return new ModelFunctionJacobian(new MultivariateMatrixFunction() { 118 public double[][] value(double[] point) { 119 return jacobian(point); 120 } 121 }); 122 } 123 124 /** 125 * Directly solve the linear problem, using the {@link SimpleRegression} 126 * class. 127 */ 128 public double[] solve() { 129 final SimpleRegression regress = new SimpleRegression(true); 130 for (double[] d : points) { 131 regress.addData(d[0], d[1]); 132 } 133 134 final double[] result = { regress.getSlope(), regress.getIntercept() }; 135 return result; 136 } 137 138 private double[][] jacobian(double[] params) { 139 final double[][] jacobian = new double[points.size()][2]; 140 141 for (int i = 0; i < points.size(); i++) { 142 final double[] p = points.get(i); 143 // Partial derivative wrt "a". 144 jacobian[i][0] = p[0]; 145 // Partial derivative wrt "b". 146 jacobian[i][1] = 1; 147 } 148 149 return jacobian; 150 } 151 152 /** 153 * Linear function. 154 */ 155 public static class Model implements UnivariateFunction { 156 final double a; 157 final double b; 158 159 public Model(double a, 160 double b) { 161 this.a = a; 162 this.b = b; 163 } 164 165 public double value(double x) { 166 return a * x + b; 167 } 168 } 169 } 170