001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.math4.fitting.leastsquares;
018
019import org.apache.commons.math4.analysis.MultivariateMatrixFunction;
020import org.apache.commons.math4.analysis.MultivariateVectorFunction;
021import org.apache.commons.math4.fitting.leastsquares.LeastSquaresProblem.Evaluation;
022import org.apache.commons.math4.linear.ArrayRealVector;
023import org.apache.commons.math4.linear.RealMatrix;
024import org.apache.commons.math4.linear.RealVector;
025import org.apache.commons.math4.optim.ConvergenceChecker;
026import org.apache.commons.math4.optim.PointVectorValuePair;
027
028/**
029 * A mutable builder for {@link LeastSquaresProblem}s.
030 *
031 * @see LeastSquaresFactory
032 * @since 3.3
033 */
034public class LeastSquaresBuilder {
035
036    /** max evaluations */
037    private int maxEvaluations;
038    /** max iterations */
039    private int maxIterations;
040    /** convergence checker */
041    private ConvergenceChecker<Evaluation> checker;
042    /** model function */
043    private MultivariateJacobianFunction model;
044    /** observed values */
045    private RealVector target;
046    /** initial guess */
047    private RealVector start;
048    /** weight matrix */
049    private RealMatrix weight;
050    /**
051     * Lazy evaluation.
052     *
053     * @since 3.4
054     */
055    private boolean lazyEvaluation;
056    /** Validator.
057     *
058     * @since 3.4
059     */
060    private ParameterValidator paramValidator;
061
062
063    /**
064     * Construct a {@link LeastSquaresProblem} from the data in this builder.
065     *
066     * @return a new {@link LeastSquaresProblem}.
067     */
068    public LeastSquaresProblem build() {
069        return LeastSquaresFactory.create(model,
070                                          target,
071                                          start,
072                                          weight,
073                                          checker,
074                                          maxEvaluations,
075                                          maxIterations,
076                                          lazyEvaluation,
077                                          paramValidator);
078    }
079
080    /**
081     * Configure the max evaluations.
082     *
083     * @param newMaxEvaluations the maximum number of evaluations permitted.
084     * @return this
085     */
086    public LeastSquaresBuilder maxEvaluations(final int newMaxEvaluations) {
087        this.maxEvaluations = newMaxEvaluations;
088        return this;
089    }
090
091    /**
092     * Configure the max iterations.
093     *
094     * @param newMaxIterations the maximum number of iterations permitted.
095     * @return this
096     */
097    public LeastSquaresBuilder maxIterations(final int newMaxIterations) {
098        this.maxIterations = newMaxIterations;
099        return this;
100    }
101
102    /**
103     * Configure the convergence checker.
104     *
105     * @param newChecker the convergence checker.
106     * @return this
107     */
108    public LeastSquaresBuilder checker(final ConvergenceChecker<Evaluation> newChecker) {
109        this.checker = newChecker;
110        return this;
111    }
112
113    /**
114     * Configure the convergence checker.
115     * <p>
116     * This function is an overloaded version of {@link #checker(ConvergenceChecker)}.
117     *
118     * @param newChecker the convergence checker.
119     * @return this
120     */
121    public LeastSquaresBuilder checkerPair(final ConvergenceChecker<PointVectorValuePair> newChecker) {
122        return this.checker(LeastSquaresFactory.evaluationChecker(newChecker));
123    }
124
125    /**
126     * Configure the model function.
127     *
128     * @param value the model function value
129     * @param jacobian the Jacobian of {@code value}
130     * @return this
131     */
132    public LeastSquaresBuilder model(final MultivariateVectorFunction value,
133                                     final MultivariateMatrixFunction jacobian) {
134        return model(LeastSquaresFactory.model(value, jacobian));
135    }
136
137    /**
138     * Configure the model function.
139     *
140     * @param newModel the model function value and Jacobian
141     * @return this
142     */
143    public LeastSquaresBuilder model(final MultivariateJacobianFunction newModel) {
144        this.model = newModel;
145        return this;
146    }
147
148    /**
149     * Configure the observed data.
150     *
151     * @param newTarget the observed data.
152     * @return this
153     */
154    public LeastSquaresBuilder target(final RealVector newTarget) {
155        this.target = newTarget;
156        return this;
157    }
158
159    /**
160     * Configure the observed data.
161     *
162     * @param newTarget the observed data.
163     * @return this
164     */
165    public LeastSquaresBuilder target(final double[] newTarget) {
166        return target(new ArrayRealVector(newTarget, false));
167    }
168
169    /**
170     * Configure the initial guess.
171     *
172     * @param newStart the initial guess.
173     * @return this
174     */
175    public LeastSquaresBuilder start(final RealVector newStart) {
176        this.start = newStart;
177        return this;
178    }
179
180    /**
181     * Configure the initial guess.
182     *
183     * @param newStart the initial guess.
184     * @return this
185     */
186    public LeastSquaresBuilder start(final double[] newStart) {
187        return start(new ArrayRealVector(newStart, false));
188    }
189
190    /**
191     * Configure the weight matrix.
192     *
193     * @param newWeight the weight matrix
194     * @return this
195     */
196    public LeastSquaresBuilder weight(final RealMatrix newWeight) {
197        this.weight = newWeight;
198        return this;
199    }
200
201    /**
202     * Configure whether evaluation will be lazy or not.
203     *
204     * @param newValue Whether to perform lazy evaluation.
205     * @return this object.
206     *
207     * @since 3.4
208     */
209    public LeastSquaresBuilder lazyEvaluation(final boolean newValue) {
210        lazyEvaluation = newValue;
211        return this;
212    }
213
214    /**
215     * Configure the validator of the model parameters.
216     *
217     * @param newValidator Parameter validator.
218     * @return this object.
219     *
220     * @since 3.4
221     */
222    public LeastSquaresBuilder parameterValidator(final ParameterValidator newValidator) {
223        paramValidator = newValidator;
224        return this;
225    }
226}