İngilizce dilinde oku

Aracılığıyla paylaş


Öğretici: Içinde Quantum Fourier Dönüşümünü Uygulama Q#

Bu öğreticide, tek tek kubitler üzerinde çalışan temel bir kuantum programının nasıl yazıldığını ve simülasyonunu nasıl gerçekleştirdiğiniz gösterilir.

Öncelikle büyük ölçekli kuantum programları için üst düzey bir programlama dili olarak oluşturulmuş olsa Q# da, kuantum programlamanın alt düzeyini, yani belirli kubitleri doğrudan ele almak için de kullanılabilir. Özellikle, bu öğretici birçok büyük kuantum algoritmasının ayrılmaz bir alt parçası olan Quantum Fourier Dönüşümü'ne (QFT) daha yakından bakar.

Bu öğreticide şunların nasıl yapılacağını öğreneceksiniz:

  • içinde Q#kuantum işlemlerini tanımlayın.
  • Quantum Fourier Dönüşüm devresini yazma
  • Kubit ayırmadan ölçüm çıkışına kuantum işleminin benzetimini yap.
  • Kuantum sisteminin simülasyon dalga işlevinin işlem boyunca nasıl geliştiğini gözlemleyin.

Not

Kuantum bilgi işlemenin bu alt düzey görünümü genellikle bir sistemin belirli kubitlerine geçitlerin veya işlemlerin sıralı uygulamasını temsil eden kuantum devreleri açısından açıklanmaktadır. Bu nedenle, sırayla uyguladığınız tek ve çok kubitli işlemler devre diyagramlarında kolayca temsil edilebilir. Örneğin, bu öğreticide kullanılan üç kubitli kuantum Fourier dönüşümlerinin tamamı, devre olarak aşağıdaki gösterime sahiptir: Quantum Fourier Dönüşüm devresinin diyagramı.

İpucu

Kuantum bilişim yolculuğunuzu hızlandırmak istiyorsanız Azure Quantum web sitesinin benzersiz bir özelliği olan Azure Quantum ile kod bölümüne bakın. Burada yerleşik Q# örnekleri veya kendi Q# programlarınızı çalıştırabilir, istemlerinizden yeni Q# kod oluşturabilir, kodunuzu tek tıklamayla Web için VS Code'da açıp çalıştırabilir ve Copilot'a kuantum bilişimi hakkında sorular sorabilirsiniz.

Önkoşullar

Yeni Q# dosya oluşturma

  1. VS Code'da Dosya > Yeni Metin Dosyası'na tıklayın
  2. Dosyayı QFTcircuit.qs olarak kaydedin. Bu dosya, programınızın Q# kodunu içerir.
  3. QFTcircuit.qs dosyasını açın.

içinde QFT bağlantı hattı yazma Q#

Bu öğreticinin ilk bölümü, üç kubit üzerinde kuantum Fourier dönüşümünü gerçekleştiren işlemini Q#tanımlamaktırMain. DumpMachine işlevi, üç kubitli sistemin simülasyon dalga işlevinin işlem genelinde nasıl geliştiğini gözlemlemek için kullanılır. Öğreticinin ikinci bölümünde ölçüm işlevselliği ekler ve kubitlerin ölçüm öncesi ve son durumlarını karşılaştırırsınız.

İşlemi adım adım oluşturursunuz. Aşağıdaki bölümlerde yer alan kodu kopyalayıp QFTcircuit.qs dosyasına yapıştırın.

Bu bölümün tam Q# kodunu başvuru olarak görüntüleyebilirsiniz.

Gerekli Q# kitaplıkları içeri aktarma

Dosyanızın Q# içinde ilgili Microsoft.Quantum.* ad alanlarını içeri aktarın.

Q#
import Microsoft.Quantum.Diagnostics.*;
import Microsoft.Quantum.Math.*;
import Microsoft.Quantum.Arrays.*;

// operations go here

Bağımsız değişkenler ve dönüşlerle işlemleri tanımlama

Ardından işlemi tanımlayın Main :

Q#
operation Main() : Unit {
    // do stuff
}

İşlem Main() hiçbir zaman bağımsız değişken almaz ve şimdilik Python'da C# veya boş bir tanımlama grubu Unitdöndürmeye void benzer bir Tuple[()] nesne döndürür. Daha sonra, bir ölçüm sonuçları dizisi döndürmek için işlemi değiştirirsiniz.

Kubitleri ayırma

İşlemin içinde Q# anahtar sözcüğüyle use üç kubitin bir kaydını ayırın. ile use, kubitler otomatik olarak |0 durumunda ayrılır.

Q#
use qs = Qubit[3]; // allocate three qubits

Message("Initial state |000>:");
DumpMachine();

Gerçek kuantum hesaplamalarında olduğu gibi Q# kubit durumlarına doğrudan erişmenize izin vermez. Ancak, DumpMachine işlemi target makinenin geçerli durumunu yazdırır, böylece tam durum simülatörüyle birlikte kullanıldığında hata ayıklama ve öğrenme için değerli içgörüler sağlayabilir.

Tek kubitli ve denetimli işlemleri uygulama

Ardından, işlemin kendisini oluşturan Main işlemleri uygularsınız. Q# zaten ad alanında Microsoft.Quantum.Intrinsic bunların çoğunu ve diğer temel kuantum işlemlerini içerir.

Not

Microsoft.Quantum.Intrinsic Tüm Q# programlar için derleyici tarafından otomatik olarak yüklendiğinden, önceki kod parçacığında diğer ad alanlarıyla içeri aktarılamdığını unutmayın.

Uygulanan ilk işlem, ilk kubite (Hadamard) işlemidir H :

İlk Hadamard'a kadar üç kubit QFT için bir bağlantı hattını gösteren diyagram.

Bir yazmaçtan belirli bir kubite işlem uygulamak için (örneğin, bir dizideki Qubittek Qubit[] bir işlem), standart dizin gösterimini kullanın. Bu nedenle, kaydın H ilk kubitine qs işlemi uygulamak şu şekilde olur:

Q#
H(qs[0]);

QFT devresi, işlemi tek tek kubitlere uygulamanın H yanı sıra öncelikli olarak kontrollü R1 döndürmelerden oluşur. Genel olarak bir R1(θ, <qubit>) işlem, |0 bileşenine eiθ döndürme uygularken kubitin |1 bileşenini değiştirmeden bırakır.

Q# bir işlemin çalışmasını bir veya birden çok denetim kubitine göre koşula bağlamayı kolaylaştırır. Genel olarak, çağrısı ile Controlledbaşlanır ve işlem bağımsız değişkenleri aşağıdaki gibi değişir:

Op(<normal args>) Controlled Op([<control qubits>], (<normal args>))

Tek bir kubit için olsa bile denetim kubiti bağımsız değişkeninin bir dizi olması gerektiğini unutmayın.

QFT'deki denetlenen işlemler, ilk kubit üzerinde işlem gerçekleştiren (ve ikinci ve üçüncü kubitler tarafından denetlenen) işlemlerdir R1 :

İlk kubit aracılığıyla üç kubit Quantum Fourier Dönüşümü için bir bağlantı hattını gösteren diyagram.

Dosyanızda Q# bu işlemleri şu deyimlerle çağırarak:

Q#
Controlled R1([qs[1]], (PI()/2.0, qs[0]));
Controlled R1([qs[2]], (PI()/4.0, qs[0]));

PI() işlevi, döndürmeleri pi radyan açısından tanımlamak için kullanılır.

SWAP işlemi uygulama

İlgili H işlemlerini ve denetimli döndürmeleri ikinci ve üçüncü kubitlere uyguladıktan sonra, devre şöyle görünür:

Q#
//second qubit:
H(qs[1]);
Controlled R1([qs[2]], (PI()/2.0, qs[1]));

//third qubit:
H(qs[2]);

Son olarak, devreyi tamamlamak için birinci ve üçüncü kubitlere bir SWAP işlem uygularsınız. Kuantum Fourier dönüşümü kubitleri ters sırada çıkardığından bu işlem gereklidir, bu nedenle değiştirme işlemleri alt düğümün daha büyük algoritmalarla sorunsuz tümleştirilmesine olanak tanır.

Q#
SWAP(qs[2], qs[0]);

Şimdi kuantum Fourier dönüşümünün kubit düzeyindeki işlemlerini işleminize yazmayı tamamladınız Q# :

Üç kubit Quantum Fourier Dönüşümü için bir bağlantı hattını gösteren diyagram.

Kubitleri serbest bırakma

Son adım, işlem sonrası durumunu görmek ve kubitleri serbest bırakmak için yeniden çağırmaktır DumpMachine() . Kubitleri ayırdığınızda |0 durumundaydı ve işlemi kullanarak ResetAll ilk durumlarına sıfırlanması gerekiyor.

Tüm kubitlerin açıkça |0 olarak sıfırlanması zorunluluğu, diğer işlemlerin Q#aynı kubitleri (kıt kaynak) kullanmaya başladığında durumlarını tam olarak bilmesini sağladığından temel bir özelliğidir. Ayrıca bunları sıfırlamak, sistemdeki diğer kübitlerle dolanık olmamalarını garanti eder. Sıfırlama bir use ayırma bloğunun sonunda gerçekleştirilmezse bir çalışma zamanı hatası ortaya çıkabilir.

Dosyanıza Q# aşağıdaki satırları ekleyin:

Q#
Message("After:");
DumpMachine();

ResetAll(qs); // deallocate qubits

Tam QFT işlemi

Program Q# tamamlandı. QFTcircuit.qs dosyanız şu şekilde görünmelidir:

Q#
import Microsoft.Quantum.Diagnostics.*;
import Microsoft.Quantum.Math.*;
import Microsoft.Quantum.Arrays.*;

operation Main() : Unit {

    use qs = Qubit[3]; // allocate three qubits

    Message("Initial state |000>:");
    DumpMachine();

    //QFT:
    //first qubit:
    H(qs[0]);
    Controlled R1([qs[1]], (PI()/2.0, qs[0]));
    Controlled R1([qs[2]], (PI()/4.0, qs[0]));

    //second qubit:
    H(qs[1]);
    Controlled R1([qs[2]], (PI()/2.0, qs[1]));

    //third qubit:
    H(qs[2]);

    SWAP(qs[2], qs[0]);

    Message("After:");
    DumpMachine();

    ResetAll(qs); // deallocate qubits

}                                                                                                                                                                               

QFT devresini çalıştırma

Şimdilik işlem Main herhangi bir değer döndürmez, işlem değer döndürür Unit . Daha sonra, işlemi bir ölçüm sonuçları dizisi (Result[]) döndürecek şekilde değiştirirsiniz.

  1. Programı çalıştırmadan önce, VS Code'un altındaki durum çubuğunda profilin target olarak ayarlandığını Q#doğrulayın: Sınırsız. Profili değiştirmek target için durum çubuğundan target profili seçin ve açılan menüden Kısıtlanmamış'ı seçin. profili Kısıtlanmamışolarak ayarlanmamışsa, programı çalıştırdığınızda bir hata alırsınız.
  2. Programınızı çalıştırmak için sağ üstteki yürütme simgesi açılan listesinden Dosyayı Çalıştır'ı Q# seçin veya Ctrl+F5 tuşlarına basın. Program, Main() işlemi varsayılan simülatörde çalıştırır.
  3. Message ve DumpMachine çıkışları hata ayıklama konsolunda görünür.

Diğer giriş durumlarının nasıl etkilendiğini merak ediyorsanız, dönüştürmeden önce diğer kubit işlemlerini uygulamayı denemeniz tavsiye edilir.

QFT bağlantı hattına ölçüm ekleme

DumpMachine işlevinden görüntülenen görüntüde işlemin sonuçları gösterilir, ancak ne yazık ki kuantum mekaniğinin bir köşe taşı, gerçek bir kuantum sisteminin böyle bir DumpMachine işlevine sahip olmadığını belirtir. Bunun yerine, bilgiler ölçümler aracılığıyla ayıklanır ve genel olarak tam kuantum durumu hakkında bilgi sağlanmaz, aynı zamanda sistemin kendisini önemli ölçüde değiştirebilir.

Birçok tür kuantum ölçümü vardır, ancak buradaki örnek en temel ölçümlere odaklanır: tek kubitlerdeki yansıtıcı ölçümler. Belirli bir temelde ölçüldükten sonra (örneğin, hesaplama temeli |0,|1), kubit durumu ölçülen temel duruma yansıtılır ve bu nedenle ikisi arasındaki süper konum yok edilir.

QFT işlemini değiştirme

Bir Q# program içinde ölçümler uygulamak için bir tür döndüren M işlemi kullanınResult.

İlk olarak, işlemi yerine bir ölçü sonuçları MainResult[]dizisi döndürecek şekilde değiştirinUnit.

Q#
operation Main() : Result[] {

Dizi tanımlama ve başlatma Result[]

Kubitleri ayırmadan önce üç öğeli bir dizi (her kubit için bir tane Result ) bildirin ve bağlayın:

Q#
mutable resultArray = [Zero, size = 3];

mutable Anahtar sözcük prefacing resultArray değişkeninin kodda daha sonra değiştirilmesini sağlar, örneğin ölçüm sonuçlarınızı eklerken.

Döngüde for ölçümler yapma ve diziye sonuç ekleme

QFT dönüştürme işlemlerden sonra aşağıdaki kodu ekleyin:

Q#
for i in IndexRange(qs) {
    resultArray w/= i <- M(qs[i]);
}

Bir IndexRange dizide çağrılan işlev (örneğin kubit dizisi), qsdizinin dizinleri üzerinde bir aralık döndürür. Burada, M(qs[i]) deyimini kullanarak her kubiti sıralı olarak ölçmek için for döngüsünde kullanılır. Ölçülen Result her tür ( Zero veya One) bir update-and-reassign deyimiyle içindeki ilgili dizin konumuna resultArray eklenir.

Not

Bu deyimin söz dizimi için Q#benzersizdir, ancak F# ve R gibi diğer dillerde görülen benzer değişken yeniden atamasına resultArray[i] <- M(qs[i]) karşılık gelir.

anahtar sözcüğü set her zaman kullanarak mutablebağlı değişkenleri yeniden atamak için kullanılır.

Dönmek resultArray

Üç kubitin de ölçülmesi ve sonuçların resultArray'a eklenmesiyle, kubitleri daha önce olduğu gibi sıfırlayabilir ve serbest bırakabilirsiniz. Ölçümleri döndürmek için şunu ekleyin:

Q#
return resultArray;

Ölçümlerle QFT devresini çalıştırma

Şimdi işlevlerin yerleşimini DumpMachine değiştirerek ölçümlerden önceki ve sonraki durumu çıkış olarak belirleyin. Son Q# kodunuz şu şekilde görünmelidir:

Q#
import Microsoft.Quantum.Diagnostics.*;
import Microsoft.Quantum.Math.*;
import Microsoft.Quantum.Arrays.*;

operation Main() : Result[] {

    mutable resultArray = [Zero, size = 3];

    use qs = Qubit[3];

    //QFT:
    //first qubit:
    H(qs[0]);
    Controlled R1([qs[1]], (PI()/2.0, qs[0]));
    Controlled R1([qs[2]], (PI()/4.0, qs[0]));

    //second qubit:
    H(qs[1]);
    Controlled R1([qs[2]], (PI()/2.0, qs[1]));

    //third qubit:
    H(qs[2]);

    SWAP(qs[2], qs[0]);

    Message("Before measurement: ");
    DumpMachine();

    for i in IndexRange(qs) {
        resultArray w/= i <- M(qs[i]);
    }

    Message("After measurement: ");
    DumpMachine();

    ResetAll(qs);
    Message("Post-QFT measurement results [qubit0, qubit1, qubit2]: ");
    return resultArray;

}

İpucu

Yeniden çalıştırmadan önce kodda her değişiklik eklediğinizde dosyanızı kaydetmeyi unutmayın.

  1. Programı çalıştırmadan önce, VS Code'un altındaki durum çubuğunda profilin target olarak ayarlandığını Q#doğrulayın: Sınırsız. Profili değiştirmek target için durum çubuğundan target profili seçin ve açılan menüden Kısıtlanmamış'ı seçin. profili Kısıtlanmamışolarak ayarlanmamışsa, programı çalıştırdığınızda bir hata alırsınız.
  2. Programınızı çalıştırmak için sağ üstteki yürütme simgesi açılan listesinden Dosyayı çalıştır'ı Q# seçin veya Ctrl+5 tuşlarına basın. Program, Main() işlemi varsayılan simülatörde çalıştırır.
  3. Message ve DumpMachine çıkışları hata ayıklama konsolunda görünür.

Çıkışınız şuna benzer görünmelidir:

Output
Before measurement: 

 Basis | Amplitude      | Probability | Phase
 -----------------------------------------------
 |000⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
 |001⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
 |010⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
 |011⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
 |100⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
 |101⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
 |110⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000
 |111⟩ |  0.3536+0.0000𝑖 |    12.5000% |   0.0000

After measurement: 

 Basis | Amplitude      | Probability | Phase
 -----------------------------------------------
 |010⟩ |  1.0000+0.0000𝑖 |   100.0000% |   0.0000

Post-QFT measurement results [qubit0, qubit1, qubit2]: 

[Zero, One, Zero]

Bu çıkış birkaç farklı şeyi gösterir:

  1. Ölçüm öncesi DumpMachineile döndürülen sonucu karşılaştırdığınızda, QFT sonrası süperpozisyonun temel durumlar üzerindeki açıkça gösterilmediği görülmektedir. Ölçüm, sistemin dalga işlevindeki bu durumun genliği tarafından belirlenen bir olasılıkla yalnızca tek bir temel durum döndürür.
  2. Ölçüm DumpMachinesonrası durumundan ölçümün durumu değiştirdiğini ve bunu temel durumlar üzerinden ilk süper pozisyondan ölçülen değere karşılık gelen tek temel duruma yansıttığını görürsünüz.

Bu işlemi birçok kez tekrarlarsanız, sonuç istatistiklerinin her çekimde rastgele bir sonuca neden olan QFT sonrası durumunun eşit ağırlıklı süper konumunu göstermeye başladığına bakın. Ancak, verimsiz ve hala kusurlu olmasının yanı sıra, bu yine de aralarındaki göreli aşamaları değil, yalnızca temel durumların göreli genliklerini yeniden üretir. İkincisi bu örnekte bir sorun değildir, ancak QFT'ye |000 durumundan daha karmaşık bir giriş verildiğinde göreli fazların ortaya çıktığını görürdünüz.

QFT devresini Q# basitleştirmek için işlemleri kullanın

Girişte belirtildiği gibi, 'nin gücünün Q#çoğu, bireysel kubitlerle ilgilenme endişelerini soyutlamanıza olanak sağlaması gerçeğinde durmektedir. Aslında, tam ölçekli, geçerli kuantum programları geliştirmek istiyorsanız, bir işlemin belirli bir H döndürmeden önce mi yoksa sonra mı geçeceği konusunda endişelenmeniz sizi yalnızca yavaşlatır. Azure Quantum, istediğiniz sayıda kubit için kullanabileceğiniz ve uygulayabileceğiniz işlemi sağlar ApplyQFT .

  1. İlk H işlemden işleme (dahil) kadar SWAP her şeyi şununla değiştirin:

    Q#
    ApplyQFT(qs);
    
  2. Kodunuz şimdi şöyle görünmelidir

    Q#
    import Microsoft.Quantum.Diagnostics.*;
    import Microsoft.Quantum.Math.*;
    import Microsoft.Quantum.Arrays.*;
    
    operation Main() : Result[] {
    
        mutable resultArray = [Zero, size = 3];
    
        use qs = Qubit[3];
    
        //QFT:
        //first qubit:
    
        ApplyQFT(qs);
    
        Message("Before measurement: ");
        DumpMachine();
    
        for i in IndexRange(qs) {
            resultArray w/= i <- M(qs[i]);
        }
    
        Message("After measurement: ");
        DumpMachine();
    
        ResetAll(qs);
        Message("Post-QFT measurement results [qubit0, qubit1, qubit2]: ");
        return resultArray;
    
    }
    
  3. Q# Programı yeniden çalıştırın ve çıkışın öncekiyle aynı olduğuna dikkat edin.

  4. İşlemleri kullanmanın Q# gerçek avantajını görmek için kubit sayısını dışında 3bir şeyle değiştirin:

Q#
mutable resultArray = [Zero, size = 4];

use qs = Qubit[4];
//...

Böylece, her kubite yeni H işlemler ve döndürmeler ekleme konusunda endişelenmenize gerek kalmadan, belirli sayıda kubit için uygun QFT'yi uygulayabilirsiniz.

Diğer Q# öğreticileri keşfedin: