Commit 3afbfebd authored by Tómas's avatar Tómas Committed by Anton Akhmerov

validate to return all broken symmetries

parent c494477a
......@@ -157,19 +157,25 @@ class DiscreteSymmetry:
matrix = new_matrix
else:
matrix = hstack([matrix, csr_matrix((n, n-m))])
broken_symmetries = []
if self.projectors is not None:
for proj in self.projectors:
full = proj.dot(proj.T.conj())
commutator = full.dot(matrix) - (full.T.dot(matrix.T)).T
if np.linalg.norm(commutator.data) > 1e-8:
return 'Conservation law'
broken_symmetries.append('Conservation law')
break
for symm, conj, sign, name in zip(self[1:], _conj, _signs, _names):
if symm is None:
continue
commutator = symm.T.conj().dot((symm.T.dot(matrix.T)).T)
commutator = commutator - sign * cond_conj(matrix, conj)
if np.linalg.norm(commutator.data) > 1e-8:
return name
broken_symmetries.append(name)
if not len(broken_symmetries):
return None
else:
return broken_symmetries
def __getitem__(self, item):
return (self.projectors, self.time_reversal,
......
......@@ -151,21 +151,21 @@ def test_validate():
csr = sparse.csr_matrix
sym = DiscreteSymmetry(projectors=[csr(np.array([[1], [0]])),
csr(np.array([[0], [1]]))])
assert sym.validate(csr(np.array([[0], [1]]))) == 'Conservation law'
assert sym.validate(csr(np.array([[0], [1]]))) == ['Conservation law']
assert sym.validate(np.array([[1], [0]])) is None
assert sym.validate(np.eye(2)) is None
assert sym.validate(1 - np.eye(2)) == 'Conservation law'
assert sym.validate(1 - np.eye(2)) == ['Conservation law']
sym = DiscreteSymmetry(particle_hole=sparse.identity(2))
assert sym.validate(1j * sparse.identity(2)) is None
assert sym.validate(sparse.identity(2)) == 'Particle-hole'
assert sym.validate(sparse.identity(2)) == ['Particle-hole']
sym = DiscreteSymmetry(time_reversal=sparse.identity(2))
assert sym.validate(sparse.identity(2)) is None
assert sym.validate(1j * sparse.identity(2)) == 'Time reversal'
assert sym.validate(1j * sparse.identity(2)) == ['Time reversal']
sym = DiscreteSymmetry(chiral=csr(np.diag((1, -1))))
assert sym.validate(np.eye(2)) == 'Chiral'
assert sym.validate(np.eye(2)) == ['Chiral']
assert sym.validate(1 - np.eye(2)) is None
......@@ -203,4 +203,4 @@ def test_validate_commutator():
chiral=c_mat)
assert disc_symm.validate(h) == None
a = random_onsite_hop(n, rng=rng)[1]
assert disc_symm.validate(a) in ['Time reversal', 'Particle-hole', 'Chiral']
assert len(disc_symm.validate(a))
......@@ -238,24 +238,23 @@ class InfiniteSystem(System, metaclass=abc.ABCMeta):
symmetries = self.discrete_symmetry(args, params=params)
# Check whether each symmetry is broken.
# If a symmetry is broken, it is ignored in the computation.
symmetry_names = ['Conservation law'] + physics.symmetry._names
broken = (symmetries.validate(ham),
symmetries.validate(hop))
for name in symmetry_names:
if name in broken:
warnings.warn("Hamiltonian breaks " + name +
", ignoring the symmetry in the computation.")
if name == symmetry_names[0]:
symmetries.projectors = None
elif name == symmetry_names[1]:
symmetries.time_reversal = None
elif name == symmetry_names[2]:
symmetries.particle_hole = None
elif name == symmetry_names[3]:
symmetries.chiral = None
else:
warnings.warn("Misidentified a broken symmetry"
+" in the lead.")
broken = {symmetry for item in (symmetries.validate(ham),
symmetries.validate(hop))
if item is not None for symmetry in item}
for name in broken:
warnings.warn("Hamiltonian breaks " + name +
", ignoring the symmetry in the computation.")
if name == 'Conservation law':
symmetries.projectors = None
elif name == 'Time reversal':
symmetries.time_reversal = None
elif name == 'Particle-hole':
symmetries.particle_hole = None
elif name == 'Chiral':
symmetries.chiral = None
else:
warnings.warn("Misidentified a broken symmetry"
" in the lead.")
shape = ham.shape
assert len(shape) == 2
assert shape[0] == shape[1]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment