def perm_sign(self, G, p): if self.even_edges: # The total sign is: # (a:induced sign on vertices) # * (b:induced sign of the unmarked-edge-permutation) # * (c:induced sign unmarked-edge orientations) # * (d:induced sign marked-edge orientations) # note that we have no tadpoles in case of even edges # This is a*b sign = Shared.Perm([ j for j in p if (j < self.n_vertices + self.n_unmarked_edges) ]).signature() # Now * d for (u, v) in G.edges(labels=False): if (u < self.n_vertices and v < self.n_vertices): # We assume the edge is always directed from the larger to smaller index if (u < v and p[u] > p[v]) or (u > v and p[u] < p[v]): sign *= -1 # Finally * c for i in range(self.n_vertices, self.n_vertices + self.n_unmarked_edges): nb = G.neighbors(i) if len(nb) != 2: # This is a graph with a tadpole, and hence zero... we return zero for now, although this is not ideal. return 0 # raise ValueError( # '%s: Vertices of second colour should have 2 neighbours' % str(self)) u = nb[0] v = nb[1] if (u < v and p[u] > p[v]) or (u > v and p[u] < p[v]): sign *= -1 return sign else: # The sign is (induced sign of the marked-edge-permutation) # We assume the edges are always lexicographically ordered # For the computation we use that G.edges() returns the edges in lex ordering # We first label the edges on a copy of G lexicographically G1 = copy(G) self.label_marked_edges(G1) # print("edges before ", [j for (u, v, j) in G1.edges()]) # We permute the graph, and read of the new labels, ... # but only those between internal vertices of the first color, i.e., the first n_vertices ones G1.relabel(p, inplace=True) # print("edges after ", [(u, v, j) for (u, v, j) in G1.edges()]) return Shared.Perm([ j for (u, v, j) in G1.edges() if (u < self.n_vertices and v < self.n_vertices) ]).signature()
def perm_sign(self, G, p): if self.even_edges: # The sign is (induced sign on vertices) * (induced sign edge orientations) sign = Shared.Perm(p).signature() for (u, v) in G.edges(labels=False): # We assume the edge is always directed from the larger to smaller index if (u < v and p[u] > p[v]) or (u > v and p[u] < p[v]): sign *= -1 return sign else: # The sign is (induced sign of the edge permutation) # We assume the edges are always lexicographically ordered # For the computation we use that G.edges() returns the edges in lex ordering # We first label the edges on a copy of G lexicographically G1 = copy(G) Shared.enumerate_edges(G1) # We permute the graph, and read of the new labels G1.relabel(p, inplace=True) return Shared.Perm([j for (u, v, j) in G1.edges()]).signature()
def plot_2d_array(value_dict, ordered_param_range_dict, path, parameter_order=(0, 1)): """Plot a 2 dimensional array given by the value_dict. :param value_dict: Dictionary (parameters tuple -> value) containing the values to be ploted. :type value_dict: dict(tuple -> int) :param ordered_param_range_dict: Ordered dictionary (parameter name -> range of the parameter). :type ordered_param_range_dict: Shared.OrderedDict(str -> range) :param path: Path to the plot file without suffix. :type path: path :param parameter_order: Permutation of the parameter indices, to specify the order of the parameters (Default: None/given ordering). Example: (1, 0) to plot the second parameter on the x-axis and the first on the y-axis. :type parameter_order: list(int) """ path += '.png' if parameter_order in {(0, 1), (1, 0)}: (x_idx, y_idx) = parameter_order else: raise ValueError('invalid parameter order') inverse_order = tuple(Shared.Perm(list(parameter_order)).inverse()) (x_label, x_range) = list(ordered_param_range_dict.items())[x_idx] (y_label, y_range) = list(ordered_param_range_dict.items())[y_idx] if len(list(x_range)) == 0 or len(list(y_range)) == 0: logging.warn('empty parameter range: nothing to plot') return x_min = min(x_range) x_max = max(x_range) x_size = (x_max + 1 - x_min) * Parameters.x_width y_min = min(y_range) y_max = max(y_range) y_size = (y_max + 1 - y_min) * Parameters.y_width fig, ax = plt.subplots(figsize=(x_size, y_size)) plt.xlabel(x_label) plt.ylabel(y_label) plt.xlim(x_min, x_max) plt.ylim(y_min, y_max) for coordinates in itertools.product(x_range, y_range): old_coordinates = tuple(coordinates[i] for i in inverse_order) v = value_dict.get(old_coordinates) if v is not None: if v == '*': v = Parameters.zero_v_symbol elif v == 0: v = Parameters.zero_symbol (x, y) = coordinates ax.text(x, y, str(v), va='center', ha='center') x_ticks_grid = np.arange(x_min - 0.5, x_max + 1, 1) y_ticks_grid = np.arange(y_min - 0.5, y_max + 1, 1) x_ticks = np.arange(x_min, x_max + 1, 1) y_ticks = np.arange(y_min, y_max + 1, 1) ax.set_xticks(x_ticks) ax.set_yticks(y_ticks) ax.set_xticks(x_ticks_grid, minor=True) ax.set_yticks(y_ticks_grid, minor=True) ax.grid(which='minor') plt.tight_layout() StoreLoad.generate_path(path) plt.savefig(path)
def plot_3d_array(value_dict, ordered_param_range_dict, path, parameter_order=(0, 1, 2), x_plots=2): """Plot a 3 dimensional array given by the value_dict as a list of 2 dimensional plots with x_plots per line. :param value_dict: Dictionary (parameters tuple -> value) containing the values to be ploted. :type value_dict: dict(tuple -> int) :param ordered_param_range_dict: Ordered dictionary (parameter name -> range of the parameter). :type ordered_param_range_dict: Shared.OrderedDict(str -> range) :param path: Path to the plot file without suffix. :type path: path :param x_plots: Number of plots on the x-axis (Default: 2) :type x_plots: int :param parameter_order: tuple(non-negative int), optional: Permutation of the parameter indices, to specify the order of the parameters (Default: None/given ordering). Only for plots. Example: (1, 2, 0) to plot the second parameter on the x-axis, the third on the y-axis and the first on the z-axis. :type parameter_order: list(int) """ path += '.png' if parameter_order in {(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)}: (x_idx, y_idx, z_idx) = parameter_order else: raise ValueError('invalid parameter order') inverse_order = tuple(Shared.Perm(list(parameter_order)).inverse()) (x_label, x_range) = ordered_param_range_dict.items()[x_idx] (y_label, y_range) = ordered_param_range_dict.items()[y_idx] (z_label, z_range) = ordered_param_range_dict.items()[z_idx] if len(list(x_range)) == 0 or len(list(y_range)) == 0 or len(list(z_range)) == 0: logging.warn('empty parameter range: nothing to plot') return x_min = min(x_range) x_max = max(x_range) x_size = (x_max + 1 - x_min) * Parameters.x_width y_min = min(y_range) y_max = max(y_range) y_size = (y_max + 1 - y_min) * Parameters.y_width z_min = min(z_range) z_max = max(z_range) z_size = z_max + 1 - z_min if z_size % x_plots: y_plots = int(round(float(z_size)/x_plots + 0.5)) else: y_plots = z_size / x_plots fig, axarr = plt.subplots( y_plots, x_plots, figsize=(x_plots*x_size, y_plots*y_size)) for z in z_range: ax = _get_ax(axarr, x_plots, y_plots, z, z_min) ax.set_xlabel(x_label) ax.set_ylabel(y_label) ax.set_title(str(z)+' '+z_label) ax.set_xlim(x_min, x_max) ax.set_ylim(y_min, y_max) for coordinates in itertools.product(x_range, y_range, z_range): old_coordinates = tuple(coordinates[i] for i in inverse_order) v = value_dict.get(old_coordinates) if v is not None: if v == '*': v = Parameters.zero_v_symbol elif v == 0: v = Parameters.zero_symbol (x, y, z) = coordinates _get_ax(axarr, x_plots, y_plots, z, z_min).text( x, y, str(v), va='center', ha='center') x_ticks_grid = np.arange(x_min - 0.5, x_max + 1, 1) y_ticks_grid = np.arange(y_min - 0.5, y_max + 1, 1) x_ticks = np.arange(x_min, x_max + 1, 1) y_ticks = np.arange(y_min, y_max + 1, 1) for z in z_range: ax = _get_ax(axarr, x_plots, y_plots, z, z_min) ax.set_xticks(x_ticks) ax.set_yticks(y_ticks) ax.set_xticks(x_ticks_grid, minor=True) ax.set_yticks(y_ticks_grid, minor=True) ax.grid(which='minor') plt.tight_layout() if z_size % x_plots: for z in range(z_max + 1, z_min + x_plots*y_plots): ax = _get_ax(axarr, x_plots, y_plots, z, z_min) fig.delaxes(ax) StoreLoad.generate_path(path) plt.savefig(path)