# Path: catsim/cat.py
# def generate_item_bank(n: int, itemtype: str = "4PL", corr: float = 0) -> numpy.ndarray:
#     """Generate a synthetic item bank whose parameters approximately follow
#     real-world parameters, as proposed by [Bar10]_.
# 
#     Item parameters are extracted from the following probability distributions:
# 
#     * discrimination: :math:`N(1.2, 0.25)`
# 
#     * difficulty: :math:`N(0,  1)`
# 
#     * pseudo-guessing: :math:`N(0.25, 0.02)`
# 
#     * upper asymptote: :math:`U(0.94, 1)`
# 
#     :param n: how many items are to be generated
#     :param itemtype: either ``1PL``, ``2PL``, ``3PL`` or ``4PL`` for the one-, two-,
#                      three- or four-parameter logistic model
#     :param corr: the correlation between item discrimination and difficulty. If
#                  ``itemtype == '1PL'``, it is ignored.
#     :return: an ``n x 4`` numerical matrix containing item parameters
#     :rtype: numpy.ndarray
# 
#     >>> generate_item_bank(5, '1PL')
#     >>> generate_item_bank(5, '2PL')
#     >>> generate_item_bank(5, '3PL')
#     >>> generate_item_bank(5, '4PL')
#     >>> generate_item_bank(5, '4PL', corr=0)
#     """
# 
#     valid_itemtypes = ["1PL", "2PL", "3PL", "4PL"]
# 
#     if itemtype not in valid_itemtypes:
#         raise ValueError("Item type not in " + str(valid_itemtypes))
# 
#     means = [0, 1.2]
#     stds = [1, 0.25]
#     covs = [
#         [stds[0]**2, stds[0] * stds[1] * corr],
#         [stds[0] * stds[1] * corr, stds[1]**2],
#     ]
# 
#     b, a = numpy.random.multivariate_normal(means, covs, n).T
# 
#     # if by chance there is some discrimination value below zero
#     # this makes the problem go away
#     if any(disc < 0 for disc in a):
#         min_disc = min(a)
#         a = [disc + abs(min_disc) for disc in a]
# 
#     if itemtype not in ["2PL", "3PL", "4PL"]:
#         a = numpy.ones(n)
# 
#     if itemtype in ["3PL", "4PL"]:
#         c = numpy.random.normal(0.25, 0.02, n).clip(min=0)
#     else:
#         c = numpy.zeros(n)
# 
#     if itemtype == "4PL":
#         d = numpy.random.uniform(0.94, 1, n)
#     else:
#         d = numpy.ones(n)
# 
#     return irt.normalize_item_bank(numpy.array([a, b, c, d]).T)


import numpy as np
import matplotlib.pyplot as plt
from catsim.estimation import *
from catsim.cat import generate_item_bank

test_size = 20
items = generate_item_bank(20)
items = items[items[:,1].argsort()] # order by difficulty ascending
r0 = [True] * 7 + [False] * 13
r1 = [True] * 10 + [False] * 10
r2 = [True] * 15 + [False] * 5
response_vectors = [r0, r1, r2]
thetas = np.arange(-6.,6.,.1)

for estimator in [
        NumericalSearchEstimator(method=m) for m in NumericalSearchEstimator.methods
    ]:
    plt.figure()

    for response_vector in response_vectors:
        ll_line = [irt.log_likelihood(theta, response_vector, items) for theta in thetas]

# Path: catsim/cat.py
# def generate_item_bank(n: int, itemtype: str = "4PL", corr: float = 0) -> numpy.ndarray:
#     """Generate a synthetic item bank whose parameters approximately follow
#     real-world parameters, as proposed by [Bar10]_.
# 
#     Item parameters are extracted from the following probability distributions:
# 
#     * discrimination: :math:`N(1.2, 0.25)`
# 
#     * difficulty: :math:`N(0,  1)`
# 
#     * pseudo-guessing: :math:`N(0.25, 0.02)`
# 
#     * upper asymptote: :math:`U(0.94, 1)`
# 
#     :param n: how many items are to be generated
#     :param itemtype: either ``1PL``, ``2PL``, ``3PL`` or ``4PL`` for the one-, two-,
#                      three- or four-parameter logistic model
#     :param corr: the correlation between item discrimination and difficulty. If
#                  ``itemtype == '1PL'``, it is ignored.
#     :return: an ``n x 4`` numerical matrix containing item parameters
#     :rtype: numpy.ndarray
# 
#     >>> generate_item_bank(5, '1PL')
#     >>> generate_item_bank(5, '2PL')
#     >>> generate_item_bank(5, '3PL')
#     >>> generate_item_bank(5, '4PL')
#     >>> generate_item_bank(5, '4PL', corr=0)
#     """
# 
#     valid_itemtypes = ["1PL", "2PL", "3PL", "4PL"]
# 
#     if itemtype not in valid_itemtypes:
#         raise ValueError("Item type not in " + str(valid_itemtypes))
# 
#     means = [0, 1.2]
#     stds = [1, 0.25]
#     covs = [
#         [stds[0]**2, stds[0] * stds[1] * corr],
#         [stds[0] * stds[1] * corr, stds[1]**2],
#     ]
# 
#     b, a = numpy.random.multivariate_normal(means, covs, n).T
# 
#     # if by chance there is some discrimination value below zero
#     # this makes the problem go away
#     if any(disc < 0 for disc in a):
#         min_disc = min(a)
#         a = [disc + abs(min_disc) for disc in a]
# 
#     if itemtype not in ["2PL", "3PL", "4PL"]:
#         a = numpy.ones(n)
# 
#     if itemtype in ["3PL", "4PL"]:
#         c = numpy.random.normal(0.25, 0.02, n).clip(min=0)
#     else:
#         c = numpy.zeros(n)
# 
#     if itemtype == "4PL":
#         d = numpy.random.uniform(0.94, 1, n)
#     else:
#         d = numpy.ones(n)
# 
#     return irt.normalize_item_bank(numpy.array([a, b, c, d]).T)


# Path: docs/estimation-2.py
import numpy as np
import matplotlib.pyplot as plt
from catsim.estimation import *
from catsim.cat import generate_item_bank


test_size = 20
items = generate_item_bank(20)
items = items[items[:,1].argsort()] # order by difficulty ascending
r0 = [True] * 7 + [False] * 13
r1 = [True] * 10 + [False] * 10
r2 = [True] * 15 + [False] * 5
response_vectors = [r0, r1, r2]
thetas = np.arange(-6.,6.,.1)

for estimator in [
        NumericalSearchEstimator(method=m) for m in NumericalSearchEstimator.methods
    ]:
    plt.figure()

    for response_vector in response_vectors:
        ll_line = [irt.log_likelihood(theta, response_vector, items) for theta in thetas]

        max_LL = estimator.estimate(items=items, administered_items=range(20),