Esempio n. 1
0
def test_core_numbers():
    for c in (Catalan, Catalan(), ComplexInfinity, ComplexInfinity(),
              EulerGamma, EulerGamma(), Exp1, Exp1(), GoldenRatio, GoldenRatio(),
              Half, Half(), ImaginaryUnit, ImaginaryUnit(), Infinity, Infinity(),
              Integer, Integer(2), NaN, NaN(), NegativeInfinity,
              NegativeInfinity(), NegativeOne, NegativeOne(), Number, Number(15),
              NumberSymbol, NumberSymbol(), One, One(), Pi, Pi(), Rational,
              Rational(1,2), Real, Real("1.2"), Zero, Zero()):
        check(c)
Esempio n. 2
0
def test_sympy__core__numbers__One():
    from sympy.core.numbers import One
    assert _test_args(One())
Esempio n. 3
0
def _to_bloch_coeff(key, momenta):
    """Transform sympy expression to BlochCoeff if possible."""
    def is_hopping_expo(expo):
        # Check whether a sympy exponential represents a hopping.
        base, exponent = expo.as_base_exp()
        if base == e and any(
            [momentum in exponent.atoms() for momentum in momenta]):
            return True
        else:
            return False

    # We combine exponentials with the same base and exponent.
    key = sympy.powsimp(key, combine='exp')
    # Expand multiplication of brackets into sums.
    key = sympy.expand(key,
                       power_base=False,
                       power_exp=False,
                       mul=True,
                       log=False,
                       multinomial=False)
    if isinstance(key, sympy.Add):
        raise ValueError("Key cannot be a sum of terms.")
    # Key is a single exponential.
    if isinstance(key, sympy.Pow):
        base, exp = key.as_base_exp()
        # If the exponential is a hopping, store it
        # with coefficient 1.
        if is_hopping_expo(key):
            hop_expo = key
            coeff = One()
        # If it is not a hopping, it belongs to the coeff.
        else:
            hop, coeff, hop_expo = np.zeros((len(momenta, ))), key, None
    # Key is the product of an exponential and some extra stuff.
    elif sympy.Pow in [type(arg) for arg in key.args]:
        # Check that a natural exponential is present, which also
        # includes momenta in its arguments.
        # First find all exponentials.
        find_expos = [ele for ele in key.args if ele.is_Pow]
        # Then pick out exponentials that are hoppings.
        hop_expos = [expo for expo in find_expos if is_hopping_expo(expo)]
        # We should find at most one exponential that represents a
        # hopping, because all exponentials with the same base have been
        # combined.
        if len(hop_expos) == 1:
            hop_expo = hop_expos[0]
            coeff = sympy.simplify(key / hop_expo)
        # If none of the exponentials match the hopping structure, the
        # exponentials that are present are parts of the coefficient,
        # so this is an onsite term.
        elif not len(hop_expos):
            hop, coeff, hop_expo = np.zeros((len(momenta, ))), key, None
        # Should never be called.
        else:
            raise ValueError("Unable to read the hoppings in "
                             "conversion to BlochCoeff.")
    # If the key contains no exponentials, then it is not a hopping.
    else:
        hop, coeff, hop_expo = np.zeros((len(momenta, ))), key, None
    # Extract hopping vector from exponential
    # If the exponential contains more arguments than the hopping,
    # append it to coeff.
    if hop_expo is not None:
        base, exponent = hop_expo.as_base_exp()
        if base != e or type(exponent) not in (sympy.Mul, sympy.Add):
            raise ValueError('Incorrect format of exponential.')
        # Pick out the real space part, remove the complex i,
        # expand any brackets if present.
        arg = exponent.expand()
        # Check that the momenta all have i as a prefactor
        momenta_present = [
            momentum for momentum in momenta if momentum in arg.atoms()
        ]
        if not all([
                sympy.I in (arg.coeff(momentum)).atoms()
                for momentum in momenta_present
        ]):
            raise ValueError(
                "Momenta in hopping exponentials should have a complex prefactor."
            )
        hop = [
            sympy.expand(arg.coeff(momentum) / sympy.I) for momentum in momenta
        ]
        # We do not allow sympy symbols in the hopping, should
        # be numerical values only.
        if any([
                isinstance(item, sympy.Symbol) for ele in hop
                for item in ele.atoms() if isinstance(ele, sympy.Expr)
        ]):
            raise ValueError(
                "Real space part of the hopping must be numbers, not symbols.")
        # If the exponential contains something extra other than the
        # hopping part, we append it to the coefficient.
        spatial_arg = sympy.I * sum(
            [ele * momentum for ele, momentum in zip(momenta, hop)])
        diff = sympy.nsimplify(sympy.expand(arg - spatial_arg))
        coeff = sympy.simplify(coeff * e**diff)
        hop = np.array(hop).astype(float)
    # Make sure there is no momentum dependence in the coefficient.
    if any([momentum in coeff.atoms() for momentum in momenta]):
        raise ValueError(
            "All momentum dependence should be confined to hopping exponentials."
        )
    return BlochCoeff(hop, coeff)
Esempio n. 4
0
def calc(n, start, end, E, generate_dot=False):
    """Calculate the resistance of a network.
    A node represent a crossroads of electric lines,
    each segment has a resistance

    Parameters:
    n     (int): the number of nodes in the network, which are
        labelled from 1 to n.
    start (int): the node with input current.
    end   (int): the node with output current.
    E (list[(u, v, r)]): network data. (u, v, r) represent
        a segment between u and v with a resistance of r.

    Flags:
    generate_dot (bool, False): If set to True, this function will return
        the result in dot script for analysis.

    Return values:
    (sympy.core.numbers.Rational / str)
    the resistance of the network represented in rational.
    When `generate_dot` is set, return str instead.
    """

    start, end = start - 1, end - 1

    # Set up a graph, whose edges are bidirectional.
    # Each pair of directed edge has different coefficients (1 and -1).
    G = [[] for i in range(n)]
    for i in range(len(E)):
        u, v, r = E[i]
        u, v = u - 1, v - 1
        s = sym('I' + str(i))
        G[u].append((v, 1, r, s))
        G[v].append((u, -1, r, s))

    # Set up equations.
    A = []
    for v in range(n - 1):
        if v == start:
            eq = One()
        elif v == end:
            eq = -One()
        else:
            eq = Zero()

        for u, f, r, s in G[v]:
            eq -= f * s

        A.append(eq)

    father, depth = [None] * n, [0] * n

    def dfs(A, G, father, tm, x):
        for v, f, r, s in G[x]:
            if s == father[x][3]:
                continue
            if depth[v] and depth[v] < depth[x]:
                eq, u = f * r * s, x
                while u != v:
                    u, f1, r1, s1 = father[u]
                    eq += f1 * r1 * s1
                A.append(eq)
            elif not depth[v]:
                father[v] = (x, f, r, s)
                depth[v] = depth[x] + 1
                dfs(A, G, father, depth, v)

    # Solve it.
    father[start], depth[start] = (0, ) * 4, 1
    dfs(A, G, father, depth, start)
    sol = solve(A)

    # Calculate the resistance.
    ret, x = 0, end
    while x != start:
        x, f, r, s = father[x]
        ret += f * r * sol[s]

    if generate_dot:
        buf = ['digraph {', '    rankdir = "LR";']

        buf.append('    r [shape = rectangle, label = "%sΩ"];' % ret)
        for i in range(1, n + 1):
            if i == start + 1:
                c = 'green'
            elif i == end + 1:
                c = 'red'
            else:
                c = 'blue'

            buf.append('    %s [shape = point, color = %s];' % (i, c))

        for u in range(1, n + 1):
            for v, f, r, s in G[u - 1]:
                if f < 0:
                    continue

                I, v = sol[s], v + 1
                if I < 0:
                    e = '%s -> %s [' % (v, u)
                elif I > 0:
                    e = '%s -> %s [' % (u, v)
                else:
                    e = '%s -> %s [arrowhead = none, ' % (u, v)

                buf.append('    %slabel = "%sA,%sΩ"];' % (e, abs(I), r))

        buf += '}'
        return '\n'.join(buf)
    else:
        return ret
Esempio n. 5
0
 def sym_transform(self, xlabels):
     left = self.left.sym_transform(xlabels)
     right = self.right.sym_transform(xlabels)
     return Piecewise((right, Eq(Missing(left), One())), (left, True))
Esempio n. 6
0
 def sym_transform(self, xlabels):
     left = self.left.sym_transform(xlabels)
     right = self.right.sym_transform(xlabels)
     return Piecewise((NAN(1), Eq(right, One())), (left, True))
Esempio n. 7
0
 def sym_transform(self, xlabels):
     left = self.left.sym_transform(xlabels)
     right = self.right.sym_transform(xlabels)
     return Piecewise((One(), left >= right), (Zero(), True))
Esempio n. 8
0
 def sym_transform(self, xlabels):
     arg = self.arg.sym_transform(xlabels)
     return Piecewise((Zero(), Eq(arg, Zero())), (One(), True))