-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsolver.py
131 lines (91 loc) · 4.56 KB
/
solver.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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""
solver.py - Solvers for LinearCombinaisonPauliString
Copyright 2020-2021 Maxime Dion <[email protected]>
This file has been modified by **Jonas Jaeger** <[email protected]> during the
QSciTech-QuantumBC virtual workshop on gate-based quantum computing.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import numpy as np
import time
from pauli_string import LinearCombinaisonPauliString
from numpy.typing import NDArray
class LCPSSolver:
def lowest_eig_value(self, observable: LinearCombinaisonPauliString) -> float:
raise NotImplementedError("Virtual base class implementation")
class ExactSolver(LCPSSolver):
def __init__(self):
"""Exact solver to compute the expectation value of a given operator in the form of a
LinearCombinaisonPauliString
"""
self.last_eig_value = None
self.last_eig_vector = None
def eig(self, observable:LinearCombinaisonPauliString) -> tuple[NDArray, NDArray]:
"""
Convert LCPS into a matrix and return sorted eigenvalues and eigenvectors.
Args:
observable (LinearCombinaisonPauliString): The observable to be solved.
Returns:
np.array, np.array : Eigenvalues and eigenvectors sorted with respect to the eigenvalues.
"""
eig_values, eig_vectors = None
################################################################################################################
# YOUR CODE HERE (OPTIONAL)
# TO COMPLETE (after lecture on VQE)
# Hint : np.linalg.eigh
################################################################################################################
raise NotImplementedError()
return eig_values, eig_vectors
def lowest_eig_value(self, observable: LinearCombinaisonPauliString) -> float:
"""
Return lowest eigenvalue and associated eigenvector.
Args:
observable (LinearCombinaisonPauliString): The observable to be solved.
Returns:
float, np.array : The lowest eigenvalue and the associated eigenvector.
"""
eig_values, eig_vectors = np.linalg.eigh(observable.to_matrix())
eig_value, eig_vector = min(eig_values), eig_vectors[:, 0]
self.last_opt_params = eig_vector # store the state vector for retrieval
return eig_value
class VQESolver(LCPSSolver):
def __init__(self, estimator, minimizer, start_params, name='vqe_solver'):
"""
Solver based on the VQE algorithm to estimate the lowest expectation value of a given operator in the form of a
LinearCombinaisonPauliString
Args:
estimator (Estimator): The Evaluator that allows to transform a LCPS into a function.
minimizer (lambda): Function that accepts 2 inputs : a function and a starting parameter list/array.
start_params (list or np.array): The starting parameter to the minimization process.
name (str, optional): A name to the solver. Useful when testing multiple solver in parallel.
Defaults to 'vqe_solver'.
"""
self.estimator = estimator
self.minimizer = minimizer
self.start_params = start_params
self.name = name
self.last_minimization_duration = 0
self.last_result = None
self.last_opt_value = None
self.last_opt_params = None
def lowest_eig_value(self, observable: LinearCombinaisonPauliString) -> float:
"""
Return lowest expectation value and associated parameters the minimization could find.
Args:
observable (LinearCombinaisonPauliString): The observable to be solved.
Returns:
float : The lowest eigenvalue.
"""
t0 = time.time()
minimization_result = self.minimizer(self.estimator.eval, self.start_params)
opt_value, opt_params = minimization_result.fun, minimization_result.x
self.last_minimization_duration = time.time()-t0
self.last_opt_params = opt_params # store the parameters of the variationnal circuit.
return opt_value