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)
def test_sympy__core__numbers__One(): from sympy.core.numbers import One assert _test_args(One())
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)
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
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))
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))
def sym_transform(self, xlabels): left = self.left.sym_transform(xlabels) right = self.right.sym_transform(xlabels) return Piecewise((One(), left >= right), (Zero(), True))
def sym_transform(self, xlabels): arg = self.arg.sym_transform(xlabels) return Piecewise((Zero(), Eq(arg, Zero())), (One(), True))