24 #include "../density_matrix/include/density_matrix.h" 25 #include "../density_matrix/include/noisy_circuit.h" 27 #include "../../gates/include/H.h" 28 #include "../../gates/include/SDG.h" 30 #include <nlohmann/json.hpp> 42 const char *VQE_BACKEND_MODE_CONFIG_KEY =
"backend_mode";
47 return "local_depolarizing";
49 return "amplitude_damping";
51 return "phase_damping";
53 return "unknown_density_noise";
59 switch (circuit_source) {
63 return "generated_hea";
65 return "generated_hea_zyz";
67 return "binary_import";
69 return "custom_gate_structure";
71 return "unknown_circuit_source";
76 parse_vqe_backend_mode(std::map<std::string, Config_Element> &
config) {
79 if (config.count(VQE_BACKEND_MODE_CONFIG_KEY) > 0) {
80 config[VQE_BACKEND_MODE_CONFIG_KEY].get_property(backend_mode_value);
83 switch (backend_mode_value) {
90 "Variational_Quantum_Eigensolver_Base::Variational_Quantum_Eigensolver_" 91 "Base: unsupported backend_mode value");
139 const std::vector<DensityNoiseSpec> &density_noise_specs_in) {
141 for (
const auto &
spec : density_noise_specs_in) {
143 throw std::string(
"Variational_Quantum_Eigensolver_Base::set_density_" 144 "noise_specs: target_qbit out of range");
147 if (
spec.after_gate_index < 0) {
148 throw std::string(
"Variational_Quantum_Eigensolver_Base::set_density_" 149 "noise_specs: after_gate_index must be non-negative");
152 if (
spec.value < 0.0 ||
spec.value > 1.0) {
153 throw std::string(
"Variational_Quantum_Eigensolver_Base::set_density_" 154 "noise_specs: noise values must be in [0, 1]");
172 std::vector<DensityBridgeOperationInfo>
177 std::vector<DensityBridgeOperationInfo> info;
182 for (
int gate_idx = 0; gate_idx < gate_num; ++gate_idx) {
195 info.push_back(gate_info);
200 if (
spec.after_gate_index != gate_idx) {
205 noise_info.
name = density_noise_type_to_label(
spec.type);
214 info.push_back(noise_info);
222 bool require_optimizer_support,
bool require_gradient_support) {
226 throw std::string(
"Variational_Quantum_Eigensolver_Base::validate_" 227 "density_anchor_support: state_vector backend does not " 228 "support density_matrix-only noise configuration");
236 throw std::string(
"Variational_Quantum_Eigensolver_Base::validate_density_" 237 "anchor_support: density_matrix backend requires a " 238 "square Hamiltonian matching the configured qubit count");
241 if (require_gradient_support) {
243 "Variational_Quantum_Eigensolver_Base::validate_density_anchor_support:" 244 " density_matrix backend does not support gradient-based optimization");
249 "Variational_Quantum_Eigensolver_Base::validate_density_anchor_support:" 250 " density_matrix backend currently supports only the HEA ansatz");
254 throw std::string(
"Variational_Quantum_Eigensolver_Base::validate_density_" 255 "anchor_support: density_matrix backend currently " 256 "supports only BAYES_OPT or COSINE optimization traces");
261 "Variational_Quantum_Eigensolver_Base::validate_density_anchor_support:" 262 " density_matrix backend requires a generated HEA circuit");
267 "Variational_Quantum_Eigensolver_Base::validate_density_anchor_support:" 268 " unsupported circuit source in density backend path: ");
276 "Variational_Quantum_Eigensolver_Base::validate_density_anchor_support:" 277 " density_matrix backend requires a generated HEA circuit");
280 for (
int gate_idx = 0; gate_idx < gate_num; ++gate_idx) {
288 "Variational_Quantum_Eigensolver_Base::validate_density_anchor_" 289 "support: first unsupported gate in density backend path is ");
298 if (
spec.after_gate_index >= gate_num) {
300 "Variational_Quantum_Eigensolver_Base::validate_density_anchor_" 301 "support: unsupported density-noise insertion at index ");
302 error += std::to_string(spec_idx);
303 error +=
" because after_gate_index exceeds generated gate count";
313 if (
spec.after_gate_index != gate_index) {
329 "Variational_Quantum_Eigensolver_Base::append_density_noise_for_gate_" 330 "index: unsupported density-noise type ");
331 error += density_noise_type_to_label(
spec.type);
345 for (
int gate_idx = 0; gate_idx < gate_num; ++gate_idx) {
357 "Variational_Quantum_Eigensolver_Base::lower_anchor_circuit_to_noisy_" 358 "circuit: unsupported gate in density backend path: ");
373 throw std::string(
"Variational_Quantum_Eigensolver_Base::expectation_value_" 374 "of_density_energy_real: dimension mismatch");
377 double energy_real = 0.0;
389 if (!std::isfinite(energy_real)) {
390 throw std::string(
"Variational_Quantum_Eigensolver_Base::expectation_value_" 391 "of_density_energy_real: produced a non-finite energy");
424 false, config_in,
RANDOM, accelerator_num) {
454 std::random_device rd;
456 gen = std::mt19937(rd());
483 if (
gates.size() == 0) {
484 std::string error(
"Variational_Quantum_Eigensolver_Base::Get_ground_state: " 485 "for VQE process the circuit needs to be initialized");
490 if (num_of_parameters == 0) {
491 std::string error(
"Variational_Quantum_Eigensolver_Base::Get_ground_state: " 492 "No intial parameters were given");
497 std::string error(
"Variational_Quantum_Eigensolver_Base::Get_ground_state: " 498 "The number of initial parameters does not match with " 499 "the number of parameters in the circuit");
525 if (State_left.
rows != State_right.
rows ||
527 std::string error(
"Variational_Quantum_Eigensolver_Base::Expectation_value_" 528 "of_energy: States on the right and left should be of " 529 "the same dimension as the Hamiltonian");
538 tbb::combinable<double> priv_partial_energy_real{[]() {
return 0.0; }};
539 tbb::combinable<double> priv_partial_energy_imag{[]() {
return 0.0; }};
542 tbb::blocked_range<int>(0, State_left.
rows, 1024),
543 [&](tbb::blocked_range<int> r) {
544 double &energy_local_real = priv_partial_energy_real.local();
545 double &energy_local_imag = priv_partial_energy_imag.local();
547 for (int idx = r.begin(); idx < r.end(); idx++) {
548 energy_local_real += State_left[idx].real * tmp[idx].real +
549 State_left[idx].imag * tmp[idx].imag;
550 energy_local_imag += State_left[idx].real * tmp[idx].imag -
551 State_left[idx].imag * tmp[idx].real;
556 priv_partial_energy_real.combine_each(
557 [&Energy](
double a) { Energy.real = Energy.real + a; });
559 priv_partial_energy_imag.combine_each(
560 [&Energy](
double a) { Energy.imag = Energy.imag + a; });
566 tbb::spin_mutex::scoped_lock my_lock{
my_mutex};
587 if (State_left.
rows != State_right.
rows ||
589 std::string error(
"Variational_Quantum_Eigensolver_Base::Expectation_value_" 590 "of_energy_real: States on the right and left should be " 591 "of the same dimension as the Hamiltonian");
598 tbb::combinable<double> priv_partial_energy{[]() {
return 0.0; }};
600 tbb::parallel_for(tbb::blocked_range<int>(0, State_left.
rows, 1024),
601 [&](tbb::blocked_range<int> r) {
602 double &energy_local = priv_partial_energy.local();
604 for (int idx = r.begin(); idx < r.end(); idx++) {
605 energy_local += State_left[idx].real * tmp[idx].real +
606 State_left[idx].imag * tmp[idx].imag;
611 priv_partial_energy.combine_each(
612 [&Energy](
double a) { Energy = Energy + a; });
618 tbb::spin_mutex::scoped_lock my_lock{
my_mutex};
701 "Expectation_value_with_shot_noise_real: dimension mismatch");
704 const int N = State.
rows;
705 const int n_qubits =
static_cast<int>(std::round(std::log2(N)));
706 if ((1 << n_qubits) !=
N) {
708 "Expectation_value_with_shot_noise_real: State.rows not power of two");
714 std::vector<double> probsZ(N);
716 for (
int idx = 0; idx <
N; ++idx) {
717 double re = State[idx].real;
718 double im = State[idx].imag;
719 double p = re * re + im * im;
723 if (std::abs(sum_pZ - 1.0) > 1e-6) {
725 for (
auto &v : probsZ)
728 for (
auto &v : probsZ)
732 std::mt19937_64 rng(seed ? seed : std::random_device{}());
733 std::discrete_distribution<int> distZ(probsZ.begin(), probsZ.end());
734 std::uniform_real_distribution<double> unif01(0.0, 1.0);
741 std::discrete_distribution<int>
747 std::vector<bool> need_H(n_qubits,
false);
751 std::tie(i, j, coeff) = t;
752 if (i < 0 || i >= n_qubits || j < 0 || j >= n_qubits) {
753 throw std::string(
"XX term index out of range in " 754 "Expectation_value_with_shot_noise_real");
763 for (
int q = 0; q < n_qubits; ++q) {
765 H h_gate(n_qubits, q);
771 std::vector<double> probsX(N);
773 for (
int idx = 0; idx <
N; ++idx) {
774 double re = psi_rot[idx].real;
775 double im = psi_rot[idx].imag;
776 double p = re * re + im * im;
781 throw std::string(
"X-rotated state has zero norm in " 782 "Expectation_value_with_shot_noise_real");
784 for (
auto &v : probsX)
788 distX = std::discrete_distribution<int>(probsX.begin(), probsX.end());
797 std::discrete_distribution<int>
803 std::vector<bool> need_SDG_H(n_qubits,
false);
807 std::tie(i, j, coeff) = t;
808 if (i < 0 || i >= n_qubits || j < 0 || j >= n_qubits) {
809 throw std::string(
"YY term index out of range in " 810 "Expectation_value_with_shot_noise_real");
812 need_SDG_H[i] =
true;
813 need_SDG_H[j] =
true;
820 for (
int q = 0; q < n_qubits; ++q) {
823 SDG sdg_gate(n_qubits, q);
826 H h_gate(n_qubits, q);
833 std::vector<double> probsY(N);
835 for (
int idx = 0; idx <
N; ++idx) {
836 double re = psi_rot_y[idx].real;
837 double im = psi_rot_y[idx].imag;
838 double p = re * re + im * im;
843 throw std::string(
"Y-rotated state has zero norm in " 844 "Expectation_value_with_shot_noise_real");
846 for (
auto &v : probsY)
850 distY = std::discrete_distribution<int>(probsY.begin(), probsY.end());
863 for (
int s = 0; s <
shots; ++s) {
868 int idx = distZ(rng);
870 if (p_readout > 0.0) {
872 for (
int q = 0; q < n_qubits; ++q) {
873 if (unif01(rng) < p_readout) {
874 observed ^= (1 << q);
884 std::tie(i, j, coeff) = t;
886 const int zi = ((idx >> i) & 1) ? -1 : +1;
887 const int zj = ((idx >> j) & 1) ? -1 : +1;
888 E += coeff * (zi * zj);
892 for (
const auto &z :
z_terms) {
893 const int i = z.first;
894 const double h = z.second;
895 const int zi = ((idx >> i) & 1) ? -1 : +1;
901 int idx_x = distX(rng);
903 if (p_readout > 0.0) {
904 int observed = idx_x;
905 for (
int q = 0; q < n_qubits; ++q) {
906 if (unif01(rng) < p_readout) {
907 observed ^= (1 << q);
917 std::tie(i, j, coeff) = t;
919 const int xi = ((idx_x >> i) & 1) ? -1 : +1;
920 const int xj = ((idx_x >> j) & 1) ? -1 : +1;
921 E += coeff * (xi * xj);
927 int idx_y = distY(rng);
929 if (p_readout > 0.0) {
930 int observed = idx_y;
931 for (
int q = 0; q < n_qubits; ++q) {
932 if (unif01(rng) < p_readout) {
933 observed ^= (1 << q);
943 std::tie(i, j, coeff) = t;
945 const int yi = ((idx_y >> i) & 1) ? -1 : +1;
946 const int yj = ((idx_y >> j) & 1) ? -1 : +1;
947 E += coeff * (yi * yj);
955 const double mean = sum /
static_cast<double>(
shots);
956 const double mean_sq = sum_sq /
static_cast<double>(
shots);
957 double variance = mean_sq - mean * mean;
958 if (variance < 0.0 && variance > -1e-12) {
961 const double std_error =
962 (variance > 0.0) ? std::sqrt(variance / static_cast<double>(shots)) : 0.0;
965 tbb::spin_mutex::scoped_lock my_lock{
my_mutex};
969 return {mean, variance, std_error};
999 instance->
apply_to(parameters, State);
1014 double Variational_Quantum_Eigensolver_Base::optimization_problem_Groq(
1022 std::vector<Matrix> u3_qbit;
1023 extract_gate_kernels_target_and_control_qubits(u3_qbit, target_qbits,
1024 control_qbits, parameters);
1031 target_qbits, control_qbits, State_zero,
id);
1040 target_qbits, control_qbits, State,
id);
1102 return optimization_problem_Groq(parameters, 0);
1133 void *void_instance,
double *f0,
1146 int parameter_num_loc = parameters.
size();
1151 std::vector<Matrix> State_deriv;
1156 tbb::parallel_invoke(
1159 instance->
apply_to(parameters, State);
1170 tbb::parallel_for(tbb::blocked_range<int>(0, parameter_num_loc, 2),
1171 [&](tbb::blocked_range<int> r) {
1172 for (
int idx = r.begin(); idx < r.end(); ++idx) {
1175 State_deriv[idx], State);
1255 int initialize_state;
1256 if (
config.count(
"initialize_state") > 0) {
1258 config[
"initialize_state"].get_property(value);
1259 initialize_state = (
int)value;
1261 initialize_state = 1;
1264 if (initialize_state == 0) {
1311 "Variational_Quantum_Eigensolver_Base::generate_initial_circuit: " 1312 "number of qubits should be at least 1");
1317 for (
int layer_idx = 0; layer_idx <
layers; layer_idx++) {
1327 for (
int layer_idx = 0; layer_idx <
layers; layer_idx++) {
1365 "Variational_Quantum_Eigensolver_Base::generate_initial_circuit: " 1366 "number of qubits should be at least 2");
1370 for (
int layer_idx = 0; layer_idx <
layers; layer_idx++) {
1440 std::string error(
"Variational_Quantum_Eigensolver_Base::generate_initial_" 1441 "circuit: ansatz not implemented");
1454 if (
gates.size() > 0) {
1455 gate_structure_tmp->
combine(static_cast<Gates_block *>(
this));
1463 memcpy(optimized_parameters_mtx_tmp2.get_data(),
1464 optimized_parameters_mtx_tmp.
get_data(),
1465 optimized_parameters_mtx_tmp.
size() *
sizeof(double));
1466 memcpy(optimized_parameters_mtx_tmp2.get_data() +
1467 optimized_parameters_mtx_tmp.
size(),
1475 std::stringstream sstream;
1479 for (
auto it = gate_nums.begin(); it != gate_nums.end(); it++) {
1480 sstream << it->second <<
" " << it->first <<
" gates" << std::endl;
1500 Matrix initial_state_in) {
1504 std::string error(
"Variational_Quantum_Eigensolver_Base::set_initial_state:" 1505 " teh number of elements in the input state does not " 1506 "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 apply_to_groq_sv(int reserved_device_num, int chosen_device_num, int qbit_num, std::vector< Matrix > &u3_qbit, std::vector< int > &target_qbits, std::vector< int > &control_qbits, Matrix &quantum_state, int id_in)
Call to pefrom the state vector simulation on the Groq hardware.
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)
vqe_circuit_source_type circuit_source
Provenance of the currently configured circuit.
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
ansatz_type
Type definition of the fifferent types of ansatz.
std::vector< std::tuple< int, int, double > > yy_terms
Coupling terms of the form coeff * Y_i * Y_j.
bool decomposition_finalized
The optimized parameters for the gates.
std::vector< std::pair< int, double > > z_terms
Local magnetic field terms of the form coeff * Z_i.
std::map< std::string, int > get_gate_nums()
Call to get the number of the individual gate types in the list of gates.
void add_CNOT(int target, int control)
SimulationResult Expectation_value_with_shot_noise_real(Matrix &State, int shots, uint64_t seed, double p_readout)
Evaluate the expectation value of the energy with simulated shot noise and readout error...
void add_local_depolarizing(int target)
Add parametric local single-qubit depolarizing noise (1 parameter)
Class to solve VQE problems.
double expectation_value_of_density_energy_real(const squander::density::DensityMatrix &rho) const
void set_custom_gate_structure(Gates_block *gate_structure_in)
Call to set custom layers to the gate structure that are intended to be used in the subdecomposition...
std::vector< int > target_qbits
Vector of target qubit indices (for multi-qubit gates)
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...
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.
void add_phase_damping(int target)
Add parametric phase damping noise (1 parameter)
std::vector< std::tuple< int, int, double > > zz_terms
Coupling terms of the form coeff * Z_i * Z_j.
cost_function_type cost_fnc
The chosen variant of the cost function.
Variational_Quantum_Eigensolver_Base()
Nullary constructor of the class.
void apply_to(const double *params, int param_count, DensityMatrix &rho)
Apply entire circuit to density matrix.
Reviewable metadata describing one lowered density-bridge operation.
void release_gates()
Call to release the stored gates.
vqe_backend_type
Supported execution backends for the VQE workflow contract.
static tbb::spin_mutex my_mutex
void release_data()
Call to release the data stored by the matrix.
std::atomic< int > number_of_iters
number of iterations
std::vector< DensityBridgeOperationInfo > inspect_density_bridge()
Describe the supported density bridge for the current VQE instance.
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.
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)
Use to import a quantum circuit from a binary format.
int get_gate_num()
Call to get the number of gates grouped in the class.
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.
void add_U3(int target)
3 parameters
double evaluate_density_matrix_backend(Matrix_real ¶meters)
double optimization_tolerance
The maximal allowed error of the optimization problem (The error of the decomposition would scale wit...
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 lower_anchor_circuit_to_noisy_circuit(squander::density::NoisyCircuit &circuit)
vqe_backend_type backend_mode
Effective execution backend selected for this VQE instance.
void start_optimization()
Call to start solving the VQE problem to get the approximation for the ground state.
void set_density_noise_specs(const std::vector< DensityNoiseSpec > &density_noise_specs_in)
Configure ordered fixed local-noise insertions for the density backend.
double convergence_threshold
The convergence threshold in the optimization process.
gate_type get_type()
Call to get the type of the operation.
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.
Quantum density matrix Ï for mixed-state representation.
std::string get_density_bridge_source_label() const
Return the current circuit-source label used by bridge inspection.
virtual void apply_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel=0) override
Call to apply the gate on the input array/matrix Gates_block*input.
Container for statistics returned by shot-noise simulations.
density_noise_type
Supported local noise channels.
void append_density_noise_for_gate_index(squander::density::NoisyCircuit &circuit, int gate_index) const
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...
void set_ansatz(ansatz_type ansatz_in)
Call to set the ansatz type.
Matrix copy() const
Call to create a copy of the matrix.
int Power_of_2(int n)
Calculates the n-th power of 2.
Double-precision complex matrix (float64).
int size() const
Call to get the number of the allocated elements.
std::vector< int > control_qbits
Vector of control qubit indices (for multi-qubit gates)
Gates_block()
Default constructor of the class.
virtual int get_parameter_num()
Call to get the number of free parameters.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
Matrix_sparse Hamiltonian
The Hamiltonian of the system.
int get_target_qbit()
Call to get the index of the target qubit.
std::map< std::string, Config_Element > config
config metadata utilized during the optimization
Base class for the representation of general gate operations.
bool density_optimizer_supported() const
std::string get_name()
Call to get the name label of the gate.
int get_dim() const
Get matrix dimension (2^qbit_num)
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...
volatile double current_minimum
The current minimum of the optimization problem.
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>.
std::vector< std::tuple< int, int, double > > xx_terms
Coupling terms of the form coeff * X_i * X_j.
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
vqe_circuit_source_type
Provenance of the active VQE circuit used for backend validation.
std::vector< DensityNoiseSpec > density_noise_specs
Ordered fixed local-noise insertions for the density backend.
double decomposition_error
error of the final decomposition
Gate * get_gate(int idx)
Call to get the gates stored in the class.
Quantum circuit with noise for density matrix simulation.
virtual void apply_to(Matrix &input, int parallel)
Call to apply the gate on the input array/matrix.
int random_shift_count_max
the maximal number of parameter randomization tries to escape a local minimum.
void add_amplitude_damping(int target)
Add parametric amplitude damping noise (1 parameter)
Matrix_real optimized_parameters_mtx
The optimized parameters for the gates.
int get_parallel_configuration()
Get the parallel configuration from the config.
int get_parameter_num() override
Call to get the number of free parameters.
void set_custom_gate_structure(Gates_block *gate_structure_in)
Call to set custom gate structure for VQE experiments.
double global_target_minimum
The global target minimum of the optimization problem.
int get_control_qbit()
Call to get the index of the control qubit.
Class to store data of complex arrays and its properties.
void validate_density_anchor_support(bool require_optimizer_support=false, bool require_gradient_support=false)
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()
virtual std::vector< Matrix > apply_derivate_to(Matrix_real ¶meters_mtx, Matrix &input, int parallel) override
Call to evaluate the derivate of the circuit on an inout with respect to all of the free parameters...
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.