def orthogonalization_matrix(self, inverse=False): """orthogonalization matrix for crystal to cartesian coordinates not to be confused with the unit cell orthogonalization matrix, which is the transpose of this one Dunitz convention, Dunitz, 1979, p237""" a, b, c, al, be, ga = self.parameters al = radians(al) be = radians(be) ga = radians(ga) vol = self.volume if inverse: mat = ta.array([[ old_div(1, a), old_div((-1 * cos(ga)), (a * sin(ga))), old_div((cos(ga) * cos(al) - cos(be)), (a * vol * sin(ga))) ], [ 0, old_div(1, (b * sin(ga))), old_div((cos(ga) * cos(be) - cos(al)), (b * vol * sin(ga))) ], [0, 0, old_div((a * b * sin(ga)), (vol))]]) else: mat = ta.array( [[a, b * cos(ga), c * cos(be)], [0, b * sin(ga), c * (cos(al) - cos(be) * cos(ga)) / sin(ga)], [0, 0, old_div(vol, (a * b * sin(ga)))]]) return mat
def test_broadcasting(): for sa in [(), 1, (1, 1, 1, 1), 2, (3, 2), (4, 3, 2), (5, 4, 3, 2)]: for sb in [(), 1, (1, 1), (4, 1, 1), 2, (1, 2), (3, 1), (1, 3, 2)]: a = make(sa, int) b = make(sb, int) assert ta.array(a.tolist()) + ta.array(b.tolist()) == a + b assert ta.array(a) + ta.array(b) == a + b
def test_iteration(): for dtype in dtypes: raises(TypeError, tuple, ta.array(1, dtype)) for shape in [0, 1, 2, 3, (1, 0), (2, 2), (17, 17), (1, 1, 1), (2, 2, 1), (2, 0, 3)]: a = make(shape, dtype) assert tuple(ta.array(a)) == tuple(a)
def metric_tensor(self, inverse=False): """Returns the metric tensor http://reference.iucr.org/dictionary/Metric_tensor Dunitz, 1979, p227""" a, b, c, al, be, ga = self.parameters al = radians(al) be = radians(be) ga = radians(ga) vol = self.volume if inverse: m11 = (b * c * sin(al) / vol)**2 m22 = (c * a * sin(be) / vol)**2 m33 = (a * b * sin(ga) / vol)**2 m12 = a * b * (old_div(c, vol))**2 * (cos(al) * cos(be) - cos(ga)) m23 = b * c * (old_div(a, vol))**2 * (cos(be) * cos(ga) - cos(al)) m13 = a * c * (old_div(b, vol))**2 * (cos(ga) * cos(al) - cos(be)) mat = ta.array([[m11, m12, m13], [m12, m22, m23], [m13, m23, m33]]) else: mat = ta.array([[a * a, a * b * cos(ga), a * c * cos(be)], [a * b * cos(ga), b * b, b * c * cos(al)], [a * c * cos(be), b * c * cos(al), c * c]]) return mat
def __init__(self, prim_vecs, basis, name='', norbs=None): prim_vecs = ta.array(prim_vecs, float) _check_prim_vecs(prim_vecs) dim = prim_vecs.shape[1] if name is None: name = '' if isinstance(name, str): name = [name + str(i) for i in range(len(basis))] basis = ta.array(basis, float) if basis.ndim != 2: raise ValueError('`basis` must be a 2d array-like object.') if basis.shape[1] != dim: raise ValueError('Basis dimensionality does not match ' 'the space dimensionality.') try: norbs = list(norbs) if len(norbs) != len(basis): raise ValueError('Length of `norbs` is not the same as ' 'the number of basis vectors') except TypeError: norbs = [norbs] * len(basis) self.sublattices = [ Monatomic(prim_vecs, offset, sname, norb) for offset, sname, norb in zip(basis, name, norbs) ] # Sequence of primitive vectors of the lattice. self._prim_vecs = prim_vecs # Precalculation of auxiliary arrays for real space calculations. self.reduced_vecs, self.transf = lll.lll(prim_vecs) self.voronoi = ta.dot(lll.voronoi(self.reduced_vecs), self.transf)
def test_promotion(): for dtypea in dtypes: for dtypeb in dtypes: a = make(3, dtypea) b = make(3, dtypeb) assert_equal(ta.array(a.tolist()) + ta.array(b.tolist()), a + b) assert_equal(ta.array(a) + ta.array(b), a + b)
def test_broadcasting(): for sa in [(), 1, (1, 1, 1, 1), 2, (3, 2), (4, 3, 2), (5, 4, 3, 2)]: for sb in [(), 1, (1, 1), (4, 1, 1), 2, (1, 2), (3, 1), (1, 3, 2)]: a = make(sa, int) b = make(sb, int) assert_equal(ta.array(a.tolist()) + ta.array(b.tolist()), a + b) assert_equal(ta.array(a) + ta.array(b), a + b)
def angle_pos(atom_pos, bond_pos, bond_length, degrees, coplanar=None): if coplanar is not None and len(coplanar) > 0: # may have one or two coplanar positions specified, # if two, compute both resultant positions and average # (the up vector has to be negated for the second one) xforms = [] if len(coplanar) > 2: raise ValueError("More than 2 coplanar positions specified!") for cpos in coplanar: up = cpos - atom_pos if xforms: up = tinyarray.negative(up) # lookAt puts ref point opposite that of zAlign, so # also rotate 180 degrees around y axis xform = rotation( (0.0, 1.0, 0.0), 180.0) * look_at(atom_pos, bond_pos, up) xforms.append(xform) else: xforms = [z_align(atom_pos, bond_pos)] points = [] for xform in xforms: radians = pi * degrees / 180.0 angle = tinyarray.array( [0.0, bond_length * sin(radians), bond_length * cos(radians)]) points.append(xform.inverse() * angle) if len(points) > 1: midpoint = points[0] + (points[1] - points[0]) / 2.0 v = midpoint - atom_pos v = v * bond_length / norm(v) return atom_pos + v return tinyarray.array(points[0])
def __init__(self, prim_vecs, basis, name='', norbs=None): prim_vecs = ta.array(prim_vecs, float) if prim_vecs.ndim != 2: raise ValueError('`prim_vecs` must be a 2d array-like object.') dim = prim_vecs.shape[1] if name is None: name = '' if isinstance(name, str): name = [name + str(i) for i in range(len(basis))] if prim_vecs.shape[0] > dim: raise ValueError('Number of primitive vectors exceeds ' 'the space dimensionality.') basis = ta.array(basis, float) if basis.ndim != 2: raise ValueError('`basis` must be a 2d array-like object.') if basis.shape[1] != dim: raise ValueError('Basis dimensionality does not match ' 'the space dimensionality.') try: norbs = list(norbs) if len(norbs) != len(basis): raise ValueError('Length of `norbs` is not the same as ' 'the number of basis vectors') except TypeError: norbs = [norbs] * len(basis) self.sublattices = [Monatomic(prim_vecs, offset, sname, norb) for offset, sname, norb in zip(basis, name, norbs)] # Sequence of primitive vectors of the lattice. self._prim_vecs = prim_vecs # Precalculation of auxiliary arrays for real space calculations. self.reduced_vecs, self.transf = lll.lll(prim_vecs) self.voronoi = ta.dot(lll.voronoi(self.reduced_vecs), self.transf)
def test_promotion(): for dtypea in dtypes: for dtypeb in dtypes: a = make(3, dtypea) b = make(3, dtypeb) assert ta.array(a.tolist()) + ta.array(b.tolist()) == a + b assert ta.array(a) + ta.array(b) == a + b
def make_system(W, theta, kz): #make a 2D cut of the original system with fixed kz syst = kwant.Builder() lat = kwant.lattice.square(a=1, name='u', norbs=2) sigma_x = ta.array([[0, 1], [1, 0]]) sigma_y = ta.array([[0, -1j], [1j, 0]]) sigma_z = ta.array([[1, 0], [0, -1]]) x, y = W, W M = 0.7 #same parameter as before k0 = 1 for i in range(x): for j in range(y): syst[lat(i, j)] = M * (k0**2 - 4 - kz**2) * sigma_z + ( -sin(theta) / sqrt(2) * sin(kz) - 1j * sin(theta) / sqrt(2) * sin(kz)) * sigma_x if i > 0: syst[lat(i, j), lat(i - 1, j)] = 1j / 2 * (cos( theta / 2)**2) * sigma_x + 1j / 2 * (sin( theta / 2)**2) * sigma_y + M * sigma_z if j > 0: syst[lat(i, j), lat(i, j - 1)] = 1j / 2 * (cos( theta / 2)**2) * sigma_y + 1j / 2 * (sin( theta / 2)**2) * sigma_x + M * sigma_z syst1 = syst.finalized() return syst1
def __init__(self, dim=1): self.__dim = dim self.__s = [ ta.array([[1, 0], [0, 1]]), ta.array([[0, 1], [1, 0]]), ta.array([[0, -1j], [1j, 0]]), ta.array([[1, 0], [0, -1]]) ]
def test_unary_operators(): ops = operator for op in [ops.neg, ops.pos, ops.abs]: for dtype in dtypes: for shape in [(), 1, 3, (3, 2)]: a = make(shape, dtype) assert_equal(op(ta.array(a.tolist())), op(a)) assert_equal(op(ta.array(a)), op(a))
def test_unary_operators(): ops = operator for op in [ops.neg, ops.pos, ops.abs]: for dtype in dtypes: for shape in [(), 1, 3, (3, 2)]: a = make(shape, dtype) assert op(ta.array(a.tolist())) == op(a) assert op(ta.array(a)) == op(a)
def _inv_int(A): """Invert an integer square matrix A. """ _A = ta.array(A, int) if A == np.empty((0, 0)): return A if _A != A or abs(la.det(A)) != 1: raise ValueError('Input needs to be an invertible integer matrix') return ta.array(np.round(la.inv(_A)), int)
def _inv(R): if isinstance(R, ta.ndarray_int): Rinv = ta.array(_inv_int(R), int) elif isinstance(R, ta.ndarray_float): Rinv = ta.array(la.inv(R)) elif is_sympy_matrix(R): Rinv = R**(-1) else: raise ValueError('Invalid rotation matrix.') return Rinv
def test_comparison(): ops = operator for op in [ops.ge, ops.gt, ops.le, ops.lt, ops.eq, ops.ne]: for dtype in (int, float, complex): for left, right in it.product((np.zeros, np.ones), repeat=2): for shape in [(), (1,), (2,), (2, 2), (2, 2, 2), (2, 3)]: a = left(shape, dtype) b = right(shape, dtype) if dtype is complex and op not in [ops.eq, ops.ne]: # unorderable types raises(TypeError, op, ta.array(a), ta.array(b)) else: # passing the same object same = ta.array(a) assert op(same, same) == op(a.tolist(), a.tolist()) # passing different objects, but equal assert (op(ta.array(a), ta.array(a)) == op(a.tolist(), a.tolist())) # passing different objects, not equal assert (op(ta.array(a), ta.array(b)) == op(a.tolist(), b.tolist())) # test different ndims and different shapes for shp1, shp2 in [((2,), (2, 2)), ((2, 2), (2, 3))]: a = left(shp1, dtype) b = right(shp2, dtype) if op not in (ops.eq, ops.ne): # unorderable types raises(TypeError, op, ta.array(a), ta.array(b))
def test_value_types(k=(-1.1, 0.5), E=2, t=1): sym_extents = [1, 2, 3] lattices = [kwant.lattice.honeycomb(), kwant.lattice.square()] lat_syms = [(lat, kwant.TranslationalSymmetry(lat.vec((n, 0)), lat.vec((0, n)))) for n, lat in itertools.product(sym_extents, lattices)] for lat, sym in lat_syms: syst = wraparound(_simple_syst(lat, E, t, sym)).finalized() H = syst.hamiltonian_submatrix(k, sparse=False) for E1, t1 in [(float(E), float(t)), (np.array([[E]], float), np.array([[t]], float)), (ta.array([[E]], float), ta.array([[t]], float))]: # test when Hamiltonian values do not take any extra parameters # (only 'k' needs to be passed) for E2 in [E1, lambda a: E1]: for t2 in [t1, lambda a, b: t1]: syst = wraparound(_simple_syst(lat, E2, t2, sym)).finalized() H_alt = syst.hamiltonian_submatrix(k, sparse=False) np.testing.assert_equal(H_alt, H) # test when Hamiltonian value functions take extra parameters and # have compatible signatures (can be passed with 'args') onsites = [ lambda a, E, t: E, lambda a, E, *args: E, lambda a, *args: args[0], ] hoppings = [ lambda a, b, E, t: t, lambda a, b, E, *args: args[0], lambda a, b, *args: args[1], ] args = (E1, t1) + k for E2, t2 in itertools.product(onsites, hoppings): syst = wraparound(_simple_syst(lat, E2, t2, sym)).finalized() H_alt = syst.hamiltonian_submatrix(args, sparse=False) np.testing.assert_equal(H_alt, H) # test when hamiltonian value functions take extra parameters and # have incompatible signaures (must be passed with 'params') onsites = [ lambda a, E: E, lambda a, **kwargs: kwargs['E'], lambda a, *, E: E, ] hoppings = [ lambda a, b, t: t, lambda a, b, **kwargs: kwargs['t'], lambda a, b, *, t: t, ] params = dict(E=E1, t=t1, **dict(zip(['k_x', 'k_y'], k))) for E2, t2 in itertools.product(onsites, hoppings): syst = wraparound(_simple_syst(lat, E2, t2, sym)).finalized() H_alt = syst.hamiltonian_submatrix(params=params, sparse=False) np.testing.assert_equal(H_alt, H)
def _eq(R1, R2): if type(R1) != type(R2): R1 = ta.array(np.array(R1).astype(float), float) R2 = ta.array(np.array(R2).astype(float), float) if isinstance(R1, ta.ndarray_float): # Check equality with allclose if floating point R_eq = allclose(R1, R2) else: # If exact use exact equality R_eq = (R1 == R2) return R_eq
def test_value_types(k=(-1.1, 0.5), E=0, t=1): for lat in [kwant.lattice.honeycomb(), kwant.lattice.square()]: syst = wraparound(_simple_syst(lat, E, t)).finalized() H = syst.hamiltonian_submatrix(k, sparse=False) for E1, t1 in [(float(E), float(t)), (np.array([[E]], float), np.array([[1]], float)), (ta.array([[E]], float), ta.array([[1]], float))]: for E2 in [E1, lambda a: E1]: for t2 in [t1, lambda a, b: t1]: syst = wraparound(_simple_syst(lat, E2, t2)).finalized() H_alt = syst.hamiltonian_submatrix(k, sparse=False) np.testing.assert_equal(H_alt, H)
def make_system_step1(q): L1 = tinyarray.array((3 / sqrt(3), 0)) SC1 = L1 L2 = tinyarray.array((0, q)) SC2 = L2 syst = kwant.Builder() ##primitive graphene,dispersion without B: # for i in range(1): # #for i in range(q): # for j in range(1): # # On-site Hamiltonian # syst[a(i, j)] =0 # syst[b(i, j)] =0 # syst[a(0,0),b(0,0)]=-1-np.exp(1j*k1)-np.exp(1j*k2) # def rectangle(pos): xR, yR = pos #print(pos) #sys.exit() # xR,yR=list(x*v1+y*v2) #return (xR <=Lx2)&(yR<=Ly2)&(xR >= Lx1)&(yR>=Ly1) return (-cos_30 / 3 - 0.00001 <= xR < 3 / sqrt(3) * Nx - 1 / sqrt(3)) & (0 - 0.0001 <= yR <= Ny * q - 0.0001) syst[graphene.shape(rectangle, (0, 0))] = 0 syst0 = syst.finalized() N_ToT = syst0.graph.num_nodes print(N_ToT) def neighbors(): nns = [[] for i in range(N_ToT)] for ni in range(N_ToT): #print(ni) ri = syst0.sites[ni].pos for nj in range(N_ToT): rj = syst0.sites[nj].pos for n1 in range(-1, 2): for n2 in range(-1, 2): rjn = rj + (n1 * SC1 + n2 * SC2) ss = ri - rjn dis = sqrt(np.dot(ss, ss)) if (abs(dis - 1 / sqrt(3)) < 10**-5): if not ((n1 == 0) & (n2 == 0) & (nj == ni)): nns[ni].append((nj, n1, n2)) return nns nns = neighbors() return nns, syst, syst0
def __lt__(self, other): # Sort group elements: # First by conjugate and a, then R = identity, then the rest # lexicographically Rs = ta.array(np.array(self.R).astype(float), float) Ro = ta.array(np.array(other.R).astype(float), float) identity = ta.array(np.eye(Rs.shape[0], dtype=int)) if not (self.conjugate, self.antisymmetry) == (other.conjugate, other.antisymmetry): return (self.conjugate, self.antisymmetry) < (other.conjugate, other.antisymmetry) elif (Rs == identity) ^ (Ro == identity): return Rs == identity else: return Rs < Ro
def test_pickle(): import pickle for dtype in dtypes: for shape in some_shapes: a = ta.array(make(shape, dtype)) assert pickle.loads(pickle.dumps(a)) == a
def test_iteration(): for dtype in dtypes: assert_raises(TypeError, tuple, ta.array(1, dtype)) for shape in [0, 1, 2, 3, (1, 0), (2, 2), (17, 17), (1, 1, 1), (2, 2, 1), (2, 0, 3)]: a = make(shape, dtype) assert_equal(tuple(a), a)
def test_hash_equality(): random.seed(123) maxint = sys.maxsize + 1 # will be typically 2**31 or 2**63 int_bits = 63 if maxint > 2**32 else 31 special = [float('nan'), float('inf'), float('-inf'), 0, -1, -1.0, -1 + 0j, 303, -312424, -0.3, 1.7, 0.4j, -12.3j, 1 - 12.3j, 1.3 - 12.3j, (), (-1,), (2,), (0, 0), (-1, -1), (-5, 7), (3, -1, 0), ((0, 1), (2, 3)), (((-1,),),)] powers = [sign * (2**e + a) for sign in [1, -1] for a in [-1, 0, 1] for e in range(int_bits)] powers.extend([2**int_bits - 1, -2**int_bits, -2**int_bits + 1]) small_random_ints = (random.randrange(-2**16, 2**16) for i in range(1000)) large_random_ints = (random.randrange(-maxint, maxint) for i in range(1000)) small_random_floats = (random.gauss(0, 1) for i in range(1000)) large_random_floats = (random.gauss(0, 1e100) for i in range(1000)) for collection in [special, powers, small_random_ints, large_random_ints, small_random_floats, large_random_floats]: for thing in collection: arr = ta.array(thing) if thing == thing: assert arr == thing assert not (arr != thing) assert_equal(hash(arr), hash(thing), repr(thing))
def subgroup(self, *generators): generators = ta.array(generators) assert generators.shape == (1, 1) if generators.dtype != int: raise ValueError('Generators must be sequences of integers.') g = generators[0, 0] return VerySimpleSymmetry(g * self.period)
def test_other_scalar_types(): types = [np.int16, np.int32, np.int64, np.float16, np.float32, np.float64] for t in types: a = t(123.456) assert_equal(ta.array(a), np.array(a)) assert_equal(ta.matrix(a), np.matrix(a))
def test_pickle(): import pickle for dtype in dtypes: for shape in some_shapes: a = ta.array(make(shape, dtype)) assert_equal(pickle.loads(pickle.dumps(a)), a)
def test_hash_equality(): random.seed(123) maxint = sys.maxsize + 1 # will be typically 2**31 or 2**63 int_bits = 63 if maxint > 2**32 else 31 special = [float('nan'), float('inf'), float('-inf'), 0, -1, -1.0, -1 + 0j, 303, -312424, -0.3, 1.7, 0.4j, -12.3j, 1 - 12.3j, 1.3 - 12.3j, (), (-1,), (2,), (0, 0), (-1, -1), (-5, 7), (3, -1, 0), ((0, 1), (2, 3)), (((-1,),),)] powers = [sign * (2**e + a) for sign in [1, -1] for a in [-1, 0, 1] for e in range(int_bits)] powers.extend([2**int_bits - 1, -2**int_bits, -2**int_bits + 1]) small_random_ints = (random.randrange(-2**16, 2**16) for i in range(1000)) large_random_ints = (random.randrange(-maxint, maxint) for i in range(1000)) small_random_floats = (random.gauss(0, 1) for i in range(1000)) large_random_floats = (random.gauss(0, 1e100) for i in range(1000)) for collection in [special, powers, small_random_ints, large_random_ints, small_random_floats, large_random_floats]: for thing in collection: arr = ta.array(thing) if thing == thing: assert arr == thing assert not (arr != thing) assert hash(arr) == hash(thing), repr(thing)
def force(self, model): res = ta.array([0.0, 0.0]) res += -model.gradient('pressure', self) if viscosity: res += viscosity * model.laplace('velocity', self) if nudge: res -= self.velocity * nudge if model.t < 1.0: res -= self.velocity * 1.0 res = res * ta.array([0.0, 10.0]) res += ta.array([0.0, gravitiy]) return res
def act(self, element, a, b=None): element = ta.array(element) if element.dtype is not int: raise ValueError("group element must be a tuple of integers") m_part = self._get_site_family_data(a.family)[0] try: delta = ta.dot(m_part, element) except ValueError: msg = 'Expecting a {0}-tuple group element, but got `{1}` instead.' raise ValueError(msg.format(self.num_directions, element)) if self.is_reversed: delta = -delta if b is None: return builder.Site(a.family, a.tag + delta, True) elif b.family == a.family: return (builder.Site(a.family, a.tag + delta, True), builder.Site(b.family, b.tag + delta, True)) else: m_part = self._get_site_family_data(b.family)[0] try: delta2 = ta.dot(m_part, element) except ValueError: msg = ('Expecting a {0}-tuple group element, ' 'but got `{1}` instead.') raise ValueError(msg.format(self.num_directions, element)) if self.is_reversed: delta2 = -delta2 return (builder.Site(a.family, a.tag + delta, True), builder.Site(b.family, b.tag + delta2, True))
def __init__(self, R, conjugate=False, antisymmetry=False, U=None, _strict_eq=False): if isinstance(R, sympy.ImmutableMatrix): # If it is integer, recast to integer tinyarray R = _make_int(R) elif isinstance(R, ta.ndarray_int): pass elif isinstance(R, ta.ndarray_float): R = _make_int(R) elif isinstance(R, sympy.matrices.MatrixBase): R = sympy.ImmutableMatrix(R) R = _make_int(R) elif isinstance(R, np.ndarray): # If it is integer, recast to integer tinyarray R = ta.array(R) R = _make_int(R) else: raise ValueError( 'Real space rotation must be provided as a sympy matrix or an array.' ) self.R, self.conjugate, self.antisymmetry, self.U = R, conjugate, antisymmetry, U # Calculating sympy inverse is slow, remember it self._strict_eq = _strict_eq
def __init__(self, prim_vecs, offset=None, name='', norbs=None): prim_vecs = ta.array(prim_vecs, float) if prim_vecs.ndim != 2: raise ValueError('``prim_vecs`` must be a 2d array-like object.') dim = prim_vecs.shape[1] if name is None: name = '' if prim_vecs.shape[0] > dim: raise ValueError('Number of primitive vectors exceeds ' 'the space dimensionality.') if offset is None: offset = ta.zeros(dim) else: offset = ta.array(offset, float) if offset.shape != (dim, ): raise ValueError('Dimensionality of offset does not match ' 'that of the space.') msg = '{0}({1}, {2}, {3}, {4})' cl = self.__module__ + '.' + self.__class__.__name__ canonical_repr = msg.format(cl, short_array_repr(prim_vecs), short_array_repr(offset), repr(name), repr(norbs)) super().__init__(canonical_repr, name, norbs) self.sublattices = [self] self._prim_vecs = prim_vecs self.inv_pv = ta.array(np.linalg.pinv(prim_vecs)) self.offset = offset # Precalculation of auxiliary arrays for real space calculations. self.reduced_vecs, self.transf = lll.lll(prim_vecs) self.voronoi = ta.dot(lll.voronoi(self.reduced_vecs), self.transf) self.dim = dim self.lattice_dim = len(prim_vecs) if name != '': msg = "<Monatomic lattice {0}{1}>" orbs = ' with {0} orbitals'.format( self.norbs) if self.norbs else '' self.cached_str = msg.format(name, orbs) else: msg = "<unnamed Monatomic lattice, vectors {0}, origin [{1}]{2}>" orbs = ', with {0} orbitals'.format(norbs) if norbs else '' self.cached_str = msg.format(short_array_str(self._prim_vecs), short_array_str(self.offset), orbs)
def make_system(a, t, W, L, salt): # Start with an empty tight-binding system and a single square lattice. # `a` is the lattice constant (by default set to 1 for simplicity). def hopping(site1, site2): alpha = uniform(repr(site1), salt) * 2 * np.pi beta = np.arccos(1 - 2 * uniform(repr(site1.pos), salt)) / 2 gamma = uniform(repr(site2), salt) * 2 * np.pi # np.random.seed(seed=salt) # alpha=np.random.rand()*2*np.pi # beta=np.arccos(1-2*np.random.rand())/2 # gamma=np.random.rand()*2*np.pi return -tinyarray.array([[ cmath.exp(1j * alpha) * math.cos(beta), cmath.exp(1j * gamma) * math.sin(beta) ], [ -cmath.exp(-1j * gamma) * math.sin(beta), cmath.exp(-1j * alpha) * math.cos(beta) ]]) # return np.array([[1,0],[0,1]]) lat = kwant.lattice.square(a) sys = kwant.Builder() #### Define the scattering region. #### sys[(lat(x, y) for x in range(L) for y in range(W))] = tinyarray.array([[0, 0], [0, 0]]) # hoppings in x-direction sys[lat.neighbors()] = hopping #### Define the left lead. #### lead = kwant.Builder(kwant.TranslationalSymmetry((-a, 0))) lead[(lat(0, j) for j in range(W))] = tinyarray.array([[0, 0], [0, 0]]) # hoppings in x-direction lead[lat.neighbors()] = -sigma_0 #### Attach the leads and return the finalized system. #### sys.attach_lead(lead) sys.attach_lead(lead.reversed()) return sys
def grad_weight(displacement): res = list() for i in range(len(displacement)): res.append( grad_weight_1d(displacement[i]) * weight(displacement[j] for j in range(len(displacement)) if j != i)) return ta.array(res)
def __init__(self, prim_vecs, offset=None, name='', norbs=None): prim_vecs = ta.array(prim_vecs, float) if prim_vecs.ndim != 2: raise ValueError('``prim_vecs`` must be a 2d array-like object.') dim = prim_vecs.shape[1] if name is None: name = '' if prim_vecs.shape[0] > dim: raise ValueError('Number of primitive vectors exceeds ' 'the space dimensionality.') if offset is None: offset = ta.zeros(dim) else: offset = ta.array(offset, float) if offset.shape != (dim,): raise ValueError('Dimensionality of offset does not match ' 'that of the space.') msg = '{0}({1}, {2}, {3}, {4})' cl = self.__module__ + '.' + self.__class__.__name__ canonical_repr = msg.format(cl, short_array_repr(prim_vecs), short_array_repr(offset), repr(name), repr(norbs)) super().__init__(canonical_repr, name, norbs) self.sublattices = [self] self._prim_vecs = prim_vecs self.inv_pv = ta.array(np.linalg.pinv(prim_vecs)) self.offset = offset # Precalculation of auxiliary arrays for real space calculations. self.reduced_vecs, self.transf = lll.lll(prim_vecs) self.voronoi = ta.dot(lll.voronoi(self.reduced_vecs), self.transf) self.dim = dim self.lattice_dim = len(prim_vecs) if name != '': msg = "<Monatomic lattice {0}{1}>" orbs = ' with {0} orbitals'.format(self.norbs) if self.norbs else '' self.cached_str = msg.format(name, orbs) else: msg = "<unnamed Monatomic lattice, vectors {0}, origin [{1}]{2}>" orbs = ', with {0} orbitals'.format(norbs) if norbs else '' self.cached_str = msg.format(short_array_str(self._prim_vecs), short_array_str(self.offset), orbs)
def test_symmetry_act(): lat = lattice.square(norbs=1) sym = lattice.TranslationalSymmetry((1, 0), (0, 1)) site = lat(0, 0) hopping = (lat(0, 0), lat(1, 0)) el = (1, 0) # Verify that the dtype of tags of sites returned by 'act' is 'int' for el in [el, ta.array(el, int)]: assert sym.act(el, site).tag.dtype is int assert all(s.tag.dtype is int for s in sym.act(el, *hopping)) for el in [(1.0, 0), (1.5, 0)]: with raises(ValueError): sym.act(el, site) with raises(ValueError): sym.act(ta.array(el), site)
def single_pos(bondee, bond_len, toward=None, away=None): if toward is not None: v = toward - bondee return bondee + normalize(v) * bond_len elif away is not None: v = bondee - away return bondee + normalize(v) * bond_len return bondee + tinyarray.array([bond_len, 0.0, 0.0])
def make_int(R): # If close to an integer array convert to integer tinyarray, else # return None R_int = ta.array(np.round(R), int) if qsymm.linalg.allclose(R, R_int): return R_int else: return None
def test_as_dict_key(): n = 100 d = {} for dtype in dtypes + dtypes: for i in range(n): d[ta.array(range(i), dtype)] = i assert len(d) == n for i in range(n): assert d[tuple(range(i))] == i
def test_binary_operators(): ops = operator operations = [ops.add, ops.sub, ops.mul, ops.mod, ops.floordiv, ops.truediv] if sys.version_info.major < 3: operations.append(ops.div) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=RuntimeWarning) for op in operations: for dtype in dtypes: for shape in [(), 1, 3, (3, 2)]: if dtype is complex and op in [ops.mod, ops.floordiv]: continue a = make(shape, dtype) b = make(shape, dtype) assert_equal(op(ta.array(a.tolist()), ta.array(b.tolist())), op(a, b)) assert_equal(op(ta.array(a), ta.array(b)), op(a, b))
def wire(self, center, radius): """Return a key for all the lattice sites inside an infinite cylinder. This method makes it easy to define cylindrical (2d: rectangular) leads that point in any direction. The object returned by this method is primarily meant to be used as a key for indexing `~kwant.builder.Builder` instances. See example below. Parameters ---------- center : 1d array-like of floats A point belonging to the axis of the cylinder. radius : float The radius of the cylinder. Notes ----- The function returned by this method is to be called with a `~kwant.builder.TranslationalSymmetry` instance (or a `~kwant.builder.Builder` instance whose symmetry is used then) as sole argument. All the lattice sites (in the fundamental domain of the symmetry) inside the specified infinite cylinder are yielded. The direction of the cylinder is determined by the symmetry. Examples -------- >>> lat = kwant.lattice.honeycomb() >>> sym = kwant.TranslationalSymmetry(lat.a.vec((-2, 1))) >>> lead = kwant.Builder(sym) >>> lead[lat.wire((0, -5), 5)] = 0 >>> lead[lat.neighbors()] = 1 """ center = ta.array(center, float) def wire_sites(sym): if not isinstance(sym, builder.Symmetry): sym = sym.symmetry if not isinstance(sym, TranslationalSymmetry): raise ValueError('wire shape only works with ' 'translational symmetry.') if len(sym.periods) != 1: raise ValueError('wire shape only works with one-dimensional ' 'translational symmetry.') period = np.array(sym.periods)[0] direction = ta.array(period / np.linalg.norm(period)) r_squared = radius**2 def wire_shape(pos): rel_pos = pos - center projection = rel_pos - direction * ta.dot(direction, rel_pos) return sum(projection * projection) <= r_squared return self.shape(wire_shape, center)(sym) return wire_sites
def __init__(self, *periods): self.periods = ta.array(periods) if self.periods.ndim != 2: # TODO: remove the second part of the following message once # everybody got used to it. msg = ("TranslationalSymmetry takes 1d sequences as parameters.\n" "See What's new in Kwant 0.2 in the documentation.") raise ValueError(msg) if np.linalg.matrix_rank(periods) < len(periods): raise ValueError("Translational symmetry periods must be " "linearly independent") # A dictionary containing cached data required for applying the # symmetry to different site families. self.site_family_data = {} self.is_reversed = False
def test_value_equality_and_identity(): m = ta.array([[1, 2], [3j, 4j]]) syst = builder.Builder() fam = builder.SimpleSiteFamily() syst[fam(0)] = m syst[fam(1)] = m assert syst[fam(1)] is m syst[fam(0), fam(1)] = m assert syst[fam(1), fam(0)] == m.transpose().conjugate() assert syst[fam(0), fam(1)] is m syst[fam(1), fam(0)] = m assert syst[fam(0), fam(1)] == m.transpose().conjugate() assert syst[fam(1), fam(0)] is m
def test_dot(): # Check acceptance of non-tinyarray arguments. assert ta.dot([1, 2], (3, 4)) == 11 for dtype in dtypes: shape_pairs = [(1, 1), (2, 2), (3, 3), (0, 0), (0, (0, 1)), ((0, 1), 1), (0, (0, 2)), ((0, 2), 2), (1, (1, 2)), ((2, 1), 1), (2, (2, 1)), ((1, 2), 2), (2, (2, 3)), ((3, 2), 2), ((1, 1), (1, 1)), ((2, 2), (2, 2)), ((3, 3), (3, 3)), ((2, 3), (3, 2)), ((2, 1), (1, 2)), ((2, 3, 4), (4, 3)), ((2, 3, 4), 4), ((3, 4), (2, 4, 3)), (4, (2, 4, 3))] # We have to use almost_equal here because the result of numpy's dot # does not always agree to the last bit with a naive implementation. # (This is probably due to their usage of SSE or parallelization.) # # On my machine in summer 2012 with Python 2.7 and 3.2 the program # # import numpy as np # a = np.array([13.2, 14.3, 15.4, 16.5]) # b = np.array([-5.0, -3.9, -2.8, -1.7]) # r = np.dot(a, b) # rr = sum(x * y for x, y in zip(a, b)) # print(r - rr) # # outputs 2.84217094304e-14. for sa, sb in shape_pairs: a = make(sa, dtype) b = make(sb, dtype) - 5 assert_almost_equal(ta.dot(ta.array(a), ta.array(b)), np.dot(a, b), 13) shape_pairs = [((), 2), (2, ()), (1, 2), (1, (2, 2)), ((1, 1), 2), ((2, 2), (3, 2)), ((2, 3, 2), (4, 3)), ((2, 3, 4), 3), ((3, 3), (2, 4, 3)), (3, (2, 4, 3))] for sa, sb in shape_pairs: a = make(sa, dtype) b = make(sb, dtype) - 5 raises(ValueError, ta.dot, ta.array(a.tolist()), ta.array(b.tolist())) raises(ValueError, ta.dot, ta.array(a), ta.array(b))
def wire_sites(sym): if not isinstance(sym, builder.Symmetry): sym = sym.symmetry if not isinstance(sym, TranslationalSymmetry): raise ValueError('wire shape only works with ' 'translational symmetry.') if len(sym.periods) != 1: raise ValueError('wire shape only works with one-dimensional ' 'translational symmetry.') period = np.array(sym.periods)[0] direction = ta.array(period / np.linalg.norm(period)) r_squared = radius**2 def wire_shape(pos): rel_pos = pos - center projection = rel_pos - direction * ta.dot(direction, rel_pos) return sum(projection * projection) <= r_squared return self.shape(wire_shape, center)(sym)
def test_matrix(): for l in [(), 3, (3,), ((3,)), (1, 2), ((1, 2), (3, 4))]: a = ta.matrix(l) b = np.matrix(l) assert a == b assert a.shape == b.shape a = ta.matrix(ta.array(l)) assert a == b assert a.shape == b.shape a = ta.matrix(np.array(l)) assert a == b assert a.shape == b.shape if sys.version_info[:2] > (2, 6): # Creation of tinyarrays from NumPy matrices only works for Python > # 2.6. I don't know whether this is our bug or their's. a = ta.matrix(b) assert a == b for l in [(((),),), ((3,), ()), ((1, 2), (3,))]: raises(ValueError, ta.matrix, l)
def test(n=20000): """Test the generator with the dieharder suite generating n**2 samples. Executing this function may take a very long time. """ import os import tempfile import subprocess from tinyarray import array from struct import pack f = tempfile.NamedTemporaryFile(delete=False) try: for x in xrange(n): for y in xrange(n): a = array((x, y)) i = int(2**32 * uniform(a)) f.write(pack('I', i)) f.close() subprocess.call(['dieharder', '-a', '-g', '201', '-f', f.name]) finally: os.remove(f.name)
def test_conversion(): for src_dtype in dtypes: for dest_dtype in dtypes: src = ta.zeros(3, src_dtype) tsrc = tuple(src) npsrc = np.array(tsrc) impossible = src_dtype is complex and dest_dtype in [int, float] for s in [src, tsrc, npsrc]: if impossible: raises(TypeError, ta.array, s, dest_dtype) else: dest = ta.array(s, dest_dtype) assert isinstance(dest[0], dest_dtype) assert src == dest # Check for overflow. long_overflow = [1e300, np.array([1e300])] # This check only works for Python 2. if 18446744073709551615 > sys.maxsize: long_overflow.extend([np.array([18446744073709551615], np.uint64), 18446744073709551615]) for s in long_overflow: raises(OverflowError, ta.array, s, int)
def test_array(): for dtype in dtypes: for a_shape in some_shapes: a = make(a_shape, dtype) # Creation from list. This also tests creation from scalars. l = a.tolist() b = ta.array(l) b_shape = shape_of_seq(l) # a_shape and b_shape are not always equal. # Example: a_shape == (0, 0), b_shape = (0,). assert isinstance(repr(b), str) assert b.ndim == len(b_shape) assert tuple(b.shape) == b_shape assert b.size == a.size if a_shape != (): assert len(b) == len(a) assert_equal(np.array(ta.array(b)), np.array(l)) else: assert b.dtype == dtype raises(TypeError, len, b) if sys.version_info[:2] > (2, 6): # Python 2.6 does not have memoryview. assert memoryview(b).tobytes() == memoryview(a).tobytes() assert_equal(np.array(b), np.array(l)) assert ta.transpose(l) == np.transpose(l) # Here, the tinyarray is created via the buffer interface. It's # possible to distinguish shape 0 from (0, 0). b = ta.array(a) # This tests creation of arrays from non-C-contiguous buffers. assert b == ta.array(a.transpose()).transpose() assert isinstance(repr(b), str) assert b.ndim == len(b.shape) assert b.shape == a.shape assert b.size == a.size assert b == a assert_equal(np.array(b), a) if a_shape != (): assert len(b) == len(a) else: raises(TypeError, len, b) if sys.version_info[:2] > (2, 6): # Python 2.6 does not have memoryview. assert memoryview(b).tobytes() == memoryview(a).tobytes() assert ta.transpose(b) == np.transpose(a) # Check creation from NumPy matrix. This only works for Python > # 2.6. I don't know whether this is our bug or their's. if sys.version_info[:2] > (2, 6): if not isinstance(a_shape, tuple) or len(a_shape) <= 2: b = ta.array(np.matrix(a)) assert b.ndim == 2 assert b == np.matrix(a) l = [] for i in range(16): l = [l] raises(ValueError, ta.array, l, dtype) raises(TypeError, ta.array, [0, [0, 0]], dtype) raises(ValueError, ta.array, [[0], [0, 0]], dtype) raises(ValueError, ta.array, [[0, 0], 0], dtype) raises(ValueError, ta.array, [[0, 0], [0]], dtype) raises(ValueError, ta.array, [[0, 0], [[0], [0]]], dtype)
def which(self, site): return ta.array((site.tag[0] // self.period,), int)
def f(i, j, arg): i, j = i.tag, j.tag if j[0] == i[0] + 1: return arg * ta.array([[1, 2j], [3 + 1j, 4j]]) else: raise ValueError
def closest(self, pos): """ Find the lattice coordinates of the site closest to position ``pos``. """ return ta.array(self.n_closest(pos)[0])
################ Library of lattices def chain(a=1, name='', norbs=None): """Make a one-dimensional lattice.""" return Monatomic(((a,),), name=name, norbs=norbs) def square(a=1, name='', norbs=None): """Make a square lattice.""" return Monatomic(((a, 0), (0, a)), name=name, norbs=norbs) tri = ta.array(((1, 0), (0.5, 0.5 * sqrt(3)))) def triangular(a=1, name='', norbs=None): """Make a triangular lattice.""" return Monatomic(a * tri, name=name, norbs=norbs) def honeycomb(a=1, name='', norbs=None): """Make a honeycomb lattice.""" lat = Polyatomic(a * tri, ((0, 0), (0, a / sqrt(3))), name=name, norbs=norbs) lat.a, lat.b = lat.sublattices return lat def kagome(a=1, name='', norbs=None):
"""An example of advanced system creation.""" from math import tanh from cmath import exp import tinyarray as ta import kwant sigma_0 = ta.identity(2) sigma_x = ta.array([[0, 1], [1, 0]]) sigma_y = ta.array([[0, -1j], [1j, 0]]) sigma_z = ta.array([[1, 0], [0, -1]]) def make_system(R): def in_ring(pos): x, y = pos return R**2 / 4 < x**2 + y**2 < R**2 def in_lead(pos): x, y = pos return -R / 4 < y < R / 4 def pot(site, B): x, y = site.pos return (0.1 * tanh(x / R) + tanh(2 * y / R)) * sigma_z def hop(site1, site2, B): x1, y1 = site1.pos x2, y2 = site2.pos return - exp(.5j * B * (x1 - x2) * (y1 + y2)) * sigma_0
def normalize_tag(self, tag): tag = ta.array(tag, int) if len(tag) != self.lattice_dim: raise ValueError("Dimensionality mismatch.") return tag
def add_site_family(self, fam, other_vectors=None): """ Select a fundamental domain for site family and cache associated data. Parameters ---------- fam : `SiteFamily` the site family which has to be processed. Be sure to delete the previously processed site families from `site_family_data` if you want to modify the cache. other_vectors : 2d array-like of integers Bravais lattice vectors used to complement the periods in forming a basis. The fundamental domain consists of all the lattice sites for which the zero coefficients corresponding to the symmetry periods in the basis formed by the symmetry periods and `other_vectors`. If an insufficient number of `other_vectors` is provided to form a basis, the missing ones are selected automatically. Raises ------ KeyError If `fam` is already stored in `site_family_data`. ValueError If lattice `fam` is incompatible with given periods. """ ensure_isinstance(fam, Monatomic) dim = self.periods.shape[1] if fam in self.site_family_data: raise KeyError('Family already processed, delete it from ' 'site_family_data first.') inv = np.linalg.pinv(fam.prim_vecs) try: bravais_periods = np.dot(self.periods, inv) except ValueError: fam_space_dim = fam.prim_vecs.shape[1] if dim == fam_space_dim: raise msg = ("{0}-d-embedded lattice is incompatible with " "{1}-d translational symmetry.") raise ValueError(msg.format(fam_space_dim, dim)) # Absolute tolerance is correct in the following since we want an error # relative to the closest integer. if (not np.allclose(bravais_periods, np.round(bravais_periods), rtol=0, atol=1e-8) or not np.allclose([fam.vec(i) for i in bravais_periods], self.periods)): msg = ('Site family {0} does not have commensurate periods with ' 'symmetry {1}.') raise ValueError(msg.format(fam, self)) bravais_periods = np.array(np.round(bravais_periods), dtype='int') (num_dir, lat_dim) = bravais_periods.shape if other_vectors is None: other_vectors = np.zeros((0, lat_dim), dtype=int) else: other_vectors = np.array(other_vectors) if other_vectors.ndim != 2: raise ValueError( '`other_vectors` must be a 2d array-like object.') if np.any(np.round(other_vectors) - other_vectors): raise ValueError('Only integer other_vectors are allowed.') other_vectors = np.array(np.round(other_vectors), dtype=int) m = np.zeros((lat_dim, lat_dim), dtype=int) m.T[:num_dir] = bravais_periods num_vec = num_dir + len(other_vectors) m.T[num_dir:num_vec] = other_vectors if np.linalg.matrix_rank(m) < num_vec: raise ValueError('other_vectors and symmetry periods are not ' 'linearly independent.') # To define the fundamental domain of the new site family we now need to # choose `lat_dim - num_vec` extra lattice vectors that are not # linearly dependent on the vectors we already have. To do so we # continuously add the lattice basis vectors one by one such that they # are not linearly dependent on the existent vectors while num_vec < lat_dim: vh = np.linalg.svd(np.dot(m[:, :num_vec].T, fam.prim_vecs), full_matrices=False)[2] projector = np.identity(dim) - np.dot(vh.T, vh) residuals = np.dot(fam.prim_vecs, projector) residuals = np.apply_along_axis(np.linalg.norm, 1, residuals) m[np.argmax(residuals), num_vec] = 1 num_vec += 1 det_m = int(round(np.linalg.det(m))) if det_m == 0: raise RuntimeError('Adding site family failed.') det_x_inv_m = np.array(np.round(det_m * np.linalg.inv(m)), dtype=int) assert (np.dot(m, det_x_inv_m) // det_m == np.identity(lat_dim)).all() det_x_inv_m_part = det_x_inv_m[:num_dir, :] m_part = m[:, :num_dir] self.site_family_data[fam] = (ta.array(m_part), ta.array(det_x_inv_m_part), det_m)
# -------------------------- # - Repetition of previously used concepts (band structure calculations, # matrices as values in Builder). # - Main motivation is to contrast to the implementation of superconductivity # in tutorial5b.py import kwant import numpy as np import tinyarray # For plotting from matplotlib import pyplot #HIDDEN_BEGIN_nbvn tau_x = tinyarray.array([[0, 1], [1, 0]]) tau_z = tinyarray.array([[1, 0], [0, -1]]) def make_lead(a=1, t=1.0, mu=0.7, Delta=0.1, W=10): # Start with an empty lead with a single square lattice lat = kwant.lattice.square(a) sym_lead = kwant.TranslationalSymmetry((-a, 0)) lead = kwant.Builder(sym_lead) # build up one unit cell of the lead, and add the hoppings # to the next unit cell for j in xrange(W): lead[lat(0, j)] = (4 * t - mu) * tau_z + Delta * tau_x