def wrap_histogram(hist_, edges_, DEBUG_ROTINVAR=False): r""" Simulates the first and last histogram bin being being adjacent to one another by replicating those bins at the last and first positions respectively. Args: hist_ (ndarray): edges_ (ndarray): Returns: tuple: (hist_wrap, edge_wrap) CommandLine: python -m vtool.histogram --test-wrap_histogram Example: >>> # ENABLE_DOCTEST >>> from vtool.histogram import * # NOQA >>> # build test data >>> hist_ = np.array([ 8. , 0. , 0. , 34.32, 29.45, 0. , 0. , 6.73]) >>> edges_ = np.array([ 0. , 0.78539816, 1.57079633, ... 2.35619449, 3.14159265, 3.92699081, ... 4.71238898, 5.49778714, 6.2831853 ]) >>> # execute function >>> (hist_wrap, edge_wrap) = wrap_histogram(hist_, edges_) >>> # verify results >>> edgewrap_str = '[' + ', '.join(['%.2f' % _ for _ in edge_wrap]) + ']' >>> histwrap_str = str(hist_wrap.tolist()) >>> result = histwrap_str + ut.NEWLINE + edgewrap_str >>> print(result) [6.73, 8.0, 0.0, 0.0, 34.32, 29.45, 0.0, 0.0, 6.73, 8.0] [-0.79, 0.00, 0.79, 1.57, 2.36, 3.14, 3.93, 4.71, 5.50, 6.28, 7.07] """ # FIXME; THIS NEEDS INFORMATION ABOUT THE DISTANCE FROM THE LAST BIN # TO THE FIRST. IT IS OK AS LONG AS ALL STEPS ARE EQUAL, BUT IT IS NOT # GENERAL left_step, right_step = np.diff(edges_)[[0, -1]] hist_wrap = np.hstack((hist_[-1:], hist_, hist_[0:1])) edge_wrap = np.hstack( (edges_[0:1] - left_step, edges_, edges_[-1:] + right_step)) if DEBUG_ROTINVAR: import vtool as vt print(vt.kpts_docrepr(hist_wrap, 'hist_wrap', False)) print(vt.kpts_docrepr(edge_wrap, 'edge_wrap', False)) return hist_wrap, edge_wrap
def wrap_histogram(hist_, edges_, DEBUG_ROTINVAR=False): r""" Simulates the first and last histogram bin being being adjacent to one another by replicating those bins at the last and first positions respectively. Args: hist_ (ndarray): edges_ (ndarray): Returns: tuple: (hist_wrap, edge_wrap) CommandLine: python -m vtool.histogram --test-wrap_histogram Example: >>> # ENABLE_DOCTEST >>> from vtool.histogram import * # NOQA >>> # build test data >>> hist_ = np.array([ 8. , 0. , 0. , 34.32, 29.45, 0. , 0. , 6.73]) >>> edges_ = np.array([ 0. , 0.78539816, 1.57079633, ... 2.35619449, 3.14159265, 3.92699081, ... 4.71238898, 5.49778714, 6.2831853 ]) >>> # execute function >>> (hist_wrap, edge_wrap) = wrap_histogram(hist_, edges_) >>> # verify results >>> edgewrap_str = '[' + ', '.join(['%.2f' % _ for _ in edge_wrap]) + ']' >>> histwrap_str = str(hist_wrap.tolist()) >>> result = histwrap_str + ut.NEWLINE + edgewrap_str >>> print(result) [6.73, 8.0, 0.0, 0.0, 34.32, 29.45, 0.0, 0.0, 6.73, 8.0] [-0.79, 0.00, 0.79, 1.57, 2.36, 3.14, 3.93, 4.71, 5.50, 6.28, 7.07] """ # FIXME; THIS NEEDS INFORMATION ABOUT THE DISTANCE FROM THE LAST BIN # TO THE FIRST. IT IS OK AS LONG AS ALL STEPS ARE EQUAL, BUT IT IS NOT # GENERAL left_step, right_step = np.diff(edges_)[[0, -1]] hist_wrap = np.hstack((hist_[-1:], hist_, hist_[0:1])) edge_wrap = np.hstack((edges_[0:1] - left_step, edges_, edges_[-1:] + right_step)) if DEBUG_ROTINVAR: import vtool as vt print(vt.kpts_docrepr(hist_wrap, 'hist_wrap', False)) print(vt.kpts_docrepr(edge_wrap, 'edge_wrap', False)) return hist_wrap, edge_wrap
def interpolated_histogram(data, weights, range_, bins, interpolation_wrap=True, DEBUG_ROTINVAR=False): r""" Follows np.histogram, but does interpolation Args: range_ (tuple): range from 0 to 1 bins (?): CommandLine: python -m vtool.histogram --test-interpolated_histogram Example0: >>> # ENABLE_DOCTEST >>> from vtool.histogram import * # NOQA >>> # build test data >>> data = np.array([ 0, 1, 2, 3.5, 3, 3, 4, 4]) >>> weights = np.array([1., 1., 1., 1., 1., 1., 1., 1.]) >>> range_ = (0, 4) >>> bins = 5 >>> interpolation_wrap = False >>> # execute function >>> hist, edges = interpolated_histogram(data, weights, range_, bins, interpolation_wrap) >>> assert np.abs(hist.sum() - weights.sum()) < 1E-9 >>> assert hist.size == bins >>> assert edges.size == bins + 1 >>> result = get_histinfo_str(hist, edges) >>> print(result) Example1: >>> # ENABLE_DOCTEST >>> from vtool.histogram import * # NOQA >>> # build test data >>> data = np.array([ 0, 1, 2, 3.5, 3, 3, 4, 4]) >>> weights = np.array([4.5, 1., 1., 1., 1., 1., 1., 1.]) >>> range_ = (-.5, 4.5) >>> bins = 5 >>> interpolation_wrap = True >>> # execute function >>> hist, edges = interpolated_histogram(data, weights, range_, bins, interpolation_wrap) >>> assert np.abs(hist.sum() - weights.sum()) < 1E-9 >>> assert hist.size == bins >>> assert edges.size == bins + 1 >>> result = get_histinfo_str(hist, edges) >>> print(result) #Example2: # >>> # ENABLE_DOCTEST # >>> from vtool.histogram import * # NOQA # >>> # build test data # >>> data = np.random.rand(10) # >>> weights = np.random.rand(10) # >>> range_ = (0, 1) # >>> bins = np.random.randint(2) + 1 + np.random.randint(2) * 100 # >>> interpolation_wrap = True # >>> # execute function # >>> hist, edges = interpolated_histogram(data, weights, range_, bins, interpolation_wrap) # >>> assert np.abs(hist.sum() - weights.sum()) < 1E-9 # >>> assert hist.size == bins # >>> assert edges.size == bins + 1 # >>> result = get_histinfo_str(hist, edges) # >>> print(result) """ assert bins > 0, 'must have nonzero bins' data = np.asarray(data) if weights is not None: weights = np.asarray(weights) assert np.all(weights.shape == data.shape), 'shapes disagree' weights = weights.ravel() data = data.ravel() # Compute bin edges like in np.histogram start, stop = float(range_[0]), float(range_[1]) if start == stop: start -= 0.5 stop += 0.5 # Find bin edges hist_dtype = np.float64 # Compute bin step size, add one if last bin is the same as the first step = (stop - start) / float((bins + interpolation_wrap)) #edges = [start + i * step for i in range(bins + 1)] #centers = hist_edges_to_centers(edges) half_step = step / 2.0 # Find fractional bin center index for each datapoint data_offset = start + half_step frac_index = (data - data_offset) / step # Find bin center to the left of each datapoint left_index = np.floor(frac_index).astype(np.int32) # Find bin center to the right of each datapoint right_index = left_index + 1 # Find the fraction of the distiance the right center is away from the datapoint right_alpha = (frac_index - left_index) left_alpha = 1.0 - right_alpha if DEBUG_ROTINVAR: print('bins = %r' % bins) print('step = %r' % step) print('half_step = %r' % half_step) print('data_offset = %r' % data_offset) TAU = 2 * np.pi print("-.5 MOD tau = %r" % (-.5 % TAU,)) # Handle edge cases if interpolation_wrap: # when the stop == start (like in orientations) left_index %= bins right_index %= bins else: left_index[left_index < 0] = 0 right_index[right_index >= bins] = bins - 1 # Each keypoint votes into its left and right bins left_vote = left_alpha * weights right_vote = right_alpha * weights hist = np.zeros((bins,), hist_dtype) # TODO: can problably do this faster with cumsum for index, vote in zip(left_index, left_vote): hist[index] += vote for index, vote in zip(right_index, right_vote): hist[index] += vote if interpolation_wrap: edges = np.linspace(start, stop, bins + 1, endpoint=False) else: edges = np.linspace(start, stop, bins + 1, endpoint=True) if DEBUG_ROTINVAR: import vtool as vt assert np.allclose(np.diff(edges), step) print(hist.shape) print(edges.shape) print(vt.kpts_docrepr(hist, 'hist', False)) print(vt.kpts_docrepr(edges, 'edges', False)) return hist, edges
def interpolated_histogram(data, weights, range_, bins, interpolation_wrap=True, DEBUG_ROTINVAR=False): r""" Follows np.histogram, but does interpolation Args: range_ (tuple): range from 0 to 1 bins (?): CommandLine: python -m vtool.histogram --test-interpolated_histogram Example0: >>> # ENABLE_DOCTEST >>> from vtool.histogram import * # NOQA >>> # build test data >>> data = np.array([ 0, 1, 2, 3.5, 3, 3, 4, 4]) >>> weights = np.array([1., 1., 1., 1., 1., 1., 1., 1.]) >>> range_ = (0, 4) >>> bins = 5 >>> interpolation_wrap = False >>> # execute function >>> hist, edges = interpolated_histogram(data, weights, range_, bins, interpolation_wrap) >>> assert np.abs(hist.sum() - weights.sum()) < 1E-9 >>> assert hist.size == bins >>> assert edges.size == bins + 1 >>> result = get_histinfo_str(hist, edges) >>> print(result) Example1: >>> # ENABLE_DOCTEST >>> from vtool.histogram import * # NOQA >>> # build test data >>> data = np.array([ 0, 1, 2, 3.5, 3, 3, 4, 4]) >>> weights = np.array([4.5, 1., 1., 1., 1., 1., 1., 1.]) >>> range_ = (-.5, 4.5) >>> bins = 5 >>> interpolation_wrap = True >>> # execute function >>> hist, edges = interpolated_histogram(data, weights, range_, bins, interpolation_wrap) >>> assert np.abs(hist.sum() - weights.sum()) < 1E-9 >>> assert hist.size == bins >>> assert edges.size == bins + 1 >>> result = get_histinfo_str(hist, edges) >>> print(result) #Example2: # >>> # ENABLE_DOCTEST # >>> from vtool.histogram import * # NOQA # >>> # build test data # >>> data = np.random.rand(10) # >>> weights = np.random.rand(10) # >>> range_ = (0, 1) # >>> bins = np.random.randint(2) + 1 + np.random.randint(2) * 100 # >>> interpolation_wrap = True # >>> # execute function # >>> hist, edges = interpolated_histogram(data, weights, range_, bins, interpolation_wrap) # >>> assert np.abs(hist.sum() - weights.sum()) < 1E-9 # >>> assert hist.size == bins # >>> assert edges.size == bins + 1 # >>> result = get_histinfo_str(hist, edges) # >>> print(result) """ assert bins > 0, 'must have nonzero bins' data = np.asarray(data) if weights is not None: weights = np.asarray(weights) assert np.all(weights.shape == data.shape), 'shapes disagree' weights = weights.ravel() data = data.ravel() # Compute bin edges like in np.histogram start, stop = float(range_[0]), float(range_[1]) if start == stop: start -= 0.5 stop += 0.5 # Find bin edges hist_dtype = np.float64 # Compute bin step size, add one if last bin is the same as the first step = (stop - start) / float((bins + interpolation_wrap)) #edges = [start + i * step for i in range(bins + 1)] #centers = hist_edges_to_centers(edges) half_step = step / 2.0 # Find fractional bin center index for each datapoint data_offset = start + half_step frac_index = (data - data_offset) / step # Find bin center to the left of each datapoint left_index = np.floor(frac_index).astype(np.int32) # Find bin center to the right of each datapoint right_index = left_index + 1 # Find the fraction of the distiance the right center is away from the datapoint right_alpha = (frac_index - left_index) left_alpha = 1.0 - right_alpha if DEBUG_ROTINVAR: print('bins = %r' % bins) print('step = %r' % step) print('half_step = %r' % half_step) print('data_offset = %r' % data_offset) TAU = 2 * np.pi print("-.5 MOD tau = %r" % (-.5 % TAU, )) # Handle edge cases if interpolation_wrap: # when the stop == start (like in orientations) left_index %= bins right_index %= bins else: left_index[left_index < 0] = 0 right_index[right_index >= bins] = bins - 1 # Each keypoint votes into its left and right bins left_vote = left_alpha * weights right_vote = right_alpha * weights hist = np.zeros((bins, ), hist_dtype) # TODO: can problably do this faster with cumsum for index, vote in zip(left_index, left_vote): hist[index] += vote for index, vote in zip(right_index, right_vote): hist[index] += vote if interpolation_wrap: edges = np.linspace(start, stop, bins + 1, endpoint=False) else: edges = np.linspace(start, stop, bins + 1, endpoint=True) if DEBUG_ROTINVAR: import vtool as vt assert np.allclose(np.diff(edges), step) print(hist.shape) print(edges.shape) print(vt.kpts_docrepr(hist, 'hist', False)) print(vt.kpts_docrepr(edges, 'edges', False)) return hist, edges