/*
 Copyright (C) 2007 Dominik Holenstein

 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.testsuite.math.distributions;

// import static org.junit.Assert.assertEquals; --> not JUnit 4.4 conform

import static org.junit.Assert.fail;

import org.jquantlib.QL;
import org.jquantlib.Settings;
import org.jquantlib.math.distributions.InverseCumulativeNormal;
import org.junit.Test;

/**
 * @author Dominik Holenstein
 */

public class InverseCumulativeNormalTest {

    public InverseCumulativeNormalTest() {
        QL.info("::::: "+this.getClass().getSimpleName()+" :::::");
    }

    @Test
    public void testInverseCumulativeNormal(){
        QL.info("Running new test");

        //normal values generated by quantlib - digits down to 1e-16
        final double[][] normal_testvalues = {
                {0.01,-2.3263478743880279},
                {0.1, -1.2815515641401563},
                {0.2, -0.84162123272661848},
                {0.3, -0.52440051327929527},
                {0.4, -0.25334710285999862},
                {0.5, 0.00000000000000000},
                {0.6, 0.25334710285999862},
                {0.7, 0.52440051327929516},
                {0.8, 0.84162123272661860},
                {0.9, 1.2815515641401563},
                {0.99, 2.3263478743880279}};

        //high precision values generated by quantlib using halleys method - digits down to 1e-16
        final double[][] precision_testvalues = {
                {0.01,-2.3263478740408416},
                {0.1, -1.2815515655446004},
                {0.2, -0.84162123357291430},
                {0.3, -0.52440051270804078},
                {0.4, -0.25334710313579978},
                {0.5, 0.00000000000000000},
                {0.6, 0.25334710313579961},
                {0.7, 0.52440051270804056},
                {0.8, 0.84162123357291441},
                {0.9, 1.2815515655446004},
                {0.99, 2.3263478740408412}};


        final Settings settings = new Settings();

        //FIXME: obtain original value :: this is a thread safety problem :(
        final boolean oldHighPrecision = settings.isRefineHighPrecisionUsingHalleysMethod();

        settings.setRefineHighPrecisionUsingHalleysMethod(false);
        InverseCumulativeNormal icn;

        //test the normal values
        icn = new InverseCumulativeNormal();
        for (final double[] normalTestvalue : normal_testvalues) {
            final double x_position = normalTestvalue[0];
            final double tolerance = 1.0e-15;//(Math.abs(x_position)<3.01) ? 1.0e-15: 1.0e-10;

            final double normal_expected = normalTestvalue[1];
            final double computed_normal = icn.op(x_position);
            if (Math.abs(normal_expected-computed_normal)>tolerance) {
                fail("x_position " + x_position + " normal_expected: " + normal_expected + " normal_computed: " + normal_expected);
            }
        }


        //test the normal values using high machine precision Halley's method
        settings.setRefineHighPrecisionUsingHalleysMethod(true);
        icn = new InverseCumulativeNormal();
        for (final double[] precisionTestvalue : precision_testvalues) {
            final double x_position = precisionTestvalue[0];
            final double tolerance = 1.0e-15;//(Math.abs(x_position)<3.01) ? 1.0e-15: 1.0e-10;

            final double precision_expected = precisionTestvalue[1];
            final double computed_precision = icn.op(x_position);

            if (Math.abs(precision_expected-computed_precision)>tolerance) {
                fail("x_position " + x_position + " precision_expected: " + precision_expected + " precision_computed: " + computed_precision);
            }
        }

        //FIXME: back to original value :: this is a thread safety problem :(
        settings.setRefineHighPrecisionUsingHalleysMethod(oldHighPrecision);
    }

}

 

Ads help maintain this website.