Commit e1c6cbf6 authored by Christoph Groth's avatar Christoph Groth
Browse files

require discretizer 'coords' to be sorted

parent 0ec6a259
...@@ -97,11 +97,10 @@ def discretize(hamiltonian, coords=None, *, grid_spacing=1, ...@@ -97,11 +97,10 @@ def discretize(hamiltonian, coords=None, *, grid_spacing=1,
proper commutation properties. If a string is provided it will be proper commutation properties. If a string is provided it will be
converted to a sympy expression using `kwant.continuum.sympify`. converted to a sympy expression using `kwant.continuum.sympify`.
coords : sequence of strings, or ``None`` (default) coords : sequence of strings, or ``None`` (default)
Set of coordinates for which momentum operators will be treated as The coordinates for which momentum operators will be treated as
differential operators. For example ``coords=('x', 'y')``. differential operators. May contain only "x", "y" and "z" and must be
If not provided they will be obtained from the input hamiltonian by sorted. If not provided, `coords` will be obtained from the input
reading present coordinates and momentum operators. Order of discrete Hamiltonian by reading the present coordinates and momentum operators.
coordinates is always lexical, even if provided otherwise.
grid_spacing : int or float, default: 1 grid_spacing : int or float, default: 1
Grid spacing for the template Builder. Grid spacing for the template Builder.
subs : dict, defaults to empty subs : dict, defaults to empty
...@@ -138,11 +137,10 @@ def discretize_symbolic(hamiltonian, coords=None, *, subs=None): ...@@ -138,11 +137,10 @@ def discretize_symbolic(hamiltonian, coords=None, *, subs=None):
proper commutation properties. If a string is provided it will be proper commutation properties. If a string is provided it will be
converted to a sympy expression using `kwant.continuum.sympify`. converted to a sympy expression using `kwant.continuum.sympify`.
coords : sequence of strings, or ``None`` (default) coords : sequence of strings, or ``None`` (default)
Set of coordinates for which momentum operators will be treated as The coordinates for which momentum operators will be treated as
differential operators. For example ``coords=('x', 'y')``. differential operators. May contain only "x", "y" and "z" and must be
If not provided they will be obtained from the input hamiltonian by sorted. If not provided, `coords` will be obtained from the input
reading present coordinates and momentum operators. Order of discrete Hamiltonian by reading the present coordinates and momentum operators.
coordinates is always lexical, even if provided otherwise.
subs: dict, defaults to empty subs: dict, defaults to empty
A namespace of substitutions to be performed on the input A namespace of substitutions to be performed on the input
``hamiltonian``. Values can be either strings or ``sympy`` objects. ``hamiltonian``. Values can be either strings or ``sympy`` objects.
...@@ -172,10 +170,12 @@ def discretize_symbolic(hamiltonian, coords=None, *, subs=None): ...@@ -172,10 +170,12 @@ def discretize_symbolic(hamiltonian, coords=None, *, subs=None):
used_momenta = set(_momentum_operators) & set(atoms_names) used_momenta = set(_momentum_operators) & set(atoms_names)
coords = {k[-1] for k in used_momenta} coords = {k[-1] for k in used_momenta}
else: else:
coords = set(coords) coords = list(coords)
if not coords <= set('xyz'): if coords != sorted(coords):
msg = "Discrete coordinates must only contain 'x', 'y', or 'z'." raise ValueError("The argument 'coords' must be sorted.")
raise ValueError(msg) if any(c not in 'xyz' for c in coords):
raise ValueError("The argument 'coords' may only contain "
"'x', 'y', or 'z'.")
coords = sorted(coords) coords = sorted(coords)
...@@ -228,8 +228,9 @@ def build_discretized(tb_hamiltonian, coords, *, ...@@ -228,8 +228,9 @@ def build_discretized(tb_hamiltonian, coords, *,
for the hoppings/onsite or expressions that can by sympified using for the hoppings/onsite or expressions that can by sympified using
`kwant.continuum.sympify`. `kwant.continuum.sympify`.
coords : sequence of strings coords : sequence of strings
Set of coordinates for which momentum operators will be treated as The coordinates for which momentum operators will be treated as
differential operators. For example ``coords=('x', 'y')``. differential operators. May contain only "x", "y" and "z" and must be
sorted.
grid_spacing : int or float, default: 1 grid_spacing : int or float, default: 1
Grid spacing for the template Builder. Grid spacing for the template Builder.
subs: dict, defaults to empty subs: dict, defaults to empty
...@@ -252,7 +253,9 @@ def build_discretized(tb_hamiltonian, coords, *, ...@@ -252,7 +253,9 @@ def build_discretized(tb_hamiltonian, coords, *,
for k, v in tb_hamiltonian.items(): for k, v in tb_hamiltonian.items():
tb_hamiltonian[k] = sympify(v, subs) tb_hamiltonian[k] = sympify(v, subs)
coords = sorted(coords) coords = list(coords)
if coords != sorted(coords):
raise ValueError("The argument 'coords' must be sorted.")
tb = {} tb = {}
for n, (offset, hopping) in enumerate(tb_hamiltonian.items()): for n, (offset, hopping) in enumerate(tb_hamiltonian.items()):
......
...@@ -208,10 +208,10 @@ def test_integer_float_input(): ...@@ -208,10 +208,10 @@ def test_integer_float_input():
} }
for inp, out in test.items(): for inp, out in test.items():
got, _ = discretize_symbolic(int(inp), {'x', 'y', 'z'}) got, _ = discretize_symbolic(int(inp), 'xyz')
assert got == out assert got == out
got, _ = discretize_symbolic(float(inp), {'x', 'y', 'z'}) got, _ = discretize_symbolic(float(inp), 'xyz')
assert got == out assert got == out
# let's test in matrix version too # let's test in matrix version too
...@@ -223,54 +223,54 @@ def test_integer_float_input(): ...@@ -223,54 +223,54 @@ def test_integer_float_input():
new_test.append((inp, new_out)) new_test.append((inp, new_out))
for inp, out in new_test: for inp, out in new_test:
got, _ = discretize_symbolic(sympy.Matrix([int(inp)]), {'x', 'y', 'z'}) got, _ = discretize_symbolic(sympy.Matrix([int(inp)]), 'xyz')
assert got == out assert got == out
got, _ = discretize_symbolic(sympy.Matrix([float(inp)]), {'x', 'y', 'z'}) got, _ = discretize_symbolic(sympy.Matrix([float(inp)]), 'xyz')
assert got == out assert got == out
def test_different_discrete_coordinates(): def test_different_discrete_coordinates():
test = [ test = [
( (
{'x', 'y', 'z'}, { 'xyz', {
(1, 0, 0): -1/a**2, (0, 0, 1): -1/a**2, (1, 0, 0): -1/a**2, (0, 0, 1): -1/a**2,
(0, 0, 0): 6/a**2, (0, 1, 0): -1/a**2 (0, 0, 0): 6/a**2, (0, 1, 0): -1/a**2
} }
), ),
( (
{'x', 'y'}, { 'xy', {
(0, 1): -1/a**2, (0, 1): -1/a**2,
(1, 0): -1/a**2, (1, 0): -1/a**2,
(0, 0): kz**2 + 4/a**2 (0, 0): kz**2 + 4/a**2
} }
), ),
( (
{'x', 'z'}, { 'xz', {
(0, 1): -1/a**2, (0, 1): -1/a**2,
(1, 0): -1/a**2, (1, 0): -1/a**2,
(0, 0): ky**2 + 4/a**2 (0, 0): ky**2 + 4/a**2
} }
), ),
( (
{'y', 'z'}, { 'yz', {
(0, 1): -1/a**2, (0, 1): -1/a**2,
(1, 0): -1/a**2, (1, 0): -1/a**2,
(0, 0): kx**2 + 4/a**2 (0, 0): kx**2 + 4/a**2
} }
), ),
( (
{'x'}, { 'x', {
(0,): ky**2 + kz**2 + 2/a**2, (1,): -1/a**2 (0,): ky**2 + kz**2 + 2/a**2, (1,): -1/a**2
} }
), ),
( (
{'y'}, { 'y', {
(0,): kx**2 + kz**2 + 2/a**2, (1,): -1/a**2 (0,): kx**2 + kz**2 + 2/a**2, (1,): -1/a**2
} }
), ),
( (
{'z'}, { 'z', {
(0,): ky**2 + kx**2 + 2/a**2, (1,): -1/a**2 (0,): ky**2 + kx**2 + 2/a**2, (1,): -1/a**2
} }
) , ) ,
...@@ -313,20 +313,20 @@ def test_matrix_with_zeros(): ...@@ -313,20 +313,20 @@ def test_matrix_with_zeros():
def test_numeric_functions_basic_symbolic(): def test_numeric_functions_basic_symbolic():
for i in [0, 1, 3, 5]: for i in [0, 1, 3, 5]:
builder = discretize(i, {'x'}) builder = discretize(i, 'x')
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
assert builder[lat(0)] == i assert builder[lat(0)] == i
p = dict(t=i) p = dict(t=i)
tb = {(0,): sympy.sympify("2*t"), (1,): sympy.sympify('-t')} tb = {(0,): sympy.sympify("2*t"), (1,): sympy.sympify('-t')}
builder = build_discretized(tb, {'x'}, grid_spacing=1) builder = build_discretized(tb, 'x', grid_spacing=1)
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
assert 2*p['t'] == builder[lat(0)](None, **p) assert 2*p['t'] == builder[lat(0)](None, **p)
assert -p['t'] == builder[lat(1), lat(0)](None, None, **p) assert -p['t'] == builder[lat(1), lat(0)](None, None, **p)
tb = {(0,): sympy.sympify("0"), (1,): sympy.sympify('-1j * t')} tb = {(0,): sympy.sympify("0"), (1,): sympy.sympify('-1j * t')}
builder = build_discretized(tb, {'x'}, grid_spacing=1) builder = build_discretized(tb, 'x', grid_spacing=1)
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
assert -1j * p['t'] == builder[lat(0), lat(1)](None, None, **p) assert -1j * p['t'] == builder[lat(0), lat(1)](None, None, **p)
assert +1j * p['t'] == builder[lat(1), lat(0)](None, None, **p) assert +1j * p['t'] == builder[lat(1), lat(0)](None, None, **p)
...@@ -369,26 +369,26 @@ def test_numeric_functions_with_pi(): ...@@ -369,26 +369,26 @@ def test_numeric_functions_with_pi():
def test_numeric_functions_basic_string(): def test_numeric_functions_basic_string():
for i in [0, 1, 3, 5]: for i in [0, 1, 3, 5]:
builder = discretize(i, {'x'}) builder = discretize(i, 'x')
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
assert builder[lat(0)] == i assert builder[lat(0)] == i
p = dict(t=i) p = dict(t=i)
tb = {(0,): "2*t", (1,): "-t"} tb = {(0,): "2*t", (1,): "-t"}
builder = build_discretized(tb, {'x'}, grid_spacing=1) builder = build_discretized(tb, 'x', grid_spacing=1)
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
assert 2*p['t'] == builder[lat(0)](None, **p) assert 2*p['t'] == builder[lat(0)](None, **p)
assert -p['t'] == builder[lat(1), lat(0)](None, None, **p) assert -p['t'] == builder[lat(1), lat(0)](None, None, **p)
tb = {(0,): "0", (1,): "-1j * t"} tb = {(0,): "0", (1,): "-1j * t"}
builder = build_discretized(tb, {'x'}, grid_spacing=1) builder = build_discretized(tb, 'x', grid_spacing=1)
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
assert -1j * p['t'] == builder[lat(0), lat(1)](None, None, **p) assert -1j * p['t'] == builder[lat(0), lat(1)](None, None, **p)
assert +1j * p['t'] == builder[lat(1), lat(0)](None, None, **p) assert +1j * p['t'] == builder[lat(1), lat(0)](None, None, **p)
tb = {(0,): "0", (-1,): "+1j * t"} tb = {(0,): "0", (-1,): "+1j * t"}
builder = build_discretized(tb, {'x'}, grid_spacing=1) builder = build_discretized(tb, 'x', grid_spacing=1)
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
assert -1j * p['t'] == builder[lat(0), lat(1)](None, None, **p) assert -1j * p['t'] == builder[lat(0), lat(1)](None, None, **p)
assert +1j * p['t'] == builder[lat(1), lat(0)](None, None, **p) assert +1j * p['t'] == builder[lat(1), lat(0)](None, None, **p)
...@@ -428,7 +428,7 @@ def test_numeric_functions_advance(): ...@@ -428,7 +428,7 @@ def test_numeric_functions_advance():
for hamiltonian in hams: for hamiltonian in hams:
for a in [1, 2, 5]: for a in [1, 2, 5]:
for fA in [lambda x: x, lambda x: x**2, lambda x: x**3]: for fA in [lambda x: x, lambda x: x**2, lambda x: x**3]:
symbolic, coords = discretize_symbolic(hamiltonian, {'x'}) symbolic, coords = discretize_symbolic(hamiltonian, 'x')
builder = build_discretized(symbolic, coords, grid_spacing=a) builder = build_discretized(symbolic, coords, grid_spacing=a)
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
...@@ -473,7 +473,7 @@ def test_numeric_functions_with_parameter(): ...@@ -473,7 +473,7 @@ def test_numeric_functions_with_parameter():
for a in [1, 2, 5]: for a in [1, 2, 5]:
for fA in [lambda c, x: x+c, lambda c, x: x**2 + c]: for fA in [lambda c, x: x+c, lambda c, x: x**2 + c]:
symbolic, coords = discretize_symbolic(hamiltonian, {'x'}) symbolic, coords = discretize_symbolic(hamiltonian, 'x')
builder = build_discretized(symbolic, coords, grid_spacing=a) builder = build_discretized(symbolic, coords, grid_spacing=a)
lat = next(iter(builder.sites()))[0] lat = next(iter(builder.sites()))[0]
......
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