1010# of Health and Human Services, which is making the software available to the
1111# public for any commercial or non-commercial purpose under the following
1212# open-source BSD license.
13- #
13+ #
1414# Redistribution and use in source and binary forms, with or without
1515# modification, are permitted provided that the following conditions are met:
16- #
16+ #
1717# (1) Redistributions of source code must retain this copyright
1818# notice, this list of conditions and the following disclaimer.
19- #
19+ #
2020# (2) Redistributions in binary form must reproduce this copyright
2121# notice, this list of conditions and the following disclaimer in the
2222# documentation and/or other materials provided with the distribution.
23- #
23+ #
2424# (3) Neither the names of the National Institutes of Health Clinical
2525# Center, the National Institutes of Health, the U.S. Department of
2626# Health and Human Services, nor the names of any of the software
2727# developers may be used to endorse or promote products derived from
2828# this software without specific prior written permission.
29- #
29+ #
3030# (4) Please acknowledge NIHCC as the source of this software by including
3131# the phrase "Courtesy of the U.S. National Institutes of Health Clinical
3232# Center"or "Source: U.S. National Institutes of Health Clinical Center."
33- #
33+ #
3434# THIS SOFTWARE IS PROVIDED BY THE U.S. GOVERNMENT AND CONTRIBUTORS "AS
3535# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
3636# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
3737# PARTICULAR PURPOSE ARE DISCLAIMED.
38- #
38+ #
3939# You are under no obligation whatsoever to provide any bug fixes,
4040# patches, or upgrades to the features, functionality or performance of
4141# the source code ("Enhancements") to anyone; however, if you choose to
@@ -68,14 +68,14 @@ def __init__(self, scoring, deterministic=True, hybrid=False, **kwargs):
6868 self .hybrid = hybrid
6969 self .deterministic = deterministic
7070
71- def criterion (self , scoring : BayesianScoring , items : list [dict ], scale = None ) -> dict [str : Any ]:
72-
71+ def criterion (
72+ self , scoring : BayesianScoring , items : list [dict ], scale = None
73+ ) -> dict [str :Any ]:
7374 """
7475 Parameters: session: instance of CatSession
7576 Returns: item dictionary entry or None
7677 """
7778
78-
7979 unresponded = [i for i in items if "scales" in i .keys ()]
8080 in_scale = [i for i in unresponded if scale in i ["scales" ].keys ()]
8181
@@ -106,19 +106,25 @@ def criterion(self, scoring: BayesianScoring, items: list[dict], scale=None) ->
106106 )[
107107 :, unresponded_ndx , :
108108 ] #
109-
109+
110110 p_itemized = np .exp (lp_itemized )
111111 pi_density = scoring .scores [scale ].density
112112
113- criterion = np .sum (p_itemized * (lp_itemized - lp_point )* pi_density [:, np .newaxis , np .newaxis ], axis = 0 )
113+ criterion = np .trapz (
114+ p_itemized
115+ * (lp_itemized - lp_point )
116+ * pi_density [:, np .newaxis , np .newaxis ],
117+ x = scoring .interpolation_pts [scale ],
118+ axis = 0 ,
119+ )
114120 criterion = np .sum (criterion , axis = - 1 )
115- criterion = dict (zip ([x [' item' ] for x in items ], criterion ))
121+ criterion = dict (zip ([x [" item" ] for x in items ], criterion ))
116122 return criterion
117-
123+
118124 def _next_scored_item (
119125 self , tracker : CatSessionTracker , scale = None
120- ) -> dict [str : dict [str :Any ]]:
121-
126+ ) -> dict [str : dict [str :Any ]]:
127+
122128 scale = self .next_scale (tracker )
123129 un_items = self .un_items (tracker , scale )
124130
@@ -131,9 +137,9 @@ def _next_scored_item(
131137 trait = 0.0 if trait is None else trait
132138 error = tracker .errors [scale ]
133139 error = 100.0 if error is None else error
134-
135- criterion = self .criterion (scoring = self .scoring , items = un_items , scale = scale )
136- valid_items = [x [' item' ] for x in un_items ]
140+
141+ criterion = self .criterion (scoring = self .scoring , items = un_items , scale = scale )
142+ valid_items = [x [" item" ] for x in un_items ]
137143 items = []
138144 Delta = []
139145 for k , v in criterion .items ():
@@ -143,15 +149,15 @@ def _next_scored_item(
143149 if len (items ) == 0 :
144150 return {}
145151 Delta -= np .max (Delta )
146- probs = np .exp (Delta / self .temperature )
152+ probs = np .exp (Delta / self .temperature )
147153 probs /= np .sum (probs )
148-
149- if self .deterministic or (self .hybrid and ((self .scoring .n_scored [scale ] > 3 ))):
154+
155+ if self .deterministic or (self .hybrid and ((self .scoring .n_scored [scale ] > 3 ))):
150156 ndx = np .argmax (probs )
151157 else :
152158 ndx = np .random .choice (np .arange (len (criterion .keys ())), p = probs )
153159 result = list (criterion .keys ())[ndx ]
154160 for i in un_items :
155- if i [' item' ] == result :
161+ if i [" item" ] == result :
156162 return i
157- return {}
163+ return {}
0 commit comments