Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu öğreticide, belirli bir kuantum durumunda iki kubit hazırlayan, kubitleri birbiriyle dolanık hale getirmek için çalışan ve süper pozisyon ve dolanıklığın etkilerini göstermek için ölçümler yapan bir Q# program yazacaksınız. Kubit durumlarını, kuantum işlemlerini ve ölçümleri tanıtmak için programınızı Q# parça parça oluşturursunuz.
Başlamadan önce aşağıdaki kuantum bilgi işlem kavramlarını gözden geçirin:
- Klasik bitler, 0 veya 1 gibi tek bir ikili değeri barındırır, ancak kubitler 0 ve 1 durumlarının süperpozisyonunda olabilir. Her olası kubit durumu, bir olasılık genlikleri kümesiyle açıklanır.
- Kubitin durumunu ölçtüyseniz her zaman 0 veya 1 alırsınız. Her sonucun olasılığı, bir ölçüm yaptığınızda süper pozisyon durumunu tanımlayan olasılık genlikleri tarafından belirlenir.
- Birden çok kubit dolanık olabilir, böylece bunları birbirinden bağımsız olarak açıklayamazsınız. Dolanık bir çiftteki bir kubiti ölçtüyseniz, diğer kubit hakkındaki bilgileri de ölçmeden alırsınız.
Bu eğitimde şunları öğreniyorsunuz:
- Kubit durumlarını başlatmak için Q# işlemleri oluşturun.
- Kubiti süper pozisyon durumuna yerleştirin.
- Bir kubit çiftini dolandırın.
- Kubiti ölçün ve sonuçları görüntüleyin.
Önkoşullar
Kod örneğini yerel geliştirme ortamınızda geliştirmek ve çalıştırmak için aşağıdaki araçları yükleyin:
- Visual Studio Code'un (VS Code) en son sürümü veya Web için VS Code dosyasını açın.
- Microsoft Quantum Development Kit (QDK) uzantısının en son sürümü. Yükleme ayrıntıları için bkz. QDK'yi ayarlama.
Yeni Q# dosya oluşturma
- VS Code'da Dosya menüsünü açın ve Yeni Metin Dosyası'nı seçerek yeni bir dosya oluşturun.
- Dosyayı
CreateBellStates.qsolarak kaydedin. Bu dosya, programınızın kodunu yazdığınız Q# yerdir.
Kübiti bilinen bir duruma başlatın.
İlk adım, kubiti istenen klasik duruma (0 veya 1) başlatan bir işlem tanımlamaktır Q# . Bu işlem, genel bir kuantum durumundaki bir kubiti ölçer ve bu ölçüm, Q# veya Result değerlerinden birini döndüren bir ZeroOne türü değer sağlar. Ölçüm sonucu istenen durumdan farklıysa, işlem durumu çevirir ve böylece işlem her zaman %100 istenen durumu döndürür.
Aşağıdaki kodu açın CreateBellStates.qs ve kopyalayın:
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
Kod örneği, Q# kubitin durumunu dönüştüren iki standart M işlemi ve Xtanıtır.
İşlemin nasıl çalıştığına ilişkin ayrıntılı bir açıklama aşağıdadır SetQubitState :
- İki parametre alır: Kubitin bulunacağı arzu edilen durumu (
Resultveyadesired) temsil eden, adıZeroolan birOnetür parametresi ve birQubittür parametresi. - Kubitin (
MveyaZero) durumunu ölçen ve sonucu içinOnegeçirdiğiniz değerle karşılaştıran bir ölçüm işlemidesiredgerçekleştirir. - Ölçüm sonucu değeriyle
desiredeşleşmiyorsa kubite birXişlem uygulanır. Bu işlem,ZeroveOneiçin ölçüm olasılıklarını tersine çevirmek üzere kubitin durumunu çevirir.
Bell durumunu test etmek için bir test işlemi yazma
SetQubitState işlemini programınızda çağırmak için Q# adlı Main adlı başka bir işlem oluşturun. Bu işlem iki kubit ayırır, ilk kubiti bilinen bir duruma ayarlamak için çağrılar SetQubitState ve ardından sonuçları görmek için kubitleri ölçer.
CreateBellStates.qs işleminden sonra, SetQubitState dosyanıza aşağıdaki işlemi ekleyin:
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
numOnesQ1 += 1;
}
if resultQ2 == One {
numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Kodda, count ve initial değişkenleri sırasıyla 1000 ve One olarak ayarlanır. Bu, ilk kubiti One başlatır ve her kubiti 1000 kez ölçer.
İşlem Main aşağıdakileri yapar:
- Çekim sayısı () ve ilk kubit durumu (
countOne) için değişkenleri ayarlar. - İki kubiti başlatmak için
useifadesini çağırır. - Deneme
countzamanları üzerinde döngüler. - Döngüde, ilk kübitte belirtilen
SetQubitStatedeğerini ayarlamak içininitialçağırır, ardından ikinci kübitiSetQubitStatedurumuna ayarlamak içinZero'yi yeniden çağırır. - Döngüde, her kubiti
Mölçmek için işlemi uygular ve ardından döndürenOneher kubit için ölçü sayısını depolar. - Döngü tamamlandıktan sonra kubitleri bilinen bir duruma (
SetQubitState) sıfırlamak için yeniden çağırırZero.usedeyimiyle ayırdığınız kubitleri sıfırlamanız gerekir. - Konsola sonuçlarınızı yazdırmak için
Messageişlevini çağırır.
Kodu çalıştırma
Süperpozisyon ve dolanıklık için kod yazmadan önce, kubitlerin başlatılmasını ve ölçülmesini sağlamak için geçerli programınızı test edin.
Kodu tek başına bir program olarak çalıştırmak için derleyicinin Q# programı nereden başlatacaklarını bilmesi gerekir. Ad alanı belirtmediğiniz için, derleyici varsayılan giriş noktasını işlem olarak Main tanır. Daha fazla bilgi için bkz . Projeler ve örtük ad alanları.
Dosyanız CreateBellStates.qs şimdi şöyle görünür:
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = One;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
numOnesQ1 += 1;
}
if resultQ2 == One {
numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Programı çalıştırmak için, işlemin önündeki kod merceğinden Main komutunu seçin veya Ctrl + F5 girin. Program, Main işlemi varsayılan simülatörde çalıştırır.
Çıkışınız hata ayıklama konsolunda görünür.
Q1 - Zeros: 0
Q1 - Ones: 1000
Q2 - Zeros: 1000
Q2 - Ones: 0
Programınız henüz kubit durumlarını değiştirmediğinden, ilk kubitin ölçümü her zaman döndürür Oneve ikinci kubit her zaman döndürür Zero.
değerini initialZero olarak değiştirir ve programı yeniden çalıştırırsanız, ilk kubit de her zaman döndürür Zero.
Q1 - Zeros: 1000
Q1 - Ones: 0
Q2 - Zeros: 1000
Q2 - Ones: 0
Kubiti süper pozisyon durumuna yerleştirme
Şu anda, programınızdaki kubitler normal bir bilgisayardaki bitler gibi 1 veya 0 klasik bir durumdadır. Kubitleri dolanık hale getirmek için önce kubitlerden birini eşit süper pozisyon durumuna yerleştirmeniz gerekir. Eşit süperpozisyon durumundaki bir kubitin ölçümü, Zero ölçüm sonucu için %50 ve One ölçüm sonucu için %50 şansa sahiptir.
Kubiti süper pozisyon durumuna yerleştirmek için , veya Hadamard, işlemini kullanın Q#H. İşlem, saf H veya Zero durumundaki bir kubiti, One ve Zero arasında bir tür yarı yol durumuna dönüştürür.
İşlemdeki Main kodunuzu değiştirin. İlk değeri One olarak sıfırlayın ve operasyon için H bir satır ekleyin.
for test in 1..count {
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
H(q1); // Add the H operation after initialization and before measurement
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
...
Programınızı yeniden çalıştırın. İlk kubiti ölçtüğünüzde eşit bir süperpozisyonda olduğundan, Zero ve One için yaklaşık olarak bir 50/50 sonucuna ulaşırsınız. Örneğin, çıktınız buna benzer:
Q1 - Zeros: 523
Q1 - Ones: 477
Q2 - Zeros: 1000
Q2 - Ones: 0
Programı her çalıştırdığınızda, ilk kubitin sonuçları biraz değişir, ancak 50% One ve 50% Zeroyakındır; ikinci kubitin sonuçları yine de her zaman Zeroolur.
İlk kubiti Zero olarak başlatın, One yerine ve programı yeniden çalıştırın.
H işlemi her iki saf durumu da eşit bir süperpozisyon durumuna dönüştürdüğünden benzer sonuçlar elde edersiniz.
İki kubiti dolanıklığa sokun
Dolanık kubitler, birbirlerinden bağımsız olarak tanımlanamayacak şekilde birbirleriyle bağıntılıdır. Dolanık kubitlerden birinin durumunu ölçerken, diğer kubiti ölçmeden durumunu da bilirsiniz. Bu öğreticide iki dolanık kubit içeren bir örnek kullanılır, ancak üç veya daha fazla kubiti de dolandırabilirsiniz.
Dolanık bir durum oluşturmak için , veya Controlled-NOT, işlemini kullanın Q#CNOT. İki kubite uyguladığınızda CNOT , bir kubit denetim kubiti, diğeri de hedef kubittir. Denetim kubitinin durumu iseOneCNOT, işlem hedef kubitin durumunu çevirir. Aksi takdirde kubitlere CNOT hiçbir şey yapmaz.
CNOT işlemini, H işleminden hemen sonra programınıza ekleyin. Tam programınız şöyle görünür:
operation SetQubitState(desired : Result, target : Qubit) : Unit {
if desired != M(target) {
X(target);
}
}
operation Main() : (Int, Int, Int, Int) {
mutable numOnesQ1 = 0;
mutable numOnesQ2 = 0;
let count = 1000;
let initial = Zero;
// allocate the qubits
use (q1, q2) = (Qubit(), Qubit());
for test in 1..count {
SetQubitState(initial, q1);
SetQubitState(Zero, q2);
H(q1);
CNOT(q1, q2); // Add the CNOT operation after the H operation
// measure each qubit
let resultQ1 = M(q1);
let resultQ2 = M(q2);
// Count the number of 'Ones' returned:
if resultQ1 == One {
numOnesQ1 += 1;
}
if resultQ2 == One {
numOnesQ2 += 1;
}
}
// reset the qubits
SetQubitState(Zero, q1);
SetQubitState(Zero, q2);
// Display the times that |0> is returned, and times that |1> is returned
Message($"Q1 - Zeros: {count - numOnesQ1}");
Message($"Q1 - Ones: {numOnesQ1}");
Message($"Q2 - Zeros: {count - numOnesQ2}");
Message($"Q2 - Ones: {numOnesQ2}");
return (count - numOnesQ1, numOnesQ1, count - numOnesQ2, numOnesQ2 );
}
Programı çalıştırın ve çıkışı görüntüleyin. Programı her çalıştırdığınızda sonuçlarınız çok az değişiklik gösterir.
Q1 - Zeros: 502
Q1 - Ones: 498
Q2 - Zeros: 502
Q2 - Ones: 498
İlk kubitin istatistikleri, hem One hem de Zero ölçülmesi için yaklaşık %50 şans gösterir, ancak ikinci kubitin ölçüm sonuçları artık her zaman Zero göstermez. Her kubit aynı sayıda Zero sonuç ve One sonuç içeriyor. İki kubit dolanık olduğundan, ikinci kubitin ölçüm sonucu her zaman ilk kubitin sonucuyla aynıdır. İlk kubit Zero olarak ölçülürse, dolanık kubit de Zero olacaktır. İlk kubit One olarak ölçülürse, dolanık kubit de One olacaktır.
Sıklık histogramını çizme
Programınızı birden çok kez çalıştırdığınızda sonuçların dağılımını gösteren bir sıklık histogramı çizmek için aşağıdaki adımları tamamlayın:
Dosyanızı
CreateBellStates.qsVS Code'da açın.Görünüm menüsünü açın ve Komut Paleti'ni seçin.
QDK: Dosyayı çalıştır ve histogram seçeneğini göstermek için histogram girin. İsterseniz, işlemden önceki kod merceği seçeneğinden
Mainkomutunu da seçebilirsiniz. Ardından, bir çekim sayısı girin (örneğin, 100). Histogram Q# yeni bir sekmede açılır.Histogramdaki her çubuk, dolanıklık devresi 1000 kez çalıştığında olası bir sonuca karşılık gelir. Çubuğun yüksekliği, sonucun kaç kez ortaya çıktığını gösterir. Örneğin, aşağıdaki histogramda 50 benzersiz sonuç içeren bir dağılım gösterilmektedir. Her sonuç için birinci ve ikinci kubit için ölçüm sonuçlarının her zaman aynı olduğunu unutmayın.
İpucu
Histogramı yakınlaştırmak için fare kaydırma tekerleğini veya izleme yüzeyi hareketini kullanın. Yakınlaştırdığınızda grafiği kaydırmak için, kaydırırken Alt tuşunu basılı tutun.
Bu sonucu oluşturan toplam çekimlerin yüzdesini görüntülemek için bir çubuk seçin.
Görselleştirme seçeneklerini görüntülemek için sol üstteki ayarlar simgesini seçin.
Kodu yeniden çalıştırın, ancak bu kez 1000 çekimle. Çekim sayısı arttıkça, sonuçların dağılımı normal bir dağılıma yaklaşır.
İlgili içerik
Diğer Q# öğreticileri keşfedin:
- Grover arama algoritması, Grover arama algoritmasını kullanan bir Q# programın nasıl yazıldığını gösterir.
- Quantum Fourier Transform , belirli kubitleri doğrudan ele alan bir Q# programın nasıl yazıldığını keşfeder.
- Quantum Katas, kuantum bilişimi ve programlama öğelerini aynı anda öğreten, kendi hızınıza göre ilerleyen öğreticiler ve programlama alıştırmalarıdır.