共用方式為


特製化宣告

如同可呼叫宣告一節中所述,目前沒有理由明確宣告函式的特製化。 本主題詳述宣告必要特製化以支援特定函子的作業和做法介紹。

量子運算其常見問題為需要使用指定轉換的伴隨。 許多量子演算法都需要作業和其伴隨來執行計算。 Q# 採用符號計算功能,可自動為特定主體實作產生對應的伴隨實作。 甚至針對自由混合傳統和量子運算的實作,也能實現這項產生作業。 不過,在此情況下會有一些限制。 例如,如果實作是使用可變的變數,則基於效能考量不支援自動產生功能。 此外,在主體內呼叫的每個作業都會產生對應的伴隨,其本身需要支援 Adjoint 函子。

即使無法輕易復原多量子位元案例中的測量,我們仍可以結合測量,讓套用的轉換為單一量子位元。 在這種情況下,表示即使主體實作包含的測量本身不支援 Adjoint 函子,其整體主體仍為可伴隨。 不過,這時候自動產生伴隨實作的作業將會失敗。 因此,您可以手動指定實作。 編譯器會自動針對常見模式 (例如動詞詞形變化) 產生最佳化實作。 不過,您可能想透過明確特製化,以手動方式進一步定義最佳化的實作。 您可以明確地指定任何一個實作和任意數量的實作。

注意

編譯器不會驗證這類手動指定實作的正確性。

在下列範例中,SWAP 作業的宣告會交換 q1q2 這兩個量子位元的狀態,並為其伴隨版本和其受控版本宣告明確特製化。 因此,當 Adjoint SWAPControlled SWAP 的實作為使用者定義時,編譯器仍然需要為這兩個函子的組合 (Controlled Adjoint SWAPAdjoint Controlled SWAP 相同) 產生實作。

    operation SWAP (q1 : Qubit, q2 : Qubit) : Unit
    is Adj + Ctl { 

        body ... {
            CNOT(q1, q2);
            CNOT(q2, q1);
            CNOT(q1, q2);
        }

        adjoint ... { 
            SWAP(q1, q2);
        }

        controlled (cs, ...) { 
            CNOT(q1, q2);
            Controlled CNOT(cs, (q2, q1));
            CNOT(q1, q2);            
        } 
    }

自動產生指示詞

判斷如何產生特定的特製化時,編譯器會為使用者定義的實作排列優先順序。 這表示,如果伴隨特製化是使用者定義,而受控特製化為自動產生,則會根據使用者定義的伴隨來產生受控伴隨特製化,反之亦然。 在這種情況下,兩種特製化都是使用者定義。 由於伴隨實作的自動產生有更多限制,因此受控伴隨特製化預設會產生伴隨特製化明確定義實作的受控特製化。

若為 SWAP 實作,則較佳選項是伴隨受控特製化,以避免針對控制量子位元狀態上第一個和最後一個 CNOT 的執行進行非必要調節。 為受控伴隨版本新增明確宣告,以指定適當的「產生指示詞」時,可強制要求編譯器改為根據手動指定的受控版本實作來產生受控伴隨特製化。 這樣的特製化明確宣告是由編譯器所產生,會具體成形

    controlled adjoint invert;

並插入 SWAP 宣告內。 另一方面,插入該行時,

    controlled adjoint distribute;

會強制要求編譯器根據定義的 (或產生的)伴隨特製化來產生特製化。 如需詳細資料,請參閱這篇部分特製化推斷建議 (英文)。

針對 SWAP 作業,有一個更好的選項。 SWAP 為其自身的反向,故為「自伴」,因此定義的伴隨實作僅會呼叫 SWAP 主體。 您可以使用指示詞來表示這種情況

    adjoint self;

以這種方式宣告伴隨特製化時,可確保編譯器自動插入的受控伴隨特製化只會叫用受控特製化。

下列為可用且有效的產生指示詞:

特製化 指示詞
body 特製化: -
adjoint 特製化: self, invert
controlled 特製化: distribute
controlled adjoint 特製化: self, invert, distribute

所有產生指示詞對受控伴隨特製化而言都是有效的,這不是巧合;只要函子可以交換,針對函子組合實作特製化的有效產生指示詞集合,就一律是每個函子的有效產生器集合聯集。

除了先前列出的指示詞之外,指示 auto 詞也適用於所有特製化,但 body指出編譯程式應該自動挑選適當的世代指示詞。 這個宣告

    operation DoNothing() : Unit {
        body ... { }
        adjoint auto;
        controlled auto;
        controlled adjoint auto;
    }

相當於

    operation DoNothing() : Unit 
    is Adj + Ctl { }

此範例中的註釋 is Adj + Ctl 會指定作業特性,其中包含特定作業所支援函子的資訊。

為了方便閱讀,建議為每個作業加上其特性的完整描述,以便編譯器根據明確宣告的特製化自動插入或完成註釋。 相反地,編譯器也會產生尚未明確宣告但必須根據註釋特性而存在的特製化。 這表示,指定的註釋已「隱含宣告」這些特製化。 編譯器會盡可能自動產生必要的特製化,並挑選適當的指示詞。 因此,Q# 支援依據 (部分) 註釋和明確定義的特製化來推斷作業特性和現有特製化。

從某方面來說,特製化類似用於相同可呼叫項目的個別多載,但請注意,針對您可以宣告哪些多載仍有特定限制。