-
Notifications
You must be signed in to change notification settings - Fork 3
/
hamiltonian.py
61 lines (52 loc) · 1.93 KB
/
hamiltonian.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from typing import Optional
import cirq
import tensorflow as tf
class Hamiltonian:
def __init__(
self, problem: cirq.PauliSum, coefficients: Optional[tf.Tensor] = None,
) -> None:
self._problem = problem
self.pauli_terms = list(problem)
if coefficients is not None:
self._coefficients = tf.Variable(coefficients)
else:
self._coefficients = tf.Variable(
[term.coefficient.real for term in self.pauli_terms]
)
def to_pauli_sum(self) -> cirq.PauliSum:
return cirq.PauliSum.from_pauli_strings(
[
pauli_term.with_coefficient(self._coefficients[i])
for i, pauli_term in enumerate(self.pauli_terms)
]
)
@property
def coefficients(self) -> tf.Tensor:
return self._coefficients
@property
def problem(self) -> tf.Tensor:
return self._problem
@coefficients.setter
def coefficients(self, new_coefficients: tf.Tensor):
self._coefficients = new_coefficients
def normalize_coefficients(self, clip=False):
if clip:
clipped_coefficients = tf.clip_by_value(
self._coefficients, clip_value_min=-10, clip_value_max=10
)
self._coefficients = tf.Variable(clipped_coefficients)
else:
normalized_coefficients, _ = tf.linalg.normalize(self._coefficients)
self._coefficients = tf.Variable(normalized_coefficients)
def finite_difference_models(self, difference=0.1):
n = self.coefficients.shape[0]
finite_difference_coefficients = (
tf.tile(tf.expand_dims(self.coefficients, 0), [n, 1])
+ tf.eye(n) * difference
)
return [
Hamiltonian(self._problem, finite_difference_coefficients[i])
for i in range(n)
]
def __str__(self) -> str:
return self.to_pauli_sum().__str__()