Example usage for org.apache.commons.math3.stat.descriptive.moment StandardDeviation clear

List of usage examples for org.apache.commons.math3.stat.descriptive.moment StandardDeviation clear

Introduction

In this page you can find the example usage for org.apache.commons.math3.stat.descriptive.moment StandardDeviation clear.

Prototype

@Override
public void clear() 

Source Link

Usage

From source file:com.itemanalysis.psychometrics.irt.estimation.StartingValues.java

/**
 * Computes normal approximation estimates (PROX) of item difficulty and person ability
 * in a way that allows for missing data (Linacre, 1994). It is an iterative procedure.
 *
 * Linacre, J. M., (1994). PROX with missing data, or known item or person measures.
 * Rasch Measurement Transactions, 8:3, 378, http://www.rasch.org/rmt/rmt83g.htm.
 *
 * @param converge convergence criterion as the maximum change in person logits.
 * @param maxIter maximum number of iterations. About 10 iterations works well.
 *//*from w ww.  j a  v a 2  s.  com*/
private void prox(double converge, int maxIter) {
    double delta = 1.0 + converge;
    int iter = 0;
    double pProx = 0;
    double pScore = 0;
    double maxTestScore = 0;
    double maxChange = 0;
    double logit = 0;

    Mean personGrandMean = new Mean();
    StandardDeviation personGrandSd = new StandardDeviation();
    double iProx = 0.0;
    double iMean = 0;
    theta = new double[nResponseVectors];

    Mean[] mPerson = new Mean[nItems];//Item difficulty mean for those examinees completing item j
    StandardDeviation[] sdPerson = new StandardDeviation[nItems];//Item difficulty standard deviation for those examinees completing item j
    double[] Si = null;
    double[] Ni = null;

    Mean[] mItem = new Mean[nResponseVectors];
    StandardDeviation[] sdItem = new StandardDeviation[nResponseVectors];

    while (delta > converge && iter < maxIter) {
        Si = new double[nItems];
        Ni = new double[nItems];

        //Compute descriptive statistics for persons and items
        double resp = 0;
        double freq = 0;
        for (int l = 0; l < nResponseVectors; l++) {
            freq = responseVector[l].getFrequency();

            for (int j = 0; j < nItems; j++) {

                //initialize arrays
                if (l == 0) {
                    mPerson[j] = new Mean();
                    sdPerson[j] = new StandardDeviation();
                }

                if (j == 0) {
                    mItem[l] = new Mean();
                    sdItem[l] = new StandardDeviation();
                }

                if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L4) {

                    resp = responseVector[l].getResponseAt(j);

                    //increment item and person summary statistics
                    if (resp != -1) {
                        //incorporate weights - crude workaround
                        for (int w = 0; w < freq; w++) {
                            mItem[l].increment(irm[j].getDifficulty());
                            sdItem[l].increment(irm[j].getDifficulty());

                            mPerson[j].increment(theta[l]);
                            sdPerson[j].increment(theta[l]);
                            Si[j] += resp;
                            Ni[j]++;
                        }

                    }
                }
            } //end item loop

        } //end summary loop

        //Compute item PROX for binary items only
        iMean = 0;
        double pSd = 1e-8;
        double ni = 0;
        for (int j = 0; j < nItems; j++) {
            if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L4) {
                pSd = sdPerson[j].getResult();

                //adjust extreme item scores
                if (Si[j] == 0)
                    Si[j] += 0.3;
                if (Si[j] == Ni[j])
                    Si[j] -= 0.3;

                logit = Math.log(Si[j] / (Ni[j] - Si[j]));
                iProx = mPerson[j].getResult() - Math.sqrt(1.0 + pSd / 2.9) * logit;
                irm[j].setDifficulty(iProx);
                iMean += iProx;
                ni++;
            }
        }
        iMean /= ni;

        //center difficulties about the mean item difficulty
        for (int j = 0; j < nItems; j++) {
            if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L4) {
                iProx = irm[j].getDifficulty();
                irm[j].setDifficulty(iProx - iMean);
            }
        }

        //Compute person PROX
        maxChange = 0;
        personGrandMean.clear();
        personGrandSd.clear();
        Pair<Double, Double> personScores = null;
        for (int l = 0; l < nResponseVectors; l++) {
            personScores = computePersonScores(responseVector[l]);
            pScore = personScores.getFirst();
            maxTestScore = personScores.getSecond();

            //adjust extreme person scores
            if (pScore == 0)
                pScore += 0.3;
            if (pScore == maxTestScore)
                pScore -= 0.3;

            logit = Math.log(pScore / (maxTestScore - pScore));
            pProx = mItem[l].getResult() + Math.sqrt(1.0 + sdItem[l].getResult() / 2.9) * logit;
            maxChange = Math.max(maxChange, Math.abs(theta[l] - pProx));
            theta[l] = pProx;
            personGrandMean.increment(pProx);
            personGrandSd.increment(pProx);
        }

        delta = maxChange;
        iter++;

        fireEMStatusEvent(iter, delta, Double.NaN);

    } //end while

    //Linearly transform theta estimate to have a mean of 0 and a standard deviation of 1.
    //Apply the same transformation to item difficulty values.
    double A = 1.0 / personGrandSd.getResult();
    double B = -A * personGrandMean.getResult();

    for (int l = 0; l < nResponseVectors; l++) {
        theta[l] = theta[l] * A + B;
    }

    double a = 1;
    double b = 0;
    for (int j = 0; j < nItems; j++) {
        if (irm[j].getType() == IrmType.L3 || irm[j].getType() == IrmType.L3) {
            b = irm[j].getDifficulty();
            irm[j].setDifficulty(b * A + B);

            //Adjust discrimination parameter for scaling constant.
            //PROX assumes a logit scale. This conversion is to convert to the normal metric.
            a = irm[j].getDiscrimination();
            irm[j].setDiscrimination(a / irm[j].getScalingConstant());
        }
    }

    //For debugging
    //        System.out.println("ITER: " + iter);
    //        for(int j=0;j<nItems;j++){
    //            System.out.println("PROX: " + irm[j].toString());
    //        }

}