Group similar calculations
@@ -321,24 +321,24 @@ def variance(input, labels=None, index=None):
'for the fast implmentation', util.PerformanceWarning)
use_kern = True
- def single_group(vals):
- vals_c = vals - vals.mean()
- return vals.size, cupy.square(vals_c).sum()
+ def calc_var_with_intermediate_float(input):
+ vals_c = input - input.mean()
+ count = vals_c.size
+ # Does not use `ndarray.mean()` here to return the same results as
+ # SciPy does, especially in case `input`'s dtype is float16.
+ return cupy.square(vals_c).sum() / cupy.asanyarray(count).astype(float)
if labels is None:
- count, sum_c_sq = single_group(input)
- return sum_c_sq / cupy.asanyarray(count).astype(float)
+ return calc_var_with_intermediate_float(input)
if not isinstance(labels, cupy.ndarray):
raise TypeError('label must be cupy.ndarray')
if index is None:
- count, sum_c_sq = single_group(input[labels > 0])
- return sum_c_sq / cupy.asanyarray(count).astype(float)
+ return calc_var_with_intermediate_float(input[labels > 0])
if cupy.isscalar(index):
- count, sum_c_sq = single_group(input[labels == index])
- return sum_c_sq / cupy.asanyarray(count).astype(float)
+ return calc_var_with_intermediate_float(input[labels == index])
input, labels = cupy.broadcast_arrays(input, labels)
@@ -460,23 +460,24 @@ def mean(input, labels=None, index=None):
'for the fast implmentation', util.PerformanceWarning)
use_kern = True
- def single_group(vals):
- return vals.size, vals.sum()
+ def calc_mean_with_intermediate_float(input):
+ sum = input.sum()
+ count = input.size
+ # Does not use `ndarray.mean()` here to return the same results as
+ # SciPy does, especially in case `input`'s dtype is float16.
+ return sum / cupy.asanyarray(count).astype(float)
if labels is None:
- count, sum = single_group(input)
- return sum / cupy.asanyarray(count).astype(float)
+ return calc_mean_with_intermediate_float(input)
if not isinstance(labels, cupy.ndarray):
raise TypeError('label must be cupy.ndarray')
if index is None:
- count, sum = single_group(input[labels > 0])
- return sum / cupy.asanyarray(count).astype(float)
+ return calc_mean_with_intermediate_float(input[labels > 0])
if cupy.isscalar(index):
- count, sum = single_group(input[labels == index])
- return sum / cupy.asanyarray(count).astype(float)
+ return calc_mean_with_intermediate_float(input[labels == index])
input, labels = cupy.broadcast_arrays(input, labels)
