Sequential Quantum Gate Decomposer  v1.9.3
Powerful decomposition of general unitarias into one- and two-qubit gates gates
qgd_Variational_Quantum_Eigensolver_Base.py
Go to the documentation of this file.
1 
3 """
4 
5 Created on Fri Jun 26 14:13:26 2020
6 Copyright 2020 Peter Rakyta, Ph.D.
7 
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11 
12  http://www.apache.org/licenses/LICENSE-2.0
13 
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19 
20 @author: Peter Rakyta, Ph.D.
21 
22 """
23 
24 
26 
27 
28 import numpy as np
29 from os import path
30 from squander.variational_quantum_eigensolver.qgd_Variational_Quantum_Eigensolver_Base_Wrapper import qgd_Variational_Quantum_Eigensolver_Base_Wrapper
31 from squander.gates.qgd_Circuit import qgd_Circuit
32 
33 
34 
35 
37 class qgd_Variational_Quantum_Eigensolver_Base(qgd_Variational_Quantum_Eigensolver_Base_Wrapper):
38 
39 
40 
46  def __init__( self, Hamiltonian, qbit_num, config={}, accelerator_num=0):
47 
48 
49  # config
50  if not( type(config) is dict):
51  print("Input parameter config should be a dictionary describing the following hyperparameters:") #TODO
52  return
53 
54 
55  # call the constructor of the wrapper class
56  super(qgd_Variational_Quantum_Eigensolver_Base, self).__init__(Hamiltonian.data, Hamiltonian.indices, Hamiltonian.indptr, qbit_num, config=config, accelerator_num=accelerator_num)
57  self.qbit_num = qbit_num
58 
59 
60 
63  def set_Optimizer(self, alg):
64 
65  super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Optimizer(alg)
66 
67 
69  def Start_Optimization(self):
70 
71  # call the C wrapper function
72  super(qgd_Variational_Quantum_Eigensolver_Base, self).Start_Optimization()
73 
74 
78 
79  return super(qgd_Variational_Quantum_Eigensolver_Base, self).get_Optimized_Parameters()
80 
81 
82 
85  def set_Optimized_Parameters(self, new_params):
86 
87  super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Optimized_Parameters(new_params)
88 
89 
90 
91 # TODO should be deleted!
92  def set_Optimization_Tolerance(self, tolerance):
93 
94  super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Optimization_Tolerance(tolerance)
95 
96 
97 
100  def set_Project_Name(self, project_name):
101 
102  super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Project_Name(project_name)
103 
104 
107  def set_Gate_Structure_from_Binary(self, filename):
108 
109  super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Gate_Structure_From_Binary(filename)
110 
111 
112 
115  def set_Ansatz(self, ansatz_new):
116 
117  super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Ansatz(ansatz_new)
118 
119 
123  def Generate_Circuit(self, layers, inner_blocks=1):
124 
125  super(qgd_Variational_Quantum_Eigensolver_Base, self).Generate_Circuit( layers, inner_blocks )
126 
127 
130  def Optimization_Problem(self, parameters):
131 
132  return super(qgd_Variational_Quantum_Eigensolver_Base, self).Optimization_Problem(parameters)
133 
134 
137  def Optimization_Problem_Grad(self, parameters):
138 
139  return super(qgd_Variational_Quantum_Eigensolver_Base, self).Optimization_Problem_Grad(parameters)
140 
141 
147  def get_Second_Renyi_Entropy(self, parameters=None, input_state=None, qubit_list=None ):
148 
149  qbit_num = self.get_Qbit_Num()
150 
151  qubit_list_validated = list()
152  if isinstance(qubit_list, list) or isinstance(qubit_list, tuple):
153  for item in qubit_list:
154  if isinstance(item, int):
155  qubit_list_validated.append(item)
156  qubit_list_validated = list(set(qubit_list_validated))
157  else:
158  print("Elements of qbit_list should be integers")
159  return
160  elif qubit_list == None:
161  qubit_list_validated = [ x for x in range(qbit_num) ]
162 
163  else:
164  print("Elements of qbit_list should be integers")
165  return
166 
167 
168  if parameters is None:
169  print( "get_Second_Renyi_entropy: array of input parameters is None")
170  return None
171 
172 
173  if input_state is None:
174  matrix_size = 1 << qbit_num
175  input_state = np.zeros( (matrix_size,1) )
176  input_state[0] = 1
177 
178  # evaluate the entropy
179  entropy = super(qgd_Variational_Quantum_Eigensolver_Base, self).get_Second_Renyi_Entropy( parameters, input_state, qubit_list_validated)
180 
181 
182  return entropy
183 
184 
185 
188  def get_Qbit_Num(self):
189 
190  return super(qgd_Variational_Quantum_Eigensolver_Base, self).get_Qbit_Num()
191 
192 
193 
195  def get_Parameter_Num( self ):
196 
197  return super(qgd_Variational_Quantum_Eigensolver_Base, self).get_Parameter_Num()
198 
199 
200 
201 #@brief Call to apply the gate operation on the input state
202 #@param parameters_mtx Python array ontaining the parameter set
203 #@param state_to_be_transformed Numpy array storing the state on which the transformation should be applied
204  def apply_to( self, parameters_mtx, state_to_be_transformed):
205 
206  # call the C wrapper function
207  super().apply_to( parameters_mtx, state_to_be_transformed )
208 
209 
210 
213  def get_Circuit( self ):
214 
215  # call the C wrapper function
216  return super().get_Circuit()
217 
218 
219 
220 
224 
225  from squander import Qiskit_IO
226 
227  squander_circuit = self.get_Circuit()
228  parameters = self.get_Optimized_Parameters()
229 
230  return Qiskit_IO.get_Qiskit_Circuit( squander_circuit, parameters )
231 
232 
233 
235  def set_Initial_State( self, initial_state ):
236 
237  super(qgd_Variational_Quantum_Eigensolver_Base, self).set_Initial_State( initial_state )
238 
239 
240 
243  def set_Gate_Structure( self, Gate_structure ):
244 
245  if not isinstance(Gate_structure, qgd_Circuit) :
246  raise Exception("Input parameter Gate_structure should be a an instance of Circuit")
247 
248 
249  return super().set_Gate_Structure( Gate_structure )
250 
251 
252 
def get_Optimized_Parameters(self)
Call to get the optimized parameters set in numpy array.
def get_Parameter_Num(self)
Call to get the number of free parameters in the gate structure used for the decomposition.
def set_Gate_Structure_from_Binary(self, filename)
Call to set custom layers to the gate structure that are intended to be used in the decomposition fro...
def set_Initial_State(self, initial_state)
Call to get the number of free parameters in the gate structure used for the decomposition.
def __init__(self, Hamiltonian, qbit_num, config={}, accelerator_num=0)
Constructor of the class.
def get_Circuit(self)
Call to retrieve the incorporated quantum circuit (Squander format)
def set_Gate_Structure(self, Gate_structure)
Call to set custom gate structure to used in the decomposition.
def set_Optimized_Parameters(self, new_params)
Call to set the parameters which are used as a starting point in the optimization.
def Start_Optimization(self)
Call to start solving the VQE problem to get the approximation for the ground state.
def get_Second_Renyi_Entropy(self, parameters=None, input_state=None, qubit_list=None)
Call to get the second Rényi entropy.
def set_Project_Name(self, project_name)
Call to set the name of the SQUANDER project.
def set_Gate_Structure_From_Binary(self, filename)
Call to set custom layers to the gate structure that are intended to be used in the decomposition fro...
def Generate_Circuit(self, layers, inner_blocks=1)
Call to generate the circuit ansatz.