def plot_tree(tree): root_x = input_x[tree.root.i_input] activity = preprocessor.input_activities[tree.root.i_input] plot_branch(sensor_x, root_x, ymin, activity, branch_length) nodes = tree.get_list() for node in nodes: if node.lo_child is not None: y_start = ymin + (node.depth + 1.) * branch_length x_start = input_x[node.i_input] x_end = input_x[node.lo_child.i_input] lo_activity = preprocessor.input_activities[ node.lo_child.i_input] plot_branch( x_start, x_end, y_start, lo_activity, branch_length, is_leaf=node.lo_child.leaf, max_y=ymax, ) vt.plot_point_activity( x_end, y_start + branch_length, lo_activity, x_spacing, ) x_end = input_x[node.hi_child.i_input] hi_activity = preprocessor.input_activities[ node.hi_child.i_input] plot_branch( x_start, x_end, y_start, hi_activity, branch_length, is_leaf=node.hi_child.leaf, max_y=ymax, ) vt.plot_point_activity( x_end, y_start + branch_length, hi_activity, x_spacing, )
def render( filter, bbox, y_pool, pool_viz_map, radius=0, n_commands=None, n_inputs=None, n_bundles_all=None, ): """ Make a picture of the discretization that happens in an input filter. To simplify the notation on transforms here, the following substitutions will be used: A: feature pool in visualized order B: feature pool in natural order (the order passed in) C: features in natural order D: features in visualized order Parameters ---------- bbox: list of floats Of the form [x_bottom, x_top, y_left, y_right] filter: InputFilter y_pool: array of floats pool_viz_map: 2D array of ints radius: float n_commands, n_inputs: int n_bundles_all: list of int Returns ------- y_features: array of floats feature_viz_map: 2D array of ints """ xmin, xmax, ymin, ymax = bbox width = xmax - xmin height = ymax - ymin n_pool = y_pool.size y_pool_spacing = (height - 2 * radius) / (n_pool + 1) y_A = np.linspace( ymin + radius + y_pool_spacing, ymax - radius - y_pool_spacing, num=n_pool, endpoint=True, ) # Place labels alongside the features to show where they come from. if (n_commands is not None and n_inputs is not None and n_bundles_all is not None): i_last = n_commands - 1 ylabel = "commands" text_sep = width * vt.text_shift plt.text( xmin - text_sep, y_A[i_last], ylabel, fontsize=4, color=vt.copper, verticalalignment="top", horizontalalignment="right", rotation=-90, family="sans-serif", ) i_last += n_inputs ylabel = "inputs" text_sep = width * vt.text_shift plt.text( xmin - text_sep, y_A[i_last], ylabel, fontsize=4, color=vt.copper, verticalalignment="top", horizontalalignment="right", rotation=-90, family="sans-serif", ) for i_ziptie, n_bundles in enumerate(n_bundles_all): if n_bundles > 0: i_last += n_bundles ylabel = "ziptie " + str(i_ziptie) text_sep = width * vt.text_shift plt.text( xmin - text_sep, y_A[i_last], ylabel, fontsize=4, color=vt.copper, verticalalignment="top", horizontalalignment="right", rotation=-90, family="sans-serif", ) map_AB = pool_viz_map.T activities_B = filter.candidate_activities activities_A = np.matmul(map_AB, activities_B) n_inputs = (np.where(np.sum(filter.mapping, axis=0))[0]).size map_BC = filter.mapping[:n_pool, :n_inputs] map_AC = np.matmul(map_AB, map_BC) order_CD = np.argsort(np.argsort(np.matmul(y_A, map_AC))) map_CD = np.zeros((n_inputs, n_inputs), dtype=np.int) map_CD[np.arange(n_inputs, dtype=np.int), order_CD] = 1 map_AD = np.matmul(map_AC, map_CD) y_spacing = (height - 2 * radius) / (n_inputs + 1) y_D = np.linspace( ymin + radius + y_spacing, ymax - radius - y_spacing, num=n_inputs, endpoint=True, ) activities_D = np.matmul(activities_A, map_AD) i_DA = np.matmul(np.arange(n_pool, dtype=np.int), map_AD) # Show the filter's selection for i_D, activity in enumerate(activities_D): i_A = i_DA[i_D] y_end = y_D[i_D] y_start = y_A[i_A] vt.plot_curve_activity_horiz(y_start, y_end, xmin, xmax, activity) vt.plot_point_activity(xmax, y_end, activity, y_spacing) return y_D, map_CD
def render(ziptie, bbox, x_inputs, cable_viz_map, y_prev, radius=0): """ Make a picture of the cable-to-bundle combinations that happen in a ziptie. To keep notation simpler, maps will be referred to as map_xy, where x and y can be any of the following: A: cable visualization order B: cable natural order (in which the ziptie receives it) C: bundle natural order (in which ziptie.map creates it) D: bundle visualization order Parameters ---------- bbox: list of floats Of the form [x_left, x_right, y_bottom, y_top] ziptie: Ziptie cable_viz_map: 2D array of ints y_prev: float radius: float Returns ------- x_bundles: array of floats The absolute x positions of the cables. bundle_viz_map: 2D array of ints The indices for ordering bundles to align with the visualization. """ xmin, xmax, ymin, ymax = bbox frame_width = xmax - xmin height = ymax - ymin xlabel = ziptie.name text_sep = height * vt.text_shift plt.text( xmin + radius, ymin + height + text_sep, xlabel, fontsize=4, color=vt.copper, verticalalignment="bottom", horizontalalignment="right", family="sans-serif", ) n_A = x_inputs.size n_D = ziptie.n_bundles x_A_spacing = (frame_width - 2 * radius) / (n_A + 1) x_A = np.linspace( xmin + radius + x_A_spacing, xmax - radius - x_A_spacing, num=n_A, endpoint=True, ) map_BA = cable_viz_map map_AB = map_BA.T activities_B = ziptie.cable_activities[:n_A] # activities_A = np.matmul(map_AB, activities_B) # activities_A = np.matmul(activities_B, map_BA) if n_D > 0: x_D_spacing = (frame_width - 2 * radius) / (n_D + 1) x_D = np.linspace( xmin + radius + x_D_spacing, xmax - radius - x_D_spacing, num=n_D, endpoint=True, ) map_BC = ziptie.mapping[:n_A, :n_D] x_B = np.matmul(x_A, map_AB) bundle_score = (np.sum(x_B[:, np.newaxis] * map_BC, axis=0) / np.sum(map_BC, axis=0)) map_CD = np.zeros((n_D, n_D), dtype=np.int) map_CD[np.arange(n_D, dtype=np.int), np.argsort(np.argsort(bundle_score))] = 1 i_CD = np.matmul(map_CD, np.arange(n_D, dtype=np.int)) i_BA = np.matmul(np.arange(n_A, dtype=np.int), map_AB) for i_B, activity in enumerate(activities_B): i_A = i_BA[i_B] for i_C in np.where(map_BC[i_B, :])[0]: i_D = i_CD[i_C] x_end = x_D[i_D] x_start = x_A[i_A] vt.plot_curve_activity(x_start, x_end, ymin, ymax, activity) activities_C = ziptie.bundle_activities activities_D = np.matmul(activities_C, map_CD) for i_D, activity in enumerate(activities_D): vt.plot_point_activity(x_D[i_D], ymax, activity, x_D_spacing) else: x_D = None map_CD = None x_bundles = x_D bundle_viz_map = map_CD return x_bundles, bundle_viz_map
def render(postprocessor, bbox, radius=0, phase=0): """ Make a picture of the discretization that happens in the Preprocessor. Parameters ---------- bbox: list of floats Of the form [x_bottom, x_top, y_left, y_right] phase: int postprocessor: Postprocessor radius: float The corner radius of the box. Returns ------- x_commands: array of floats The absolute x positions of the command nodes. i_to_viz: 2D array of ints Mapping from commands to visualization order. """ xmin, xmax, ymin, ymax = bbox width = xmax - xmin height = ymax - ymin n_commands = postprocessor.n_commands n_actions = postprocessor.n_actions # Collect positions from all the commands. n_commands_per_action = int(n_commands / n_actions) x_command_spacing = ((width - 2 * radius) / (n_commands + 1)) x_commands = (xmin + radius + x_command_spacing * np.cumsum(np.ones(n_commands))) x_action_spacing = (width - 2 * radius) / (n_actions + 1) x_actions = (xmin + radius + x_action_spacing * np.cumsum(np.ones(n_commands))) i_to_viz = np.eye(n_commands, dtype=np.int) # Create labels xlabel = "actions" text_sep = height * vt.text_shift plt.text( # xmin + width * vt.xlabel_shift, xmin + radius, ymin - text_sep, xlabel, fontsize=4, color=vt.copper, verticalalignment="top", horizontalalignment="right", family="sans-serif", ) xlabel = "commands" text_sep = height * vt.text_shift plt.text( xmin + radius, ymin + height + text_sep, xlabel, fontsize=4, color=vt.copper, verticalalignment="bottom", horizontalalignment="right", family="sans-serif", ) # Find the spacing between labeled sensors n_target = 4 d_label = int(2**np.maximum(0, int(np.log2(n_actions / n_target)))) # Show the upward, sensed commands from the previous time step. for i_action, _ in enumerate(postprocessor.actions): # Apply action labels if i_action % d_label == 0: plt.text( x_actions[i_action], ymin - text_sep, str(i_action), fontsize=4, color=vt.copper, verticalalignment="top", horizontalalignment="center", family="sans-serif", ) for j in range(n_commands_per_action): i_command = i_action * n_commands_per_action + j command_activity = postprocessor.previous_commands[i_command] vt.plot_point_activity( x_commands[i_command], ymax, command_activity, x_command_spacing, ) vt.plot_curve_activity( x_actions[i_action], x_commands[i_command], ymin, ymax, command_activity, ) offset = (x_actions[1] - x_actions[0]) / 10 # Show the downward commands, to be executed during the next time step. for i_action, action in enumerate(postprocessor.actions): for j in range(n_commands_per_action): i_command = i_action * n_commands_per_action + j command_activity = postprocessor.command_activities[i_command] if command_activity > .02: vt.plot_point_activity( x_commands[i_command] + offset, ymax, command_activity, x_command_spacing, activity_color=vt.oxide, ) vt.plot_curve_activity( x_actions[i_action] + offset, x_commands[i_command] + offset, ymin, ymax, command_activity, activity_color=vt.oxide, ) vt.plot_point_activity( x_actions[i_action] + offset, ymin, action, x_action_spacing, activity_color=vt.oxide, ) return x_commands, i_to_viz
def render(filter, bbox, x_pool_prev, pool_viz_map, y_prev, radius=0): """ Make a picture of the discretization that happens in an input filter. To simplify the notation on transforms here, the following substitutions will be used: A: candidate pool in visualized order B: candidate pool in natural order (the order passed in) C: inputs in natirual order D: inputs in visualized order Parameters ---------- bbox: list of floats Of the form [x_bottom, x_top, y_left, y_right] filter: InputFilter radius: float Returns ------- x_cables: array of floats The absolute x positions of the cables. i_to_viz_cables: 2D array of ints Mapping from cable pool to their visualization order """ xmin, xmax, ymin, ymax = bbox frame_width = xmax - xmin # frame_height = ymax - ymin n_pool = x_pool_prev.size x_pool_spacing = (frame_width - 2 * radius) / (x_pool_prev.size + 1) x_A = np.linspace( xmin + radius + x_pool_spacing, xmax - radius - x_pool_spacing, num=n_pool, endpoint=True, ) map_BA = pool_viz_map map_AB = map_BA.T activities_B = filter.candidate_activities activities_A = np.matmul(activities_B, map_BA) # Connect the previous block(s) to this one. for i_A, activity in enumerate(activities_A): vt.plot_curve_activity(x_pool_prev[i_A], x_A[i_A], y_prev, ymin, activity) vt.plot_point_activity(x_A[i_A], ymin, activity, x_pool_spacing) n_inputs = (np.where(np.sum(filter.mapping, axis=0))[0]).size map_BC = filter.mapping[:n_pool, :n_inputs] map_AC = np.matmul(map_AB, map_BC) order_CD = np.argsort(np.argsort(np.matmul(x_A, map_AC))) map_CD = np.zeros((n_inputs, n_inputs), dtype=np.int) map_CD[np.arange(n_inputs, dtype=np.int), order_CD] = 1 map_AD = np.matmul(map_AC, map_CD) x_spacing = (frame_width - 2 * radius) / (n_inputs + 1) x_D = np.linspace( xmin + radius + x_spacing, xmax - radius - x_spacing, num=n_inputs, endpoint=True, ) activities_D = np.matmul(activities_A, map_AD) i_DA = np.matmul(np.arange(n_pool, dtype=np.int), map_AD) # Show the filter's selection for i_D, activity in enumerate(activities_D): i_A = i_DA[i_D] x_end = x_D[i_D] x_start = x_A[i_A] vt.plot_curve_activity(x_start, x_end, ymin, ymax, activity) vt.plot_point_activity(x_end, ymax, activity, x_spacing) return x_D, map_CD
def render(featurizer, bbox, viz_maps, radius=0): """ Parameters ---------- featurizer : Featurizer bbox: list of floats In the format [xmin, xmax, ymin, ymax] viz_maps: list of 2D arrays of ints Maps between cable candidate pools and their visualization order. radius: float Returns ------- y_pool_feature: array of floats The absolute positions of each member of the feature pool. feature_viz_map: 2D array of floats Map between the feature pool and their visualization order. """ xmin, xmax, ymin, ymax = bbox # frame_width = xmax - xmin frame_height = ymax - ymin if viz_maps[-1] is None: viz_maps = viz_maps[:-1] block_rows = [] for i_map in np.arange(len(viz_maps), dtype=np.int): block_row = [] mrows, mcols = viz_maps[i_map].shape for j_map in np.arange(len(viz_maps), dtype=np.int): nrows, ncols = viz_maps[j_map].shape if i_map == j_map: block_row.append(np.fliplr(viz_maps[i_map])) else: block_row.append(np.zeros((mrows, ncols), dtype=np.int)) block_rows.append(block_row) map_AB = np.block(block_rows).T map_BC = featurizer.mapping order_CD = np.argsort( np.argsort( np.matmul(np.arange(map_AB.shape[0]), np.matmul(map_AB, map_BC)))) n_D = map_BC.shape[1] map_CD = np.zeros((n_D, n_D), dtype=np.int) map_CD[np.arange(n_D, dtype=np.int), order_CD] = 1 activities_B = [] for level_activities in featurizer.activities: activities_B += list(level_activities) activities_B = np.array(activities_B) activities_D = np.matmul(activities_B, np.matmul(map_BC, map_CD)) y_spacing = (frame_height - 2 * radius) / (n_D + 1) y_D = np.linspace( ymin + radius + y_spacing, ymax - radius - y_spacing, num=n_D, endpoint=True, ) for i_D, activity in enumerate(activities_D): # vt.plot_curve_activity_horiz( # y_start, y_end, xmin, xmax, activity, start=.3) vt.plot_point_activity(xmin, y_D[i_D], activity, y_spacing) return y_D, map_CD