98 double trace_real = 0.0;
100 if ( trace_offset == 0 ) {
104 trace_real += matrix[idx*matrix.
stride + idx].real;
112 trace_real += matrix[(idx+trace_offset)*matrix.
stride + idx].real;
119 double cost_function = (1.0 - trace_real/
matrix_size);
121 return cost_function;
146 double trace_real = 0.0;
148 if ( trace_offset == 0 ) {
149 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
151 int qbit_error_mask = 1 << qbit_idx;
153 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
156 int row_idx = col_idx ^ qbit_error_mask;
158 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
166 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
168 int qbit_error_mask = 1 << qbit_idx;
170 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
173 int row_idx = (col_idx + trace_offset) ^ qbit_error_mask;
175 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
188 ret[1] = cost_function;
219 double trace_real = 0.0;
221 if ( trace_offset == 0 ) {
222 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
224 int qbit_error_mask = 1 << qbit_idx;
226 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
229 int row_idx = col_idx ^ qbit_error_mask;
231 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
239 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
241 int qbit_error_mask = 1 << qbit_idx;
243 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
246 int row_idx = (col_idx+trace_offset) ^ qbit_error_mask;
248 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
257 ret[1] = cost_function;
266 if ( trace_offset == 0 ) {
267 for (
int qbit_idx=0; qbit_idx<qbit_num-1; qbit_idx++) {
268 for (
int qbit_idx2=qbit_idx+1; qbit_idx2<
qbit_num; qbit_idx2++) {
270 int qbit_error_mask = (1 << qbit_idx) + (1 << qbit_idx2);
272 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
275 int row_idx = col_idx ^ qbit_error_mask;
277 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
285 for (
int qbit_idx=0; qbit_idx<qbit_num-1; qbit_idx++) {
286 for (
int qbit_idx2=qbit_idx+1; qbit_idx2<
qbit_num; qbit_idx2++) {
288 int qbit_error_mask = (1 << qbit_idx) + (1 << qbit_idx2);
290 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
293 int row_idx = (col_idx+trace_offset) ^ qbit_error_mask;
295 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
306 ret[2] = cost_function2;
319 for (
int rowidx = 0; rowidx < matrix.
rows; rowidx++) {
320 int baseidx = rowidx*matrix.
stride;
321 for (
int colidx = 0; colidx < matrix.
cols; colidx++) {
322 if (rowidx == colidx) {
323 ret += (matrix[baseidx+colidx].real - 1.0) * (matrix[baseidx+colidx].real - 1.0) + matrix[baseidx+colidx].imag * matrix[baseidx+colidx].imag;
325 ret += matrix[baseidx+colidx].real * matrix[baseidx+colidx].real + matrix[baseidx+colidx].imag * matrix[baseidx+colidx].imag;
340 double trace_real=0.0;
341 double trace_imag=0.0;
346 trace_real += matrix[idx*matrix.
stride + idx].real;
347 trace_imag += matrix[idx*matrix.
stride + idx].imag;
350 ret.
real = trace_real;
351 ret.
imag = trace_imag;
364 double d = 1.0/matrix.
cols;
365 double cost_function = 0.0;
369 return cost_function;
374 double d = matrix.
cols;
375 double cost_function = 0.0;
379 return cost_function;
396 double trace_real = 0.0;
397 double trace_imag = 0.0;
399 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
401 int qbit_error_mask = 1 << qbit_idx;
403 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
406 int row_idx = col_idx ^ qbit_error_mask;
408 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
409 trace_imag += matrix[row_idx*matrix.
stride + col_idx].imag;
413 ret[0].real = trace_tmp.
real;
414 ret[0].imag = trace_tmp.
imag;
415 ret[1].real = trace_real;
416 ret[1].imag = trace_imag;
436 double trace_real = 0.0;
437 double trace_imag = 0.0;
439 for (
int qbit_idx=0; qbit_idx<
qbit_num; qbit_idx++) {
441 int qbit_error_mask = 1 << qbit_idx;
443 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
446 int row_idx = col_idx ^ qbit_error_mask;
448 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
449 trace_imag += matrix[row_idx*matrix.
stride + col_idx].imag;
454 ret[1].real = trace_real;
455 ret[1].imag = trace_imag;
464 for (
int qbit_idx=0; qbit_idx<qbit_num-1; qbit_idx++) {
465 for (
int qbit_idx2=qbit_idx+1; qbit_idx2<
qbit_num; qbit_idx2++) {
467 int qbit_error_mask = (1 << qbit_idx) + (1 << qbit_idx2);
469 for (
int col_idx=0; col_idx<
matrix_size; col_idx++) {
472 int row_idx = col_idx ^ qbit_error_mask;
474 trace_real += matrix[row_idx*matrix.
stride + col_idx].real;
475 trace_imag += matrix[row_idx*matrix.
stride + col_idx].imag;
482 ret[2].real = trace_real;
483 ret[2].imag = trace_imag;
484 ret[0].real = trace_tmp.
real;
485 ret[0].imag = trace_tmp.
imag;
514 for (
int row_idx = r.begin(); row_idx != r.end(); row_idx++) {
516 if ( row_idx > matrix_size ) {
517 std::string err(
"Error: row idx should be less than the number of roes in the matrix.");
526 double partial_cost_function = 0;
528 int idx_max = idx_offset + row_idx;
529 for (
int idx=idx_offset; idx<idx_max; idx++ ) {
533 int diag_element_idx = row_idx*matrix_size + row_idx;
534 double diag_real =
data[diag_element_idx].
real - corner_element.
real;
535 double diag_imag =
data[diag_element_idx].
imag - corner_element.
imag;
536 partial_cost_function = partial_cost_function + diag_real*diag_real + diag_imag*diag_imag;
539 idx_offset = idx_max + 1;
541 for (
int idx=idx_offset; idx<idx_max; idx++ ) {
546 cost_function_priv = cost_function_priv + partial_cost_function;
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.
QGD_Complex16 * data
Pointer to the data stored in the matrix.
Matrix_real get_cost_function_with_correction(Matrix matrix, int qbit_num, int trace_offset)
Call co calculate the cost function of the optimization process, and the first correction to the cost...
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)
double get_cost_function(Matrix matrix, int trace_offset)
Call co calculate the cost function during the final optimization process.
double get_infidelity(Matrix &matrix)
Call to calculate infidelity.
scalar * get_data() const
Call to get the pointer to the stored data.
Matrix_real get_cost_function_with_correction2(Matrix matrix, int qbit_num, int trace_offset)
Call co calculate the cost function of the optimization process, and the first correction to the cost...
int rows
The number of rows.
int cols
The number of columns.
Matrix matrix
Array stroing the matrix.
functor_cost_fnc(Matrix matrix_in, tbb::combinable< double > *partial_cost_functions_in)
Constructor of the class.
void operator()(tbb::blocked_range< int > r) const
Operator to calculate the partial cost function derived from the row of the matrix labeled by row_idx...
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...
Structure type representing complex numbers in the SQUANDER package.
Class to store data of complex arrays and its properties.
double get_cost_function_sum_of_squares(Matrix &matrix)
Header file for the paralleized calculation of the cost function of the final optimization problem (s...
double real
the real part of a complex number
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...
Class to store data of complex arrays and its properties.
tbb::combinable< double > * partial_cost_functions
array storing the partial cost functions
double imag
the imaginary part of a complex number
QGD_Complex16 get_trace(Matrix &matrix)
Call to calculate the real and imaginary parts of the trace.