def test_set_attributes(self): pos_cfs = CyclicFeedbackSystem(*self.positive_toggle()) assert (pos_cfs.cfs_sign == 1) assert (pos_cfs.rho == [1, 0]) assert (pos_cfs.rho_inv == [1, 0]) assert (pos_cfs.edge_sign == [1, 1]) neg_cfs = CyclicFeedbackSystem(*self.negative_toggle()) assert (neg_cfs.cfs_sign == -1) assert (neg_cfs.rho == [1, 0]) assert (neg_cfs.rho_inv == [1, 0]) assert (neg_cfs.edge_sign == [1, -1]) three_node_cfs = CyclicFeedbackSystem(*self.three_node_network()) assert (three_node_cfs.cfs_sign == -1) assert (three_node_cfs.rho == [1, 2, 0]) assert (three_node_cfs.rho_inv == [2, 0, 1]) assert (three_node_cfs.edge_sign == [1, 1, -1]) try: not_cfs = CyclicFeedbackSystem(*self.toggle_plus()) except ValueError: assert (True) else: assert (False)
def test_pos_bifurcations(self): N, L, Delta, theta, gamma = self.neg_edge_toggle() cfs = CyclicFeedbackSystem(N, L, Delta, theta, gamma) s = sympy.symbols('s') eps_func = sympy.Matrix([[0, 1], [1, 0]]) * s x_eq = cfs.singular_equilibrium(eps_func, lambdify=False) zero_crossings = cfs.j_border_crossings(0, x_eq, eps_func) assert (len(zero_crossings) == 1) for crossing in zero_crossings: assert (np.allclose(crossing[0], .3162, rtol=1e-4)) assert (np.allclose(cfs(crossing[1], np.array([[0, .3162], [.3162, 0]])), np.zeros([2, 1]), atol=1e-4)) crossings, eps_func_out = cfs.border_crossings(eps_func) assert (eps_func_out == eps_func) assert (crossings[0][0][0] == zero_crossings[0][0]) assert (len(crossings[1]) == 1) for crossing in crossings[1]: assert (np.allclose(crossing[0], .67202)) assert (np.allclose(cfs(crossing[1], np.array([[0, .67202], [.67202, 0]])), np.zeros([2, 1]), atol=1e-4)) #get_bifurcations bifurcations = cfs.get_bifurcations(eps_func)[0] assert (not cfs.in_singular_domain( x_eq.subs(s, .37202), np.array([[0, .37202], [.37202, 0]]), 1)) assert (len(bifurcations[0]) == 1) for s_val in bifurcations[0]: assert (np.allclose(s_val[0], .3162, rtol=1e-4)) #make sure border_crossings runs on three nodes cfs = CyclicFeedbackSystem(*self.three_node_network()) crossings, eps_func = cfs.border_crossings() assert (True)
def test_in_singular_domain(self): pos_cfs = CyclicFeedbackSystem(*self.positive_toggle()) eps = np.array([[0, .5], [.5, 0]]) x = np.array([.5, .5]) assert (not pos_cfs.in_singular_domain(x, eps)) assert (not pos_cfs.in_singular_domain(x, eps, 0)) x = np.array([1.5, 1.5]) assert (pos_cfs.in_singular_domain(x, eps)) assert (pos_cfs.in_singular_domain(x, eps, 1)) x = np.array([.5, 1.5]) assert (not pos_cfs.in_singular_domain(x, eps)) assert (pos_cfs.in_singular_domain(x, eps, 0)) assert (not pos_cfs.in_singular_domain(x, eps, 1))
def test_singular_equilibrium(self): N, L, Delta, theta, gamma = self.positive_toggle() pos_cfs = CyclicFeedbackSystem(N, L, Delta, theta, gamma) x = pos_cfs.singular_equilibrium() assert (np.allclose(x(.1), np.array([[1.5], [1.5]]))) N, L, Delta, theta, gamma = self.neg_edge_toggle() pos_cfs = CyclicFeedbackSystem(N, L, Delta, theta, gamma) U1 = Delta[0, 1] + L[0, 1] U2 = Delta[1, 0] + L[1, 0] theta1 = theta[0, 1] theta2 = theta[1, 0] Delta1 = Delta[0, 1] Delta2 = Delta[1, 0] s = sympy.symbols('r') eps_func = sympy.Matrix([[0, 1], [1, 0]]) * s s_val = .1 eps1 = s_val eps2 = s_val m1 = Delta1 / (2 * eps1) m2 = Delta2 / (2 * eps2) #solution for gamma1 = gamma2 = 1 x1 = (U1 + (theta1 - eps1 - U2) * m1 - (theta2 - eps2) * m1 * m2) / (1 - m1 * m2) x2 = (U2 + (theta2 - eps2 - U1) * m2 - (theta1 - eps1) * m1 * m2) / (1 - m1 * m2) expected = np.array([[x1], [x2]]) x = pos_cfs.singular_equilibrium(eps_func) assert (np.allclose(x(s_val), expected))
def test_get_saddles(): ## test on two independent toggle switches N, L, Delta, theta, gamma = two_independent_toggles() RS = RampSystem(N, L, Delta, theta, gamma) # loop characteristic cell with only first loop LCC = Cell(RS.theta, 1, 0, (3, np.inf), (-np.inf, 2)) saddles = get_saddles(RS, LCC) CFS = CyclicFeedbackSystem(*neg_edge_toggle()) CFS_saddles, eps_func = CFS.get_bifurcations() s = sympy.symbols('s') expected_saddle_val = np.zeros([4, 1]) CFS_saddle_val = CFS_saddles[0][0][1] expected_saddle_val = np.array([[CFS_saddle_val[0, 0]], [CFS_saddle_val[1, 0]], [L[3, 2] + Delta[3, 2]], [L[2, 3]]]) for saddle in saddles[(0, 1)]: eps = saddle[2].subs(s, saddle[0]) assert (np.allclose(RS(saddle[1][0], eps), np.zeros([4, 1]))) assert (np.array_equal(saddle[1][0], expected_saddle_val)) # LCC with both loops LCC = Cell(RS.theta, 1, 0, 3, 2) saddles = get_saddles(RS, LCC) assert (len(saddles[(0, 1)]) == 3) assert (len(saddles[(2, 3)]) == 3) ## test that throwing out bifurcations that occur past weak equivalence are thrown out N, L, Delta, theta, gamma = almost_two_independent_toggles() RS = RampSystem(N, L, Delta, theta, gamma) LCC = Cell(RS.theta, 1, 0, (3, np.inf), (-np.inf, 2)) saddles = get_saddles(RS, LCC) assert (len(saddles[(0, 1)]) == 0) theta[2, 0] = .3 Delta[2, 0] = .5 theta[3, 2] = 1.1 RS = RampSystem(N, L, Delta, theta, gamma) LCC.theta = RS.theta saddles = get_saddles(RS, LCC) assert (len(saddles[(0, 1)]) == 1)
def get_CFS_from_cycle(RS, cycle, LCC): """ Creates a CyclicFeedbackSystem object which corresponds to cycle at the loop characteristic cell defined by rho :param RS: RampSystem object :param cycle: tuple defining a cycle. The cycle is defined by cycle[0]->cycle[1] ->...->cycle[n]->cycle[0] :param LCC: Loop characteristic cell represeneted as a Cell object. :return: CyclicFeedbackSystem object, CFS. CFS.Network node j corresponds to RS.Network node cycle[j]. """ CFS_network = make_cycle_subnetwork(RS.Network, cycle) CFS_theta = get_cycle_thresholds(RS, cycle) CFS_L, CFS_Delta = get_cycle_L_and_Delta(RS, cycle, LCC) CFS_gamma = get_cycle_gamma(RS, cycle) return CyclicFeedbackSystem(CFS_network, CFS_L, CFS_Delta, CFS_theta, CFS_gamma)
def test_neg_bifurcations(self): N, L, Delta, theta, gamma = self.negative_toggle() L[0, 1] = .95 Delta[0, 1] = 1 theta[0, 1] = 1.3 L[1, 0] = .5 Delta[1, 0] = 1 theta[1, 0] = 1 gamma = [1, 1] cfs = CyclicFeedbackSystem(N, L, Delta, theta, gamma) bifurcations = cfs.neg_loop_bifurcations() for j in range(3): assert (len(bifurcations[j]) == 0) three_node = CyclicFeedbackSystem(*self.three_node_network()) bifurcations, eps_func_out = three_node.neg_loop_bifurcations() for j in range(3): assert (len(bifurcations[j]) == 0) assert (len(bifurcations[3]) == 1) for bif in bifurcations[3]: assert (np.allclose(bif[0], .25, rtol=1e-4)) assert (np.allclose(np.array([[1], [1], [1]]), bif[1], rtol=1e-4))
def test_decompose(): RS = RampSystem(*toggle_plus_parameters()) ## test getting parameters cycle = (0, 1) cycle_theta = get_cycle_thresholds(RS, cycle) assert (np.array_equal( cycle_theta, np.array([[0, RS.theta[0, 1]], [RS.theta[1, 0], 0]]))) LCC = Cell(RS.theta, 1, 0) cycle_L, cycle_Delta = get_cycle_L_and_Delta(RS, cycle, LCC) L01 = (RS.L[0, 0] + RS.Delta[0, 0]) * RS.L[0, 1] Delta01 = (RS.L[0, 0] + RS.Delta[0, 0]) * (RS.L[0, 1] + RS.Delta[0, 1]) - L01 L10 = RS.L[1, 0] * (RS.L[1, 1] + RS.Delta[1, 1]) Delta10 = (RS.L[1, 0] + RS.Delta[1, 0]) * (RS.L[1, 1] + RS.Delta[1, 1]) - L10 assert (np.array_equal(cycle_L, np.array([[0, L01], [L10, 0]]))) assert (np.array_equal(cycle_Delta, np.array([[0, Delta01], [Delta10, 0]]))) ## test decompose CFS_list = decompose(RS, LCC) assert (len(CFS_list) == 1) CFS = CFS_list[0][0] cycle_out = CFS_list[0][1] cycle_net = DSGRN.Network('X0 : X1 \n X1 : X0') assert (cycle_out == cycle) assert (CFS == CyclicFeedbackSystem(cycle_net, cycle_L, cycle_Delta, cycle_theta, RS.gamma)) ## test getting parameters cycle = (0, ) cycle_theta = get_cycle_thresholds(RS, cycle) assert (np.array_equal(cycle_theta, np.array([[RS.theta[0, 0]]]))) LCC = Cell(RS.theta, 0, (0, np.inf)) cycle_L, cycle_Delta = get_cycle_L_and_Delta(RS, cycle, LCC) L00 = RS.L[0, 0] * RS.L[0, 1] Delta00 = (RS.L[0, 0] + RS.Delta[0, 0]) * RS.L[0, 1] - L00 assert (cycle_L == L00) assert (np.array_equal(cycle_Delta, np.array([[Delta00]]))) ## test decompose CFS_list = decompose(RS, LCC) assert (len(CFS_list) == 1) CFS = CFS_list[0][0] cycle_out = CFS_list[0][1] cycle_net = DSGRN.Network('X0 : X0') assert (cycle_out == cycle) assert (CFS == CyclicFeedbackSystem(cycle_net, cycle_L, cycle_Delta, cycle_theta, RS.gamma[0, 0])) ## test decompose LCC = Cell(RS.theta, 0, 1) CFS_list = decompose(RS, LCC) assert (len(CFS_list) == 2) cycle_list = [CFS_list[0][1], CFS_list[1][1]] assert ((0, ) in cycle_list and (1, ) in cycle_list) ## decompose two independent toggles RS = RampSystem(*two_independent_toggles()) LCC = Cell(RS.theta, 1, 0, (3, np.inf), (-np.inf, 2)) CFS_list = decompose(RS, LCC) assert (len(CFS_list) == 1) assert (CFS_list[0][1] == (0, 1)) CFS = CyclicFeedbackSystem(*neg_edge_toggle()) assert (CFS_list[0][0] == CFS)
def test_cyclic_feedback_system_map(self): N, L, Delta, theta, gamma = self.neg_edge_toggle() L[0, 1] = .5 Delta[0, 1] = 1 theta[0, 1] = 1.3 L[1, 0] = .5 Delta[1, 0] = 1 theta[1, 0] = 1 gamma = [1, 1] the_map = RampToHillSaddleMap(N) CFS = CyclicFeedbackSystem(N, L, Delta, theta, gamma) #bifurcations = CFS.get_bifurcations(eps_func)[0] bifurcations, eps_func = CFS.get_bifurcations() assert (len(bifurcations[0]) == 1) for bifurcation in bifurcations[0]: hill_sys_parameter, x_hill = the_map.cyclic_feedback_system_map( CFS, bifurcation, eps_func, 0) assert (np.array_equal(CFS.Delta, hill_sys_parameter.Delta)) assert (np.array_equal(CFS.theta, hill_sys_parameter.theta)) assert (np.array_equal(hill_sys_parameter.sign, np.array([[0, -1], [-1, 0]]))) assert (np.allclose(hill_sys_parameter.L[0, 1], .6560, rtol=1e-2)) assert (np.allclose(hill_sys_parameter.L[1, 0], .5981, rtol=1e-2)) assert (np.allclose(hill_sys_parameter.n[0, 1], 12.1399, rtol=1e-2)) assert (np.allclose(hill_sys_parameter.n[1, 0], 10.2267, rtol=1e-2)) assert (np.allclose(x_hill, np.array([[.7958], [1.5098]]), rtol=1e-2)) hill_saddles = the_map.map_all_saddles(CFS, eps_func) assert (len(hill_saddles) == 1) assert (hill_saddles[0][0] == hill_sys_parameter) assert (hill_sys_parameter != HillSystemParameter( N, [[0, 1], [1, 0]], L, Delta, theta, [[0, 1], [1, 0]], gamma)) assert (np.array_equal(hill_saddles[0][1], x_hill)) gamma = [1.1, 0.9] CFS = CyclicFeedbackSystem(N, L, Delta, theta, gamma) crossings = CFS.border_crossings(eps_func)[0] bifurcations = CFS.get_bifurcations(eps_func)[0] assert (len(bifurcations[0]) == 1) assert (np.allclose(bifurcations[0][0][0], .45622, rtol=1e-4)) assert (np.allclose(bifurcations[0][0][1], np.array([[.54377], [1.66667]]), rtol=1e-4)) hill_sys_parameter, x_hill = the_map.cyclic_feedback_system_map( CFS, bifurcations[0][0], eps_func, 0) assert (np.allclose(hill_sys_parameter.L[0, 1], .77468, rtol=1e-4)) assert (np.allclose(hill_sys_parameter.L[1, 0], .5922, rtol=1e-4)) assert (np.allclose(x_hill, np.array([[.82535], [1.58024]]))) #three node map N, L, Delta, theta, gamma = self.three_node_network() CFS = CyclicFeedbackSystem(N, L, Delta, theta, gamma) saddles, eps_func = CFS.get_bifurcations() assert (len(saddles[0]) == 0) assert (len(saddles[1]) == 1) assert (len(saddles[2]) == 0) assert (len(saddles[3]) == 0) saddle = saddles[1][0] s_val = saddle[0] x = saddle[1] assert (np.allclose(s_val, .292402, rtol=1e-2)) assert (np.allclose(x, np.array([[1.171], [1.292402], [1.5]]), rtol=1e-3)) the_map = RampToHillSaddleMap(N) hill_saddles = the_map.map_all_saddles(CFS) assert (len(hill_saddles) == 1) hill_sys = hill_saddles[0][0] x_hill = hill_saddles[0][1] assert (hill_sys.is_saddle(x_hill))
def test_equilibria(self): N, L, Delta, theta, gamma = self.neg_edge_toggle() CFS = CyclicFeedbackSystem(N, L, Delta, theta, gamma) eq_cells = CFS.switch_equilibrium_cells() assert (len(eq_cells) == 3) expected_cells = [ Cell(CFS.theta, (-np.inf, 1), (0, np.inf)), Cell(CFS.theta, 1, 0), Cell(CFS.theta, (1, np.inf), (-np.inf, 0)) ] for kappa in eq_cells: assert (kappa in expected_cells) eq_list = CFS.equilibria() assert (len(eq_list) == 3) U = L + Delta stable_eq = [ np.array([[L[0, 1]], [U[1, 0]]]), np.array([[U[0, 1]], [L[1, 0]]]) ] unstable_eq = np.array([[theta[1, 0]], [theta[0, 1]]]) for eq, stable in eq_list: if not stable: assert (np.array_equal(eq, unstable_eq)) else: assert (any( np.array_equal(eq, expected) for expected in stable_eq)) ## test with inessential nodes theta[1, 0] = 2 CFS = CyclicFeedbackSystem(N, L, Delta, theta, gamma) eq_cells = CFS.switch_equilibrium_cells() assert (len(eq_cells) == 1) expected_cell = Cell(CFS.theta, (-np.inf, 1), (0, np.inf)) assert (eq_cells[0] == expected_cell) eq_list = CFS.equilibria() expected = np.array([[L[0, 1]], [U[1, 0]]]) assert (len(eq_list) == 1) assert (np.array_equal(eq_list[0][0], expected)) assert (eq_list[0][1] == True) ## test with negative CFS N, L, Delta, theta, gamma = self.negative_toggle() CFS = CyclicFeedbackSystem(N, L, Delta, theta, gamma) eq_cells = CFS.switch_equilibrium_cells() assert (len(eq_cells) == 1) expected_cell = Cell(CFS.theta, 1, 0) assert (eq_cells[0] == expected_cell) eq_list = CFS.equilibria() assert (len(eq_list) == 1) assert (np.array_equal(eq_list[0][0], np.array([[1.5], [1.5]]))) assert (eq_list[0][1] == True) ## test with 3 node network N, L, Delta, theta, gamma = self.pos_three_node_network() CFS = CyclicFeedbackSystem(N, L, Delta, theta, gamma) eq_cells = CFS.switch_equilibrium_cells() assert (len(eq_cells) == 3) expected_cells = [ Cell(CFS.theta, (2, np.inf), (-np.inf, 0), (-np.inf, 1)), Cell(CFS.theta, 2, 0, 1), Cell(CFS.theta, (-np.inf, 2), (0, np.inf), (1, np.inf)) ] for kappa in eq_cells: assert (kappa in expected_cells) eps = np.array([[0, .1, 0], [0, 0, .1], [.1, 0, 0]]) eq_list = CFS.equilibria(eps) assert (len(eq_list) == 3) for eq, stable in eq_list: assert (np.allclose(CFS(eq, eps), np.zeros([3, 1]))) if CFS.in_singular_domain(eq, eps): assert (stable == False) else: assert (stable == True)