38 #include <tbb/enumerable_thread_specific.h> 39 #include <tbb/tick_count.h> 41 extern "C" int LAPACKE_dgesv(
int matrix_layout,
int n,
int nrhs,
double *a,
int lda,
int *ipiv,
double *b,
int ldb);
154 max_layer_num.insert( std::pair<int, int>(it->first, it->second) );
179 std::uniform_int_distribution<> distrib_int(0, INT_MAX);
180 id = distrib_int(
gen);
192 #elif defined __GROQ__ 223 max_layer_num.insert( std::pair<int, int>(it->first, it->second) );
246 std::uniform_int_distribution<> distrib_int(0, INT_MAX);
247 id = distrib_int(
gen);
257 #elif defined __GROQ__ 292 if (
this == &other ) {
296 Decomposition_Base::operator=(other);
346 std::string
filename(
"costfuncs_and_entropy.txt");
352 const char* c_filename = filename.c_str();
354 errno_t err = fopen_s(&pFile, c_filename,
"a");
359 pFile = fopen(c_filename,
"a");
363 fputs (
"File error",stderr);
364 std::string error(
"Cannot open file.");
370 std::uniform_int_distribution<> distrib(0,
qbit_num-2);
372 memset(input_state.
get_data(), 0, (input_state.
size()*2)*
sizeof(
double) );
373 input_state[0].real = 1.0;
415 for (
int qbit=0; qbit<
qbit_num; qbit++) {
454 double d = 1.0/decomposed_matrix.
cols;
460 double d = 1.0/decomposed_matrix.
cols;
474 std::string err(
"Optimization_Interface::optimization_problem: Cost function variant not implmented.");
488 std::stringstream sstream;
489 sstream <<
"***************************************************************" << std::endl;
490 sstream <<
"Final fine tuning of the parameters in the " <<
qbit_num <<
"-qubit decomposition" << std::endl;
491 sstream <<
"***************************************************************" << std::endl;
557 std::string error(
"Optimization_Interface::solve_layer_optimization_problem: unimplemented optimization algorithm");
579 std::uniform_real_distribution<> distrib_prob(0.0, 1.0);
580 std::uniform_real_distribution<> distrib_real(-2*
M_PI, 2*
M_PI);
584 if (
config.count(
"Randomized_Radius") > 0 ) {
585 config[
"Randomized_Radius"].get_property( radius_loc );
593 int changed_parameters = 0;
596 output[jdx] = (
cost_fnc!=
VQE) ? input[jdx] + distrib_real(
gen)*std::sqrt(f0)*radius_loc : input[jdx] + distrib_real(
gen)*radius_loc;
597 changed_parameters++;
600 output[jdx] = input[jdx];
638 std::stringstream sstream;
639 sstream <<
"Optimization_Interface::optimization_problem: Number of free paramaters should be " <<
parameter_num <<
", but got " << parameters.
size() << std::endl;
641 std::string err(
"Optimization_Interface::optimization_problem: Wrong number of parameters.");
649 const bool use_float_cost_path =
false;
650 if ( use_float_cost_path &&
use_float ) {
651 static tbb::enumerable_thread_specific<Matrix_real_float> parameters_float_tls;
652 static tbb::enumerable_thread_specific<Matrix_float> matrix_new_tls;
655 parameters.
copy_to(parameters_float);
661 static tbb::enumerable_thread_specific<Matrix> matrix_new_tls;
662 Matrix& matrix_new = matrix_new_tls.local();
689 if ( ret_temp != NULL ) {
691 (*ret_temp)[0].real = trace_temp.
real;
692 (*ret_temp)[0].imag = trace_temp.
imag;
693 double d = 1.0/matrix_new.
cols;
694 return 1 - d*d*(trace_temp.
real*trace_temp.
real + trace_temp.
imag*trace_temp.
imag);
699 double d = 1.0/matrix_new.
cols;
700 if ( ret_temp != NULL ) {
701 for (
int idx=0; idx<3; idx++) {
702 (*ret_temp)[idx].real = ret[idx].real;
703 (*ret_temp)[idx].imag = ret[idx].imag;
709 double d = 1.0/matrix_new.
cols;
710 if ( ret_temp != NULL ) {
711 for (
int idx=0; idx<4; idx++) {
712 (*ret_temp)[idx].real = ret[idx].real;
713 (*ret_temp)[idx].imag = ret[idx].imag;
720 if ( ret_temp != NULL ) {
722 (*ret_temp)[0].real = trace_temp.
real;
723 (*ret_temp)[0].imag = trace_temp.
imag;
724 double d = matrix_new.
cols;
725 return 1.0-((trace_temp.
real*trace_temp.
real+trace_temp.
imag*trace_temp.
imag)/d+1)/(d+1);
731 std::string err(
"Optimization_Interface::optimization_problem: Cost function variant not implmented.");
753 if ( ret_temp != NULL ) {
754 (*ret_temp)[0].real =
static_cast<float>(trace_temp.
real);
755 (*ret_temp)[0].imag =
static_cast<float>(trace_temp.
imag);
757 double d = 1.0/matrix_new.
cols;
758 return 1 - d*d*(trace_temp.
real*trace_temp.
real + trace_temp.
imag*trace_temp.
imag); }
761 if ( ret_temp != NULL ) {
762 (*ret_temp)[0].real =
static_cast<float>(trace_temp.
real);
763 (*ret_temp)[0].imag =
static_cast<float>(trace_temp.
imag);
765 double d = matrix_new.
cols;
766 return 1.0-((trace_temp.
real*trace_temp.
real+trace_temp.
imag*trace_temp.
imag)/d+1)/(d+1); }
777 std::string err(
"Optimization_Interface::calculate_cost_function(Matrix_float&): Cost function variant not implmented.");
790 Optimization_Interface::optimization_problem_batched_DFE( std::vector<Matrix_real>& parameters_vec) {
793 Matrix_real cost_fnc_mtx(parameters_vec.size(), 1);
795 int gatesNum, gateSetNum, redundantGateSets;
796 DFEgate_kernel_type* DFEgates = convert_to_batched_DFE_gates( parameters_vec, gatesNum, gateSetNum, redundantGateSets );
810 int mpi_starting_gateSetIdx = gateSetNum/
world_size * current_rank;
823 int bytes = mpi_trace_DFE_mtx.
size()*
sizeof(double);
824 MPI_Allgather(mpi_trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, MPI_COMM_WORLD);
837 for (
int idx=0; idx<parameters_vec.size(); idx++ ) {
838 cost_fnc_mtx[idx] = 1-trace_DFE_mtx[idx*3]/
Umtx.
cols;
842 for (
int idx=0; idx<parameters_vec.size(); idx++ ) {
847 for (
int idx=0; idx<parameters_vec.size(); idx++ ) {
852 std::string err(
"Optimization_Interface::optimization_problem_batched: Cost function variant not implmented for DFE.");
881 throw std::string(
"Optimization_Interface::optimization_problem_Groq should be implemented in derrived classes.");
895 Optimization_Interface::optimization_problem_batched_Groq( std::vector<Matrix_real>& parameters_vec) {
897 int task_num = parameters_vec.
size();
907 int chosen_device = 0;
909 for(
int idx=0; idx<task_num; idx++ ) {
910 cost_fnc_mtx[idx] = optimization_problem_Groq( parameters_vec[idx], chosen_device );
916 for(
int idx=0; idx<task_num; idx=idx+2 ) {
917 tbb::parallel_invoke(
918 [&]() { cost_fnc_mtx[idx] = optimization_problem_Groq( parameters_vec[idx], 0 ); },
919 [&]() {
if ( (idx+1) < task_num ) cost_fnc_mtx[idx+1] = optimization_problem_Groq( parameters_vec[idx+1], 1 ); }
925 throw std::string(
"Unsupported number of Groq accelerators.");
942 tbb::tick_count t0_circuit_simulation = tbb::tick_count::now();
946 Matrix_real cost_fnc_mtx = optimization_problem_batched_DFE( parameters_vec );
950 #elif defined __GROQ__ 952 Matrix_real cost_fnc_mtx = optimization_problem_batched_Groq( parameters_vec );
959 Matrix_real cost_fnc_mtx(static_cast<int>(parameters_vec.size()), 1);
967 int batch_element_num = parameters_vec.size();
968 int mpi_batch_element_num = batch_element_num /
world_size;
969 int mpi_batch_element_remainder = batch_element_num %
world_size;
971 if ( mpi_batch_element_remainder > 0 ) {
972 std::string err(
"Optimization_Interface::optimization_problem_batched: The size of the batch should be divisible with the number of processes.");
976 int mpi_starting_batchIdx = mpi_batch_element_num * current_rank;
979 Matrix_real cost_fnc_mtx_loc(mpi_batch_element_num, 1);
981 auto calculate_local_batch_element = [&](
int idx) {
985 if ( parallel == 0 ) {
986 for (
int idx=0; idx<mpi_batch_element_num; ++idx) {
987 calculate_local_batch_element(idx);
992 tbb::parallel_for( tbb::blocked_range<int>(0, (
int)mpi_batch_element_num, work_batch), [&](tbb::blocked_range<int> r) {
993 for (
int idx=r.begin(); idx<r.end(); ++idx) {
994 calculate_local_batch_element(idx);
1003 int bytes = cost_fnc_mtx_loc.
size()*
sizeof(double);
1004 MPI_Allgather(cost_fnc_mtx_loc.
get_data(), bytes, MPI_BYTE, cost_fnc_mtx.
get_data(), bytes, MPI_BYTE, MPI_COMM_WORLD);
1009 auto calculate_batch_element = [&](
int idx) {
1013 if ( parallel == 0 ) {
1014 for (
int idx=0; idx<(
int)parameters_vec.size(); ++idx) {
1015 calculate_batch_element(idx);
1020 tbb::parallel_for( tbb::blocked_range<int>(0, (
int)parameters_vec.size(), work_batch), [&](tbb::blocked_range<int> r) {
1021 for (
int idx=r.begin(); idx<r.end(); ++idx) {
1022 calculate_batch_element(idx);
1031 return cost_fnc_mtx;
1055 const bool use_float_cost_path =
false;
1057 static tbb::enumerable_thread_specific<Matrix_real_float> parameters_float_tls;
1058 static tbb::enumerable_thread_specific<Matrix_float> matrix_new_tls;
1059 static tbb::enumerable_thread_specific<Matrix_float> ret_temp_float_tls;
1062 Matrix_float& ret_temp_float = ret_temp_float_tls.local();
1063 parameters.
copy_to(parameters_float);
1065 instance->Gates_block::apply_to( parameters_float, matrix_new );
1072 static tbb::enumerable_thread_specific<Matrix> matrix_new_tls;
1073 Matrix& matrix_new = matrix_new_tls.local();
1075 instance->Gates_block::apply_to( parameters, matrix_new );
1169 const bool use_float_combined_cost_path =
false;
1170 if ( use_float_combined_cost_path && instance->
get_use_float() ) {
1171 static tbb::enumerable_thread_specific<Matrix_real_float> parameters_float_tls;
1173 parameters.
copy_to(parameters_float);
1175 static tbb::enumerable_thread_specific<std::vector<Matrix_float>> combined_result_tls;
1176 std::vector<Matrix_float>& combined_result = combined_result_tls.local();
1177 instance->Gates_block::apply_to_combined( parameters_float, Umtx_loc, parallel, combined_result );
1194 auto calculate_gradient_component = [&](
int idx) {
1196 Matrix_float& deriv_mtx = combined_result[
static_cast<size_t>(idx) + 1];
1203 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*deriv_tmp[1]*correction1_scale - 1.0);
1208 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*(deriv_tmp[1]*correction1_scale + deriv_tmp[2]*
correction2_scale) - 1.0);
1212 double d = 1.0/deriv_mtx.
cols;
1214 grad_comp = -2.0*d*d*trace_tmp[0].real*deriv_tmp.
real-2.0*d*d*trace_tmp[0].imag*deriv_tmp.
imag;
1218 double d = deriv_mtx.
cols;
1220 grad_comp = -2.0/d/(d+1)*trace_tmp[0].
real*deriv_tmp.
real-2.0/d/(d+1)*trace_tmp[0].imag*deriv_tmp.
imag;
1239 double d = 1.0/deriv64.
cols;
1240 grad_comp = -2.0*d*d*(trace_tmp64[0].real*deriv_tmp[0].real+trace_tmp64[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*correction1_scale*(trace_tmp64[1].real*deriv_tmp[1].real+trace_tmp64[1].imag*deriv_tmp[1].imag));
1244 double d = 1.0/deriv64.
cols;
1245 grad_comp = -2.0*d*d*(trace_tmp64[0].real*deriv_tmp[0].real+trace_tmp64[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*(correction1_scale*(trace_tmp64[1].real*deriv_tmp[1].real+trace_tmp64[1].imag*deriv_tmp[1].imag) + correction2_scale*(trace_tmp64[2].
real*deriv_tmp[2].
real+trace_tmp64[2].imag*deriv_tmp[2].imag)));
1250 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1253 grad[idx] = grad_comp;
1256 if ( parallel == 0 ) {
1257 for (
int idx=0; idx<parameter_num_loc; ++idx) {
1258 calculate_gradient_component(idx);
1262 int work_batch = 10;
1263 tbb::parallel_for( tbb::blocked_range<int>(0,parameter_num_loc,work_batch), [&](tbb::blocked_range<int> r) {
1264 for (
int idx=r.begin(); idx<r.end(); ++idx) {
1265 calculate_gradient_component(idx);
1271 std::stringstream sstream;
1272 sstream << *f0 << std::endl;
1273 instance->
print(sstream, 5);
1284 int gatesNum, redundantGateSets, gateSetNum;
1285 DFEgate_kernel_type* DFEgates = instance->convert_to_DFE_gates_with_derivates( parameters, gatesNum, gateSetNum, redundantGateSets );
1294 int mpi_gateSetNum = gateSetNum / instance->world_size;
1295 int mpi_starting_gateSetIdx = gateSetNum/instance->world_size * instance->current_rank;
1303 calcqgdKernelDFE( Umtx_loc.
rows, Umtx_loc.
cols, DFEgates+mpi_starting_gateSetIdx*gatesNum, gatesNum, mpi_gateSetNum, trace_offset_loc, mpi_trace_DFE_mtx.
get_data() );
1306 int bytes = mpi_trace_DFE_mtx.
size()*
sizeof(double);
1307 MPI_Allgather(mpi_trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, trace_DFE_mtx.
get_data(), bytes, MPI_BYTE, MPI_COMM_WORLD);
1320 std::stringstream sstream;
1321 sstream << *f0 <<
" " << 1.0 - trace_DFE_mtx[0]/Umtx_loc.
cols <<
" " << trace_DFE_mtx[1]/Umtx_loc.
cols <<
" " << trace_DFE_mtx[2]/Umtx_loc.
cols << std::endl;
1322 instance->
print(sstream, 5);
1326 *f0 = 1-trace_DFE_mtx[0]/Umtx_loc.
cols;
1329 *f0 = 1 - (trace_DFE_mtx[0] + std::sqrt(prev_cost_fnv_val)*trace_DFE_mtx[1]*
correction1_scale)/Umtx_loc.
cols;
1332 *f0 = 1 - (trace_DFE_mtx[0] + std::sqrt(prev_cost_fnv_val)*(trace_DFE_mtx[1]*correction1_scale + trace_DFE_mtx[2]*
correction2_scale))/Umtx_loc.
cols;
1335 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1342 for (
int idx=0; idx<parameter_num_loc; idx++) {
1345 grad[idx] = -trace_DFE_mtx[3*(idx+1)]/Umtx_loc.
cols;
1348 grad[idx] = -(trace_DFE_mtx[3*(idx+1)] + std::sqrt(prev_cost_fnv_val)*trace_DFE_mtx[3*(idx+1)+1]*correction1_scale)/Umtx_loc.
cols;
1351 grad[idx] = -(trace_DFE_mtx[3*(idx+1)] + std::sqrt(prev_cost_fnv_val)*(trace_DFE_mtx[3*(idx+1)+1]*correction1_scale + trace_DFE_mtx[3*(idx+1)+2]*
correction2_scale))/Umtx_loc.
cols;
1354 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1376 tbb::tick_count t0_CPU = tbb::tick_count::now();
1382 static tbb::enumerable_thread_specific<std::vector<Matrix>> combined_result_tls;
1383 std::vector<Matrix>& combined_result = combined_result_tls.local();
1385 Matrix& matrix_new = combined_result[0];
1397 auto calculate_gradient_component = [&](
int idx) {
1399 Matrix& deriv_mtx = combined_result[
static_cast<size_t>(idx) + 1];
1406 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*deriv_tmp[1]*correction1_scale - 1.0);
1411 grad_comp = (deriv_tmp[0] - std::sqrt(prev_cost_fnv_val)*(deriv_tmp[1]*correction1_scale + deriv_tmp[2]*
correction2_scale) - 1.0);
1415 double d = 1.0/deriv_mtx.
cols;
1417 grad_comp = -2.0*d*d*trace_tmp[0].real*deriv_tmp.
real-2.0*d*d*trace_tmp[0].imag*deriv_tmp.
imag;
1422 double d = 1.0/deriv_mtx.
cols;
1423 grad_comp = -2.0*d*d* (trace_tmp[0].real*deriv_tmp[0].real+trace_tmp[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*correction1_scale*(trace_tmp[1].real*deriv_tmp[1].real+trace_tmp[1].imag*deriv_tmp[1].imag));
1428 double d = 1.0/deriv_mtx.
cols;
1429 grad_comp = -2.0*d*d* (trace_tmp[0].real*deriv_tmp[0].real+trace_tmp[0].imag*deriv_tmp[0].imag+std::sqrt(prev_cost_fnv_val)*(correction1_scale*(trace_tmp[1].real*deriv_tmp[1].real+trace_tmp[1].imag*deriv_tmp[1].imag) + correction2_scale*(trace_tmp[2].
real*deriv_tmp[2].
real+trace_tmp[2].imag*deriv_tmp[2].imag)));
1447 double d = deriv_mtx.
cols;
1449 grad_comp = -2.0/d/(d+1)*trace_tmp[0].
real*deriv_tmp.
real-2.0/d/(d+1)*trace_tmp[0].imag*deriv_tmp.
imag;
1453 std::string err(
"Optimization_Interface::optimization_problem_combined: Cost function variant not implmented.");
1457 grad[idx] = grad_comp;
1460 if ( parallel == 0 ) {
1461 for (
int idx=0; idx<parameter_num_loc; ++idx) {
1462 calculate_gradient_component(idx);
1466 int work_batch = 10;
1467 tbb::parallel_for( tbb::blocked_range<int>(0,parameter_num_loc,work_batch), [&](tbb::blocked_range<int> r) {
1468 for (
int idx=r.begin(); idx<r.end(); ++idx) {
1469 calculate_gradient_component(idx);
1476 std::stringstream sstream;
1477 sstream << *f0 << std::endl;
1478 instance->
print(sstream, 5);
1532 static tbb::enumerable_thread_specific<std::vector<Matrix>> combined_result_tls;
1533 std::vector<Matrix>& combined_result = combined_result_tls.local();
1535 combined_result[0].copy_to(Umtx);
1536 Umtx_deriv.resize(combined_result.size() - 1);
1537 for (
size_t idx = 1; idx < combined_result.size(); ++idx) {
1538 combined_result[idx].copy_to(Umtx_deriv[idx - 1]);
1584 std::stringstream sstream;
1585 sstream <<
"Optimization_Interface::set_cost_function_variant: Cost function variant set to " <<
cost_fnc << std::endl;
1691 std::string error(
"Optimization_Interface::set_optimizer: unimplemented optimization algorithm");
1800 std::string error(
"Optimization_Interface::set_trace_offset: trace offset must be smaller or equal to the difference of the rows and columns in the input unitary.");
1809 std::stringstream sstream;
1810 sstream <<
"Optimization_Interface::set_trace_offset: trace offset set to " <<
trace_offset << std::endl;
1819 Optimization_Interface::upload_Umtx_to_DFE() {
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 ...
Header file of single-precision complex array storage with automatic and thread safe reference counti...
Header file for a class containing basic methods for the decomposition process.
void set_osr_params(std::vector< std::vector< int >> use_cuts_in, int osr_rank_in, bool use_softmax_in)
int id
unique id indentifying the instance of the class
void export_current_cost_fnc(double current_minimum)
Call to print out into a file the current cost function and the second Rényi entropy on the subsyste...
void print(const std::stringstream &sstream, int verbose_level=1) const
Call to print output messages in the function of the verbosity level.
Class to store single-precision real arrays and properties.
int get_num_iters()
Get the number of processed iterations during the optimization process.
void set_optimizer(optimization_aglorithms alg_in)
Call to set the optimizer engine to be used in solving the optimization problem.
void solve_layer_optimization_problem_AGENTS(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the AGENT algorithm.
Matrix get_Umtx()
Call to retrive a pointer to the unitary to be transformed.
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...
int init_groq_sv_lib(const int reserved_device_num, int initialize_id_in)
Call to allocated Groq cards for calculations.
std::map< int, int > identical_blocks
A map of <int n: int num> indicating that how many identical successive blocks should be used in the ...
Matrix_real get_cost_function_with_correction(const Matrix &matrix, int qbit_num, int trace_offset=0)
Call co calculate the cost function of the optimization process, and the first correction to the cost...
void add_gate(Gate *gate)
Append a general gate to the list of gates.
int stride
The column stride of the array. (The array elements in one row are a_0, a_1, ... a_{cols-1}, 0, 0, 0, 0. The number of zeros is stride-cols)
Matrix to_float64() const
Convert to double precision.
static void optimization_problem_combined_unitary(Matrix_real parameters, void *void_instance, Matrix &Umtx, std::vector< Matrix > &Umtx_deriv)
Call to calculate both the effect of the circuit on th eunitary and it's gradient componets...
double correction1_scale
prefactor of the single-bitflip errors in the cost function. (see Eq. (21) in arXiv:2210.09191)
bool use_float
Selects float32 circuit application for parameter/unitary/state data.
double get_correction2_scale()
Call to get the prefactor of the two-bitflip errors in the cost function.
cost_function_type cost_fnc
The chosen variant of the cost function.
Matrix get_deriv_sum_of_squares(Matrix &matrix)
void add_u1(int target_qbit)
Append a U1 gate to the list of gates.
Matrix_real_float optimized_parameters_mtx_float
Float32 optimized parameters used by the hot gate-application path.
void release_gates()
Call to release the stored gates.
int get_accelerator_num()
Get the number of accelerators to be reserved on DFEs on users demand.
std::vector< std::vector< int > > use_cuts
cuts used for OSR entanglement cost function
double optimization_problem(double *parameters)
Evaluate the optimization problem of the optimization.
double get_osr_entanglement_test(Matrix &matrix, std::vector< std::vector< int >> &use_cuts, int rank=-1, bool use_softmax=false)
void solve_layer_optimization_problem_GRAD_DESCEND(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the GRAD_DESCEND (line search in the direct...
void set_trace_offset(int trace_offset_in)
Set the trace offset used in the evaluation of the cost function.
double prev_cost_fnv_val
the previous value of the cost funtion to be used to evaluate bitflip errors in the cost funtion (see...
std::atomic< int > number_of_iters
number of iterations
int trace_offset
The offset in the first columns from which the "trace" is calculated. In this case Tr(A) = sum_(i-off...
double calculate_cost_function(Matrix &matrix_new, Matrix *ret_temp=NULL)
Calculate the current cost function value from an already transformed matrix.
std::map< int, int > max_layer_num
A map of <int n: int num> indicating that how many layers should be used in the subdecomposition proc...
void set_random_shift_count_max(int random_shift_count_max_in)
Call to set the maximal number of parameter randomization tries to escape a local minimum...
void increment_num_iters(int delta=1)
Atomically increment the tracked number of optimization iterations.
scalar * get_data() const
Call to get the pointer to the stored data.
virtual double optimization_problem_non_static(Matrix_real parameters, void *void_instance)
The optimization problem of the final optimization.
double correction2_scale
prefactor of the double-bitflip errors in the cost function. (see Eq. (21) in arXiv:2210.09191)
cost_function_type get_cost_function_variant()
Call to get the variant of the cost function used in the calculations.
int get_trace_offset()
Get the trace ffset used in the evaluation of the cost function.
void init_dfe_lib_and_upload(const int accelerator_num, int qbit_num, int initialize_id_in, Matrix &input)
Initialize the DFE library if needed and upload the input matrix while holding the writer lock...
void set_qbit_num(int qbit_num_in)
Set the number of qubits spanning the matrix of the gates stored in the block of gates.
int max_outer_iterations
Maximal number of iterations allowed in the optimization process.
Matrix_real get_cost_function_with_correction2(const Matrix &matrix, int qbit_num, int trace_offset=0)
Call co calculate the cost function of the optimization process, and the first correction to the cost...
int osr_rank
rank used for OSR entanglement cost function
optimization_aglorithms
implemented optimization strategies
int LAPACKE_dgesv(int matrix_layout, int n, int nrhs, double *a, int lda, int *ipiv, double *b, int ldb)
bool use_softmax
logical variable indicating whether to use softmax or average in the OSR entanglement cost function ...
std::string project_name
the name of the project
void set_max_inner_iterations(int max_inner_iterations_in)
Call to set the maximal number of iterations for which an optimization engine tries to solve the opti...
void solve_layer_optimization_problem_BAYES_AGENTS(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via Bayes & Agents algorithm.
gate_type type
The type of the operation (see enumeration gate_type)
QGD_Complex16 get_trace(Matrix &matrix)
Call to calculate the real and imaginary parts of the trace.
double get_infidelity(Matrix &matrix)
Call to calculate infidelity.
double get_second_Renyi_entropy(Matrix_real ¶meters_mtx, Matrix &input_state, matrix_base< int > &qbit_list)
Call to evaluate the seconf Rényi entropy.
int accelerator_num
number of utilized accelerators
int rows
The number of rows.
int cols
The number of columns.
Matrix get_deriv_osr_entanglement(Matrix &matrix, std::vector< std::vector< int >> &use_cuts, int rank=-1, bool use_softmax=false)
Matrix_float Umtx_float
Float32 copy of the unitary used when config["use_float"] is true.
virtual void add_finalyzing_layer()
Call to add further layer to the gate structure used in the subdecomposition.
A base class to determine the decomposition of an N-qubit unitary into a sequence of CNOT and U3 gate...
void combine(Gates_block *op_block)
Call to append the gates of an gate block to the current block.
double randomization_rate
randomization rate
std::map< int, int > iteration_loops
A map of <int n: int num> indicating the number of iteration in each step of the decomposition.
double real_trace_conj_dot(Matrix &A, Matrix &B)
void randomize_parameters(Matrix_real &input, Matrix_real &output, const double f0)
Call to randomize the parameter.
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.
void solve_layer_optimization_problem_BFGS2(int num_of_parameters, Matrix_real solution_guess)
Call to solve layer by layer the optimization problem via BBFG algorithm.
Structure type representing complex numbers in the SQUANDER package.
double CPU_time
Time spent on optimization [seconds].
A class containing basic methods for the decomposition process.
double circuit_simulation_time
Time spent on circuit simulation/cost function evaluation [seconds].
decomposed_matrix
the unitary matrix from the result object
void copy_to(Matrix_real &target) const
Copy the matrix to a reusable double-precision target matrix.
int Power_of_2(int n)
Calculates the n-th power of 2.
void solve_layer_optimization_problem_BFGS(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via BBFG algorithm.
Double-precision complex matrix (float64).
Matrix get_trace_with_correction(Matrix &matrix, int qbit_num)
Call co calculate the Hilbert Schmidt testof the optimization process, and the first correction to th...
void copy_to(matrix_base< scalar > &target) const
Copy the current matrix storage into a reusable target matrix.
double get_previous_cost_function_value()
Call to retrieve the previous value of the cost funtion to be used to evaluate bitflip errors in the ...
void calc_decomposition_error(Matrix &decomposed_matrix)
Calculate the error of the decomposition according to the spectral norm of , where is the unitary pr...
int size() const
Call to get the number of the allocated elements.
double get_cost_function(const Matrix &matrix, int trace_offset=0)
Call co calculate the cost function during the final optimization process.
Gates_block()
Default constructor of the class.
cost_function_type
Type definition of the different types of the cost function.
A class responsible for grouping two-qubit (CNOT,CZ,CH) and one-qubit gates into layers.
int get_initialize_id()
Call to get the identification number of the inititalization of the library.
Single-precision complex matrix (float32).
guess_type
Type definition of the types of the initial guess.
Fixed point data related to a gate operation.
static void optimization_problem_combined(Matrix_real parameters, void *void_instance, double *f0, Matrix_real &grad)
Call to calculate both the cost function and the its gradient components.
std::map< std::string, Config_Element > config
config metadata utilized during the optimization
void solve_layer_optimization_problem_ADAM(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via ADAM algorithm.
void unload_dfe_lib()
Call to unload the DFE libarary and release the allocated devices.
double get_cost_function_sum_of_squares(Matrix &matrix)
Optimization_Interface & operator=(const Optimization_Interface &other)
Copy assignment operator.
static void optimization_problem_grad(Matrix_real parameters, void *void_instance, Matrix_real &grad)
Calculate the derivative of the cost function with respect to the free parameters.
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...
Header file for the paralleized calculation of the cost function of the final optimization problem (s...
void solve_layer_optimization_problem_GRAD_DESCEND_PARAMETER_SHIFT_RULE(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the GRAD_DESCEND_PARAMETER_SHIFT_RULE algor...
volatile double current_minimum
The current minimum of the optimization problem.
void solve_optimization_problem(double *solution_guess, int solution_guess_num)
This method can be used to solve the main optimization problem which is devidid into sub-layer optimi...
Matrix Umtx
The unitary to be decomposed.
virtual ~Optimization_Interface()
Destructor of the class.
double get_correction1_scale()
Call to get the prefactor of the single-bitflip errors in the cost function.
Header file for a class ???
int calcqgdKernelDFE(size_t rows, size_t cols, DFEgate_kernel_type *gates, int gatesNum, int gateSetNum, int traceOffset, double *trace)
Call to execute the calculation on the reserved DFE engines.
void solve_layer_optimization_problem_COSINE(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the COSINE algorithm.
static std::map< int, int > max_layer_num_def
A map of <int n: int num> indicating that how many layers should be used in the subdecomposition proc...
double real
the real part of a complex number
void final_optimization()
final optimization procedure improving the accuracy of the decompositin when all the qubits were alre...
Matrix_float get_Umtx_float()
Return the float32 unitary copy used by float execution.
int qbit_num
number of qubits spanning the matrix of the operation
bool optimize_layer_num
logical value. Set true to optimize the minimum number of gate layers required in the decomposition...
int get_qbit_num()
Call to get the number of qubits composing the unitary.
bool check_optimization_solution()
check_optimization_solution
double decomposition_error
error of the final decomposition
int max_inner_iterations
the maximal number of iterations for which an optimization engine tries to solve the optimization pro...
void solve_layer_optimization_problem_AGENTS_COMBINED(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via the AGENT COMBINED algorithm.
int random_shift_count_max
the maximal number of parameter randomization tries to escape a local minimum.
virtual std::vector< Matrix > apply_to_combined(Matrix_real ¶meters_mtx, Matrix &input, int parallel) override
Combined forward + derivative application with shared precomputed trig cache.
Optimization_Interface()
Nullary constructor of the class.
void solve_layer_optimization_problem_ADAM_BATCHED(int num_of_parameters, Matrix_real &solution_guess_)
Call to solve layer by layer the optimization problem via batched ADAM algorithm. ...
Matrix_real optimized_parameters_mtx
The optimized parameters for the gates.
int get_parallel_configuration()
Get the parallel configuration from the config.
void set_cost_function_variant(cost_function_type variant)
Call to set the variant of the cost function used in the calculations.
Matrix get_trace_with_correction2(Matrix &matrix, int qbit_num)
Call co calculate the Hilbert Schmidt testof the optimization process, and the first correction to th...
int get_parameter_num() override
Call to get the number of free parameters.
double radius
parameter to contron the radius of parameter randomization around the curren tminimum ...
bool get_use_float() const
True when config["use_float"] requests float32 circuit execution.
Matrix_real optimization_problem_batched(std::vector< Matrix_real > ¶meters_vec)
The cost function of the optimization with batched input (implemented only for the Frobenius norm cos...
double global_target_minimum
The global target minimum of the optimization problem.
Class to store data of complex arrays and its properties.
double get_hilbert_schmidt_test(Matrix &matrix)
Call co calculate the cost function of the optimization process according to https://arxiv.org/pdf/2210.09191.pdf.
virtual void optimization_problem_combined_non_static(Matrix_real parameters, void *void_instance, double *f0, Matrix_real &grad)
Call to calculate both the cost function and the its gradient components.
void solve_layer_optimization_problem_BAYES_OPT(int num_of_parameters, Matrix_real &solution_guess)
Call to solve layer by layer the optimization problem via Bayes algorithm.
std::mt19937 gen
Standard mersenne_twister_engine seeded with rd()
double imag
the imaginary part of a complex number