00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 #include <stdio.h>
00164 #include <unistd.h>
00165 #include <math.h>
00166 #include <time.h>
00167 #include <sys/time.h>
00168 #include <string.h>
00169
00170 #include <gsl/gsl_complex.h>
00171 #include <gsl/gsl_complex_math.h>
00172 #include <gsl/gsl_matrix.h>
00173 #include <gsl/gsl_vector.h>
00174 #include <gsl/gsl_blas.h>
00175 #include <gsl/gsl_rng.h>
00176 #include <gsl/gsl_randist.h>
00177 #include <gsl/gsl_eigen.h>
00178 #include <gsl/gsl_linalg.h>
00179 #include <gsl/gsl_multimin.h>
00180
00181
00182 #include "header.h"
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 void
00202 load_basis();
00203 void
00204 init();
00205 void
00206 prepare_state(gsl_matrix_complex *density_matrix);
00207 void
00208 measure_state(gsl_matrix_complex *density_matrix, gsl_vector *n);
00209 void
00210 apply_noise(gsl_vector *n);
00211 void
00212 linear_estimate(gsl_vector *n, gsl_matrix_complex *density_linear);
00213 void
00214 MLE(gsl_vector *n, gsl_matrix_complex *density_physical, gsl_matrix_complex *density_linear, gsl_matrix_complex *density_mle, gsl_matrix *fidelities, gsl_matrix *times, gsl_matrix *f_vals, gsl_matrix *abs_gradient, int trial);
00215 void
00216 quick_and_dirty(gsl_matrix_complex *density_linear, gsl_matrix_complex *density_quick);
00217 void
00218 quick_and_dirty_2(gsl_matrix_complex *density_linear, gsl_matrix_complex *density_quick);
00219
00220 double
00221 my_f(const gsl_vector * x, void * params);
00222 void
00223 my_df(const gsl_vector * x, void * params, gsl_vector * g);
00224 void
00225 my_fdf(const gsl_vector * x, void * params, double * f, gsl_vector * g);
00226
00227 void
00228 fill_tangle_entropy_plane();
00229 void
00230 states_1_to_10();
00231
00232 void
00233 find_N();
00234
00235 int
00236 main(void) {
00237
00238
00239 init();
00240
00241 if (STATE == 11) {
00242 if (NQ == 2) {
00243 fill_tangle_entropy_plane();
00244 }
00245 else {
00246 fprintf(stderr, "Only defined for 2 qubits\n");
00247 exit(1);
00248 }
00249 } else if (STATE == 15) {
00250 find_N();
00251 } else {
00252 states_1_to_10();
00253 }
00254
00255 return 0;
00256 }
00257
00258
00259
00260 void
00261 fill_tangle_entropy_plane() {
00262 int numtrials = 99;
00263 int i, j, k;
00264
00265
00266 gsl_matrix_complex *density_physical = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00267
00268 gsl_matrix_complex *density_theoretical = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00269
00270 gsl_vector *n = gsl_vector_alloc(pow(4, NQ));
00271
00272
00273 gsl_matrix_complex *density_linear = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
00274 gsl_matrix_complex *density_quick = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00275 gsl_matrix_complex *density_fp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00276 gsl_matrix_complex *density_mle = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
00277 gsl_matrix_complex *psi_outer = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
00278 gsl_vector_complex *psi_ket = gsl_vector_complex_alloc(pow(2, NQ));
00279
00280
00281 gsl_vector *f_mle, *f_quick, *f_fp, *tau, *sl;
00282
00283 gsl_matrix *fidelities, *times, *f_vals, *abs_gradient;
00284
00285
00286 int num_records = 2*MILLION;
00287 f_mle = gsl_vector_alloc(num_records);
00288 f_quick = gsl_vector_alloc(num_records);
00289 f_fp = gsl_vector_alloc(num_records);
00290 tau = gsl_vector_alloc(num_records);
00291 sl = gsl_vector_alloc(num_records);
00292 printf("HERE\n");
00293
00294 fidelities = gsl_matrix_alloc(1, MAXITER);
00295 times = gsl_matrix_alloc(1, MAXITER);
00296 f_vals = gsl_matrix_alloc(1, MAXITER);
00297 abs_gradient = gsl_matrix_alloc(1, MAXITER);
00298
00299 gsl_vector_set_zero(f_mle);
00300 gsl_vector_set_zero(f_quick);
00301 gsl_vector_set_zero(f_fp);
00302 gsl_vector_set_zero(tau);
00303 gsl_vector_set_zero(sl);
00304 gsl_matrix_set_all(fidelities, GSL_NAN);
00305 gsl_matrix_set_all(times, GSL_NAN);
00306 gsl_matrix_set_all(f_vals, GSL_NAN);
00307 gsl_matrix_set_all(abs_gradient, GSL_NAN);
00308
00309
00310 char output[MAXCHAR];
00311 char integer[MAXCHAR];
00312
00313 int counter = 0;
00314
00315 double eps_squared;
00316 double tangle_eps;
00317
00318
00319
00320 for (i=0; i<=numtrials; i++) {
00321 tangle_eps = (double)i/numtrials/sqrt(2.0);
00322
00323 for (j=0; j<=numtrials; j++) {
00324 for (k=0; k<=numtrials; k++) {
00325 random_density_matrix(density_theoretical);
00326
00327 eps_squared = gsl_pow_2((double)j/numtrials);
00328
00329
00330 PSI_matrix(psi_outer, tangle_eps);
00331
00332 gsl_matrix_complex_scale(density_theoretical, gsl_complex_rect(eps_squared, 0.0));
00333 gsl_matrix_complex_scale(psi_outer, gsl_complex_rect(1.0 - eps_squared, 0.0));
00334 gsl_matrix_complex_add(density_theoretical, psi_outer);
00335
00336
00337 gsl_vector_set(tau, counter, pow(concurrence(density_theoretical), 2));
00338 gsl_vector_set(sl, counter, entropy_linear(density_theoretical));
00339 printf("Tau: %e\n", gsl_vector_get(tau, counter));
00340 printf("Entropy Linear: %e\n", gsl_vector_get(sl, counter));
00341
00342
00343 gsl_matrix_complex_memcpy(density_physical, density_theoretical);
00344
00345
00346 printf("Measuring the state\n");
00347 measure_state(density_physical, n);
00348
00349
00350 gsl_vector_scale(n, N);
00351
00352 if (WRITE_DENSITY) {
00353
00354 printf("Writing data to disc - density_physical\n");
00355
00356 strncpy(output, "density_physical_trial_", MAXCHAR);
00357 snprintf(integer, MAXCHAR, "%d", counter);
00358 strncat(output, integer, MAXCHAR);
00359 write_data(output, density_physical);
00360 }
00361
00362
00363 printf("Applying experimental noise to data\n");
00364 apply_noise(n);
00365
00366 printf("Performing linear reconstruction\n");
00367
00368 linear_estimate(n, density_linear);
00369
00370 if (WRITE_DENSITY) {
00371 printf("Writing data to disc - density_linear\n");
00372 strncpy(output, "density_linear_trial_", MAXCHAR);
00373 snprintf(integer, MAXCHAR, "%d", counter);
00374 strncat(output, integer, MAXCHAR);
00375 write_data(output, density_linear);
00376 }
00377
00378
00379 gsl_matrix_complex_memcpy(density_fp, density_linear);
00380
00381
00382 printf("Performing Quick and Dirty\n");
00383 quick_and_dirty(density_linear, density_quick);
00384
00385 if (WRITE_DENSITY) {
00386 printf("Writing data to disc - density_quick\n");
00387
00388 strncpy(output, "density_quick_trial_", MAXCHAR);
00389 snprintf(integer, MAXCHAR, "%d", counter);
00390 strncat(output, integer, MAXCHAR);
00391 write_data(output, density_quick);
00392 }
00393
00394
00395 gsl_vector_set(f_quick, counter, fidelity(density_quick, density_physical));
00396 printf("Fidelity Quick: %e\n", gsl_vector_get(f_quick, counter));
00397
00398
00399 gsl_matrix_complex_memcpy(density_linear, density_fp);
00400
00401
00402 printf("Performing Forced Purity\n");
00403 quick_and_dirty_2(density_linear, density_fp);
00404
00405 if (WRITE_DENSITY) {
00406 printf("Writing data to disc - density_fp\n");
00407 strncpy(output, "density_fp_trial_", MAXCHAR);
00408 snprintf(integer, MAXCHAR, "%d", counter);
00409 strncat(output, integer, MAXCHAR);
00410 write_data(output, density_fp);
00411 }
00412
00413
00414 gsl_vector_set(f_fp, counter, fidelity(density_fp, density_physical));
00415 printf("Fidelity Forced Purity: %e\n", gsl_vector_get(f_fp, counter));
00416
00417 printf("Performing MLE\n");
00418 MLE(n, density_physical, density_quick, density_mle, fidelities, times, f_vals, abs_gradient, 0);
00419
00420 if (WRITE_DENSITY) {
00421 printf("Writing data to disc - density_mle\n");
00422
00423 write_data("density_mle", density_mle);
00424 strncpy(output, "density_mle_trial_", MAXCHAR);
00425 snprintf(integer, MAXCHAR, "%d", counter);
00426 strncat(output, integer, MAXCHAR);
00427 write_data(output, density_mle);
00428 }
00429
00430 gsl_vector_set(f_mle, counter, fidelity(density_mle, density_physical));
00431 printf("Fidelity MLE: %e\n", gsl_vector_get(f_mle, counter));
00432
00433 counter++;
00434 }
00435 }
00436 }
00437
00438
00439
00440
00441 numtrials = 999;
00442
00443 gsl_matrix_complex *rho_mems = gsl_matrix_complex_alloc(4, 4);
00444
00445 for (i = 0; i <= numtrials; i++) {
00446
00447
00448
00449 for (j = 0; j <= numtrials; j++) {
00450
00451
00452 rho_MEMS(rho_mems, (double) i/numtrials);
00453
00454 random_density_matrix(density_theoretical);
00455
00456
00457
00458 eps_squared = pow((double)j/numtrials, 2);
00459
00460 gsl_matrix_complex_scale(density_theoretical, gsl_complex_rect(eps_squared, 0));
00461 gsl_matrix_complex_scale(rho_mems, gsl_complex_rect(1 - eps_squared, 0));
00462 gsl_matrix_complex_add(density_theoretical, rho_mems);
00463
00464
00465
00466
00467
00468 gsl_vector_set(tau, counter, pow(concurrence(density_theoretical), 2));
00469 gsl_vector_set(sl, counter, entropy_linear(density_theoretical));
00470 printf("Tau: %e\n", gsl_vector_get(tau, counter));
00471 printf("Entropy Linear: %e\n", gsl_vector_get(sl, counter));
00472
00473
00474 gsl_matrix_complex_memcpy(density_physical, density_theoretical);
00475
00476
00477 printf("Measuring the state\n");
00478 measure_state(density_physical, n);
00479
00480
00481 gsl_vector_scale(n, N);
00482
00483 if (WRITE_DENSITY) {
00484
00485 printf("Writing data to disc - density_physical\n");
00486
00487 strncpy(output, "density_physical_trial_", MAXCHAR);
00488 snprintf(integer, MAXCHAR, "%d", counter);
00489 strncat(output, integer, MAXCHAR);
00490 write_data(output, density_physical);
00491 }
00492
00493
00494 printf("Applying experimental noise to data\n");
00495 apply_noise(n);
00496
00497 printf("Performing linear reconstruction\n");
00498
00499 linear_estimate(n, density_linear);
00500
00501 if (WRITE_DENSITY) {
00502 printf("Writing data to disc - density_linear\n");
00503 strncpy(output, "density_linear_trial_", MAXCHAR);
00504 snprintf(integer, MAXCHAR, "%d", counter);
00505 strncat(output, integer, MAXCHAR);
00506 write_data(output, density_linear);
00507 }
00508
00509
00510 gsl_matrix_complex_memcpy(density_fp, density_linear);
00511
00512
00513 printf("Performing Quick and Dirty\n");
00514 quick_and_dirty(density_linear, density_quick);
00515
00516 if (WRITE_DENSITY) {
00517 printf("Writing data to disc - density_quick\n");
00518
00519 strncpy(output, "density_quick_trial_", MAXCHAR);
00520 snprintf(integer, MAXCHAR, "%d", counter);
00521 strncat(output, integer, MAXCHAR);
00522 write_data(output, density_quick);
00523 }
00524
00525
00526 gsl_vector_set(f_quick, counter, fidelity(density_quick, density_physical));
00527 printf("Fidelity Quick: %e\n", gsl_vector_get(f_quick, counter));
00528
00529
00530 gsl_matrix_complex_memcpy(density_linear, density_fp);
00531
00532
00533 printf("Performing Forced Purity\n");
00534 quick_and_dirty_2(density_linear, density_fp);
00535
00536 if (WRITE_DENSITY) {
00537 printf("Writing data to disc - density_fp\n");
00538 strncpy(output, "density_fp_trial_", MAXCHAR);
00539 snprintf(integer, MAXCHAR, "%d", counter);
00540 strncat(output, integer, MAXCHAR);
00541 write_data(output, density_fp);
00542 }
00543
00544
00545 gsl_vector_set(f_fp, counter, fidelity(density_fp, density_physical));
00546 printf("Fidelity Forced Purity: %e\n", gsl_vector_get(f_fp, counter));
00547
00548 printf("Performing MLE\n");
00549 MLE(n, density_physical, density_quick, density_mle, fidelities, times, f_vals, abs_gradient, 0);
00550
00551 if (WRITE_DENSITY) {
00552 printf("Writing data to disc - density_mle\n");
00553
00554 write_data("density_mle", density_mle);
00555 strncpy(output, "density_mle_trial_", MAXCHAR);
00556 snprintf(integer, MAXCHAR, "%d", counter);
00557 strncat(output, integer, MAXCHAR);
00558 write_data(output, density_mle);
00559 }
00560
00561 gsl_vector_set(f_mle, counter, fidelity(density_mle, density_physical));
00562 printf("Fidelity MLE: %e\n", gsl_vector_get(f_mle, counter));
00563
00564 counter++;
00565
00566 }
00567 }
00568
00569
00570 printf("Writing data to disc - fidelities and times vectors\n");
00571 write_vector_real("f_mle", f_mle);
00572 write_vector_real("f_quick", f_quick);
00573 write_vector_real("f_fp", f_fp);
00574 write_vector_real("tau", tau);
00575 write_vector_real("entropy_linear", sl);
00576
00577
00578
00579
00580
00581
00582 gsl_matrix_complex_free(density_physical);
00583 gsl_matrix_complex_free(density_theoretical);
00584 gsl_matrix_complex_free(density_linear);
00585 gsl_matrix_complex_free(density_quick);
00586 gsl_matrix_complex_free(density_mle);
00587 gsl_matrix_complex_free(psi_outer);
00588 gsl_vector_complex_free(psi_ket);
00589 gsl_matrix_complex_free(rho_mems);
00590 gsl_vector_free(n);
00591 gsl_matrix_free(fidelities);
00592 gsl_matrix_free(times);
00593
00594 }
00595
00596 void
00597 find_N() {
00598
00599
00600 gsl_matrix_complex *density_physical = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00601
00602 gsl_matrix_complex *density_theoretical = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00603
00604 gsl_vector *n = gsl_vector_alloc(pow(4, NQ));
00605 gsl_vector *n_copy = gsl_vector_alloc(pow(4, NQ));
00606
00607
00608 gsl_matrix_complex *density_linear = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
00609 gsl_matrix_complex *density_quick = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00610 gsl_matrix_complex *density_fp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00611
00612
00613
00614 char output[MAXCHAR];
00615 char integer[MAXCHAR];
00616
00617
00618 gsl_vector *f_quick, *f_fp, *tau, *sl;
00619
00620 gsl_vector *N_vec;
00621
00622 f_quick = gsl_vector_alloc(NUMTRIALS + 1);
00623 f_fp = gsl_vector_alloc(NUMTRIALS + 1);
00624 tau = gsl_vector_alloc(NUMTRIALS + 1);
00625 sl = gsl_vector_alloc(NUMTRIALS + 1);
00626 N_vec = gsl_vector_alloc(NUMTRIALS + 1);
00627
00628 gsl_vector_set_zero(f_quick);
00629 gsl_vector_set_zero(f_fp);
00630 gsl_vector_set_zero(tau);
00631 gsl_vector_set_zero(sl);
00632 gsl_vector_set_zero(N_vec);
00633
00634 int counter = 0, j;
00635
00636 for (j = 0; j<=NUMTRIALS; j++)
00637 {
00638
00639 theta_handle = (double)j/NUMTRIALS*(1.0/sqrt(2));
00640 prepare_state(density_theoretical);
00641
00642
00643 gsl_vector_set(tau, counter, pow(concurrence(density_theoretical), 2));
00644 gsl_vector_set(sl, counter, entropy_linear(density_theoretical));
00645 printf("Tau: %e\n", gsl_vector_get(tau, counter));
00646 printf("Entropy Linear: %e\n", gsl_vector_get(sl, counter));
00647
00648
00649 gsl_matrix_complex_memcpy(density_physical, density_theoretical);
00650
00651
00652 printf("Measuring the state\n");
00653 measure_state(density_physical, n);
00654
00655 gsl_vector_memcpy(n_copy, n);
00656
00657
00658
00659
00660 if (NQ == 2)
00661 N = 10;
00662 else if (NQ == 3)
00663 N = 100;
00664 else if (NQ == 4)
00665 N = 1000;
00666 else if (NQ == 5)
00667 N = 5000;
00668 else if (NQ == 6)
00669 N = 10000;
00670 else if (NQ == 7)
00671 N = 130000;
00672 else if (NQ == 8)
00673 N = 5000000;
00674
00675 if (WRITE_DENSITY) {
00676
00677 printf("Writing data to disc - density_physical\n");
00678
00679 strncpy(output, "density_physical_trial_", MAXCHAR);
00680 snprintf(integer, MAXCHAR, "%d", counter);
00681 strncat(output, integer, MAXCHAR);
00682 write_data(output, density_physical);
00683 }
00684 while(1) {
00685
00686 N++;
00687
00688 gsl_vector_memcpy(n, n_copy);
00689
00690
00691 gsl_vector_scale(n, N);
00692
00693
00694
00695 apply_noise(n);
00696
00697
00698
00699 linear_estimate(n, density_linear);
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 quick_and_dirty_2(density_linear, density_fp);
00724
00725 printf("N value is: %e\n", N);
00726
00727
00728 gsl_vector_set(f_fp, counter, fidelity(density_fp, density_physical));
00729 printf("Fidelity Forced Purity: %e\n", gsl_vector_get(f_fp, counter));
00730
00731
00732 if (gsl_vector_get(f_fp, counter) >= 0.90)
00733 break;
00734
00735 }
00736 gsl_vector_set(N_vec, counter, N);
00737 printf("N final value is: %e\n", N);
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 if (WRITE_DENSITY) {
00757 printf("Writing data to disc - density_fp\n");
00758 strncpy(output, "density_fp_trial_", MAXCHAR);
00759 snprintf(integer, MAXCHAR, "%d", counter);
00760 strncat(output, integer, MAXCHAR);
00761 write_data(output, density_fp);
00762 }
00763
00764 write_vector_real("N_vec", N_vec);
00765 counter++;
00766 }
00767
00768
00769
00770 printf("Writing data to disc - fidelities and times vectors\n");
00771 write_vector_real("f_quick", f_quick);
00772 write_vector_real("f_fp", f_fp);
00773 write_vector_real("tau", tau);
00774 write_vector_real("entropy_linear", sl);
00775 write_vector_real("N_vec", N_vec);
00776
00777
00778 gsl_matrix_complex_free(density_physical);
00779 gsl_matrix_complex_free(density_theoretical);
00780 gsl_matrix_complex_free(density_linear);
00781 gsl_matrix_complex_free(density_quick);
00782 gsl_vector_free(n);
00783
00784 }
00785
00786 void
00787 states_1_to_10() {
00788
00789 int i, range;
00790
00791 gsl_matrix_complex *density_physical = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00792
00793 gsl_matrix_complex *density_theoretical = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00794
00795 gsl_vector *n = gsl_vector_alloc(pow(4, NQ));
00796
00797
00798 gsl_matrix_complex *density_linear = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
00799 gsl_matrix_complex *density_quick = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00800 gsl_matrix_complex *density_fp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00801 gsl_matrix_complex *density_mle = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
00802 gsl_vector *result = gsl_vector_alloc(pow(4,NQ));
00803
00804
00805 char output[MAXCHAR];
00806 char integer[MAXCHAR];
00807
00808
00809 if (STATE!=9) {
00810 printf("Preparing the state\n");
00811 prepare_state(density_physical);
00812 write_data("density_state", density_physical);
00813
00814 gsl_matrix_complex_memcpy(density_theoretical, density_physical);
00815 }
00816
00817
00818 if (STATE != 10 && STATE!=12)
00819 range = 0;
00820 else
00821 range = NUMTRIALS;
00822
00823
00824 gsl_vector *f_mle, *f_quick, *f_fp, *tau, *sl, *times_qd, *times_fp, *times_lin, *times_meas;
00825
00826 gsl_matrix *fidelities, *times;
00827
00828 gsl_matrix *f_vals, *abs_gradient;
00829
00830 f_mle = gsl_vector_alloc(NUMTRIALS * (range+1));
00831 f_quick = gsl_vector_alloc(NUMTRIALS * (range+1));
00832 f_fp = gsl_vector_alloc(NUMTRIALS * (range+1));
00833 tau = gsl_vector_alloc(NUMTRIALS * (range+1));
00834 sl = gsl_vector_alloc(NUMTRIALS * (range+1));
00835
00836 fidelities = gsl_matrix_alloc(NUMTRIALS * (range+1), MAXITER);
00837 times = gsl_matrix_alloc(NUMTRIALS * (range+1), MAXITER);
00838 times_lin = gsl_vector_alloc(NUMTRIALS * (range+1));
00839 times_qd = gsl_vector_alloc(NUMTRIALS * (range+1));
00840 times_fp = gsl_vector_alloc(NUMTRIALS * (range+1));
00841 times_meas = gsl_vector_alloc(NUMTRIALS * (range+1));
00842 f_vals = gsl_matrix_alloc(NUMTRIALS * (range+1), MAXITER);
00843 abs_gradient = gsl_matrix_alloc(NUMTRIALS * (range+1), MAXITER);
00844 gsl_vector_set_zero(f_mle);
00845 gsl_vector_set_zero(f_quick);
00846 gsl_vector_set_zero(f_fp);
00847 gsl_vector_set_zero(tau);
00848 gsl_vector_set_zero(sl);
00849 gsl_vector_set_all(times_lin, GSL_NAN);
00850 gsl_vector_set_all(times_qd, GSL_NAN);
00851 gsl_vector_set_all(times_fp, GSL_NAN);
00852 gsl_vector_set_all(times_meas, GSL_NAN);
00853 gsl_matrix_set_all(fidelities, GSL_NAN);
00854 gsl_matrix_set_all(times, GSL_NAN);
00855 gsl_matrix_set_all(f_vals, GSL_NAN);
00856 gsl_matrix_set_all(abs_gradient, GSL_NAN);
00857
00858 int counter = 0, j;
00859
00860
00861 struct timeval tpstart, tpend;
00862 double timedif;
00863
00864 for (j = 0; j<=range; j++)
00865 {
00866 if (STATE == 10 || STATE == 12) {
00867
00868
00869 Werner_handle = (double)j/range;
00870
00871
00872 theta_handle = Werner_handle*(1.0/sqrt(2));
00873
00874
00875 prepare_state(density_theoretical);
00876 }
00877
00878 for (i=0; i<NUMTRIALS; i++) {
00879
00880
00881
00882
00883 printf("===========================\n");
00884 printf("Iteration percent complete: %e\n", (double)counter/(range+1)/NUMTRIALS*100);
00885 printf("===========================\n");
00886
00887 if (STATE == 9 ) {
00888
00889 prepare_state(density_theoretical);
00890 }
00891
00892
00893 gsl_vector_set(tau, counter, pow(concurrence(density_theoretical), 2));
00894 gsl_vector_set(sl, counter, entropy_linear(density_theoretical));
00895 printf("Tau: %e\n", gsl_vector_get(tau, counter));
00896 printf("Entropy Linear: %e\n", gsl_vector_get(sl, counter));
00897
00898
00899 gsl_matrix_complex_memcpy(density_physical, density_theoretical);
00900
00901
00902 printf("Measuring the state\n");
00903 gettimeofday(&tpstart, NULL);
00904 measure_state(density_physical, n);
00905 gettimeofday(&tpend, NULL);
00906 timedif = (double) MILLION*(tpend.tv_sec - tpstart.tv_sec);
00907 gsl_vector_set(times_meas, counter, timedif);
00908
00909
00910 gsl_vector_scale(n, N);
00911
00912 if (WRITE_DENSITY) {
00913
00914 printf("Writing data to disc - density_physical\n");
00915
00916 strncpy(output, "density_physical_trial_", MAXCHAR);
00917 snprintf(integer, MAXCHAR, "%d", counter);
00918 strncat(output, integer, MAXCHAR);
00919 write_data(output, density_physical);
00920 }
00921
00922
00923 printf("Applying experimental noise to data\n");
00924 apply_noise(n);
00925
00926 printf("Performing linear reconstruction\n");
00927
00928 gettimeofday(&tpstart, NULL);
00929 linear_estimate(n, density_linear);
00930 gettimeofday(&tpend, NULL);
00931 timedif = (double) MILLION*(tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec;
00932 gsl_vector_set(times_lin, counter, timedif);
00933
00934 if (WRITE_DENSITY) {
00935 printf("Writing data to disc - density_linear\n");
00936 strncpy(output, "density_linear_trial_", MAXCHAR);
00937 snprintf(integer, MAXCHAR, "%d", counter);
00938 strncat(output, integer, MAXCHAR);
00939 write_data(output, density_linear);
00940 }
00941
00942
00943 gsl_matrix_complex_memcpy(density_fp, density_linear);
00944
00945
00946 printf("Performing Quick and Dirty\n");
00947 gettimeofday(&tpstart, NULL);
00948 quick_and_dirty(density_linear, density_quick);
00949 gettimeofday(&tpend, NULL);
00950 timedif = (double) MILLION*(tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec;
00951 gsl_vector_set(times_qd, counter, timedif);
00952
00953 if (WRITE_DENSITY) {
00954 printf("Writing data to disc - density_quick\n");
00955
00956 strncpy(output, "density_quick_trial_", MAXCHAR);
00957 snprintf(integer, MAXCHAR, "%d", counter);
00958 strncat(output, integer, MAXCHAR);
00959 write_data(output, density_quick);
00960 }
00961
00962
00963 gsl_vector_set(f_quick, counter, fidelity(density_quick, density_physical));
00964 printf("Fidelity Quick: %e\n", gsl_vector_get(f_quick, counter));
00965
00966
00967 gsl_matrix_complex_memcpy(density_linear, density_fp);
00968
00969
00970 printf("Performing Forced Purity\n");
00971 gettimeofday(&tpstart, NULL);
00972 quick_and_dirty_2(density_linear, density_fp);
00973 gettimeofday(&tpend, NULL);
00974 timedif = (double) MILLION*(tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec;
00975 gsl_vector_set(times_fp, counter, timedif);
00976
00977 if (WRITE_DENSITY) {
00978 printf("Writing data to disc - density_fp\n");
00979 strncpy(output, "density_fp_trial_", MAXCHAR);
00980 snprintf(integer, MAXCHAR, "%d", counter);
00981 strncat(output, integer, MAXCHAR);
00982 write_data(output, density_fp);
00983 }
00984
00985
00986 gsl_vector_set(f_fp, counter, fidelity(density_fp, density_physical));
00987 printf("Fidelity Forced Purity: %e\n", gsl_vector_get(f_fp, counter));
00988
00989 if (DO_MLE) {
00990 printf("Performing MLE\n");
00991 MLE(n, density_physical, density_quick, density_mle, fidelities, times, f_vals, abs_gradient, counter);
00992
00993 if (WRITE_DENSITY) {
00994 printf("Writing data to disc - density_mle\n");
00995
00996
00997 strncpy(output, "density_mle_trial_", MAXCHAR);
00998 snprintf(integer, MAXCHAR, "%d", counter);
00999 strncat(output, integer, MAXCHAR);
01000 write_data(output, density_mle);
01001 }
01002
01003 gsl_vector_set(f_mle, counter, fidelity(density_mle, density_physical));
01004 printf("Fidelity MLE: %e\n", gsl_vector_get(f_mle, counter));
01005 }
01006
01007 counter++;
01008 }
01009 }
01010
01011
01012
01013 printf("Writing data to disc - fidelities and times vectors\n");
01014 write_vector_real("f_mle", f_mle);
01015 write_vector_real("f_quick", f_quick);
01016 write_vector_real("f_fp", f_fp);
01017 write_vector_real("tau", tau);
01018 write_vector_real("times_lin", times_lin);
01019 write_vector_real("times_meas", times_meas);
01020 write_matrix_real("fidelities", fidelities);
01021 write_matrix_real("times_mle", times);
01022 write_vector_real("times_qd", times_qd);
01023 write_vector_real("times_fp", times_fp);
01024 write_matrix_real("f_vals", f_vals);
01025 write_matrix_real("abs_gradient", abs_gradient);
01026
01027
01028 gsl_matrix_complex_free(density_physical);
01029 gsl_matrix_complex_free(density_theoretical);
01030 gsl_matrix_complex_free(density_linear);
01031 gsl_matrix_complex_free(density_quick);
01032 gsl_matrix_complex_free(density_mle);
01033 gsl_vector_free(n);
01034 gsl_vector_free(result);
01035
01036 gsl_matrix_free(fidelities);
01037 gsl_matrix_free(times);
01038 }
01039
01040 void
01041 quick_and_dirty(gsl_matrix_complex *density_linear, gsl_matrix_complex *density_quick) {
01042
01043 int i;
01044
01045 gsl_eigen_hermv_workspace *w = gsl_eigen_hermv_alloc (pow(2,NQ));
01046
01047 gsl_vector *eval = gsl_vector_alloc(pow(2,NQ));
01048
01049 gsl_matrix_complex *evec = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
01050
01051
01052 gsl_matrix_complex_memcpy(density_quick, density_linear);
01053 if ((gsl_eigen_hermv (density_quick, eval, evec, w)) != 0) {
01054
01055 gsl_matrix_complex_memcpy(density_quick, density_linear);
01056 printf("Failed at finding eigenvalues and eigenvectors\n");
01057 printf("Quick and Dirty Estimate not available\n");
01058 return;
01059 } else {
01060 if (VERBOSE)
01061 printf("Succeeded in finding eigenvalues and eigenvectors\n");
01062 }
01063
01064
01065
01066
01067
01068
01069
01070
01071 for (i=0; i<pow(2,NQ); i++)
01072 if (gsl_vector_get(eval, i)<0)
01073 gsl_vector_set(eval, i, 0);
01074
01075 gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_ABS_ASC);
01076
01077
01078 gsl_matrix_complex *eval_matrix = gsl_matrix_complex_alloc(pow(2,NQ), pow(2, NQ));
01079 gsl_matrix_complex_set_zero(eval_matrix);
01080 for (i=0; i<pow(2,NQ); i++)
01081 gsl_matrix_complex_set(eval_matrix, i, i, gsl_complex_rect(gsl_vector_get(eval, i), 0));
01082
01083
01084
01085 gsl_matrix_complex *tmp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
01086 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, evec, eval_matrix, zero, tmp);
01087 gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, tmp, evec, zero, density_quick);
01088
01089
01090 gsl_matrix_complex_scale(density_quick, gsl_complex_rect(1.0/GSL_REAL(trace(density_quick)), 0));
01091
01092
01093 gsl_matrix_complex_free(eval_matrix);
01094 gsl_eigen_hermv_free(w);
01095 gsl_vector_free(eval);
01096 gsl_matrix_complex_free(evec);
01097 gsl_matrix_complex_free(tmp);
01098 }
01099
01100 void
01101 quick_and_dirty_2(gsl_matrix_complex *density_linear, gsl_matrix_complex *density_quick) {
01102
01103 int i;
01104
01105 gsl_eigen_hermv_workspace *w = gsl_eigen_hermv_alloc (pow(2,NQ));
01106
01107 gsl_vector *eval = gsl_vector_alloc(pow(2,NQ));
01108
01109 gsl_matrix_complex *evec = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
01110
01111
01112 gsl_matrix_complex_memcpy(density_quick, density_linear);
01113 if ((gsl_eigen_hermv (density_quick, eval, evec, w)) != 0) {
01114
01115 gsl_matrix_complex_memcpy(density_quick, density_linear);
01116 printf("Failed at finding eigenvalues and eigenvectors\n");
01117 printf("Quick and Dirty Estimate not available\n");
01118 return;
01119 } else {
01120 if (VERBOSE)
01121 printf("Succeeded in finding eigenvalues and eigenvectors\n");
01122 }
01123
01124
01125 gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC);
01126
01127
01128
01129
01130
01131
01132 for (i=0; i<pow(2,NQ); i++)
01133 if (i==pow(2,NQ)-1)
01134 gsl_vector_set(eval, i, 1.0);
01135 else
01136 gsl_vector_set(eval, i, 0.0);
01137
01138
01139
01140
01141
01142
01143 gsl_matrix_complex *eval_matrix = gsl_matrix_complex_alloc(pow(2,NQ), pow(2, NQ));
01144 gsl_matrix_complex_set_zero(eval_matrix);
01145 for (i=0; i<pow(2,NQ); i++)
01146 gsl_matrix_complex_set(eval_matrix, i, i, gsl_complex_rect(gsl_vector_get(eval, i), 0));
01147
01148
01149
01150 gsl_matrix_complex *tmp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
01151 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, evec, eval_matrix, zero, tmp);
01152 gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, tmp, evec, zero, density_quick);
01153
01154
01155 gsl_matrix_complex_scale(density_quick, gsl_complex_rect(1.0/GSL_REAL(trace(density_quick)), 0));
01156
01157
01158 gsl_matrix_complex_free(eval_matrix);
01159 gsl_eigen_hermv_free(w);
01160 gsl_vector_free(eval);
01161 gsl_matrix_complex_free(evec);
01162 gsl_matrix_complex_free(tmp);
01163 }
01164
01165 void
01166 MLE(gsl_vector *n, gsl_matrix_complex *density_physical, gsl_matrix_complex *density_linear, gsl_matrix_complex *density_mle, gsl_matrix *fidelities, gsl_matrix *times, gsl_matrix *f_vals, gsl_matrix *abs_gradient, int trial) {
01167
01168
01169
01170 gsl_vector *x = gsl_vector_alloc(pow(4,NQ));
01171
01172
01173 int counter, limiter, nu;
01174 counter = 1;
01175 for (limiter = 0; limiter < pow(2, NQ); limiter++) {
01176 for (nu=1+limiter; nu <= pow(2, NQ); nu++) {
01177 if (counter<=pow(2, NQ)) {
01178 gsl_vector_set(x, counter-1, GSL_REAL(gsl_matrix_complex_get(density_linear, nu-1, nu-1)));
01179 } else {
01180 gsl_vector_set(x, counter-1, GSL_REAL(gsl_matrix_complex_get(density_linear, nu-1, nu-1-limiter)));
01181 gsl_vector_set(x, counter, GSL_IMAG(gsl_matrix_complex_get(density_linear, nu-1, nu-1-limiter)));
01182
01183 counter++;
01184
01185 }
01186 counter++;
01187 }
01188 }
01189
01190
01191
01192
01193
01194
01195
01196 gsl_vector_set(x, 0, pow(4, -NQ));
01197
01198
01199 const gsl_multimin_fdfminimizer_type *T;
01200 gsl_multimin_fdfminimizer *s;
01201
01202
01203
01204
01205 T = gsl_multimin_fdfminimizer_vector_bfgs2;
01206
01207 s = gsl_multimin_fdfminimizer_alloc(T, pow(4,NQ));
01208 gsl_multimin_function_fdf my_func;
01209 size_t iter = 0;
01210 int status;
01211
01212 my_func.f = &my_f;
01213 my_func.df = &my_df;
01214 my_func.fdf = &my_fdf;
01215
01216 my_func.n = pow(4,NQ);
01217 my_func.params = n;
01218
01219
01220
01221
01222
01223 gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4);
01224
01225
01226
01227
01228
01229 int truth=1;
01230
01231
01232 gsl_matrix_complex *temp_mle = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01233
01234 gsl_matrix_complex *T_mat = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01235
01236
01237
01238
01239
01240 struct timeval tpstart_iter, tpend_iter;
01241 double timedif_iter;
01242
01243 double temp_fid;
01244
01245
01246 double previous_fidelity = -999.0;
01247 double previous_f_value = -1.0;
01248 gsl_vector *previous_t = gsl_vector_alloc(pow(4, NQ));
01249
01250 do {
01251
01252 gettimeofday(&tpstart_iter, NULL);
01253
01254 status = gsl_multimin_fdfminimizer_iterate (s);
01255
01256
01257 if (status)
01258 break;
01259
01260 status = gsl_multimin_test_gradient (s->gradient, 1e-3);
01261
01262
01263 if (status == GSL_SUCCESS)
01264 printf ("Minimum found.\n");
01265
01266 if (VERBOSE)
01267 printf("%d: f() = %7.3f \n", iter, s->f);
01268
01269
01270 gettimeofday(&tpend_iter, NULL);
01271 timedif_iter = (double) MILLION*(tpend_iter.tv_sec - tpstart_iter.tv_sec) + tpend_iter.tv_usec - tpstart_iter.tv_usec;
01272
01273
01274 make_T(s->x, T_mat);
01275 gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, T_mat, T_mat, zero, temp_mle);
01276 gsl_matrix_complex_scale(temp_mle, gsl_complex_rect(1.0/GSL_REAL(trace(temp_mle)), 0));
01277
01278
01279 temp_fid = fidelity(temp_mle, density_physical);
01280
01281
01282
01283 if (temp_fid >= MAX_FIDELITY && KEEP_GOING==0)
01284 truth = 0;
01285
01286
01287 if (CUT_ITER == 1) {
01288 if (iter>0) {
01289 if ((previous_f_value - s->f) <= 1.0) {
01290 truth = 0;
01291 }
01292 }
01293 }
01294
01295 previous_f_value = s->f;
01296
01297 if (KEEP_GOING == 0) {
01298
01299
01300 if (previous_fidelity > temp_fid) {
01301 truth = 0;
01302 gsl_vector_memcpy(s->x, previous_t);
01303 }
01304 }
01305
01306
01307 previous_fidelity = temp_fid;
01308 gsl_vector_memcpy(previous_t, s->x);
01309
01310
01311
01312 gsl_matrix_set(fidelities, trial, iter, temp_fid);
01313 gsl_matrix_set(times, trial, iter, timedif_iter);
01314 gsl_matrix_set(f_vals, trial, iter, s->f);
01315 gsl_matrix_set(abs_gradient, trial, iter, abs_val(s->gradient));
01316
01317
01318
01319 if ((s->f) == GSL_POSINF) {
01320 printf("Either no point in using MLE or we have a bad guess\n");
01321 truth = 0;
01322 }
01323
01324
01325 iter++;
01326
01327 } while (status == GSL_CONTINUE && truth && iter<MAXITER);
01328
01329 if (!VERBOSE)
01330 printf("%d: f() = %7.3f \n", iter, s->f);
01331
01332
01333 make_T(s->x, T_mat);
01334 gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, T_mat, T_mat, zero, density_mle);
01335 gsl_matrix_complex_scale(density_mle, gsl_complex_rect(1.0/GSL_REAL(trace(density_mle)), 0));
01336
01337
01338 gsl_multimin_fdfminimizer_free(s);
01339 gsl_vector_free(x);
01340 gsl_vector_free(previous_t);
01341 gsl_matrix_complex_free(T_mat);
01342 gsl_matrix_complex_free(temp_mle);
01343
01344 }
01345
01346
01347
01348 double
01349 my_f(const gsl_vector * x, void * n) {
01350 gsl_matrix_complex *rho_mat = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01351 gsl_matrix_complex *T_mat = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01352 make_T(x, T_mat);
01353
01354 gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, T_mat, T_mat, zero, rho_mat);
01355
01356 gsl_matrix_complex_scale(rho_mat, gsl_complex_rect(1/GSL_REAL(trace(rho_mat)), 0));
01357
01358 int i, nu;
01359 double ret=0;
01360
01361
01362 int counter[NQ], old_counter[NQ];
01363 for (i=0; i<NQ-1; i++) {
01364 counter[i]=0;
01365 old_counter[i]=0;
01366 }
01367 counter[NQ-1]=-1;
01368 old_counter[NQ-1]=-1;
01369
01370
01371 gsl_matrix_complex_memcpy(mu_cell[0], mu_array[0]);
01372 for (i=1; i<NQ; i++)
01373 kron(mu_cell[i-1], mu_array[0], mu_cell[i]);
01374
01375 for (nu=0; nu<pow(4, NQ); nu++) {
01376 base_4_rep_inc(counter, nu);
01377
01378 mu_tensor(mu_cell, mu_array, old_counter, counter);
01379
01380 for (i=0; i<NQ; i++)
01381 old_counter[i] = counter[i];
01382
01383
01384 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, mu_cell[NQ-1], rho_mat, zero, T_mat);
01385
01386
01387
01388 ret+=pow(((double)N*GSL_REAL(trace(T_mat))-gsl_vector_get(n, nu)),2)/gsl_vector_get(n,nu);
01389 }
01390 ret*=(double)1/2;
01391
01392 gsl_matrix_complex_free(T_mat);
01393 gsl_matrix_complex_free(rho_mat);
01394
01395 return ret;
01396 }
01397
01398 void
01399 my_df(const gsl_vector * x_vec, void * n, gsl_vector * g) {
01400 gsl_matrix_complex *rho_mat = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01401 gsl_matrix_complex *T_mat = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01402 make_T(x_vec, T_mat);
01403 gsl_matrix_complex *T_dag_T = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01404 gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, T_mat, T_mat, zero, rho_mat);
01405 gsl_matrix_complex_memcpy(T_dag_T, rho_mat);
01406
01407 double tr_T_dag_T = GSL_REAL(trace(T_dag_T));
01408 gsl_matrix_complex_scale(rho_mat, gsl_complex_rect(1/tr_T_dag_T,0));
01409
01410
01411
01412 int i, j;
01413 gsl_matrix *X, *Y;
01414 X = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01415 Y = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01416 for (i=0; i<pow(2, NQ); i++) {
01417 for (j=0; j<pow(2, NQ); j++) {
01418 gsl_matrix_set(X, i, j, GSL_REAL(gsl_matrix_complex_get(T_mat, i, j)));
01419 gsl_matrix_set(Y, i, j, GSL_IMAG(gsl_matrix_complex_get(T_mat, i, j)));
01420 }
01421 }
01422
01423 gsl_matrix_complex *Answer = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01424
01425 gsl_matrix_complex_set_zero(Answer);
01426
01427 int counter[NQ], old_counter[NQ];
01428 for (i=0; i<NQ-1; i++) {
01429 counter[i]=0;
01430 old_counter[i]=0;
01431 }
01432 counter[NQ-1]=-1;
01433 old_counter[NQ-1]=-1;
01434
01435
01436 gsl_matrix_complex_memcpy(mu_cell[0], mu_array[0]);
01437 for (i=1; i<NQ; i++)
01438 kron(mu_cell[i-1], mu_array[0], mu_cell[i]);
01439
01440
01441 gsl_matrix_complex *temp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2, NQ));
01442 gsl_matrix_complex_set_zero(temp);
01443
01444 gsl_matrix *K, *L;
01445 K = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01446 L = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01447
01448 gsl_matrix *XK, *YL, *XL, *YK;
01449 XK = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01450 YK = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01451 XL = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01452 YL = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01453
01454
01455 gsl_complex temp_num;
01456 double real, imag;
01457 double x, y, xk, xl, yl, yk;
01458 int nu;
01459 double tr_mu_rho, tr_mu_T_dag_T, scale;
01460 for (nu=0; nu<pow(4, NQ); nu++) {
01461 base_4_rep_inc(counter, nu);
01462
01463 mu_tensor(mu_cell, mu_array, old_counter, counter);
01464 for (i=0; i<NQ; i++)
01465 old_counter[i] = counter[i];
01466
01467 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, mu_cell[NQ-1], rho_mat, zero, temp);
01468 tr_mu_rho = GSL_REAL(trace(temp));
01469 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, mu_cell[NQ-1], T_dag_T, zero, temp);
01470 tr_mu_T_dag_T = GSL_REAL(trace(temp));
01471
01472 scale = ((double)N*tr_mu_rho - gsl_vector_get(n,nu))/gsl_vector_get(n,nu);
01473
01474 for (i=0; i<pow(2, NQ); i++) {
01475 for (j=0; j<pow(2, NQ); j++) {
01476 gsl_matrix_set(K, i, j, GSL_REAL(gsl_matrix_complex_get(mu_cell[NQ-1], i, j)));
01477 gsl_matrix_set(L, i, j, GSL_IMAG(gsl_matrix_complex_get(mu_cell[NQ-1], i, j)));
01478 }
01479 }
01480
01481 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, X, K, 0.0, XK);
01482 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, X, L, 0.0, XL);
01483 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, Y, K, 0.0, YK);
01484 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, Y, L, 0.0, YL);
01485
01486
01487
01488
01489 for (i=0; i<pow(2, NQ); i++) {
01490 for (j=0; j<i+1; j++) {
01491 x = gsl_matrix_get(X, i, j);
01492 y = gsl_matrix_get(Y, i, j);
01493 xk = gsl_matrix_get(XK, i, j);
01494 xl = gsl_matrix_get(XL, i, j);
01495 yk = gsl_matrix_get(YK, i, j);
01496 yl = gsl_matrix_get(YL, i, j);
01497 real = tr_T_dag_T*2*(xk - yl) - tr_mu_T_dag_T*2*x;
01498 imag = tr_T_dag_T*2*(xl + yk) - tr_mu_T_dag_T*2*y;
01499
01500 temp_num = gsl_complex_rect(real, imag);
01501
01502 temp_num = gsl_complex_mul(temp_num, gsl_complex_rect(scale,0));
01503 gsl_matrix_complex_set(Answer, i, j,
01504 gsl_complex_add(gsl_matrix_complex_get(Answer,i,j),temp_num));
01505
01506 }
01507 }
01508
01509 }
01510
01511
01512
01513 gsl_matrix_complex_scale(Answer, gsl_complex_rect(N/(tr_T_dag_T*tr_T_dag_T), 0));
01514
01515
01516 int row = 2;
01517 int col = 1;
01518 int prev_row = row;
01519
01520 i=1;
01521 while (i<=pow(4,NQ)) {
01522 if (i<=pow(2, NQ)) {
01523 gsl_vector_set(g, i-1, GSL_REAL(gsl_matrix_complex_get(Answer, i-1,i-1)));
01524 } else {
01525 gsl_vector_set(g, i-1, GSL_REAL(gsl_matrix_complex_get(Answer, row-1,col-1)));
01526 i++;
01527 gsl_vector_set(g, i-1, GSL_IMAG(gsl_matrix_complex_get(Answer, row-1, col-1)));
01528 row++;
01529 col++;
01530 if (row>pow(2, NQ)) {
01531 prev_row++;
01532 row = prev_row;
01533 col=1;
01534 }
01535 }
01536 i++;
01537 }
01538
01539
01540 gsl_matrix_complex_free(Answer);
01541 gsl_matrix_free(X);
01542 gsl_matrix_free(Y);
01543 gsl_matrix_free(K);
01544 gsl_matrix_free(L);
01545
01546 gsl_matrix_free(XK);
01547 gsl_matrix_free(YL);
01548 gsl_matrix_free(YK);
01549 gsl_matrix_free(XL);
01550
01551 gsl_matrix_complex_free(T_mat);
01552 gsl_matrix_complex_free(rho_mat);
01553 gsl_matrix_complex_free(temp);
01554 gsl_matrix_complex_free(T_dag_T);
01555
01556
01557
01558 }
01559
01560 void
01561 my_fdf(const gsl_vector * x_vec, void *n, double * f, gsl_vector * g) {
01562
01563 gsl_matrix_complex *rho_mat = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01564 gsl_matrix_complex *T_mat = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01565 make_T(x_vec, T_mat);
01566 gsl_matrix_complex *T_dag_T = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01567 gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, T_mat, T_mat, zero, rho_mat);
01568 gsl_matrix_complex_memcpy(T_dag_T, rho_mat);
01569
01570 double tr_T_dag_T = GSL_REAL(trace(T_dag_T));
01571 gsl_matrix_complex_scale(rho_mat, gsl_complex_rect(1/tr_T_dag_T,0));
01572
01573
01574
01575 int i, j;
01576 gsl_matrix *X, *Y;
01577 X = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01578 Y = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01579 for (i=0; i<pow(2, NQ); i++) {
01580 for (j=0; j<pow(2, NQ); j++) {
01581 gsl_matrix_set(X, i, j, GSL_REAL(gsl_matrix_complex_get(T_mat, i, j)));
01582 gsl_matrix_set(Y, i, j, GSL_IMAG(gsl_matrix_complex_get(T_mat, i, j)));
01583 }
01584 }
01585
01586 gsl_matrix_complex *Answer = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01587
01588 gsl_matrix_complex_set_zero(Answer);
01589
01590 int counter[NQ], old_counter[NQ];
01591 for (i=0; i<NQ-1; i++) {
01592 counter[i]=0;
01593 old_counter[i]=0;
01594 }
01595 counter[NQ-1]=-1;
01596 old_counter[NQ-1]=-1;
01597
01598
01599 gsl_matrix_complex_memcpy(mu_cell[0], mu_array[0]);
01600 for (i=1; i<NQ; i++)
01601 kron(mu_cell[i-1], mu_array[0], mu_cell[i]);
01602
01603
01604 gsl_matrix_complex *temp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2, NQ));
01605 gsl_matrix_complex_set_zero(temp);
01606
01607 gsl_matrix *K, *L;
01608 K = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01609 L = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01610
01611 gsl_matrix *XK, *YL, *XL, *YK;
01612 XK = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01613 YK = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01614 XL = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01615 YL = gsl_matrix_alloc(pow(2, NQ), pow(2, NQ));
01616
01617
01618 gsl_complex temp_num;
01619 double real, imag;
01620 double x, y, xk, xl, yl, yk;
01621 int nu;
01622 double tr_mu_rho, tr_mu_T_dag_T, scale;
01623 (*f) = 0;
01624 for (nu=0; nu<pow(4, NQ); nu++) {
01625 base_4_rep_inc(counter, nu);
01626
01627 mu_tensor(mu_cell, mu_array, old_counter, counter);
01628 for (i=0; i<NQ; i++)
01629 old_counter[i] = counter[i];
01630
01631 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, mu_cell[NQ-1], rho_mat, zero, temp);
01632 tr_mu_rho = GSL_REAL(trace(temp));
01633 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, mu_cell[NQ-1], T_dag_T, zero, temp);
01634 tr_mu_T_dag_T = GSL_REAL(trace(temp));
01635
01636 scale = ((double)N*tr_mu_rho - gsl_vector_get(n,nu))/gsl_vector_get(n,nu);
01637
01638 (*f) += pow((double)N*tr_mu_rho - gsl_vector_get(n,nu), 2)/gsl_vector_get(n,nu);
01639
01640 for (i=0; i<pow(2, NQ); i++) {
01641 for (j=0; j<pow(2, NQ); j++) {
01642 gsl_matrix_set(K, i, j, GSL_REAL(gsl_matrix_complex_get(mu_cell[NQ-1], i, j)));
01643 gsl_matrix_set(L, i, j, GSL_IMAG(gsl_matrix_complex_get(mu_cell[NQ-1], i, j)));
01644 }
01645 }
01646
01647 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, X, K, 0.0, XK);
01648 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, X, L, 0.0, XL);
01649 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, Y, K, 0.0, YK);
01650 gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, Y, L, 0.0, YL);
01651
01652
01653
01654
01655 for (i=0; i<pow(2, NQ); i++) {
01656 for (j=0; j<i+1; j++) {
01657 x = gsl_matrix_get(X, i, j);
01658 y = gsl_matrix_get(Y, i, j);
01659 xk = gsl_matrix_get(XK, i, j);
01660 xl = gsl_matrix_get(XL, i, j);
01661 yk = gsl_matrix_get(YK, i, j);
01662 yl = gsl_matrix_get(YL, i, j);
01663 real = tr_T_dag_T*2*(xk - yl) - tr_mu_T_dag_T*2*x;
01664 imag = tr_T_dag_T*2*(xl + yk) - tr_mu_T_dag_T*2*y;
01665
01666 temp_num = gsl_complex_rect(real, imag);
01667
01668 temp_num = gsl_complex_mul(temp_num, gsl_complex_rect(scale,0));
01669 gsl_matrix_complex_set(Answer, i, j,
01670 gsl_complex_add(gsl_matrix_complex_get(Answer,i,j),temp_num));
01671
01672 }
01673 }
01674
01675 }
01676
01677
01678
01679 (*f) *= (double) 1/2;
01680
01681 gsl_matrix_complex_scale(Answer, gsl_complex_rect(N/(tr_T_dag_T*tr_T_dag_T), 0));
01682
01683
01684 int row = 2;
01685 int col = 1;
01686 int prev_row = row;
01687
01688 i=1;
01689 while (i<=pow(4,NQ)) {
01690 if (i<=pow(2, NQ)) {
01691 gsl_vector_set(g, i-1, GSL_REAL(gsl_matrix_complex_get(Answer, i-1,i-1)));
01692 } else {
01693 gsl_vector_set(g, i-1, GSL_REAL(gsl_matrix_complex_get(Answer, row-1,col-1)));
01694 i++;
01695 gsl_vector_set(g, i-1, GSL_IMAG(gsl_matrix_complex_get(Answer, row-1, col-1)));
01696 row++;
01697 col++;
01698 if (row>pow(2, NQ)) {
01699 prev_row++;
01700 row = prev_row;
01701 col=1;
01702 }
01703 }
01704 i++;
01705 }
01706
01707
01708 gsl_matrix_complex_free(Answer);
01709 gsl_matrix_free(X);
01710 gsl_matrix_free(Y);
01711 gsl_matrix_free(K);
01712 gsl_matrix_free(L);
01713
01714 gsl_matrix_free(XK);
01715 gsl_matrix_free(YL);
01716 gsl_matrix_free(YK);
01717 gsl_matrix_free(XL);
01718
01719 gsl_matrix_complex_free(T_mat);
01720 gsl_matrix_complex_free(rho_mat);
01721 gsl_matrix_complex_free(temp);
01722 gsl_matrix_complex_free(T_dag_T);
01723
01724
01725 }
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746 void
01747 linear_estimate(gsl_vector *n, gsl_matrix_complex *density_linear) {
01748
01749 gsl_matrix *gamma = gsl_matrix_alloc(4, 4);
01750 gsl_matrix_set(gamma, 0, 0, 1);
01751 gsl_matrix_set(gamma, 0, 1, 0);
01752 gsl_matrix_set(gamma, 0, 2, 0);
01753 gsl_matrix_set(gamma, 0, 3, 0);
01754 gsl_matrix_set(gamma, 1, 0, 1);
01755 gsl_matrix_set(gamma, 1, 1, 0);
01756 gsl_matrix_set(gamma, 1, 2, -1);
01757 gsl_matrix_set(gamma, 1, 3, 0);
01758 gsl_matrix_set(gamma, 2, 0, 1);
01759 gsl_matrix_set(gamma, 2, 1, 0);
01760 gsl_matrix_set(gamma, 2, 2, 0);
01761 gsl_matrix_set(gamma, 2, 3, -1);
01762 gsl_matrix_set(gamma, 3, 0, -1);
01763 gsl_matrix_set(gamma, 3, 1, 1);
01764 gsl_matrix_set(gamma, 3, 2, 0);
01765 gsl_matrix_set(gamma, 3, 3, 0);
01766
01767
01768
01769 gsl_matrix_complex_set_zero(density_linear);
01770 int base_4_nu[NQ], base_4_mu[NQ], base_4_nu_old[NQ], i;
01771 int nu, mu, bcount;
01772 double temp, B_inv_element;
01773 gsl_matrix_complex *temporary = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01774 for (i=0; i<NQ-1; i++) {
01775 base_4_nu[i]=0;
01776 base_4_nu_old[i]=0;
01777 base_4_mu[i]=0;
01778 }
01779 base_4_nu[NQ-1] = -1;
01780 base_4_mu[NQ-1] = -1;
01781 base_4_nu_old[NQ-1] = -1;
01782
01783 for (nu=0; nu<pow(4,NQ); nu++) {
01784 temp = 0;
01785 base_4_rep_inc(base_4_nu, nu);
01786
01787 for (mu=0; mu<pow(4,NQ); mu++) {
01788 base_4_rep_inc(base_4_mu, mu);
01789
01790
01791
01792 B_inv_element = 1;
01793 for (bcount = 0; bcount<NQ; bcount++) {
01794 B_inv_element*=gsl_matrix_get(gamma, base_4_nu[bcount], base_4_mu[bcount]);
01795 }
01796 temp+=B_inv_element*gsl_vector_get(n, mu);
01797 }
01798
01799
01800 for (i=0; i<NQ-1; i++)
01801 base_4_mu[i] = 0;
01802 base_4_mu[NQ-1] = -1;
01803
01804 sig_tensor(sigma_cell, sig_array, base_4_nu_old, base_4_nu);
01805
01806
01807 for (i=0; i<NQ; i++)
01808 base_4_nu_old[i] = base_4_nu[i];
01809
01810 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, sigma_cell[NQ-1], sigma_cell[NQ-1], zero, temporary);
01811
01812
01813
01814
01815 gsl_complex normalize;
01816 GSL_SET_COMPLEX(&normalize, sqrt(1/GSL_REAL(trace(temporary))), 0);
01817 gsl_matrix_complex_scale(sigma_cell[NQ-1], normalize);
01818 gsl_matrix_complex_scale(sigma_cell[NQ-1], gsl_complex_rect(temp, 0));
01819
01820 gsl_matrix_complex_add(density_linear, sigma_cell[NQ-1]);
01821
01822 }
01823
01824
01825 gsl_complex tmp;
01826 GSL_SET_COMPLEX(&tmp, 1/gsl_vector_get(n, 0)/sqrt(pow(2,NQ)), 0);
01827 gsl_matrix_complex_scale(density_linear, tmp);
01828
01829 gsl_matrix_free(gamma);
01830 gsl_matrix_complex_free(temporary);
01831
01832 }
01833
01834 void
01835 init() {
01836
01837 load_basis();
01838
01839 GSL_SET_COMPLEX(&zero, 0, 0);
01840 GSL_SET_COMPLEX(&one, 1, 0);
01841 ones = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01842 gsl_matrix_complex_set_all(ones, one);
01843
01844 int i;
01845 mu_cell[0] = gsl_matrix_complex_alloc(2, 2);
01846 gsl_matrix_complex_memcpy(mu_cell[0], mu_array[0]);
01847 for (i=1; i<NQ; i++) {
01848 mu_cell[i] = gsl_matrix_complex_alloc((mu_cell[i-1]->size1)*2, (mu_cell[i-1]->size2)*2);
01849
01850
01851
01852 kron(mu_cell[i-1], mu_array[0], mu_cell[i]);
01853 }
01854
01855
01856 sigma_cell[0] = gsl_matrix_complex_alloc(2,2);
01857 gsl_matrix_complex_memcpy(sigma_cell[0], sig_array[0]);
01858 for (i=1; i<NQ; i++) {
01859 sigma_cell[i] = gsl_matrix_complex_alloc((sigma_cell[i-1]->size1)*2, (sigma_cell[i-1]->size2)*2);
01860 kron(sigma_cell[i-1], sig_array[0], sigma_cell[i]);
01861 }
01862
01863
01864 N = 1000000;
01865 }
01866
01867 void
01868 prepare_state(gsl_matrix_complex *density_random) {
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887 if (STATE==1) {
01888
01889
01890 gsl_vector_complex *ghz_vec = gsl_vector_complex_alloc(pow(2, NQ));
01891 gsl_vector_complex_set_zero(ghz_vec);
01892 gsl_vector_complex_set(ghz_vec, 0, gsl_complex_rect(1/sqrt(2), 0));
01893 gsl_vector_complex_set(ghz_vec, pow(2, NQ)-1, gsl_complex_rect(1/sqrt(2), 0));
01894
01895
01896
01897 outer_product(ghz_vec, density_random);
01898
01899
01900 gsl_vector_complex_free(ghz_vec);
01901 } else if (STATE==2) {
01902
01903 gsl_matrix_complex_set_zero(density_random);
01904 gsl_matrix_complex_set(density_random, 0, 0, gsl_complex_rect(1, 0));
01905
01906 } else if (STATE==3 || STATE==4 || STATE ==5 || STATE == 10) {
01907 gsl_matrix_complex *identity = gsl_matrix_complex_alloc(pow(2, NQ), pow(2, NQ));
01908 gsl_matrix_complex_set_zero(identity);
01909 int i;
01910 for (i=0; i<pow(2, NQ); i++)
01911 gsl_matrix_complex_set(identity, i, i, gsl_complex_rect(1/pow(2, NQ), 0));
01912
01913 gsl_complex eps, one_min_eps;
01914 double value;
01915 if (STATE==3)
01916 value = 0.2;
01917 else if (STATE==4)
01918 value = 0.80475;
01919 else if (STATE==5)
01920 value = 0.99;
01921 else if (STATE == 10)
01922 value = Werner_handle;
01923
01924 GSL_SET_COMPLEX(&eps, value, 0);
01925 GSL_SET_COMPLEX(&one_min_eps, 1.0-value, 0);
01926
01927
01928 gsl_vector_complex *ghz_vec = gsl_vector_complex_alloc(pow(2, NQ));
01929 gsl_vector_complex_set_zero(ghz_vec);
01930 gsl_vector_complex_set(ghz_vec, 0, gsl_complex_rect(1/sqrt(2), 0));
01931 gsl_vector_complex_set(ghz_vec, pow(2, NQ)-1, gsl_complex_rect(1/sqrt(2), 0));
01932 outer_product(ghz_vec, density_random);
01933 gsl_vector_complex_free(ghz_vec);
01934
01935 gsl_matrix_complex_scale(identity, one_min_eps);
01936 gsl_matrix_complex_scale(density_random, eps);
01937
01938 gsl_matrix_complex_add(density_random, identity);
01939
01940 gsl_matrix_complex_free(identity);
01941 } else if (STATE == 6) {
01942 if (NQ != 2) {
01943 fprintf(stderr, "MEMS state is only defined for 2 Qubits\n");
01944 exit(1);
01945 }
01946 gsl_matrix_complex_set_zero(density_random);
01947
01948
01949
01950
01951 double gam = 0.74 + 0.0123;
01952
01953
01954
01955
01956 gsl_matrix_complex_set(density_random, 0, 0, gsl_complex_rect(gam/2.0, 0));
01957 gsl_matrix_complex_set(density_random, 0, 3, gsl_complex_rect(gam/2.0, 0));
01958 gsl_matrix_complex_set(density_random, 1, 1, gsl_complex_rect(1.0-gam, 0));
01959 gsl_matrix_complex_set(density_random, 3, 0, gsl_complex_rect(gam/2.0, 0));
01960 gsl_matrix_complex_set(density_random, 3, 3, gsl_complex_rect(gam/2.0, 0));
01961
01962 } else if (STATE == 7) {
01963 gsl_matrix_complex_set_zero(density_random);
01964 int i;
01965 for (i=0; i<pow(2, NQ); i++)
01966 gsl_matrix_complex_set(density_random, i, i, gsl_complex_rect(1/pow(2, NQ), 0));
01967
01968 } else if (STATE == 8) {
01969
01970 gsl_vector_complex *w_state = gsl_vector_complex_alloc(pow(2, NQ));
01971 gsl_matrix_complex *middle = gsl_matrix_complex_alloc(1, 2);
01972 gsl_vector_complex_set_zero(w_state);
01973
01974 int temp[NQ], i, j;
01975 for (i=0; i<NQ; i++)
01976 temp[i] = 0;
01977
01978
01979
01980 gsl_matrix_complex *after = gsl_matrix_complex_alloc(1, 1);
01981 gsl_matrix_complex *before = gsl_matrix_complex_alloc(1, 1);
01982 for (i=0; i<NQ; i++) {
01983 temp[i] = 1;
01984
01985 gsl_matrix_complex_free(before);
01986 gsl_matrix_complex *before = gsl_matrix_complex_alloc(1, 2);
01987
01988 if (temp[0] == 1) {
01989 gsl_matrix_complex_set(before, 0, 0, gsl_complex_rect(0.0, 0.0));
01990 gsl_matrix_complex_set(before, 0, 1, gsl_complex_rect(1.0, 0.0));
01991 } else {
01992 gsl_matrix_complex_set(before, 0, 0, gsl_complex_rect(1.0, 0.0));
01993 gsl_matrix_complex_set(before, 0, 1, gsl_complex_rect(0.0, 0.0));
01994 }
01995 for (j=1; j<NQ; j++) {
01996 if (temp[j] == 1) {
01997 gsl_matrix_complex_set(middle, 0, 0, gsl_complex_rect(0.0, 0.0));
01998 gsl_matrix_complex_set(middle, 0, 1, gsl_complex_rect(1.0, 0.0));
01999 } else {
02000 gsl_matrix_complex_set(middle, 0, 0, gsl_complex_rect(1.0, 0.0));
02001 gsl_matrix_complex_set(middle, 0, 1, gsl_complex_rect(0.0, 0.0));
02002 }
02003 gsl_matrix_complex_free(after);
02004 gsl_matrix_complex *after = gsl_matrix_complex_alloc(1, 2*(before->size2));
02005 kron(before, middle, after);
02006
02007 gsl_matrix_complex_free(before);
02008 gsl_matrix_complex *before = gsl_matrix_complex_alloc(1, after->size2);
02009 gsl_matrix_complex_memcpy(before, after);
02010 }
02011
02012
02013
02014
02015 for (j=0; j<pow(2, NQ); j++)
02016 gsl_vector_complex_set(w_state, j, gsl_complex_add(gsl_vector_complex_get(w_state, j), gsl_matrix_complex_get(after, 0, j)));
02017
02018
02019 temp[i] = 0;
02020 }
02021
02022
02023 for (j=0; j<pow(2, NQ); j++)
02024 gsl_vector_complex_set(w_state, j, gsl_complex_rect(GSL_REAL(gsl_vector_complex_get(w_state, j))/(double)sqrt(NQ), 0.0));
02025 outer_product(w_state, density_random);
02026
02027
02028 gsl_matrix_complex_free(middle);
02029 gsl_matrix_complex_free(before);
02030 gsl_matrix_complex_free(after);
02031 gsl_vector_complex_free(w_state);
02032
02033 } else if (STATE == 9) {
02034 random_density_matrix(density_random);
02035 } else if (STATE == 12 || STATE == 15) {
02036 PSI_matrix(density_random, theta_handle);
02037 } else if (STATE == 14) {
02038 PSI_matrix(density_random, 1.0/sqrt(2.0)/2.0 + 0.029151) ;
02039 } else if (STATE == 16) {
02040 W_state(density_random);
02041 }
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067 }
02068
02069 void
02070 measure_state(gsl_matrix_complex *density_matrix, gsl_vector *n) {
02071 int counter[NQ], old_counter[NQ], i, nu;
02072
02073
02074 gsl_complex epsilon = gsl_complex_rect(EPS, 0);
02075 gsl_complex one_min_epsilon = gsl_complex_rect(1.0-EPS, 0);
02076 gsl_matrix_complex *random = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
02077 gsl_matrix_complex *tmp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
02078 matrix_complex_random_init(random);
02079 gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, random, random, zero, tmp);
02080 gsl_matrix_complex_memcpy(random, tmp);
02081
02082 gsl_matrix_complex_scale(random, gsl_complex_rect(1/GSL_REAL(trace(tmp)), 0));
02083
02084
02085
02086 gsl_matrix_complex_scale(random, epsilon);
02087 gsl_matrix_complex_scale(density_matrix, one_min_epsilon);
02088 gsl_matrix_complex_add(density_matrix, random);
02089 gsl_matrix_complex_free(random);
02090
02091
02092
02093
02094
02095
02096
02097 for (i=0; i<NQ-1; i++)
02098 counter[i]=0;
02099 counter[NQ-1]=-1;
02100 gsl_matrix_complex_memcpy(mu_cell[0], mu_array[0]);
02101 for (i=1; i<NQ; i++)
02102 kron(mu_cell[i-1], mu_array[0], mu_cell[i]);
02103
02104
02105 for (nu=0; nu<pow(4, NQ); nu++) {
02106
02107
02108 base_4_rep_inc(counter, nu);
02109
02110
02111 mu_tensor(mu_cell, mu_array, old_counter, counter);
02112
02113
02114
02115
02116 for (i=0; i<NQ; i++)
02117 old_counter[i] = counter[i];
02118
02119
02120 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, mu_cell[NQ-1],
02121 density_matrix, zero, tmp);
02122
02123
02124
02125 gsl_vector_set(n, nu, GSL_REAL(trace(tmp)));
02126 }
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140 gsl_matrix_complex_free(tmp);
02141
02142 }
02143
02144
02145 void
02146 apply_noise(gsl_vector *n) {
02147
02148
02149 gsl_rng * r;
02150 if ((r = gsl_rng_alloc (gsl_rng_taus)) == NULL) {
02151 perror("gsl_rng_alloc");
02152 exit(1);
02153 }
02154
02155
02156 struct timeval tv;
02157 struct timezone tz;
02158 struct tm *tm;
02159 gettimeofday(&tv, &tz);
02160 tm = localtime(&tv.tv_sec);
02161 if (VERBOSE)
02162 printf(" %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, (int)tv.tv_usec);
02163
02164 gsl_rng_set (r, tv.tv_usec);
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180 int i;
02181 for (i=0; i<pow(4, NQ); i++) {
02182 gsl_vector_set(n, i, gsl_ran_poisson(r, gsl_vector_get(n, i)));
02183 }
02184
02185
02186 gsl_rng_free(r);
02187 }
02188
02189 void
02190 load_basis() {
02191
02192
02193
02194 mu_array[0] = gsl_matrix_complex_alloc(2, 2);
02195 mu_array[1] = gsl_matrix_complex_alloc(2, 2);
02196 mu_array[2] = gsl_matrix_complex_alloc(2, 2);
02197 mu_array[3] = gsl_matrix_complex_alloc(2, 2);
02198
02199 gsl_complex half, zero, one, nhalf, halfc, nhalfc;
02200 GSL_SET_COMPLEX(&half, 0.5, 0);
02201 GSL_SET_COMPLEX(&zero, 0, 0);
02202 GSL_SET_COMPLEX(&one, 1, 0);
02203 GSL_SET_COMPLEX(&nhalf, -0.5, 0);
02204 GSL_SET_COMPLEX(&halfc, 0, 0.5);
02205 GSL_SET_COMPLEX(&nhalfc, 0, -0.5);
02206
02207 gsl_matrix_complex_set(mu_array[0], 0, 0, half);
02208 gsl_matrix_complex_set(mu_array[0], 0, 1, zero);
02209 gsl_matrix_complex_set(mu_array[0], 1, 0, zero);
02210 gsl_matrix_complex_set(mu_array[0], 1, 1, half);
02211
02212 gsl_matrix_complex_set(mu_array[1], 0, 0, one);
02213 gsl_matrix_complex_set(mu_array[1], 0, 1, zero);
02214 gsl_matrix_complex_set(mu_array[1], 1, 0, zero);
02215 gsl_matrix_complex_set(mu_array[1], 1, 1, zero);
02216
02217 gsl_matrix_complex_set(mu_array[2], 0, 0, half);
02218 gsl_matrix_complex_set(mu_array[2], 0, 1, nhalf);
02219 gsl_matrix_complex_set(mu_array[2], 1, 0, nhalf);
02220 gsl_matrix_complex_set(mu_array[2], 1, 1, half);
02221
02222 gsl_matrix_complex_set(mu_array[3], 0, 0, half);
02223 gsl_matrix_complex_set(mu_array[3], 0, 1, halfc);
02224 gsl_matrix_complex_set(mu_array[3], 1, 0, nhalfc);
02225 gsl_matrix_complex_set(mu_array[3], 1, 1, half);
02226
02227
02228
02229
02230
02231
02232
02233 sig_array[0] = gsl_matrix_complex_alloc(2, 2);
02234 sig_array[1] = gsl_matrix_complex_alloc(2, 2);
02235 sig_array[2] = gsl_matrix_complex_alloc(2, 2);
02236 sig_array[3] = gsl_matrix_complex_alloc(2, 2);
02237
02238 gsl_matrix_complex_set(sig_array[0], 0, 0, one);
02239 gsl_matrix_complex_set(sig_array[0], 0, 1, zero);
02240 gsl_matrix_complex_set(sig_array[0], 1, 0, zero);
02241 gsl_matrix_complex_set(sig_array[0], 1, 1, one);
02242
02243 gsl_matrix_complex_set(sig_array[1], 0, 0, zero);
02244 gsl_matrix_complex_set(sig_array[1], 0, 1, one);
02245 gsl_matrix_complex_set(sig_array[1], 1, 0, one);
02246 gsl_matrix_complex_set(sig_array[1], 1, 1, zero);
02247 gsl_complex imag;
02248 GSL_SET_COMPLEX(&imag, 0, 1);
02249
02250 gsl_matrix_complex_set(sig_array[2], 0, 0, zero);
02251 gsl_matrix_complex_set(sig_array[2], 0, 1, gsl_complex_negative(imag));
02252 gsl_matrix_complex_set(sig_array[2], 1, 0, imag);
02253 gsl_matrix_complex_set(sig_array[2], 1, 1, zero);
02254
02255 gsl_matrix_complex_set(sig_array[3], 0, 0, one);
02256 gsl_matrix_complex_set(sig_array[3], 0, 1, zero);
02257 gsl_matrix_complex_set(sig_array[3], 1, 0, zero);
02258 gsl_matrix_complex_set(sig_array[3], 1, 1, gsl_complex_negative(one));
02259
02260
02261
02262 }