com.itemanalysis.psychometrics.irt.estimation.ItemParamPriorLogNormal.java Source code

Java tutorial

Introduction

Here is the source code for com.itemanalysis.psychometrics.irt.estimation.ItemParamPriorLogNormal.java

Source

/**
 * Copyright 2014 J. Patrick Meyer
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.itemanalysis.psychometrics.irt.estimation;

import org.apache.commons.math3.util.Precision;

/**
 * Implementation of an ItemParamPrior for the LogNormal distribution. This class is a translation
 * of ItemParamPriorLogNormal.cpp in Brad Hanson's ETIRM library, Copyright (c) 2000, Bradley A. Hanson.
 */
public class ItemParamPriorLogNormal implements ItemParamPrior {

    private double[] parameters = null;
    private double variance = 0.0;

    /**
     * Constructor for the standard lognormal distribution
     */
    public ItemParamPriorLogNormal() {
        this(0.0, 1.0);
    }

    /**
     * Constructor takes an array as the input parameters. The first element is the mean and
     * the second element is the standard deviation.
     * @param param
     */
    public ItemParamPriorLogNormal(double[] param) {
        this.parameters = param;
        variance = param[1] * param[1];
    }

    /**
     * Returns true if density at p is zero
     * @param p
     * @return
     */
    public boolean zeroDensity(double p) {
        return (p <= 0.0) ? true : false;
    }

    /**
     * If density of x is zero (x <= 0) then return small slightly greater than zero that has a non-zero density
     * @param x
     * @return
     */
    public double nearestNonZero(double x) {
        return (x <= 0.0) ? Precision.EPSILON : x;
    }

    /**
     * Constructor taking teh mean and standard deviation as arguments.
     * @param mean
     * @param sd
     */
    public ItemParamPriorLogNormal(double mean, double sd) {
        if (sd <= 0.0)
            throw new IllegalArgumentException("Negative sd not allowed in ItemParamPriorLogNormal");
        parameters = new double[2];
        parameters[0] = mean;
        parameters[1] = sd;
        variance = sd * sd;
    }

    /**
     * Only compute part of the log of the density that depends on the parameter
     * @param p Argument of log density function (an item parameter value)
     * @return
     */
    public double logDensity(double p) {
        //Check for value outside limits of distribution
        if (zeroDensity(p)) {
            return Double.MIN_VALUE;
        }
        double value = Math.log(p) - parameters[0];
        value *= value;
        value /= -2.0 * variance;
        value -= Math.log(p);

        return value;
    }

    /**
     * First derivative of log density. Only compute part of the log of the density that depends on the parameter.
     *
     * @param p
     * @return
     */
    public double logDensityDeriv1(double p) {
        //Outside limits of distribution density does not change, so derivative is zero
        if (zeroDensity(p))
            return 0.0;
        double value = Math.log(p) - parameters[0] + variance;
        value /= variance * p;
        return -value;
    }

    /**
     * Second derivative of log density. Only compute part of the log of the density that depends on the parameter.
     *
     * @param p
     * @return
     */
    public double logDensityDeriv2(double p) {
        //Outside limits of distribution density does not change, so derivative is zero
        if (zeroDensity(p))
            return 0.0;
        double value = Math.log(p) - parameters[0] + variance - 1.0;
        value /= p * p * variance;
        return value;
    }

    public int getNumberOfParameters() {
        return parameters.length;
    }

    public String distributionName() {
        return "LogNormal(" + parameters[0] + ", " + parameters[1] + ")";
    }

}