Package org.jquantlib.math.interpolations

Source Code of org.jquantlib.math.interpolations.AbstractInterpolation$LogInterpolationImpl

/*
Copyright (C) 2008 Richard Gomes

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
<jquant-devel@lists.sourceforge.net>. The license is also available online at
<http://www.jquantlib.org/index.php/LICENSE.TXT>.

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.
*/

/*
Copyright (C) 2002, 2003 Ferdinando Ametrano
Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
Copyright (C) 2003, 2004, 2005, 2006 StatPro Italia srl

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

QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license.  You should have received a
copy of the license along with this program; if not, please email
<quantlib-dev@lists.sf.net>. The license is also available online at
<http://quantlib.org/license.shtml>.

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.
*/

package org.jquantlib.math.interpolations;

import static org.jquantlib.math.Closeness.isClose;

import org.jquantlib.QL;
import org.jquantlib.Settings;
import org.jquantlib.math.matrixutilities.Array;


/** Abstract base class for 1-D interpolations.
* <p>
* Classes derived from this class will provide interpolated
* values from two sequences of equal length, representing
* discretized values of a variable and a function of the former,
* respectively.
*
* @author Richard Gomes
*/
public abstract class AbstractInterpolation implements Interpolation {

    protected Impl impl;

    @Override
    public boolean empty() /* @ReadOnly */ { return impl==null; }

    @Override
    public /*@Real*/ double op(final /*@Real*/ double x) /* @ReadOnly */ {
        return op(x, false);
    }
    @Override
    public /*@Real*/ double op(final /*@Real*/ double x, final boolean allowExtrapolation) /* @ReadOnly */ {
        checkRange(x, allowExtrapolation);
        return impl.op(x);
    }

    @Override
    public /*@Real*/ double primitive(final /*@Real*/ double x) /* @ReadOnly */ {
        return primitive(x, false);
    }
    @Override
    public /*@Real*/ double primitive(final /*@Real*/ double x, final boolean allowExtrapolation) /* @ReadOnly */ {
        checkRange(x, allowExtrapolation);
        return impl.primitive(x);
    }

    @Override
    public /*@Real*/ double derivative(final /*@Real*/ double x) /* @ReadOnly */ {
        return derivative(x, false);
    }
    @Override
    public /*@Real*/ double derivative(final /*@Real*/ double x, final boolean allowExtrapolation) /* @ReadOnly */ {
        checkRange(x, allowExtrapolation);
        return impl.derivative(x);
    }

    @Override
    public /*@Real*/ double secondDerivative(final /*@Real*/ double x) /* @ReadOnly */ {
        return secondDerivative(x, false);
    }
    @Override
    public /*@Real*/ double secondDerivative(final /*@Real*/ double x, final boolean allowExtrapolation) /* @ReadOnly */ {
        checkRange(x, allowExtrapolation);
        return impl.secondDerivative(x);
    }

    @Override
    public /*@Real*/ double xMin() /* @ReadOnly */ {
        return impl.xMin();
    }

    @Override
    public /*@Real*/ double xMax() /* @ReadOnly */ {
        return impl.xMax();
    }

    @Override
    public boolean isInRange(final /*@Real*/ double x) /* @ReadOnly */ {
        return impl.isInRange(x);
    }

    @Override
    public void update() {
        impl.update();
    }


    //
    // protected methods
    //

    /**
     * This method verifies if
     * <li> extrapolation is enabled;</li>
     * <li> requested <i>x</i> is valid</li>
     *
     * @param x
     * @param extrapolate
     *
     * @throws IllegalStateException if extrapolation is not enabled.
     * @throws IllegalArgumentException if <i>x</i> is out of range
     */
    protected final void checkRange(final double x, final boolean extrapolate) /* @ReadOnly */ {
        if (! (extrapolate || allowsExtrapolation() || impl.isInRange(x)) ) {
            final StringBuilder sb = new StringBuilder();
            sb.append("interpolation range is [");
            sb.append(xMin()).append(", ").append(xMax());
            sb.append("]: extrapolation at ");
            sb.append(x);
            sb.append(" not allowed");
            throw new IllegalArgumentException(sb.toString());
        }
    }


    //
    // implements Extrapolator
    //

    /**
     * Implements multiple inheritance via delegate pattern to an inner class
     *
     * @see Extrapolator
     */
    private final DefaultExtrapolator delegatedExtrapolator = new DefaultExtrapolator();

    @Override
    public final boolean allowsExtrapolation() {
        return delegatedExtrapolator.allowsExtrapolation();
    }

    @Override
    public void disableExtrapolation() {
        delegatedExtrapolator.disableExtrapolation();
    }

    @Override
    public void enableExtrapolation() {
        delegatedExtrapolator.enableExtrapolation();
    }


    //
    // protected inner classes
    //

    protected abstract class Impl {

        /**
         * @note Derived classes are responsible for initializing <i>vx</i> and <i>vy</i>
         */
        protected Array vx;

        /**
         * @note Derived classes are responsible for initializing <i>vx</i> and <i>vy</i>
         */
        protected Array vy;


        protected Impl(final Array vx, final Array vy) {
            this.vx = vx; // TODO: clone?
            this.vy = vy; // TODO: clone?

            QL.require(vx.size() >= 2 , "not enough points to interpolate"); // TODO: message
            QL.require(extraSafetyChecks(), "unsorted values on array X");   // TODO: message
        }

        //
        // final public methods
        //

        public final double xMin() /* @ReadOnly */ {
            return  vx.first();
        }

        public final double xMax() /* @ReadOnly */ {
            return vx.last();
        }

        public final boolean isInRange(final double x) {
            QL.require(extraSafetyChecks(), "unsorted values on array X"); // TODO: message
            final double x1 = xMin(), x2 = xMax();
            return (x >= x1 && x <= x2) || isClose(x,x1) || isClose(x,x2);
        }

        public final double op(final double x, final boolean allowExtrapolation) {
            checkRange(x, allowExtrapolation);
            return op(x);
        }

        public final double primitive(final double x, final boolean allowExtrapolation) {
            checkRange(x, allowExtrapolation);
            return primitive(x);
        }

        public final double derivative(final double x, final boolean allowExtrapolation) {
            checkRange(x, allowExtrapolation);
            return derivative(x);
        }

        public final double secondDerivative(final double x, final boolean allowExtrapolation) {
            checkRange(x, allowExtrapolation);
            return secondDerivative(x);
        }


        //
        // virtual public methods
        //

        public abstract void update();
        public abstract double op(final double x) /* @ReadOnly */;
        public abstract double primitive(final double x) /* @ReadOnly */;
        public abstract double derivative(final double x) /* @ReadOnly */;
        public abstract double secondDerivative(final double x) /* @ReadOnly */;


        //
        // protected methods
        //

        protected int locate(final double x) /* @ReadOnly */ {
            QL.require(extraSafetyChecks(), "unsorted values on array X"); // TODO: message
            if (x < vx.first())
                return 0;
            else if (x > vx.last())
                return vx.size()-2;
            else {
                //return vx.upperBound(x)-1;
                final int ub = vx.upperBound(vx.begin(), vx.end()-1, x)-1;
                return ub;
            }
        }


        //
        // private methods
        //

        private boolean extraSafetyChecks() {
            if (new Settings().isExtraSafetyChecks()) {
                for (int i=0; i<vx.size()-1; i++) {
                    if (vx.get(i) > vx.get(i+1))
                        return false;
                }
            }
            return true;
        }

    }


    protected class LogInterpolationImpl extends Impl {

        private final Array logY_;
        private final Interpolation interpolation_;

        public LogInterpolationImpl(final Array vx, final Array vy, final Interpolation.Interpolator factory) {
            super(vx, vy);
            this.logY_ = new Array(vx.size());
            this.interpolation_ = factory.interpolate(vx, logY_);
        }

        @Override
        public void update() {
            for (int i=0; i<logY_.size(); i++) {
                QL.require(vy.get(i)>0.0, "invalid value"); // TODO: message
                logY_.set(i, Math.log(vx.get(i)));
            }
            interpolation_.update();
        }

        @Override
        public double op(final double x) /* @ReadOnly */ {
            return Math.exp(interpolation_.op(x, true));
        }

        @Override
        public double primitive(final double x) /* @ReadOnly */ {
            throw new UnsupportedOperationException("LogInterpolation primitive not implemented"); // TODO: message
        }

        @Override
        public double derivative(final double x) /* @ReadOnly */ {
            return op(x)*interpolation_.derivative(x, true);
        }

        @Override
        public double secondDerivative(final double x) /* @ReadOnly */ {
            return derivative(x)*interpolation_.derivative(x, true) + op(x)*interpolation_.secondDerivative(x, true);
        }
    }

}
TOP

Related Classes of org.jquantlib.math.interpolations.AbstractInterpolation$LogInterpolationImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
google.gwt.user.client.Element">com.google.gwt.user.client.Element
  • com.google.gwt.user.client.ui.MultiWordSuggestOracle
  • com.hp.hpl.jena.datatypes.xsd.XSDDateTime
  • TOP
    Copyright © 2018 www.massapi.com. All rights reserved.
    All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.