Skip to content

Commit

Permalink
Add Space class to analysis folder
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulaGarciaMolina committed Nov 2, 2023
1 parent 9e73258 commit 21fa9a0
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
112 changes: 112 additions & 0 deletions seemps/analysis/space.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import numpy as np
from ..operators import MPO, MPOList, MPOSum


def mpo_flip(operator):
"""Swap the qubits in the quantum register, to fix the reversal
suffered during the quantum Fourier transform."""
if isinstance(operator, MPO):
return MPO(
[np.moveaxis(op, [0, 1, 2, 3], [3, 1, 2, 0]) for op in reversed(operator)],
strategy=operator.strategy,
)
elif isinstance(operator, MPOList):
return MPOList(
[
MPO(
[
np.moveaxis(op, [0, 1, 2, 3], [3, 1, 2, 0])
for op in reversed(mpo)
],
strategy=operator.strategy,
)
for mpo in operator.mpos
],
strategy=operator.strategy,
)
elif isinstance(operator,MPOSum):
new_mpos = []
for weight, op in zip(operator.weights, operator.mpos):
new_mpos.append(weight * mpo_flip(op))
return MPOSum(new_mpos,strategy=operator.strategy,)

class Space:
"""Class to encode the definition space of a discretized multidimensional function.
Parameters
----------
qubits_per_dimension : list[int]
Number of qubits for each dimension.
L : list[list[floats]]
Position space intervals [a_i,b_i] for each dimension i.
closed : bool
If closed is True, the position space intervals are closed (symmetrically defined).
If False, the interval is open. (Optional, defaults to True).
"""

def __init__(self, qubits_per_dimension, L, closed=True):
self.qubits_per_dimension = qubits_per_dimension
self.grid_dimensions = [2**n for n in qubits_per_dimension]
self.closed = closed
self.n_sites = sum(qubits_per_dimension)
self.sites = self.get_sites()
self.L = L
self.a = [L_i[0] for L_i in L]
self.b = [L_i[1] for L_i in L]
self.dx = np.array([
(end - start) / ((d - 1) if closed else d)
for (start, end), d in zip(L, self.grid_dimensions)
])
self.x =[self.a[i] + self.dx[i] * np.arange(dim) for i, dim in enumerate(self.grid_dimensions)]

def increase_resolution(self, new_qubits_per_dimension):
if self.closed:
new_space = Space(
new_qubits_per_dimension,
self.L,
closed=self.closed,
)
new_space.dx = np.array([dx * self.grid_dimensions[i]/new_space.grid_dimensions[i] for i, dx in enumerate(self.dx)])
new_space.x =[new_space.a[i] + new_space.dx[i] * np.arange(dim) for i, dim in enumerate(new_space.grid_dimensions)]
else:
new_space = Space(
new_qubits_per_dimension,
[
(an, an + dxn * (2**old_qubits))
for an, dxn, old_qubits in zip(
self.a, self.dx, self.qubits_per_dimension
)
],
closed=self.closed,
)
return new_space

def __str__(self):
return f"Space(a={self.a}, b={self.b}, dx={self.dx}, closed={self.closed}, qubits={self.qubits_per_dimension})"

def get_coordinates_tuples(self):
"""Creates a list of coordinates tuples of the form
(n,k), where n is the dimension and k is the significant digit
of the qubits used for storing that dimension. Each qubit has
a tuple (n,k) associated to it.
"""
coordinates_tuples = []
coordinates_tuples = [
(n, k)
for n, n_q in enumerate(self.qubits_per_dimension)
for k in range(n_q)
]
return coordinates_tuples

def get_sites(self):
"""Sites for each dimension"""
sites = []
index = 0
for n in self.qubits_per_dimension:
sites.append(list(range(index, index + n)))
index += n
return sites

def extend(self, op, dim):
"""Extend MPO acting on 1D to a multi-dimensional MPS."""
return op.extend(self.n_sites, self.sites[dim])
40 changes: 40 additions & 0 deletions tests/test_space.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import numpy as np
from seemps.analysis.space import Space
from .tools import *

class TestSpace(TestCase):
qubits = [[3],[3,3],[2,4,3]]

def test_coordinates(self):
a, b = 0, 1
for qubits_i in self.qubits:
for closed in [False, True]:
dims = [2**q for q in qubits_i]
L = [[a,b]]*len(qubits_i)
dx = np.array([
(end - start) / ((d - 1) if closed else d)
for (start, end), d in zip(L, dims)
])
space = Space(qubits_i, L, closed=closed)
for i, dim in enumerate(dims):
x = a + dx[i]*np.arange(dim)
self.assertSimilar(x, space.x[i])

def test_increase_resolution(self):
a, b = 0, 1
for qubits_i in self.qubits:
for closed in [False, True]:
dims = [2**q for q in qubits_i]
L = [[a,b]]*len(qubits_i)
dx = np.array([
(end - start) / ((d - 1) if closed else d)
for (start, end), d in zip(L, dims)
])
space = Space(qubits_i, L, closed=closed)
new_qubits = [q+1 for q in qubits_i]
new_space = space.increase_resolution(new_qubits)
new_dims = [2**q for q in new_qubits]
new_dx = [dx * dims[i]/new_dims[i] for i, dx in enumerate(space.dx)]
for i, dim in enumerate(new_dims):
x = a + new_dx[i]*np.arange(dim)
self.assertSimilar(x, new_space.x[i])

0 comments on commit 21fa9a0

Please sign in to comment.