def wass_2Ddist_approx(ssData, ssFake): """ Compute the Wasserstein via a projection onto the hilbert space filling curve. Parameters ---------- ssData, ssFake : n*2 arrays, where n is the sample size Returns ------- scalar The Wasserstein distance between the 2D samples """ maxData = np.max([np.max(ssData), np.max(ssFake)]) k = int(np.ceil(np.log(maxData + 1) / np.log(2))) hilbert_curve = HilbertCurve(k, 2) permut = np.argsort(hilbert_curve.distances_from_points( ssData.astype(int))) permutFake = np.argsort( hilbert_curve.distances_from_points(ssFake.astype(int))) diff = ssData[permut, :] - ssFake[permutFake, :] sqrtSumSqrs = np.sqrt(np.sum(diff**2, axis=1)) dist = np.mean(sqrtSumSqrs) return dist
def build_superworld(world, new_size): p = int( math.log2(len(world)) ) + 1 # 2^p is number of points along each dimention of the space hc = HilbertCurve(p, 2) node_seq_coords = [(hc.distance_from_coordinates(n[1]['coords']), n[0]) for n in world.nodes(data=True)] node_seq_coords.sort() chunks = np.array_split(node_seq_coords, new_size) center_nodes = [chunk[len(chunk) // 2][1] for chunk in chunks] node_mapping = nx.voronoi_cells(world, center_nodes) new_nodes = [] i = 0 for center_node in center_nodes: new_nodes.append((i, {"nodes": node_mapping[center_node]})) for n in node_mapping[center_node]: world.nodes[n]['supernode'] = i i += 1 superworld = nx.Graph( ) # we always use graph to simplify training, for both world and superworld superworld.add_nodes_from(new_nodes) # we assume all areas are approximately the same size, so we add edges in superworld of the same length edges = set() for e in world.edges(): n1 = world.nodes[e[0]]['supernode'] n2 = world.nodes[e[1]]['supernode'] if n1 != n2 and (n1, n2) not in edges: edges.add((n1, n2)) superworld.add_edges_from(list(edges)) return superworld
def create_node_remap(nodes, channels_obj): N = 2 p = math.ceil(math.log2(max(channels_obj.x_max, channels_obj.y_max))) point_map = {} for node in nodes: x = node.loc.x_low y = node.loc.y_low if (x, y) not in point_map: point_map[(x, y)] = [] point_map[(x, y)].append(node.id) hilbert_curve = HilbertCurve(p, N) idx = 0 id_map = {} for h in range(hilbert_curve.max_h + 1): coord = tuple(hilbert_curve.coordinates_from_distance(h)) if coord not in point_map: continue for old_id in point_map[coord]: id_map[old_id] = idx idx += 1 del point_map[coord] return lambda x: id_map[x]
def __init__(self, data_label, augment=False): self.augment = augment self.data, self.label = data_label self.p = 7 # compute hilbert order for voxelized space logging.info('Computing hilbert distances...') self.hilbert_curve = HilbertCurve(self.p, 3)
def range2bbox(hlevel, query, dims=2, margin=0): hilbert_curve = HilbertCurve(hlevel, dims) inc = 0 # ite = 0 start = query["start"] + 1 points = [] if start % 4 is 1: points.append(start) start += 1 if start % 4 is 2: points.append(start) start += 1 if start % 4 is 3: points.append(start) start += 1 points.append(start) # assume at this ppoint, start is always at the end of a level 0 while start < query["end"] + 1: # ite += 1 # print(inc) # locate the proper power incrementer # the incrementor indicates the maximum power of 4 while start % (4**(inc + 1)) == 0: inc += 1 while inc >= 0: # to get min x, min y, max x, max y, it is necessary to # locate the diagnol coordinates. # the 3rd point of the thrid sub-quadrons is always diagnol # to the starting point. if start + (4**inc) <= query["end"] + 1: points.append(start + 1) displacement = 0 for x in range(inc - 1, -1, -1): # the following lines are equivalent, and does not # improve any speed # displacement = displacement | (0b01 << (2 * x)) displacement += 2 * 4**x points.append(start + displacement + 1) start += 4**inc break else: inc = inc - 1 # print(points) hillcorX = [] hillcorY = [] for point in points: [x, y] = hilbert_curve.coordinates_from_distance(point) # print(x, y, point) hillcorX.append(x) hillcorY.append(y) bbox = (min(hillcorX) - margin, min(hillcorY) - margin, max(hillcorX) + margin, max(hillcorY) + margin) # print(bbox) # print(time.time() - now) return bbox
def hilbert_sort(conf, D): hc = HilbertCurve(64, D) int_confs = (conf * 1000).astype(np.int64) dists = [] for xyz in int_confs.tolist(): dist = hc.distance_from_coordinates(xyz) dists.append(dist) perm = np.argsort(dists) return perm
def test_base(self): """Assert list is unmodified""" n = 4 p = 8 hilbert_curve = HilbertCurve(p, n) x = [[1, 5, 3, 19]] x_in = list(x) h = hilbert_curve.distances_from_points(x_in) self.assertEqual(x, x_in)
def __init__(self, root_dir, phase='train', augment=False): self.phase = phase self.augment = augment self.data, self.label = load_data(root_dir=root_dir, phase=phase) self.p = 7 # compute hilbert order for voxelized space logging.info('Computing hilbert distances...') self.hilbert_curve = HilbertCurve(self.p, 3)
def load_code_linear(fileobj): code_helper = defaultdict(lambda: defaultdict(str)) chars = "".join(char for line in fileobj for char in line.strip()) p = (ceil(len(chars)**0.5) - 1).bit_length() hilbert = HilbertCurve(p, 2) for step, char in enumerate(chars): y, x = hilbert.coordinates_from_distance(step) code_helper[x][y] = char return code_helper, p
def RGBToImage (C, p, N): desired_size = 2**p im2 = Image.new("RGB", (desired_size , desired_size) , (255,255,255)) hilbert_curve = HC(p, N) for i in range(4**p): coords = hilbert_curve.coordinates_from_distance(i) #coords becomes a tuple, with an x and y value (in that order - which is why you take x coord = coords[0] and raw y = coords[1] - but then you have to change y to flip it and asjust it because the y axis goes from 0 to 99 and not 1 to 100) im2.putpixel((coords[0], (desired_size - coords[1] - 1)), (C[3*i],C[3*i+1],C[3*i+2])) pix = im2.load() PaddingColour2 = pix[0, 0] return [PaddingColour2, im2]
def test_points_from_distances_ndarray(self): """Assert tuple type matching works in points_from_distances""" n = 2 p = 3 hilbert_curve = HilbertCurve(p, n) dists = np.arange(hilbert_curve.max_h + 1) points = hilbert_curve.points_from_distances(dists, match_type=True) target_type = type(dists) self.assertTrue(isinstance(points, target_type)) self.assertTrue(all(isinstance(vec, target_type) for vec in points))
def test_pt_one(self): """Assert x=0 raises an error""" n = 0 p = 5 with pytest.raises(ValueError): hilbert_curve = HilbertCurve(p, n) n = 3 p = 0 with pytest.raises(ValueError): hilbert_curve = HilbertCurve(p, n)
def test_pt_one(self): """Assert x.1 raises an error""" n = 3 p = 5.1 with pytest.raises(TypeError): hilbert_curve = HilbertCurve(p, n) n = 3.1 p = 5 with pytest.raises(TypeError): hilbert_curve = HilbertCurve(p, n)
def hilbert_distance(coordinates, iterations=5): count_entries, dims = coordinates.shape distances = np.zeros([count_entries]) cells = 2**(iterations * dims) transform = HilbertCurve(iterations, dims) mm = MinMaxScaler((0, transform.max_x)) normed_coords = np.rint(mm.fit_transform(coordinates)).astype('int') for i in range(len(coordinates)): distances[i] = transform.distance_from_coordinates(normed_coords[i]) return distances
def hilbert_curve(p=12, n=2): hilbert_curve = HilbertCurve(p, n) coords = [] i = 0 while True: try: coords.append(hilbert_curve.coordinates_from_distance(i)) i += 1 except: break np.savez_compressed(f'hilvert_p{p}_n{n}.npz', np.array(coords))
def hilbert_idx(rows, cols): assert rows == cols, "Image must be square for Hilbert curve" assert (rows > 0 and (rows & (rows - 1)) == 0), "Must have power-of-two sized image" order = int(np.log2(rows)) curve = HilbertCurve(order, 2) idx = np.zeros((rows * cols, 2), dtype=np.int) for i in range(rows * cols): coords = curve.coordinates_from_distance(i) # cols, then rows idx[i, 0] = coords[1] idx[i, 1] = coords[0] return idx
def __init__(self, root_dir, phase='train', augment=False): self.phase = phase self.augment = augment self.data, self.label = load_data(root_dir=root_dir, phase=phase) self.p = 7 # hilbert iteration # by changing the value of p, we can control the level of hilbert curve. # this hyperparameter has to be careful and ideally, p should be different for each point cloud. # (because the density distribution is different # compute hilbert order for voxelized space logging.info('Computing hilbert distances...') self.hilbert_curve = HilbertCurve(self.p, 3)
def test_reversibility(self): """Assert points_from_distances and distances_from_points are inverse operations.""" n = 3 p = 5 hilbert_curve = HilbertCurve(p, n) n_h = 2**(n * p) distances = list(range(n_h)) coordinates = hilbert_curve.points_from_distances(distances) distances_check = hilbert_curve.distances_from_points(coordinates) for dist, dist_check in zip(distances, distances_check): self.assertEqual(dist, dist_check)
def create_curve(): hilbert_curve = HilbertCurve(4, 2) d = np.dtype(np.uint8) curve = np.empty((400, 2), dtype=d) reverse_curve = np.empty((20, 20), dtype=d) for i in range(9): curve[4 * i] = [2 * i, 0] curve[4 * i + 1] = [2 * i, 1] curve[4 * i + 2] = [2 * i + 1, 1] curve[4 * i + 3] = [2 * i + 1, 0] curve[36] = [18, 0] curve[37] = [19, 0] for i in range(9): curve[38 + 4 * i] = [19, 2 * i + 1] curve[38 + 4 * i + 1] = [18, 2 * i + 1] curve[38 + 4 * i + 2] = [18, 2 * i + 2] curve[38 + 4 * i + 3] = [19, 2 * i + 2] curve[74] = [19, 19] curve[75] = [18, 19] for i in range(8): curve[76 + 4 * i] = [17 - 2 * i, 19] curve[76 + 4 * i + 1] = [17 - 2 * i, 18] curve[76 + 4 * i + 2] = [17 - 2 * i - 1, 18] curve[76 + 4 * i + 3] = [17 - 2 * i - 1, 19] curve[108] = [1, 19] curve[109] = [0, 19] for i in range(8): curve[110 + 4 * i] = [0, 19 - 2 * i - 1] curve[110 + 4 * i + 1] = [1, 19 - 2 * i - 1] curve[110 + 4 * i + 2] = [1, 19 - 2 * i - 2] curve[110 + 4 * i + 3] = [0, 19 - 2 * i - 2] curve[142] = [0, 2] curve[143] = [1, 2] for i in range(256): curve[144 + i][0] = hilbert_curve.coordinates_from_distance(i)[0] + 2 curve[144 + i][1] = hilbert_curve.coordinates_from_distance(i)[1] + 2 '''for i in range(399): if (curve[i][0] != curve[i + 1][0] and curve[i][1] != curve[i + 1][1]): print("error: ", i)''' pic = np.zeros([400, 400, 3], dtype=np.uint8) for i in range(400): for j in range(10): for k in range(10): pic[20 * curve[i][0] + j + 5][20 * curve[i][1] + k + 5][0] = int(i / 400 * 255) new_im = Image.fromarray(pic) new_im.save("../Misc/curve.png") #idx2numpy.convert_to_file("../MNIST/curve", curve)
def __init__( self, rotation_axis=((0, 1), (1, 2), (3, 0)), dimension_columns = ['x','y','z','t'], iterations=10 ): # TODO: document rotation_axis self.rotation_axis = rotation_axis self.dimension_columns = dimension_columns self.dims = len(dimension_columns) self.dims_output = 1+ len(self.rotation_axis) self.cells = 2 ** (iterations * self.dims) self.transform = HilbertCurve(iterations, self.dims) self.scale_factor = self.transform.max_x self.edge_resolution = self.transform.max_x
def test_distances_from_points_tuple(self): """Assert tuple type matching works in distances_from_points""" n = 2 p = 3 hilbert_curve = HilbertCurve(p, n) points = tuple([ tuple([0, 0]), tuple([7, 7]), ]) distances = hilbert_curve.distances_from_points(points, match_type=True) target_type = type(points) self.assertTrue(isinstance(distances, target_type))
def test_distances_from_points_ndarray(self): """Assert ndarray type matching works in distances_from_points""" n = 2 p = 3 hilbert_curve = HilbertCurve(p, n) points = np.array([ [0, 0], [7, 7], ]) distances = hilbert_curve.distances_from_points(points, match_type=True) target_type = type(points) self.assertTrue(isinstance(distances, target_type))
def verify(self): """ Verification with simple examples: 1. Hilbert curve (should have fracDim=2) 2. Randomly scattered points (should have fracDim=2) 3. Straight line (should have fracDim=1) NOTE: Computing example 1 requires hilbertcurve package Returns ------- veri : List of floats List containing metric(s) for verification case. """ from hilbertcurve.hilbertcurve import HilbertCurve # 1. Hilbert curve (should have fracDim=2) t1 = np.zeros((512, 512)) pHil = 8 nHil = 2 dist = 2 ** (pHil * nHil) hilbert_curve = HilbertCurve(pHil, nHil) coords = np.zeros((dist, nHil)) for i in range(dist): coords[i, :] = hilbert_curve.coordinates_from_distance(i) coords = coords.astype(int) coords *= 2 coordsAv = (coords[1:, :] + coords[:-1, :]) / 2 coordsAv = coordsAv.astype(int) t1[coords[:, 0], coords[:, 1]] = 1 t1[coordsAv[:, 0], coordsAv[:, 1]] = 1 # 2. Random points (should have fracDim=2) t2 = np.random.rand(512, 512) ind = np.where(t2 > 0.5) t2[ind] = 1 ind = np.where(t2 <= 0.5) t2[ind] = 0 # 3. Vertical line (should have fracDim=1) t3 = np.zeros((512, 512)) t3[:, 250:252] = 1 tests = [t1, t2, t3] veri = [] for i in range(len(tests)): fracDim = self.metric(tests[i]) veri.append(fracDim) return veri
def assign_hilbert_curve(normals: np.ndarray): dtype = np.uint32 max_length_axis = 2**16 - 1 bucket_normals = normals bucket_normals_xy = (azimuth_equidistant(bucket_normals) * max_length_axis).astype(dtype) # print(bucket_normals_xy) hilbert_curve = HilbertCurve(16, 2) bucket_normals_hv = [] for i in range(bucket_normals_xy.shape[0]): hv = hilbert_curve.distance_from_coordinates(bucket_normals_xy[i, :]) bucket_normals_hv.append(hv) bucket_normals_hv = np.array(bucket_normals_hv) return bucket_normals_hv
def test_pt_oh(self): """Assert x.0 goes to x""" n = 3.0 n_int = 3 p = 5 hilbert_curve = HilbertCurve(p, n) self.assertTrue(isinstance(hilbert_curve.n, int)) self.assertEqual(hilbert_curve.n, n_int) n = 3 p_int = 5 p = 5.0 hilbert_curve = HilbertCurve(p, n) self.assertTrue(isinstance(hilbert_curve.p, int)) self.assertEqual(hilbert_curve.p, p_int)
def load_code(self, filename, linear_mode=False): with open(filename, encoding=self.encoding) as f: if linear_mode: self.code, self.p = self.load_code_linear(f) else: self.code, self.p = self.load_code_hilbert(f) self.s = 2**self.p self.x, self.y = 0, 0 self.timestamp = time.time() self.catch_mark = None self.dir = 1 self.buf = "" self.mode = "command" self.previous_cmd = " " self.hilbert = HilbertCurve(self.p, 2) # side length p, 2 dimensions
def convert1dto2d(x): """ x = [N, 1024, 3] return [N, 32, 32, 3] """ N = x.shape[0] hilbert_curve = HilbertCurve(5, 2) s = np.zeros((N, 32, 32, 3)) cells = [hilbert_curve.coordinates_from_distance(d) for d in range(1024)] for k in range(N): for d in range(1024): i = cells[d][0] j = cells[d][1] s[k, i, j, :] = x[k, d, :] return s
class HCFlatten(layers.Layer): def __init__(self, **kwargs): super(HCFlatten, self).__init__(**kwargs) def build(self, input_shape): self.side_length = input_shape[1] if 2**math.log2(self.side_length) != self.side_length: raise dim = len(input_shape) - 2 iters = int(math.log2(input_shape[1])) self.hc = HilbertCurve(n=dim, p=iters) self.side_length = input_shape[1] self.channel_dim = input_shape[-1] self.place_holder = tf.ones((self.side_length**2, 1)) self.idxs = np.zeros(self.side_length**2, dtype='int') for i in range(self.side_length**2): x, y = self.hc.coordinates_from_distance(i) idx = x + self.side_length * y self.idxs[i] = idx def compute_output_shape(self, input_shape): return (input_shape[0], self.side_length**2, 1) def call(self, inputs): shape = (-1, self.side_length**2, self.channel_dim) inputs = tf.reshape(inputs, shape) def apply_gather(x): return tf.gather(x, self.idxs) #outputs = tf.reshape(tf.map_fn(apply_gather, inputs), shape + (1,)) outputs = tf.map_fn(apply_gather, inputs) return outputs
def makeHilbertLocationHeuristic(preferences): curve_size = math.ceil( math.sqrt(max(preferences.shape[0], preferences.shape[1]))) print(curve_size) curve_size = 4 h_curve = HilbertCurve(curve_size, 2) def h_coords(): for i in range(100000): #print(i) try: coords = h_curve.coordinates_from_distance(i) except ValueError: coords = [0, 0] #print(coords) yield coords cell_order = fill_with_curve(preferences, h_coords()) #print(cell_order) def hilbertLocationHeuristic(wave): unresolved_cell_mask = (numpy.count_nonzero(wave, axis=0) > 1) cell_weights = numpy.where(unresolved_cell_mask, cell_order, numpy.inf) row, col = numpy.unravel_index(numpy.argmin(cell_weights), cell_weights.shape) return [row, col] return hilbertLocationHeuristic
def build(self, input_shape): self.side_length = input_shape[1] if 2**math.log2(self.side_length) != self.side_length: raise dim = len(input_shape) - 2 iters = int(math.log2(input_shape[1])) self.hc = HilbertCurve(n=dim, p=iters) self.side_length = input_shape[1] self.channel_dim = input_shape[-1] self.place_holder = tf.ones((self.side_length**2, 1)) self.idxs = np.zeros(self.side_length**2, dtype='int') for i in range(self.side_length**2): x, y = self.hc.coordinates_from_distance(i) idx = x + self.side_length * y self.idxs[i] = idx