Skip to content

Configuring a QNN

In qadence, the QNN is a variational quantum model that can potentially take multi-dimensional input.

The QNN class needs a circuit and a list of observables; the number of feature parameters in the input circuit determines the number of input features (i.e. the dimensionality of the classical data given as input) whereas the number of observables determines the number of outputs of the quantum neural network.

The circuit has two parts, the feature map and the ansatz. The feature map is responsible for encoding the input data into the quantum state, while the ansatz is responsible for the variational part of the model. In addition, a third part of the QNN is the observables, which is (a list of) operators that are measured at the end of the circuit.

In QML Constructors we have seen how to construct the feature map and the ansatz. In this tutorial, we will see how to do the same using configs.

One convenient way to construct these three parts of the model is to use the config classes, namely, ObservableConfig, FeatureMapConfig, AnsatzConfig. These classes allow you to specify the type of circuit and the parameters of the circuit in a structured way.

Defining the Observable

The model output is the expectation value of the defined observable(s). We use the ObservableConfig class to specify the observable.

It can be used to create Hamiltonians with 2-qubit interactions and single-qubit detunings. Any Hamiltonian supported by hamiltonian_factory can be specified as an observable. For example, suppose we want to measure the Z operator:

from qadence import create_observable, ObservableConfig, Z

observable_config = ObservableConfig(
    detuning=Z,
    interaction = None,
    scale = 2.0,
    shift=-1.0,
)

observable = create_observable(register=4, config=observable_config)
%3 cluster_26383cb4c7944b74ba19b41944530150 bbe37f84ac87462583aeb43d802756c5 0 e73efe7ec1d54200be4c798ebda534c0 bbe37f84ac87462583aeb43d802756c5--e73efe7ec1d54200be4c798ebda534c0 8b5a9c02b803452bb46900e168c37648 1 34c720389144432e88b9843bda70b8a4 e73efe7ec1d54200be4c798ebda534c0--34c720389144432e88b9843bda70b8a4 135f8a92eb2b47d181b2ee5b965c795e ded5069a2aa94d6ea6354eeeb4ca08ee AddBlock 8b5a9c02b803452bb46900e168c37648--ded5069a2aa94d6ea6354eeeb4ca08ee 1c2e7f870e9c4ce3b3a4a68465994e50 2 ded5069a2aa94d6ea6354eeeb4ca08ee--135f8a92eb2b47d181b2ee5b965c795e b670635644074cb7a57b534f59e8a651 979070bc7bf04b9796bc9a39ab226e41 1c2e7f870e9c4ce3b3a4a68465994e50--979070bc7bf04b9796bc9a39ab226e41 55cab032965a44fc8c8c4ef9f831712e 3 979070bc7bf04b9796bc9a39ab226e41--b670635644074cb7a57b534f59e8a651 889cd1bb7ab8483f9cad5fd3f438c13a 6af7505ac38e430fbd383cf05b16185e 55cab032965a44fc8c8c4ef9f831712e--6af7505ac38e430fbd383cf05b16185e 6af7505ac38e430fbd383cf05b16185e--889cd1bb7ab8483f9cad5fd3f438c13a

We have specified the observable Hamiltonian to be one with \(Z\)-detuning. The result is linearly scaled by 2.0 and shifted by -1.0. The shift or the scale can optionally also be a VariationalParameter

It is also possible to import some common Hamiltonians, such as total_magnetization_config, zz_hamiltonian_config and, ising_hamiltonian_config.

For example, the total magnetization configuration:

from qadence import create_observable
from qadence.constructors import total_magnetization_config

observable_total_magnetization  = create_observable(register=4, config=total_magnetization_config())

Alternatively, you can define the observable as a list of observables, in which case the QNN will output a list of values.

Scaling and Shifting the QNN Output

For any observable, by appropriately choosing the scale \(\alpha\) and shift \(\beta\), you can constrain the QNN output within a desired range. This is particularly useful for normalizing measurements or ensuring that values remain within a meaningful interval for optimization. To accomplish this, you need to determine the maximum and minimum values that the QNN output can take. For an observable, these extreme values are the two extreme eigenvalues \(\lambda_{max}\) and \(\lambda_{min}\) of the concerned Hamiltonian. Using these values, you can set the scale \(\alpha\) and shift \(\beta\) so that the QNN output is mapped to a specific range \([a,b]\):

\[\alpha = \frac{b-a}{\lambda_{max}-\lambda_{min}}\]
\[\beta = \frac{a\lambda_{max}-b\lambda_{min}}{\lambda_{max}-\lambda_{min}}\]

This transformation ensures that:

\[ a \leq \alpha \lambda + \beta \leq b,\quad\forall \lambda \in [\lambda_{min},\lambda_{max}] \]

For full details on the ObservableConfig class, see the API documentation.

Defining the Feature Map

Let us say we want to build a 4-qubit QNN that takes two inputs, namely, the \(x\) and the \(y\) coordinates of a point in the plane. We can use the FeatureMapConfig class to specify the feature map.

from qadence import BasisSet, chain, create_fm_blocks, FeatureMapConfig, ReuploadScaling

fm_config = FeatureMapConfig(
    num_features=2,
    inputs = ["x", "y"],
    basis_set=BasisSet.CHEBYSHEV,
    reupload_scaling=ReuploadScaling.TOWER,
    feature_range={
        "x": (-1.0, 1.0),
        "y": (0.0, 1.0),
    },
)

fm_blocks = create_fm_blocks(register=4, config=fm_config)
feature_map = chain(*fm_blocks)
%3 cluster_698e94597e654781a89b6030a54dcbc3 Tower Chebyshev FM cluster_7d948e03f41f48bdb96353419e63aa33 Tower Chebyshev FM 306e9d0d7e894f3a9c2b0f00e9dedde0 0 3a3b9e364cbb44c59eb93358c7b69460 RX(1.0*acos(x)) 306e9d0d7e894f3a9c2b0f00e9dedde0--3a3b9e364cbb44c59eb93358c7b69460 33c0218e7a8a4ff9b0efbfdc5472e7d3 1 757909a2069d451fa03ab653b470ba8d 3a3b9e364cbb44c59eb93358c7b69460--757909a2069d451fa03ab653b470ba8d 7fac6d74990b46e38d464f3b44bcf788 cb3ab84db1f24e9e85e474b06ee5bb28 RX(2.0*acos(x)) 33c0218e7a8a4ff9b0efbfdc5472e7d3--cb3ab84db1f24e9e85e474b06ee5bb28 4a78ec68d13147b0bc5ad5112a05cd9c 2 cb3ab84db1f24e9e85e474b06ee5bb28--7fac6d74990b46e38d464f3b44bcf788 d9140493bec9438fa0d3f8dbb615acbe c8ba775c051c4e0fb0bd01d66f04571d RX(1.0*acos(2.0*y - 1.0)) 4a78ec68d13147b0bc5ad5112a05cd9c--c8ba775c051c4e0fb0bd01d66f04571d c8de6edda43447aca3c50174d3699310 3 c8ba775c051c4e0fb0bd01d66f04571d--d9140493bec9438fa0d3f8dbb615acbe dd69c2725c1c418697865c6e6ca3ee84 4c21bcee24f64b1ea50e315661f62602 RX(2.0*acos(2.0*y - 1.0)) c8de6edda43447aca3c50174d3699310--4c21bcee24f64b1ea50e315661f62602 4c21bcee24f64b1ea50e315661f62602--dd69c2725c1c418697865c6e6ca3ee84

We have specified that the feature map should take two features, and have named the FeatureParameter "x" and "y" respectively. Both these parameters are encoded using the Chebyshev basis set, and the reupload scaling is set to ReuploadScaling.TOWER. One can optionally add the basis and the reupload scaling for each parameter separately.

The feature_range parameter is a dictionary that specifies the range of values that each feature comes from. This is useful for scaling the input data to the range that the encoding function can handle. In default case, this range is mapped to the target range of the Chebyshev basis set which is \([-1, 1]\). One can also specify the target range for each feature separately.

For full details on the FeatureMapConfig class, see the API documentation.

Defining the Ansatz

The next part of the QNN is the ansatz. We use AnsatzConfig class to specify the type of ansatz.

Let us say, we want to follow this feature map with 2 layers of hardware efficient ansatz.

from qadence import AnsatzConfig, AnsatzType, create_ansatz, Strategy

ansatz_config = AnsatzConfig(
    depth=2,
    ansatz_type=AnsatzType.HEA,
    ansatz_strategy=Strategy.DIGITAL,
)

ansatz = create_ansatz(register=4, config=ansatz_config)
%3 132bfe3a9d6649ab9ffef91b8b52d0f5 0 70b5f0b5f6c94d2eb352eb6a2d1501c7 RX(theta₀) 132bfe3a9d6649ab9ffef91b8b52d0f5--70b5f0b5f6c94d2eb352eb6a2d1501c7 b393696443b845b48b4cc4760a49485e 1 619ba3ff414d427b83ca3a44736dcefe RY(theta₄) 70b5f0b5f6c94d2eb352eb6a2d1501c7--619ba3ff414d427b83ca3a44736dcefe 625fab3adc1c45b1af85d19f16e99845 RX(theta₈) 619ba3ff414d427b83ca3a44736dcefe--625fab3adc1c45b1af85d19f16e99845 74669c1c54e14a7bab8f92695ae2a4da 625fab3adc1c45b1af85d19f16e99845--74669c1c54e14a7bab8f92695ae2a4da a0b0ffb4f0f340aba9ff49f167f764ad 74669c1c54e14a7bab8f92695ae2a4da--a0b0ffb4f0f340aba9ff49f167f764ad 59e60f267c964f849c7e3fd1a682eea3 RX(theta₁₂) a0b0ffb4f0f340aba9ff49f167f764ad--59e60f267c964f849c7e3fd1a682eea3 8e6ee9f66e0e457fa8c447bcd8fc649c RY(theta₁₆) 59e60f267c964f849c7e3fd1a682eea3--8e6ee9f66e0e457fa8c447bcd8fc649c 967d4b9fff4d4a859b014601f7fd505b RX(theta₂₀) 8e6ee9f66e0e457fa8c447bcd8fc649c--967d4b9fff4d4a859b014601f7fd505b d0919de523d34b33b1fa47f8df073e7e 967d4b9fff4d4a859b014601f7fd505b--d0919de523d34b33b1fa47f8df073e7e 60b779e6ae4241ca90d7cc9faf0f8d1d d0919de523d34b33b1fa47f8df073e7e--60b779e6ae4241ca90d7cc9faf0f8d1d f82c1460689147549e8ec29f832d3710 60b779e6ae4241ca90d7cc9faf0f8d1d--f82c1460689147549e8ec29f832d3710 e4a12802e48f4a6a8ef412981d82f0a3 0f8249b01f334b18813261a7f082d186 RX(theta₁) b393696443b845b48b4cc4760a49485e--0f8249b01f334b18813261a7f082d186 60c22ffb143f43079220c0a08e336d87 2 d207940765c8456ab904e53afb13dbbf RY(theta₅) 0f8249b01f334b18813261a7f082d186--d207940765c8456ab904e53afb13dbbf 3fa48c1666574f01876dbbacde338d10 RX(theta₉) d207940765c8456ab904e53afb13dbbf--3fa48c1666574f01876dbbacde338d10 161fbe5e995945f58dadbfda25d3def8 X 3fa48c1666574f01876dbbacde338d10--161fbe5e995945f58dadbfda25d3def8 161fbe5e995945f58dadbfda25d3def8--74669c1c54e14a7bab8f92695ae2a4da 504a84f035d4493ebe36e5aed7c9e7df 161fbe5e995945f58dadbfda25d3def8--504a84f035d4493ebe36e5aed7c9e7df a77d8fb7ed6644efb8ad4047a16b610f RX(theta₁₃) 504a84f035d4493ebe36e5aed7c9e7df--a77d8fb7ed6644efb8ad4047a16b610f 33742a1e36694e21a6e605efbef3b5d2 RY(theta₁₇) a77d8fb7ed6644efb8ad4047a16b610f--33742a1e36694e21a6e605efbef3b5d2 ff4a6517b53b427892fb3fa68d6c1469 RX(theta₂₁) 33742a1e36694e21a6e605efbef3b5d2--ff4a6517b53b427892fb3fa68d6c1469 44e295bbc8274300a8a80f263efc1528 X ff4a6517b53b427892fb3fa68d6c1469--44e295bbc8274300a8a80f263efc1528 44e295bbc8274300a8a80f263efc1528--d0919de523d34b33b1fa47f8df073e7e a0e2c0516db04948a0ba8bf33235da0e 44e295bbc8274300a8a80f263efc1528--a0e2c0516db04948a0ba8bf33235da0e a0e2c0516db04948a0ba8bf33235da0e--e4a12802e48f4a6a8ef412981d82f0a3 e8593ee0f6d04afd9e42456ad6cbf692 44bff90b00a04ab09c8cd784af46800e RX(theta₂) 60c22ffb143f43079220c0a08e336d87--44bff90b00a04ab09c8cd784af46800e 2353992cf0b643ba8283cd0f348ab188 3 b1219147395641e4a57559a4db027b89 RY(theta₆) 44bff90b00a04ab09c8cd784af46800e--b1219147395641e4a57559a4db027b89 ab3efb6b2a9644cf896b3d427cc99d27 RX(theta₁₀) b1219147395641e4a57559a4db027b89--ab3efb6b2a9644cf896b3d427cc99d27 a456f62482434e79bd7e39192c65c4f0 ab3efb6b2a9644cf896b3d427cc99d27--a456f62482434e79bd7e39192c65c4f0 1f9d8fc0055f4a19a4c6d40811afc468 X a456f62482434e79bd7e39192c65c4f0--1f9d8fc0055f4a19a4c6d40811afc468 1f9d8fc0055f4a19a4c6d40811afc468--504a84f035d4493ebe36e5aed7c9e7df 9f55eca9a2e342beba393fa3b05e9b21 RX(theta₁₄) 1f9d8fc0055f4a19a4c6d40811afc468--9f55eca9a2e342beba393fa3b05e9b21 5d0982a111c742b9adb8d2ab00c06a93 RY(theta₁₈) 9f55eca9a2e342beba393fa3b05e9b21--5d0982a111c742b9adb8d2ab00c06a93 311b64a6bb9f4deca47255346872d1b8 RX(theta₂₂) 5d0982a111c742b9adb8d2ab00c06a93--311b64a6bb9f4deca47255346872d1b8 336c95734fb340eaaa0b5860113a4cfb 311b64a6bb9f4deca47255346872d1b8--336c95734fb340eaaa0b5860113a4cfb 99e23f93704c42ee9d8f9b104c7e77d3 X 336c95734fb340eaaa0b5860113a4cfb--99e23f93704c42ee9d8f9b104c7e77d3 99e23f93704c42ee9d8f9b104c7e77d3--a0e2c0516db04948a0ba8bf33235da0e 99e23f93704c42ee9d8f9b104c7e77d3--e8593ee0f6d04afd9e42456ad6cbf692 e6760c6836864f24bdb95dadaba1961b 8880d9e984774ae9b5307e5a7e99947a RX(theta₃) 2353992cf0b643ba8283cd0f348ab188--8880d9e984774ae9b5307e5a7e99947a 99f871fc4fde444fb14fe2dc65eeb7b3 RY(theta₇) 8880d9e984774ae9b5307e5a7e99947a--99f871fc4fde444fb14fe2dc65eeb7b3 f020e3cc56bd4883be4d24ea3f2b7198 RX(theta₁₁) 99f871fc4fde444fb14fe2dc65eeb7b3--f020e3cc56bd4883be4d24ea3f2b7198 1c4b8290ccea40169cfdf6635dc5437d X f020e3cc56bd4883be4d24ea3f2b7198--1c4b8290ccea40169cfdf6635dc5437d 1c4b8290ccea40169cfdf6635dc5437d--a456f62482434e79bd7e39192c65c4f0 8ef504e6a1df4197ac445d9e7b6021dd 1c4b8290ccea40169cfdf6635dc5437d--8ef504e6a1df4197ac445d9e7b6021dd 219ea11e88854f029af41236f229b391 RX(theta₁₅) 8ef504e6a1df4197ac445d9e7b6021dd--219ea11e88854f029af41236f229b391 9df01775d57a4fec82217dc2b4347a57 RY(theta₁₉) 219ea11e88854f029af41236f229b391--9df01775d57a4fec82217dc2b4347a57 67cae51b5bec4c558875e8141adc582e RX(theta₂₃) 9df01775d57a4fec82217dc2b4347a57--67cae51b5bec4c558875e8141adc582e b9834dd515b8414aa64fd587510b0e8f X 67cae51b5bec4c558875e8141adc582e--b9834dd515b8414aa64fd587510b0e8f b9834dd515b8414aa64fd587510b0e8f--336c95734fb340eaaa0b5860113a4cfb d8481c64041f418b9c972af9280013c3 b9834dd515b8414aa64fd587510b0e8f--d8481c64041f418b9c972af9280013c3 d8481c64041f418b9c972af9280013c3--e6760c6836864f24bdb95dadaba1961b

We have specified that the ansatz should have a depth of 2, and the ansatz type is "hea" (Hardware Efficient Ansatz). The ansatz strategy is set to "digital", which means digital gates are being used. One could alternatively use "analog" or "rydberg" as the ansatz strategy.

For full details on the AnsatzConfig class, see the API documentation.

Defining the QNN from the Configs

To build the QNN, we can now use the QNN class as a QuantumModel subtype. In addition to the feature map, ansatz and the observable configs, we can also specify options such as the backend, diff_mode, etc. For full details on the QNN class, see the API documentation or the documentation on the config constructor here.

from qadence import BackendName, DiffMode, QNN

qnn = QNN.from_configs(
    register=4,
    obs_config=observable_config,
    fm_config=fm_config,
    ansatz_config=ansatz_config,
    backend=BackendName.PYQTORCH,
    diff_mode=DiffMode.AD,
)
%3 cluster_9b16ef563a7d437f9c9de876094131f5 Obs. cluster_20285765561947fc920bdc13c0f3aed4 cluster_6a4aa5b13550428c8a221c2a3dcc2672 Tower Chebyshev FM cluster_066f40ab22f5405fbab170571c030fc8 Tower Chebyshev FM cluster_2ed6aa0f33dd4aa69616fa3acde58099 HEA 68cdfd1d0b99421c9f50cc62408f62a7 0 d7535e4b034b4b8c9c4120b60ac20a50 RX(1.0*acos(x)) 68cdfd1d0b99421c9f50cc62408f62a7--d7535e4b034b4b8c9c4120b60ac20a50 1e60991eca9948f0b52fab0c3d73486a 1 1823de43a3524be68dd7f919de34b120 RX(theta₀) d7535e4b034b4b8c9c4120b60ac20a50--1823de43a3524be68dd7f919de34b120 292cb10ae8934c1cbb4e5ec7b77ae49e RY(theta₄) 1823de43a3524be68dd7f919de34b120--292cb10ae8934c1cbb4e5ec7b77ae49e 45e7ab39cb124c509572e22df47d4b9f RX(theta₈) 292cb10ae8934c1cbb4e5ec7b77ae49e--45e7ab39cb124c509572e22df47d4b9f dbb974788d1c4a81bed3603cf0474f4e 45e7ab39cb124c509572e22df47d4b9f--dbb974788d1c4a81bed3603cf0474f4e c79a53437fcf44259fa9af5335e2f97c dbb974788d1c4a81bed3603cf0474f4e--c79a53437fcf44259fa9af5335e2f97c 1e5cade1da204e80bca5e79cb39c8698 RX(theta₁₂) c79a53437fcf44259fa9af5335e2f97c--1e5cade1da204e80bca5e79cb39c8698 c612fc7aca574ab5afc21702d12d356a RY(theta₁₆) 1e5cade1da204e80bca5e79cb39c8698--c612fc7aca574ab5afc21702d12d356a 5cf605a3208f4d3c8cb74c36158077eb RX(theta₂₀) c612fc7aca574ab5afc21702d12d356a--5cf605a3208f4d3c8cb74c36158077eb 1ef83be2e09a43c78f867854b67b6c38 5cf605a3208f4d3c8cb74c36158077eb--1ef83be2e09a43c78f867854b67b6c38 69e900c1eb7e4f21aea0770665220093 1ef83be2e09a43c78f867854b67b6c38--69e900c1eb7e4f21aea0770665220093 7e362d97a8984c04bb65ab3138e0c772 69e900c1eb7e4f21aea0770665220093--7e362d97a8984c04bb65ab3138e0c772 211c0defc7fa4a9d9b15be2039331e93 7e362d97a8984c04bb65ab3138e0c772--211c0defc7fa4a9d9b15be2039331e93 7cc92596c2554f528100dd76a4d100d3 fc3bc6c4dc054e2183bb22390263680e RX(2.0*acos(x)) 1e60991eca9948f0b52fab0c3d73486a--fc3bc6c4dc054e2183bb22390263680e 469dd72abf0d4359b61b07d4c21f34f8 2 8d60570ab7534991a8cba44987632d7d RX(theta₁) fc3bc6c4dc054e2183bb22390263680e--8d60570ab7534991a8cba44987632d7d 0d52b0cdfa7f4c129e4f20d6ce249bf8 RY(theta₅) 8d60570ab7534991a8cba44987632d7d--0d52b0cdfa7f4c129e4f20d6ce249bf8 885670a60c484541aa6ea09ee11e1825 RX(theta₉) 0d52b0cdfa7f4c129e4f20d6ce249bf8--885670a60c484541aa6ea09ee11e1825 7a10029b006c4d1aa24ddb6c87ff9124 X 885670a60c484541aa6ea09ee11e1825--7a10029b006c4d1aa24ddb6c87ff9124 7a10029b006c4d1aa24ddb6c87ff9124--dbb974788d1c4a81bed3603cf0474f4e 2b112b6f402848b0b15a46f88f831050 7a10029b006c4d1aa24ddb6c87ff9124--2b112b6f402848b0b15a46f88f831050 06e0e78c20c84450a09a5ba5812432f1 RX(theta₁₃) 2b112b6f402848b0b15a46f88f831050--06e0e78c20c84450a09a5ba5812432f1 0452609f94774577843f6dfbe6f36bde RY(theta₁₇) 06e0e78c20c84450a09a5ba5812432f1--0452609f94774577843f6dfbe6f36bde 82637cd1d43e4197b9b52b2bd5e4e011 RX(theta₂₁) 0452609f94774577843f6dfbe6f36bde--82637cd1d43e4197b9b52b2bd5e4e011 022bc1ad9fdd4ddfb3a81965befe3ca3 X 82637cd1d43e4197b9b52b2bd5e4e011--022bc1ad9fdd4ddfb3a81965befe3ca3 022bc1ad9fdd4ddfb3a81965befe3ca3--1ef83be2e09a43c78f867854b67b6c38 baa215ba1ad5401b861d78171b6f88ec 022bc1ad9fdd4ddfb3a81965befe3ca3--baa215ba1ad5401b861d78171b6f88ec d105c1bf3c6543d99b607cad3efa9bb4 AddBlock baa215ba1ad5401b861d78171b6f88ec--d105c1bf3c6543d99b607cad3efa9bb4 d105c1bf3c6543d99b607cad3efa9bb4--7cc92596c2554f528100dd76a4d100d3 25af084d2c4c486297a8c04f18a432a0 9d47abd303124806ba5074f478715be4 RX(1.0*acos(2.0*y - 1.0)) 469dd72abf0d4359b61b07d4c21f34f8--9d47abd303124806ba5074f478715be4 c228394540db472c9b968931538f54f7 3 2e6a5dd925454f0dbb5b1de222a8b77b RX(theta₂) 9d47abd303124806ba5074f478715be4--2e6a5dd925454f0dbb5b1de222a8b77b 0e9f589aad7b476fa1f42aba44974e20 RY(theta₆) 2e6a5dd925454f0dbb5b1de222a8b77b--0e9f589aad7b476fa1f42aba44974e20 9856f154f85543f58e743317ef24b40d RX(theta₁₀) 0e9f589aad7b476fa1f42aba44974e20--9856f154f85543f58e743317ef24b40d bb82eb022efb4f87a6bbc14b2dba75f8 9856f154f85543f58e743317ef24b40d--bb82eb022efb4f87a6bbc14b2dba75f8 1b1c84d51bc740e0b8ee8c730109c07f X bb82eb022efb4f87a6bbc14b2dba75f8--1b1c84d51bc740e0b8ee8c730109c07f 1b1c84d51bc740e0b8ee8c730109c07f--2b112b6f402848b0b15a46f88f831050 3ef3b98ac42243658a401ddec257e173 RX(theta₁₄) 1b1c84d51bc740e0b8ee8c730109c07f--3ef3b98ac42243658a401ddec257e173 730d47fd3b594fb8824718917b5a60b9 RY(theta₁₈) 3ef3b98ac42243658a401ddec257e173--730d47fd3b594fb8824718917b5a60b9 e9988ae35102420494f5360148a395d8 RX(theta₂₂) 730d47fd3b594fb8824718917b5a60b9--e9988ae35102420494f5360148a395d8 2bc7c4617dc34d509574f218cf8860f1 e9988ae35102420494f5360148a395d8--2bc7c4617dc34d509574f218cf8860f1 28fa29d821f14cc1a1a876253d3602b0 X 2bc7c4617dc34d509574f218cf8860f1--28fa29d821f14cc1a1a876253d3602b0 28fa29d821f14cc1a1a876253d3602b0--baa215ba1ad5401b861d78171b6f88ec 2dd12ff124324f9b9e406ac2e21d5408 28fa29d821f14cc1a1a876253d3602b0--2dd12ff124324f9b9e406ac2e21d5408 2dd12ff124324f9b9e406ac2e21d5408--25af084d2c4c486297a8c04f18a432a0 16ee5b0b26cd48d1beae869e77ac6783 0e3299e15db1482790d8cbf395162198 RX(2.0*acos(2.0*y - 1.0)) c228394540db472c9b968931538f54f7--0e3299e15db1482790d8cbf395162198 2ecd44eba0524ad8bb77bdc110e9b35c RX(theta₃) 0e3299e15db1482790d8cbf395162198--2ecd44eba0524ad8bb77bdc110e9b35c 67543411d83a4b1fbc45e806b0469a4e RY(theta₇) 2ecd44eba0524ad8bb77bdc110e9b35c--67543411d83a4b1fbc45e806b0469a4e 1da322d51edb4ae3a2d60f29c6da165a RX(theta₁₁) 67543411d83a4b1fbc45e806b0469a4e--1da322d51edb4ae3a2d60f29c6da165a 5cfdb78352414feaa70309da457d58d6 X 1da322d51edb4ae3a2d60f29c6da165a--5cfdb78352414feaa70309da457d58d6 5cfdb78352414feaa70309da457d58d6--bb82eb022efb4f87a6bbc14b2dba75f8 fa7f9a3f82dd4e18b13e315c8b63a8a8 5cfdb78352414feaa70309da457d58d6--fa7f9a3f82dd4e18b13e315c8b63a8a8 c986cafe310841449df2554f6917c3ec RX(theta₁₅) fa7f9a3f82dd4e18b13e315c8b63a8a8--c986cafe310841449df2554f6917c3ec b8c940464813430eb4ee383a2ee9ed9f RY(theta₁₉) c986cafe310841449df2554f6917c3ec--b8c940464813430eb4ee383a2ee9ed9f 6a76692778f945b798ce133ad9ef536c RX(theta₂₃) b8c940464813430eb4ee383a2ee9ed9f--6a76692778f945b798ce133ad9ef536c c1b31ffe97424351803ffc2e6d534ee7 X 6a76692778f945b798ce133ad9ef536c--c1b31ffe97424351803ffc2e6d534ee7 c1b31ffe97424351803ffc2e6d534ee7--2bc7c4617dc34d509574f218cf8860f1 61917834503c4dfc8941bf37eb5e5ee9 c1b31ffe97424351803ffc2e6d534ee7--61917834503c4dfc8941bf37eb5e5ee9 0037c5b9a9b1408c8eaf9ecf07966fba 61917834503c4dfc8941bf37eb5e5ee9--0037c5b9a9b1408c8eaf9ecf07966fba 0037c5b9a9b1408c8eaf9ecf07966fba--16ee5b0b26cd48d1beae869e77ac6783