量子計算 開放環境中QKH模型的量子模擬程式 (C語言)
阿新 • • 發佈:2018-12-20
《量子混沌運動:量子計算中的干擾及其影響》 – 葉賓 仇量著
附錄:開放環境中QKH模型的量子模擬程式
vs2017執行正常.
qkh.cpp
#include <cstdlib> #include <cstdio> #include <cmath> #include <ctime> #include <complex> //#include <random> using namespace std; typedef complex<double> complexe; //#define M_PI _Pi #define M_PI 3.14159265 double K, L, hbar; // Harper 模型引數 int nq, nr; // nq:量子暫存器中量子位元數目(含1個輔助量子位元),nr=nq-1 long int N, Nr; // Hilbert 空間維數 int steps; // 短時間片演算法中分解的門序列個數 int p_pair, q_pair; long int p, p_imp, q, q_imp; int res1, res2; long int portes; double gam; // 退相干速率 int dissipation_err; // 標記耗散干擾是否存在 int Ntray=150; // 量子軌跡的數目 int channel = 4; // 選擇耗散干擾的噪聲模型:幅值阻尼通道或相位阻尼通道等 int Iter = 10; // 退相干步數 // 計算整數"num"的二進位制表示中"1"的數目之和 int binsum(int num) { int sum, temp; sum = 0; while (num != 0) { temp = num % 2; if (temp == 1) { sum++; } num = num / 2; } return sum; } complexe ampdamp2a(complexe *VE, int k) { int j2, b, i, j; complexe VEtemp, aux1; VEtemp = 0.0; i = 0; for (j2 = 0; j2 < N / 2; j2++) { j = j2 / (i << k) * (1 << (k + 1)) + (1 << k) + j2 - j2 / (1 << k) * (1 <<k); i = j - (1 << k); if (i == 0) { VEtemp = VEtemp + conj(VE[j]) * VE[j]; } else { if (channel == 0) { b = binsum(j); aux1 = conj(complexe(sqrt(1. / float(b)), 0.) * VE[j]); aux1 = aux1 * complexe(sqrt(1. / float(b)), 0.) * VE[j]; } else { aux1 = conj(VE[j]) * VE[j]; } VEtemp = VEtemp + aux1; } } return VEtemp; } // 幅值阻尼通道模型,計算 L_mu |psi> void ampdamp2b(complexe *VE, complexe *VE3, int k) { int j2, b, i, j; for (j2 = 0; j2 < N; j2++) { VE3[j2] = 0.0; } for (j2 = 0; j2 < N / 2; j2++) { j = j2 / (1 << k) * (1 << (k + 1)) + (1 << k) + j2 - j2 / (1 << k) * (1 << k); i = j - (1 << k); if (i == 0) { VE3[i] = VE[j]; } else if (channel == 0) { b = binsum(j); VE3[i] = complexe(sqrt(1. / float(b)), 0.) * VE[j]; } else { VE3[i] = VE[j]; } } } // 去極化通道模型,計算 L_mu |psi> void depolarizaion2b(complexe *VE, complexe *VE3, int k, int j) { int i, i2, j2; complexe aux1; // 位元翻轉型別 if (j == 0) { for (i = 0; i < N / 2; i++) { i2 = (i / (1 << k)) * (1 << (k + 1)) + i - (i / (1 << k)) * (1 <<k); j2 = i2 + (1 << k); VE3[i2] = VE[j2]; j2 = i2; i2 = i2 + (1 << k); VE3[i2] = VE[j2]; } } // 相位翻轉型別 if (j == 2) { for (i = 0; i < N / 2; i++) { i2 = (i / (1 << k)) * (1 << (k + 1)) + i - (i / (1 << k)) * (1 << k); VE3[i2] = VE[i2]; i2 = i2 + (1 << k); VE3[i2] = -1.0 * VE[i2]; } } // 位元和相位同時翻轉型別 if (j == 1) { for (i = 0; i < N / 2; i++) { i2 = (i / (1 << k)) * (1 << (k + 1)) + i - (i / (1 << k)) * (1 << k); j2 = i2 + (1 << k); VE3[i2] = complexe(0.0, -1.0) * VE[j2]; j2 = i2; i2 = i2 + (1 << k); VE3[i2] = complexe(0.0, 1.0) * VE[j2]; } } } // 量子軌跡子函式 void distep(complexe *VE) { int i, j, jj, k, channelNr; int init; double normalisation, delta; double dp, dpm; //double dpv[3 * nq]; complexe VEtemp, *VE3; int bsum; double* dpv = (double*)malloc(3 * nq *sizeof(double)); if (dpv == nullptr) { fprintf(stderr, "Memory allocaltion of dpv failed.\n"); exit(1); } VE3 = (complexe*)malloc(N * sizeof(complexe)); if (VE3 == nullptr) { fprintf(stderr, "Memory allocaltion of VE3 failed.\n"); exit(1); } if (channel <= 1) { channelNr = nq; } else { if (channel == 5) { channelNr = 3 * nq; } else { channelNr = nq; } } for (jj = 1; jj <= Iter; jj++) { if (channel <= 1) { // 幅值阻尼通道 for (k = 0; k < nq; k++) { VEtemp = ampdamp2a(VE, k); dp = real(VEtemp) / (double)Iter; dpv[k+1] = gam * dp; } } else { // 去極化通道 for (k = 0; k < nq; k++) { if (channel == 5) { for (j = 0; j <= 2; j++) { dp = 1.0 / (double)Iter; dpv[1 + k*3 +j] = gam * dp; } } else { j = channel - 2; dp = 1.0 / (float)Iter; dpv[1 + k] = gam * dp; } } } dp = 0.0; for (k = 1; k <= channelNr; k++) { dp = dp + dpv[k]; } //delta = (random() / (double)RAND_MAX); // 產生隨機數delta delta = (rand() / (double)RAND_MAX); // 產生隨機數delta if (delta < dp) { // 量子躍遷 j = 1; dpm = dpv[j]; while ((delta > dpm) && (j < channelNr)) { j = j + 1; dpm = dpm + dpv[j]; } j = j - 1; if (channel <= 1) { ampdamp2b(VE, VE3, j); } else if (channel == 5) { depolarizaion2b(VE, VE3, (j - (j % 3)) / 3, (j % 3)); } else { depolarizaion2b(VE, VE3, j, channel - 2); } normalisation = 0.0; for (i = 0; i < N; i++) { normalisation += norm(VE3[i]); } for (i = 0; i < N; i++) { VE[i] = VE3[i] / sqrt(normalisation); } } else { // 在 H_eff 下演化 for (i = 0; i < N; i++) { VE3[i] = 0.0; } if (channel <= 1) { VE3[0] = VE[0]; init = 1; } else { init = 0; } for (i = init; i < N; i++) { if (channel <= 1) { if (channel == 1) { bsum = binsum(i); VE3[i] = (1.0 - (gam / 2.0 / (float)Iter * (float)bsum)) * VE[i]; } else { VE3[i] = (1.0 - (gam / 2.0 / (float)Iter)) * VE[i]; } } else { VE3[i] = (1.0 - (gam / 2.0 / (float)Iter * (float)channelNr)) * VE[i]; } } normalisation = 0.0; for (i = 0; i < N; i++) { normalisation += norm(VE3[i]); } for (i = 0; i < N; i++) { VE[i] = VE3[i] / sqrt(normalisation); } } } if (VE3 != nullptr) { free(VE3); VE3 = nullptr; } if (dpv != nullptr) { free(dpv); dpv = nullptr; } } // 對第j個量子位元進行 Hadamard 量子門變換 void Porte_Ai(complexe *n, int j) { long int i, masque, complement; complexe temp0, temp1; complexe a11, a12, a21, a22; a11 = 1 / sqrt(2.0); a12 = a11; a21 = a11; a22 = -a11; masque = (long int)1 << j; for (i = 0; i < N; i++) { if (!(i & masque)) { complement = i + masque; temp0 = n[i]; temp1 = n[complement]; n[i] = a11 * temp0 + a12 * temp1; n[complement] = a21 * temp0 + a22 * temp1; } } if (dissipation_err == 1) { distep(n); // 處理耗散干擾 } portes++; } // 量子傅立葉變換中的受控相位門 void Porte_Bjk(complexe *n, int j, int k, int signe) { long int i, masquej, masquek; complexe phase; masquej = (long int)1 << j; masquek = (long int)1 << k; phase = polar(1.0, signe * M_PI / ((long int)1 << (k - j))); for (i = 0; i < N; i++) { if ((i & masquej) && (i & masquek)) { n[i] *= phase; } } if (dissipation_err == 1) { distep(n); } portes++; } // 相移角為 theta 的受控相位門 void Control_Phase(complexe *n, int j, int k, double theta) { long int i, masquej, masquek; complexe phase; masquej = (long int)1 << j; masquek = (long int)1 << k; phase = polar(1.0, theta); for (i = 0; i < N; i++) { if ((i & masquej) && (i & masquek)) { n[i] *= phase; } } if (dissipation_err == 1) { distep(n); } portes++; } // 交換量子位元 j 和 k void Porte_Echange(complexe *n, int j, int k) { long int i, masquej, masquek, complement; complexe temp; masquej = (long int) 1 << j; masquek = (long int) 1 << k; for (i = 0; i < N; i++) { if ((!(i & masquej)) && (i & masquek)) { complement = i - masquek + masquej; temp = n[i]; n[i] = n[complement]; n[complement] = temp; } } } // 量子傅立葉變換, signe 取 -1 表示量子傅立葉逆變換 void QFT(complexe *n, int signe) { int x, m; for (x = nr - 1; x >= 0; x--) { for (m = nr - 1; m > x; m--) { Porte_Bjk(n, x, m, signe); } Porte_Ai(n, x); } for (x = 0; x < (nr / 2); x++) { Porte_Echange(n, x, nr - x - 1); } } // 短時間片逼近演算法中的相位門旋轉門 void Rotation_z(complexe *n, int j, double coef) { long int i, masquej; complexe phase; masquej = (long int) 1 << j; phase = polar(1.0, coef / 2.0); for (i = 0; i < N; i++) { if (i & masquej) { n[i] /= phase; } else { n[i] *= phase; } } if (dissipation_err == 1) { distep(n); } portes++; } // 短時間片逼近演算法中的受控U門 void Control_U(complexe *n, int j, int debut, long int pp) { int k; for (k = 0; k <= debut; k++) { Control_Phase(n, j, debut - k, pp * M_PI / pow(2.0, (double)k)); } } // 短時間片逼近演算法實現的週期驅動演算法 void Kick(complexe *n, double coef, long int pp, int a) { double alpha; int i; int control_qubit, debut; alpha = -coef /steps; control_qubit = nr; debut = nr - 1 - a; Porte_Ai(n, control_qubit); Control_U(n, control_qubit, debut, -pp); Porte_Ai(n, control_qubit); for (i = 0; i < (steps - 1); i++) { Rotation_z(n, control_qubit, alpha / 2.0); Porte_Ai(n, control_qubit); Control_U(n, control_qubit, debut, 2 * pp); Porte_Ai(n, control_qubit); Rotation_z(n, control_qubit, alpha); Porte_Ai(n, control_qubit); Control_U(n, control_qubit, debut, -2 * pp); Porte_Ai(n, control_qubit); Rotation_z(n, control_qubit, alpha / 2.0); } Porte_Ai(n, control_qubit); Control_U(n, control_qubit, debut, pp); Porte_Ai(n, control_qubit); } // 週期驅動的 Harper 模型演化 void Evolution(complexe *n) { QFT(n, 1); // 量子傅立葉變換 Kick(n, K / hbar, q_imp, q_pair); // 算符 U_theta 下演化 QFT(n, -1); // 量子傅立葉逆變換 Kick(n, L / hbar, p_imp, p_pair); // 算符 U_p 下演化 } // 將量子態 nh 置為中心在 (p0, q0) 的高斯波包 void gauss_add(complexe *nh, double p0, double q0, double sigma2) { int p; double angle, fak, norm, xx, NN, N2; complexe val; norm = 1.0 / sqrt(sqrt(2.0 * M_PI * sigma2)); NN = (double) Nr; N2 = NN / 2.0; for (p = 0; p < Nr; p++) { xx = (double) p - p0; if (xx > N2) { xx -= NN; } if (xx < -N2) { xx += NN; } xx = xx * xx / 4.0 / sigma2; fak = exp (-xx) * norm; angle = -q0 * (double)p; val = polar(fak, angle); nh[p] = nh[p] + val; } } // 計算保真度 double fidelity(complexe *n_clean, complexe *n) { complexe sum; int i; sum = 0.0; for (i = 0; i < Nr; i++) { sum += conj(n_clean[i]) * n[i]; } return pow(abs(sum), 2); } int main(int argc, char** argv) { complexe *n, *nh, *n_clean; long int i, j, iterations; int o; double itoq, itop; double normalisation; double *fid; // 保真度 // 輸入5個引數: Harper模型中引數K和L,退相干速率,模擬模型中實際量子位元數目,以及Harper模型迭代次數 if (argc < 6) { puts("syntax: K L dissipation_rate nr iterations"); exit(1); } if (sscanf(argv[1], "%lf", &K) == 0) { puts("syntax: K L dissipation_rate nr iterations"); exit(1); } if (sscanf(argv[2], "%lf", &L) == 0) { puts("syntax: K L dissipation_rate nr iterations"); exit(1); } if (sscanf(argv[3], "%lf", &gam) == 0) { puts("syntax: K L dissipation_rate nr iterations"); exit(1); } if (sscanf(argv[4], "%d", &nr) == 0) { puts("syntax: K L dissipation_rate nr iterations"); exit(1); } if (sscanf(argv[5], "%ld", &iterations) == 0) { puts("syntax: K L dissipation_rate nr iterations"); exit(1); } //srandom((unsigned int)time(NULL)); srand((unsigned int)time(NULL)); Nr = 1 << nr; nq = nr + 1; N = 1 << nq; q = 1; // 相空間中位置座標上相格的數目 p = 1; // 相空間中動量座標上相格的數目 hbar = 2.0 * M_PI / (6.0 + (sqrt(5.0) + 1.0) / 2.0); //hbar = 2.0 * M_PI * p * q / ((double)Nr); // 每個週期驅動算符中短時間片的數目 steps = 100; itoq = 2.0 * M_PI * q / ((double)Nr); itop = 2.0 * M_PI * p / ((double)Nr); p_pair = 0; p_imp = p; while (!(p_imp & 1)) { p_imp >>= 1; p_pair++; } q_pair = 0; q_imp = q; while (!(q_imp & 1)) { q_imp >>= 1; q_pair++; } // 受控量子態記憶體分配 n = (complexe*)malloc(N*sizeof(complexe)); if (n == nullptr) { fprintf(stderr, "Memory allocation of n failed.\n"); exit(1); } // 自由演化的量子態記憶體分配 n_clean = (complexe*)malloc(N*sizeof(complexe)); if (n_clean == nullptr) { fprintf(stderr, "Memory allocation of n_clean failed.\n"); exit(1); } nh = (complexe*)malloc(Nr*sizeof(complexe)); if (nh == nullptr) { fprintf(stderr, "Memory allocation of nh failed.\n"); exit(1); } fid = (double*)malloc(iterations*sizeof(double)); if (fid == nullptr) { fprintf(stderr, "Memory allocations of fid failed.\n"); exit(1); } for (int i = 0; i < iterations; i++) { fid[i] = 0.0; } // 量子態初始化為一高斯波包 gauss_add(nh, Nr/2, Nr/2, sqrt(hbar/2.0)); // 量子軌跡迴圈 for (o = 1; o <= Ntray; o++) { for (i = 0; i < Nr; i++) { n[i] = nh[i]; } for (i = Nr; i < N; i++) { n[i] = 0.0; } for (i = 0; i < N; i++) { n_clean[i] = n[i]; } // Harper模型的演化, 共iterations次 for (j = 0; j < iterations; j++) { fid[j] = fid[j] + fidelity(n_clean, n); // 受退相干影響的量子態演化 dissipation_err = 1; Evolution(n); normalisation = 0.0; // 歸一化 for (i = 0; i < Nr; i++) { normalisation += norm(n[i]); } for (i = 0; i < Nr; i++) { n[i] = n[i] / sqrt(normalisation); } // 無退相干影響的量子態演化 dissipation_err = 0; Evolution(n_clean); normalisation = 0.0; for (i = 0; i < Nr; i++) { normalisation += norm(n_clean[i]); } for (i = 0; i < Nr; i++) { n_clean[i] = n_clean[i] / sqrt(normalisation); } } } for (i = 0; i < iterations; i++) { fid[i] = fid[i] / (double)Ntray; printf("%f\n", fid[i]); } if (n != nullptr) { free(n); n = nullptr; } if (n_clean != nullptr) { free(n_clean); n_clean = nullptr; } if (nh != nullptr) { free(nh); nh = nullptr; } if (fid != nullptr) { free(fid); fid = nullptr; } return 0; }
執行測試結果:
qkh.exe 2 3 0.00001 8 10
407070664077128925905746591304527684289817794357391677350186349610932926098386204699747349466868462346917135026795245006280426456235975363663123728786504798731450690373716158292983879068848854677349490274511261158861483489416101103588216295805018387470820629419971754065920.000000 0.586667 0.079837 0.061836 0.056589 0.021332 0.015638 0.004132 0.001694 0.001328