|
75 | 75 | "except ImportError:\n",
|
76 | 76 | " print(\"installing cirq...\")\n",
|
77 | 77 | " !pip install --quiet cirq\n",
|
78 |
| - " print(\"installed cirq.\")" |
| 78 | + " print(\"installed cirq.\")\n", |
| 79 | + " import cirq" |
79 | 80 | ]
|
80 | 81 | },
|
81 | 82 | {
|
|
93 | 94 | "The names *pure state simulator* and *mixed state\n",
|
94 | 95 | "simulators* refer to the fact that these simulations are\n",
|
95 | 96 | "for quantum circuits; including unitary, measurements, and noise\n",
|
96 |
| - "that keeps the evolution in a pure state or a mixed state.\n", |
97 |
| - "In other words, there are some noisy evolutions\n", |
98 |
| - "that are supported by the pure state simulator as long as they\n", |
99 |
| - "preserve the purity of the state.\n", |
| 97 | + "that keeps the evolution in a pure state (i.e. a single quantum state)\n", |
| 98 | + "or a mixed state (a mix of quantum states, each with a classical\n", |
| 99 | + "probability). Noisy evolutions are supported by the pure state\n", |
| 100 | + "simulator, as long as they preserve the purity of the state.\n", |
100 | 101 | "\n",
|
101 | 102 | "Some external high-performance simulators also provide an interface\n",
|
102 | 103 | "to Cirq. These can often provide results faster than Cirq's\n",
|
|
127 | 128 | "name": "stdout",
|
128 | 129 | "output_type": "stream",
|
129 | 130 | "text": [
|
130 |
| - "(0, 0): ───X^0.5───@───X^0.5───M('q0')───\n │\n(1, 0): ───X^0.5───@───X^0.5───M('q1')───\n" |
| 131 | + "(0, 0): ───X^0.5───@───X^0.5───M('q0')───\n", |
| 132 | + " │\n", |
| 133 | + "(1, 0): ───X^0.5───@───X^0.5───M('q1')───\n" |
131 | 134 | ]
|
132 | 135 | }
|
133 | 136 | ],
|
134 | 137 | "source": [
|
135 |
| - "import cirq\n", |
136 |
| - "\n", |
137 | 138 | "q0 = cirq.GridQubit(0, 0)\n",
|
138 | 139 | "q1 = cirq.GridQubit(1, 0)\n",
|
139 | 140 | "\n",
|
|
172 | 173 | "name": "stdout",
|
173 | 174 | "output_type": "stream",
|
174 | 175 | "text": [
|
175 |
| - "q0=0\nq1=1\n" |
| 176 | + "q0=0\n", |
| 177 | + "q1=1\n" |
176 | 178 | ]
|
177 | 179 | }
|
178 | 180 | ],
|
179 | 181 | "source": [
|
180 |
| - "from cirq import Simulator\n", |
181 |
| - "simulator = Simulator()\n", |
| 182 | + "simulator = cirq.Simulator()\n", |
182 | 183 | "result = simulator.run(circuit)\n",
|
183 | 184 | "\n",
|
184 | 185 | "print(result)"
|
|
191 | 192 | },
|
192 | 193 | "source": [
|
193 | 194 | "The method `run()` returns a\n",
|
194 |
| - "[`Result`](https://github.com/quantumlib/Cirq/blob/985b411c42cbd2cd97d21e766d28f1f332cfee8b/cirq/study/result.py#L83).\n", |
| 195 | + "[`Result`](https://github.com/quantumlib/Cirq/blob/dd1b1a4a0e26775bf94eb567591397f1f989ca55/cirq-core/cirq/study/result.py#L85).\n", |
195 | 196 | "As you can see, the object `result` contains the result of any\n",
|
196 | 197 | "measurements for the simulation run.\n",
|
197 | 198 | "\n",
|
198 |
| - "The actual measurement results depend on the seeding from\n", |
199 |
| - "`random` seed generator (`numpy`). You can set this using\n", |
200 |
| - "`numpy.random_seed`.\n", |
| 199 | + "The actual measurement results depend on the `random` seed generator (`numpy`).\n", |
| 200 | + "You can set this seed by passing an integer or `numpy.RandomState` as the\n", |
| 201 | + "`seed` parameter in the `Simulator` constructor.\n", |
201 | 202 | "\n",
|
202 | 203 | "Another run can result in a different set of measurement results:"
|
203 | 204 | ]
|
|
213 | 214 | "name": "stdout",
|
214 | 215 | "output_type": "stream",
|
215 | 216 | "text": [
|
216 |
| - "q0=1\nq1=0\n" |
| 217 | + "q0=1\n", |
| 218 | + "q1=0\n" |
217 | 219 | ]
|
218 | 220 | }
|
219 | 221 | ],
|
|
229 | 231 | "id": "b6847671058f"
|
230 | 232 | },
|
231 | 233 | "source": [
|
232 |
| - "The simulator is designed to mimic what running a program\n", |
233 |
| - "on a quantum computer is actually like. \n", |
| 234 | + "The `run()` methods (`run()` and `run_sweep()`) are designed to mimic what\n", |
| 235 | + "running a program on a quantum computer is actually like. `result` only\n", |
| 236 | + "contains measurement data, and the complete state vector is hidden.\n", |
234 | 237 | "\n",
|
235 | 238 | "### Accessing the state vector\n",
|
236 | 239 | "\n",
|
237 |
| - "In particular, the `run()` methods (`run()` and `run_sweep()`)\n", |
238 |
| - "on the simulator do not give access to the state vector of the\n", |
239 |
| - "quantum computer (since one doesn't have access to this on the\n", |
240 |
| - "actual quantum hardware). Instead, the `simulate()` methods\n", |
| 240 | + "To access the full state vector, the `simulate()` methods\n", |
241 | 241 | "(`simulate()`, `simulate_sweep()`, `simulate_moment_steps()`)\n",
|
242 |
| - "should be used if one wants to debug the circuit and get access\n", |
243 |
| - "to the full state vector:" |
| 242 | + "can be used instead. This behavior is only possible in\n", |
| 243 | + "simulation, but can be useful for debugging a circuit:" |
244 | 244 | ]
|
245 | 245 | },
|
246 | 246 | {
|
|
275 | 275 | "source": [
|
276 | 276 | "`simulate()` returns a `SimulationTrialResult` containing\n",
|
277 | 277 | "the final state, as seen above. The built-in Cirq simulator returns a\n",
|
278 |
| - "[`StateVectorTrialResult`](https://github.com/quantumlib/Cirq/blob/b190b40fe2b8161729c5e02464e49092339c8014/cirq/sim/state_vector_simulator.py#L120)\n", |
| 278 | + "[`StateVectorTrialResult`](https://github.com/quantumlib/Cirq/blob/dd1b1a4a0e26775bf94eb567591397f1f989ca55/cirq-core/cirq/sim/state_vector_simulator.py#L147)\n", |
279 | 279 | ",\n",
|
280 | 280 | "which includes a number of utilities for analyzing the final state\n",
|
281 | 281 | "vector.\n",
|
|
348 | 348 | "The `qubit_order` argument to the simulator's `run()` method\n",
|
349 | 349 | "determines the ordering of some results, such as the\n",
|
350 | 350 | "amplitudes in the final wave function. The `qubit_order` argument is optional: when it is omitted, qubits are ordered\n",
|
351 |
| - "ascending by their name (i.e., what their `__str__` method returns).\n", |
| 351 | + "ascending by their name (i.e., what `str(qubit)` returns).\n", |
352 | 352 | "\n",
|
353 | 353 | "The simplest `qubit_order` value you can provide is a list of\n",
|
354 |
| - "the qubits in the desired ordered. Any qubits from the circuit\n", |
| 354 | + "the qubits in the desired order. Any qubits from the circuit\n", |
355 | 355 | "that are not in the list will be ordered using the\n",
|
356 |
| - "default `__str__` ordering, but come after qubits that are in\n", |
| 356 | + "default `str(qubit)` ordering, but come after qubits that are in\n", |
357 | 357 | "the list. Be aware that all qubits in the list are included in\n",
|
358 | 358 | "the simulation, even if they are not operated on by the circuit.\n",
|
359 | 359 | "\n",
|
|
389 | 389 | "id": "a36137200917"
|
390 | 390 | },
|
391 | 391 | "source": [
|
392 |
| - "More concretely, `k`'th amplitude in the wave function\n", |
| 392 | + "More concretely, the `k`'th amplitude in the wave function\n", |
393 | 393 | "will correspond to the `k`'th case that would be encountered\n",
|
394 | 394 | "when nesting loops over the possible values of each qubit.\n",
|
395 | 395 | "\n",
|
|
409 | 409 | "name": "stdout",
|
410 | 410 | "output_type": "stream",
|
411 | 411 | "text": [
|
412 |
| - "amps[0] is for first=0, second=0\namps[1] is for first=0, second=1\namps[2] is for first=1, second=0\namps[3] is for first=1, second=1\n" |
| 412 | + "amps[0] is for first=0, second=0\n", |
| 413 | + "amps[1] is for first=0, second=1\n", |
| 414 | + "amps[2] is for first=1, second=0\n", |
| 415 | + "amps[3] is for first=1, second=1\n" |
413 | 416 | ]
|
414 | 417 | }
|
415 | 418 | ],
|
|
486 | 489 | "## Stepping through a circuit\n",
|
487 | 490 | "\n",
|
488 | 491 | "When debugging, it is useful to not just see the end\n",
|
489 |
| - "result of a circuit, but to inspect, or even modify, the\n", |
490 |
| - "state of the system at different steps in the circuit. \n", |
| 492 | + "result of a circuit, but to inspect the state of the system\n", |
| 493 | + "at different steps in the circuit. \n", |
491 | 494 | "\n",
|
492 | 495 | "To support this, Cirq provides a method to return an iterator\n",
|
493 | 496 | "over a `Moment` by `Moment` simulation. This method is named `simulate_moment_steps`:"
|
|
504 | 507 | "name": "stdout",
|
505 | 508 | "output_type": "stream",
|
506 | 509 | "text": [
|
507 |
| - "state at step 0: [0. +0.5j 0.5+0.j 0.5+0.j 0. -0.5j]\nstate at step 1: [0. +0.5j 0.5+0.j 0.5+0.j 0. +0.5j]\nstate at step 2: [0.5+0.j 0. +0.5j 0. +0.5j 0.5+0.j ]\nstate at step 3: [1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n" |
| 510 | + "state at step 0: [0. +0.5j 0.5+0.j 0.5+0.j 0. -0.5j]\n", |
| 511 | + "state at step 1: [0. +0.5j 0.5+0.j 0.5+0.j 0. +0.5j]\n", |
| 512 | + "state at step 2: [0.5+0.j 0. +0.5j 0. +0.5j 0.5+0.j ]\n", |
| 513 | + "state at step 3: [1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n" |
508 | 514 | ]
|
509 | 515 | }
|
510 | 516 | ],
|
|
523 | 529 | "source": [
|
524 | 530 | "The object returned by the `moment_steps` iterator is a\n",
|
525 | 531 | "`StepResult`. This object has the state along with any\n",
|
526 |
| - "measurements that occurred **during** that step (so does\n", |
527 |
| - "not include measurement results from previous `Moments`).\n", |
528 |
| - "\n", |
529 |
| - "In addition, the `StepResult` contains `set_state_vector()`,\n", |
530 |
| - "which can be used to set the `state`. One can pass a valid\n", |
531 |
| - "full state to this method by passing a numpy array. Or,\n", |
532 |
| - "alternatively, one can pass an integer, and then the state\n", |
533 |
| - "will be set to lie entirely in the computation basis state\n", |
534 |
| - "for the binary expansion of the passed integer." |
| 532 | + "measurements that occurred before or during that step." |
535 | 533 | ]
|
536 | 534 | },
|
537 | 535 | {
|
|
598 | 596 | "In addition to circuit gates with fixed values, Cirq also\n",
|
599 | 597 | "supports gates which can have `Symbol` value (see\n",
|
600 | 598 | "[Gates](gates.ipynb)). These are values that can be resolved\n",
|
601 |
| - "at *run-time*. \n", |
| 599 | + "at runtime. \n", |
602 | 600 | "\n",
|
603 | 601 | "For simulators, these values are resolved by\n",
|
604 | 602 | "providing a `cirq.ParamResolver`. A `cirq.ParamResolver` provides\n",
|
|
616 | 614 | "name": "stdout",
|
617 | 615 | "output_type": "stream",
|
618 | 616 | "text": [
|
619 |
| - "[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n[ 0.6 +0.6j 0.25-0.25j 0.25-0.25j -0.1 -0.1j ]\n[0. +0.5j 0.5+0.j 0.5+0.j 0. -0.5j]\n[-0.1 +0.1j 0.25+0.25j 0.25+0.25j 0.6 -0.6j ]\n[0.+0.j 0.+0.j 0.+0.j 1.+0.j]\n" |
| 617 | + "[1.+0.j 0.+0.j 0.+0.j 0.+0.j]\n", |
| 618 | + "[ 0.6 +0.6j 0.25-0.25j 0.25-0.25j -0.1 -0.1j ]\n", |
| 619 | + "[0. +0.5j 0.5+0.j 0.5+0.j 0. -0.5j]\n", |
| 620 | + "[-0.1 +0.1j 0.25+0.25j 0.25+0.25j 0.6 -0.6j ]\n", |
| 621 | + "[0.+0.j 0.+0.j 0.+0.j 1.+0.j]\n" |
620 | 622 | ]
|
621 | 623 | }
|
622 | 624 | ],
|
|
637 | 639 | "id": "10617793bfd2"
|
638 | 640 | },
|
639 | 641 | "source": [
|
640 |
| - "Here we see that the `Symbol` is used in two gates, and then the resolver provides this value at run time.\n", |
| 642 | + "Here we see that the `Symbol` is used in two gates, and then the resolver\n", |
| 643 | + "provides this value at run time.\n", |
641 | 644 | "\n",
|
642 | 645 | "Parameterized values are most useful in defining what we call a\n",
|
643 | 646 | "`sweep`. A `sweep` is a sequence of trials, where each\n",
|
644 | 647 | "trial is a run with a particular set of parameter values.\n",
|
645 | 648 | "\n",
|
646 |
| - "Running a `sweep` returns a `Result` for each set of fixed parameter values and repetitions. \n", |
| 649 | + "Running a `sweep` returns a `Result` for each set of fixed parameter\n", |
| 650 | + "values and repetitions. \n", |
647 | 651 | "\n",
|
648 | 652 | "For instance:"
|
649 | 653 | ]
|
|
659 | 663 | "name": "stdout",
|
660 | 664 | "output_type": "stream",
|
661 | 665 | "text": [
|
662 |
| - "q0=00\nq1=00\nq0=10\nq1=10\nq0=11\nq1=11\n" |
| 666 | + "q0=00\n", |
| 667 | + "q1=00\n", |
| 668 | + "q0=10\n", |
| 669 | + "q1=10\n", |
| 670 | + "q0=11\n", |
| 671 | + "q1=11\n" |
663 | 672 | ]
|
664 | 673 | }
|
665 | 674 | ],
|
|
697 | 706 | "In addition to pure state simulation, Cirq also supports\n",
|
698 | 707 | "simulation of mixed states. \n",
|
699 | 708 | "\n",
|
700 |
| - "Even though this simulator is not as efficient as the pure state simulators, they allow for a larger class of noisy circuits to be run as well as keeping track of the simulation's density matrix. This fact can allow for more exact simulations (for example,\n", |
701 |
| - "the pure state simulator's Monte Carlo simulation only\n", |
702 |
| - "allows sampling from the density matrix, not explicitly giving\n", |
703 |
| - "the entries of the density matrix like the mixed state simulator\n", |
704 |
| - "can do). \n", |
| 709 | + "Even though this simulator is not as efficient as the pure state simulators,\n", |
| 710 | + "they allow for a larger class of noisy circuits to be run as well as keeping\n", |
| 711 | + "track of the simulation's density matrix. This fact can allow for more exact\n", |
| 712 | + "simulations: the density matrix can represent all possible results of a\n", |
| 713 | + "noisy circuit, while the pure-state simulator can only sample from these\n", |
| 714 | + "results.\n", |
705 | 715 | "\n",
|
706 | 716 | "Mixed state simulation is supported by the\n",
|
707 | 717 | "`cirq.DensityMatrixSimulator` class.\n",
|
|
770 | 780 | "name": "stdout",
|
771 | 781 | "output_type": "stream",
|
772 | 782 | "text": [
|
773 |
| - "[[0.6 +0.j 0.447+0.j]\n [0.447+0.j 0.4 +0.j]]\n" |
| 783 | + "[[0.6 +0.j 0.447+0.j]\n", |
| 784 | + " [0.447+0.j 0.4 +0.j]]\n" |
774 | 785 | ]
|
775 | 786 | }
|
776 | 787 | ],
|
|
805 | 816 | "These projects are listed below, along with their PyPI package\n",
|
806 | 817 | "name and a description of simulator methods that they support.\n",
|
807 | 818 | "\n",
|
808 |
| - "**Note:** In general, these simulators are optimized for\n", |
809 |
| - "specific use cases. Before choosing a simulator, make sure it\n", |
810 |
| - "supports the behavior that you need!\n", |
| 819 | + "For most users we recommend [qsim](https://github.com/quantumlib/qsim),\n", |
| 820 | + "but each simulator is optimized for specific use cases. Before choosing\n", |
| 821 | + "a simulator, make sure it supports the behavior that you need!\n", |
811 | 822 | "\n",
|
812 | 823 | "| Project name | PyPI package | Description |\n",
|
813 | 824 | "| --- | --- | --- |\n",
|
814 |
| - "| [qsim](https://github.com/quantumlib/qsim) | qsimcirq | Implements `cirq.SimulatesAmplitudes` and `cirq.SimulatesFinalState`. Recommended for deep circuits with up to 30 qubits (consumes 8GB RAM). Larger circuits are possible, but RAM usage doubles with each additional qubit. |\n", |
| 825 | + "| [qsim](https://github.com/quantumlib/qsim) | qsimcirq | Implements `cirq.SimulatesAmplitudes`, `cirq.SimulatesFinalState`, and `cirq.SimulatesExpectationValues`. Recommended for deep circuits with up to 30 qubits (consumes 8GB RAM). Larger circuits are possible, but RAM usage doubles with each additional qubit. |\n", |
815 | 826 | "| [qsimh](https://github.com/quantumlib/qsim/blob/master/qsimcirq/qsimh_simulator.py) | qsimcirq | Implements `cirq.SimulatesAmplitudes`. Intended for heavy parallelization across several computers; Cirq users should generally prefer qsim. |\n",
|
816 |
| - "| [qFlex](https://github.com/ngnrsaa/qflex) | qflexcirq | Implements `cirq.SimulatesAmplitudes`. Recommended for shallow / low-entanglement circuits with more than 30 qubits. RAM usage is highly dependent on the number of two-qubit gates in the circuit. |\n", |
817 |
| - "| [quimb](https://quimb.readthedocs.io/en/latest/) | quimb | Cirq-to-quimb translation layer provided in `contrib/quimb`. In addition to circuit simulation, this allows the use of quimb circuit-analysis tools on Cirq circuits. |\n" |
| 827 | + "| [quimb](https://quimb.readthedocs.io/en/latest/) | quimb | Not based on `cirq.Simulator`; instead uses a Cirq-to-quimb translation layer provided in `contrib/quimb`. In addition to circuit simulation, this allows the use of quimb circuit-analysis tools on Cirq circuits. |\n", |
| 828 | + "| [qFlex](https://github.com/ngnrsaa/qflex) | qflexcirq | Implements `cirq.SimulatesAmplitudes`. RAM usage is highly dependent on the number of two-qubit gates in the circuit. Not recommended - prefer qsim or quimb. |\n" |
818 | 829 | ]
|
819 | 830 | }
|
820 | 831 | ],
|
|
0 commit comments