def test_connected_components(): assert connected_components(([], [])) == [] assert connected_components(([1, 2, 3], [])) == [[1], [2], [3]] V = [1, 2, 3] E = [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1)] assert connected_components((V, E)) == [[1, 2, 3]] V = [1, 2, 3, 4] E = [(1, 2), (2, 3), (3, 2), (3, 4)] assert connected_components((V, E)) == [[1, 2, 3, 4]] V = [1, 2, 3, 4] E = [(1, 2), (3, 4)] assert connected_components((V, E)) == [[1, 2], [3, 4]]
def _connected_components(M): """Returns the list of connected vertices of the graph when a square matrix is viewed as a weighted graph. Examples ======== >>> from sympy import symbols, Matrix >>> a, b, c, d, e, f, g, h = symbols('a:h') >>> A = Matrix([ ... [a, 0, b, 0], ... [0, e, 0, f], ... [c, 0, d, 0], ... [0, g, 0, h]]) >>> A.connected_components() [[0, 2], [1, 3]] Notes ===== Even if any symbolic elements of the matrix can be indeterminate to be zero mathematically, this only takes the account of the structural aspect of the matrix, so they will considered to be nonzero. """ if not M.is_square: raise NonSquareMatrixError V = range(M.rows) E = sorted(M.todok().keys()) return connected_components((V, E))
def _connected_components(M): """Returns the list of connected vertices of the graph when a square matrix is viewed as a weighted graph. Examples ======== >>> from sympy import Matrix >>> A = Matrix([ ... [66, 0, 0, 68, 0, 0, 0, 0, 67], ... [0, 55, 0, 0, 0, 0, 54, 53, 0], ... [0, 0, 0, 0, 1, 2, 0, 0, 0], ... [86, 0, 0, 88, 0, 0, 0, 0, 87], ... [0, 0, 10, 0, 11, 12, 0, 0, 0], ... [0, 0, 20, 0, 21, 22, 0, 0, 0], ... [0, 45, 0, 0, 0, 0, 44, 43, 0], ... [0, 35, 0, 0, 0, 0, 34, 33, 0], ... [76, 0, 0, 78, 0, 0, 0, 0, 77]]) >>> A.connected_components() [[0, 3, 8], [1, 6, 7], [2, 4, 5]] Notes ===== Even if any symbolic elements of the matrix can be indeterminate to be zero mathematically, this only takes the account of the structural aspect of the matrix, so they will considered to be nonzero. """ if not M.is_square: raise NonSquareMatrixError V = range(M.rows) E = sorted(M.todok().keys()) return connected_components((V, E))
def _solve_lin_sys(eqs_coeffs, eqs_rhs, ring): """Solve a linear system from dict of PolynomialRing coefficients Explanation =========== This is an **internal** function used by :func:`solve_lin_sys` after the equations have been preprocessed. The role of this function is to split the system into connected components and pass those to :func:`_solve_lin_sys_component`. Examples ======== Setup a system for $x-y=0$ and $x+y=2$ and solve: >>> from sympy import symbols, sring >>> from sympy.polys.solvers import _solve_lin_sys >>> x, y = symbols('x, y') >>> R, (xr, yr) = sring([x, y], [x, y]) >>> eqs = [{xr:R.one, yr:-R.one}, {xr:R.one, yr:R.one}] >>> eqs_rhs = [R.zero, -2*R.one] >>> _solve_lin_sys(eqs, eqs_rhs, R) {y: 1, x: 1} See also ======== solve_lin_sys: This function is used internally by :func:`solve_lin_sys`. """ V = ring.gens E = [] for eq_coeffs in eqs_coeffs: syms = list(eq_coeffs) E.extend(zip(syms[:-1], syms[1:])) G = V, E components = connected_components(G) sym2comp = {} for n, component in enumerate(components): for sym in component: sym2comp[sym] = n subsystems = [([], []) for _ in range(len(components))] for eq_coeff, eq_rhs in zip(eqs_coeffs, eqs_rhs): sym = next(iter(eq_coeff), None) sub_coeff, sub_rhs = subsystems[sym2comp[sym]] sub_coeff.append(eq_coeff) sub_rhs.append(eq_rhs) sol = {} for subsystem in subsystems: subsol = _solve_lin_sys_component(subsystem[0], subsystem[1], ring) if subsol is None: return None sol.update(subsol) return sol
def _component_division(eqs, funcs, t): from sympy.utilities.iterables import connected_components, strongly_connected_components # Assuming that each eq in eqs is in canonical form, # that is, [f(x).diff(x) = .., g(x).diff(x) = .., etc] # and that the system passed is in its first order eqsmap, eqsorig = _eqs2dict(eqs, funcs) subsystems = [] for cc in connected_components(_dict2graph(eqsmap)): eqsmap_c = {f: eqsmap[f] for f in cc} sccs = strongly_connected_components(_dict2graph(eqsmap_c)) subsystem = [[eqsorig[f] for f in scc] for scc in sccs] subsystem = _combine_type1_subsystems(subsystem, sccs, t) subsystems.append(subsystem) return subsystems