From 93c90377c311a949da9954cac7f44631c165ed3e Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Fri, 1 Jan 2010 13:01:56 +0200 Subject: [PATCH] graph: spath: Fix documentation indentation. --- scikits/image/graph/_spath.pyx | 23 ++++++---- scikits/image/graph/spath.py | 78 ++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/scikits/image/graph/_spath.pyx b/scikits/image/graph/_spath.pyx index d4624ef2..dbb465e0 100644 --- a/scikits/image/graph/_spath.pyx +++ b/scikits/image/graph/_spath.pyx @@ -1,29 +1,34 @@ +# -*- python -*- + import _mcp cimport _mcp cdef extern from "math.h": double fabs(double f) - + cdef class MCP_Diff(_mcp.MCP): """MCP_Diff(costs, offsets=None, fully_connected=True) - + Find minimum-difference paths through an n-d costs array. - - See the documentation for MCP for full details. This class differs from + + See the documentation for MCP for full details. This class differs from MCP in that the cost of a path is not simply the sum of the costs along that path. - + This class instead assumes that the cost of moving from one point to another is the absolute value of the difference in the costs between the - two points + two points. + """ def __init__(self, costs, offsets=None, fully_connected=True): """__init__(costs, offsets=None, fully_connected=True) - + See class documentation. """ _mcp.MCP.__init__(self, costs, offsets, fully_connected) self.use_start_cost = 0 - - cdef _mcp.FLOAT_C _travel_cost(self, _mcp.FLOAT_C old_cost, _mcp.FLOAT_C new_cost, _mcp.FLOAT_C offset_length): + + cdef _mcp.FLOAT_C _travel_cost(self, _mcp.FLOAT_C old_cost, + _mcp.FLOAT_C new_cost, + _mcp.FLOAT_C offset_length): return fabs(old_cost - new_cost) diff --git a/scikits/image/graph/spath.py b/scikits/image/graph/spath.py index 92bd012e..5ce34fee 100644 --- a/scikits/image/graph/spath.py +++ b/scikits/image/graph/spath.py @@ -4,70 +4,76 @@ import _spath def shortest_path(arr, reach=1, axis=-1, output_indexlist=False): """Find the shortest path through an n-d array from one side to another. - Parameters - ---------- - arr : ndarray of float64 - reach : int, optional - By default (``reach = 1``), the shortest path can only move - one row up or down for every step it moves forward (i.e., - the path gradient is limited to 1). `reach` defines the - number of elements that can be skipped along each non-axis - dimension at each step. + Parameters + ---------- + arr : ndarray of float64 + reach : int, optional + By default (``reach = 1``), the shortest path can only move + one row up or down for every step it moves forward (i.e., + the path gradient is limited to 1). `reach` defines the + number of elements that can be skipped along each non-axis + dimension at each step. axis : int, optional The axis along which the path must always move forward (default -1) output_indexlist: bool, optional See return value `p` for explanation. - - Returns - ------- - p : iterable of int - For each step along `axis`, the coordinate of the shortest path. - If `output_indexlist` is True, then the path is returned as a list of - n-d tuples that index into `arr`. If False, then the path is returned - as an array listing the coordinates of the path along the non-axis - dimensions for each step along the axis dimension. That is, - `p.shape == (arr.shape[axis], arr.ndim-1)` except that p is squeezed - before returning so if `arr.ndim == 2`, then - `p.shape == (arr.shape[axis],)` - cost : float - Cost of path. This is the absolute sum of all the - differences along the path. - """ + + Returns + ------- + p : iterable of int + For each step along `axis`, the coordinate of the shortest path. + If `output_indexlist` is True, then the path is returned as a list of + n-d tuples that index into `arr`. If False, then the path is returned + as an array listing the coordinates of the path along the non-axis + dimensions for each step along the axis dimension. That is, + `p.shape == (arr.shape[axis], arr.ndim-1)` except that p is squeezed + before returning so if `arr.ndim == 2`, then + `p.shape == (arr.shape[axis],)` + cost : float + Cost of path. This is the absolute sum of all the + differences along the path. + + """ # First: calculate the valid moves from any given position. Basically, - # always move +1 along the given axis, and then can move anywhere within + # always move +1 along the given axis, and then can move anywhere within # a grid defined by the reach. - if axis < 0: + if axis < 0: axis += arr.ndim offset_ind_shape = (2*reach + 1,) * (arr.ndim - 1) offset_indices = np.indices(offset_ind_shape) - reach - offset_indices = np.insert(offset_indices, axis, np.ones(offset_ind_shape), axis=0) + offset_indices = np.insert(offset_indices, axis, + np.ones(offset_ind_shape), axis=0) offset_size = np.multiply.reduce(offset_ind_shape) offsets = np.reshape(offset_indices, (arr.ndim, offset_size), order='F').T - - # Valid starting positions are anywhere on the hyperplane defined by + + # Valid starting positions are anywhere on the hyperplane defined by # position 0 on the given axis. Ending positions are anywhere on the # hyperplane at position -1 along the same. non_axis_shape = arr.shape[:axis] + arr.shape[axis+1:] non_axis_indices = np.indices(non_axis_shape) non_axis_size = np.multiply.reduce(non_axis_shape) - start_indices = np.insert(non_axis_indices, axis, np.zeros(non_axis_shape), axis=0) + start_indices = np.insert(non_axis_indices, axis, + np.zeros(non_axis_shape), axis=0) starts = np.reshape(start_indices, (arr.ndim, non_axis_size), order='F').T - end_indices = np.insert(non_axis_indices, axis, -np.ones(non_axis_shape), axis=0) + end_indices = np.insert(non_axis_indices, axis, -np.ones(non_axis_shape), + axis=0) ends = np.reshape(end_indices, (arr.ndim, non_axis_size), order='F').T - + # Find the minimum-cost path to one of the end-points m = _spath.MCP_Diff(arr, offsets=offsets) costs, traceback = m.find_costs(starts, ends, find_all_ends=False) - + # Figure out which end-point was found for end in ends: cost = costs[tuple(end)] if cost != np.inf: break traceback = m.traceback(end) + if not output_indexlist: traceback = np.array(traceback) - traceback = np.concatenate([traceback[:,:axis], traceback[:,axis+1:]], axis=1) + traceback = np.concatenate([traceback[:,:axis], traceback[:,axis+1:]], + axis=1) traceback = np.squeeze(traceback) + return traceback, cost -