public static string DataConverterRtoCS(CATItems itemBank, Double[] items)
        {
            int index = 0;

            try
            {
                // Populate data to the object array property "all_items_poly"
                for (int i = 0; i < itemBank.colSize; i++)
                {
                    double[] array = new double[itemBank.NumOfItems];

                    for (int j = 0; j < itemBank.NumOfItems; j++)
                    {
                        array[j] = items[index];
                        index++;
                    }

                    itemBank.all_items_poly[i] = array;
                }

                // Convert "NA" values to "NaN"
                itemBank.NAValueHandler();
            }
            catch (System.IndexOutOfRangeException ex)
            {
                //throw ex;
            }

            return("Index value: " + index.ToString());

            //return itemBank;
        }
        private void ProcessTheta(int[] items, int[] responses)
        {
            CATItems itemBank = null;

            if ((bool)Session["IsDicho"])
            {
                itemBank = new CATItems(items.Length);
                Tuple <CATItems.ColumnNames, int>[] cols = itemBank.GetKeys();

                for (int i = 0; i < cols.Length; i++)
                {
                    string tempKey = cols[i].Item1.ToString() + cols[i].Item2.ToString();
                    itemBank.SetItemParamter(cols[i], cat_items[tempKey].Select(y => (double)y).ToArray());
                }

                // Calculate theta
                CalculateTheta(itemBank, responses);
            }

            if ((bool)Session["IsPoly"])
            {
                ModelNames.Models paramModel = ModelNames.Models.GRM;
                itemBank = new CATItems(items.Length, paramModel.EnumToString(), nrCat: 5);
                Tuple <CATItems.ColumnNames, int>[] cols = itemBank.GetKeys();

                for (int i = 0; i < cols.Length; i++)
                {
                    string tempKey = cols[i].Item1.ToString() + cols[i].Item2.ToString();
                    itemBank.SetItemParamter(cols[i], cat_items[tempKey].Select(y => (double)y).ToArray());
                }

                // Calculate theta
                CalculateTheta(itemBank, responses, model: paramModel.EnumToString());
            }
        }
        public void test_NextItem_P(int numofItems, ModelNames.Models paramModel, ModelNames.CriterionTypes paramCriterion)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Polytomous Items
            CharacterVector modelName = engineObj.CreateCharacterVector(new string[] { paramModel.EnumToString() });

            engineObj.SetSymbol("modelName", modelName);
            DataFrame PolyItems = engineObj.Evaluate("PolyItems <- genPolyMatrix(" + numofItems + ", 5, model = modelName, same.nrCat = TRUE)").AsDataFrame();

            engineObj.SetSymbol("PolyItems", PolyItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)
            Console.WriteLine("*******************************************");
            Console.WriteLine("Polytomous Items, Model : " + paramModel.EnumToString());
            Console.WriteLine("*******************************************");

            CATItems itemBank = new CATItems(PolyItems[0].Length, paramModel.EnumToString(), 5);

            Tuple <CATItems.ColumnNames, int>[] cols = itemBank.GetKeys();

            for (int i = 0; i < cols.Length; i++)
            {
                itemBank.SetItemParamter(cols[i], PolyItems[i].Select(y => (double)y).ToArray());
            }

            // Call "NextItem" function from R
            GenericVector r_NextItem = engineObj.Evaluate("r_NextItem <- nextItem(PolyItems, model = modelName, theta = 0, criterion = \"" + paramCriterion.ToString() + "\")").AsList();

            // Selected item
            NumericVector item = r_NextItem[0].AsNumeric();

            DataFrame par = r_NextItem[1].AsDataFrame();

            // Value of "info"
            NumericVector thStart = r_NextItem[2].AsNumeric();

            // Criterion
            CharacterVector startSelect = r_NextItem[3].AsCharacter();

            // Call "NextItem" function from CS
            NextItemModel cs_NextItem = CatRLib.NextItem(itemBank, model: paramModel.EnumToString(), theta: 0, criterion: (int)paramCriterion);

            //Test passed for "MFI"

            if (item[0] != cs_NextItem.item)
            {
                resultFlag = false;
            }

            Assert.IsTrue(resultFlag);
        }
Example #4
0
        public void testKL_D(int NumOfItems)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Dichotomous Items
            DataFrame DichoItems = engineObj.Evaluate("DichoItems <- genDichoMatrix(items = " + NumOfItems + ")").AsDataFrame();

            engineObj.SetSymbol("DichoItems", DichoItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)
            CATItems itemBank = new CATItems(DichoItems[0].Length, false);

            // New Dictionary
            itemBank.SetItemParamter(CATItems.ColumnNames.a, DichoItems[0].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.b, DichoItems[1].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.c, DichoItems[2].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.d, DichoItems[3].Select(y => (double)y).ToArray());

            // Dichotomous Items
            DataFrame it_given_R = engineObj.Evaluate("it_given_R <- DichoItems[c(4, 8),]").AsDataFrame();

            engineObj.SetSymbol("it_given_R", it_given_R);

            CATItems it_given = itemBank.FindItem(new int[] { 4, 8 });

            //Creation of a response pattern
            NumericVector x_val = engineObj.Evaluate("x_val <- c(0, 1)").AsNumeric();

            engineObj.SetSymbol("x_val", x_val);

            int[] x = new int[] { 0, 1 };

            // Call "thetaEST" function from R,   method = \"ML\"
            NumericVector Theta = engineObj.Evaluate("Theta <- thetaEst(it_given_R, x_val, method = \"ML\")").AsNumeric();

            // Call "KL" function from R
            NumericVector r_KL = engineObj.Evaluate("r_KL <- KL(DichoItems, 1, x_val, it_given_R, theta = Theta)").AsNumeric();

            // Call "thetaEST" function from CS
            double th = CatRLib.ThetaEst(it_given, x, "", method: "ML");

            // Call "KL" function from CS
            double cs_KL = CatRLib.KL(itemBank, 1, x, it_given, "", theta: th);

            if (r_KL[0] - cs_KL > testEpsilon)
            {
                resultFlag = false;
            }

            Assert.IsTrue(resultFlag);
        }
Example #5
0
        public static NextItemModel NextItem(CATItems itemBank, string model = null, double theta = 0, int[] Out   = null, int[] x     = null, int criterion = 5, /* MFI */ string method = "BM",
                                             string priorDist = "norm", double[] priorPar         = null, double D = 1, double[] range = null, int[] parInt  = null, int infoType         = 2, /* observed */ int randomesque = 1, int rule = 1, /* Length */
                                             double thr       = 20, double?SETH = null, double AP = 1, int[] nAvailable = null, int maxItems = 50, CBControlList cbControl = null, string[] cbGroup = null)
        {
            NextItemModel result = CatRcs.NextItem.NextItem_Calc(itemBank, model, theta, Out, x, criterion, method, priorDist, priorPar, D, range, parInt,
                                                                 infoType, randomesque, rule, thr, SETH, AP, nAvailable, maxItems, cbControl, cbGroup);

            return(result);
        }
Example #6
0
        // Pi method for Dichotomous items
        public static PiList Pi_Calc(double th, CATItems it, string model, double D)
        {
            PiList objPi = null;

            if (String.IsNullOrEmpty(model))
            {
                #region "Functional Logic"
                try
                {
                    double[] e = new double[it.NumOfItems];
                    objPi = new PiList(it.NumOfItems);

                    for (int i = 0; i < it.NumOfItems; i++)
                    {
                        e[i] = Math.Exp(D * it.a[i] * (th - it.b[i])); // round test

                        double final_pi = 0;

                        double temp_pi = it.c[i] + (it.d[i] - it.c[i]) * e[i] / (1 + e[i]);

                        final_pi = (temp_pi == 0) ? 1e-10 : temp_pi;

                        final_pi = (temp_pi == 1) ? 1 - 1e-10 : temp_pi;

                        double temp_dPi = D * it.a[i] * e[i] * (it.d[i] - it.c[i]) / Math.Pow(1 + e[i], 2);                                                                 // round test

                        double temp_d2Pi = Math.Pow(D, 2) * Math.Pow(it.a[i], 2) * e[i] * (1 - e[i]) * (it.d[i] - it.c[i]) / Math.Pow(1 + e[i], 3);                         // round test

                        double temp_d3Pi = Math.Pow(D, 3) * Math.Pow(it.a[i], 3) * e[i] * (it.d[i] - it.c[i]) * (Math.Pow(e[i], 2) - 4 * e[i] + 1) / Math.Pow(1 + e[i], 4); // round test

                        objPi.AddPiList(final_pi, temp_dPi, temp_d2Pi, temp_d3Pi, i);
                    }
                }
                catch (Exception ex)
                {
                    if (ex != null)
                    {
                        if (objPi == null)
                        {
                            objPi = new PiList(ex.Message);
                        }
                    }
                    return(objPi);
                }
                #endregion
            }
            else
            {
                objPi = new PiList();
                objPi.Errors.SetValue("Model is not empty!!", 0);
            }

            return(objPi);
        }
Example #7
0
        public void test_MWI_D(int NumOfItems)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Dichotomous Items
            DataFrame DichoItems = engineObj.Evaluate("DichoItems <- genDichoMatrix(items = " + NumOfItems + ")").AsDataFrame();

            engineObj.SetSymbol("DichoItems", DichoItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)
            CATItems itemBank = new CATItems(DichoItems[0].Length, false);

            // New Dictionary
            itemBank.SetItemParamter(CATItems.ColumnNames.a, DichoItems[0].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.b, DichoItems[1].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.c, DichoItems[2].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.d, DichoItems[3].Select(y => (double)y).ToArray());

            // Dichotomous Items
            DataFrame it_given_R = engineObj.Evaluate("it_given_R <- DichoItems[c(4, 8),]").AsDataFrame();

            engineObj.SetSymbol("it_given_R", it_given_R);

            //Creation of a response pattern for theta value
            engineObj.Evaluate("set.seed(1)");
            NumericVector x_val = engineObj.Evaluate("x_val <- genPattern(0, it_given_R)").AsNumeric();

            engineObj.SetSymbol("x_val", x_val);

            int[] x = x_val.Select(y => (int)y).ToArray();

            CATItems it_given = itemBank.FindItem(new int[] { 4, 8 });

            // Call "MWI" function from R
            NumericVector r_mwi = engineObj.Evaluate("r_mei <- MWI(DichoItems, 1, x_val, it_given_R, type = \"MPWI\")").AsNumeric();

            // Call "MWI" function from CatRCS
            double cs_mwi = CatRLib.MWI(itemBank, 1, x, it_given, "", 2);

            if (r_mwi[0] - cs_mwi > testEpsilon)
            {
                resultFlag = false;
            }

            Assert.IsTrue(resultFlag);
        }
        public static CATItems DataConverterRtoCS(CATItems itemBank, DataFrame items)
        {
            // Populate data to the object array property "all_items_poly"
            for (int i = 0; i < itemBank.colSize; i++)
            {
                itemBank.all_items_poly[i] = items[i].Select(y => (double)y).ToArray();
            }

            // Convert "NA" values to "NaN"
            itemBank.NAValueHandler();

            return(itemBank);
        }
        private void CalculateTheta(CATItems itemBank, int[] responses, string model = "")
        {
            if (string.IsNullOrEmpty(model))
            {
                // Calling "thetaEST" function
                double cs_ThetaEst = CatRcs.CatRLib.ThetaEst(itemBank, responses, "");
                Session["Theta_Value"] = cs_ThetaEst;
            }
            else
            {
                double[] priorPar = new double[2]; priorPar[0] = -2; priorPar[1] = 2;

                // Calling "thetaEST" function
                double cs_ThetaEst = CatRcs.CatRLib.ThetaEst(it: itemBank, x: responses, method: "BM", model: model, priorPar: priorPar, priorDist: "Jeffreys");
                Session["Theta_Value"] = cs_ThetaEst;
            }
        }
Example #10
0
        // Function for calculating Next Item
        public static NextItemModel NextItem_Calc(CATItems itemBank, string model = null, double theta = 0, int[] Out   = null, int[] x     = null, int criterion = 5, /* MFI */ string method = "BM",
                                                  string priorDist = "norm", double[] priorPar         = null, double D = 1, double[] range = null, int[] parInt  = null, int infoType         = 2, /* observed */ int randomesque = 1, int rule = 1, /* Length */
                                                  double thr       = 20, double?SETH = null, double AP = 1, int[] nAvailable = null, int maxItems = 50, CBControlList cbControl = null, string[] cbGroup = null)
        {
            CATItems      par    = null;
            NextItemModel result = null;

            #region "Parameter Validation"

            if (priorPar == null || priorPar.Length < 2)
            {
                priorPar    = new double[2];
                priorPar[0] = 0;
                priorPar[1] = 1;
            }

            if (range == null || range.Length < 2)
            {
                range    = new double[2];
                range[0] = -4;
                range[1] = 4;
            }

            if (parInt == null || parInt.Length < 3)
            {
                parInt    = new int[3];
                parInt[0] = -4;
                parInt[1] = 4;
                parInt[2] = 33;
            }

            ModelNames.CriterionTypes?crit = null;

            switch (criterion)
            {
            case (int)ModelNames.CriterionTypes.bOpt:
                crit = ModelNames.CriterionTypes.bOpt;
                break;

            case (int)ModelNames.CriterionTypes.thOpt:
                crit = ModelNames.CriterionTypes.thOpt;
                break;

            case (int)ModelNames.CriterionTypes.KL:
                crit = ModelNames.CriterionTypes.KL;
                break;

            case (int)ModelNames.CriterionTypes.KLP:
                crit = ModelNames.CriterionTypes.KLP;
                break;

            case (int)ModelNames.CriterionTypes.MEI:
                crit = ModelNames.CriterionTypes.MEI;
                break;

            case (int)ModelNames.CriterionTypes.MEPV:
                crit = ModelNames.CriterionTypes.MEPV;
                break;

            case (int)ModelNames.CriterionTypes.MFI:
                crit = ModelNames.CriterionTypes.MFI;
                break;

            case (int)ModelNames.CriterionTypes.MLWI:
                crit = ModelNames.CriterionTypes.MLWI;
                break;

            case (int)ModelNames.CriterionTypes.MPWI:
                crit = ModelNames.CriterionTypes.MPWI;
                break;

            case (int)ModelNames.CriterionTypes.progressive:
                crit = ModelNames.CriterionTypes.progressive;
                break;

            case (int)ModelNames.CriterionTypes.proportional:
                crit = ModelNames.CriterionTypes.proportional;
                break;

            case (int)ModelNames.CriterionTypes.random:
                crit = ModelNames.CriterionTypes.random;
                break;
            }

            if (crit == null)
            {
                result = new NextItemModel(true, "Invalid 'criterion' name!");
                return(result);
            }

            int mod = 0;
            ModelNames.Models modelEnum = ModelNames.StringToEnum(model);

            if (!String.IsNullOrEmpty(model))
            {
                switch (modelEnum)
                {
                case ModelNames.Models.GRM:
                    mod = 1;
                    break;

                case ModelNames.Models.MGRM:
                    mod = 2;
                    break;

                case ModelNames.Models.PCM:
                    mod = 3;
                    break;

                case ModelNames.Models.GPCM:
                    mod = 4;
                    break;

                case ModelNames.Models.RSM:
                    mod = 5;
                    break;

                case ModelNames.Models.NRM:
                    mod = 6;
                    break;
                }

                if (mod == 0)
                {
                    result = new NextItemModel(true, "Invalid 'model' type!");
                    return(result);
                }
            }

            #endregion

            int[]    OUT     = null;
            double[] empProp = null;
            int      nrGroup = 0;
            double[] thProp  = null;

            #region Handling "cbControl" Parameter

            if (cbControl == null)
            {
                OUT = Out;
            }
            else
            {
                if (cbGroup == null)
                {
                    result = new NextItemModel(true, "'cbGroup' argument must be provided for content balancing!");
                    return(result);
                }

                if (RowColumn.Sum(cbControl.Props) != 1)
                {
                    double temp_sum = RowColumn.Sum(cbControl.Props);

                    for (int i = 0; i < cbControl.Props.Length; i++)
                    {
                        cbControl.Props[i] = cbControl.Props[i] / temp_sum;
                    }
                }

                nrGroup = cbControl.Names.Length;

                empProp = new double[nrGroup];

                if (Out == null)
                {
                    empProp = CatRcs.Utils.CommonHelper.Replicate(new double[] { 0 }, nrGroup);
                }
                else
                {
                    string[] temp_grp = new string[Out.Length];

                    for (int i = 0; i < Out.Length; i++)
                    {
                        temp_grp[i] = cbGroup[Out[i]];
                    }

                    for (int j = 0; j < nrGroup; j++)
                    {
                        string[] values = temp_grp.Where(m => m == cbControl.Names[j]).ToArray();

                        if (values != null && values.Length > 0)
                        {
                            empProp[j] = values.Length;
                        }
                        else
                        {
                            empProp[j] = 0;
                        }
                    }

                    empProp = empProp.Select(n => n / CatRcs.Utils.RowColumn.Sum(empProp)).ToArray();  // Functional Testing needed !!
                }

                thProp = cbControl.Props;

                List <int> indGroup = new List <int>(); int selGroup = 0;

                // Array of Group Numbers ex: "1 2 3 4 5" for nrGroup = 5.
                int[] GrpIndValues = new int[nrGroup];
                GrpIndValues = GrpIndValues.Select((a, i) => i + 1).ToArray();

                if (empProp.Min() == 0)
                {
                    for (int m = 0; m < empProp.Length; m++)
                    {
                        if (empProp[m] == 0)
                        {
                            indGroup.Add(GrpIndValues[m]);
                        }
                    }
                }
                else
                {
                    double[] tempProp = thProp.Select((a, i) => a - empProp[i]).ToArray();

                    for (int n = 0; n < tempProp.Length; n++)
                    {
                        if (tempProp[n] == tempProp.Max())
                        {
                            indGroup.Add(GrpIndValues[n]);
                        }
                    }
                }

                if (indGroup.Count == 1)
                {
                    selGroup = indGroup[0];
                }
                else
                {
                    selGroup = CatRcs.Utils.RandomNumberHandler.Sample(indGroup.ToArray(), 1, false)[0];
                }

                // Populating the OUT array
                string[] tempGrp = cbGroup.Where(c => c != cbControl.Names[selGroup]).ToArray();
                OUT = tempGrp.Select((a, i) => i + 1).ToArray();
                OUT = Out.Concat(OUT).ToArray();
                OUT = CatRcs.Utils.CommonHelper.Unique(OUT);
            }

            #endregion

            #region Handling "nAvalilable Parameter"

            if (nAvailable != null)
            {
                List <int> ind_temp = new List <int>();

                for (int k = 0; k < nAvailable.Length; k++)
                {
                    if (nAvailable[k] == 0)
                    {
                        ind_temp.Add(k);
                    }
                }

                OUT = OUT.Concat(ind_temp.ToArray()).ToArray();
                OUT = CatRcs.Utils.CommonHelper.Unique(OUT);
            }

            #endregion

            int select = 0;

            #region Criterion Type "MFI"

            if (crit == ModelNames.CriterionTypes.MFI)
            {
                int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a] - 1] = 0;
                    }
                }

                double[] info = Ii.Ii_Calc(theta, itemBank, model, D).Ii;
                double[] ranks = CatRcs.Utils.CommonHelper.Rank(info).Select(m => m).ToArray();
                int      nrIt = new int[] { randomesque, (int)CatRcs.Utils.RowColumn.Sum(items) }.Min();

                List <double> tempRanks = new List <double>();

                for (int j = 0; j < items.Length; j++)
                {
                    if (items[j] == 1)
                    {
                        tempRanks.Add(ranks[j]);
                    }
                }

                tempRanks = tempRanks.OrderByDescending(n => n).ToList();
                double[] keepRank = tempRanks.GetRange(0, nrIt).ToArray();

                List <int> keep = new List <int>();

                if (ranks.Length == items.Length)
                {
                    for (int m = 0; m < keepRank.Length; m++)
                    {
                        for (int n = 0; n < ranks.Length; n++)
                        {
                            if ((items[n] == 1) && (ranks[n] == keepRank[m]))
                            {
                                keep.Add(n + 1);
                            }
                        }
                    }
                }

                if (keep.Count == 1)
                {
                    select = keep[0];
                }
                else
                {
                    select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                }

                result = new NextItemModel(select, itemBank.FindItem(select), info[select - 1], criterion, randomesque);
            }

            #endregion

            #region Criterion Type "bOpt"

            if (crit == ModelNames.CriterionTypes.bOpt)
            {
                if (string.IsNullOrEmpty(model))
                {
                    int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                    if (OUT != null)
                    {
                        for (int a = 0; a < OUT.Length; a++)
                        {
                            items[OUT[a] - 1] = 0;
                        }
                    }

                    double[] distance = itemBank.GetItemParamter(CATItems.ColumnNames.b).Select(a => Math.Abs(a - theta)).ToArray();
                    double[] ranks    = CatRcs.Utils.CommonHelper.Rank(distance).Select(m => m).ToArray();

                    if (OUT != null)
                    {
                        for (int a = 0; a < OUT.Length; a++)
                        {
                            ranks[OUT[a] - 1] = -1;
                        }
                    }

                    int nrIt = new int[] { randomesque, (int)CatRcs.Utils.RowColumn.Sum(items) }.Min();

                    List <double> tempRanks = new List <double>();

                    for (int j = 0; j < items.Length; j++)
                    {
                        if (items[j] == 1)
                        {
                            tempRanks.Add(ranks[j]);
                        }
                    }

                    tempRanks = tempRanks.OrderBy(n => n).ToList();
                    double[] keepRank       = tempRanks.GetRange(0, nrIt).ToArray();
                    keepRank = keepRank.Distinct().ToArray();

                    List <int> keep = new List <int>();

                    if (ranks.Length == items.Length)
                    {
                        for (int m = 0; m < keepRank.Length; m++)
                        {
                            for (int n = 0; n < ranks.Length; n++)
                            {
                                if ((items[n] == 1) && (ranks[n] == keepRank[m]))
                                {
                                    keep.Add(n + 1);
                                }
                            }
                        }
                    }

                    if (keep.Count == 1)
                    {
                        select = keep[0];
                    }
                    else
                    {
                        select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                    }

                    result = new NextItemModel(select, itemBank.FindItem(select), distance[select - 1], criterion, randomesque);
                }
                else
                {
                    result = new NextItemModel(true, "bOpt's rule cannot be considered with polytomous items!");
                    return(result);
                }
            }

            #endregion

            #region Criterion Type "MLWI" OR "MPWI"

            if (crit == ModelNames.CriterionTypes.MLWI || crit == ModelNames.CriterionTypes.MPWI)
            {
                if (Out != null)
                {
                    if (Out.Length == 1)
                    {
                        par = itemBank.FindItem(Out[0]);
                    }
                    else
                    {
                        par = itemBank.FindItem(Out);
                    }
                }
                else
                {
                    result = new NextItemModel(true, "Out parameter can't be empty!");
                    return(result);
                }

                int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a] - 1] = 0;
                    }
                }

                double[] likInfo = CatRcs.Utils.CommonHelper.Replicate(new double[] { 0 }, itemBank.NumOfItems);

                int mwiType = 0;

                if (criterion == (int)ModelNames.CriterionTypes.MLWI)
                {
                    mwiType = (int)ModelNames.MWI_Type.MLWI;
                }
                if (criterion == (int)ModelNames.CriterionTypes.MPWI)
                {
                    mwiType = (int)ModelNames.MWI_Type.MPWI;
                }

                if (x != null)
                {
                    for (int j = 0; j < itemBank.NumOfItems; j++)
                    {
                        if (items[j] == 1)
                        {
                            likInfo[j] = MWI.MWI_Calc(itemBank, j + 1, x, par, model, mwiType, priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]);
                            /* item number is always 1 greater than the index */
                        }
                    }
                }

                int nrIt = new int[] { randomesque, (int)CatRcs.Utils.RowColumn.Sum(items) }.Min();

                double likVal = likInfo.ToList().OrderByDescending(n => n).ToArray()[nrIt - 1]; // First value with index 0

                List <int> keep = new List <int>();

                for (int k = 0; k < items.Length; k++)
                {
                    if (likInfo[k] >= likVal)
                    {
                        keep.Add(k + 1);  // Converting from index to item number
                    }
                }

                if (keep.Count == 1)
                {
                    select = keep[0];
                }
                else
                {
                    select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                }

                result = new NextItemModel(select, itemBank.FindItem(select), likInfo[select - 1], criterion, randomesque);
            }

            #endregion

            #region Criterion Type "KL" OR "KLP"

            if (crit == ModelNames.CriterionTypes.KL || crit == ModelNames.CriterionTypes.KLP)
            {
                if (Out != null)
                {
                    if (Out.Length == 1)
                    {
                        par = itemBank.FindItem(Out[0]);
                    }
                    else
                    {
                        par = itemBank.FindItem(Out);
                    }
                }
                else
                {
                    result = new NextItemModel(true, "Out parameter can't be empty!");
                    return(result);
                }

                int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a] - 1] = 0;
                    }
                }

                double[] klValue = CatRcs.Utils.CommonHelper.Replicate(new double[] { 0 }, itemBank.NumOfItems);
                double[] X       = CatRcs.Utils.CommonHelper.Sequence(parInt[0], parInt[1], parInt[2]);

                #region "Function 'L' "
                Func <double, int[], CATItems, double> L = (th, r, param) =>
                {
                    double res = 0;

                    var temp_1 = Pi.Pi_Calc(th, param, model, D).Pi.Select((p, i) => Math.Pow(p, r[i])).ToArray();

                    var temp_2 = Pi.Pi_Calc(th, param, model, D).Pi.Select((p, i) => Math.Pow(1 - p, 1 - r[i])).ToArray();

                    if (temp_1.Length == temp_2.Length)
                    {
                        var temp_3 = temp_1.Select((p, i) => p * temp_2[i]).ToArray();

                        res = temp_3.Aggregate((acc, val) => acc * val);
                    }

                    return(res);
                };
                #endregion

                #region "Function 'LL' "
                Func <double, int[], CATItems, double> LL = (th, r, param) =>
                {
                    double res = 0;

                    if (param.NumOfItems == 0)
                    {
                        res = 1;
                    }
                    else
                    {
                        double[,] prob = Pi.Pi_Poly_Calc(th, param, model, D).Pi;

                        for (int i = 0; i < r.Length; i++)
                        {
                            res = res * prob[i, r[i] + 1];
                        }
                    }

                    return(res);
                };
                #endregion

                double[] LF = null;

                if (string.IsNullOrEmpty(model))
                {
                    LF = X.Select(p => L(p, x, par)).ToArray();
                }
                else
                {
                    LF = X.Select(p => LL(p, x, par)).ToArray();
                }

                int kType = 0;

                if (criterion == (int)ModelNames.CriterionTypes.KL)
                {
                    kType = (int)ModelNames.KLTypes.KL;
                }
                if (criterion == (int)ModelNames.CriterionTypes.KLP)
                {
                    kType = (int)ModelNames.KLTypes.KLP;
                }

                for (int j = 0; j < itemBank.NumOfItems; j++)
                {
                    if (items[j] == 1)
                    {
                        klValue[j] = KL.KL_Calc(itemBank, j + 1, x, par, model, theta, priorPar, X, LF, kType, D, priorDist, parInt[0], parInt[1], parInt[2]);
                        /* item number is always 1 greater than the index */
                    }
                }

                int nrIt = new int[] { randomesque, (int)CatRcs.Utils.RowColumn.Sum(items) }.Min();

                double klVal = klValue.ToList().OrderByDescending(n => n).ToArray()[nrIt - 1];

                List <int> keep = new List <int>();

                for (int k = 0; k < items.Length; k++)
                {
                    if (klValue[k] >= klVal)
                    {
                        keep.Add(k + 1);
                    }
                }

                if (keep.Count == 1)
                {
                    select = keep[0];
                }
                else
                {
                    select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                }

                result = new NextItemModel(select, itemBank.FindItem(select), klValue[select - 1], criterion, randomesque);
            }

            #endregion

            #region Criterion Type "MEI"

            if (crit == ModelNames.CriterionTypes.MEI)
            {
                int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a] - 1] = 0;
                    }
                }

                double[] infos = CatRcs.Utils.CommonHelper.Replicate(new double[] { 0 }, itemBank.NumOfItems);

                for (int j = 0; j < items.Length; j++)
                {
                    if (items[j] > 0)
                    {
                        infos[j] = MEI.MEI_Calc(itemBank, j + 1, x, theta, itemBank.FindItem(Out), model, method, D, priorPar, priorDist, range, parInt, infoType);
                    }
                }

                int nrIt = new int[] { randomesque, (int)CatRcs.Utils.RowColumn.Sum(items) }.Min();

                double infoVal = infos.ToList().OrderByDescending(n => n).ToArray()[nrIt - 1];

                List <int> keep = new List <int>();

                for (int k = 0; k < items.Length; k++)
                {
                    if (infos[k] >= infoVal)
                    {
                        keep.Add(k + 1);
                    }
                }

                if (keep.Count == 1)
                {
                    select = keep[0];
                }
                else
                {
                    select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                }

                result = new NextItemModel(select, itemBank.FindItem(select), infos[select - 1], criterion, randomesque);
            }

            #endregion

            #region Criterion Type "MEPV"

            if (crit == ModelNames.CriterionTypes.MEPV)
            {
                int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a] - 1] = 0;
                    }
                }

                double[] epvs = CatRcs.Utils.CommonHelper.Replicate(new double[] { 1000 }, itemBank.NumOfItems);

                for (int j = 0; j < items.Length; j++)
                {
                    if (items[j] > 0)
                    {
                        epvs[j] = EPV.EPV_Calc(itemBank, j + 1, x, theta, itemBank.FindItem(Out), model, priorPar, parInt, D, priorDist);
                    }
                }

                var    tempVal = new int[] { randomesque, items.Sum() }.Min();
                double epVal = epvs.ToList().OrderBy(n => n).ToArray()[tempVal - 1];

                List <int> keep = new List <int>();

                for (int k = 0; k < itemBank.NumOfItems; k++)
                {
                    if (epvs[k] <= epVal)
                    {
                        keep.Add(k + 1);
                    }
                }

                if (keep.Count == 1)
                {
                    select = keep[0];
                }
                else
                {
                    select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                }

                result = new NextItemModel(select, itemBank.FindItem(select), epvs[select - 1], criterion, randomesque);
            }

            #endregion

            #region Criterion Type "random"

            if (crit == ModelNames.CriterionTypes.random)
            {
                int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a]] = 0;
                    }
                }

                int gen = Convert.ToInt32(Convert.ToInt32(CatRcs.Utils.RandomNumberHandler.Runif(1, 0, 1)[0]) * items.Sum()) + 1;

                List <int> indexs = new List <int>();

                for (int k = 0; k < itemBank.NumOfItems; k++)
                {
                    if (items[k] > 0)
                    {
                        indexs.Add(k + 1);
                    }
                }

                select = indexs.ElementAt(gen);

                result = new NextItemModel(select, itemBank.FindItem(select), double.NaN, criterion, randomesque);
            }

            #endregion

            #region Criterion Type "progressive"

            if (crit == ModelNames.CriterionTypes.progressive)
            {
                int   item_administered = Out.Length;
                int[] items             = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a] - 1] = 0;
                    }
                }

                double[]      info      = Ii.Ii_Calc(theta, itemBank, model, D).Ii;
                List <double> tempItems = new List <double>();

                for (int j = 0; j < items.Length; j++)
                {
                    if (items[j] == 1)
                    {
                        tempItems.Add(info[j]);
                    }
                }

                double wq = 0;

                double   itemMaxInfo  = tempItems.Max();
                double[] randomValues = CatRcs.Utils.RandomNumberHandler.Runif(items.Length, 0, itemMaxInfo);

                if (rule == (int)ModelNames.RuleType.Precision)
                {
                    double infostop = Math.Pow((1 / thr), 2);
                    double cuminfo  = Math.Pow(double.Parse((1 / SETH).ToString()), 2);

                    if (item_administered > 0)
                    {
                        wq = Math.Pow(new double[] { cuminfo / infostop, item_administered / (maxItems - 1) }.Max(), AP);
                    }
                }

                if (rule == (int)ModelNames.RuleType.Length)
                {
                    if (item_administered > 0)
                    {
                        List <double> tempNum = new List <double>();

                        for (int i = 1; i <= item_administered; i++)
                        {
                            tempNum.Add(Math.Pow(i, AP));
                        }

                        double numerador = tempNum.Sum();

                        List <double> tempDenom = new List <double>();

                        for (int j = 1; j <= thr - 1; j++)
                        {
                            tempDenom.Add(Math.Pow(j, AP));
                        }

                        double denominador = tempDenom.Sum();

                        wq = numerador / denominador;
                    }
                }

                double[] funcPR = info.Select((d, i) => d * wq + randomValues[i] * (1 - wq)).ToArray();

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        funcPR[OUT[a] - 1] = 0;
                    }
                }

                List <int> keep = new List <int>();

                for (int k = 0; k < funcPR.Length; k++)
                {
                    if (funcPR[k] == funcPR.Max())
                    {
                        keep.Add(k + 1);
                    }
                }

                if (keep.Count == 1)
                {
                    select = keep[0];
                }
                else
                {
                    select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                }

                result = new NextItemModel(select, itemBank.FindItem(select), info[select - 1], criterion, randomesque);
            }

            #endregion

            #region Criterion Type "proportional"

            if (crit == ModelNames.CriterionTypes.proportional)
            {
                int   item_administered = Out.Length;
                int[] items             = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        items[OUT[a] - 1] = 0;
                    }
                }

                double wq = 0;

                if (rule == (int)ModelNames.RuleType.Precision)
                {
                    double infostop = Math.Pow((1 / thr), 2);
                    double cuminfo  = Math.Pow(double.Parse((1 / SETH).ToString()), 2);

                    if (item_administered > 0)
                    {
                        wq = infostop * Math.Pow(new double[] { cuminfo / infostop, item_administered / (maxItems - 1) }.Max(), AP);
                    }
                }

                if (rule == (int)ModelNames.RuleType.Length)
                {
                    if (item_administered > 0)
                    {
                        List <double> tempNum = new List <double>();

                        for (int i = 1; i <= item_administered; i++)
                        {
                            tempNum.Add(Math.Pow(i, AP));
                        }

                        double numerador = tempNum.Sum();

                        List <double> tempDenom = new List <double>();

                        for (int j = 1; j <= thr - 1; j++)
                        {
                            tempDenom.Add(Math.Pow(j, AP));
                        }

                        double denominador = tempDenom.Sum();

                        wq = thr * numerador / denominador;
                    }
                }

                double[] info   = Ii.Ii_Calc(theta, itemBank, model, D).Ii;
                double[] infoPR = info.Select(s => Math.Pow(s, wq)).ToArray();

                if (OUT != null)
                {
                    for (int a = 0; a < OUT.Length; a++)
                    {
                        infoPR[OUT[a] - 1] = 0;
                    }
                }

                List <double> tempInfoPR = new List <double>();

                for (int k = 0; k < items.Length; k++)
                {
                    if (items[k] == 1)
                    {
                        tempInfoPR.Add(infoPR[k]);
                    }
                }

                double   totalInfoPR = tempInfoPR.Sum();
                double[] probSelect  = infoPR.Select(m => m / totalInfoPR).ToArray();

                int[] selectItems = items.Select((n, i) => i + 1).ToArray();

                select = CatRcs.Utils.RandomNumberHandler.Sample(selectItems, 1, false)[0];  // prob parameter will be added after Sample functiom modification

                result = new NextItemModel(select, itemBank.FindItem(select), info[select], criterion, randomesque);
            }

            #endregion

            #region Criterion Type "thOpt"

            if (crit == ModelNames.CriterionTypes.thOpt)
            {
                if (string.IsNullOrEmpty(model))  // Only for Dichotomous Items
                {
                    int[] items = CatRcs.Utils.CommonHelper.Replicate(new int[] { 1 }, itemBank.NumOfItems);

                    if (OUT != null)
                    {
                        for (int a = 0; a < OUT.Length; a++)
                        {
                            items[OUT[a] - 1] = 0;
                        }
                    }

                    double[] u = itemBank.GetItemParamter(CATItems.ColumnNames.c).Select((s, i) => - 0.75 + (s + itemBank.GetItemParamter(CATItems.ColumnNames.d)[i] + -2 * s * itemBank.GetItemParamter(CATItems.ColumnNames.d)[i]) / 2).ToArray();
                    double[] v = itemBank.GetItemParamter(CATItems.ColumnNames.c).Select((n, i) => (n + itemBank.GetItemParamter(CATItems.ColumnNames.d)[i] - 1) / 4).ToArray();

                    double[] xstar  = u.Select((m, i) => 2 * Math.Sqrt(-m / 3) * Math.Cos(Math.Acos(-v[i] * Math.Sqrt(-27 / Math.Pow(m, 3)) / 2) / 3 + 4 * (Math.PI / 3)) + 0.5).ToArray();
                    double[] thstar = itemBank.GetItemParamter(CATItems.ColumnNames.b).Select((o, i) => o + Math.Log((xstar[i] - itemBank.GetItemParamter(CATItems.ColumnNames.c)[i]) / (itemBank.GetItemParamter(CATItems.ColumnNames.d)[i] - xstar[i])) / (D * itemBank.GetItemParamter(CATItems.ColumnNames.a)[i])).ToArray();

                    double[] distance = thstar.Select(p => Math.Abs(p - theta)).ToArray();
                    double[] ranks    = CatRcs.Utils.CommonHelper.Rank(distance).Select(m => m).ToArray();

                    if (OUT != null)
                    {
                        for (int a = 0; a < OUT.Length; a++)
                        {
                            ranks[OUT[a] - 1] = -1;
                        }
                    }

                    int nrIt = new int[] { randomesque, (int)CatRcs.Utils.RowColumn.Sum(items) }.Min();

                    List <double> tempRanks = new List <double>();

                    for (int j = 0; j < items.Length; j++)
                    {
                        if (items[j] == 1)
                        {
                            tempRanks.Add(ranks[j]);
                        }
                    }

                    tempRanks = tempRanks.OrderBy(n => n).ToList();
                    double[] keepRank       = tempRanks.GetRange(0, nrIt).ToArray();
                    keepRank = keepRank.Distinct().ToArray();

                    List <int> keep = new List <int>();

                    if (ranks.Length == items.Length)
                    {
                        for (int m = 0; m < keepRank.Length; m++)
                        {
                            for (int n = 0; n < ranks.Length; n++)
                            {
                                if ((items[n] == 1) && (ranks[n] == keepRank[m]))
                                {
                                    keep.Add(n + 1);
                                }
                            }
                        }
                    }

                    if (keep.Count == 1)
                    {
                        select = keep[0];
                    }
                    else
                    {
                        select = CatRcs.Utils.RandomNumberHandler.Sample(keep.ToArray(), 1, false)[0];
                    }

                    result = new NextItemModel(select, itemBank.FindItem(select), distance[select - 1], criterion, randomesque);
                }
                else
                {
                    result = new NextItemModel(true, "thOpt's rule cannot be considered with polytomous items!");
                    return(result);
                }
            }

            #endregion

            #region Handling "cbControl" Parameter

            if (cbControl == null)
            {
                if (result != null)
                {
                    result.prior_prop = null;
                    result.post_prop  = null;
                    result.cb_prop    = null;
                }
            }
            else
            {
                result.prior_prop = empProp;

                double[] postProp = new double[nrGroup];

                string[] temp_grp = new string[Out.Length + 1];

                for (int i = 0; i < temp_grp.Length; i++)
                {
                    if (i == 0)
                    {
                        temp_grp[i] = cbGroup[result.item];
                    }

                    temp_grp[i] = cbGroup[Out[i]];
                }

                for (int j = 0; j < postProp.Length; j++)
                {
                    string[] values = temp_grp.Where(m => m == cbControl.Names[j]).ToArray();

                    if (values != null && values.Length > 0)
                    {
                        postProp[j] = values.Length;
                    }
                    else
                    {
                        postProp[j] = 0;
                    }
                }

                result.post_prop = postProp.Select(n => n / CatRcs.Utils.RowColumn.Sum(postProp)).ToArray();
                result.cb_prop   = thProp;
            }

            #endregion

            return(result);
        }
Example #11
0
        public static OIiList OIi_Calc(double th, CATItems it, int[] x, string model, double D)
        {
            OIiList objOIi = null;

            double[] OIi = null;
            try
            {
                if (String.IsNullOrEmpty(model))
                {
                    #region "Calculation for Dichotmous Items"

                    PiList pr = Pi.Pi_Calc(th, it, model, D);

                    if (pr == null)
                    {
                        objOIi           = new OIiList();
                        objOIi.Exception = "No Pi values found!";
                        return(objOIi);
                    }

                    double[] P = pr.Pi; double[] dP = pr.dPi; double[] d2P = pr.d2Pi;

                    OIi = new double[P.Length];

                    objOIi = new OIiList(P.Length);

                    double[] Q = new double[P.Length];

                    for (int i = 0; i < P.Length; i++)
                    {
                        Q[i] = 1 - P[i];
                    }

                    for (int j = 0; j < OIi.Length; j++)
                    {
                        OIi[j] = (P[j] * Q[j] * Math.Pow(dP[j], 2) - (x[0] - P[j]) * (P[j] * Q[j] * d2P[j] + Math.Pow(dP[j], 2) * (P[j] - Q[j]))) / (Math.Pow(P[j], 2) * Math.Pow(Q[j], 2));
                    }

                    #endregion
                }
                else
                {
                    #region "Calculation for Polytomous Items"

                    PiListPoly pr = Pi.Pi_Poly_Calc(th, it, model, D);

                    if (pr == null)
                    {
                        objOIi           = new OIiList();
                        objOIi.Exception = "No Pi values found!";
                        return(objOIi);
                    }

                    double[,] P = pr.Pi; double[,] dP = pr.dPi; double[,] d2P = pr.d2Pi;

                    OIi = new double[it.NumOfItems];

                    objOIi = new OIiList(it.NumOfItems);

                    for (int i = 0; i < x.Length; i++)
                    {
                        double tempdP  = dP[i, x[i]];
                        double tempP   = P[i, x[i]];
                        double tempd2P = d2P[i, x[i]];

                        OIi[i] = (Math.Pow(dP[i, x[i]], 2) / Math.Pow(P[i, x[i]], 2)) - (d2P[i, x[i]] / P[i, x[i]]);
                    }

                    #endregion
                }

                objOIi.Add(OIi);
            }
            catch (Exception ex)
            {
                if (ex != null)
                {
                    if (objOIi == null)
                    {
                        objOIi = new OIiList();
                    }
                    objOIi.Exception = "No Pi value found!";
                }
                return(objOIi);
            }

            return(objOIi);
        }
Example #12
0
        public void testEapEST_and_EapSEM_D()
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Test for item banks with different number of items

            for (int i1 = 0; i1 < numberOfItems.Length; i1++)
            {
                // Dichotomous Items
                DataFrame DichoItems = engineObj.Evaluate("DichoItems <- genDichoMatrix(items = " + numberOfItems[i1] + ")").AsDataFrame();
                engineObj.SetSymbol("DichoItems", DichoItems);

                // Adapting with the existing "CAT-Items" type (Wrapper)
                CATItems itemBank = new CATItems(DichoItems[0].Select(y => (double)y).ToArray(), DichoItems[1].Select(y => (double)y).ToArray(),
                                                 DichoItems[2].Select(y => (double)y).ToArray(), DichoItems[3].Select(y => (double)y).ToArray());

                // test for different theta values
                double[] th = CatRcs.Utils.CommonHelper.Sequence(-6, 6, length: 11);

                var stopwatch = new Stopwatch();
                stopwatch.Restart();

                for (int i2 = 0; i2 < th.Length; i2++)
                {
                    string temp = th[i2].ToString(nfi);

                    //Creation of a response pattern for theta value
                    NumericVector x_val = engineObj.Evaluate("x_val <- genPattern(" + th[i2].ToString(nfi) + ", DichoItems)").AsNumeric();

                    int[] x = x_val.Select(y => (int)y).ToArray();

                    // Call "EapEST" function from R
                    NumericVector r_eapEst = engineObj.Evaluate("result_Eap <- eapEst(DichoItems, x_val)").AsNumeric();

                    // Call "EapSEM" function from R
                    NumericVector r_eapSem = engineObj.Evaluate("result_EapSem <- eapSem(result_Eap, DichoItems, x_val)").AsNumeric();

                    stopwatch.Restart();

                    // Call "EapEST" function from CatRCS
                    double cs_eapEst = CatRLib.EapEST(itemBank, x, "");

                    // Call "EapSEM" function from CatRCS
                    double cs_eapSem = CatRLib.EapSEM(cs_eapEst, itemBank, x, "");

                    Console.WriteLine("Time: " + stopwatch.ElapsedMilliseconds);

                    if (r_eapEst[0] - cs_eapEst > testEpsilon ||
                        r_eapSem[0] - cs_eapSem > testEpsilon)
                    {
                        resultFlag = false;
                    }
                }
            }

            Assert.IsTrue(resultFlag, "Test Passed!");
        }
Example #13
0
        public void testEPV_P(int NumOfItems, ModelNames.Models paramModel)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Polytomous Items
            CharacterVector modelName = engineObj.CreateCharacterVector(new string[] { paramModel.EnumToString() });

            engineObj.SetSymbol("modelName", modelName);
            DataFrame PolyItems = engineObj.Evaluate("PolyItems <- genPolyMatrix(" + NumOfItems + ", 5, model = modelName, same.nrCat = TRUE)").AsDataFrame();

            engineObj.SetSymbol("PolyItems", PolyItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)

            Console.WriteLine("*******************************************");
            Console.WriteLine("Polytomous Items, Model : " + paramModel.EnumToString());
            Console.WriteLine("*******************************************");

            CATItems itemBank = new CATItems(PolyItems[0].Length, paramModel.EnumToString(), 5);

            Tuple <CATItems.ColumnNames, int>[] cols = itemBank.GetKeys();

            for (int i = 0; i < cols.Length; i++)
            {
                itemBank.SetItemParamter(cols[i], PolyItems[i].Select(y => (double)y).ToArray());
            }

            #region "Test block for Ability Values (th)"

            double[] th = CatRcs.Utils.CommonHelper.Sequence(-6, 6, length: 11);

            for (int j = 0; j < th.Length; j++)
            {
                string temp = th[j].ToString(nfi);

                // Polytomous Items
                DataFrame it_given_R = engineObj.Evaluate("it_given_R <- PolyItems[c(4, 8),]").AsDataFrame();
                engineObj.SetSymbol("it_given_R", it_given_R);

                //Creation of a response pattern for theta value
                engineObj.Evaluate("set.seed(1)");
                NumericVector x_val = engineObj.Evaluate("x_val <- genPattern(" + th[j].ToString(nfi) + ", it_given_R, model = modelName)").AsNumeric();
                engineObj.SetSymbol("x_val", x_val);

                int[] x = x_val.Select(y => (int)y).ToArray();

                CATItems it_given = itemBank.FindItem(new int[] { 4, 8 });

                // Call "EPV" function from R
                NumericVector r_epv = engineObj.Evaluate("r_epv <- EPV(PolyItems, 1, x_val, " + th[j].ToString(nfi) + ", it_given_R, model = modelName)").AsNumeric();

                // Call "EPV" function from CatRCS
                double cs_epv = CatRLib.EPV(itemBank, 1, x, th[j], it_given, paramModel.EnumToString());

                if (r_epv[0] - cs_epv > testEpsilon)
                {
                    resultFlag = false;
                }
            }

            Assert.IsTrue(resultFlag);

            #endregion
        }
Example #14
0
        public void testPi_P_New(ModelNames.Models paramModel)
        {
            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Polytomous Items
            CharacterVector modelName = engineObj.CreateCharacterVector(new string[] { paramModel.EnumToString() });

            engineObj.SetSymbol("modelName", modelName);
            DataFrame PolyItems = engineObj.Evaluate("PolyItems <- genPolyMatrix(100, 5, model = modelName, same.nrCat = FALSE)").AsDataFrame();

            engineObj.SetSymbol("PolyItems", PolyItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)

            Console.WriteLine("*******************************************");
            Console.WriteLine("Polytomous Items, Model : " + paramModel.EnumToString());
            Console.WriteLine("*******************************************");

            CATItems itemBank = new CATItems(NumOfItems: PolyItems[0].Length, model: paramModel.EnumToString(), nrCat: 5);

            for (int i = 0; i < itemBank.colSize; i++)
            {
                itemBank.all_items_poly[i] = PolyItems[i].Select(y => (double)y).ToArray();
            }

            PiListPoly objPI        = null;
            int        decimalPoint = 4;

            double[]      th_Values = CatRcs.Utils.CommonHelper.Sequence(-4, 4, by: 1);
            NumericVector th_val    = engineObj.CreateNumericVector(new double[] { th_Values[0] });

            engineObj.SetSymbol("th_val", th_val);

            // Calling the "Pi" from R
            GenericVector result_Pi = engineObj.Evaluate("result_Pi <- Pi(th = th_val, PolyItems, model = modelName, D = 1)").AsList();

            // Getting the "Pi" function result
            NumericVector Pi   = result_Pi[0].AsNumeric();
            NumericVector dPi  = result_Pi[1].AsNumeric();
            NumericVector d2Pi = result_Pi[2].AsNumeric();
            NumericVector d3Pi = result_Pi[3].AsNumeric();

            Console.WriteLine("Value of Theta: " + th_Values[0]);

            // Calling "Pi" function
            objPI = CatRLib.Pi_P(th_Values[0], itemBank, paramModel.EnumToString(), 1);

            #region "Pi"

            int z = 0, pi_index = 0;
            resultFlag = true;
            Console.WriteLine("****** Pi ******");

            int len  = objPI.Pi.GetLength(0);
            int len2 = objPI.Pi.GetLength(1);

            for (int i = 0; i < objPI.Pi.GetLength(1); i++)     // column
            {
                z = i + 1;                                      // item number

                for (int j = 0; j < objPI.Pi.GetLength(0); j++) // row
                {
                    double tempPiVal = !CatRcs.Utils.CheckNaValues.IsNaNvalue(Pi[pi_index]) ? Pi[pi_index] : 0;

                    if (decimal.Round(Convert.ToDecimal(tempPiVal), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.Pi[j, i]), decimalPoint))
                    {
                        Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }

                    pi_index++;
                }
            }

            Assert.IsTrue(resultFlag);
            Console.WriteLine("Values of Pi are Matched!");

            #endregion

            #region "dPi"

            z          = 0; pi_index = 0;
            resultFlag = true;
            Console.WriteLine("****** dPi ******");

            for (int i = 0; i < objPI.dPi.GetLength(1); i++)     // column
            {
                z = i + 1;                                       // item number

                for (int j = 0; j < objPI.dPi.GetLength(0); j++) // row
                {
                    double tempPiVal = !CatRcs.Utils.CheckNaValues.IsNaNvalue(dPi[pi_index]) ? dPi[pi_index] : 0;

                    if (decimal.Round(Convert.ToDecimal(tempPiVal), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.dPi[j, i]), decimalPoint))
                    {
                        Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }

                    pi_index++;
                }
            }

            Assert.IsTrue(resultFlag);
            Console.WriteLine("Values of dPi are Matched!");

            #endregion

            #region "d2Pi"

            z          = 0; pi_index = 0;
            resultFlag = true;
            Console.WriteLine("****** d2Pi ******");

            for (int i = 0; i < objPI.d2Pi.GetLength(1); i++)     // column
            {
                z = i + 1;                                        // item number

                for (int j = 0; j < objPI.d2Pi.GetLength(0); j++) // row
                {
                    double tempPiVal = !CatRcs.Utils.CheckNaValues.IsNaNvalue(d2Pi[pi_index]) ? d2Pi[pi_index] : 0;

                    if (decimal.Round(Convert.ToDecimal(tempPiVal), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.d2Pi[j, i]), decimalPoint))
                    {
                        Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }

                    pi_index++;
                }
            }

            Assert.IsTrue(resultFlag);
            Console.WriteLine("Values of d2Pi are Matched!");

            #endregion

            #region "d3Pi"

            z          = 0; pi_index = 0;
            resultFlag = true;
            Console.WriteLine("****** d3Pi ******");

            for (int i = 0; i < objPI.d3Pi.GetLength(1); i++)     // column
            {
                z = i + 1;                                        // item number

                for (int j = 0; j < objPI.d3Pi.GetLength(0); j++) // row
                {
                    double tempPiVal = !CatRcs.Utils.CheckNaValues.IsNaNvalue(d3Pi[pi_index]) ? d3Pi[pi_index] : 0;

                    if (decimal.Round(Convert.ToDecimal(tempPiVal), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.d3Pi[j, i]), decimalPoint))
                    {
                        Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }

                    pi_index++;
                }
            }

            Assert.IsTrue(resultFlag);
            Console.WriteLine("Values of d3Pi are Matched!");

            #endregion
        }
Example #15
0
        // Optimization needed !!!
        public static double KL_Calc(CATItems itemBank, int item, int[] x, CATItems it_given, string model = null, double theta = 0, double[] priorPar = null, double[] X = null, double[] lik = null, int type = 1, double D = 1, string priorDist = "norm", double lower = -4, double upper = 4, int nqp = 33)
        {
            double res = 0;

            if ((type == (int)ModelNames.KLTypes.KL) || (type == (int)ModelNames.KLTypes.KLP))  // type is either "KL" or "KLP"
            {
                if (X != null && lik != null)
                {
                    if (X.Length > 0 && lik.Length > 0)
                    {
                        if (X.Length != lik.Length)
                        {
                            return(res); // Error handling
                        }
                    }
                }

                if (theta == 0)
                {
                    theta = CatRcs.ThetaEST.ThetaEst_Calc(it_given, x, D: D, model: model, method: CatRcs.Models.ModelNames.EstimaatorMethods.ML.EnumToString());
                }

                double[] KLF        = new double[nqp];
                double[] crit_value = new double[nqp];

                CATItems par = itemBank.FindItem(item);

                if (X == null)
                {
                    X = CatRcs.Utils.CommonHelper.Sequence(lower, upper, nqp);
                }

                if (String.IsNullOrEmpty(model))   // Dichotomous Items
                {
                    if (lik == null)
                    {
                        #region "Function 'L' "
                        Func <double, int[], CATItems, double> L = (th, r, param) =>
                        {
                            double result = 0;

                            var temp_1 = Pi.Pi_Calc(th, param, model, D).Pi.Select((p, i) => Math.Pow(p, r[i])).ToArray();

                            var temp_2 = Pi.Pi_Calc(th, param, model, D).Pi.Select((p, i) => Math.Pow(1 - p, 1 - r[i])).ToArray();

                            if (temp_1.Length == temp_2.Length)
                            {
                                var temp_3 = temp_1.Select((p, i) => p * temp_2[i]).ToArray();

                                result = temp_3.Aggregate((acc, val) => acc * val);
                            }

                            return(result);
                        };
                        #endregion

                        lik = X.ToList().Select(a => L(a, x, it_given)).ToArray();
                    }

                    for (int j = 0; j < KLF.Length; j++)
                    {
                        KLF[j] = Pi.Pi_Calc(theta, par, model, D).Pi[0] * Math.Log(Pi.Pi_Calc(theta, par, model, D).Pi[0] / Pi.Pi_Calc(X[j], par, model, D).Pi[0], Math.Exp(1))
                                 + (1 - Pi.Pi_Calc(theta, par, model, D).Pi[0]) * Math.Log((1 - Pi.Pi_Calc(theta, par, model, D).Pi[0]) / (1 - Pi.Pi_Calc(X[j], par, model, D).Pi[0]), Math.Exp(1));
                    }

                    crit_value = KLF.ToList().Select((c, i) => c * lik[i]).ToArray();

                    if ((type == (int)ModelNames.KLTypes.KLP))
                    {
                        double[] pd = null;

                        switch (priorDist)
                        {
                        case "norm":
                            pd = CatRcs.Utils.CommonHelper.Dnorm(X, priorPar[0], priorPar[1]);
                            break;

                        case "unif":
                            pd = CatRcs.Utils.CommonHelper.Dunif(X, priorPar[0], priorPar[1]);
                            break;
                        }

                        crit_value = crit_value.ToList().Select((c, i) => c * pd[i]).ToArray();
                    }
                }
                else   // Polytomous Items
                {
                    if (lik == null)
                    {
                        #region "Function 'LL' "
                        Func <double, CATItems, int[], double> LL = (th, param, r) =>
                        {
                            double result = 1;

                            double[,] prob = Pi.Pi_Poly_Calc(th, param, model, D).Pi;

                            for (int i = 0; i < r.Length; i++)
                            {
                                result = result * prob[i, r[i]];
                            }

                            return(result);
                        };
                        #endregion

                        lik = X.ToList().Select(a => LL(a, it_given, x)).ToArray();
                    }

                    double[,] pi = Pi.Pi_Poly_Calc(theta, par, model, D).Pi;

                    for (int i = 0; i < X.Length; i++)
                    {
                        double[,] pri = Pi.Pi_Poly_Calc(X[i], par, model, D).Pi;
                        double[] tempPi = new double[pi.Length];

                        for (int j = 0; j < pi.Length; j++)
                        {
                            tempPi[j] = pi[0, j] * Math.Log(pi[0, j] / pri[0, j]);
                        }

                        KLF[i] = CatRcs.Utils.RowColumn.Sum(tempPi);
                    }

                    crit_value = KLF.ToList().Select((c, i) => c * lik[i]).ToArray();

                    if ((type == (int)ModelNames.KLTypes.KLP))
                    {
                        double[] pd = null;

                        switch (priorDist)
                        {
                        case "norm":
                            pd = CatRcs.Utils.CommonHelper.Dnorm(X, priorPar[0], priorPar[1]);
                            break;

                        case "unif":
                            pd = CatRcs.Utils.CommonHelper.Dunif(X, priorPar[0], priorPar[1]);
                            break;
                        }

                        crit_value = crit_value.ToList().Select((c, i) => c * pd[i]).ToArray();
                    }
                }

                res = CatRcs.Integrate_catR.Integrate_CatR_Calc(X, crit_value);
            }
            else
            {
                return(res);
            }

            return(res);
        }
        public void test_StartItems_D(int numofItems)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Dichotomous Items
            DataFrame DichoItems = engineObj.Evaluate("DichoItems <- genDichoMatrix(items = " + numofItems + ")").AsDataFrame();

            engineObj.SetSymbol("DichoItems", DichoItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)
            CATItems itemBank = new CATItems(DichoItems[0].Length, false);

            // New Dictionary
            itemBank.SetItemParamter(CATItems.ColumnNames.a, DichoItems[0].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.b, DichoItems[1].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.c, DichoItems[2].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.d, DichoItems[3].Select(y => (double)y).ToArray());

            // Call "StartItems" function from R, "MFI" criterion
            GenericVector r_StartItems = engineObj.Evaluate("r_StartItems <- startItems(DichoItems, nrItems = 3, theta = 1, halfRange = 2)").AsList();

            // Resulting item numbers
            IntegerVector items = r_StartItems[0].AsInteger();

            DataFrame tempitems = r_StartItems[1].AsDataFrame();

            // Resulting Items
            CATItems r_CatItems = new CATItems(tempitems[0].Length, false);

            r_CatItems.SetItemParamter(CATItems.ColumnNames.a, tempitems[0].Select(y => (double)y).ToArray());
            r_CatItems.SetItemParamter(CATItems.ColumnNames.b, tempitems[1].Select(y => (double)y).ToArray());
            r_CatItems.SetItemParamter(CATItems.ColumnNames.c, tempitems[2].Select(y => (double)y).ToArray());
            r_CatItems.SetItemParamter(CATItems.ColumnNames.d, tempitems[3].Select(y => (double)y).ToArray());

            // Ability value
            NumericVector thStart = r_StartItems[2].AsNumeric();

            // Criterion
            CharacterVector startSelect = r_StartItems[3].AsCharacter();

            // Call "StartItems" function from CS
            StartItemsModel cs_StartItems = CatRLib.StartItems(itemBank, nrItems: 3, theta: 1, halfRange: 2);

            // Check selected items
            if (items.Length == cs_StartItems.items.Length)
            {
                for (int ind = 0; ind < cs_StartItems.items.Length; ind++)
                {
                    if (items[ind] != cs_StartItems.items[ind])
                    {
                        resultFlag = false;
                    }
                }
            }

            // Check starting ability values
            if (thStart.Length == cs_StartItems.thStart.Length)
            {
                for (int ind2 = 0; ind2 < cs_StartItems.thStart.Length; ind2++)
                {
                    if (thStart[ind2] != cs_StartItems.thStart[ind2])
                    {
                        resultFlag = false;
                    }
                }
            }

            Assert.IsTrue(resultFlag);
        }
        public void test_NextItem_D(int numofItems, ModelNames.CriterionTypes paramCriterion)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Dichotomous Items
            DataFrame DichoItems = engineObj.Evaluate("DichoItems <- genDichoMatrix(items = " + numofItems + ")").AsDataFrame();

            engineObj.SetSymbol("DichoItems", DichoItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)
            CATItems itemBank = new CATItems(DichoItems[0].Length, false);

            // New Dictionary
            itemBank.SetItemParamter(CATItems.ColumnNames.a, DichoItems[0].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.b, DichoItems[1].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.c, DichoItems[2].Select(y => (double)y).ToArray());
            itemBank.SetItemParamter(CATItems.ColumnNames.d, DichoItems[3].Select(y => (double)y).ToArray());

            // Call "thetaEst" function
            //NumericVector r_th = engineObj.Evaluate("r_th <- thetaEst(rbind(DichoItems[3,], DichoItems[13,]), c(0, 1), method = \"WL\")").AsNumeric();
            //engineObj.SetSymbol("r_th", r_th);

            //double cs_th = CatRLib.ThetaEst(itemBank.FindItem(new int[] { 3, 13 }), x: new int[] { 0, 1 }, model: "", method: ModelNames.EstimaatorMethods.WL.EnumToString());

            // Call "NextItem" function from R with parameter "out"
            GenericVector r_NextItem = engineObj.Evaluate("r_NextItem <- nextItem(DichoItems, theta = 0, out = c(3, 13), criterion = \"" + paramCriterion.ToString() + "\")").AsList();

            // Call "NextItem" function from R with response pattern "x"
            //GenericVector r_NextItem = engineObj.Evaluate("r_NextItem <- nextItem(DichoItems, x = c(0, 1), out = c(3, 13), theta = r_th, criterion = \"" + paramCriterion.ToString() + "\")").AsList();

            // Selected item
            NumericVector item = r_NextItem[0].AsNumeric();

            DataFrame par = r_NextItem[1].AsDataFrame();

            // Item parameter
            CATItems parItems = new CATItems(par[0].Length, false);

            parItems.SetItemParamter(CATItems.ColumnNames.a, par[0].Select(y => (double)y).ToArray());
            parItems.SetItemParamter(CATItems.ColumnNames.b, par[1].Select(y => (double)y).ToArray());
            parItems.SetItemParamter(CATItems.ColumnNames.c, par[2].Select(y => (double)y).ToArray());
            parItems.SetItemParamter(CATItems.ColumnNames.d, par[3].Select(y => (double)y).ToArray());

            // Value of "info"
            NumericVector info = r_NextItem[2].AsNumeric();

            // Criterion
            CharacterVector startSelect = r_NextItem[3].AsCharacter();

            // Call "NextItem" function from CS with parameter "out"
            NextItemModel cs_NextItem = CatRLib.NextItem(itemBank, theta: 0, Out: new int[] { 3, 13 }, criterion: (int)paramCriterion);

            // Call "NextItem" function from CS with response pattern "x"
            //NextItemModel cs_NextItem = CatRLib.NextItem(itemBank, theta: cs_th, Out: new int[] { 3, 13 }, x: new int[] { 0, 1 }, criterion: (int)paramCriterion);

            // Checking item & other values
            if (item[0] != cs_NextItem.item)
            {
                resultFlag = false;
            }

            if (decimal.Round((decimal)info[0], 3) != decimal.Round((decimal)cs_NextItem.info, 3))
            {
                resultFlag = false;
            }

            Assert.IsTrue(resultFlag);
        }
        public void test_StartItems_P(int numofItems, ModelNames.Models paramModel)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Polytomous Items
            CharacterVector modelName = engineObj.CreateCharacterVector(new string[] { paramModel.EnumToString() });

            engineObj.SetSymbol("modelName", modelName);
            DataFrame PolyItems = engineObj.Evaluate("PolyItems <- genPolyMatrix(" + numofItems + ", 5, model = modelName, same.nrCat = TRUE)").AsDataFrame();

            engineObj.SetSymbol("PolyItems", PolyItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)

            Console.WriteLine("*******************************************");
            Console.WriteLine("Polytomous Items, Model : " + paramModel.EnumToString());
            Console.WriteLine("*******************************************");

            CATItems itemBank = new CATItems(PolyItems[0].Length, paramModel.EnumToString(), 5);

            Tuple <CATItems.ColumnNames, int>[] cols = itemBank.GetKeys();

            for (int i = 0; i < cols.Length; i++)
            {
                itemBank.SetItemParamter(cols[i], PolyItems[i].Select(y => (double)y).ToArray());
            }

            // Call "StartItems" function from R, "MFI" criterion
            GenericVector r_StartItems = engineObj.Evaluate("r_StartItems <- startItems(PolyItems, model = modelName, nrItems = 3, theta = 1, halfRange = 2)").AsList();

            // Resulting item numbers
            IntegerVector items = r_StartItems[0].AsInteger();

            DataFrame tempitems = r_StartItems[1].AsDataFrame();

            // Resulting Items
            CATItems r_CatItems = new CATItems(tempitems[0].Length, paramModel.EnumToString(), 5);

            for (int i = 0; i < cols.Length; i++)
            {
                r_CatItems.SetItemParamter(cols[i], tempitems[i].Select(y => (double)y).ToArray());
            }

            // Resulting
            NumericVector   thStart     = r_StartItems[2].AsNumeric();
            CharacterVector startSelect = r_StartItems[3].AsCharacter();

            // Call "StartItems" function from CS
            StartItemsModel cs_StartItems = CatRLib.StartItems(itemBank, paramModel.EnumToString(), nrItems: 3, theta: 1, halfRange: 2);

            // Check items
            if (items.Length == cs_StartItems.items.Length)
            {
                for (int ind = 0; ind < cs_StartItems.items.Length; ind++)
                {
                    if (items[ind] != cs_StartItems.items[ind])
                    {
                        resultFlag = false;
                    }
                }
            }

            // Check starting ability values
            if (thStart.Length == cs_StartItems.thStart.Length)
            {
                for (int ind2 = 0; ind2 < cs_StartItems.thStart.Length; ind2++)
                {
                    if (thStart[ind2] != cs_StartItems.thStart[ind2])
                    {
                        resultFlag = false;
                    }
                }
            }

            Assert.IsTrue(resultFlag);
        }
Example #19
0
        public static IiList Ii_Calc(double th, CATItems it, string model, double D)
        {
            IiList objIi = null;

            double[] Ii = null; double[] dIi = null; double[] d2Ii = null;

            try
            {
                if (String.IsNullOrEmpty(model))
                {
                    #region "Calculation for Dichotmous Items"

                    double[] P = null; double[] dP = null; double[] d2P = null; double[] d3P = null;

                    PiList pr = Pi.Pi_Calc(th, it, model, D); // Check return value of Pi

                    if (pr == null)
                    {
                        objIi           = new IiList();
                        objIi.Exception = "No Pi values found!";
                        return(objIi);
                    }

                    P   = pr.Pi;
                    dP  = pr.dPi;
                    d2P = pr.d2Pi;
                    d3P = pr.d3Pi;

                    Ii   = new double[dP.Length];
                    dIi  = new double[d2P.Length];
                    d2Ii = new double[d3P.Length];

                    objIi = new IiList(P.Length);

                    double[] Q = new double[P.Length];

                    for (int i = 0; i < P.Length; i++)
                    {
                        Q[i] = 1 - P[i];
                    }

                    for (int j = 0; j < Ii.Length; j++)
                    {
                        Ii[j] = Math.Pow(dP[j], 2) / (P[j] * Q[j]);
                    }

                    for (int k = 0; k < dIi.Length; k++)
                    {
                        dIi[k] = dP[k] * (2 * P[k] * Q[k] * d2P[k] - Math.Pow(dP[k], 2) * (Q[k] - P[k])) / (Math.Pow(P[k], 2) * Math.Pow(Q[k], 2));
                    }

                    for (int l = 0; l < d2Ii.Length; l++)
                    {
                        d2Ii[l] = (2 * P[l] * Q[l] * (Math.Pow(d2P[l], 2) + dP[l] * d3P[l]) - 2 * Math.Pow(dP[l], 2) * d2P[l] * (Q[l] - P[l])) / (Math.Pow(P[l], 2) * Math.Pow(Q[l], 2)) -
                                  (3 * Math.Pow(P[l], 2) * Q[l] * Math.Pow(dP[l], 2) * d2P[l] - P[l] * Math.Pow(dP[l], 4) * (2 * Q[l] - P[l])) / (Math.Pow(P[l], 4) * Math.Pow(Q[l], 2)) +
                                  (3 * P[l] * Math.Pow(Q[l], 2) * Math.Pow(dP[l], 2) * d2P[l] - Q[l] * Math.Pow(dP[l], 4) * (Q[l] - 2 * P[l])) / (Math.Pow(P[l], 2) * Math.Pow(Q[l], 4));
                    }

                    #endregion
                }
                else
                {
                    #region "Calculation for Polytomous Items"

                    double[,] P = null; double[,] dP = null; double[,] d2P = null; double[,] d3P = null;

                    PiListPoly pr = Pi.Pi_Poly_Calc(th, it, model, D);

                    if (pr == null)
                    {
                        objIi           = new IiList();
                        objIi.Exception = "No Pi values found!";
                        return(objIi);
                    }

                    P   = pr.Pi;
                    dP  = pr.dPi;
                    d2P = pr.d2Pi;
                    d3P = pr.d3Pi;

                    int rowLength    = pr.Pi.GetLength(0);
                    int columnLength = pr.Pi.GetLength(1);

                    objIi = new IiList(rowLength);

                    double[,] pr0 = new double[rowLength, columnLength];
                    double[,] pr1 = new double[rowLength, columnLength];
                    double[,] pr2 = new double[rowLength, columnLength];

                    Ii   = new double[rowLength];
                    dIi  = new double[rowLength];
                    d2Ii = new double[rowLength];

                    for (int i = 0; i < rowLength; i++)
                    {
                        for (int j = 0; j < columnLength; j++)
                        {
                            pr0[i, j] = Math.Pow(dP[i, j], 2) / P[i, j];

                            pr1[i, j] = 2 * dP[i, j] * (d2P[i, j] / P[i, j]) - (Math.Pow(dP[i, j], 3) / Math.Pow(P[i, j], 2));

                            pr2[i, j] = (2 * Math.Pow(d2P[i, j], 2) + 2 * dP[i, j] * d3P[i, j]) / P[i, j] - 2 * Math.Pow(dP[i, j], 2) * (d2P[i, j] / -3) * dP[i, j] * (d2P[i, j] / Math.Pow(P[i, j], 2)) + 2 * (Math.Pow(dP[i, j], 4) / Math.Pow(P[i, j], 3));
                        }
                    }

                    Ii   = RowColumn.rowSums(pr0);
                    dIi  = RowColumn.rowSums(pr1);
                    d2Ii = RowColumn.rowSums(pr2);

                    #endregion
                }

                objIi.Add(Ii, dIi, d2Ii);
            }
            catch (Exception ex)
            {
                if (ex != null)
                {
                    if (objIi == null)
                    {
                        objIi = new IiList();
                    }
                    objIi.Exception = ex.Message;
                }
                return(objIi);
            }

            return(objIi);
        }
Example #20
0
        // Optimized CAT Items
        public static double EPV_Calc(CATItems itemBank, int item, int[] x, double theta, CATItems it_given, string model, double[] priorPar = null, int[] parInt = null, double D = 1, string priorDist = "norm")
        {
            double res = 0;

            double th = theta;

            if (priorPar == null || priorPar.Length < 2)
            {
                priorPar    = new double[2];
                priorPar[0] = 0;
                priorPar[1] = 1;
            }

            if (parInt == null || parInt.Length < 3)
            {
                parInt    = new int[3];
                parInt[0] = -4;
                parInt[1] = 4;
                parInt[2] = 33;
            }

            if (String.IsNullOrEmpty(model))  // Dichotomous Items
            {
                CATItems itj = itemBank.AddItem_D(it_given, new int[] { item });

                double p1 = Pi.Pi_Calc(th, itemBank, model, D).Pi[item - 1];  // item is matched with the array index

                double p0 = 1 - p1;

                int[] temp_x = new int[x.Length + 1];
                for (int i = 0; i < x.Length; i++)
                {
                    temp_x[i] = x[i];
                }
                temp_x[x.Length - 1] = 0;

                double th0 = EapEST.EapEST_Calc(itj, temp_x, "", priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]);

                double var0 = Math.Pow(EapSEM.EapSEM_Calc(th0, itj, temp_x, "", priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]), 2);

                temp_x = new int[x.Length + 1];
                for (int i = 0; i < x.Length; i++)
                {
                    temp_x[i] = x[i];
                }
                temp_x[x.Length - 1] = 1;

                double th1 = EapEST.EapEST_Calc(itj, temp_x, "", priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]);

                double var1 = Math.Pow(EapSEM.EapSEM_Calc(th1, itj, temp_x, "", priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]), 2);

                res = (p0 * var0) + (p1 * var1);
            }
            else                                                                // Polytomous Items  !!!! Optimization needed !!!!
            {
                double[,] temp_Pi = Pi.Pi_Poly_Calc(th, itemBank, model, D).Pi; // Already returns a NA free list of values.

                // !! Optimize !!
                List <double> probs = new List <double>();

                for (int i = 0; i < temp_Pi.GetLength(1); i++)
                {
                    probs.Add(temp_Pi[0, i]);
                }

                // !!!! Add new method for polytomous items !!!!
                CATItems it_new = it_given;

                double[]   th_new = new double[probs.Count];
                double[]   se_new = new double[probs.Count];
                List <int> temp_x = new List <int>();

                for (int j = 0; j < probs.Count; j++)
                {
                    temp_x = x.ToList();
                    temp_x.Add(j);

                    th_new[j] = EapEST.EapEST_Calc(it_new, temp_x.ToArray(), "", priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]);

                    se_new[j] = Math.Pow(EapSEM.EapSEM_Calc(th_new[j], it_new, temp_x.ToArray(), "", priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]), 2);
                }

                res = CatRcs.Utils.RowColumn.Sum(probs.Select((p, s) => p * se_new[s]).ToArray());
            }

            return(res);
        }
Example #21
0
        internal static double EapSEM_Calc(double thEst, CATItems it, int[] x, string model, double[] priorPar = null, double D = 1, string priorDist = "norm", double lower = -4, double upper = 4, double nqp = 33)
        {
            double res = 0;

            double[] X = CatRcs.Utils.CommonHelper.Sequence(lower, upper, nqp);
            double[] Y1 = null; double[] Y2 = null;

            if (priorPar == null || priorPar.Length < 2)
            {
                priorPar    = new double[2];
                priorPar[0] = 0;
                priorPar[1] = 1;
            }

            if (String.IsNullOrEmpty(model))   // Dichotomous Items
            {
                #region "Function 'L' "
                Func <double, CATItems, int[], double> L = (th, items, x_in) =>
                {
                    double result = 0;

                    double[] pi = Pi.Pi_Calc(th, it, model, D).Pi;

                    double[] x_p = new double[pi.Length]; double[] x_q = new double[pi.Length]; double[] p_q = new double[pi.Length];

                    for (int ind_p = 0; ind_p < pi.Length; ind_p++)
                    {
                        x_p[ind_p] = Math.Pow(pi[ind_p], x_in[ind_p]);;
                        x_q[ind_p] = Math.Pow(1 - pi[ind_p], 1 - x_in[ind_p]);
                        p_q[ind_p] = x_p[ind_p] * x_q[ind_p];
                    }

                    result = p_q.Aggregate((acc, val) => acc * val);

                    return(result);
                };
                #endregion

                #region "Function 'g' "
                Func <double[], double[]> g = (s) =>
                {
                    double[] resList = new double[s.Length];

                    for (int i = 0; i < s.Length; i++)
                    {
                        switch (priorDist)
                        {
                        case "norm":
                            resList[i] = Math.Pow(s[i] - thEst, 2) * CatRcs.Utils.CommonHelper.Dnorm(s[i], priorPar[0], priorPar[1]) * L(s[i], it, x);
                            break;

                        case "unif":
                            resList[i] = Math.Pow(s[i] - thEst, 2) * CatRcs.Utils.CommonHelper.Dunif(s[i], priorPar[0], priorPar[1]) * L(s[i], it, x);
                            break;

                        case "Jeffreys":
                            resList[i] = Math.Pow(s[i] - thEst, 2) * Math.Sqrt(CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(s[i], it, model, D).Ii)) * L(s[i], it, x);
                            break;
                        }
                    }

                    return(resList);
                };
                #endregion

                #region "Function 'h' "
                Func <double[], double[]> h = (s) =>
                {
                    double[] resList = new double[s.Length];

                    for (int i = 0; i < s.Length; i++)
                    {
                        switch (priorDist)
                        {
                        case "norm":
                            resList[i] = CatRcs.Utils.CommonHelper.Dnorm(s[i], priorPar[0], priorPar[1]) * L(s[i], it, x);
                            break;

                        case "unif":
                            resList[i] = CatRcs.Utils.CommonHelper.Dunif(s[i], priorPar[0], priorPar[1]) * L(s[i], it, x);
                            break;

                        case "Jeffreys":
                            resList[i] = Math.Sqrt(CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(s[i], it, model, D).Ii)) * L(s[i], it, x);
                            break;
                        }
                    }

                    return(resList);
                };
                #endregion

                Y1 = g(X);
                Y2 = h(X);
            }
            else   // Polytomous Items
            {
                #region "Function 'LL' "
                Func <double, CATItems, int[], double> LL = (th, items, x_in) =>
                {
                    double result = 1;

                    double[,] prob = Pi.Pi_Poly_Calc(th, it, model, D).Pi;

                    for (int i = 0; i < x_in.Length; i++)
                    {
                        result = result * prob[i, x_in[i]];
                    }

                    return(result);
                };
                #endregion

                #region "Function 'gg' "
                Func <double[], double[]> gg = (s) =>
                {
                    double[] resList = new double[s.Length];

                    for (int i = 0; i < s.Length; i++)
                    {
                        switch (priorDist)
                        {
                        case "norm":
                            resList[i] = Math.Pow(s[i] - thEst, 2) * CatRcs.Utils.CommonHelper.Dnorm(s[i], priorPar[0], priorPar[1]) * LL(s[i], it, x);
                            break;

                        case "unif":
                            resList[i] = Math.Pow(s[i] - thEst, 2) * CatRcs.Utils.CommonHelper.Dunif(s[i], priorPar[0], priorPar[1]) * LL(s[i], it, x);
                            break;

                        case "Jeffreys":
                            resList[i] = Math.Pow(s[i] - thEst, 2) * Math.Sqrt(CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(s[i], it, model, D).Ii)) * LL(s[i], it, x);
                            break;
                        }
                    }

                    return(resList);
                };
                #endregion

                #region "Function 'hh' "
                Func <double[], double[]> hh = (s) =>
                {
                    double[] resList = new double[s.Length];

                    for (int i = 0; i < s.Length; i++)
                    {
                        switch (priorDist)
                        {
                        case "norm":
                            resList[i] = CatRcs.Utils.CommonHelper.Dnorm(s[i], priorPar[0], priorPar[1]) * LL(s[i], it, x);
                            break;

                        case "unif":
                            resList[i] = CatRcs.Utils.CommonHelper.Dunif(s[i], priorPar[0], priorPar[1]) * LL(s[i], it, x);
                            break;

                        case "Jeffreys":
                            resList[i] = Math.Sqrt(CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(s[i], it, model, D).Ii)) * LL(s[i], it, x);
                            break;
                        }
                    }

                    return(resList);
                };
                #endregion

                Y1 = gg(X);
                Y2 = hh(X);
            }

            if ((Y1 != null) && (Y2 != null))
            {
                res = Math.Sqrt(CatRcs.Integrate_catR.Integrate_CatR_Calc(X, Y1) / CatRcs.Integrate_catR.Integrate_CatR_Calc(X, Y2));
            }

            return(res);
        }
Example #22
0
        public static double ThetaEst_Calc(CATItems it, int[] x, string model = null, double[] priorPar = null, double[] range = null, int[] parInt = null, double D = 1, string method = "BM", string priorDist = "norm")
        {
            double result = 0; double[] RANGE = null;

            #region "Parameter Validation"

            if (priorPar == null || priorPar.Length < 2)
            {
                priorPar    = new double[2];
                priorPar[0] = 0;
                priorPar[1] = 1;
            }

            if (range == null || range.Length < 2)
            {
                range    = new double[2];
                range[0] = -4;
                range[1] = 4;
            }

            if (parInt == null || parInt.Length < 3)
            {
                parInt    = new int[3];
                parInt[0] = -4;
                parInt[1] = 4;
                parInt[2] = 33;
            }

            #endregion

            if (method == ModelNames.EstimaatorMethods.EAP.EnumToString())
            {
                result = EapEST.EapEST_Calc(it, x, model, priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]);
            }
            else
            {
                if (String.IsNullOrEmpty(model))   // Dichotomous Items
                {
                    #region "Function 'r0' "
                    Func <double, string, double> r0 = (th, met) =>
                    {
                        double res = 0;

                        if (met == ModelNames.EstimaatorMethods.BM.EnumToString())
                        {
                            switch (priorDist)
                            {
                            case "norm":
                                res = (priorPar[0] - th) / Math.Pow(priorPar[1], 2);
                                break;

                            case "unif":
                                res = 0;
                                break;

                            case "Jeffreys":
                                IiList objIi = Ii.Ii_Calc(th, it, model, D);
                                res = CatRcs.Utils.RowColumn.Sum(objIi.dIi) / (2 * CatRcs.Utils.RowColumn.Sum(objIi.Ii));
                                break;
                            }
                        }
                        else
                        {
                            ModelNames.EstimaatorMethods md = ModelNames.StringToEnumMethods(met);

                            switch (md)
                            {
                            case ModelNames.EstimaatorMethods.ML:
                                res = 0;
                                break;

                            case ModelNames.EstimaatorMethods.WL:
                                res = CatRcs.Utils.RowColumn.Sum(Ji.Ji_Calc(th, it, model, D).Ji) / (2 * CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(th, it, model, D).Ii));
                                break;
                            }
                        }

                        return(res);
                    };
                    #endregion

                    #region "Function 'r' "
                    Func <double, double> r = (th) =>
                    {
                        double   res = 0;
                        double[] Q   = new double[it.NumOfItems], x_p = new double[it.NumOfItems], p_q = new double[it.NumOfItems], temp = new double[it.NumOfItems];

                        double[] pi  = Pi.Pi_Calc(th, it, model, D).Pi;
                        double[] dpi = Pi.Pi_Calc(th, it, model, D).dPi;

                        for (int ind_p = 0; ind_p < pi.Length; ind_p++)
                        {
                            Q[ind_p]    = 1 - pi[ind_p];
                            x_p[ind_p]  = x[ind_p] - pi[ind_p];
                            p_q[ind_p]  = pi[ind_p] * Q[ind_p];
                            temp[ind_p] = dpi[ind_p] * (x_p[ind_p] / p_q[ind_p]);
                        }

                        res = temp.Sum();

                        return(res);
                    };
                    #endregion

                    #region "Function 'f' "
                    Func <double, double> f = (th) =>
                    {
                        double res = 0;
                        return(res);
                    };


                    if (method == ModelNames.EstimaatorMethods.BM.EnumToString() && priorDist == "unif")
                    {
                        f = (th) =>
                        {
                            double res = 0;

                            string methodName = ModelNames.EstimaatorMethods.ML.EnumToString();

                            res = r0(th, methodName) + r(th);

                            return(res);
                        };
                    }
                    else
                    {
                        f = (th) =>
                        {
                            double res = 0;

                            res = r0(th, method) + r(th);

                            return(res);
                        };
                    }

                    #endregion

                    if (method == ModelNames.EstimaatorMethods.BM.EnumToString() && priorDist == "unif")
                    {
                        RANGE = priorPar;
                    }
                    else
                    {
                        RANGE = range;
                    }

                    if (f(RANGE[0]) < 0 && f(RANGE[1]) < 0)
                    {
                        result = RANGE[0];
                    }
                    else
                    {
                        if (f(RANGE[0]) > 0 && f(RANGE[1]) > 0)
                        {
                            result = RANGE[1];
                        }
                        else
                        {
                            result = CatRcs.Utils.Maths.UniRoot(f, RANGE).root;
                        }
                    }
                }
                else   // Polytomous Items
                {
                    int met = 0, pd = 0;
                    ModelNames.EstimaatorMethods md = ModelNames.StringToEnumMethods(method);

                    #region "Conditional Block"

                    switch (md)
                    {
                    case ModelNames.EstimaatorMethods.ML:
                        met = 1;
                        break;

                    case ModelNames.EstimaatorMethods.BM:
                        met = 2;
                        break;

                    case ModelNames.EstimaatorMethods.WL:
                        met = 3;
                        break;

                    case ModelNames.EstimaatorMethods.EAP:
                        met = 4;
                        break;
                    }

                    switch (priorDist)
                    {
                    case "norm":
                        pd = 1;
                        break;

                    case "unif":
                        pd = 2;
                        break;

                    case "Jeffreys":
                        pd = 3;
                        break;
                    }

                    if (met == 2 && pd == 2)
                    {
                        RANGE    = new double[priorPar.Length];
                        RANGE[0] = Math.Max(priorPar[0], range[0]);
                        RANGE[1] = Math.Min(priorPar[1], range[1]);
                    }
                    else
                    {
                        RANGE = range;
                    }

                    #endregion

                    #region "Function 'dl' "
                    Func <double, double> dl = (th) =>
                    {
                        double res = 0;

                        PiListPoly p = Pi.Pi_Poly_Calc(th, it, model, D);
                        double[,] pr  = p.Pi;
                        double[,] dpr = p.dPi;

                        for (int i = 0; i < x.Length; i++)
                        {
                            res = res + dpr[i, x[i]] / pr[i, x[i]];
                        }

                        return(res);
                    };
                    #endregion

                    #region "Function 'f0' "
                    Func <double, double> f0 = (th) =>
                    {
                        double res = 0;

                        if (met == 2)
                        {
                            switch (pd.ToString())
                            {
                            case "1":
                                res = (priorPar[0] - th) / Math.Pow(priorPar[1], 2);
                                break;

                            case "2":
                                res = 0;
                                break;

                            case "3":
                                IiList objIi = CatRcs.Ii.Ii_Calc(th, it, model, D);
                                res = CatRcs.Utils.RowColumn.Sum(objIi.dIi) / (2 * CatRcs.Utils.RowColumn.Sum(objIi.Ii));
                                break;
                            }
                        }
                        else
                        {
                            switch (met.ToString())
                            {
                            case "1":
                                res = 0;
                                break;

                            case "2":
                                res = 0;
                                break;

                            case "3":
                                res = CatRcs.Utils.RowColumn.Sum(CatRcs.Ji.Ji_Calc(th, it, model, D).Ji) / (2 * CatRcs.Utils.RowColumn.Sum(CatRcs.Ii.Ii_Calc(th, it, model, D).Ii));
                                break;
                            }
                        }

                        return(res);
                    };
                    #endregion

                    #region "Function 'optF' "
                    Func <double, double> optF = (th) =>
                    {
                        double res = 0;
                        res = dl(th) + f0(th);
                        return(res);
                    };
                    #endregion

                    if (optF(RANGE[0]) < 0 && optF(RANGE[1]) < 0)
                    {
                        result = RANGE[0];
                    }
                    else
                    {
                        if (optF(RANGE[0]) > 0 && optF(RANGE[1]) > 0)
                        {
                            result = RANGE[1];
                        }
                        else
                        {
                            result = CatRcs.Utils.Maths.UniRoot(optF, RANGE).root;
                        }
                    }
                }
            }

            return(result);
        }
Example #23
0
        public static double SemTheta_Calc(double thEst, CATItems it, int[] x = null, string model = null, double[] priorPar = null, int[] parInt = null, double D = 1, string method = "BM", string priorDist = "norm")
        {
            double result = 0;

            if (priorPar == null || priorPar.Length < 2)
            {
                priorPar    = new double[2];
                priorPar[0] = 0;
                priorPar[1] = 1;
            }

            if (parInt == null || parInt.Length < 3)
            {
                parInt    = new int[3];
                parInt[0] = -4;
                parInt[1] = 4;
                parInt[2] = 33;
            }

            if (method == ModelNames.EstimaatorMethods.EAP.EnumToString())
            {
                result = EapSEM.EapSEM_Calc(thEst, it, x, model, priorPar, D, priorDist, parInt[0], parInt[1], parInt[2]);
            }
            else
            {
                if (String.IsNullOrEmpty(model))   // Dichotomous Items
                {
                    #region "Function 'dr0' "
                    Func <double> dr0 = () =>
                    {
                        double res = 0;

                        if (method == ModelNames.EstimaatorMethods.BM.EnumToString())
                        {
                            switch (priorDist)
                            {
                            case "norm":
                                res = -1 / (Math.Pow(priorPar[1], 2));
                                break;

                            case "unif":
                                res = 0;
                                break;

                            case "Jeffreys":
                                IiList objIi = Ii.Ii_Calc(thEst, it, model, D);
                                res = (CatRcs.Utils.RowColumn.Sum(objIi.d2Ii) * CatRcs.Utils.RowColumn.Sum(objIi.Ii)
                                       - Math.Pow(CatRcs.Utils.RowColumn.Sum(objIi.dIi), 2)) / (2 * Math.Pow(CatRcs.Utils.RowColumn.Sum(objIi.Ii), 2));
                                break;
                            }
                        }
                        else
                        {
                            if (method == ModelNames.EstimaatorMethods.ML.EnumToString() || method == ModelNames.EstimaatorMethods.WL.EnumToString())
                            {
                                res = 0;
                            }
                        }

                        return(res);
                    };
                    #endregion

                    result = 1 / Math.Sqrt(-dr0() + CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(thEst, it, model, D).Ii));
                }
                else   // Polytomous Items
                {
                    double met = 0, pd = 0, optI = 0;
                    ModelNames.EstimaatorMethods md = ModelNames.StringToEnumMethods(method);

                    switch (md)
                    {
                    case ModelNames.EstimaatorMethods.ML:
                        met = 1;
                        break;

                    case ModelNames.EstimaatorMethods.BM:
                        met = 2;
                        break;

                    case ModelNames.EstimaatorMethods.WL:
                        met = 3;
                        break;

                    case ModelNames.EstimaatorMethods.EAP:
                        met = 4;
                        break;
                    }

                    switch (priorDist)
                    {
                    case "norm":
                        pd = 1;
                        break;

                    case "unif":
                        pd = 2;
                        break;

                    case "Jeffreys":
                        pd = 3;
                        break;
                    }

                    if (met == 1 || (met == 2 && pd == 2))
                    {
                        optI = CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(thEst, it, model, D).Ii);
                    }

                    if (met == 2 && pd == 1)
                    {
                        optI = CatRcs.Utils.RowColumn.Sum(Ii.Ii_Calc(thEst, it, model, D).Ii) + (1 / Math.Pow(priorPar[1], 2));
                    }

                    if (met == 3 || (met == 2 && pd == 3))
                    {
                        IiList objIi = Ii.Ii_Calc(thEst, it, model, D);

                        if (met == 2)
                        {
                            optI = CatRcs.Utils.RowColumn.Sum(objIi.Ii) + (Math.Pow(CatRcs.Utils.RowColumn.Sum(objIi.dIi), 2) - CatRcs.Utils.RowColumn.Sum(objIi.d2Ii) *
                                                                           CatRcs.Utils.RowColumn.Sum(objIi.Ii)) / (2 * Math.Pow(CatRcs.Utils.RowColumn.Sum(objIi.Ii), 2));
                        }
                        else
                        {
                            optI = CatRcs.Utils.RowColumn.Sum(objIi.Ii);
                        }
                    }

                    result = 1 / Math.Sqrt(optI);
                }
            }

            return(result);
        }
Example #24
0
        public void testKL_P(int NumOfItems, ModelNames.Models paramModel)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Polytomous Items
            CharacterVector modelName = engineObj.CreateCharacterVector(new string[] { paramModel.EnumToString() });

            engineObj.SetSymbol("modelName", modelName);
            DataFrame PolyItems = engineObj.Evaluate("PolyItems <- genPolyMatrix(" + NumOfItems + ", 5, model = modelName, same.nrCat = TRUE)").AsDataFrame();

            engineObj.SetSymbol("PolyItems", PolyItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)

            Console.WriteLine("*******************************************");
            Console.WriteLine("Polytomous Items, Model : " + paramModel.EnumToString());
            Console.WriteLine("*******************************************");

            CATItems itemBank = new CATItems(PolyItems[0].Length, paramModel.EnumToString(), 5);

            Tuple <CATItems.ColumnNames, int>[] cols = itemBank.GetKeys();

            for (int i = 0; i < cols.Length; i++)
            {
                itemBank.SetItemParamter(cols[i], PolyItems[i].Select(y => (double)y).ToArray());
            }


            DataFrame it_given_R = engineObj.Evaluate("it_given_R <- PolyItems[c(4, 8),]").AsDataFrame();

            engineObj.SetSymbol("it_given_R", it_given_R);

            CATItems it_given = itemBank.FindItem(new int[] { 4, 8 });

            //Creation of a response pattern for theta value
            engineObj.Evaluate("set.seed(1)");
            NumericVector x_val = engineObj.Evaluate("x_val <- genPattern(0, it_given_R, model = modelName)").AsNumeric();

            engineObj.SetSymbol("x_val", x_val);

            int[] x = x_val.Select(y => (int)y).ToArray();

            // Call "thetaEST" function from R,   method = \"ML\"
            NumericVector Theta = engineObj.Evaluate("Theta <- thetaEst(it_given_R, x_val, method = \"ML\", model = modelName)").AsNumeric();

            // Call "KL" function from R
            NumericVector r_KL = engineObj.Evaluate("r_KL <- KL(PolyItems, 1, x_val, it_given_R, theta = Theta, model = modelName)").AsNumeric();

            // Call "thetaEST" function from CS
            double th_est = CatRLib.ThetaEst(it_given, x, paramModel.EnumToString(), method: "ML");

            // Call "KL" function from CS
            double cs_KL = CatRLib.KL(itemBank, 1, x, it_given, paramModel.EnumToString(), theta: th_est);

            if (r_KL[0] - cs_KL > testEpsilon)
            {
                resultFlag = false;
            }

            Assert.IsTrue(resultFlag);
        }
Example #25
0
        // Pi method for Polytomous Items
        public static PiListPoly Pi_Poly_Calc(double th, CATItems it, string model, double D)
        {
            PiListPoly objPi = null;

            double[,] prov = null, prov1 = null, prov2 = null, prov3 = null;

            try
            {
                if (!String.IsNullOrEmpty(model))
                {
                    ModelNames.Models model_Name = ModelNames.StringToEnum(model);

                    if (model_Name == ModelNames.Models.GRM || model_Name == ModelNames.Models.MGRM)
                    {
                        #region "Variable Declarations"

                        if (model_Name == ModelNames.Models.GRM)
                        {
                            prov  = new double[it.NumOfItems, it.colSize];
                            prov1 = new double[it.NumOfItems, it.colSize];
                            prov2 = new double[it.NumOfItems, it.colSize];
                            prov3 = new double[it.NumOfItems, it.colSize];

                            objPi = new PiListPoly(it.NumOfItems, it.colSize);
                        }

                        if (model_Name == ModelNames.Models.MGRM)
                        {
                            prov  = new double[it.NumOfItems, it.colSize - 1];
                            prov1 = new double[it.NumOfItems, it.colSize - 1];
                            prov2 = new double[it.NumOfItems, it.colSize - 1];
                            prov3 = new double[it.NumOfItems, it.colSize - 1];

                            objPi = new PiListPoly(it.NumOfItems, it.colSize - 1);
                        }

                        #endregion

                        #region "Functional Logic"

                        for (int i = 0; i < it.NumOfItems; i++)  // Traversing through items
                        {
                            // "alphaj", 1st column
                            double aj = it.all_items_poly[0][i];

                            // Calculation of "betaj" vector values
                            double[] bj = null;

                            // "GRM"
                            if (model_Name == ModelNames.Models.GRM)
                            {
                                bj = new double[it.colSize - 1];  // Values starting from 2nd column
                                int b_Index = 1;

                                for (int k = 0; k < bj.Length; k++)
                                {
                                    bj[k] = it.all_items_poly[b_Index][i];;

                                    b_Index++;
                                }
                            }
                            else  // "MGRM"
                            {
                                // "betaj", 2nd column
                                double bj0 = it.all_items_poly[1][i];

                                bj = new double[it.colSize - 2];  // Values starting from 3rd column
                                int c_Index = 2;

                                for (int k = 0; k < bj.Length; k++)
                                {
                                    bj[k] = bj0 - it.all_items_poly[c_Index][i];

                                    c_Index++;
                                }
                            }

                            // Final Array must be NaN value free
                            bj = CheckNaValues.GetArrayWithoutNaN(bj);

                            double[] ej    = new double[bj.Length];
                            double[] Pjs   = new double[bj.Length + 2];
                            double[] dPjs  = new double[Pjs.Length];
                            double[] d2Pjs = new double[Pjs.Length];
                            double[] d3Pjs = new double[Pjs.Length];

                            Pjs[0] = 1.000;              // 1st Column
                            Pjs[Pjs.Length - 1] = 0.000; // last column

                            for (int m = 0; m < bj.Length; m++)
                            {
                                // Calculation of "ej"
                                ej[m] = Math.Exp(D * aj * (th - bj[m]));

                                // Calculation of "Pjs"
                                Pjs[m + 1] = ej[m] / (1 + ej[m]);
                            }

                            // Calculation of "dPj", "d2Pj", "d3Pj"
                            for (int j = 0; j < Pjs.Length; j++)
                            {
                                dPjs[j]  = D * aj * Pjs[j] * (1 - Pjs[j]);
                                d2Pjs[j] = D * aj * (dPjs[j] - 2 * Pjs[j] * dPjs[j]);
                                d3Pjs[j] = D * aj * (d2Pjs[j] - 2 * Math.Pow(dPjs[j], 2) - 2 * Pjs[j] * d2Pjs[j]);
                            }

                            for (int index = 0; index < Pjs.Length - 1; index++)
                            {
                                prov[i, index]  = Pjs[index] - Pjs[index + 1];
                                prov1[i, index] = dPjs[index] - dPjs[index + 1];
                                prov2[i, index] = d2Pjs[index] - d2Pjs[index + 1];
                                prov3[i, index] = d3Pjs[index] - d3Pjs[index + 1];
                            }
                        }

                        #endregion
                    }
                    else if (model_Name == ModelNames.Models.PCM || model_Name == ModelNames.Models.GPCM || model_Name == ModelNames.Models.RSM || model_Name == ModelNames.Models.NRM)
                    {
                        double[] dj = null; double[] v = null;  // Common column for the following models

                        if (model_Name == ModelNames.Models.PCM)
                        {
                            #region "Variable Declarations"

                            prov  = new double[it.NumOfItems, it.colSize + 1];
                            prov1 = new double[it.NumOfItems, it.colSize + 1];
                            prov2 = new double[it.NumOfItems, it.colSize + 1];
                            prov3 = new double[it.NumOfItems, it.colSize + 1];

                            objPi = new PiListPoly(it.NumOfItems, it.colSize + 1);

                            #endregion

                            #region "Functional Logic"

                            for (int i = 0; i < it.NumOfItems; i++)
                            {
                                dj = new double[it.colSize + 1];
                                v  = new double[it.colSize + 1];

                                dj[0] = 0.00; v[0] = 0.00;

                                for (int k = 1; k < dj.Length; k++)
                                {
                                    dj[k] = dj[k - 1] + D * (th - it.all_items_poly[k - 1][i]);
                                    v[k]  = k;
                                }

                                double[][] temp_dj_v = CheckNaValues.GetArrayWithoutNaN(dj, v);
                                dj = temp_dj_v[0];
                                v  = temp_dj_v[1];

                                calculatePolyPi(dj, prov, prov1, prov2, prov3, v, i);
                            }

                            #endregion
                        }

                        if (model_Name == ModelNames.Models.GPCM)
                        {
                            #region "Variable Declarations"

                            prov  = new double[it.NumOfItems, it.colSize];
                            prov1 = new double[it.NumOfItems, it.colSize];
                            prov2 = new double[it.NumOfItems, it.colSize];
                            prov3 = new double[it.NumOfItems, it.colSize];

                            objPi = new PiListPoly(it.NumOfItems, it.colSize);

                            #endregion

                            #region "Functional Logic"

                            for (int i = 0; i < it.NumOfItems; i++)
                            {
                                // "alphaj", 1st column
                                double aj = it.all_items_poly[0][i];

                                dj    = new double[it.colSize];
                                v     = new double[it.colSize];
                                dj[0] = 0.00; v[0] = 0.00;

                                for (int k = 1; k < dj.Length; k++)
                                {
                                    dj[k] = dj[k - 1] + aj * D * (th - it.all_items_poly[k][i]);
                                    v[k]  = aj * k;
                                }

                                double[][] temp_dj_v = CheckNaValues.GetArrayWithoutNaN(dj, v);
                                dj = temp_dj_v[0];
                                v  = temp_dj_v[1];

                                calculatePolyPi(dj, prov, prov1, prov2, prov3, v, i);
                            }

                            #endregion
                        }

                        if (model_Name == ModelNames.Models.RSM)
                        {
                            #region "Variable Declarations"

                            prov  = new double[it.NumOfItems, it.colSize];
                            prov1 = new double[it.NumOfItems, it.colSize];
                            prov2 = new double[it.NumOfItems, it.colSize];
                            prov3 = new double[it.NumOfItems, it.colSize];

                            objPi = new PiListPoly(it.NumOfItems, it.colSize);

                            #endregion

                            #region "Functional Logic"

                            for (int i = 0; i < it.NumOfItems; i++)
                            {
                                // "lambdaj", 1st column
                                double lambdaj = it.all_items_poly[0][i];

                                dj    = new double[it.colSize];
                                v     = new double[it.colSize];
                                dj[0] = 0.00; v[0] = 0.00;

                                for (int k = 1; k < dj.Length; k++)
                                {
                                    dj[k] = dj[k - 1] + D * (th - (lambdaj + it.all_items_poly[k][i]));
                                    v[k]  = k;
                                }

                                double[][] temp_dj_v = CheckNaValues.GetArrayWithoutNaN(dj, v);
                                dj = temp_dj_v[0];
                                v  = temp_dj_v[1];

                                calculatePolyPi(dj, prov, prov1, prov2, prov3, v, i);
                            }

                            #endregion
                        }

                        if (model_Name == ModelNames.Models.NRM)
                        {
                            #region "Variable Declarations"

                            int nc = (it.colSize / 2) + 1;

                            prov  = new double[it.NumOfItems, nc];
                            prov1 = new double[it.NumOfItems, nc];
                            prov2 = new double[it.NumOfItems, nc];
                            prov3 = new double[it.NumOfItems, nc];

                            objPi = new PiListPoly(it.NumOfItems, nc);

                            #endregion

                            #region "Functional Logic"

                            for (int i = 0; i < it.NumOfItems; i++)  // Row Iteration
                            {
                                dj    = new double[nc];
                                v     = new double[nc];
                                dj[0] = 0.00; v[0] = 0.00;

                                for (int k = 1; k < dj.Length; k++)
                                {
                                    dj[k] = it.all_items_poly[2 * (k - 2) + 2][i] * th + it.all_items_poly[2 * (k - 2) + 3][i];
                                    v[k]  = it.all_items_poly[2 * (k - 2) + 2][i];
                                }

                                double[][] temp_dj_v = CheckNaValues.GetArrayWithoutNaN(dj, v);
                                dj = temp_dj_v[0];
                                v  = temp_dj_v[1];

                                calculatePolyPi(dj, prov, prov1, prov2, prov3, v, i);
                            }

                            #endregion
                        }
                    }
                    else
                    {
                        objPi.Exception = "Polytomous items model not matched!";
                    }
                }
                else
                {
                    objPi.Exception = "Polytomous model not provided!";
                }

                objPi.Add(prov, prov1, prov2, prov3);

                //objPi.catDictionaryList = new Dictionary<string, Dictionary<string, catList>>();

                //GetCATList(objPi.Pi, objPi.catDictionaryList, "Pi");
                //GetCATList(objPi.dPi, objPi.catDictionaryList, "dPi");
                //GetCATList(objPi.d2Pi, objPi.catDictionaryList, "d2Pi");
                //GetCATList(objPi.d3Pi, objPi.catDictionaryList, "d3Pi");
            }
            catch (Exception ex)
            {
                if (ex != null)
                {
                    if (objPi == null)
                    {
                        objPi = new PiListPoly();
                    }
                    objPi.Exception = ex.Message;
                }

                return(objPi);
            }

            return(objPi);
        }
Example #26
0
        public static void Main(string[] args)
        {
            //f<double[], double> delObj = new f<double[], double>(Method2);
            //Console.WriteLine(delObj(new double[] {1, 4, 5}).ToString());

            ModelNames.Models paramModel = ModelNames.Models.GRM;
            int NumOfItems = 50;

            resultFlag = true;
            var stopwatch = new Stopwatch();

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Polytomous Items
            CharacterVector modelName = engineObj.CreateCharacterVector(new string[] { paramModel.EnumToString() });

            engineObj.SetSymbol("modelName", modelName);
            DataFrame PolyItems = engineObj.Evaluate("PolyItems <- genPolyMatrix(" + NumOfItems + ", 5, model = modelName, same.nrCat = TRUE)").AsDataFrame();

            engineObj.SetSymbol("PolyItems", PolyItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)

            Console.WriteLine("*******************************************");
            Console.WriteLine("Polytomous Items, Model : " + paramModel.EnumToString());
            Console.WriteLine("*******************************************");

            CATItems itemBank = new CATItems(NumOfItems: NumOfItems, model: paramModel.EnumToString(), nrCat: 5);

            for (int i = 0; i < itemBank.colSize; i++)
            {
                itemBank.all_items_poly[i] = PolyItems[i].Select(y => (double)y).ToArray();
            }

            //Creation of a response pattern
            engineObj.Evaluate("set.seed(1)");
            NumericVector x_val = engineObj.Evaluate("x_val <- genPattern(0, PolyItems, model = modelName)").AsNumeric();

            engineObj.SetSymbol("x_val", x_val);

            int[] x = x_val.Select(y => (int)y).ToArray();

            Console.WriteLine("Start of R Processing: " + DateTime.Now.TimeOfDay.ToString());
            stopwatch.Restart();

            // Call "ThetaEST" function from R,   method = \"ML\"
            NumericVector r_ThetaEst = engineObj.Evaluate("r_ThetaEst  <- thetaEst(PolyItems, x_val, model = modelName, method = \"BM\", priorDist = \"norm\", priorPar = c(-2, 2))").AsNumeric();

            engineObj.SetSymbol("r_ThetaEst", r_ThetaEst);

            Console.WriteLine("R Time taken: " + stopwatch.ElapsedMilliseconds);
            Console.WriteLine("R Theta Calculation Finished on: " + DateTime.Now.TimeOfDay.ToString());

            double[] priorPar = new double[2]; priorPar[0] = -2; priorPar[1] = 2;

            Console.WriteLine("Start of CS Processing: " + DateTime.Now.TimeOfDay.ToString());
            stopwatch.Restart();

            // Call "ThetaEST" function from CS
            double cs_ThetaEst = CatRLib.ThetaEst(it: itemBank, x: x, method: "BM", model: paramModel.EnumToString(), priorPar: priorPar, priorDist: "norm");

            Console.WriteLine("CS Time taken: " + stopwatch.ElapsedMilliseconds);
            Console.WriteLine("CS Theta Calculation Finished on: " + DateTime.Now.TimeOfDay.ToString());

            // Compare result of function "ThetaEst"
            if (decimal.Round(Convert.ToDecimal(r_ThetaEst[0]), decimalPoint) - decimal.Round(Convert.ToDecimal(cs_ThetaEst), decimalPoint) > decimal.Round(Convert.ToDecimal(testEpsilon), decimalPoint))
            {
                resultFlag = false;
            }

            if (resultFlag)
            {
                Console.WriteLine("Values matched !!");
            }
            else
            {
                Console.WriteLine("Values are not matched !!");
            }
        }
Example #27
0
        public void testEPV_D()
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Dichotomous Items
            DataFrame DichoItems = engineObj.Evaluate("DichoItems <- genDichoMatrix(items = 200)").AsDataFrame();

            engineObj.SetSymbol("DichoItems", DichoItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)
            CATItems itemBank = new CATItems(DichoItems[0].Select(y => (double)y).ToArray(), DichoItems[1].Select(y => (double)y).ToArray(),
                                             DichoItems[2].Select(y => (double)y).ToArray(), DichoItems[3].Select(y => (double)y).ToArray());

            // test for different theta values
            double[] th = CatRcs.Utils.CommonHelper.Sequence(-6, 6, length: 11);

            var stopwatch = new Stopwatch();

            stopwatch.Restart();

            for (int t = 0; t < th.Length; t++)
            {
                string temp = th[t].ToString(nfi);

                // Dichotomous Items
                DataFrame it_given_R = engineObj.Evaluate("it_given_R <- DichoItems[c(4, 8),]").AsDataFrame();
                engineObj.SetSymbol("it_given_R", it_given_R);

                //Creation of a response pattern for theta value
                engineObj.Evaluate("set.seed(1)");
                NumericVector x_val = engineObj.Evaluate("x_val <- genPattern(" + th[t].ToString(nfi) + ", it_given_R)").AsNumeric();
                engineObj.SetSymbol("x_val", x_val);

                int[] x = x_val.Select(y => (int)y).ToArray();

                int[]    index    = new int[] { 4, 8 };
                CATItems it_given = new CATItems(index.Length);  // itemBank.FindItem(new int[] { 4, 8 });

                for (int i = 0; i < index.Length; i++)
                {
                    it_given.a[i] = itemBank.a[index[i] - 1];
                    it_given.b[i] = itemBank.b[index[i] - 1];
                    it_given.c[i] = itemBank.c[index[i] - 1];
                    it_given.d[i] = itemBank.d[index[i] - 1];
                }

                // Call "EPV" function from R
                NumericVector r_epv = engineObj.Evaluate("r_epv <- EPV(DichoItems, 1, x_val, " + th[t].ToString(nfi) + ", it_given_R)").AsNumeric();

                stopwatch.Restart();

                // Call "EPV" function from CatRCS
                double cs_epv = CatRLib.EPV(itemBank, 1, x, th[t], it_given, "");

                Console.WriteLine("Time taken: " + stopwatch.ElapsedMilliseconds);

                if (r_epv[0] - cs_epv > testEpsilon)
                {
                    resultFlag = false;
                }

                Console.WriteLine(r_epv[0] + " " + cs_epv);
            }

            Assert.IsTrue(resultFlag);
        }
Example #28
0
        public void testPi_D()
        {
            bool OSProc = System.Environment.Is64BitProcess;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Dichotomous Items
            DataFrame DichoItems = engineObj.Evaluate("DichoItems <- genDichoMatrix(items = 100)").AsDataFrame();

            engineObj.SetSymbol("DichoItems", DichoItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)
            CATItems itemBank = new CATItems(DichoItems[0].Select(y => (double)y).ToArray(), DichoItems[1].Select(y => (double)y).ToArray(),
                                             DichoItems[2].Select(y => (double)y).ToArray(), DichoItems[3].Select(y => (double)y).ToArray());

            #region "Test block for Ability Values (th)"

            PiList objPI        = null;
            int    decimalPoint = 4;

            double[] th_Values = CatRcs.Utils.CommonHelper.Sequence(-6, 6, by: 1);

            Console.WriteLine("******* TEST for Ability value Theta ********");

            for (int k = 0; k < th_Values.Length; k++)
            {
                // Sequence Generation for Theta (Ability) values
                NumericVector th_val = engineObj.CreateNumericVector(new double[] { th_Values[k] });
                engineObj.SetSymbol("th_val", th_val);

                // Calling the "Pi" from R
                GenericVector result_Pi = engineObj.Evaluate("result_Pi <- Pi(th = th_val, DichoItems, D = 1)").AsList();

                // Getting the function result
                NumericVector Pi   = result_Pi[0].AsNumeric();
                NumericVector dPi  = result_Pi[1].AsNumeric();
                NumericVector d2Pi = result_Pi[2].AsNumeric();
                NumericVector d3Pi = result_Pi[3].AsNumeric();

                Console.WriteLine("Value of Theta: " + th_Values[k]);

                objPI = CatRLib.Pi_D(th_Values[k], itemBank, "", 1);

                #region "Pi"

                int z = 0;
                resultFlag = true;

                Console.WriteLine("****** Pi ******");

                for (int i = 0; i < Pi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(Pi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.Pi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag, "Passed");
                Console.WriteLine("Values of Pi are Matched!");

                #endregion

                #region "dPi"

                z          = 0;
                resultFlag = true;

                Console.WriteLine("****** dPi ******");

                for (int i = 0; i < dPi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(dPi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.dPi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag);
                Console.WriteLine("Values of dPi are Matched!");

                #endregion

                #region "d2Pi"

                z          = 0;
                resultFlag = true;

                Console.WriteLine("****** d2Pi ******");

                for (int i = 0; i < d2Pi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(d2Pi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.d2Pi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag);
                Console.WriteLine("Values of d2Pi are Matched!");

                #endregion

                #region "d3Pi"

                z          = 0;
                resultFlag = true;

                Console.WriteLine("****** d3Pi ******");

                for (int i = 0; i < d3Pi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(d3Pi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.d3Pi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag);
                Console.WriteLine("Values of d3Pi are Matched!");

                #endregion
            }

            Assert.IsTrue(resultFlag);

            #endregion

            #region "Test block for Metric values"

            objPI = null;

            double[] D_Values = CatRcs.Utils.CommonHelper.Sequence(0.5, 1, by: 0.1);

            Console.WriteLine("******* TEST for Metric Constant ********");

            for (int k = 0; k < D_Values.Length; k++)
            {
                // Sequence Generation for Theta (Ability) values
                NumericVector D_val = engineObj.CreateNumericVector(new double[] { D_Values[k] });
                engineObj.SetSymbol("D_val", D_val);

                // Calling the "Pi" from R
                GenericVector result_Pi = engineObj.Evaluate("result_Pi <- Pi(th = 0, DichoItems, D = D_val)").AsList();

                // Getting the function result
                NumericVector Pi   = result_Pi[0].AsNumeric();
                NumericVector dPi  = result_Pi[1].AsNumeric();
                NumericVector d2Pi = result_Pi[2].AsNumeric();
                NumericVector d3Pi = result_Pi[3].AsNumeric();

                Console.WriteLine("Value of Metric constant: " + D_Values[k]);

                objPI = CatRLib.Pi_D(0, itemBank, "", D_Values[k]);

                #region "Pi"

                int z = 0;
                resultFlag = true;

                Console.WriteLine("****** Pi ******");

                for (int i = 0; i < Pi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(Pi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.Pi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag);
                Console.WriteLine("Values of Pi are matched!");

                #endregion

                #region "dPi"

                z          = 0;
                resultFlag = true;

                Console.WriteLine("****** dPi ******");

                for (int i = 0; i < dPi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(dPi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.dPi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag);
                Console.WriteLine("Values of dPi are matched!");

                #endregion

                #region "d2Pi"

                z          = 0;
                resultFlag = true;

                Console.WriteLine("****** d2Pi ******");

                for (int i = 0; i < d2Pi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(d2Pi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.d2Pi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag);
                Console.WriteLine("Values of d2Pi are Matched!");

                #endregion

                #region "d3Pi"

                z          = 0;
                resultFlag = true;

                Console.WriteLine("****** d3Pi ******");

                for (int i = 0; i < d3Pi.Length; i++)
                {
                    z = i + 1;  // item number

                    if (decimal.Round(Convert.ToDecimal(d3Pi[i]), decimalPoint) != decimal.Round(Convert.ToDecimal(objPI.d3Pi[i]), decimalPoint))
                    {
                        //Console.WriteLine("Test for Item No. # " + z + " is not Passed!");
                        resultFlag = false;
                    }
                }

                Assert.IsTrue(resultFlag);
                Console.WriteLine("Values of d3Pi are Matched!");

                #endregion
            }

            #endregion
        }
Example #29
0
        public static double MEI_Calc(CATItems itemBank, int item, int[] x, double theta, CATItems it_given, string model = null, string method = "BM", double D = 1, double[] priorPar = null, string priorDist = "norm", double[] range = null, int[] parInt = null, int infoType = 2 /* Observed */)
        {
            double res = 0;

            if (priorPar == null || priorPar.Length < 2)
            {
                priorPar    = new double[2];
                priorPar[0] = 0;
                priorPar[1] = 1;
            }

            if (parInt == null || parInt.Length < 3)
            {
                parInt    = new int[3];
                parInt[0] = -4;
                parInt[1] = 4;
                parInt[2] = 33;
            }

            if (range == null || range.Length < 2)
            {
                range    = new double[2];
                range[0] = -4;
                range[1] = 4;
            }

            if ((infoType == (int)ModelNames.InfoType.Observed) || (infoType == (int)ModelNames.InfoType.Fisher))  // type is either "Observed" or "Fisher"
            {
                double th = theta;

                // Finding desired "item" from itembank & Added to given items "it_given".
                // Instead of "itj", "it_given" will be used.
                itemBank.AddItem(it_given, item);

                if (String.IsNullOrEmpty(model))   // Dichotomous Items
                {
                    List <int> temp_x = x.ToList();
                    temp_x.Add(0);

                    double th0 = CatRcs.ThetaEST.ThetaEst_Calc(it_given, temp_x.ToArray(), D: D, model: model, method: method, priorPar: priorPar, priorDist: priorDist, parInt: parInt, range: range);

                    temp_x = x.ToList();
                    temp_x.Add(1);

                    double th1 = CatRcs.ThetaEST.ThetaEst_Calc(it_given, temp_x.ToArray(), D: D, model: model, method: method, priorPar: priorPar, priorDist: priorDist, parInt: parInt, range: range);

                    double p1 = CatRcs.Pi.Pi_Calc(th, itemBank.FindItem(item), model, D).Pi.First();
                    double p0 = 1 - p1;
                    double Ij0 = 0, Ij1 = 0;

                    if ((infoType == (int)ModelNames.InfoType.Fisher))
                    {
                        Ij0 = CatRcs.Ii.Ii_Calc(th0, itemBank.FindItem(item), model, D).Ii.First();
                        Ij1 = CatRcs.Ii.Ii_Calc(th1, itemBank.FindItem(item), model, D).Ii.First();
                    }
                    else
                    {
                        Ij0 = CatRcs.OIi.OIi_Calc(th0, itemBank.FindItem(item), new int[] { 0 }, model, D).OIi.First();
                        Ij1 = CatRcs.OIi.OIi_Calc(th1, itemBank.FindItem(item), new int[] { 1 }, model, D).OIi.First();
                    }

                    res = (p0 * Ij0) + (p1 * Ij1);
                }
                else   // Polytomous Items
                {
                    double[,] probs = Pi.Pi_Poly_Calc(theta, itemBank.FindItem(item), model, D).Pi;
                    double[] Ii_new = new double[probs.GetLength(1)];

                    for (int j = 0; j < probs.GetLength(1); j++)  // column iteration
                    {
                        List <int> temp_x = x.ToList();
                        temp_x.Add(j);

                        double th_new = CatRcs.ThetaEST.ThetaEst_Calc(it_given, temp_x.ToArray(), D: D, model: model, method: method, priorPar: priorPar, priorDist: priorDist, parInt: parInt, range: range);

                        if ((infoType == (int)ModelNames.InfoType.Fisher))
                        {
                            Ii_new[j] = CatRcs.Ii.Ii_Calc(th_new, itemBank.FindItem(item), model, D).Ii.First();
                        }
                        else
                        {
                            Ii_new[j] = CatRcs.OIi.OIi_Calc(th_new, itemBank.FindItem(item), new int[] { j }, model, D).OIi.First();
                        }
                    }

                    res = CatRcs.Utils.RowColumn.Sum(Ii_new.ToList().Select((p, i) => p * probs[0, i]).ToArray());
                }
            }
            else
            {
                return(res);
            }

            return(res);
        }
Example #30
0
        public void testEapEST_and_EapSEM_P(int NumOfItems, ModelNames.Models paramModel)
        {
            resultFlag = true;

            REngine.SetEnvironmentVariables();

            REngine engineObj = REngine.GetInstance();

            // Loading a library from R
            engineObj.Evaluate("library(catR)");

            // Polytomous Items
            CharacterVector modelName = engineObj.CreateCharacterVector(new string[] { paramModel.EnumToString() });

            engineObj.SetSymbol("modelName", modelName);
            DataFrame PolyItems = engineObj.Evaluate("PolyItems <- genPolyMatrix(" + NumOfItems + ", 5, model = modelName, same.nrCat = TRUE)").AsDataFrame();

            engineObj.SetSymbol("PolyItems", PolyItems);

            // Adapting with the existing "CAT-Items" type (Wrapper)

            Console.WriteLine("*******************************************");
            Console.WriteLine("Polytomous Items, Model : " + paramModel.EnumToString());
            Console.WriteLine("*******************************************");

            CATItems itemBank = new CATItems(PolyItems[0].Length, paramModel.EnumToString(), 5);

            Tuple <CATItems.ColumnNames, int>[] cols = itemBank.GetKeys();

            for (int i = 0; i < cols.Length; i++)
            {
                itemBank.SetItemParamter(cols[i], PolyItems[i].Select(y => (double)y).ToArray());
            }

            #region "Test block for Ability Values (th)"

            double[] th = CatRcs.Utils.CommonHelper.Sequence(-6, 6, length: 11);

            for (int j = 0; j < th.Length; j++)
            {
                string temp = th[j].ToString(nfi);

                //Creation of a response pattern for theta value
                engineObj.Evaluate("set.seed(1)");
                NumericVector x_val = engineObj.Evaluate("x_val <- genPattern(" + "th = " + th[j].ToString(nfi) + ", PolyItems, " + "model = modelName)").AsNumeric();
                engineObj.SetSymbol("x_val", x_val);

                int[] x = x_val.Select(y => (int)y).ToArray();

                // Call "EapEST" function from R
                NumericVector r_eapEst = engineObj.Evaluate("result_Eap <- eapEst(PolyItems, x_val, model = modelName)").AsNumeric();

                // Call "EapEST" function from CatRCS
                double cs_eapEst = CatRLib.EapEST(itemBank, x, paramModel.EnumToString());


                /* EapEst function, line 111 needs to be optimized for passing the Test
                 * Check EapSEM function too !! */

                // Call "EapSEM" function from R
                NumericVector r_eapSem = engineObj.Evaluate("result_EapSem <- eapSem(result_Eap, PolyItems, x_val, model = modelName)").AsNumeric();

                // Call "EapSEM" function from CatRCS
                double cs_eapSem = CatRLib.EapSEM(cs_eapEst, itemBank, x, paramModel.EnumToString());

                if (r_eapEst[0] - cs_eapEst > testEpsilon ||
                    r_eapSem[0] - cs_eapSem > testEpsilon)
                {
                    resultFlag = false;
                }
            }

            Assert.IsTrue(resultFlag);

            #endregion
        }