Commit 74173986 by Christoph Groth

### make NoSymmetry a subgroup of itself, and reorganize related code

parent dc02e80e
 ... ... @@ -333,22 +333,16 @@ class Symmetry(metaclass=abc.ABCMeta): pass @abc.abstractmethod def isstrictsupergroup(self, other): """Test whether `self` is a strict supergroup of `other`... def has_subgroup(self, other): """Test whether `self` has the subgroup `other`... or, in other words, whether `other` is a subgroup of `self`. The reason why this is the abstract method (and not `issubgroup`) is that reason why this is the abstract method (and not `is_subgroup`) is that in general it's not possible for a subgroup to know its supergroups. """ pass def issubgroup(self, other): """Test whether `self` is a subgroup of `other`.""" return other.isstrictsupergroup(self) __le__ = issubgroup class NoSymmetry(Symmetry): """A symmetry with a trivial symmetry group.""" ... ... @@ -389,8 +383,8 @@ class NoSymmetry(Symmetry): raise ValueError('Generators must be empty for NoSymmetry.') return NoSymmetry(generators) def isstrictsupergroup(self, other): return False def has_subgroup(self, other): return isinstance(other, NoSymmetry) ... ... @@ -1303,7 +1297,7 @@ class Builder: templ_sym = template.symmetry # Check that symmetries are commensurate. if not self.symmetry <= templ_sym: if not templ_sym.has_subgroup(self.symmetry): raise ValueError("Builder symmetry is not a subgroup of the " "template symmetry") ... ...
 ... ... @@ -555,7 +555,7 @@ class TranslationalSymmetry(builder.Symmetry): raise ValueError('Generators must be sequences of integers.') return TranslationalSymmetry(*ta.dot(generators, self.periods)) def isstrictsupergroup(self, other): def has_subgroup(self, other): if isinstance(other, builder.NoSymmetry): return True elif not isinstance(other, TranslationalSymmetry): ... ...
 ... ... @@ -129,7 +129,7 @@ class VerySimpleSymmetry(builder.Symmetry): def num_directions(self): return 1 def isstrictsupergroup(self, other): def has_subgroup(self, other): if isinstance(other, builder.NoSymmetry): return True elif isinstance(other, VerySimpleSymmetry): ... ... @@ -652,32 +652,36 @@ def test_fill(): return -100 <= site.pos[0] < 100 ## Test that copying a builder by "fill" preserves everything. cubic = kwant.lattice.general(ta.identity(3)) sym = kwant.TranslationalSymmetry((3, 0, 0), (0, 4, 0), (0, 0, 5)) # Make a weird system. orig = kwant.Builder(sym) sites = cubic.shape(lambda pos: True, (0, 0, 0)) for i, site in enumerate(orig.expand(sites)): if i % 7 == 0: continue orig[site] = i for i, hopp in enumerate(orig.expand(cubic.neighbors(1))): if i % 11 == 0: continue orig[hopp] = i * 1.2345 for i, hopp in enumerate(orig.expand(cubic.neighbors(2))): if i % 13 == 0: continue orig[hopp] = i * 1j # Clone the original using fill. clone = kwant.Builder(sym) clone.fill(orig, lambda s: True, (0, 0, 0)) # Verify that both are identical. assert set(clone.site_value_pairs()) == set(orig.site_value_pairs()) assert set(clone.hopping_value_pairs()) == set(orig.hopping_value_pairs()) for sym, func in [(kwant.TranslationalSymmetry(*np.diag([3, 4, 5])), lambda pos: True), (builder.NoSymmetry(), lambda pos: ta.dot(pos, pos) < 17)]: cubic = kwant.lattice.general(ta.identity(3)) # Make a weird system. orig = kwant.Builder(sym) sites = cubic.shape(func, (0, 0, 0)) for i, site in enumerate(orig.expand(sites)): if i % 7 == 0: continue orig[site] = i for i, hopp in enumerate(orig.expand(cubic.neighbors(1))): if i % 11 == 0: continue orig[hopp] = i * 1.2345 for i, hopp in enumerate(orig.expand(cubic.neighbors(2))): if i % 13 == 0: continue orig[hopp] = i * 1j # Clone the original using fill. clone = kwant.Builder(sym) clone.fill(orig, lambda s: True, (0, 0, 0)) # Verify that both are identical. assert set(clone.site_value_pairs()) == set(orig.site_value_pairs()) assert (set(clone.hopping_value_pairs()) == set(orig.hopping_value_pairs())) ## Test for warning when "start" is out. target = builder.Builder() ... ...
 ... ... @@ -251,21 +251,23 @@ def test_symmetry_act(): sym.act(ta.array(el), site) def test_symmetry_subgroup(): def test_symmetry_has_subgroup(): rng = np.random.RandomState(0) ## test whether actual subgroups are detected as such vecs = rng.randn(3, 3) sym1 = lattice.TranslationalSymmetry(*vecs) assert sym1 >= sym1 assert sym1 >= builder.NoSymmetry() assert sym1 >= lattice.TranslationalSymmetry(2 * vecs[0], 3 * vecs[1] + 4 * vecs[2]) assert not sym1 <= lattice.TranslationalSymmetry(*(0.8 * vecs)) ns = builder.NoSymmetry() assert ns.has_subgroup(ns) assert sym1.has_subgroup(sym1) assert sym1.has_subgroup(ns) assert sym1.has_subgroup(lattice.TranslationalSymmetry( 2 * vecs[0], 3 * vecs[1] + 4 * vecs[2])) assert not lattice.TranslationalSymmetry(*(0.8 * vecs)).has_subgroup(sym1) ## test subgroup creation for dim in range(1, 4): generators = rng.randint(10, size=(dim, 3)) assert sym1.subgroup(*generators) <= sym1 assert sym1.has_subgroup(sym1.subgroup(*generators)) # generators are not linearly independent with raises(ValueError): ... ...
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!