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