Source code for cereeberus.data.ex_mergetrees

import networkx as nx
import numpy as np
import warnings

from networkx.generators import random_labeled_tree

from cereeberus import MergeTree


[docs] def randomMergeTree(n=10, func_randomizer=None, range=[0, 10], seed=None): """ Generates a random tree with n nodes + 1 root. If `func_randomizer` is None, the function defined is inverted edge count distance from root node. Otherwise, func_randomizer should be an input to type the randomizeMergeFunction function. For example, this could be 'uniform' or 'exp'. """ warnings.filterwarnings("ignore") # Generate a random tree T = random_labeled_tree(n, seed=seed) np.random.seed(seed) root = np.random.randint(n) MT = MergeTree(T, root, seed=seed) if func_randomizer is not None: MT = randomizeMergeFunction(MT, type=func_randomizer, range=range, seed=seed) return MT
[docs] def randomizeMergeFunction(MT, range=[0, 10], type="exp", seed=None): """ Returns a merge tree with the same underlying tree, but randomized function values in the given range. """ np.random.seed(seed) f = {"v_inf": np.inf} for e in nx.edge_bfs(MT.to_undirected(), "v_inf"): u = e[0] v = e[1] bot_f = range[0] if u == "v_inf": top_f = range[1] else: top_f = f[u] # Here's the main thing. # We pull a random number that's lower than the upper # neighbor's funciton value. # Doing this with uniform repeatedly makes for a squashed merge tree. # The expoenential function is a bit better. if type == "uniform": f[v] = np.random.uniform(bot_f, top_f) elif type == "exp": f[v] = top_f - np.random.exponential(0.1 * (top_f - bot_f)) if f[v] < bot_f: f[v] = bot_f MT.f = f MT.set_pos_from_f() return MT