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.

We can specify any Hamiltonian that we want to measure at the end of the circuit. Let us say we want to measure the \(Z\) operator.

from qadence import observable_from_config, ObservableConfig, Z

observable_config = ObservableConfig(
    detuning=Z,
    scale=3.0,
    shift=-1.0,
)

observable = observable_from_config(register=4, config=observable_config)
%3 cluster_f036bbd891f24e76bc700dca2a4da889 17886c9d71ad4b4f8360e686e33ca2a1 0 d1d666861805478f9354f5d49ea9f59d 17886c9d71ad4b4f8360e686e33ca2a1--d1d666861805478f9354f5d49ea9f59d 362ff571f41d4c6d801aea948f5d707e 1 4aa3e6fce6c747a29c37e77b193bb8d0 d1d666861805478f9354f5d49ea9f59d--4aa3e6fce6c747a29c37e77b193bb8d0 9db8f55058e14f3da6f9cbc74d7d5d12 290381f3b8634b47bda9062bb7e959a1 AddBlock 362ff571f41d4c6d801aea948f5d707e--290381f3b8634b47bda9062bb7e959a1 f2501eac036a467e8e289c56a9f2f73e 2 290381f3b8634b47bda9062bb7e959a1--9db8f55058e14f3da6f9cbc74d7d5d12 5ff0d18c617c43d88018e588e98db5d8 1544a4aa5ae549d68eddad11b19b4dd5 f2501eac036a467e8e289c56a9f2f73e--1544a4aa5ae549d68eddad11b19b4dd5 7a14a90b4bdf4fa8be87e51587708911 3 1544a4aa5ae549d68eddad11b19b4dd5--5ff0d18c617c43d88018e588e98db5d8 88f79c2ac4e847ed96b75cbe8c0f57fb 94244d68572f49e3b928c5358ee6899f 7a14a90b4bdf4fa8be87e51587708911--94244d68572f49e3b928c5358ee6899f 94244d68572f49e3b928c5358ee6899f--88f79c2ac4e847ed96b75cbe8c0f57fb

We have specified the observable Hamiltonian to be one with \(Z\)-detuning. The result is linearly scaled by 3.0 and shifted by -1.0. These parameters can optionally also be FeatureParameter or VariationalParameter

One can also specify the observable as a list of observables, in which case the QNN will output a list of values.

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_19625a5c7e33487d9d46f2ed93f3a221 Tower Chebyshev FM cluster_aabad077262d41829e220e860f88b504 Tower Chebyshev FM d11f94aef4aa4d97a42a8b791e663630 0 9032a1ecb5a84a4681c02853ba52d95c RX(1.0*acos(x)) d11f94aef4aa4d97a42a8b791e663630--9032a1ecb5a84a4681c02853ba52d95c 0545dfb5c76342f0a77792fe65bec13e 1 830798f0709f47acb54829e174e58423 9032a1ecb5a84a4681c02853ba52d95c--830798f0709f47acb54829e174e58423 e9e968c3d9cc495ab72c767b0fb3937c 6f6df8b240824a6c967b15c163b301be RX(2.0*acos(x)) 0545dfb5c76342f0a77792fe65bec13e--6f6df8b240824a6c967b15c163b301be 07fdc1036fe8471882f1be8baf3de4f1 2 6f6df8b240824a6c967b15c163b301be--e9e968c3d9cc495ab72c767b0fb3937c 0e7658ea01564488ac5689b5788210cf 395822e68a034fecb8c9ececb823cb70 RX(1.0*acos(2.0*y - 1.0)) 07fdc1036fe8471882f1be8baf3de4f1--395822e68a034fecb8c9ececb823cb70 7dca2e277274416fb3b6ac27f42c87fa 3 395822e68a034fecb8c9ececb823cb70--0e7658ea01564488ac5689b5788210cf cbafb2e431f145ba8bfebf77833fe21a b1fb877188574fbcbd9761c927241bda RX(2.0*acos(2.0*y - 1.0)) 7dca2e277274416fb3b6ac27f42c87fa--b1fb877188574fbcbd9761c927241bda b1fb877188574fbcbd9761c927241bda--cbafb2e431f145ba8bfebf77833fe21a

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 938d3b3fa8074079ad80838e9a45e32e 0 5721207a3dcf4fd98b343d08aeb53c0c RX(theta₀) 938d3b3fa8074079ad80838e9a45e32e--5721207a3dcf4fd98b343d08aeb53c0c e8e147d1af6e42e690315dd1674ce396 1 7a722bebe4c44253a8f9a43a58547878 RY(theta₄) 5721207a3dcf4fd98b343d08aeb53c0c--7a722bebe4c44253a8f9a43a58547878 df596b8e3f264eada7ec718231ba0df4 RX(theta₈) 7a722bebe4c44253a8f9a43a58547878--df596b8e3f264eada7ec718231ba0df4 1e0678b2651b4055bda4074a95916287 df596b8e3f264eada7ec718231ba0df4--1e0678b2651b4055bda4074a95916287 2b953dac1f75450b9acbf6c2840f0383 1e0678b2651b4055bda4074a95916287--2b953dac1f75450b9acbf6c2840f0383 f3a69376ba3a4f6e876c2e6eaef2f6e9 RX(theta₁₂) 2b953dac1f75450b9acbf6c2840f0383--f3a69376ba3a4f6e876c2e6eaef2f6e9 6bf79112a98e42029dad701285eba9ba RY(theta₁₆) f3a69376ba3a4f6e876c2e6eaef2f6e9--6bf79112a98e42029dad701285eba9ba 6bbe4b28da724a71850bac4db2b840c9 RX(theta₂₀) 6bf79112a98e42029dad701285eba9ba--6bbe4b28da724a71850bac4db2b840c9 0b9f2b51713b404ca9771bb2c2b09e19 6bbe4b28da724a71850bac4db2b840c9--0b9f2b51713b404ca9771bb2c2b09e19 eefaa2d499044fc7ba33037dd878b789 0b9f2b51713b404ca9771bb2c2b09e19--eefaa2d499044fc7ba33037dd878b789 182079cd6d2748678b26bbf6f5529563 eefaa2d499044fc7ba33037dd878b789--182079cd6d2748678b26bbf6f5529563 fc8062fc0fe847048f2ed468e9b9471c 71483b3125cd4a7d8a86801f91b1f1c4 RX(theta₁) e8e147d1af6e42e690315dd1674ce396--71483b3125cd4a7d8a86801f91b1f1c4 d4b9409f42c641bc81bd079c56da8e4e 2 f56a1eedea6042df92cc81a0dc75b02c RY(theta₅) 71483b3125cd4a7d8a86801f91b1f1c4--f56a1eedea6042df92cc81a0dc75b02c 58d0f077298740788a3e7eccce1a44d9 RX(theta₉) f56a1eedea6042df92cc81a0dc75b02c--58d0f077298740788a3e7eccce1a44d9 378938f143de443591b465c2c5bddb56 X 58d0f077298740788a3e7eccce1a44d9--378938f143de443591b465c2c5bddb56 378938f143de443591b465c2c5bddb56--1e0678b2651b4055bda4074a95916287 d3608fb11d3148c79c8a80e136035d76 378938f143de443591b465c2c5bddb56--d3608fb11d3148c79c8a80e136035d76 bc831ee53cad482397a5f9690d052d2b RX(theta₁₃) d3608fb11d3148c79c8a80e136035d76--bc831ee53cad482397a5f9690d052d2b 37b6fe9f5b934f25b3a75306a92c4d53 RY(theta₁₇) bc831ee53cad482397a5f9690d052d2b--37b6fe9f5b934f25b3a75306a92c4d53 ca2e2169a5f04d4099aa261088434f48 RX(theta₂₁) 37b6fe9f5b934f25b3a75306a92c4d53--ca2e2169a5f04d4099aa261088434f48 02066c02d80046e8b8ec0e8c056548be X ca2e2169a5f04d4099aa261088434f48--02066c02d80046e8b8ec0e8c056548be 02066c02d80046e8b8ec0e8c056548be--0b9f2b51713b404ca9771bb2c2b09e19 9955b08eb56a4f2bafb275897ad6e8a2 02066c02d80046e8b8ec0e8c056548be--9955b08eb56a4f2bafb275897ad6e8a2 9955b08eb56a4f2bafb275897ad6e8a2--fc8062fc0fe847048f2ed468e9b9471c f31208117c8b4f7ca36ce7d277c333e5 58dcdcf9695d47058fbbd89236b4ac42 RX(theta₂) d4b9409f42c641bc81bd079c56da8e4e--58dcdcf9695d47058fbbd89236b4ac42 6408d46062f04dafa674f1bf5aafdd3f 3 8b6b310aa1fa4a10a2ddf188e03cb43a RY(theta₆) 58dcdcf9695d47058fbbd89236b4ac42--8b6b310aa1fa4a10a2ddf188e03cb43a a94fd7911a1e4c7d9f1aab72194f7d0e RX(theta₁₀) 8b6b310aa1fa4a10a2ddf188e03cb43a--a94fd7911a1e4c7d9f1aab72194f7d0e 83dbc742b9914f478a2269abb78402aa a94fd7911a1e4c7d9f1aab72194f7d0e--83dbc742b9914f478a2269abb78402aa 5d58b8ff7113420a9b4d6bb889fef7ae X 83dbc742b9914f478a2269abb78402aa--5d58b8ff7113420a9b4d6bb889fef7ae 5d58b8ff7113420a9b4d6bb889fef7ae--d3608fb11d3148c79c8a80e136035d76 03429b2b5a2349fbb59e4d60aff5d292 RX(theta₁₄) 5d58b8ff7113420a9b4d6bb889fef7ae--03429b2b5a2349fbb59e4d60aff5d292 f5487ca644c647fdad73694057d1d914 RY(theta₁₈) 03429b2b5a2349fbb59e4d60aff5d292--f5487ca644c647fdad73694057d1d914 5d7f4e90f7744de3a7841cb2e4ef8800 RX(theta₂₂) f5487ca644c647fdad73694057d1d914--5d7f4e90f7744de3a7841cb2e4ef8800 600910915b43400faed69833963896c7 5d7f4e90f7744de3a7841cb2e4ef8800--600910915b43400faed69833963896c7 a5bc2260994d4ee09e40fc902b0ea7f4 X 600910915b43400faed69833963896c7--a5bc2260994d4ee09e40fc902b0ea7f4 a5bc2260994d4ee09e40fc902b0ea7f4--9955b08eb56a4f2bafb275897ad6e8a2 a5bc2260994d4ee09e40fc902b0ea7f4--f31208117c8b4f7ca36ce7d277c333e5 c3201d1d6c0d4dc2aed8fa2faba4e25d f6f44180b8ec4186b686da60c8578201 RX(theta₃) 6408d46062f04dafa674f1bf5aafdd3f--f6f44180b8ec4186b686da60c8578201 f439b54bf47c43a5bf38e3a0173dadc4 RY(theta₇) f6f44180b8ec4186b686da60c8578201--f439b54bf47c43a5bf38e3a0173dadc4 fe9fd2eb68c9452dbb0af602ed979fd9 RX(theta₁₁) f439b54bf47c43a5bf38e3a0173dadc4--fe9fd2eb68c9452dbb0af602ed979fd9 1c9b8903887c46f2a6b68d29a8041b98 X fe9fd2eb68c9452dbb0af602ed979fd9--1c9b8903887c46f2a6b68d29a8041b98 1c9b8903887c46f2a6b68d29a8041b98--83dbc742b9914f478a2269abb78402aa 01f47e3d43064cd68f47cb44e1d34bae 1c9b8903887c46f2a6b68d29a8041b98--01f47e3d43064cd68f47cb44e1d34bae de632ca8b7584411adb15a7e9373f1c4 RX(theta₁₅) 01f47e3d43064cd68f47cb44e1d34bae--de632ca8b7584411adb15a7e9373f1c4 171e932477734f8796d6808196b756fb RY(theta₁₉) de632ca8b7584411adb15a7e9373f1c4--171e932477734f8796d6808196b756fb e8692e5ad36242ffa03cd2e77a12e9d5 RX(theta₂₃) 171e932477734f8796d6808196b756fb--e8692e5ad36242ffa03cd2e77a12e9d5 f74025292c534c60af9fd143d861d87e X e8692e5ad36242ffa03cd2e77a12e9d5--f74025292c534c60af9fd143d861d87e f74025292c534c60af9fd143d861d87e--600910915b43400faed69833963896c7 17d5c6935d9f4b8ea8124325cf8f1dfd f74025292c534c60af9fd143d861d87e--17d5c6935d9f4b8ea8124325cf8f1dfd 17d5c6935d9f4b8ea8124325cf8f1dfd--c3201d1d6c0d4dc2aed8fa2faba4e25d

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_ae0863235b764a8fa0621318ce181b44 Obs. cluster_a9a54e75f9cc4c3687d1942a53e86cd1 cluster_2595efde5bf64c88a0a392680a036380 Tower Chebyshev FM cluster_8c98903353f546ed81d89431f0095256 Tower Chebyshev FM cluster_dc191d3e77da48cdad6dfffc5fa7db16 HEA dbc1db3458604e9aa1321bbc72811597 0 c62e98cbd2dc47f590498288148ae651 RX(1.0*acos(x)) dbc1db3458604e9aa1321bbc72811597--c62e98cbd2dc47f590498288148ae651 4801113b6b5b4ce7b36c45f0166c7877 1 d1a87a13d5214636a10fc8053883fc2c RX(theta₀) c62e98cbd2dc47f590498288148ae651--d1a87a13d5214636a10fc8053883fc2c ce5c0a352def41799eac0f6f91b1f737 RY(theta₄) d1a87a13d5214636a10fc8053883fc2c--ce5c0a352def41799eac0f6f91b1f737 af62282b648c409f9010201950af0872 RX(theta₈) ce5c0a352def41799eac0f6f91b1f737--af62282b648c409f9010201950af0872 9f3fa769b6f94128b1bbea5e109abd20 af62282b648c409f9010201950af0872--9f3fa769b6f94128b1bbea5e109abd20 badbcadfcbca46ab88bd5c368e888de2 9f3fa769b6f94128b1bbea5e109abd20--badbcadfcbca46ab88bd5c368e888de2 0884e2630a33447490304027fbb4b1e3 RX(theta₁₂) badbcadfcbca46ab88bd5c368e888de2--0884e2630a33447490304027fbb4b1e3 8c770d8f4b174f6fa68373b43356c40c RY(theta₁₆) 0884e2630a33447490304027fbb4b1e3--8c770d8f4b174f6fa68373b43356c40c 786b7b0bab7e44c7ad1345d45e9f8e9e RX(theta₂₀) 8c770d8f4b174f6fa68373b43356c40c--786b7b0bab7e44c7ad1345d45e9f8e9e 6a4dea36fc194a97a9164e26b828c876 786b7b0bab7e44c7ad1345d45e9f8e9e--6a4dea36fc194a97a9164e26b828c876 00e1cd3274d74dd6acef75b38ac0bce1 6a4dea36fc194a97a9164e26b828c876--00e1cd3274d74dd6acef75b38ac0bce1 26913dba9c194996b7438b0153b5d83c 00e1cd3274d74dd6acef75b38ac0bce1--26913dba9c194996b7438b0153b5d83c aa30a8df5a444a198f3bfa88abb6ba49 26913dba9c194996b7438b0153b5d83c--aa30a8df5a444a198f3bfa88abb6ba49 d7f060ab77b446c88780cd0d72e08ded 78200720e53a46c5bd6b67b41e6ffc2e RX(2.0*acos(x)) 4801113b6b5b4ce7b36c45f0166c7877--78200720e53a46c5bd6b67b41e6ffc2e 6d8d1451182e45cb9d81f6ae50f39d5c 2 ef5491c60fd0450d8d75f91c784382de RX(theta₁) 78200720e53a46c5bd6b67b41e6ffc2e--ef5491c60fd0450d8d75f91c784382de c93de726542340f485125031980f780c RY(theta₅) ef5491c60fd0450d8d75f91c784382de--c93de726542340f485125031980f780c 095e5a623f6a46978c57fa86df9035e6 RX(theta₉) c93de726542340f485125031980f780c--095e5a623f6a46978c57fa86df9035e6 4a00be41a26948c587f16aaa1d5d6fd6 X 095e5a623f6a46978c57fa86df9035e6--4a00be41a26948c587f16aaa1d5d6fd6 4a00be41a26948c587f16aaa1d5d6fd6--9f3fa769b6f94128b1bbea5e109abd20 68a1bc20032e47309cd9975cb8c5eb09 4a00be41a26948c587f16aaa1d5d6fd6--68a1bc20032e47309cd9975cb8c5eb09 8fecdc2b565a4686a3ca9051a02e15bf RX(theta₁₃) 68a1bc20032e47309cd9975cb8c5eb09--8fecdc2b565a4686a3ca9051a02e15bf 2683aab6df0f4bd6926aee447abca760 RY(theta₁₇) 8fecdc2b565a4686a3ca9051a02e15bf--2683aab6df0f4bd6926aee447abca760 8da345f80b434d278f7a42bd035b4b66 RX(theta₂₁) 2683aab6df0f4bd6926aee447abca760--8da345f80b434d278f7a42bd035b4b66 047512bcdc4d43bcaf023c7071f0737d X 8da345f80b434d278f7a42bd035b4b66--047512bcdc4d43bcaf023c7071f0737d 047512bcdc4d43bcaf023c7071f0737d--6a4dea36fc194a97a9164e26b828c876 0b6ff8a68a5f4585b554523774640ce3 047512bcdc4d43bcaf023c7071f0737d--0b6ff8a68a5f4585b554523774640ce3 6dcb6091e2b24eb984706e1ba4cc0156 AddBlock 0b6ff8a68a5f4585b554523774640ce3--6dcb6091e2b24eb984706e1ba4cc0156 6dcb6091e2b24eb984706e1ba4cc0156--d7f060ab77b446c88780cd0d72e08ded cb040cde599f4ffd8ebea96b33fc5029 73228e1036954116a3edcbd38ccadb6b RX(1.0*acos(2.0*y - 1.0)) 6d8d1451182e45cb9d81f6ae50f39d5c--73228e1036954116a3edcbd38ccadb6b 51896b4cfea94cae926295ac5aea61ea 3 9bb7aac32b05446584e125cec05bf1c3 RX(theta₂) 73228e1036954116a3edcbd38ccadb6b--9bb7aac32b05446584e125cec05bf1c3 9b8e244a7e8e407e95445706ff58e0f3 RY(theta₆) 9bb7aac32b05446584e125cec05bf1c3--9b8e244a7e8e407e95445706ff58e0f3 06d08f93dbed43b39905f21eaa606a86 RX(theta₁₀) 9b8e244a7e8e407e95445706ff58e0f3--06d08f93dbed43b39905f21eaa606a86 01a12e96312d426fb30d20abd6273cc9 06d08f93dbed43b39905f21eaa606a86--01a12e96312d426fb30d20abd6273cc9 e92866735fd74badbe15a3fa59c839e5 X 01a12e96312d426fb30d20abd6273cc9--e92866735fd74badbe15a3fa59c839e5 e92866735fd74badbe15a3fa59c839e5--68a1bc20032e47309cd9975cb8c5eb09 dbeeb118945b414ebb4da3c3bdf3f175 RX(theta₁₄) e92866735fd74badbe15a3fa59c839e5--dbeeb118945b414ebb4da3c3bdf3f175 e86a4fd5d9694e70b219184ea1119e3d RY(theta₁₈) dbeeb118945b414ebb4da3c3bdf3f175--e86a4fd5d9694e70b219184ea1119e3d 1d65cef339be40668aed292ac8598d4f RX(theta₂₂) e86a4fd5d9694e70b219184ea1119e3d--1d65cef339be40668aed292ac8598d4f 2f60f28836fc48a0891a0a7c95e50644 1d65cef339be40668aed292ac8598d4f--2f60f28836fc48a0891a0a7c95e50644 e8da2b07804843cc92deb523af64a7bd X 2f60f28836fc48a0891a0a7c95e50644--e8da2b07804843cc92deb523af64a7bd e8da2b07804843cc92deb523af64a7bd--0b6ff8a68a5f4585b554523774640ce3 df45b3c277b948cd828d8d2d5a479669 e8da2b07804843cc92deb523af64a7bd--df45b3c277b948cd828d8d2d5a479669 df45b3c277b948cd828d8d2d5a479669--cb040cde599f4ffd8ebea96b33fc5029 fb3c763db0f9466197b2b3f42bc928a0 b007e78f83e24d37a3082779ed648a27 RX(2.0*acos(2.0*y - 1.0)) 51896b4cfea94cae926295ac5aea61ea--b007e78f83e24d37a3082779ed648a27 bd54d43890284fae971623b7b94ac34b RX(theta₃) b007e78f83e24d37a3082779ed648a27--bd54d43890284fae971623b7b94ac34b 264de10a9ca7429694c38799d28fa94f RY(theta₇) bd54d43890284fae971623b7b94ac34b--264de10a9ca7429694c38799d28fa94f 3970ad7064c04bcb968c3a95cf5dd4c3 RX(theta₁₁) 264de10a9ca7429694c38799d28fa94f--3970ad7064c04bcb968c3a95cf5dd4c3 38ccd1062902498f98c8aed2985dd5a2 X 3970ad7064c04bcb968c3a95cf5dd4c3--38ccd1062902498f98c8aed2985dd5a2 38ccd1062902498f98c8aed2985dd5a2--01a12e96312d426fb30d20abd6273cc9 f60f30274f6743829fa7249f57a95200 38ccd1062902498f98c8aed2985dd5a2--f60f30274f6743829fa7249f57a95200 1c92c477b43d4761824d1abad104ab8d RX(theta₁₅) f60f30274f6743829fa7249f57a95200--1c92c477b43d4761824d1abad104ab8d bfc5375aae274d7a8d443575b19c55ea RY(theta₁₉) 1c92c477b43d4761824d1abad104ab8d--bfc5375aae274d7a8d443575b19c55ea f42efe456f7d4227b3222aa7503a2a4c RX(theta₂₃) bfc5375aae274d7a8d443575b19c55ea--f42efe456f7d4227b3222aa7503a2a4c dbecf236706542eab34ccdf2392cd3c2 X f42efe456f7d4227b3222aa7503a2a4c--dbecf236706542eab34ccdf2392cd3c2 dbecf236706542eab34ccdf2392cd3c2--2f60f28836fc48a0891a0a7c95e50644 c6cbaae2830143baa86e36b0af47e8ac dbecf236706542eab34ccdf2392cd3c2--c6cbaae2830143baa86e36b0af47e8ac 0df55ac84b5d422892d7870dd97c5927 c6cbaae2830143baa86e36b0af47e8ac--0df55ac84b5d422892d7870dd97c5927 0df55ac84b5d422892d7870dd97c5927--fb3c763db0f9466197b2b3f42bc928a0