@@ -96,12 +96,13 @@ def _fft_next_fast_len(target):
9696 target += 1
9797
9898
99- def autocorrelation (x , axis = 0 ):
99+ def autocorrelation (x , axis = 0 , bias = True ):
100100 """
101101 Computes the autocorrelation of samples at dimension ``axis``.
102102
103103 :param numpy.ndarray x: the input array.
104104 :param int axis: the dimension to calculate autocorrelation.
105+ :param bias: whether to use a biased estimator.
105106 :return: autocorrelation of ``x``.
106107 :rtype: numpy.ndarray
107108 """
@@ -127,25 +128,32 @@ def autocorrelation(x, axis=0):
127128
128129 # truncate and normalize the result, then transpose back to original shape
129130 autocorr = autocorr [..., :N ]
130- autocorr = autocorr / np .arange (N , 0.0 , - 1 )
131+
132+ # the unbiased estimator is known to have "wild" tails, due to few samples at longer lags.
133+ # see Geyer (1992) and Priestley (1981) for a discussion. also note that it is only strictly
134+ # unbiased when the mean is known, whereas we it estimate from samples here.
135+ if not bias :
136+ autocorr = autocorr / np .arange (N , 0.0 , - 1 )
137+
131138 with np .errstate (invalid = "ignore" , divide = "ignore" ):
132139 autocorr = autocorr / autocorr [..., :1 ]
133140 return np .swapaxes (autocorr , axis , - 1 )
134141
135142
136- def autocovariance (x , axis = 0 ):
143+ def autocovariance (x , axis = 0 , bias = True ):
137144 """
138145 Computes the autocovariance of samples at dimension ``axis``.
139146
140147 :param numpy.ndarray x: the input array.
141148 :param int axis: the dimension to calculate autocovariance.
149+ :param bias: whether to use a biased estimator.
142150 :return: autocovariance of ``x``.
143151 :rtype: numpy.ndarray
144152 """
145- return autocorrelation (x , axis ) * x .var (axis = axis , keepdims = True )
153+ return autocorrelation (x , axis , bias ) * x .var (axis = axis , keepdims = True )
146154
147155
148- def effective_sample_size (x ):
156+ def effective_sample_size (x , bias = True ):
149157 """
150158 Computes effective sample size of input ``x``, where the first dimension of
151159 ``x`` is chain dimension and the second dimension of ``x`` is draw dimension.
@@ -158,6 +166,7 @@ def effective_sample_size(x):
158166 Stan Development Team
159167
160168 :param numpy.ndarray x: the input array.
169+ :param bias: whether to use a biased estimator of the autocovariance.
161170 :return: effective sample size of ``x``.
162171 :rtype: numpy.ndarray
163172 """
@@ -166,7 +175,7 @@ def effective_sample_size(x):
166175 assert x .shape [1 ] >= 2
167176
168177 # find autocovariance for each chain at lag k
169- gamma_k_c = autocovariance (x , axis = 1 )
178+ gamma_k_c = autocovariance (x , axis = 1 , bias = bias )
170179
171180 # find autocorrelation at lag k (from Stan reference)
172181 var_within , var_estimator = _compute_chain_variance_stats (x )
0 commit comments