Trình Mô Phỏng Máy Tính Lượng Tử
Viết một mạch lượng tử nhỏ trong JavaScript, mô phỏng trực tiếp trong trình duyệt của bạn và xem sơ đồ mạch, xác suất và vectơ trạng thái. Hoặc mô tả một phép tính ở mức cao (ví dụ: phép cộng) và xem nó tự động chuyển thành một mạch lượng tử thuận nghịch thực tế.
Mô hình nhiễu
Máy tính lượng tử thực tế không tính toán hoàn hảo: các qubit cực kỳ nhạy cảm và mất một phần thông tin của chúng (mất sự gắn kết) thông qua mọi tương tác không mong muốn với môi trường – nhiệt, trường điện từ, các qubit lân cận. Các phép toán cổng cũng không bao giờ hoàn toàn chính xác, và thậm chí cả kết quả đọc cuối cùng cũng có thể sai. Máy tính mô phỏng này tính toán lý tưởng theo mặc định; bạn có thể bật các mô hình lỗi điển hình ở đây và quan sát trực tiếp tác động của chúng đến kết quả.
Mô tả một phép tính toán bằng quantum.add, quantum.subtract, quantum.multiply, quantum.divide hoặc quantum.random. Ctrl+Enter bắt đầu mô phỏng. Tài liệu đầy đủ qua nút “Tài liệu”.
Mã này được tạo tự động từ mã chương trình ở trên và mô phỏng trực tiếp. Bạn có thể chỉnh sửa nó ở đây một cách thủ công và chạy lại.
Mạch được tạo đã được chỉnh sửa thủ công. Nhóm thanh ghi trong sơ đồ do đó bị ẩn; chạy lại mã chương trình ở trên sẽ ghi đè những thay đổi này.
Tối đa 4000 ký tự. Các phương thức QuantumCircuit có sẵn: x, y, z, h, s, sdg, t, tdg, rx, ry, rz, cnot, cz, ccnot (bí danh: toffoli), swap, measureAll, run. Ctrl+Enter bắt đầu mô phỏng.
Sơ đồ mạch
Chế độ bước hiển thị xác suất và vectơ trạng thái ngay sau cổng đã chọn. Kết quả bắn bên dưới luôn áp dụng cho toàn bộ mạch.
OpenQASM 2.0
OpenQASM 2.0 là định dạng trao đổi được sử dụng rộng rãi cho mạch lượng tử và được đọc bởi Qiskit, trong số những chương trình khác. Lưu ý về thứ tự bit: trình mô phỏng này đọc q0 là bit có ý nghĩa lớn nhất (bên trái), trong khi Qiskit đọc q[0] là bit ít có ý nghĩa nhất – các chuỗi bit đo được do đó có vẻ bị đảo ngược ở đó.
Xác suất
Khả năng đo mỗi chuỗi bit có thể, được tính toán chính xác từ vector trạng thái. Hướng đọc: q0 là bit bên trái (có ý nghĩa lớn nhất).
Hình cầu Bloch
Trạng thái của mỗi qubit riêng lẻ được biểu diễn bằng một mũi tên trên hình cầu Bloch: cực bắc = |0⟩, cực nam = |1⟩, đường xích đạo = chồng chập có trọng lượng bằng nhau. Nếu mũi tên ngắn hơn rõ ràng so với bán kính hình cầu, qubit không có trạng thái tinh khiết của riêng nó – nó bị vướng víu với các qubit khác. Mũi tên ngắn cũng có thể đến từ nhiễu: với mô hình nhiễu đang hoạt động, qubit mất tính kết hợp và mũi tên co lại. Các hình cầu nhiễu là một xấp xỉ ở đây – vectơ Bloch được trung bình hóa trên các quỹ đạo nhiễu. Với chế độ xem bước ở trên, các mũi tên di chuyển từng cổng (chỉ không có nhiễu).
Kết quả đo
Số lần mỗi chuỗi bit thực tế xảy ra trong các phép đo mô phỏng. Với nhiều kết quả có thể, các số sẽ phân tán ngẫu nhiên xung quanh các xác suất chính xác.
Vector trạng thái
Các biên độ phức sau các xác suất: bình phương độ lớn của một biên độ (thực² + ảo²) cho xác suất của trạng thái đó.
| Trạng thái | Phần thực | Phần ảo |
|---|
Cơ bản: Cách thức hoạt động?
Từ chương trình đến qubit vật lý
Một máy tính lượng tử thực tế là hơn một chip. Điện tử điều khiển cổ điển dịch mạch thành các xung chính xác. Trong ví dụ được hiển thị, làm mát, bơm lại, qubit và laser đọc định hình các tín hiệu này trên một bàn quang học và hướng chúng vào buồng chân không được che chắn. Ở đó chúng thay đổi và đo trạng thái qubit; kết quả đo sau đó trả lại cho máy tính cổ điển.
Qubit & trạng thái cơ sở
Một bit cổ điển là 0 hoặc 1. Một qubit có thể tồn tại trong trạng thái chồng chập của cả hai trạng thái cơ sở |0⟩ và |1⟩Với nhiều qubit, tất cả các trạng thái cơ sở được viết dưới dạng một chuỗi bit, ví dụ: |10⟩ dành cho 2 qubit – trong đó q0 trong trình mô phỏng này luôn là bit có trọng số lớn nhất (bên trái).
Chồng chập
Một qubit trong trạng thái chồng chập đồng thời mang các thành phần của nhiều trạng thái cơ sở. Các thành phần này được mô tả bằng biên độ phức; bình phương độ lớn của một biên độ cho xác suất thu được trạng thái tương ứng trong phép đo.
Hình cầu Bloch
Trạng thái của một qubit đơn lẻ có thể được hình dung như một mũi tên trên một hình cầu: cực bắc đại diện |0⟩cực nam |1⟩và tất cả các điểm trên đường xích đạo là các trạng thái chồng chập có trọng số bằng nhau – pha xác định hướng dọc theo đường xích đạo mà mũi tên chỉ. Các cổng xoay rx, ryvà rz xoay mũi tên xung quanh trục tương ứng, các cổng pha như S và T xoay nó xung quanh trục Z. Với các qubit vướng víu, mũi tên co lại về phía tâm của hình cầu: qubit riêng lẻ sau đó không còn trạng thái tinh khiết của riêng nó – vì vậy vướng víu trở nên hiển thị theo nghĩa đen.
Đo lường & số lần đo
measureAll() đo tất cả các qubit cùng một lúc và kết thúc mạch. Vì một phép đo duy nhất chỉ tạo ra một kết quả ngẫu nhiên, mạch được đo lường về mặt khái niệm "số lần đo" lần với run({ shots })để phân phối xác suất xuất hiện dưới dạng biểu đồ. Các xác suất chính xác cũng được tính trực tiếp từ vectơ trạng thái, độc lập với tính ngẫu nhiên của số lần đo.
Cổng Hadamard
Cổng Hadamard h(q) chuyển một qubit từ trạng thái xác định (|0⟩ hoặc |1⟩) vào trạng thái chồng chập có trọng số bằng nhau của |0⟩ và |1⟩ – khoảng 50% / 50% khi đo.
Cổng pha: S và T
các cổng s(q) và t(q) không thay đổi xác suất đo của một qubit đơn lẻ; chúng chỉ xoay pha của |1⟩ biên độ – S là 90°, T là 45°. Chúng chỉ thể hiện hiệu ứng của chúng khi kết hợp với chồng chập: giữa hai cổng Hadamard, pha quyết định cách các biên độ kết hợp hoặc triệt tiêu (giao thoa). Các biến thể dagger sdg(q) và tdg(q) xoay ngược lại chính xác và đảo ngược S và T. Quy tắc là: hai T tạo thành một S, hai S tạo thành một Z.
CNOT & vướng mắc lượng tử có điều kiện
Tự cổng CNOT cnot(control, target) lật qubit đích chính xác khi qubit điều khiển ở trạng thái |1⟩Nếu qubit điều khiển ở trạng thái chồng chập trước đó, điều này có thể tạo ra vướng mắc – hai qubit sau đó không thể được mô tả độc lập với nhau, như trong ví dụ trạng thái Bell. Nếu qubit điều khiển ở trạng thái cơ sở xác định thay vào đó, CNOT chỉ thực hiện lật bit có điều kiện mà không có vướng mắc. Vì vậy, không phải mọi CNOT đều tự động tạo ra vướng mắc.
CZ: tương đối đối xứng của CNOT
Tự cổng CZ cz(a, b) lật dấu biên độ chính xác khi cả hai qubit đều |1⟩Không giống như CNOT, không có qubit điều khiển và không có qubit đích – cổng tác động giống nhau lên cả hai qubit, đó là lý do tại sao nó được vẽ là hai chấm kết nối trong sơ đồ. CZ và CNOT có thể được chuyển đổi thành nhau: một CNOT là một CZ có qubit đích được truyền qua cổng Hadamard trước và sau đó. CZ là một khối xây dựng trung tâm của nhiều thuật toán, chẳng hạn như tìm kiếm Grover.
Trạng thái GHZ: vướng mắc như một bộ ba
Trạng thái GHZ (được đặt tên theo Greenberger, Horne và Zeilinger) mở rộng nguyên tắc trạng thái Bell sang ba qubit: một cổng Hadamard cộng với hai CNOTs vướng mắc cả ba sao cho phép đo chỉ tạo ra |000⟩ hoặc |111⟩ – không bao giờ có chuỗi bit hỗn hợp. Không có qubit nào có trạng thái của riêng nó nữa; thông tin nằm duy nhất trong tương quan được chia sẻ.
Thuật toán Deutsch: lợi thế lượng tử nhỏ nhất
Thuật toán Deutsch trả lời, với một lần đánh giá duy nhất của oracle không xác định, một câu hỏi mà máy tính cổ điển cần hai lần đánh giá: hàm có phải là hằng số hay cân bằng? Mẹo là gửi đầu vào qua oracle ở trạng thái chồng chập – nhờ giao thoa, câu trả lời sau đó được mã hóa một cách không mơ hồ trong qubit đầu vào. Nguyên tắc đằng sau nó (đánh bật pha) nằm ở trung tâm của hầu hết mọi thuật toán lượng tử.
Tìm kiếm Grover: khuếch đại biên độ
Tìm kiếm Grover tìm thấy một mục được đánh dấu trong một tập không được sắp xếp với ít truy vấn hơn đáng kể so với yêu cầu cổ điển. Một oracle đánh dấu trạng thái được tìm kiếm bằng một lật pha (ở đây thông qua cổng CZ), sau đó toán tử khuếch tán khuếch đại biên độ được đánh dấu với chi phí của tất cả những người khác. Với 2 qubit, một lần lặp là đủ để đo lường lần đánh trúng với 100% xác suất.
Phép cộng có thể đảo ngược: từ quantum.add() đến một mạch
Trình soạn thảo mã chương trình ở trên dịch quantum.add({ a, b }) thành một mạch các cổng X, CNOT và CCNOT (Toffoli) tái tạo phép cộng cổ điển một cách hoàn toàn có thể đảo ngược: mọi cổng đều có thể được hoàn tác chính xác, vì không có thông tin nào bị loại bỏ. Cổng CCNOT (ccnot(c1, c2, target)) lật qubit đích chỉ khi cả hai qubit điều khiển đều |1⟩ – điều đó đủ như một khối xây dựng để tái tạo bất kỳ mạch cổ điển nào một cách có thể đảo ngược, bao gồm cả bộ cộng đầy đủ với phần bù. Các đầu vào A và B được khởi tạo ban đầu ở các trạng thái cơ sở xác định (không chồng chập) bằng cách sử dụng các cổng X. Vì toàn bộ mạch do đó chỉ đi qua các trạng thái xác định thay vì các trạng thái chồng chập, phép đo ở cuối tạo ra chính xác một kết quả với 100% xác suất – tổng đúng theo cổ điển. Đó là lý do tại sao quantum.add() tạo ra một kết quả xác định bất chấp mô phỏng lượng tử, thay vì nhiều trạng thái có thể với xác suất dưới 100%.
Phép trừ: phép cộng theo thứ tự ngược lại
Vì mỗi cổng của mạch lượng tử đều có thể đảo ngược chính xác, mạch cộng hoàn chỉnh có thể được thực hiện ngược lại – và phép cộng trở thành phép trừ: quantum.subtract({ a, b }) sử dụng chính xác các cổng của mạch cộng theo thứ tự ngược lại và do đó tính toán a − b. Đây không phải là một trò thủ thuật mà là nguyên tắc cơ bản của tính toán có thể đảo ngược: không có bước tính toán nào phá hủy thông tin, mọi bước đều có thể được hoàn tác. Trong phiên bản này, a ≥ b là bắt buộc để không có kết quả âm nào xảy ra.
Phép nhân: quantum.multiply()
Phép nhân ở đây xuất hiện từ chính các khối xây dựng có thể đảo ngược giống như phép cộng: theo phương pháp sách giáo khoa, thừa số a được cộng nhiều lần ở các vị trí dịch chuyển – khớp với các bit được đặt của thừa số b. Mỗi phép cộng riêng lẻ là mạch cộng tràn sóng có thể đảo ngược; bit mang được truyền vào bit tích tiếp theo mỗi lần. Vì thanh ghi kết quả tăng lên cùng với tích, các thừa số bị giới hạn ở 3 bit (0–7) ở đây – chỉ khi đó thừa số, tích và qubit mang cùng nhau vừa đủ vào 10 qubit của trình mô phỏng này.
Phép chia: quantum.divide()
Phép chia cũng chỉ sử dụng các khối xây dựng có thể đảo ngược: quantum.divide({ a, b }) thực hiện phép chia dài được xây dựng từ các phép trừ dịch chuyển, có thể đảo ngược của số chia từ thanh ghi số dư; kết quả là thương số và số dư (a = quotient · b + remainder). Vì cổ tức, số chia, thương số và phải cùng nằm trong 10 qubit, phép chia là thao tác bị ràng buộc chặt chẽ nhất: bits(a) + bits(b) + bits(a÷b) + 1 ≤ 10 phải thỏa mãn, và số chia b phải ≥ 1 (không được chia cho không). Nếu một đầu vào không phù hợp với ngân sách, trình chỉnh sửa sẽ báo cáo thay vì tính toán.
Ngẫu nhiên thực sự: quantum.random()
Máy tính cổ điển không thể tạo ra tính ngẫu nhiên thực sự – “số ngẫu nhiên” của chúng đến từ các thuật toán xác định (tính ngẫu nhiên giả). Máy tính lượng tử có thể: quantum.random({ bits }) đặt mỗi bit vào trạng thái chồng chập 50/50 bằng cổng Hadamard, và chỉ phép đo mới quyết định – một cách cơ bản không thể đoán trước – giá trị nào sẽ xuất hiện. Trên phần cứng lượng tử thực tế, đây là tính ngẫu nhiên vật lý thực sự; trình mô phỏng này mô phỏng nó bằng tính ngẫu nhiên giả của trình duyệt của bạn.
Trình mô phỏng so với phần cứng lượng tử thực tế
Trình mô phỏng này tính toán trạng thái chính xác bằng cách sử dụng số thực dấu phẩy động cổ điển trong trình duyệt của bạn – điều này chỉ hoạt động vì chỉ xem xét các mạch rất nhỏ với tối đa 10 qubit. Máy tính lượng tử thực tế sử dụng các qubit vật lý, dễ bị lỗi (mất pha, nhiễu) và ưu điểm của chúng chỉ thể hiện với các mạch lớn hơn nhiều mà không thể mô phỏng cổ điển trong thực tế. Công cụ này là một công cụ học tập, không phải là bộ xử lý lượng tử thực tế.