/*
Copyright (C) 2009 Ueli Hofstetter

This source code is release under the BSD License.

This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/

JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license.  You should have received a
copy of the license along with this program; if not, please email
. The license is also available online at
.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.

JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
 */

package org.jquantlib.model;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.jquantlib.QL;
import org.jquantlib.lang.annotation.QualityAssurance;
import org.jquantlib.lang.annotation.QualityAssurance.Quality;
import org.jquantlib.lang.annotation.QualityAssurance.Version;
import org.jquantlib.math.matrixutilities.Array;
import org.jquantlib.math.optimization.CompositeConstraint;
import org.jquantlib.math.optimization.Constraint;
import org.jquantlib.math.optimization.CostFunction;
import org.jquantlib.math.optimization.EndCriteria;
import org.jquantlib.math.optimization.OptimizationMethod;
import org.jquantlib.math.optimization.Problem;
import org.jquantlib.util.DefaultObservable;
import org.jquantlib.util.Observable;
import org.jquantlib.util.Observer;


/**
 * Calibrated model class
 *
 * @author Ueli Hofstetter
 */
@QualityAssurance(quality=Quality.Q3_DOCUMENTATION, version=Version.V097, reviewers="Richard Gomes")
public abstract class CalibratedModel implements Observer, Observable {

    private static final String parameter_array_to_small = "parameter array to small";
    private static final String parameter_array_to_big = "parameter array to big";


    //
    // protected fields
    //

    protected List< Parameter > arguments_;
    protected Constraint constraint_;
    protected EndCriteria.Type shortRateEndCriteria_;


    //
    // public methods
    //

    public CalibratedModel(final int nArguments) {
        if (System.getProperty("EXPERIMENTAL") == null)
            throw new UnsupportedOperationException("Work in progress");
        this.arguments_ = new ArrayList(nArguments);
        this.constraint_ = new PrivateConstraint(arguments_);
        this.shortRateEndCriteria_ = EndCriteria.Type.None;
    }

    /**
     * 

Calibrate to a set of market instruments (caps/swaptions).

*

An additional constraint can be passed which must be satisfied in addition to the constraints of the model.

*/ public void calibrate( final List instruments, final OptimizationMethod method, final EndCriteria endCriteria, final Constraint additionalConstraint, final double[] weights) { QL.require(weights==null || weights.length == instruments.size(), "mismatch between number of instruments and weights"); // TODO: message Constraint c; if (additionalConstraint.empty()) { c = constraint_; } else { c = new CompositeConstraint(constraint_, additionalConstraint); } final double[] w = new double[instruments.size()]; if (weights==null) { Arrays.fill(w, 1.0); } else { System.arraycopy(weights, 0, w, 0, w.length); } final CalibrationFunction f = new CalibrationFunction(this, instruments, w); final Problem prob = new Problem(f, c, params()); shortRateEndCriteria_ = method.minimize(prob, endCriteria); final Array result = new Array(prob.currentValue()); setParams(result); final Array shortRateProblemValues_ = prob.values(result); notifyObservers(); } public double value(final Array params, final List instruments) { final double[] w = new double[instruments.size()]; Arrays.fill(w, 1.0); final CalibrationFunction f = new CalibrationFunction(this, instruments, w); return f.value(params); } public final Constraint constraint() /* @ReadOnly */ { return this.constraint_; } /** *

returns end criteria result

*/ public EndCriteria.Type endCriteria() { return this.shortRateEndCriteria_; } /** *

Returns array of arguments on which calibration is done.

*/ public Array params() /* @ReadOnly */ { int size = 0; for (int i=0; i * An instance of Observer does not call this method directly: instead, it will be called by * the observables the instance registered with when they need to notify any changes. */ @Override public void update(){ generateArguments(); notifyObservers(); } // // implements Observable // private final DefaultObservable delegatedObservable = new DefaultObservable(this); @Override public void addObserver(final org.jquantlib.util.Observer observer) { delegatedObservable.addObserver(observer); } @Override public int countObservers() { return delegatedObservable.countObservers(); } @Override public void deleteObserver(final org.jquantlib.util.Observer observer) { delegatedObservable.deleteObserver(observer); } @Override public void deleteObservers() { delegatedObservable.deleteObservers(); } @Override public List getObservers() { return delegatedObservable.getObservers(); } @Override public void notifyObservers() { delegatedObservable.notifyObservers(); } @Override public void notifyObservers(final Object arg) { delegatedObservable.notifyObservers(arg); } // // private inner classes // private final class CalibrationFunction extends CostFunction { private final CalibratedModel model; private final List instruments; private final double[] weights; public CalibrationFunction( final CalibratedModel model, final List instruments, final double[] weights){ this.model = model; this.instruments = instruments; this.weights = weights.clone(); } @Override public double value(final Array params) /* @ReadOnly */ { model.setParams(params); double value = 0.0; for (int i=0; imethod to overload to compute the cost function values in x

*/ @Override public Array values(final Array params) /* @ReadOnly */ { model.setParams(params); final Array values = new Array(instruments.size()); for (int i=0; i arguments) { super.impl = new Impl(arguments); } // // private inner classes // /** * Base class for constraint implementations. */ private class Impl extends Constraint.Impl { // // private fields // private final List arguments; // // private constructors // private Impl(final List arguments) { this.arguments = arguments; } // // public abstract methods // /** * Tests if params satisfy the constraint. */ @Override public boolean test(final Array params) /* @ReadOnly */ { int k = 0; for (int i = 0; i < arguments_.size(); i++) { final int size = arguments_.get(i).size(); final Array testParams = new Array(size); for (int j = 0; j < size; j++, k++) { testParams.set(j, params.get(k)); } if (!arguments_.get(i).testParams(testParams)) return false; } return true; } } } }

Ads help maintain this website.