เครื่องจำลองคอมพิวเตอร์ควอนตัม
เขียนวงจรควอนตัมขนาดเล็กด้วย JavaScript จำลองในเบราว์เซอร์โดยตรง และดูแผนผังวงจร ความน่าจะเป็น และเวกเตอร์สถานะ หรืออธิบายการคำนวณระดับสูง เช่น การบวก แล้วดูระบบแปลงเป็นวงจรควอนตัมแบบย้อนกลับได้โดยอัตโนมัติ
แบบจำลองสัญญาณรบกวน
คอมพิวเตอร์ควอนตัมจริงไม่ได้คำนวณอย่างสมบูรณ์แบบ: คิวบิตมีความไวมากและสูญเสียข้อมูลบางส่วน (decoherence) ผ่านการโต้ตอบที่ไม่ต้องการกับสภาพแวดล้อมของมัน – ความร้อน สนามแม่เหล็กไฟฟ้า คิวบิตข้างเคียง การดำเนินการเกตก็ไม่แม่นยำเช่นกัน และแม้แต่การอ่านค่าสุดท้ายอาจผิดพลาด เครื่องจำลองนี้คำนวณอย่างเหมาะสมตามค่าเริ่มต้น ที่นี่คุณสามารถเปิดใช้งานแบบจำลองข้อผิดพลาดทั่วไปและสังเกตผลกระทบโดยตรงต่อผลลัพธ์ได้
อธิบายการคำนวณด้วย quantum.add, quantum.subtract, quantum.multiply, quantum.divide หรือ quantum.random กด Ctrl+Enter เพื่อเริ่มการจำลอง ดูเอกสารฉบับเต็มได้จากปุ่ม “เอกสาร”
โค้ดนี้ถูกสร้างขึ้นโดยอัตโนมัติจากโปรแกรมโค้ดด้านบนและทำการจำลองโดยตรง คุณสามารถแก้ไขได้ด้วยตนเองและรันอีกครั้ง
วงจรที่สร้างขึ้นได้รับการแก้ไขด้วยตนเอง การจัดกลุ่มรีจิสเตอร์ในแผนภาพจึงถูกซ่อนไว้ การรันโปรแกรมโค้ดด้านบนอีกครั้งจะเขียนทับการเปลี่ยนแปลงเหล่านี้
สูงสุด 4000 ตัวอักษร เมธอดของ QuantumCircuit ที่ใช้ได้: x, y, z, h, s, sdg, t, tdg, rx, ry, rz, cnot, cz, ccnot (ชื่อแทน: toffoli), swap, measureAll, run กด Ctrl+Enter เพื่อเริ่มการจำลอง
แผนภาพวงจร
มุมมองขั้นตอนแสดงความน่าจะเป็นและเวกเตอร์สถานะทันทีหลังจากการใส่เกตที่เลือก ผลลัพธ์การยิงด้านล่างนี้ใช้กับวงจรทั้งหมด
OpenQASM 2.0
OpenQASM 2.0 เป็นรูปแบบการแลกเปลี่ยนที่ใช้กันอย่างแพร่หลายสำหรับวงจรควอนตัม และถูกอ่านโดย Qiskit ในบรรดาอื่นๆ หมายเหตุเกี่ยวกับลำดับบิต: ซิมูเลเตอร์นี้อ่าน q0 เป็นบิตที่มีนัยสำคัญมากที่สุด (ซ้าย) ในขณะที่ Qiskit อ่าน q[0] เป็นบิตที่มีนัยสำคัญน้อยที่สุด – สตริงบิตที่วัดได้จึงปรากฏเป็นกระจกกัน
ความน่าจะเป็น
โอกาสในการวัดสตริงบิตที่เป็นไปได้ทั้งหมด คำนวณจากเวกเตอร์สถานะอย่างแม่นยำ ทิศทางการอ่าน: q0 คือบิตซ้าย (มากที่สุด)
ทรงกลม Bloch
สถานะของแต่ละคิวบิตเป็นลูกศรในทรงกลม Bloch: ขั้วเหนือ = |0⟩, ขั้วใต้ = |1⟩, เส้นศูนย์สูตร = สภาวะซ้อนทับที่เท่ากัน หากลูกศรสั้นกว่ารัศมีของทรงกลม ลูกบิตนั้นไม่มีสถานะบริสุทธิ์ – มันพัวพันกับคิวบิตอื่นๆ ลูกศรที่สั้นลงอาจเกิดจากสัญญาณรบกวน: ด้วยแบบจำลองสัญญาณรบกวนที่เปิดใช้งาน คิวบิตจะสูญเสียความสอดคล้องและลูกศรจะหดตัวเข้าด้านใน ทรงกลมที่มีสัญญาณรบกวนเป็นการประมาณเท่านั้น – เวกเตอร์ Bloch จะถูกเฉลี่ยตามเส้นทางของสัญญาณรบกวน ด้วยมุมมองขั้นตอนข้างต้น ลูกศรจะเคลื่อนที่ทีละเกต (ไม่มีสัญญาณรบกวนเท่านั้น)
ผลการยิง
ความถี่ที่แต่ละสตริงบิตเกิดขึ้นจริงในการจำลองการวัด ด้วยผลลัพธ์ที่เป็นไปได้หลายแบบ ตัวเลขจะกระจายตัวอย่างสุ่มรอบๆ ความน่าจะเป็นที่แม่นยำ
เวกเตอร์สถานะ
แอมพลิจูดเชิงซ้อนเบื้องหลังความน่าจะเป็น ขนาดกำลังสองของแอมพลิจูด (ส่วนจริง² + ส่วนจินตภาพ²) ให้ความน่าจะเป็นของสถานะนั้น
| สถานะ | ส่วนจริง | ส่วนจินตภาพ |
|---|
พื้นฐาน: ทำงานอย่างไร?
จากโปรแกรมสู่คิวบิตทางกายภาพ
คอมพิวเตอร์ควอนตัมที่แท้จริงเป็นมากกว่าชิป อิเล็กทรอนิกส์ควบคุมคลาสสิคลูกค้าวงจรเป็นการพัลส์ที่แม่นยำ ในตัวอย่างที่แสดงนี้ การทำความเย็น เลเซอร์รีพัมป์ คิวบิต และอ่านค่าจะปรับรูปร่างสัญญาณเหล่านี้บนโต๊ะออปติกและนำไปสู่ห้องสุญญากาศที่มีฉนวนป้องกัน ที่นั่นพวกมันเปลี่ยนและวัดสถานะของคิวบิต ผลการวัดจากนั้นจะกลับไปยังคอมพิวเตอร์คลาสสิก
คิวบิตและสถานะฐาน
บิตแบบดั้งเดิมคือ 0 หรือ 1 คิวบิตสามารถดำรงอยู่ในสถานะซ้อนทับของสองสถานะฐานได้ |0⟩ และ |1⟩. ด้วยคิวบิตหลายตัว สถานะฐานทั้งหมดจะถูกเขียนเป็นสตริงบิต เช่น |10⟩ สำหรับ 2 คิวบิต – โดยที่ q0 ในเครื่องจำลองนี้คือบิตที่มีนัยสำคัญมากที่สุด (ซ้าย) เสมอ
การซ้อนทับ
คิวบิตในสถานะซ้อนทับพร้อมกันบรรทุกส่วนประกอบของสถานะฐานหลายสถานะ ส่วนประกอบเหล่านี้อธิบายโดยแอมพลิจูดเชิงซ้อน ขนาดกำลังสองของแอมพลิจูดให้ความน่าจะเป็นในการได้สถานะที่สอดคล้องกันในการวัด
ทรงกลมบล็อก
สถานะของคิวบิตเดียวสามารถมองเห็นได้เป็นลูกศรในทรงกลม: ขั้วเหนือแสดงถึง |0⟩, ขั้วใต้ |1⟩, และจุดทั้งหมดบนเส้นศูนย์สูตรคือซ้อนทับที่มีน้ำหนักเท่ากัน – เฟสกำหนดทิศทางตามเส้นศูนย์สูตรที่ลูกศรชี้ เกตการหมุน rx, ry, และ rz หมุนลูกศรไปรอบแกนที่เกี่ยวข้อง เกตเฟสเช่น S และ T หมุนรอบแกน Z ด้วย คิวบิตที่พันกัน ลูกศรจะหดตัวเข้าสู่ศูนย์กลางของทรงกลม: คิวบิตแต่ละตัวจึงไม่มีสถานะบริสุทธิ์ของตัวเองอีกต่อไป – ดังนั้นการพันกันจึงเห็นได้ชัดเจน
การวัดและจำนวนครั้ง
measureAll() วัดคิวบิตทั้งหมดในคราวเดียวและสิ้นสุดวงจร เนื่องจาก การวัดเพียงครั้งเดียวให้ผลลัพธ์แบบสุ่มเพียงอย่างเดียว วงจรจึงถูกวัดเชิงแนวคิด "จำนวนครั้ง" ด้วย run({ shots }), เพื่อให้การกระจายความน่าจะเป็นปรากฏเป็นฮิสโตแกรม ความน่าจะเป็นที่แน่นอนยังคำนวณได้โดยตรงจากเวกเตอร์สถานะ โดยไม่ขึ้นอยู่กับความสุ่มของจำนวนครั้ง
เกตฮาดามาร์ด
เกต Hadamard h(q) นำคิวบิตจากสถานะที่กำหนด (|0⟩ หรือ |1⟩) เข้าสู่สถานะซ้อนทับที่มีน้ำหนักเท่ากันของ |0⟩ และ |1⟩ – ดังนั้นประมาณ 50% / 50% เมื่อวัด
เกตเฟส: S และ T
เกต s(q) และ t(q) ไม่เปลี่ยนความน่าจะเป็นในการวัดของคิวบิตเดียว พวกเขาหมุนเฉพาะเฟสของ |1⟩ แอมพลิจูด – S ด้วย 90°, T ด้วย 45° พวกมันแสดงให้เห็นถึงผลกระทบเฉพาะเมื่อรวมกับสถานะซ้อนทับ: ระหว่างเกต Hadamard สองตัว เฟสจะตัดสินว่าแอมพลิจูดรวมกันหรือหักล้าง (การแทรกสอด) รูปแบบดาเงอร์ sdg(q) และ tdg(q) หมุนในทิศทางตรงกันข้ามและยกเลิก S และ T กฎคือ: สอง T ทำให้เกิด S สอง S ทำให้เกิด Z
CNOT & การพันกันแบบมีเงื่อนไข
เกต CNOT cnot(control, target) พลิกคิวบิตเป้าหมายเมื่อคิวบิตควบคุมอยู่ในสถานะ |1⟩. หากคิวบิตควบคุมอยู่ในสถานะซ้อนทับก่อนหน้านี้ สิ่งนี้สามารถสร้างการพันกันได้ – คิวบิตทั้งสองจะไม่สามารถอธิบายได้อย่างอิสระจากกัน เช่น ในตัวอย่างสถานะ Bell หากคิวบิตควบคุมอยู่ในสถานะฐานที่กำหนด CNOT จะดำเนินการพลิกบิตแบบมีเงื่อนไขเท่านั้น ดังนั้นไม่ใช่ทุก CNOT ที่สร้างการพันกันโดยอัตโนมัติ
CZ: ญาติสมมาตรของ CNOT
เกต CZ cz(a, b) กลับเครื่องหมายของแอมพลิจูดเมื่อคิวบิตทั้งสองอยู่ใน |1⟩. ไม่เหมือนกับ CNOT จะไม่มีการควบคุมและไม่มีคิวบิตเป้าหมาย – เกตทำหน้าที่เหมือนกันบนคิวบิตทั้งสอง ซึ่งเป็นเหตุผลว่าทำไมจึงถูกวาดเป็นจุดเชื่อมต่อกันในแผนภาพ CZ และ CNOT สามารถแปลงเป็นซึ่งกันและกันได้: CNOT เป็น CZ ที่คิวบิตเป้าหมายผ่านเกต Hadamard ก่อนและหลัง CZ เป็นองค์ประกอบหลักของอัลกอริทึมจำนวนมาก เช่น การค้นหา Grover
GHZ สถานะ: การพันกันเป็นสามเท่า
สถานะ GHZ (ชื่อตาม Greenberger, Horne และ Zeilinger) ขยายหลักการสถานะ Bell ไปยังคิวบิตสามตัว: เกต Hadamard บวก CNOT สองตัวจะพันคิวบิตทั้งสามเข้าด้วยกันเพื่อให้การวัดให้ผลลัพธ์ |000⟩ หรือ |111⟩ – ไม่เคยสตริงบิตผสม ไม่มีคิวบิตใดมีสถานะของตัวเองอีกต่อไป ข้อมูลทั้งหมดอยู่ในความสัมพันธ์ร่วมกัน
อัลกอริทึม Deutsch: ข้อได้เปรียบเชิงควอนตัมที่เล็กที่สุด
อัลกอริทึม Deutsch ตอบคำถามด้วยการประเมิน Oracle ที่ไม่ทราบเพียงครั้งเดียว ซึ่งคอมพิวเตอร์คลาสสิกต้องทำการประเมินสองครั้ง: ฟังก์ชันเป็นค่าคงที่หรือสมดุล? เคล็ดลับคือการส่งอินพุตผ่าน Oracle ในสถานะซ้อนทับ – ขอบคุณต่อการแทรกสอด คำตอบจะถูกเข้ารหัสอย่างชัดเจนในคิวบิตอินพุต หลักการเบื้องหลัง (การดีดเฟส) อยู่ที่หัวใจของอัลกอริทึมควอนตัมเกือบทั้งหมด
การค้นหา Grover: การขยายแอมพลิจูด
การค้นหา Grover ค้นหารายการที่ถูกทำเครื่องหมายในเซ็ตที่ไม่ได้เรียงลำดับด้วยจำนวนการสืบค้นน้อยกว่าที่จำเป็นตามแบบคลาสสิก Oracle จะทำเครื่องหมายสถานะที่ต้องการด้วยการพลิกเฟส (ผ่านเกต CZ) จากนั้นตัวดำเนินการกระจายจะขยายแอมพลิจูดที่ถูกทำเครื่องหมายไปในค่าใช้จ่ายของคนอื่นๆ ด้วยคิวบิต 2 การวนซ้ำครั้งเดียวก็เพียงพอที่จะวัดฮิตด้วยความน่าจะเป็น 100%
การบวกแบบย้อนกลับ: จาก quantum.add() ถึงวงจร
โปรแกรมแก้ไขโค้ดด้านบนจะแปล quantum.add({ a, b }) เข้าสู่วงจรเกต X, CNOT และ CCNOT (Toffoli) ซึ่งจำลองการบวกแบบคลาสสิกด้วยวิธีที่ย้อนกลับได้ทั้งหมด เกตทุกตัวสามารถย้อนการทำงานได้อย่างแม่นยำเพราะไม่มีข้อมูลถูกทิ้ง เกต CCNOT (ccnot(c1, c2, target)) ทำให้ควอนตัมบิตเป้าหมายกลับด้านเมื่อควอนตัมบิตควบคุมทั้งสองเป็น |1⟩ – ซึ่งเพียงพอที่จะใช้เป็นส่วนประกอบในการสร้างวงจรคลาสสิกที่สามารถย้อนกลับได้ รวมถึงวงจรบวกเต็มพร้อมการทดสอบค่าคงเหลือ อินพุต A และ B ถูกเริ่มต้นให้อยู่ในสถานะฐานที่แน่นอน (ไม่มีการซ้อนทับ) โดยใช้เกต X เนื่องจากวงจรทั้งหมดจึงผ่านเฉพาะสถานะที่แน่นอนแทนที่จะเป็นสถานะซ้อนทับ การวัดผลตอนท้ายจึงให้ผลลัพธ์เดียวเท่านั้นด้วยความน่าจะเป็น 100% – ผลรวมที่ถูกต้องตามแบบคลาสสิก นั่นคือเหตุผลที่ quantum.add() ทำให้ได้ผลลัพธ์ที่แน่นอนแม้จะมีการจำลองควอนตัม แทนที่จะเป็นสถานะที่เป็นไปได้หลายสถานะที่มีความน่าจะเป็นต่ำกว่า 100%
การลบ: การบวกแบบย้อนกลับ
เนื่องจากเกตทุกตัวในวงจรควอนตัมสามารถผกผันได้อย่างสมบูรณ์ วงจรบวกทั้งหมดจึงสามารถดำเนินการย้อนกลับได้ – และการบวกจะกลายเป็น การลบ: quantum.subtract({ a, b }) ใช้วงจรเกตเดียวกันกับวงจรบวก แต่ในลำดับย้อนกลับ เพื่อคำนวณ a − b นี่ไม่ใช่เพียงแค่เทคนิคเล็กน้อย แต่เป็นหลักการพื้นฐานของการคำนวณแบบย้อนกลับ: ขั้นตอนการคำนวณใดๆ ไม่ทำลายข้อมูล ทุกขั้นตอนสามารถยกเลิกได้ ในเวอร์ชันนี้ จำเป็นต้องมี a ≥ b เพื่อป้องกันผลลัพธ์ติดลบ
การคูณ: quantum.multiply()
การคูณเกิดขึ้นจากส่วนประกอบที่สามารถย้อนกลับได้เหมือนกับการบวก ตามวิธีเรียนในโรงเรียน ปัจจัย a ถูกบวกหลายครั้งในตำแหน่งที่เลื่อน – ตรงกับบิตที่ตั้งค่าของปัจจัย b การบวกบางส่วนแต่ละครั้งคือวงจร ripple-carry adder แบบย้อนกลับ; ค่าทด (carry) จะไหลไปยังบิตผลคูณถัดไปในแต่ละครั้ง เนื่องจากขนาดรีจิสเตอร์ผลลัพธ์จะเพิ่มขึ้นตามผลคูณ ปัจจัยจึงถูกจำกัดไว้ที่ 3 บิต (0–7) ที่นี่ – เพื่อให้ปัจจัย ผลคูณ และควอนตัมบิตทด สามารถใส่ลงใน 10 ควอนตัมบิตของเครื่องจำลองนี้ได้
การหาร: quantum.divide()
การหารยังใช้ส่วนประกอบที่สามารถย้อนกลับได้เท่านั้น: quantum.divide({ a, b }) ทำการหารยาวโดยสร้างจาก การลบ ที่เลื่อนและสามารถย้อนกลับได้ของตัวหารออกจากรีจิสเตอร์เศษ ผลลัพธ์คือผลหาร และ เศษ (a = quotient · b + remainder) เนื่องจากตัวหาร ตัวหาร ผลหาร และ ควอนตัมบิตต้องทั้งหมดอยู่ใน 10 ควอนตัมบิตด้วยกัน การหารจึงเป็นปฏิบัติการที่ถูกจำกัดอย่างมาก: bits(a) + bits(b) + bits(a÷b) + 1 ≤ 10 จะต้องเป็นจริง และตัวหาร b ต้องเป็น ≥ 1 (ห้ามหารด้วยศูนย์) หากอินพุตไม่สามารถใส่ในงบประมาณได้ ตัวแก้ไขจะรายงานแทนที่จะคำนวณ
ความสุ่มที่แท้จริง: quantum.random()
คอมพิวเตอร์คลาสสิกไม่สามารถสร้างความสุ่มที่แท้จริงได้ – "ตัวเลขสุ่ม" ของพวกมันมาจากอัลกอริทึมแบบกำหนด (pseudo-randomness) คอมพิวเตอร์ควอนตัมสามารถทำได้: quantum.random({ bits }) ทำให้แต่ละบิตอยู่ในสถานะซ้อนทับ 50/50 ด้วยเกต Hadamard และมีเพียงการวัดเท่านั้นที่ตัดสินอย่างคาดเดาไม่ได้โดยพื้นฐานว่าจะได้ค่าใด บนฮาร์ดแวร์ควอนตัมจริงนี่คือความสุ่มทางกายภาพอย่างแท้จริง ส่วนเครื่องจำลองนี้เลียนแบบด้วยความสุ่มเทียมของเบราว์เซอร์
เครื่องจำลองเทียบกับฮาร์ดแวร์ควอนตัมจริง
เครื่องจำลองนี้คำนวณสถานะอย่างแม่นยำโดยใช้เลขทศนิยมแบบคงที่ในเว็บเบราว์เซอร์ของคุณ – สิ่งนี้ทำได้เฉพาะเมื่อพิจารณาถึงวงจรขนาดเล็กมากที่มีควอนตัมบิตสูงสุด 10 เท่านั้น คอมพิวเตอร์ควอนตัมจริงใช้ควอนตัมบิตทางกายภาพ มีความผิดพลาด (decoherence, noise) และข้อดีของมันจะแสดงให้เห็นกับวงจรอันใหญ่กว่าที่ไม่อาจจำลองได้ด้วยวิธีคลาสสิกในทางปฏิบัติ เครื่องมือนี้เป็นเครื่องมือในการเรียนรู้ ไม่ใช่โปรเซสเซอร์ควอนตัมจริง