private static double GetSE(List <ItemScore> testScores, double theta, int seType) { double d2 = 0.0; double d1Squared = 0.0; foreach (ItemScore ir in testScores) { TestItemScoreInfo si = ir.ScoreInfo; IRTModel irt = si.IRTModel; double score = ir.Score; double deriv1 = irt.D1LnlWrtTheta(score, theta); d1Squared += deriv1 * deriv1; d2 += irt.D2LnlWrtTheta(score, theta); } if (seType == 1) { double k = testScores.Count; d1Squared *= k / (k - 1.0); return(Math.Sqrt(d1Squared / (d2 * d2))); } else { return(Math.Sqrt(1.0 / (-d2))); } }
/// <summary> /// /// </summary> /// <param name="testResponses"></param> /// <param name="startValue"></param> /// <param name="seType">seType of 0 asks for the inverse of the information // seType of 1 asks for the sandwich estimator</param> /// <param name="maxIter"></param> /// <param name="converge"></param> /// <param name="endAdjust"></param> /// <returns></returns> private static IRTScore MLEScore(List <ItemScore> testScores, double startValue, int seType, int maxIter, double converge) { double lnl = -9999999999.9, lnlChng = 99999.9, lnlNext = 0.0, se; int iter = 0; double step = 0.0, negD2 = 0.0; TestItem ti = null; IRTModel irt = null; double theta = startValue, x, d1Squared = 0.0, deriv1, d1 = 0.0, d2 = 0.0; step = 0.0; while ((lnlChng > converge) && (iter < maxIter)) { d1 = 0.0; d2 = 0.0; lnlNext = 0.0; d1Squared = 0.0; x = 0.0; foreach (ItemScore ir in testScores) { TestItemScoreInfo si = ir.ScoreInfo; irt = si.IRTModel; double score = ir.Score; x = irt.ComputeProbability(score, theta); if (x <= 0.0) { x = -1.0E10; //double.MinValue; } else { x = Math.Log(x); } lnlNext += x; deriv1 = irt.D1LnlWrtTheta(score, theta); d1Squared += deriv1 * deriv1; d1 += deriv1; d2 += irt.D2LnlWrtTheta(score, theta); } negD2 = d2 * -1.0; if (lnlNext >= lnl) { step = SteepestStep(d1, d2, d1Squared, 1.0); theta += step; lnlChng = lnlNext - lnl; lnl = lnlNext; } else { step = step * .5; theta -= step; lnlChng = lnl - lnlNext; if (Double.IsNaN(lnlChng)) { lnlChng = 100.0; } } ++iter; } //end while if (iter == maxIter) { return(new IRTScore(double.MaxValue, double.MaxValue, IRTScoreType.FailedConvergence)); } // NOTE: this computes se not at theta, but at the previous theta! if (seType == 1) { double k = testScores.Count; d1Squared *= k / (k - 1.0); se = Math.Sqrt(d1Squared / (d2 * d2)); } else { se = Math.Sqrt(1.0 / (-d2)); } //check for bad values if (double.IsNaN(theta)) { return(new IRTScore(theta, se, IRTScoreType.Diverged)); } return(new IRTScore(theta, se, IRTScoreType.Converged)); }