@staticmethod<EOL><INDENT>def estimate_distances(addresses, mesh):<DEDENT>
<EOL>d = np.full(mesh.vertex_count, np.inf) <EOL>(faces, coords) = address_data(addresses, <NUM_LIT:2>)<EOL>coords = np.vstack([coords, [<NUM_LIT:1> - np.sum(coords, axis=<NUM_LIT:0>)]])<EOL>faces  = mesh.tess.index(faces)<EOL>for (f,x) in zip(faces.T, coords.T):<EOL><INDENT>fx = mesh.coordinates[:,f]<EOL>pt = np.sum(fx * x, axis=<NUM_LIT:1>)<EOL>dd = np.sqrt(np.sum((fx.T - pt)**<NUM_LIT:2>, axis=<NUM_LIT:1>))<EOL>ii = (d[f] > dd)<EOL>d[f[ii]] = dd[ii]<EOL><DEDENT>ii0 = np.where(np.isfinite(d))[<NUM_LIT:0>]<EOL>if len(ii0) == <NUM_LIT:0>: raise ValueError('<STR_LIT>')<EOL>(max_iter,it) = (mesh.vertex_count + <NUM_LIT:1>, <NUM_LIT:0>)<EOL>(u,v) = np.hstack([mesh.tess.indexed_edges, np.flipud(mesh.tess.indexed_edges)])<EOL>elens = np.concatenate([mesh.edge_lengths, mesh.edge_lengths])<EOL>updated = ii0<EOL>while len(updated) > <NUM_LIT:0>:<EOL><INDENT>if it > max_iter: raise ValueError('<STR_LIT>')<EOL>else: it += <NUM_LIT:1><EOL>ii = np.where(np.isin(u, updated))[<NUM_LIT:0>]<EOL>(uu,vv) = (u[ii],v[ii])<EOL>dnew = d[uu] + elens[ii]<EOL>(vv,ridx) = np.unique(vv, return_inverse=True)<EOL>mx = np.max(dnew) + <NUM_LIT:1.0><EOL>mtx = sps.csr_matrix((mx - dnew, (ridx, np.arange(len(dnew)))))<EOL>dnew = mx - flattest(mtx.max(axis=<NUM_LIT:1>))<EOL>jj = np.where(d[vv] > dnew)[<NUM_LIT:0>]<EOL>updated = vv[jj]<EOL>d[updated] = dnew[jj]<EOL><DEDENT>return d<EOL>
Path.estimate_distances(addresses, mesh) estimates all the distances between the vertices in
  the mesh and the path implied by the given set of addresses using a minimum-graph-distance
  algorithm over the mesh edges.