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_75613d6b8c784b5887b5fe8aa982c54e 8a5c45d543c946a892d07087fdfcdf7f 0 64b0ab1cd4ae4f9bbd78fb907e49b081 8a5c45d543c946a892d07087fdfcdf7f--64b0ab1cd4ae4f9bbd78fb907e49b081 388fc2022ff94a8cbc021cc88e054682 1 0c0f6d039b884fd3b8d945f6aa7ec199 64b0ab1cd4ae4f9bbd78fb907e49b081--0c0f6d039b884fd3b8d945f6aa7ec199 4cda91b4bee8430fa668cd8f7f830ae8 c70ef2fcdda54d8fbfb0b6c6cf0e30ef AddBlock 388fc2022ff94a8cbc021cc88e054682--c70ef2fcdda54d8fbfb0b6c6cf0e30ef dc7fe050f8d1486885c3cd1ffcf5f506 2 c70ef2fcdda54d8fbfb0b6c6cf0e30ef--4cda91b4bee8430fa668cd8f7f830ae8 d1b5dbfca7c44ca18ffc77776bb639ff d327a9a66dba4f66a659e878af9633ee dc7fe050f8d1486885c3cd1ffcf5f506--d327a9a66dba4f66a659e878af9633ee 68765071771b4be6b05b99c408b96b58 3 d327a9a66dba4f66a659e878af9633ee--d1b5dbfca7c44ca18ffc77776bb639ff 64abdb0197b64b8783cd8acabbee9d02 1818e99ea16b4858977b9876acd901b6 68765071771b4be6b05b99c408b96b58--1818e99ea16b4858977b9876acd901b6 1818e99ea16b4858977b9876acd901b6--64abdb0197b64b8783cd8acabbee9d02

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_c16516c6aa6640dca07d569589fd2353 Tower Chebyshev FM cluster_fe2139e440b74c95a7f938a52587760a Tower Chebyshev FM 253a6c2be9f844b5a49a2912c2743468 0 f90a35b672da4adeb83918f80518d977 RX(1.0*acos(x)) 253a6c2be9f844b5a49a2912c2743468--f90a35b672da4adeb83918f80518d977 21ae3911eac044009fbf17de0634940e 1 ffe9363056184ad48fed62c2e95a79fd f90a35b672da4adeb83918f80518d977--ffe9363056184ad48fed62c2e95a79fd cf59f8e7861b4280ba40047982c0e11f 309f11ce36c8484b9aa28928516d619a RX(2.0*acos(x)) 21ae3911eac044009fbf17de0634940e--309f11ce36c8484b9aa28928516d619a e2e60759fd68477c99e30bbd86ea43f9 2 309f11ce36c8484b9aa28928516d619a--cf59f8e7861b4280ba40047982c0e11f abaf17e417994facbc3993f48ffd8655 aca4cd0e4f7a46a9b46586e273dc89a9 RX(1.0*acos(2.0*y - 1.0)) e2e60759fd68477c99e30bbd86ea43f9--aca4cd0e4f7a46a9b46586e273dc89a9 53b0c091dca241f884bf8aed689718ee 3 aca4cd0e4f7a46a9b46586e273dc89a9--abaf17e417994facbc3993f48ffd8655 ae0d27f6b67e49ceab55b683ad69a8f2 26a00267e12546ac83f511fb8bfa3713 RX(2.0*acos(2.0*y - 1.0)) 53b0c091dca241f884bf8aed689718ee--26a00267e12546ac83f511fb8bfa3713 26a00267e12546ac83f511fb8bfa3713--ae0d27f6b67e49ceab55b683ad69a8f2

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 67df882f69114d5bbad4628ff977bc66 0 96060f7a2b364d81a30d59180d4c4ea2 RX(theta₀) 67df882f69114d5bbad4628ff977bc66--96060f7a2b364d81a30d59180d4c4ea2 bf389ab187114982ab44762543461dc0 1 aab88239194444838ee07e09b60038b6 RY(theta₄) 96060f7a2b364d81a30d59180d4c4ea2--aab88239194444838ee07e09b60038b6 45613c69bcbe4e979d6a022f352e7e10 RX(theta₈) aab88239194444838ee07e09b60038b6--45613c69bcbe4e979d6a022f352e7e10 da607740e0ce45faaf38109b38c13d67 45613c69bcbe4e979d6a022f352e7e10--da607740e0ce45faaf38109b38c13d67 cfbd3e831a314960b01c53dfdb25ac07 da607740e0ce45faaf38109b38c13d67--cfbd3e831a314960b01c53dfdb25ac07 2a4cf5e400464cf08052be815b336d78 RX(theta₁₂) cfbd3e831a314960b01c53dfdb25ac07--2a4cf5e400464cf08052be815b336d78 cf149e0c9b254498a7ff9e02660429ee RY(theta₁₆) 2a4cf5e400464cf08052be815b336d78--cf149e0c9b254498a7ff9e02660429ee 1b632862dfcb461a9f129b198f6c8dd9 RX(theta₂₀) cf149e0c9b254498a7ff9e02660429ee--1b632862dfcb461a9f129b198f6c8dd9 60424827f71d49f3b926b78d020362fe 1b632862dfcb461a9f129b198f6c8dd9--60424827f71d49f3b926b78d020362fe 8cdf58446a694600b6d1bef7335a9c82 60424827f71d49f3b926b78d020362fe--8cdf58446a694600b6d1bef7335a9c82 1994fe7968354abe9b0b52bf2798dd8e 8cdf58446a694600b6d1bef7335a9c82--1994fe7968354abe9b0b52bf2798dd8e 9c88ee8c5e9a4d379fa1627e8ba9129a 49ebacee3ee249eab6a66efbcf7a43d4 RX(theta₁) bf389ab187114982ab44762543461dc0--49ebacee3ee249eab6a66efbcf7a43d4 e644a399404945c48c849f39ea5c3d79 2 ce53688b9ac944498e2aaabc0f0f2326 RY(theta₅) 49ebacee3ee249eab6a66efbcf7a43d4--ce53688b9ac944498e2aaabc0f0f2326 b5c0268f77464ed7a2ed4db694ffcc6e RX(theta₉) ce53688b9ac944498e2aaabc0f0f2326--b5c0268f77464ed7a2ed4db694ffcc6e e1db86e56698494b93c8a99f64f4e126 X b5c0268f77464ed7a2ed4db694ffcc6e--e1db86e56698494b93c8a99f64f4e126 e1db86e56698494b93c8a99f64f4e126--da607740e0ce45faaf38109b38c13d67 cfff58480e83446abe0fa3e782a8a52c e1db86e56698494b93c8a99f64f4e126--cfff58480e83446abe0fa3e782a8a52c 35756c8bb25446efa925dc113f5acae1 RX(theta₁₃) cfff58480e83446abe0fa3e782a8a52c--35756c8bb25446efa925dc113f5acae1 4b23bda3af744d10ae869559af7c3208 RY(theta₁₇) 35756c8bb25446efa925dc113f5acae1--4b23bda3af744d10ae869559af7c3208 aed838be231c4e93abe33388d519cb6f RX(theta₂₁) 4b23bda3af744d10ae869559af7c3208--aed838be231c4e93abe33388d519cb6f 3b00310f25f84321a45b66e26533f153 X aed838be231c4e93abe33388d519cb6f--3b00310f25f84321a45b66e26533f153 3b00310f25f84321a45b66e26533f153--60424827f71d49f3b926b78d020362fe bbb5a09bffda44909adee3ee93b739e0 3b00310f25f84321a45b66e26533f153--bbb5a09bffda44909adee3ee93b739e0 bbb5a09bffda44909adee3ee93b739e0--9c88ee8c5e9a4d379fa1627e8ba9129a cbd69aa7a49f4efe94a17e1147a891eb 4a29eb7e7ccb441d95468f6c023647c8 RX(theta₂) e644a399404945c48c849f39ea5c3d79--4a29eb7e7ccb441d95468f6c023647c8 2b74251281c042578e6be7614af59cc6 3 d009898ce3324ab7b8b20009796612a9 RY(theta₆) 4a29eb7e7ccb441d95468f6c023647c8--d009898ce3324ab7b8b20009796612a9 65d98ce88b7a4c1bb0df13706a45328f RX(theta₁₀) d009898ce3324ab7b8b20009796612a9--65d98ce88b7a4c1bb0df13706a45328f 04d8a830b5db402a95f3a9f9dd23af7d 65d98ce88b7a4c1bb0df13706a45328f--04d8a830b5db402a95f3a9f9dd23af7d 4c2d377b276444949bafe306e0a38193 X 04d8a830b5db402a95f3a9f9dd23af7d--4c2d377b276444949bafe306e0a38193 4c2d377b276444949bafe306e0a38193--cfff58480e83446abe0fa3e782a8a52c 09c1490cf1224d73b36a1aad6030d467 RX(theta₁₄) 4c2d377b276444949bafe306e0a38193--09c1490cf1224d73b36a1aad6030d467 2a2b2f3af3064e79b98aba31aaf06c75 RY(theta₁₈) 09c1490cf1224d73b36a1aad6030d467--2a2b2f3af3064e79b98aba31aaf06c75 a12341301caa46faaf483d824fbace9b RX(theta₂₂) 2a2b2f3af3064e79b98aba31aaf06c75--a12341301caa46faaf483d824fbace9b 032ef2445d12419bb31fd6f5fe3b0d80 a12341301caa46faaf483d824fbace9b--032ef2445d12419bb31fd6f5fe3b0d80 8f391e543d824f9b8289f06105f53eb1 X 032ef2445d12419bb31fd6f5fe3b0d80--8f391e543d824f9b8289f06105f53eb1 8f391e543d824f9b8289f06105f53eb1--bbb5a09bffda44909adee3ee93b739e0 8f391e543d824f9b8289f06105f53eb1--cbd69aa7a49f4efe94a17e1147a891eb 3d85f34477e1493492070391437ab38b 7d4cc9bdec11474798cff7d340642ad9 RX(theta₃) 2b74251281c042578e6be7614af59cc6--7d4cc9bdec11474798cff7d340642ad9 e7a15ccf444749f781605829b3c73223 RY(theta₇) 7d4cc9bdec11474798cff7d340642ad9--e7a15ccf444749f781605829b3c73223 325102cdb52b4e97b9784ecec0c7ed4f RX(theta₁₁) e7a15ccf444749f781605829b3c73223--325102cdb52b4e97b9784ecec0c7ed4f 70515e0310534be6a5a5d9d4c21bde00 X 325102cdb52b4e97b9784ecec0c7ed4f--70515e0310534be6a5a5d9d4c21bde00 70515e0310534be6a5a5d9d4c21bde00--04d8a830b5db402a95f3a9f9dd23af7d 36fd328cc23943deb05ea5edb3405b2d 70515e0310534be6a5a5d9d4c21bde00--36fd328cc23943deb05ea5edb3405b2d ea854b2335ce47c49c34321a6a854fbb RX(theta₁₅) 36fd328cc23943deb05ea5edb3405b2d--ea854b2335ce47c49c34321a6a854fbb 8a7cecab3fa8489aa95a7a5d57637333 RY(theta₁₉) ea854b2335ce47c49c34321a6a854fbb--8a7cecab3fa8489aa95a7a5d57637333 cb0686b332554e0da93ecde55746b66e RX(theta₂₃) 8a7cecab3fa8489aa95a7a5d57637333--cb0686b332554e0da93ecde55746b66e 15c3d06fd41143a2978b712ab27b494b X cb0686b332554e0da93ecde55746b66e--15c3d06fd41143a2978b712ab27b494b 15c3d06fd41143a2978b712ab27b494b--032ef2445d12419bb31fd6f5fe3b0d80 9ca048c54d9848cca2f5ebbadecc7a0b 15c3d06fd41143a2978b712ab27b494b--9ca048c54d9848cca2f5ebbadecc7a0b 9ca048c54d9848cca2f5ebbadecc7a0b--3d85f34477e1493492070391437ab38b

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_6530487ff8f44b9db382a1eb520b6732 Obs. cluster_5dd038ee07c1460db05913165acb1c0e cluster_8e0e62ffcca44d2393735170606d2cf6 Tower Chebyshev FM cluster_5c310b9b73cd4ee9adea75e867f341fd Tower Chebyshev FM cluster_c5ac18230ba84119a6719b92630b1da4 HEA 1fdb4c13f22e4a1c84cf486c06305ce8 0 b793a9684de244088b18c0f1b7c9c123 RX(1.0*acos(x)) 1fdb4c13f22e4a1c84cf486c06305ce8--b793a9684de244088b18c0f1b7c9c123 79f45a62a40945028be95dd8ec1e7fda 1 769d118489a5406fa0aaca58a00f0042 RX(theta₀) b793a9684de244088b18c0f1b7c9c123--769d118489a5406fa0aaca58a00f0042 d4b74bbcbd4243c5ba788c43de9e39e4 RY(theta₄) 769d118489a5406fa0aaca58a00f0042--d4b74bbcbd4243c5ba788c43de9e39e4 0add87d4a46549b7b57c5ab5ac7f6ffb RX(theta₈) d4b74bbcbd4243c5ba788c43de9e39e4--0add87d4a46549b7b57c5ab5ac7f6ffb f9c41fefee0d48a59ea0c39685a4ea32 0add87d4a46549b7b57c5ab5ac7f6ffb--f9c41fefee0d48a59ea0c39685a4ea32 d872170d30854187a0a051297262f32b f9c41fefee0d48a59ea0c39685a4ea32--d872170d30854187a0a051297262f32b 27fc018e52db4932a4075778ba36a924 RX(theta₁₂) d872170d30854187a0a051297262f32b--27fc018e52db4932a4075778ba36a924 e43f711faf164524b4f8d8f864a71034 RY(theta₁₆) 27fc018e52db4932a4075778ba36a924--e43f711faf164524b4f8d8f864a71034 0669654d917241ca8c4c6d4d34aa92e6 RX(theta₂₀) e43f711faf164524b4f8d8f864a71034--0669654d917241ca8c4c6d4d34aa92e6 083b67ff9a7149df8aa2fae477ecc742 0669654d917241ca8c4c6d4d34aa92e6--083b67ff9a7149df8aa2fae477ecc742 deb3dfeed4104f6486b2d6ad12310067 083b67ff9a7149df8aa2fae477ecc742--deb3dfeed4104f6486b2d6ad12310067 ffad3078ffb14b3f9ab944e33f79ffd2 deb3dfeed4104f6486b2d6ad12310067--ffad3078ffb14b3f9ab944e33f79ffd2 207cb64b1b77433c8a217508a4599bdf ffad3078ffb14b3f9ab944e33f79ffd2--207cb64b1b77433c8a217508a4599bdf 64acbfa1d8c941a688fe2edba8d7b097 afbeba92e2164356b1e2aea97bc9cd36 RX(2.0*acos(x)) 79f45a62a40945028be95dd8ec1e7fda--afbeba92e2164356b1e2aea97bc9cd36 c4f9b9c193fd4891b165fb6dc782d9fe 2 cb2dc2db9e2c418aaacf4a64b1742524 RX(theta₁) afbeba92e2164356b1e2aea97bc9cd36--cb2dc2db9e2c418aaacf4a64b1742524 865381ebf1b44191be0956b0c00d78ee RY(theta₅) cb2dc2db9e2c418aaacf4a64b1742524--865381ebf1b44191be0956b0c00d78ee 2399d5d01aac43188b5591482d00aaa8 RX(theta₉) 865381ebf1b44191be0956b0c00d78ee--2399d5d01aac43188b5591482d00aaa8 831ded7cbc44406eb511d5e1304ea79b X 2399d5d01aac43188b5591482d00aaa8--831ded7cbc44406eb511d5e1304ea79b 831ded7cbc44406eb511d5e1304ea79b--f9c41fefee0d48a59ea0c39685a4ea32 711590e7150f451685a7e6ffd506d61f 831ded7cbc44406eb511d5e1304ea79b--711590e7150f451685a7e6ffd506d61f 2b8eeacbbbfb4394b91855d47d351b22 RX(theta₁₃) 711590e7150f451685a7e6ffd506d61f--2b8eeacbbbfb4394b91855d47d351b22 9803d9bb90134e5a901455d94d5896e2 RY(theta₁₇) 2b8eeacbbbfb4394b91855d47d351b22--9803d9bb90134e5a901455d94d5896e2 45f6145d1d32423a993b4792dadedf1d RX(theta₂₁) 9803d9bb90134e5a901455d94d5896e2--45f6145d1d32423a993b4792dadedf1d 4d6466ec6dea48b4905977acdd67d9ae X 45f6145d1d32423a993b4792dadedf1d--4d6466ec6dea48b4905977acdd67d9ae 4d6466ec6dea48b4905977acdd67d9ae--083b67ff9a7149df8aa2fae477ecc742 ac54e0edb27846a8b7266caa762c9f38 4d6466ec6dea48b4905977acdd67d9ae--ac54e0edb27846a8b7266caa762c9f38 9156bf558be441d1a71c3903316e39a1 AddBlock ac54e0edb27846a8b7266caa762c9f38--9156bf558be441d1a71c3903316e39a1 9156bf558be441d1a71c3903316e39a1--64acbfa1d8c941a688fe2edba8d7b097 fb601a5f4fd84710969fae4a8a6d0f2c 4cd1711ebdc74cdc8fa519bc2fccb02a RX(1.0*acos(2.0*y - 1.0)) c4f9b9c193fd4891b165fb6dc782d9fe--4cd1711ebdc74cdc8fa519bc2fccb02a 30ba3dce34e646c181381aa3bed1eebd 3 08a13d77264e465dbbacaf9b6c38d36e RX(theta₂) 4cd1711ebdc74cdc8fa519bc2fccb02a--08a13d77264e465dbbacaf9b6c38d36e c0b7a6d33b4b4bee9d36c8764a98cb15 RY(theta₆) 08a13d77264e465dbbacaf9b6c38d36e--c0b7a6d33b4b4bee9d36c8764a98cb15 43768d2e66d8407cbb39004d0d93e295 RX(theta₁₀) c0b7a6d33b4b4bee9d36c8764a98cb15--43768d2e66d8407cbb39004d0d93e295 cbf400fb9a6b475cb4ed821421faa979 43768d2e66d8407cbb39004d0d93e295--cbf400fb9a6b475cb4ed821421faa979 71005bcd14774b64adb1938d2f96214e X cbf400fb9a6b475cb4ed821421faa979--71005bcd14774b64adb1938d2f96214e 71005bcd14774b64adb1938d2f96214e--711590e7150f451685a7e6ffd506d61f 6fbda4d31e524633904eb8494fe0f2a2 RX(theta₁₄) 71005bcd14774b64adb1938d2f96214e--6fbda4d31e524633904eb8494fe0f2a2 57d1b0c1fe9c4e8f8433dae91411a9bf RY(theta₁₈) 6fbda4d31e524633904eb8494fe0f2a2--57d1b0c1fe9c4e8f8433dae91411a9bf fa31a1e8f18a49efa44d464c69e4abea RX(theta₂₂) 57d1b0c1fe9c4e8f8433dae91411a9bf--fa31a1e8f18a49efa44d464c69e4abea 0c04401874e64b339b7d0dcc324802d9 fa31a1e8f18a49efa44d464c69e4abea--0c04401874e64b339b7d0dcc324802d9 786290aed56f472ebfffa8acd0eef1d3 X 0c04401874e64b339b7d0dcc324802d9--786290aed56f472ebfffa8acd0eef1d3 786290aed56f472ebfffa8acd0eef1d3--ac54e0edb27846a8b7266caa762c9f38 fed0b6f959974c76abedfde4d7056d69 786290aed56f472ebfffa8acd0eef1d3--fed0b6f959974c76abedfde4d7056d69 fed0b6f959974c76abedfde4d7056d69--fb601a5f4fd84710969fae4a8a6d0f2c f342f8fe2b4840bbba2d27a6d04eb861 1c0a25c669374e2b878a8f0cd77f8b0f RX(2.0*acos(2.0*y - 1.0)) 30ba3dce34e646c181381aa3bed1eebd--1c0a25c669374e2b878a8f0cd77f8b0f 587560592c3c4d51bd757e246aa3092c RX(theta₃) 1c0a25c669374e2b878a8f0cd77f8b0f--587560592c3c4d51bd757e246aa3092c 2df2470797804086aedb8e8891ac161c RY(theta₇) 587560592c3c4d51bd757e246aa3092c--2df2470797804086aedb8e8891ac161c cad6df0bf532458fb7ed302f7517f500 RX(theta₁₁) 2df2470797804086aedb8e8891ac161c--cad6df0bf532458fb7ed302f7517f500 e536c8fe568840708cb7163c9e38ca71 X cad6df0bf532458fb7ed302f7517f500--e536c8fe568840708cb7163c9e38ca71 e536c8fe568840708cb7163c9e38ca71--cbf400fb9a6b475cb4ed821421faa979 df44e185f14d40b7920e000ba9c86a10 e536c8fe568840708cb7163c9e38ca71--df44e185f14d40b7920e000ba9c86a10 cdc7f595b16e4bd6b4af975d5171fc54 RX(theta₁₅) df44e185f14d40b7920e000ba9c86a10--cdc7f595b16e4bd6b4af975d5171fc54 5e1ee9e8b71046b6ba2c53e0e3917376 RY(theta₁₉) cdc7f595b16e4bd6b4af975d5171fc54--5e1ee9e8b71046b6ba2c53e0e3917376 87fa701f453747f38ed6801cb6248fef RX(theta₂₃) 5e1ee9e8b71046b6ba2c53e0e3917376--87fa701f453747f38ed6801cb6248fef b9794d70d3d64229b45292a05731dab2 X 87fa701f453747f38ed6801cb6248fef--b9794d70d3d64229b45292a05731dab2 b9794d70d3d64229b45292a05731dab2--0c04401874e64b339b7d0dcc324802d9 9a9d3ec2492b4aaeb4bb8f59022890b5 b9794d70d3d64229b45292a05731dab2--9a9d3ec2492b4aaeb4bb8f59022890b5 a84e2a9690884bad8817b2a4c0006d9b 9a9d3ec2492b4aaeb4bb8f59022890b5--a84e2a9690884bad8817b2a4c0006d9b a84e2a9690884bad8817b2a4c0006d9b--f342f8fe2b4840bbba2d27a6d04eb861