00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdio.h>
00022 #include <math.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <time.h>
00026 #include <sys/time.h>
00027
00028 #include <gsl/gsl_complex.h>
00029 #include <gsl/gsl_complex_math.h>
00030 #include <gsl/gsl_matrix.h>
00031 #include <gsl/gsl_rng.h>
00032 #include <gsl/gsl_eigen.h>
00033 #include <gsl/gsl_blas.h>
00034 #include <gsl/gsl_sort.h>
00035 #include <gsl/gsl_sort_vector.h>
00036 #include <gsl/gsl_math.h>
00037
00038 #include "header.h"
00039
00040 void
00041 kron(gsl_matrix_complex *a, gsl_matrix_complex *b, gsl_matrix_complex *c) {
00042
00043
00044
00045 if ((c->size1)!=(a->size1)*(b->size1) || (c->size2)!=(a->size2)*(b->size2)) {
00046 fprintf(stderr, "kron: invalid size of output matrix\n");
00047 fprintf(stderr, "expected: size %d by %d\n", (a->size1)*(b->size1), (a->size1)*(b->size1));
00048 fprintf(stderr, "got: size %d by %d\n", c->size1, c->size2 );
00049 exit(1);
00050 }
00051 gsl_complex x, y;
00052 int i, j, k, l;
00053 for (i = 0; i<(a->size1); i++) {
00054 for (j = 0; j<(a->size2); j++) {
00055 for (k = 0; k<(b->size1); k++) {
00056 for (l = 0; l<(b->size2); l++) {
00057 x = gsl_matrix_complex_get(a, i, j);
00058 y = gsl_matrix_complex_get(b, k, l);
00059
00060 gsl_matrix_complex_set(c, i*(b->size1)+k, j*(b->size2)+l,
00061 gsl_complex_mul(x,y));
00062
00063 }
00064 }
00065 }
00066 }
00067
00068
00069
00070 }
00071
00072 void
00073 outer_product(gsl_vector_complex *a, gsl_matrix_complex *c) {
00074
00075 if ((c->size1)!=(a->size) || (c->size2)!=(a->size)) {
00076 fprintf(stderr, "outer product: size mismatch\n");
00077 exit(1);
00078 }
00079
00080 gsl_complex x, y;
00081 int i, j;
00082 for (i=0; i<(a->size); i++)
00083 for (j=0; j<(a->size); j++) {
00084 x = gsl_vector_complex_get(a, i);
00085 y = gsl_vector_complex_get(a, j);
00086 gsl_matrix_complex_set(c, i, j, gsl_complex_mul(x, gsl_complex_conjugate(y)));
00087 }
00088
00089 }
00090
00091 gsl_complex
00092 trace(gsl_matrix_complex *m) {
00093 if ((m->size1)!=m->size2) {
00094 fprintf(stderr, "Matrix must be square for trace to work\n");
00095 exit(1);
00096 }
00097 gsl_complex tr;
00098 gsl_complex temp;
00099 int i;
00100 GSL_SET_COMPLEX(&tr, 0, 0);
00101 for (i = 0; i<(m->size1); i++) {
00102
00103 temp=gsl_complex_add(tr, gsl_matrix_complex_get(m, i, i));
00104 tr=temp;
00105
00106 }
00107 return tr;
00108 }
00109
00110
00111
00112 void
00113 matrix_complex_random_init(gsl_matrix_complex *random) {
00114 gsl_complex rnd;
00115 gsl_rng * r;
00116 if ((r= gsl_rng_alloc (gsl_rng_taus)) == NULL) {
00117 perror("gsl_rng_alloc");
00118 exit(1);
00119 }
00120
00121
00122 struct timeval tv;
00123 struct timezone tz;
00124 struct tm *tm;
00125 gettimeofday(&tv, &tz);
00126 tm = localtime(&tv.tv_sec);
00127 if (VERBOSE)
00128 printf(" %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, (int)tv.tv_usec);
00129
00130 gsl_rng_set (r, tv.tv_usec);
00131
00132 int i, j;
00133 for (i=0; i<(random->size1); i++) {
00134 for (j=0; j<(random->size2); j++) {
00135
00136
00137
00138 GSL_SET_COMPLEX(&rnd, 2*gsl_rng_uniform_pos(r)-1,2*gsl_rng_uniform_pos(r)-1);
00139 gsl_matrix_complex_set(random, i, j, rnd);
00140 }
00141 }
00142 gsl_rng_free(r);
00143 }
00144
00145
00146 void
00147 random_density_matrix(gsl_matrix_complex *density_random) {
00148 gsl_matrix_complex *random = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00149 matrix_complex_random_init(random);
00150 gsl_blas_zgemm(CblasConjTrans, CblasNoTrans, one, random, random, zero, density_random);
00151
00152 gsl_matrix_complex_scale(density_random, gsl_complex_rect(1/GSL_REAL(trace(density_random)), 0));
00153 gsl_matrix_complex_free(random);
00154 }
00155
00156
00157 void
00158 base_4_rep_inc(int counter[], int n) {
00159 int c = n - 1;
00160 int truth = 1, subtruth;
00161 int current = NQ-1;
00162 while (truth) {
00163 if (c==n)
00164 truth=0;
00165 else {
00166 if (counter[current] == 3) {
00167 subtruth = 1;
00168 while (subtruth) {
00169 counter[current]=0;
00170 current--;
00171 if (counter[current]!=3) {
00172 counter[current]++;
00173 subtruth = 0;
00174 }
00175 }
00176 } else {
00177 counter[current]++;
00178 }
00179 }
00180 c++;
00181 }
00182 }
00183
00184 void
00185 mu_tensor(gsl_matrix_complex *mu_cell[], gsl_matrix_complex *mu_array[], int mu_counter[], int counter[]) {
00186
00187 int i, j;
00188 for (i=0; i<NQ; i++) {
00189 if (counter[i]!=mu_counter[i]) {
00190 if (i==0) {
00191
00192
00193 gsl_matrix_complex_memcpy(mu_cell[0], mu_array[counter[i]]);
00194 i++;
00195 }
00196 for (j=i; j<NQ; j++) {
00197
00198
00199
00200 kron(mu_cell[j-1], mu_array[counter[j]], mu_cell[j]);
00201 }
00202 break;
00203 }
00204 }
00205 }
00206
00207 void
00208 sig_tensor(gsl_matrix_complex *sigma_cell[], gsl_matrix_complex *sig_array[], int mu_counter[], int counter[]) {
00209
00210 int i, j;
00211 for (i=0; i<NQ; i++) {
00212 if (counter[i]!=mu_counter[i]) {
00213 if (i==0) {
00214
00215
00216 gsl_matrix_complex_memcpy(sigma_cell[0], sig_array[counter[i]]);
00217 i++;
00218 }
00219 for (j=i; j<NQ; j++) {
00220
00221
00222
00223 kron(sigma_cell[j-1], sig_array[counter[j]], sigma_cell[j]);
00224 }
00225 break;
00226 }
00227 }
00228 }
00229
00230 int
00231 write_data(char *name, gsl_matrix_complex *data) {
00232 FILE *fp_real, *fp_imag;
00233
00234 char file_real[MAXCHAR], file_imag[MAXCHAR];
00235
00236 if ((strncpy(file_real, DATA, MAXCHAR)) == NULL) {
00237 perror("strncpy");
00238 exit(1);
00239 }
00240 if ((strncat(file_real, name, MAXCHAR)) == NULL) {
00241 perror("strncat");
00242 exit(1);
00243 }
00244 if ((strncat(file_real, "_real.txt", MAXCHAR)) == NULL) {
00245 perror("strncat");
00246 exit(1);
00247 }
00248 if ((strncpy(file_imag, DATA, MAXCHAR)) == NULL) {
00249 perror("strncpy");
00250 exit(1);
00251 }
00252 if ((strncat(file_imag, name, MAXCHAR)) == NULL) {
00253 perror("strncat");
00254 exit(1);
00255 }
00256 if ((strncat(file_imag, "_imag.txt", MAXCHAR)) == NULL) {
00257 perror("strncat");
00258 exit(1);
00259 }
00260
00261
00262
00263
00264 if ((fp_real = fopen(file_real, "w")) == NULL) {
00265 perror("fopen");
00266 exit(1);
00267 }
00268 if ((fp_imag = fopen(file_imag, "w")) == NULL) {
00269 perror("fopen");
00270 exit(1);
00271 }
00272 int i, j;
00273 double number;
00274 char tab='\t';
00275 char newline='\n';
00276 char *write = malloc(MAXCHAR);
00277 char buffer[MAXCHAR];
00278 gsl_complex temp;
00279 for (i=0; i<(data->size1); i++) {
00280 for (j=0; j<(data->size2); j++) {
00281
00282 temp = gsl_matrix_complex_get(data, i, j);
00283
00284 number = GSL_REAL(temp);
00285
00286
00287 snprintf(write, MAXCHAR, "%e", number);
00288 strncpy(buffer, write, MAXCHAR);
00289
00290 Fwrite(buffer, sizeof(buffer), 1, fp_real);
00291 Fwrite(&tab, sizeof(tab), 1, fp_real);
00292
00293
00294 number = GSL_IMAG(temp);
00295 snprintf(write, MAXCHAR, "%e", number);
00296 strncpy(buffer, write, MAXCHAR);
00297
00298 Fwrite(buffer, sizeof(buffer), 1, fp_imag);
00299 Fwrite(&tab, sizeof(tab), 1, fp_imag);
00300 }
00301 Fwrite(&newline, sizeof(newline), 1, fp_real);
00302 Fwrite(&newline, sizeof(newline), 1, fp_imag);
00303 }
00304
00305 if ((fclose(fp_real)) != 0) {
00306 perror("fclose");
00307 exit(1);
00308 }
00309
00310 if ((fclose(fp_imag)) != 0) {
00311 perror("fclose");
00312 exit(1);
00313 }
00314
00315
00316 free(write);
00317 return 0;
00318 }
00319
00320
00321 int
00322 Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
00323 int n = fwrite(ptr, size, nmemb, stream);
00324 if(n < nmemb) {
00325 perror("fwrite");
00326 exit(1);
00327 }
00328 return(n);
00329 }
00330
00331 void
00332 display_matrix(gsl_matrix_complex *data) {
00333 int i, j;
00334 for (i=0; i<(data->size1); i++) {
00335 for (j=0; j<(data->size2); j++) {
00336 printf("%e+i%e\t", GSL_REAL(gsl_matrix_complex_get(data, i, j)),
00337 GSL_IMAG(gsl_matrix_complex_get(data, i, j)));
00338 }
00339 printf("\n");
00340 }
00341
00342 }
00343
00344 void
00345 display_matrix_real(gsl_matrix *data) {
00346 int i, j;
00347 for (i=0; i<(data->size1); i++) {
00348 for (j=0; j<(data->size2); j++) {
00349 printf("%e\t", gsl_matrix_get(data, i, j));
00350 }
00351 printf("\n");
00352 }
00353
00354 }
00355
00356 void
00357 make_T(const gsl_vector *t, gsl_matrix_complex *T) {
00358 gsl_matrix_complex_set_zero(T);
00359 int limiter, nu;
00360 int counter = 0;
00361 for (limiter = 0; limiter<pow(2, NQ); limiter++) {
00362 for (nu=limiter; nu<pow(2, NQ); nu++) {
00363 if (counter<pow(2,NQ)) {
00364 gsl_matrix_complex_set(T, nu, nu, gsl_complex_rect(gsl_vector_get(t, counter),0));
00365 } else {
00366 gsl_matrix_complex_set(T, nu, nu-limiter, gsl_complex_rect(gsl_vector_get(t,counter),gsl_vector_get(t,counter+1)));
00367
00368 counter++;
00369 }
00370 counter++;
00371 }
00372 }
00373
00374 }
00375
00376 int
00377 write_vector_real(char *name, gsl_vector *data) {
00378 FILE *fp;
00379
00380 char file[MAXCHAR];
00381
00382 if ((strncpy(file, DATA, MAXCHAR)) == NULL) {
00383 perror("strncpy");
00384 exit(1);
00385 }
00386 if ((strncat(file, name, MAXCHAR)) == NULL) {
00387 perror("strncat");
00388 exit(1);
00389 }
00390 if ((strncat(file, ".txt", MAXCHAR)) == NULL) {
00391 perror("strncat");
00392 exit(1);
00393 }
00394
00395
00396
00397
00398 if ((fp = fopen(file, "w")) == NULL) {
00399 perror("fopen");
00400 exit(1);
00401 }
00402
00403 int i;
00404 double number;
00405 char tab='\t';
00406 char newline='\n';
00407 char *write = malloc(MAXCHAR);
00408 char buffer[MAXCHAR];
00409
00410 for (i=0; i<(data->size); i++) {
00411
00412 number = gsl_vector_get(data, i);
00413
00414 snprintf(write, MAXCHAR, "%e", number);
00415 strncpy(buffer, write, MAXCHAR);
00416 Fwrite(buffer, sizeof(buffer), 1, fp);
00417 Fwrite(&tab, sizeof(tab), 1, fp);
00418
00419 }
00420
00421 Fwrite(&newline, sizeof(newline), 1, fp);
00422
00423 if ((fclose(fp)) != 0) {
00424 perror("fclose");
00425 exit(1);
00426 }
00427
00428 free(write);
00429 return 0;
00430 }
00431
00432 int
00433 write_matrix_real(char *name, gsl_matrix *data) {
00434 FILE *fp;
00435
00436 char file[MAXCHAR];
00437
00438 if ((strncpy(file, DATA, MAXCHAR)) == NULL) {
00439 perror("strncpy");
00440 exit(1);
00441 }
00442 if ((strncat(file, name, MAXCHAR)) == NULL) {
00443 perror("strncat");
00444 exit(1);
00445 }
00446 if ((strncat(file, ".txt", MAXCHAR)) == NULL) {
00447 perror("strncat");
00448 exit(1);
00449 }
00450
00451
00452
00453
00454 if ((fp = fopen(file, "w")) == NULL) {
00455 perror("fopen");
00456 exit(1);
00457 }
00458
00459 int i, j;
00460 double number;
00461 char tab='\t';
00462 char newline='\n';
00463 char *write = malloc(MAXCHAR);
00464 char buffer[MAXCHAR];
00465
00466 for (i=0; i<(data->size1); i++) {
00467 for (j=0; j<(data->size2); j++) {
00468
00469 number = gsl_matrix_get(data, i, j);
00470
00471 snprintf(write, MAXCHAR, "%e", number);
00472 strncpy(buffer, write, MAXCHAR);
00473 Fwrite(buffer, sizeof(buffer), 1, fp);
00474 Fwrite(&tab, sizeof(tab), 1, fp);
00475 }
00476 Fwrite(&newline, sizeof(newline), 1, fp);
00477
00478 }
00479
00480
00481
00482 if ((fclose(fp)) != 0) {
00483 perror("fclose");
00484 exit(1);
00485 }
00486
00487 free(write);
00488 return 0;
00489 }
00490
00491 int
00492 read_vector_real(char *fname, gsl_vector *data) {
00493 FILE *fname_fp;
00494 if((fname_fp = fopen(fname, "r")) == NULL) {
00495 perror("fopen");
00496 exit(1);
00497 }
00498
00499 int i=0;
00500 char line[MAXCHAR];
00501 while((fgets(line, MAXCHAR, fname_fp)) != NULL) {
00502 if (i==data->size) {
00503 fprintf(stderr, "file read mismatch - too many elements to read, aborting\n");
00504 exit(1);
00505 }
00506 line[strlen(line)-1] = '\0';
00507 gsl_vector_set(data, i, atof(line));
00508 i++;
00509 }
00510
00511 if (i!=data->size) {
00512 fprintf(stderr, "file read mismatch - too few elements to read, aborting\n");
00513 exit(1);
00514 }
00515
00516 if((fclose(fname_fp))) {
00517 perror("fclose");
00518 }
00519
00520 return 0;
00521
00522 }
00523
00524 void
00525 display_vector_real(gsl_vector *data) {
00526 int i;
00527 for (i=0; i<data->size; i++)
00528 printf("%e\t", gsl_vector_get(data, i));
00529
00530 printf("\n");
00531 }
00532
00533
00534 void
00535 sqrtm(gsl_matrix_complex *matrix) {
00536 int i;
00537
00538 gsl_eigen_hermv_workspace *w = gsl_eigen_hermv_alloc (pow(2,NQ));
00539
00540 gsl_vector *eval = gsl_vector_alloc(pow(2,NQ));
00541
00542 gsl_matrix_complex *evec = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00543
00544 if ((gsl_eigen_hermv (matrix, eval, evec, w)) != 0) {
00545
00546 fprintf(stderr, "Failed at finding eigenvalues and eigenvectors\n");
00547 fprintf(stderr, "SQRTM failed, exiting...\n");
00548 exit(1);
00549 } else {
00550 if (VERBOSE)
00551 printf("SQRTM - succeeded in finding eigenvalues and eigenvectors\n");
00552 }
00553
00554
00555
00556
00557
00558 gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_ABS_ASC);
00559
00560
00561
00562 gsl_matrix_complex *eval_matrix = gsl_matrix_complex_alloc(pow(2,NQ), pow(2, NQ));
00563 gsl_matrix_complex_set_zero(eval_matrix);
00564
00565 for (i=0; i<pow(2,NQ); i++) {
00566 gsl_matrix_complex_set(eval_matrix, i, i, gsl_complex_sqrt_real(gsl_vector_get(eval, i)));
00567 }
00568
00569
00570
00571 gsl_matrix_complex *tmp = gsl_matrix_complex_alloc(pow(2,NQ), pow(2,NQ));
00572 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, evec, eval_matrix, zero, tmp);
00573 gsl_blas_zgemm(CblasNoTrans, CblasConjTrans, one, tmp, evec, zero, matrix);
00574
00575
00576
00577
00578
00579 gsl_matrix_complex_free(eval_matrix);
00580 gsl_eigen_hermv_free(w);
00581 gsl_vector_free(eval);
00582 gsl_matrix_complex_free(evec);
00583 gsl_matrix_complex_free(tmp);
00584 }
00585
00586
00587 double
00588 fidelity(gsl_matrix_complex *m1, gsl_matrix_complex *m2) {
00589
00590 if ((m1->size1 != m2->size1) || (m1->size2 != m2->size2)) {
00591 fprintf(stderr, "inconsistent matrix size on fidelity()\n");
00592 exit(1);
00593 }
00594
00595 gsl_matrix_complex *rho1 = gsl_matrix_complex_alloc(m1->size1, m1->size2);
00596 gsl_matrix_complex *rho2 = gsl_matrix_complex_alloc(m2->size1, m2->size2);
00597 gsl_matrix_complex *tmp = gsl_matrix_complex_alloc(m2->size1, m2->size2);
00598 gsl_matrix_complex_memcpy(rho1, m1);
00599 gsl_matrix_complex_memcpy(rho2, m2);
00600
00601 double f = 0.0;
00602
00603 sqrtm(rho1);
00604
00605 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, rho1, rho2, zero, tmp);
00606 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, tmp, rho1, zero, rho2);
00607
00608
00609 sqrtm(rho2);
00610 f = GSL_REAL(trace(rho2));
00611 f = pow(f, 2);
00612
00613 gsl_matrix_complex_free(rho1);
00614 gsl_matrix_complex_free(rho2);
00615 gsl_matrix_complex_free(tmp);
00616
00617 return f;
00618 }
00619
00620 double
00621 entropy_linear(gsl_matrix_complex *matrix) {
00622
00623 double s = 0.0;
00624
00625 gsl_matrix_complex *tmp = gsl_matrix_complex_alloc(matrix->size1, matrix->size2);
00626 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, matrix, matrix, zero, tmp);
00627
00628 s = (1.0-GSL_REAL(trace(tmp)))*pow(2, NQ)/(pow(2,NQ) - 1);
00629
00630 gsl_matrix_complex_free(tmp);
00631
00632 return s;
00633 }
00634
00635
00636
00637 double
00638 concurrence(gsl_matrix_complex *matrix) {
00639
00640 if ((matrix->size1) != (matrix->size2)) {
00641 fprintf(stderr, "CONCURRENCE - must be a square matrix\n");
00642 exit(1);
00643 }
00644
00645 int i, j;
00646
00647 gsl_eigen_herm_workspace *w = gsl_eigen_herm_alloc (pow(2,NQ));
00648
00649 gsl_vector *eval = gsl_vector_alloc(pow(2,NQ));
00650
00651
00652 gsl_matrix_complex *tmp = gsl_matrix_complex_alloc(matrix->size1, matrix->size2);
00653 gsl_matrix_complex_memcpy(tmp, matrix);
00654
00655 gsl_matrix_complex *before, *after;
00656 after = gsl_matrix_complex_alloc(2, 2);
00657 before = gsl_matrix_complex_alloc(2, 2);
00658 gsl_matrix_complex_memcpy(after, sig_array[2]);
00659 gsl_matrix_complex_memcpy(before, sig_array[2]);
00660
00661 for (i=0; i<NQ-1; i++) {
00662 gsl_matrix_complex_free(after);
00663 after = gsl_matrix_complex_alloc((before->size1)*2, (before->size2)*2);
00664 kron(before, sig_array[2], after);
00665 gsl_matrix_complex_free(before);
00666 before = gsl_matrix_complex_alloc(after->size1, after->size2);
00667 gsl_matrix_complex_memcpy(before, after);
00668 }
00669
00670
00671
00672 gsl_matrix_complex *conj = gsl_matrix_complex_alloc(matrix->size1, matrix->size2);
00673 for (i=0; i<matrix->size1; i++)
00674 for (j=0; j<matrix->size1; j++)
00675 gsl_matrix_complex_set(conj, i, j, gsl_complex_conjugate(gsl_matrix_complex_get(matrix, i, j)));
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 gsl_matrix_complex *matrix_copy = gsl_matrix_complex_alloc(matrix->size1, matrix->size2);
00686 gsl_matrix_complex_memcpy(matrix_copy, matrix);
00687 sqrtm(matrix_copy);
00688 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, matrix_copy, after, zero, tmp);
00689 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, tmp, conj, zero, before);
00690 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, before, after, zero, tmp);
00691 gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, one, tmp, matrix_copy, zero, before);
00692 gsl_matrix_complex_free(conj);
00693 gsl_matrix_complex_free(matrix_copy);
00694
00695
00696
00697 if ((gsl_eigen_herm(before, eval, w)) != 0) {
00698
00699 fprintf(stderr, "Failed at finding eigenvalues\n");
00700 fprintf(stderr, "CONCURRENCE failed, exiting...\n");
00701 exit(1);
00702 } else {
00703 if (VERBOSE)
00704 printf("CONCURRENCE - succeeded in finding eigenvalues\n");
00705 }
00706
00707
00708
00709
00710 for (i=0; i<matrix->size1; i++) {
00711
00712 gsl_vector_set(eval, i, GSL_REAL(gsl_complex_sqrt_real(gsl_vector_get(eval, i))));
00713 }
00714
00715
00716
00717
00718 gsl_sort_vector(eval);
00719
00720 double sum = 0.0;
00721
00722 for (i=0; i<(matrix->size1)-1; i++) {
00723 sum += gsl_vector_get(eval, i);
00724 }
00725
00726 double largest_eval = gsl_vector_get(eval, (matrix->size1)-1);
00727
00728
00729 gsl_eigen_herm_free(w);
00730 gsl_vector_free(eval);
00731 gsl_matrix_complex_free(tmp);
00732 gsl_matrix_complex_free(before);
00733 gsl_matrix_complex_free(after);
00734
00735
00736 if ((largest_eval - sum) < 0.0) {
00737 return 0.0;
00738 } else {
00739 return largest_eval - sum;
00740 }
00741
00742 }
00743
00744 void
00745 gsl_vector_add_element(gsl_vector *vector, double element) {
00746
00747
00748 int i, orig_size = vector->size;
00749 printf("Alloc tmp\n");
00750 gsl_vector *tmp = gsl_vector_alloc(vector->size);
00751 printf("Alloc OK\n");
00752 for (i=0; i<vector->size; i++) {
00753 printf("Set tmp\n");
00754 gsl_vector_set(tmp, i, gsl_vector_get(vector, i));
00755 printf("Set OK\n");
00756 }
00757
00758 gsl_vector_free(vector);
00759 printf("Alloc vector\n");
00760 vector = gsl_vector_alloc(orig_size + 1);
00761 printf("Alloc OK\n");
00762 for (i=0; i<tmp->size; i++) {
00763 printf("Set vector\n");
00764 gsl_vector_set(vector, i, gsl_vector_get(tmp, i));
00765 printf("Set OK\n");
00766 }
00767
00768
00769 printf("Set vector 2\n");
00770 gsl_vector_set(vector, orig_size, element);
00771 printf("Set OK\n");
00772
00773 gsl_vector_free(tmp);
00774 }
00775
00776 void
00777 PSI_matrix(gsl_matrix_complex *psi, double theta) {
00778 gsl_matrix_complex_set_zero(psi);
00779 double temp = 1-pow(theta, 2);
00780 gsl_matrix_complex_set(psi, 0, 0, gsl_complex_rect(temp, 0.0));
00781 gsl_matrix_complex_set(psi, 0, (psi->size2)-1, gsl_complex_rect(theta*sqrt(temp), 0.0));
00782 gsl_matrix_complex_set(psi, (psi->size1)-1, 0, gsl_complex_rect(theta*sqrt(temp), 0.0));
00783 gsl_matrix_complex_set(psi, (psi->size1)-1, (psi->size2)-1, gsl_complex_rect(pow(theta, 2), 0.0));
00784 }
00785
00786
00787 double
00788 abs_val(gsl_vector *vec) {
00789
00790 int i;
00791 double ret = 0.0;
00792 for (i=0; i < vec->size; i++) {
00793 ret += gsl_pow_2(gsl_vector_get(vec, i));
00794 }
00795
00796 return sqrt(ret);
00797 }
00798
00799
00800 void
00801 rho_MEMS(gsl_matrix_complex *rho_mems, double gamma) {
00802
00803 double g;
00804
00805 if (gamma >= 2.0/3.0)
00806 g = (double) gamma/2.0;
00807 else
00808 g = (double) 1.0/3.0;
00809
00810 gsl_matrix_complex_set_zero(rho_mems);
00811 gsl_matrix_complex_set(rho_mems, 0, 0, gsl_complex_rect(g, 0.0));
00812 gsl_matrix_complex_set(rho_mems, 0, 3, gsl_complex_rect((double) gamma/2.0, 0.0));
00813 gsl_matrix_complex_set(rho_mems, 1, 1, gsl_complex_rect((double) (1.0 - 2.0*g), 0.0));
00814 gsl_matrix_complex_set(rho_mems, 3, 0, gsl_complex_rect((double) gamma/2.0, 0.0));
00815 gsl_matrix_complex_set(rho_mems, 3, 3, gsl_complex_rect(g, 0.0));
00816 }
00817
00818 void
00819 W_state(gsl_matrix_complex *density) {
00820 int size = density->size1;
00821 int i, j;
00822 int index_array[NQ];
00823 gsl_matrix_complex *a, *b, *c;
00824 gsl_vector_complex *psi = gsl_vector_complex_alloc(size);
00825 for (j=0; j<NQ; j++)
00826 index_array[j]=0;
00827
00828 gsl_vector_complex_set_zero(psi);
00829 b = gsl_matrix_complex_alloc(2, 1);
00830
00831 c = gsl_matrix_complex_alloc(1, 1);
00832
00833 a = gsl_matrix_complex_alloc(1,1);
00834 gsl_matrix_complex_free(a);
00835
00836 for (i=0; i<NQ; i++) {
00837
00838 for (j=0; j<NQ; j++)
00839 index_array[j]=0;
00840 index_array[i] = 1;
00841
00842
00843 for (j=1; j<NQ; j++) {
00844 if (j==1) {
00845 a = gsl_matrix_complex_alloc(2, 1);
00846 if (index_array[0] == 0) {
00847 gsl_matrix_complex_set(a, 0, 0, gsl_complex_rect(1, 0));
00848 gsl_matrix_complex_set(a, 1, 0, gsl_complex_rect(0, 0));
00849 } else {
00850 gsl_matrix_complex_set(a, 0, 0, gsl_complex_rect(0, 0));
00851 gsl_matrix_complex_set(a, 1, 0, gsl_complex_rect(1, 0));
00852 }
00853 } else {
00854 gsl_matrix_complex_free(a);
00855 a = gsl_matrix_complex_alloc(c->size1, 1);
00856 gsl_matrix_complex_memcpy(a, c);
00857 }
00858
00859 if (index_array[j] == 0) {
00860 gsl_matrix_complex_set(b, 0, 0, gsl_complex_rect(1, 0));
00861 gsl_matrix_complex_set(b, 1, 0, gsl_complex_rect(0, 0));
00862 } else {
00863 gsl_matrix_complex_set(b, 0, 0, gsl_complex_rect(0, 0));
00864 gsl_matrix_complex_set(b, 1, 0, gsl_complex_rect(1, 0));
00865 }
00866 gsl_matrix_complex_free(c);
00867 c = gsl_matrix_complex_alloc(2*(a->size1), 1);
00868 kron(a, b, c);
00869 }
00870
00871
00872 for (j=0; j<size; j++)
00873 gsl_vector_complex_set(psi, j,
00874 gsl_complex_add(gsl_vector_complex_get(psi,j), gsl_matrix_complex_get(c, j, 0)));
00875
00876
00877 gsl_matrix_complex_free(a);
00878 }
00879
00880 outer_product(psi, density);
00881
00882 gsl_matrix_complex_scale(density, gsl_complex_div(gsl_complex_rect(1,0), trace(density)));
00883
00884
00885 gsl_matrix_complex_free(b);
00886 gsl_matrix_complex_free(c);
00887 gsl_vector_complex_free(psi);
00888
00889 }
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924