@@ -36,7 +36,7 @@ def __init__(
3636 )
3737
3838 @property
39- def fim_weight (self ):
39+ def fim_weight_aa (self ):
4040 """
4141
4242 :return: observations x features
@@ -51,7 +51,7 @@ def ybar(self) -> np.ndarray:
5151 """
5252 return np .asarray (self .x - self .location ) / self .location
5353
54- def fim_weight_j (self , j ):
54+ def fim_weight_aa_j (self , j ):
5555 """
5656
5757 :return: observations x features
@@ -113,6 +113,38 @@ def jac_weight_b_j(self, j):
113113 const3 = np .log (scale ) + np .ones_like (scale ) - np .log (r_plus_mu )
114114 return scale * (const1 + const2 + const3 )
115115
116+ @property
117+ def fim_ab (self ) -> np .ndarray :
118+ """
119+ Location-scale coefficient block of FIM
120+
121+ The negative binomial model is not fit as whole with IRLS but only the location model.
122+ The location model is conditioned on the scale model estimates, which is why we only
123+ supply the FIM of the location model and return an empty FIM for scale model components.
124+ Note that there is also no closed form FIM for the scale-scale block. Returning a zero-array
125+ here leads to singular matrices for the whole location-scale FIM in some cases that throw
126+ linear algebra errors when inverted.
127+
128+ :return: (features x inferred param x inferred param)
129+ """
130+ return np .zeros ([self .b_var .shape [1 ], 0 , 0 ])
131+
132+ @property
133+ def fim_bb (self ) -> np .ndarray :
134+ """
135+ Scale-scale coefficient block of FIM
136+
137+ The negative binomial model is not fit as whole with IRLS but only the location model.
138+ The location model is conditioned on the scale model estimates, which is why we only
139+ supply the FIM of the location model and return an empty FIM for scale model components.
140+ Note that there is also no closed form FIM for the scale-scale block. Returning a zero-array
141+ here leads to singular matrices for the whole location-scale FIM in some cases that throw
142+ linear algebra errors when inverted.
143+
144+ :return: (features x inferred param x inferred param)
145+ """
146+ return np .zeros ([self .b_var .shape [1 ], 0 , 0 ])
147+
116148 @property
117149 def hessian_weight_ab (self ):
118150 scale = self .scale
@@ -209,3 +241,18 @@ def fun(x, eta_loc, b_var, xh_scale):
209241 raise ValueError ("type x %s not supported" % type (x ))
210242 return self .np_clip_param (ll , "ll" )
211243 return fun
244+
245+ def jac_b_handle (self ):
246+ def fun (x , eta_loc , b_var , xh_scale ):
247+ scale = np .exp (b_var )
248+ loc = np .exp (eta_loc )
249+ scale_plus_x = scale + x
250+ r_plus_mu = scale + loc
251+
252+ # Define graphs for individual terms of constant term of hessian:
253+ const1 = scipy .special .digamma (scale_plus_x ) - scipy .special .digamma (scale )
254+ const2 = - scale_plus_x / r_plus_mu
255+ const3 = np .log (scale ) + np .ones_like (scale ) - np .log (r_plus_mu )
256+ return scale * (const1 + const2 + const3 )
257+
258+ return fun
0 commit comments