/** * Return gradient term of quadratic. This instance will be in the vector space of the * perturbModel, if provided. Otherwise, uses an instance of the referenceModel. * * @return Value of <code> b = -F' N [data - f(m)] + Mm </code> if dampOnlyPerturbation is false, * and <code> b = -F' N [data - f(m)] </code> if dampOnlyPerturbation is true. */ public Vect getB() { Vect data = VectUtil.cloneZero(_data); // data is data with zeros _transform.forwardNonlinear(data, _referenceModel); // data is f(m) data.add(1., -1., _data); // data is -e = -(d - f(m)) _transform.adjustRobustErrors(data); // (remove outliers from e) data.multiplyInverseCovariance(); // data is -Ne Vect b = null; if (_dampOnlyPerturbation) { if (_perturbModel != null) { b = VectUtil.cloneZero(_perturbModel); // b is 0 } else { b = VectUtil.cloneZero(_referenceModel); // b is 0 } } else { if (_perturbModel != null) { b = _perturbModel.clone(); b.project(0., 1., _referenceModel); // b is m } else { b = _referenceModel.clone(); // b is m } b.multiplyInverseCovariance(); // b is M m } _transform.addTranspose(data, b, _referenceModel); // b is -F'Ne [+ Mm] data.dispose(); return b; }
/** * Evaluate the full objective function without approximation. Provide a model in the vector space * of the referenceModel. perturbModel is unused. Useful for line-search of best scale factor. If * dampedPerturbation, evaluates * * <pre> * [f(m)-data]'N[f(m)-data] + (m-m0)'M(m-m0) * </pre> * * where m0 is the reference model. Otherwise evaluates * * <pre> * [f(m)-data]'N[f(m)-data] + m'M m * </pre> * * @param m Model to be evaluated. * @return Value of objective function. */ public double evalFullObjectiveFunction(VectConst m) { Vect data = VectUtil.cloneZero(_data); // data is zeros Vect model = m.clone(); // model is m model.constrain(); // may have been done already _transform.forwardNonlinear(data, model); // data is f(m) data.add(1., -1., _data); // data is e = f(m) - data _transform.adjustRobustErrors(data); double eNe = data.magnitude(); // eNe is e'Ne checkNaN(eNe); data.dispose(); // damp perturbation if requested if (_dampOnlyPerturbation) { model.add(1., -1., _referenceModel); // model is (m-m0) } double mMm = model.magnitude(); // mMm is (m-m0)'M(m-m0) checkNaN(mMm); model.dispose(); return (eNe + mMm); }