จัดกลุ่มเทอมของตัวดำเนินการ: ใช้โครงสร้างของตัวดำเนินการ
BosonOperator ติดแท็ก ดัชนีกลุ่ม ให้แต่ละเทอมได้ แท็กไม่มีความหมายในตัวเอง: มันแค่บอกว่าเทอมไหนอยู่ด้วยกัน ความหมายของแท็กถูกกำหนดโดยสิ่งที่ใช้มัน ในแพ็กเกจนี้ ผู้ใช้คือ Gate วิวัฒนาการตามเวลา ซึ่งถูกแบ่งเป็นหนึ่งตัวประกอบต่อกลุ่ม และ pass qDRIFT แบบสุ่ม ซึ่งสุ่มเลือกทั้งกลุ่ม
คู่มือนี้แสดงวิธีกำหนดกลุ่ม วิธีตรวจสอบคุณสมบัติที่ผู้ใช้พึ่งพา และวิธีจัดวางตัวดำเนินการเพื่อให้การเลือกไม่กี่กลุ่มออกจากกลุ่มใหญ่ยังคงถูก
แพ็กเกจนี้ไม่มีกลยุทธ์การจัดกลุ่มอัตโนมัติมาให้ คุณกำหนดดัชนีเองจากสิ่งที่คุณรู้เกี่ยวกับโมเดลของคุณ
กำหนดกลุ่ม
ตัวอย่างที่ใช้ตลอดคือโซ่ Bose-Hubbard สามไซต์ แต่ละพันธะให้คู่การกระโดดหนึ่งคู่ และอันตรกิริยาบนไซต์ก่อให้เกิดส่วนแนวทแยง วิธีที่ง่ายที่สุดในการสร้างตัวดำเนินการที่จัดกลุ่มคือ from_terms_with_groups() ซึ่งรับแต่ละเทอมพร้อมดัชนีกลุ่มเป็นสามชุด (actions, coefficient, group) คุณตัดสินใจกลุ่มตอนที่เขียนเทอมลงไป ซึ่งเป็นตอนที่คุณยังรู้ว่าทำไมมันอยู่ตรงนั้น:
>>> from qiskit_bosons.operators import BosonOperator, ann, cre
>>>
>>> bonds = [(0, 1), (1, 2)]
>>> terms = []
>>> for group, (left, right) in enumerate(bonds): # one group per bond
... terms.append(([cre(left), ann(right)], -1.0, group))
... terms.append(([cre(right), ann(left)], -1.0, group))
>>> for site in range(3): # the on-site interactions share one group
... terms.append(([cre(site), cre(site), ann(site), ann(site)], 1.0, len(bonds)))
>>> hamiltonian = BosonOperator.from_terms_with_groups(terms)
>>> len(hamiltonian), hamiltonian.num_groups()
(7, 3)
เทอมถูกเก็บตามลำดับที่คุณให้ ดังนั้นดัชนีกลุ่มจะไม่ไปติดกับเทอมผิด
ตัวดำเนินการที่มีอยู่แล้วต้องถูกจัดกลุ่มภายหลัง โดยกำหนดแอตทริบิวต์ groups ตรงนี้ต้องระวัง เพราะ from_dict() ไม่ได้ระบุลำดับที่มันเก็บเทอม การเขียนรายการตามตำแหน่งจึงอาจติดดัชนีกับเทอมผิด ให้หาดัชนีแต่ละตัวจากตัวเทอมเองแทน:
>>> existing = BosonOperator.from_dict({tuple(actions): coeff for actions, coeff, _ in terms})
>>> existing.groups = [
... len(bonds)
... if len({mode for _, mode in term}) == 1
... else bonds.index(tuple(sorted({mode for _, mode in term})))
... for term, _ in existing.iter_terms()
... ]
>>> existing.num_groups(), existing.equiv(hamiltonian)
(3, True)
จำนวนดัชนีต้องตรงกับจำนวนเทอม อย่างอื่นจะถูกปฏิเสธ เพราะรายการที่สั้นเกินไปจะทิ้งเทอมท้าย ๆ แบบเงียบ ๆ ในทุกที่ที่วนเทอมพร้อมกับกลุ่มของมัน:
>>> try:
... hamiltonian.groups = [0, 1]
... except ValueError as error:
... print(error)
expected one group index per term, but got 2 for 7 terms
ตรวจสอบสิ่งที่ผู้ใช้พึ่งพา
สามฟังก์ชันใน qiskit_bosons.operators.terms ตอบคำถามแคบ ๆ ข้อละหนึ่งข้อเกี่ยวกับการจัดกลุ่มที่มีอยู่ ไม่มีฟังก์ชันไหนบอกว่าการจัดกลุ่ม "ถูกต้อง" เพราะความถูกต้องสัมพันธ์กับผู้ใช้
แต่ละกลุ่มเป็นเฮอร์มิเชียนหรือไม่? นี่คือคุณสมบัติที่สำคัญที่สุด วิวัฒนาการตามเวลาของกลุ่มเป็นยูนิตารีก็ต่อเมื่อกลุ่มนั้นเป็นเฮอร์มิเชียน และเทอมการกระโดดเดี่ยว ไม่ เป็น มีเพียงคู่กับตัวผันของมันเท่านั้นที่เป็นเฮอร์มิเชียน:
>>> from qiskit_bosons.operators.terms import groups_are_hermitian
>>> groups_are_hermitian(hamiltonian)
[True, True, True]
การจัดกลุ่มที่แยกคู่การกระโดดจะถูกจับได้ทันที:
>>> split = BosonOperator.from_terms_with_groups(
... [(actions, coeff, index) for index, (actions, coeff, _) in enumerate(terms)]
... ) # one term per group
>>> [bool(flag) for flag in groups_are_hermitian(split)]
[False, False, False, False, True, True, True]
จับเทอมการกระโดดทั้งสี่ได้แล้ว ส่วนรายการ True ทั้งสามคือเทอมบนไซต์ ซึ่งเป็น Hermitian ในตัวเองอยู่แล้ว โหมดหนึ่งซ้ำกันภายในเทอมเดียวได้อย่างถูกต้อง และไม่มีอะไรถูกตัดทิ้งเพราะเหตุนั้น แฟล็กเรียงตามลำดับของ terms จึงอ่านแต่ละตัวเทียบกับเทอมที่มันอธิบายได้
สัมประสิทธิ์สม่ำเสมอกันไหม? สูตรผลคูณแบบสุ่มจะถ่วงน้ำหนักกลุ่มด้วย ขนาด เฉลี่ยของสัมประสิทธิ์ ซึ่งจะอธิบายกลุ่มได้ตรงตามจริงก็ต่อเมื่อขนาดเหล่านั้นตรงกัน
>>> from qiskit_bosons.operators.terms import group_coeff_means, groups_have_uniform_coeffs
>>> groups_have_uniform_coeffs(hamiltonian)
[True, True, True]
>>> group_coeff_means(hamiltonian)
[1.0, 1.0, 1.0]
การตรวจทั้งสองแบบไม่ได้บอกนัยถึงกันและกัน สัมประสิทธิ์ที่สม่ำเสมอไม่ได้ทำให้กลุ่มเป็น Hermitian และกลุ่มที่เป็น Hermitian ก็อาจมีขนาดที่ปะปนกันได้ โดยค่าเริ่มต้นจะเปรียบเทียบขนาด เพราะนั่นคือสิ่งที่ group_coeff_means() นำไปหาค่าเฉลี่ย คู่ Hermitian ที่มีสัมประสิทธิ์เชิงซ้อนจะมีขนาดเท่ากันแต่สัมประสิทธิ์ไม่เท่ากัน จึงผ่านเฉพาะแบบเริ่มต้น:
>>> conjugate = BosonOperator.from_terms_with_groups(
... [([cre(0), ann(1)], 1.0j, 0), ([cre(1), ann(0)], -1.0j, 0)]
... )
>>> groups_have_uniform_coeffs(conjugate)
[True]
>>> groups_have_uniform_coeffs(conjugate, abs=False)
[False]
groups_are_hermitian() สร้างขึ้นบน is_hermitian() ซึ่งเปรียบเทียบตัวดำเนินการกับตัวผูกพันหลังจัดเรียงแบบปกติ นั่นเป็นเอกลักษณ์ของพีชคณิตที่ยังไม่ถูกตัดทอน ดังนั้นกลุ่มที่ผ่านจึงเป็น Hermitian ในฐานะตัวดำเนินการโบซอน ดูวิธีเรียงและเปรียบเทียบผลคูณของตัวดำเนินการแลดเดอร์ได้ที่ หลักการออกแบบการแทนตัวดำเนินการ
เรียงเทอมตามกลุ่ม
split_out_groups() คืนตัวดำเนินการหนึ่งตัวต่อหนึ่งกลุ่มที่ร้องขอ เมื่อเทอมของกลุ่มกระจัดกระจายอยู่ทั่วตัวดำเนินการ มันต้องสแกนทุกเทอมเพื่อหาเทอมเหล่านั้น แต่เมื่อแต่ละกลุ่มเรียงต่อกันเป็นช่วงเดียว มันจะใช้การค้นหาแบบทวิภาคกับขอบเขตของกลุ่มแทน ต้นทุนของการค้นหาจึงขึ้นกับจำนวนกลุ่มที่ ร้องขอ ไม่ใช่จำนวนเทอมที่ เก็บไว้
group_order() สร้างการจัดวางแบบนั้น มันเป็นการเรียงแบบเสถียรตามดัชนีกลุ่ม ค่าของตัวดำเนินการไม่เปลี่ยน และเทอมภายในกลุ่มยังคงลำดับสัมพัทธ์เดิม
>>> from qiskit_bosons.operators.terms import group_order
>>> scattered = BosonOperator.from_terms_with_groups(
... [(actions, coeff, group) for (actions, coeff, _), group in zip(terms, [1, 0, 1, 0, 2, 2, 2])]
... )
>>> ordered = group_order(scattered)
>>> ordered.groups
[0, 0, 1, 1, 2, 2, 2]
>>> ordered.equiv(scattered)
True
การจัดวางทั้งสองแบบคืนตัวดำเนินการชุดเดียวกัน ต่างกันแค่ต้นทุน:
>>> request = [2, 0]
>>> all(
... a.equiv(b)
... for a, b in zip(
... scattered.split_out_groups(request), ordered.split_out_groups(request), strict=True
... )
... )
True
ขั้นตอนถัดไป
การจัดกลุ่มถูกเลือกที่นี่ ในระดับโบซอน ขณะที่โครงสร้างของโมเดลยังมองเห็นได้อยู่
-
สังเคราะห์เกต Evolution ในปริภูมิโบซอน แสดงวิธีใช้มัน Trotterize วิวัฒนาการ และเหตุผลที่มันลดความคลาดเคลื่อนที่สูตรผลคูณระดับ Qubit ทำไม่ได้
-
หลักการออกแบบการแทนตัวดำเนินการ อธิบายโครงสร้างข้อมูลของตัวดำเนินการที่เก็บดัชนีกลุ่ม และวิธีที่เทอมของมันถูกเก็บและเรียงลำดับ
-
2. จัดกลุ่มก่อนแมป ใช้การจัดกลุ่มกับโมเดลที่สมบูรณ์