00001 /*! \file header.h 00002 \brief Main header file which specifies arguments for the program 00003 00004 * Numerical State Tomography 00005 * Using GSL -> www.gnu.org/software/gsl 00006 * Copyright (C) 2007 Max S Kaznady 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; 00011 * 00012 * AUTHOR 00013 * Max S Kaznady, [EMAIL PROTECTED] 00014 * max.kaznady@gmail.com 00015 * Summer, 2007 00016 * 00017 * This header file is used to specify all the parameters for the program 00018 * instead of using command line arguments. This is not a very good 00019 * software practice but saved a lot of time while developing the code. 00020 * 00021 ******************************************************************************/ 00022 00023 00024 /*! \def NQ 00025 * \brief Number of Qubits 00026 * 00027 * This is the main control used to specify the number of qubits. 00028 * The amount of memory on a regular PC (2 GB) should handle 00029 * 1-15 qubits with this setting. Going over 15 qubits may result in memory 00030 * overflow, as the density matrix itself would become a problem. 00031 */ 00032 00033 /*! \def DATA 00034 * \brief Output location for the matrices produced by the program 00035 * 00036 * Valid directory with sufficient space and write permissions is a must 00037 * for this setting. All the simulation data would be outputted there as 00038 * ASCII files. 00039 */ 00040 00041 /*! \def NUMTRIALS 00042 * \brief Number of times tomography is repeated. 00043 * 00044 * Used to define how many times tomography is performed on an identical 00045 * state and has many uses in the code. 00046 */ 00047 00048 /*! \def MILLION 00049 * \brief Defines the numerical value of one million - do not alter. 00050 */ 00051 00052 /*! \def MAXCHAR 00053 * \brief Defines the numerical value of a character - do not alter. 00054 */ 00055 00056 /*! \def STATE 00057 * \brief Main control which selects what kind of tomography will be perfomred. 00058 * 00059 * The numerical value of this variable selects the type of tomography: \n 00060 * 1 - GHZ state -- obsolete: it's just state 5 \n 00061 2 - tau = 0, S_l = 0 \n 00062 3 - Werner state, epsilon ~= 0 (low tau, high S) \n 00063 4 - Werner state, epsilon ~= 0.5-0.0123 (middle) \n 00064 5 - Werner state, epsilon ~= 1 (high tau, low S) \n 00065 6 - MEMS State - only available for 2 QB \n 00066 7 - tau = 0; S_l = 1 \n 00067 8 - W state \n 00068 9 - completely random state \n 00069 10 - Werner state, epsilon is being adjusted from 0 to 1 each time \n 00070 11 - not really a state - for 2 qubits, this is used to fill the 00071 tangle/entropy plane - only defined for 2 qubits \n 00072 12 - cycle through all tangle values for a pure state (S_l = 0) and 00073 and apply a different Quick and Dirty routine \n 00074 13 - not a state - vary experimental error for many pure states, see how 00075 this scales with the number of qubits \n 00076 14 - middle tangle value, pure state \n 00077 15 - determine value for N which results in 90% Fidelity for pure states \n 00078 16 - W state density matrix \n 00079 */ 00080 00081 /*! \def EPS 00082 * \brief Experimental State Error value. 00083 * 00084 Used to adjust the "coherence" of the state 00085 rho_out = (1-EPS)*rho_state + EPS*rho_random 00086 do not set equal to zero 00087 * 00088 */ 00089 00090 /*! \def VERBOSE 00091 * \brief Boolean extra verboseness level toggle. 00092 */ 00093 00094 /*! \def WRITE_DENSITY 00095 * \brief Boolean toggle for density matrices to be written to disc. 00096 */ 00097 00098 /*! \def MAX_FIDELITY 00099 * \brief Max fidelity cutoff point. If fidelity is over this value, simulations stops. 00100 */ 00101 00102 /*! \def KEEP_GOING 00103 * \brief Boolean to cutoff MLE based on MAX_FIDELITY. 00104 * 00105 * For MLE Optimisation routine \n 00106 if 0, then will stop iterating as soon as fidelity will start to decrease \n 00107 if 1, then will keep iterating until either MLE Objective function stops 00108 decreasing, or gradient is close to zero, or some other GSL-induced condition. 00109 * 00110 * 00111 */ 00112 00113 /*! \def MAXITER 00114 * \brief Maximum number of iterations of MLE function, an integer. 00115 */ 00116 00117 /*! \def CUT_ITER 00118 * \brief Boolean to stop iteration if MLE function starts to decrease by some very small amount. 00119 * 00120 * 00121 */ 00122 00123 /*! \def DO_MLE 00124 * \brief Boolean to specify whether MLE should be performed. 00125 */ 00126 00127 00128 00129 /*! \fn void kron(gsl_matrix_complex *a, gsl_matrix_complex *b, gsl_matrix_complex *c); 00130 * \brief Performs tensor product on matrices A and B storing the output into pre-allocated matrix C. 00131 */ 00132 00133 /*! \fn gsl_complex trace(gsl_matrix_complex *m); 00134 * \brief Computes trace of a complex matrix and returns a complex number. 00135 */ 00136 00137 /*! \fn void matrix_complex_random_init(gsl_matrix_complex *random); 00138 * \brief Fills a pre-allocated matrix with random values sampled from U(-1,1). 00139 */ 00140 00141 00142 /*! \fn void outer_product(gsl_vector_complex *a, gsl_matrix_complex *outp); 00143 * \brief Performs outer product |a><a| into pre-allocated output matrix. 00144 */ 00145 00146 /*! \fn void base_4_rep_inc(int counter[], int n); 00147 * \brief Input array has base-4 rep of n-1, it's incremented to n. 00148 */ 00149 00150 /*! \fn void mu_tensor(gsl_matrix_complex *mu_cell[], gsl_matrix_complex *mu_array[], int mu_counter[], int counter[]); 00151 * \brief Shortcut algorithm for tensoring on additional mu matrices to save computation time. 00152 * 00153 * Mu_cell contains pointers to gsl mu matrices that make up the final mu 00154 * matrix which corresponds to base-4 representation in mu_counter. The 00155 * function corrects mu_cell to represent "counter" base-4 representation 00156 * by location the index of the mu matrix in mu_cell starting from which 00157 * new matrices need to be tensored on from mu_array. 00158 * 00159 * Basically this is an update function which computes the final mu_matrix 00160 * corresponding to the correct base-4 representation in counter without 00161 * recomputing everything from scratch. 00162 * 00163 */ 00164 00165 /*! \fn void sig_tensor(gsl_matrix_complex *sigma_cell[], gsl_matrix_complex *sig_array[], int mu_counter[], int counter[]); 00166 * \brief Shortcut algorithm for tensoring on additional sigma matrices to save computation time, see mu_tensor function description. 00167 * 00168 */ 00169 00170 /*! \fn int write_data(char *name, gsl_matrix_complex *data); 00171 * \brief Writes complex matrix data into ASCII file specified by name, standard return codes for write. 00172 * 00173 */ 00174 00175 /*! \fn int Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 00176 * \brief Wrapper function for fwrite to handle return codes. 00177 */ 00178 00179 /*! \fn void display_matrix(gsl_matrix_complex *data); 00180 * \brief Prints complex matrix to screen. 00181 */ 00182 00183 /*! \fn void display_matrix_real(gsl_matrix *data); 00184 * \brief Prints real matrix to screen. 00185 */ 00186 00187 /*! \fn void make_T(const gsl_vector *t, gsl_matrix_complex *T); 00188 * \brief Seeds in values from vector t into Cholesky lower-diagonal matrix T, like described in the paper. 00189 */ 00190 00191 /*! \fn int write_vector_real(char *name, gsl_vector *data); 00192 * \brief Writes real vector into ASCII file specified by name char string. 00193 */ 00194 00195 /*! \fn int read_vector_real(char *fname, gsl_vector *data); 00196 * \brief Reads in real valued vector into \e data from ASCII file \e fname. 00197 */ 00198 00199 /*! \fn void display_vector_real(gsl_vector *data); 00200 * \brief Prints real-valued vector to screen. 00201 */ 00202 00203 /*! \fn void sqrtm(gsl_matrix_complex *matrix); 00204 * \brief Computes square root of complex \e matrix, stores output in originally pre-allocated matrix. 00205 */ 00206 00207 /*! \fn double fidelity(gsl_matrix_complex *m1, gsl_matrix_complex *m2); 00208 * \brief Returns fidelity between two density matrices \e m1 and \e m2. 00209 */ 00210 00211 /*! \fn double entropy_linear(gsl_matrix_complex *matrix); 00212 * \brief Returns entropy of the input complex-valued density matrix. 00213 */ 00214 00215 /*! \fn double concurrence(gsl_matrix_complex *matrix); 00216 * \brief Returns concurrence of the input density matrix. 00217 */ 00218 00219 /*! \fn void gsl_vector_add_element(gsl_vector *vector, double element); 00220 * \brief Adds \e element as last element in \e vector, after re-allocating size of \e vector. 00221 */ 00222 00223 /*! \fn void random_density_matrix(gsl_matrix_complex *density_random); 00224 * \brief Creates a random density matrix out of a pre-allocated complex matrix. 00225 */ 00226 00227 /*! \fn void PSI_matrix(gsl_matrix_complex *psi, double theta); 00228 * \brief Adjusts the density matrix \e psi to fall on the Werner state line by using the paramter \e theta, which is \e delta in the paper. 00229 */ 00230 00231 /*! \fn void rho_MEMS(gsl_matrix_complex *rho_mems, double gamma); 00232 * \brief Density matrix \e rho_mems fall on MEMS line by varying parameter \e gamma, as described in the paper. 00233 */ 00234 00235 /*! \fn int write_matrix_real(char *name, gsl_matrix *data); 00236 * \brief Writes real matrix \e data into ASCII file \e name. 00237 */ 00238 00239 /*! \fn double abs_val(gsl_vector *vec); 00240 * \brief Returns absolute value (length) of vector \e vec. 00241 */ 00242 00243 /*! \fn void W_state(gsl_matrix_complex *density); 00244 * \brief Creates a W state density matrix. 00245 */ 00246 00247 /*! \var gsl_matrix_complex *mu_array[4]; 00248 * \brief Stores the Stokes measurement basis matrices. 00249 */ 00250 00251 /*! \var gsl_matrix_complex *sig_array[4]; 00252 * \brief Stores the 4 Pauli matrices. 00253 */ 00254 00255 /*! \var gsl_matrix_complex *mu_cell[NQ] 00256 * \brief Stores tensored \e mu matrices to compute the projection operators for >1 qubits, as described in the paper. 00257 */ 00258 00259 /*! \var gsl_matrix_complex *sigma_cell[NQ]; 00260 * \brief Stores tensored \e sigma matrices to compute the Pauli operators for >1 qubits, as described in the paper. 00261 */ 00262 00263 /*! \var gsl_complex zero; 00264 * \brief Computational constant. 00265 */ 00266 00267 /*! \var gsl_complex one; 00268 * \brief Computational constant. 00269 */ 00270 00271 /*! \var gsl_matrix_complex *ones; 00272 * \brief Matrix full of ones. 00273 */ 00274 00275 /*! \var double Werner_handle; 00276 * \brief State handle used to adjust the Werner state. 00277 */ 00278 00279 /*! \var double theta_handle; 00280 * \brief Used to adjust the tangle value. 00281 */ 00282 00283 /*! \var double N; 00284 * \brief Specifies the simulated number of times an experiment is performed, i.e. the number of times projection measurements were taken. 00285 */ 00286 00287 #ifndef header_h 00288 #define header_h 00289 00290 // typedef struct gsl_matrix_complex_float Matrix; 00291 // typedef struct gsl_matrix_complex_float_alloc Matrix_alloc; 00292 // typedef struct gsl_matrix_complex_float_set Matrix_set; 00293 // typedef struct gsl_matrix_complex_float_get Matrix_get; 00294 00295 //don't forget to also set DATA to point to correct NQ location 00296 #define NQ 2 00297 //finish the line below with a forward slash 00298 #define DATA "/home/max/Desktop/2/" 00299 00300 //number of times we will perform tomography - used to obtain averages 00301 #define NUMTRIALS 1 00302 #define MILLION 1000000 00303 //#define N 10000 00304 #define MAXCHAR 512 00305 //state 1 - GHZ state -- obsolete: it's just state 5 00306 //state 2 - tau = 0, S_l = 0 00307 //state 3 - Werner state, epsilon ~= 0 (low tau, high S) 00308 //state 4 - Werner state, epsilon ~= 0.5-0.0123 (middle) 00309 //state 5 - Werner state, epsilon ~= 1 (high tau, low S) 00310 //state 6 - MEMS State - only available for 2 QB 00311 //state 7 - tau = 0; S_l = 1 00312 //state 8 - W state 00313 //state 9 - completely random state 00314 //state 10 - Werner state, epsilon is being adjusted from 0 to 1 each time 00315 //state 11 - not really a state - for 2 qubits, this is used to fill the 00316 // tangle/entropy plane - only defined for 2 qubits 00317 //state 12 - cycle through all tangle values for a pure state (S_l = 0) and 00318 // and apply a different Quick and Dirty routine 00319 //state 13 - not a state - vary eperimental error for many pure states, see how 00320 // this scales with the number of qubits 00321 //state 14 - middle tangle value, pure state 00322 //state 15 - determine value for N which results in 90% Fidelity for pure states 00323 //state 16 - W state density matrix 00324 #define STATE 5 00325 00326 //used to adjust the "coherence" of the state 00327 //rho_out = (1-EPS)*rho_state + EPS*rho_random 00328 //do not set equal to zero 00329 #define EPS 0.05 00330 00331 //make script be more verbose - good for debugging 00332 //set to 1 for verboseness, 0 otherwise 00333 #define VERBOSE 1 00334 00335 //define how much data to write to disc 00336 //if we write too much, this will slow down runs 00337 //for a large number of trials 00338 #define WRITE_DENSITY 1 00339 00340 //define the maximum number of fidelity that one can go to 00341 #define MAX_FIDELITY 0.90 00342 00343 //For MLE Optimization routine 00344 //if 0, then will stop iterating as soon as fidelity will start to decrease 00345 //if 1, then will keep iterating until either MLE Objective function stops 00346 //decreasing, or gradient is close to zero, or some other GSL-induced condition. 00347 #define KEEP_GOING 1 00348 00349 //Maximum number of iterations of MLE function 00350 #define MAXITER 100 00351 00352 //stops the iteration if function difference is less than a certain number 00353 #define CUT_ITER 1 00354 00355 //specify whether or not MLE should be performed 00356 #define DO_MLE 1 00357 00358 //extern int M2 = pow(2, NQ); 00359 //extern int M4 = pow(4, NQ); 00360 00361 void 00362 kron(gsl_matrix_complex *a, gsl_matrix_complex *b, gsl_matrix_complex *c); 00363 00364 gsl_complex 00365 trace(gsl_matrix_complex *m); 00366 00367 void 00368 matrix_complex_random_init(gsl_matrix_complex *random); 00369 00370 void 00371 outer_product(gsl_vector_complex *a, gsl_matrix_complex *outp); 00372 00373 void 00374 base_4_rep_inc(int counter[], int n); 00375 00376 void 00377 mu_tensor(gsl_matrix_complex *mu_cell[], gsl_matrix_complex *mu_array[], int mu_counter[], int counter[]); 00378 00379 void 00380 sig_tensor(gsl_matrix_complex *sigma_cell[], gsl_matrix_complex *sig_array[], int mu_counter[], int counter[]); 00381 00382 int 00383 write_data(char *name, gsl_matrix_complex *data); 00384 00385 int 00386 Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 00387 00388 void 00389 display_matrix(gsl_matrix_complex *data); 00390 00391 void 00392 display_matrix_real(gsl_matrix *data); 00393 00394 void 00395 make_T(const gsl_vector *t, gsl_matrix_complex *T); 00396 00397 int 00398 write_vector_real(char *name, gsl_vector *data); 00399 00400 int 00401 read_vector_real(char *fname, gsl_vector *data); 00402 00403 void 00404 display_vector_real(gsl_vector *data); 00405 00406 void 00407 sqrtm(gsl_matrix_complex *matrix); 00408 00409 double 00410 fidelity(gsl_matrix_complex *m1, gsl_matrix_complex *m2); 00411 00412 double 00413 entropy_linear(gsl_matrix_complex *matrix); 00414 00415 double 00416 concurrence(gsl_matrix_complex *matrix); 00417 00418 void 00419 gsl_vector_add_element(gsl_vector *vector, double element); 00420 00421 void 00422 random_density_matrix(gsl_matrix_complex *density_random); 00423 00424 void 00425 PSI_matrix(gsl_matrix_complex *psi, double theta); 00426 00427 void 00428 rho_MEMS(gsl_matrix_complex *rho_mems, double gamma); 00429 00430 int 00431 write_matrix_real(char *name, gsl_matrix *data); 00432 00433 double 00434 abs_val(gsl_vector *vec); 00435 00436 void 00437 W_state(gsl_matrix_complex *density); 00438 00439 //public variables 00440 //Stokes measurement basis 00441 gsl_matrix_complex *mu_array[4]; 00442 //Pauli matrices 00443 gsl_matrix_complex *sig_array[4]; 00444 //stores tensored measurement operators 00445 gsl_matrix_complex *mu_cell[NQ]; 00446 //stores tensored measurement Pauli matrices 00447 gsl_matrix_complex *sigma_cell[NQ]; 00448 //computation constants 00449 gsl_complex zero, one; 00450 //matrix full of ones 00451 gsl_matrix_complex *ones; 00452 //Werner state handle 00453 double Werner_handle; 00454 //Tangle handle 00455 double theta_handle; 00456 //! Specifies the simulated number of times an experiment is performed 00457 double N; 00458 00459 // int 00460 // write_data_binary(char *name, gsl_matrix_complex *data); 00461 00462 #endif 00463