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_a4ed89abba0646e68021fb1591a0a836 3295a1c0c81c4c52b924a0230e1ba65d 0 8da1c47fc11d422fb93cbfd849f0e00b 3295a1c0c81c4c52b924a0230e1ba65d--8da1c47fc11d422fb93cbfd849f0e00b df5ecb3044c646019ce61567048a62d4 1 45c04110bcc94edebfa174f6b3aed79b 8da1c47fc11d422fb93cbfd849f0e00b--45c04110bcc94edebfa174f6b3aed79b ca122246677140089c67225593a6269d e5d663c96af5462abc826ed88e71ee57 AddBlock df5ecb3044c646019ce61567048a62d4--e5d663c96af5462abc826ed88e71ee57 1fb7156c298b420eab76a24b5c64e765 2 e5d663c96af5462abc826ed88e71ee57--ca122246677140089c67225593a6269d 5ce2f7ad9de248e0b6f97e6775f3c10d ed4752291f9a484c87c1141c829da0aa 1fb7156c298b420eab76a24b5c64e765--ed4752291f9a484c87c1141c829da0aa 88c0ea7c95f94c05b5a4eb8effd320dd 3 ed4752291f9a484c87c1141c829da0aa--5ce2f7ad9de248e0b6f97e6775f3c10d 2daf8092aa7a4681ae4db77c51932ce5 e28eb25743ea450b9685af6dfd016532 88c0ea7c95f94c05b5a4eb8effd320dd--e28eb25743ea450b9685af6dfd016532 e28eb25743ea450b9685af6dfd016532--2daf8092aa7a4681ae4db77c51932ce5

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_7b06c0f3a7134273ada9cb7ca2379e7b Tower Chebyshev FM cluster_38325b36669d41f4a99e4d386382d874 Tower Chebyshev FM 4cbf00e31ade46a785c2b519f87ae5b3 0 04cdb48554e64605b1e2be60d451d7ae RX(1.0*acos(x)) 4cbf00e31ade46a785c2b519f87ae5b3--04cdb48554e64605b1e2be60d451d7ae ea83d129aec14309ae1673b69b38ea05 1 246a69eeb5dd4aafa9c31db90017edd5 04cdb48554e64605b1e2be60d451d7ae--246a69eeb5dd4aafa9c31db90017edd5 b44d26b573e74fc9bbf395e96fd0c985 8a0cabd7ed71427cba2dcfa16cfd6ad0 RX(2.0*acos(x)) ea83d129aec14309ae1673b69b38ea05--8a0cabd7ed71427cba2dcfa16cfd6ad0 0e1fd351b0cc4b0781ebdbb6a5966d93 2 8a0cabd7ed71427cba2dcfa16cfd6ad0--b44d26b573e74fc9bbf395e96fd0c985 e989a29052b64d8e8b247dc4ebc92055 b6b97af5cccf40baaf2359ca4aa9ae20 RX(1.0*acos(2.0*y - 1.0)) 0e1fd351b0cc4b0781ebdbb6a5966d93--b6b97af5cccf40baaf2359ca4aa9ae20 bb42318154cc4f11999cdcb328747f20 3 b6b97af5cccf40baaf2359ca4aa9ae20--e989a29052b64d8e8b247dc4ebc92055 2e58a96f4f1b48bf8c2a36e50a2eba90 7b1804e70e0049c69d25c309727dd01f RX(2.0*acos(2.0*y - 1.0)) bb42318154cc4f11999cdcb328747f20--7b1804e70e0049c69d25c309727dd01f 7b1804e70e0049c69d25c309727dd01f--2e58a96f4f1b48bf8c2a36e50a2eba90

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 4a059b6f4fa145259e2d53f348d783bd 0 67ecc55396544bb4857e9d25ab37d1f1 RX(theta₀) 4a059b6f4fa145259e2d53f348d783bd--67ecc55396544bb4857e9d25ab37d1f1 a321a3fa72b646c4af22be8523f379dc 1 e694be45f77e4e36833b7df190b188f2 RY(theta₄) 67ecc55396544bb4857e9d25ab37d1f1--e694be45f77e4e36833b7df190b188f2 5f75b978f2e94fb2a9a20d0fa36d1413 RX(theta₈) e694be45f77e4e36833b7df190b188f2--5f75b978f2e94fb2a9a20d0fa36d1413 e222eb33722e49fd99f6669111944433 5f75b978f2e94fb2a9a20d0fa36d1413--e222eb33722e49fd99f6669111944433 f0396c144ca54e8f8b353351d1ce5f4d e222eb33722e49fd99f6669111944433--f0396c144ca54e8f8b353351d1ce5f4d 8ec90067841041d88f70d5e726d1123f RX(theta₁₂) f0396c144ca54e8f8b353351d1ce5f4d--8ec90067841041d88f70d5e726d1123f 8d25755bfbeb47d3bec367d34cac6256 RY(theta₁₆) 8ec90067841041d88f70d5e726d1123f--8d25755bfbeb47d3bec367d34cac6256 1787c1bfbf834a8a85adde225fa09472 RX(theta₂₀) 8d25755bfbeb47d3bec367d34cac6256--1787c1bfbf834a8a85adde225fa09472 7cf66589f9bc4f97948e3a3e859d1462 1787c1bfbf834a8a85adde225fa09472--7cf66589f9bc4f97948e3a3e859d1462 bdf6c64ca74d40cd88c4f75522c96fc1 7cf66589f9bc4f97948e3a3e859d1462--bdf6c64ca74d40cd88c4f75522c96fc1 de66e8f278804a519284486b6728ee3b bdf6c64ca74d40cd88c4f75522c96fc1--de66e8f278804a519284486b6728ee3b 89f92e7eefab4d79915d9f6ff768a90d b660eda415fe4b18a482ad8f1520479d RX(theta₁) a321a3fa72b646c4af22be8523f379dc--b660eda415fe4b18a482ad8f1520479d 9d04cdbad1f44f3ebafd13b82a0499ce 2 8af242fabb654c4eb1a2d05a290dd459 RY(theta₅) b660eda415fe4b18a482ad8f1520479d--8af242fabb654c4eb1a2d05a290dd459 c993db23ddfd43fa9e5ba4ac783f3a58 RX(theta₉) 8af242fabb654c4eb1a2d05a290dd459--c993db23ddfd43fa9e5ba4ac783f3a58 b3db67049515404ca6cd1f2e1c8b2a95 X c993db23ddfd43fa9e5ba4ac783f3a58--b3db67049515404ca6cd1f2e1c8b2a95 b3db67049515404ca6cd1f2e1c8b2a95--e222eb33722e49fd99f6669111944433 0692b159016d4fc4b98e33e25b8aa8ed b3db67049515404ca6cd1f2e1c8b2a95--0692b159016d4fc4b98e33e25b8aa8ed acef52fb4b94425fa710757972f65686 RX(theta₁₃) 0692b159016d4fc4b98e33e25b8aa8ed--acef52fb4b94425fa710757972f65686 950e18481ae04d9e81d220d4188087f2 RY(theta₁₇) acef52fb4b94425fa710757972f65686--950e18481ae04d9e81d220d4188087f2 1ddb034fbbec4419baa048cac126350f RX(theta₂₁) 950e18481ae04d9e81d220d4188087f2--1ddb034fbbec4419baa048cac126350f 9e845aef115641a783a7dd9400eb28a9 X 1ddb034fbbec4419baa048cac126350f--9e845aef115641a783a7dd9400eb28a9 9e845aef115641a783a7dd9400eb28a9--7cf66589f9bc4f97948e3a3e859d1462 91361241d9374f5bac7aadaf09e0b1eb 9e845aef115641a783a7dd9400eb28a9--91361241d9374f5bac7aadaf09e0b1eb 91361241d9374f5bac7aadaf09e0b1eb--89f92e7eefab4d79915d9f6ff768a90d b7037ae53c54429f974a18db0371b763 fea71b8fa37948a3bcb715ebcc2516d7 RX(theta₂) 9d04cdbad1f44f3ebafd13b82a0499ce--fea71b8fa37948a3bcb715ebcc2516d7 5d9a3447a6b14725872214678a28f41e 3 31bda20899004532afe894be3ca66cfe RY(theta₆) fea71b8fa37948a3bcb715ebcc2516d7--31bda20899004532afe894be3ca66cfe 782020e06b6e4837a7c534804f7bd86d RX(theta₁₀) 31bda20899004532afe894be3ca66cfe--782020e06b6e4837a7c534804f7bd86d fcb07b9e72044dcdba39f52950c01e36 782020e06b6e4837a7c534804f7bd86d--fcb07b9e72044dcdba39f52950c01e36 3fa7b828b7c24480a16bcbbb89ef6fdf X fcb07b9e72044dcdba39f52950c01e36--3fa7b828b7c24480a16bcbbb89ef6fdf 3fa7b828b7c24480a16bcbbb89ef6fdf--0692b159016d4fc4b98e33e25b8aa8ed 8ee953d6cc8a4d73b795b685ef6f5408 RX(theta₁₄) 3fa7b828b7c24480a16bcbbb89ef6fdf--8ee953d6cc8a4d73b795b685ef6f5408 8454ca9497b649af85764a2788de5581 RY(theta₁₈) 8ee953d6cc8a4d73b795b685ef6f5408--8454ca9497b649af85764a2788de5581 4066dd88e18949cf95f476e0719074c7 RX(theta₂₂) 8454ca9497b649af85764a2788de5581--4066dd88e18949cf95f476e0719074c7 2dabcacc7172487bb0982264ba9e5b54 4066dd88e18949cf95f476e0719074c7--2dabcacc7172487bb0982264ba9e5b54 461dfccf25fb42e3b83e4bbdae709a07 X 2dabcacc7172487bb0982264ba9e5b54--461dfccf25fb42e3b83e4bbdae709a07 461dfccf25fb42e3b83e4bbdae709a07--91361241d9374f5bac7aadaf09e0b1eb 461dfccf25fb42e3b83e4bbdae709a07--b7037ae53c54429f974a18db0371b763 fdb2620156b54ddfa5fefa9101de3f8c 0760723976ab4f459df99250a331a0d3 RX(theta₃) 5d9a3447a6b14725872214678a28f41e--0760723976ab4f459df99250a331a0d3 82c4469ccbc44b469858caf0f75963a0 RY(theta₇) 0760723976ab4f459df99250a331a0d3--82c4469ccbc44b469858caf0f75963a0 5d7db260c95d4ad181e5812b74992862 RX(theta₁₁) 82c4469ccbc44b469858caf0f75963a0--5d7db260c95d4ad181e5812b74992862 5ad392577549440fa1a0a934721d3eec X 5d7db260c95d4ad181e5812b74992862--5ad392577549440fa1a0a934721d3eec 5ad392577549440fa1a0a934721d3eec--fcb07b9e72044dcdba39f52950c01e36 0aa209fbd7814192b51a047adcd9013c 5ad392577549440fa1a0a934721d3eec--0aa209fbd7814192b51a047adcd9013c 22d8cef95a874b8285ca8d57bd03fd60 RX(theta₁₅) 0aa209fbd7814192b51a047adcd9013c--22d8cef95a874b8285ca8d57bd03fd60 67a66476e3a94dc69f9384179c783b81 RY(theta₁₉) 22d8cef95a874b8285ca8d57bd03fd60--67a66476e3a94dc69f9384179c783b81 46b9b8ed80d9460da9996a9ed14f4a71 RX(theta₂₃) 67a66476e3a94dc69f9384179c783b81--46b9b8ed80d9460da9996a9ed14f4a71 455e2342aabe466cbfe40c002644a6f8 X 46b9b8ed80d9460da9996a9ed14f4a71--455e2342aabe466cbfe40c002644a6f8 455e2342aabe466cbfe40c002644a6f8--2dabcacc7172487bb0982264ba9e5b54 aca8d8090efa4641b5da6549d5e08edb 455e2342aabe466cbfe40c002644a6f8--aca8d8090efa4641b5da6549d5e08edb aca8d8090efa4641b5da6549d5e08edb--fdb2620156b54ddfa5fefa9101de3f8c

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_8baf87a6424b446190e5f867c3366bf3 Obs. cluster_12324775c9804f5884d6c44bf58007c8 cluster_990f83e27e0a484ca3f023a541be8afb Tower Chebyshev FM cluster_e51af4a3d5d248f6bc11284dba86074a Tower Chebyshev FM cluster_ab15c60a0b7344e3bf07252f007242f1 HEA cfb4159a1df0447dbdbf6a4e8b21aa52 0 217c06d1c9f34c1a933df26f1288d0b8 RX(1.0*acos(x)) cfb4159a1df0447dbdbf6a4e8b21aa52--217c06d1c9f34c1a933df26f1288d0b8 afcae2c722ae48b9a034f10fa1d7de0b 1 a8b2469bdaad4d8292e5d801e7397ef9 RX(theta₀) 217c06d1c9f34c1a933df26f1288d0b8--a8b2469bdaad4d8292e5d801e7397ef9 a927f9d27cf3453db3749c73f1288dce RY(theta₄) a8b2469bdaad4d8292e5d801e7397ef9--a927f9d27cf3453db3749c73f1288dce 7353c454677f4ffdb9d7e5ca5be11f03 RX(theta₈) a927f9d27cf3453db3749c73f1288dce--7353c454677f4ffdb9d7e5ca5be11f03 28bd344203214d0ca8256950ff778de0 7353c454677f4ffdb9d7e5ca5be11f03--28bd344203214d0ca8256950ff778de0 ce8bcff5c8484a2f929c4a51ff67a442 28bd344203214d0ca8256950ff778de0--ce8bcff5c8484a2f929c4a51ff67a442 89afa45309254c778c5a6b011e2b9e85 RX(theta₁₂) ce8bcff5c8484a2f929c4a51ff67a442--89afa45309254c778c5a6b011e2b9e85 2d3eb72228634861af2980e55b14eb1d RY(theta₁₆) 89afa45309254c778c5a6b011e2b9e85--2d3eb72228634861af2980e55b14eb1d 30b226914f8542b88b850876d5af8bf4 RX(theta₂₀) 2d3eb72228634861af2980e55b14eb1d--30b226914f8542b88b850876d5af8bf4 44b252cc38cb4cafb27e46f247ee2513 30b226914f8542b88b850876d5af8bf4--44b252cc38cb4cafb27e46f247ee2513 6b04893ea8ae42818b465e727715ca20 44b252cc38cb4cafb27e46f247ee2513--6b04893ea8ae42818b465e727715ca20 2d51bb9a5ebd4e6a9f7c25a544f7f47e 6b04893ea8ae42818b465e727715ca20--2d51bb9a5ebd4e6a9f7c25a544f7f47e 8c5d6707434b45bcb839256fe68a8e90 2d51bb9a5ebd4e6a9f7c25a544f7f47e--8c5d6707434b45bcb839256fe68a8e90 47143bd806d349f0b68b1ff4c9748104 8a67dfaa70db427198cfa39c8e9c93ed RX(2.0*acos(x)) afcae2c722ae48b9a034f10fa1d7de0b--8a67dfaa70db427198cfa39c8e9c93ed 20cb627d439943188f148a709573955f 2 504099d7e75244918159d2f9e3a61126 RX(theta₁) 8a67dfaa70db427198cfa39c8e9c93ed--504099d7e75244918159d2f9e3a61126 6ae5393cac7340fb96483a25bed0b38a RY(theta₅) 504099d7e75244918159d2f9e3a61126--6ae5393cac7340fb96483a25bed0b38a acc2571f172c4798b8ce6253742cce2d RX(theta₉) 6ae5393cac7340fb96483a25bed0b38a--acc2571f172c4798b8ce6253742cce2d 2c07c37b6e364ced9f6d2ef54c2cea58 X acc2571f172c4798b8ce6253742cce2d--2c07c37b6e364ced9f6d2ef54c2cea58 2c07c37b6e364ced9f6d2ef54c2cea58--28bd344203214d0ca8256950ff778de0 a46d1c644832416bb06150f203d75c58 2c07c37b6e364ced9f6d2ef54c2cea58--a46d1c644832416bb06150f203d75c58 ddf273b74ae04c7b926c01581d2c18dc RX(theta₁₃) a46d1c644832416bb06150f203d75c58--ddf273b74ae04c7b926c01581d2c18dc 74382345561a4d21976738792341c339 RY(theta₁₇) ddf273b74ae04c7b926c01581d2c18dc--74382345561a4d21976738792341c339 4c7cd6d9b64641ac9c37cf01a7556ff9 RX(theta₂₁) 74382345561a4d21976738792341c339--4c7cd6d9b64641ac9c37cf01a7556ff9 c844e85ef4b045d68e3e9c8d3e828cd6 X 4c7cd6d9b64641ac9c37cf01a7556ff9--c844e85ef4b045d68e3e9c8d3e828cd6 c844e85ef4b045d68e3e9c8d3e828cd6--44b252cc38cb4cafb27e46f247ee2513 e45b0936748a4c5ca4a10f15119fd4e9 c844e85ef4b045d68e3e9c8d3e828cd6--e45b0936748a4c5ca4a10f15119fd4e9 0c79effd93de4c3d9e498f008601c7fd AddBlock e45b0936748a4c5ca4a10f15119fd4e9--0c79effd93de4c3d9e498f008601c7fd 0c79effd93de4c3d9e498f008601c7fd--47143bd806d349f0b68b1ff4c9748104 dbc569ee492b4e6ea6b972eac4080e35 86167bd1c41248a8af26545ff6e863fc RX(1.0*acos(2.0*y - 1.0)) 20cb627d439943188f148a709573955f--86167bd1c41248a8af26545ff6e863fc 32314b12bffe4cad81a134a963f34463 3 30e7cbeda4414bcaba91710ca17d0158 RX(theta₂) 86167bd1c41248a8af26545ff6e863fc--30e7cbeda4414bcaba91710ca17d0158 b69f6fc561ff4a8b9dd41413ca3b3abc RY(theta₆) 30e7cbeda4414bcaba91710ca17d0158--b69f6fc561ff4a8b9dd41413ca3b3abc 00a5ec14eb8d4361a02980d0d60773d7 RX(theta₁₀) b69f6fc561ff4a8b9dd41413ca3b3abc--00a5ec14eb8d4361a02980d0d60773d7 0729c4b26ea5432483a0ca3d731e3d45 00a5ec14eb8d4361a02980d0d60773d7--0729c4b26ea5432483a0ca3d731e3d45 ddabcf70e25943959691fa33bae3b991 X 0729c4b26ea5432483a0ca3d731e3d45--ddabcf70e25943959691fa33bae3b991 ddabcf70e25943959691fa33bae3b991--a46d1c644832416bb06150f203d75c58 e84bc67fe77f4ef7909378e9104ff9e2 RX(theta₁₄) ddabcf70e25943959691fa33bae3b991--e84bc67fe77f4ef7909378e9104ff9e2 4a54a9c8c4e24be4bed1242c10c1aa4c RY(theta₁₈) e84bc67fe77f4ef7909378e9104ff9e2--4a54a9c8c4e24be4bed1242c10c1aa4c fa41a03cb57a46cfb3d0b4466888d9e2 RX(theta₂₂) 4a54a9c8c4e24be4bed1242c10c1aa4c--fa41a03cb57a46cfb3d0b4466888d9e2 0ff105095bad40559a9fd8715ec1f4ca fa41a03cb57a46cfb3d0b4466888d9e2--0ff105095bad40559a9fd8715ec1f4ca ca1feab012a84aa3b5d749052ccecd5a X 0ff105095bad40559a9fd8715ec1f4ca--ca1feab012a84aa3b5d749052ccecd5a ca1feab012a84aa3b5d749052ccecd5a--e45b0936748a4c5ca4a10f15119fd4e9 8dc9ade1ca3e4a7191dab2d628e88923 ca1feab012a84aa3b5d749052ccecd5a--8dc9ade1ca3e4a7191dab2d628e88923 8dc9ade1ca3e4a7191dab2d628e88923--dbc569ee492b4e6ea6b972eac4080e35 a35733f9cc874c02b88f974035344ac9 15a080f922b34449a719f7fe168a5c9d RX(2.0*acos(2.0*y - 1.0)) 32314b12bffe4cad81a134a963f34463--15a080f922b34449a719f7fe168a5c9d 0558bc2d43754159b1194d595f828c95 RX(theta₃) 15a080f922b34449a719f7fe168a5c9d--0558bc2d43754159b1194d595f828c95 8c23b0494271473cac9f2622e1ea287e RY(theta₇) 0558bc2d43754159b1194d595f828c95--8c23b0494271473cac9f2622e1ea287e eb3c53d7d2d94504b5b208d400267c69 RX(theta₁₁) 8c23b0494271473cac9f2622e1ea287e--eb3c53d7d2d94504b5b208d400267c69 7ef88e99f9fc4f5692197180bda379ef X eb3c53d7d2d94504b5b208d400267c69--7ef88e99f9fc4f5692197180bda379ef 7ef88e99f9fc4f5692197180bda379ef--0729c4b26ea5432483a0ca3d731e3d45 958d8823659a4a4fa7e043d827266f1d 7ef88e99f9fc4f5692197180bda379ef--958d8823659a4a4fa7e043d827266f1d fffca9436b7a4045849ab44c8baee096 RX(theta₁₅) 958d8823659a4a4fa7e043d827266f1d--fffca9436b7a4045849ab44c8baee096 fb8fc23b1c234276a9c616d56d943954 RY(theta₁₉) fffca9436b7a4045849ab44c8baee096--fb8fc23b1c234276a9c616d56d943954 9f0d789aad4d47c7a00b6b0aecac3f54 RX(theta₂₃) fb8fc23b1c234276a9c616d56d943954--9f0d789aad4d47c7a00b6b0aecac3f54 b2836d784df4405ca0a13d88b261e1c0 X 9f0d789aad4d47c7a00b6b0aecac3f54--b2836d784df4405ca0a13d88b261e1c0 b2836d784df4405ca0a13d88b261e1c0--0ff105095bad40559a9fd8715ec1f4ca 019d050190d54b1cb0541b6b7fd103ec b2836d784df4405ca0a13d88b261e1c0--019d050190d54b1cb0541b6b7fd103ec ffac6eb4aab947cfba6a4c0c6f85176b 019d050190d54b1cb0541b6b7fd103ec--ffac6eb4aab947cfba6a4c0c6f85176b ffac6eb4aab947cfba6a4c0c6f85176b--a35733f9cc874c02b88f974035344ac9