77 Variational_Quantum_Eigensolver_Base::Variational_Quantum_Eigensolver_Base(
Matrix_sparse Hamiltonian_in,
int qbit_num_in, std::map<std::string, Config_Element>& config_in,
int accelerator_num) :
Optimization_Interface(
Matrix(
Power_of_2(qbit_num_in),1), qbit_num_in, false, config_in,
RANDOM, accelerator_num) {
112 std::random_device rd;
114 gen = std::mt19937(rd());
148 if (
gates.size() == 0 ) {
149 std::string error(
"Variational_Quantum_Eigensolver_Base::Get_ground_state: for VQE process the circuit needs to be initialized");
154 if ( num_of_parameters == 0 ) {
155 std::string error(
"Variational_Quantum_Eigensolver_Base::Get_ground_state: No intial parameters were given");
161 std::string error(
"Variational_Quantum_Eigensolver_Base::Get_ground_state: The number of initial parameters does not match with the number of parameters in the circuit");
186 std::string error(
"Variational_Quantum_Eigensolver_Base::Expectation_value_of_energy: States on the right and left should be of the same dimension as the Hamiltonian");
196 tbb::combinable<double> priv_partial_energy_real{[](){
return 0.0;}};
197 tbb::combinable<double> priv_partial_energy_imag{[](){
return 0.0;}};
199 tbb::parallel_for( tbb::blocked_range<int>(0, State_left.
rows, 1024), [&](tbb::blocked_range<int> r) {
201 double& energy_local_real = priv_partial_energy_real.local();
202 double& energy_local_imag = priv_partial_energy_imag.local();
204 for (int idx=r.begin(); idx<r.end(); idx++){
205 energy_local_real += State_left[idx].real*tmp[idx].real + State_left[idx].imag*tmp[idx].imag;
206 energy_local_imag += State_left[idx].real*tmp[idx].imag - State_left[idx].imag*tmp[idx].real;
212 priv_partial_energy_real.combine_each([&Energy](
double a) {
213 Energy.real = Energy.real + a;
216 priv_partial_energy_imag.combine_each([&Energy](
double a) {
217 Energy.imag = Energy.imag + a;
224 tbb::spin_mutex::scoped_lock my_lock{
my_mutex};
244 std::string error(
"Variational_Quantum_Eigensolver_Base::Expectation_value_of_energy_real: States on the right and left should be of the same dimension as the Hamiltonian");
252 tbb::combinable<double> priv_partial_energy{[](){
return 0.0;}};
254 tbb::parallel_for( tbb::blocked_range<int>(0, State_left.
rows, 1024), [&](tbb::blocked_range<int> r) {
256 double& energy_local = priv_partial_energy.local();
258 for (int idx=r.begin(); idx<r.end(); idx++){
259 energy_local += State_left[idx].real*tmp[idx].real + State_left[idx].imag*tmp[idx].imag;
265 priv_partial_energy.combine_each([&Energy](
double a) {
273 tbb::spin_mutex::scoped_lock my_lock{
my_mutex};
299 instance->
apply_to(parameters, State);
313 double Variational_Quantum_Eigensolver_Base::optimization_problem_Groq(
Matrix_real&
parameters,
int chosen_device) {
321 std::vector<int> target_qbits;
322 std::vector<int> control_qbits;
323 std::vector<Matrix> u3_qbit;
324 extract_gate_kernels_target_and_control_qubits(u3_qbit, target_qbits, control_qbits, parameters);
331 apply_to_groq_sv(
accelerator_num, chosen_device,
qbit_num, u3_qbit, target_qbits, control_qbits, State_zero,
id);
402 return optimization_problem_Groq( parameters, 0 );
446 int parameter_num_loc = parameters.
size();
451 std::vector<Matrix> State_deriv;
456 tbb::parallel_invoke(
459 instance->
apply_to(parameters, State);
470 tbb::parallel_for( tbb::blocked_range<int>(0,parameter_num_loc,2), [&](tbb::blocked_range<int> r) {
471 for (
int idx=r.begin(); idx<r.end(); ++idx) {
558 int initialize_state;
559 if (
config.count(
"initialize_state") > 0 ) {
561 config[
"initialize_state"].get_property( value );
562 initialize_state = (
int) value;
565 initialize_state = 1;
569 if( initialize_state == 0 ) {
623 std::string error(
"Variational_Quantum_Eigensolver_Base::generate_initial_circuit: number of qubits should be at least 2");
627 for (
int layer_idx=0; layer_idx<
layers ;layer_idx++){
668 std::string error(
"Variational_Quantum_Eigensolver_Base::generate_initial_circuit: number of qubits should be at least 2");
672 for (
int layer_idx=0; layer_idx<
layers ;layer_idx++){
743 std::string error(
"Variational_Quantum_Eigensolver_Base::generate_initial_circuit: ansatz not implemented");
756 if (
gates.size() > 0 ) {
757 gate_structure_tmp->
combine( static_cast<Gates_block*>(
this) );
764 memcpy( optimized_parameters_mtx_tmp2.get_data(), optimized_parameters_mtx_tmp.
get_data(), optimized_parameters_mtx_tmp.
size()*
sizeof(double) );
772 std::stringstream sstream;
776 for(
auto it=gate_nums.begin(); it != gate_nums.end(); it++ ) {
777 sstream << it->second <<
" " << it->first <<
" gates" << std::endl;
797 std::string error(
"Variational_Quantum_Eigensolver_Base::set_initial_state: teh number of elements in the input state does not match with the number of qubits.");
optimization_aglorithms alg
The optimization algorithm to be used in the optimization.
bool adaptive_eta
logical variable indicating whether adaptive learning reate is used in the ADAM algorithm ...
void set_gate_structure(std::string filename)
Call to set custom layers to the gate structure that are intended to be used in the VQE process...
ansatz_type ansatz
Ansatz type (HEA stands for hardware efficient ansatz)
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
bool decomposition_finalized
The optimized parameters for the gates.
std::map< std::string, int > get_gate_nums()
Call to get the number of the individual gate types in the list of gates.
Class to solve VQE problems.
Matrix_real copy() const
Call to create a copy of the matrix.
int control_qbit
The index of the qubit which acts as a control qubit (control_qbit >= 0) in controlled operations...
double current_minimum
The current minimum of the optimization problem.
bool optimization_problem_solved
logical value describing whether the optimization problem was solved or not
void add_gate(Gate *gate)
Append a general gate to the list of gates.
cost_function_type cost_fnc
The chosen variant of the cost function.
Variational_Quantum_Eigensolver_Base()
Nullary constructor of the class.
void release_gates()
Call to release the stored gates.
void release_data()
Call to release the data stored by the matrix.
void add_cnot(int target_qbit, int control_qbit)
Append a CNOT gate gate to the list of gates.
QGD_Complex16 mult(QGD_Complex16 &a, QGD_Complex16 &b)
Call to calculate the product of two complex scalars.
Class to store data of complex arrays and its properties.
virtual void apply_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel=0)
Call to apply the gate on the input array/matrix Gates_block*input.
scalar * get_data() const
Call to get the pointer to the stored data.
virtual void optimization_problem_combined(Matrix_real parameters, double *f0, Matrix_real grad) override
Call to calculate both the cost function and the its gradient components.
Matrix initial_state
Quantum state used as an initial state in the VQE iterations.
Gates_block * import_gate_list_from_binary(Matrix_real ¶meters, const std::string &filename, int verbosity)
?????????
virtual double optimization_problem_non_static(Matrix_real parameters, void *void_instance) override
The optimization problem of the final optimization.
std::vector< Gate * > gates
The list of stored gates.
void generate_circuit(int layers, int inner_blocks)
Call to generate the circuit ansatz.
double optimization_tolerance
The maximal allowed error of the optimization problem (The error of the decomposition would scale wit...
int get_parameter_num()
Call to get the number of free parameters.
static void optimization_problem_grad_vqe(Matrix_real parameters, void *void_instance, Matrix_real &grad)
Calculate the derivative of the cost function with respect to the free parameters.
int accelerator_num
number of utilized accelerators
int rows
The number of rows.
void start_optimization()
Call to start solving the VQE problem to get the approximation for the ground state.
double convergence_threshold
The convergence threshold in the optimization process.
int number_of_iters
number of iterations
ansatz_type
Type definition of the fifferent types of ansatz.
void add_u3(int target_qbit)
Append a U3 gate to the list of gates.
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
void add_rz(int target_qbit)
Append a RZ gate to the list of gates.
QGD_Complex16 Expectation_value_of_energy(Matrix &State_left, Matrix &State_right)
Call to evaluate the expectation value of the energy <State_left| H | State_right>.
virtual void optimization_problem_combined_non_static(Matrix_real parameters, void *void_instance, double *f0, Matrix_real &grad) override
Call to calculate both the cost function and the its gradient components.
void combine(Gates_block *op_block)
Call to append the gates of an gate block to the current block.
void add_ry(int target_qbit)
Append a RY gate to the list of gates.
Structure type representing complex numbers in the SQUANDER package.
void set_initial_state(Matrix initial_state_in)
Call to set the initial quantum state in the VQE iterations.
A base class to solve VQE problems This class can be used to approximate the ground state of the inpu...
virtual std::vector< Matrix > apply_derivate_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel)
Call to evaluate the derivate of the circuit on an inout with respect to all of the free parameters...
void set_ansatz(ansatz_type ansatz_in)
Call to set the ansatz type.
int Power_of_2(int n)
Calculates the n-th power of 2.
Class to store data of complex arrays and its properties.
int size() const
Call to get the number of the allocated elements.
Gates_block()
Default constructor of the class.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
Matrix_sparse Hamiltonian
The Hamiltonian of the system.
std::map< std::string, Config_Element > config
config metadata utilized during the optimization
int parameter_num
the number of free parameters of the operation
void solve_layer_optimization_problem(int num_of_parameters, Matrix_real solution_guess)
Call to solve layer by layer the optimization problem via calling one of the implemented algorithms...
Matrix copy()
Call to create a copy of the matrix.
double Expectation_value_of_energy_real(Matrix &State_left, Matrix &State_right)
Call to evaluate the expectation value of the energy <State_left| H | State_right>.
double real
the real part of a complex number
void initialize_zero_state()
Initialize the state used in the quantun circuit.
int qbit_num
number of qubits spanning the matrix of the operation
double decomposition_error
error of the final decomposition
int random_shift_count_max
the maximal number of parameter randomization tries to escape a local minimum.
Matrix_real optimized_parameters_mtx
The optimized parameters for the gates.
int get_parallel_configuration()
Get the parallel configuration from the config.
double global_target_minimum
The global target minimum of the optimization problem.
Class to store data of complex arrays and its properties.
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()
double imag
the imaginary part of a complex number
virtual ~Variational_Quantum_Eigensolver_Base()
Destructor of the class.
virtual double optimization_problem(Matrix_real ¶meters) override
The optimization problem of the final optimization.