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_5494a90ec1694321a337117f93f40a38 ddf71264887348ce8067fcf69024808d 0 77b41d03fd5e4e68bfa97c1eb332490d ddf71264887348ce8067fcf69024808d--77b41d03fd5e4e68bfa97c1eb332490d 81f5c330837e4ee7899f4c2ac06525ef 1 ed4260eaeacf4143b4d16e403f99e665 77b41d03fd5e4e68bfa97c1eb332490d--ed4260eaeacf4143b4d16e403f99e665 7df41e26984547d38a069a13260f5268 5faa58767d0346a6ac6d1b3b8e2fc493 AddBlock 81f5c330837e4ee7899f4c2ac06525ef--5faa58767d0346a6ac6d1b3b8e2fc493 d94b51eab3a9405ca1d12d659b4f2be4 2 5faa58767d0346a6ac6d1b3b8e2fc493--7df41e26984547d38a069a13260f5268 c0d776264f9f4d2abdd60c3300fdbf18 55e38324d5e04be3ae6a6e0138a740d0 d94b51eab3a9405ca1d12d659b4f2be4--55e38324d5e04be3ae6a6e0138a740d0 3f8790438a1a428d8482c17028956a1f 3 55e38324d5e04be3ae6a6e0138a740d0--c0d776264f9f4d2abdd60c3300fdbf18 ae1fb3f0e1c54829ada8a1f7cf412825 632b3ec502c441638ddf6521c37f47b5 3f8790438a1a428d8482c17028956a1f--632b3ec502c441638ddf6521c37f47b5 632b3ec502c441638ddf6521c37f47b5--ae1fb3f0e1c54829ada8a1f7cf412825

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_c87eacc604d646b2bc5e103d06fcf56d Tower Chebyshev FM cluster_531cb9d8795547b8bad89732f9e396a1 Tower Chebyshev FM 99e76e13d9304104b11dc175f2dd38c1 0 6982d63b03984f04b04c25ae4135c822 RX(1.0*acos(x)) 99e76e13d9304104b11dc175f2dd38c1--6982d63b03984f04b04c25ae4135c822 edf4aaca40ef4eceb07287775e83a60c 1 5537a7c016e8436fa2e938b2d96ca63e 6982d63b03984f04b04c25ae4135c822--5537a7c016e8436fa2e938b2d96ca63e a2fdd26d5d1545f78a5b04b8a7f609ca 37669bd8e1da4b8f8f7ea7a93b82f8ab RX(2.0*acos(x)) edf4aaca40ef4eceb07287775e83a60c--37669bd8e1da4b8f8f7ea7a93b82f8ab 3a9bfe6e34fc45dd854109786bb9aa61 2 37669bd8e1da4b8f8f7ea7a93b82f8ab--a2fdd26d5d1545f78a5b04b8a7f609ca 6ad7258b4be84b8881f4b8a49b5a0cb7 aee0c34a549f47c88a918ce4e8c16d7c RX(1.0*acos(2.0*y - 1.0)) 3a9bfe6e34fc45dd854109786bb9aa61--aee0c34a549f47c88a918ce4e8c16d7c 1a301d16073c4051aa7dac0df25d3cdd 3 aee0c34a549f47c88a918ce4e8c16d7c--6ad7258b4be84b8881f4b8a49b5a0cb7 b614b90b7a7a44e3aaeb15273011509a 8a8f0a9297724b94ba797a01312a0495 RX(2.0*acos(2.0*y - 1.0)) 1a301d16073c4051aa7dac0df25d3cdd--8a8f0a9297724b94ba797a01312a0495 8a8f0a9297724b94ba797a01312a0495--b614b90b7a7a44e3aaeb15273011509a

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 78d434a23f2f4c2db0f7958c4e776877 0 9586e1f52a214343b89e8df4247e9ff4 RX(theta₀) 78d434a23f2f4c2db0f7958c4e776877--9586e1f52a214343b89e8df4247e9ff4 e7cf036610c244549871152d5be104d9 1 01581f7b2d1c468799aa9a8531282145 RY(theta₄) 9586e1f52a214343b89e8df4247e9ff4--01581f7b2d1c468799aa9a8531282145 cde417bc343747959ab40cfb9c6c7182 RX(theta₈) 01581f7b2d1c468799aa9a8531282145--cde417bc343747959ab40cfb9c6c7182 d5338ba598f842be886db0c4ece31825 cde417bc343747959ab40cfb9c6c7182--d5338ba598f842be886db0c4ece31825 8fc82c6f372549aca9da2eb93e9ba649 d5338ba598f842be886db0c4ece31825--8fc82c6f372549aca9da2eb93e9ba649 4f9782d9f8264f6f9475183dd159ceb8 RX(theta₁₂) 8fc82c6f372549aca9da2eb93e9ba649--4f9782d9f8264f6f9475183dd159ceb8 677378f6e14049b2be73fa819fe60399 RY(theta₁₆) 4f9782d9f8264f6f9475183dd159ceb8--677378f6e14049b2be73fa819fe60399 1b889760015a4c11b4400a8dc0de5f84 RX(theta₂₀) 677378f6e14049b2be73fa819fe60399--1b889760015a4c11b4400a8dc0de5f84 6a61106933c44c9fa2f2ad8daf976a7e 1b889760015a4c11b4400a8dc0de5f84--6a61106933c44c9fa2f2ad8daf976a7e e289e2f3fd52424da70c7114ad1752ac 6a61106933c44c9fa2f2ad8daf976a7e--e289e2f3fd52424da70c7114ad1752ac 5fe413aaaa754527ae15d6f5cd766028 e289e2f3fd52424da70c7114ad1752ac--5fe413aaaa754527ae15d6f5cd766028 b7eb81185c714cab929d4c89843b5c72 0c877cb610a04a199351a75a322d1bd2 RX(theta₁) e7cf036610c244549871152d5be104d9--0c877cb610a04a199351a75a322d1bd2 04a6406e0cef4737aedac66211775a70 2 77d870bd393d4697a4b73942eb71e9d1 RY(theta₅) 0c877cb610a04a199351a75a322d1bd2--77d870bd393d4697a4b73942eb71e9d1 571e850ecbe14e52ace48008786b62f8 RX(theta₉) 77d870bd393d4697a4b73942eb71e9d1--571e850ecbe14e52ace48008786b62f8 982a43d8344e4c6695941769f3198ffd X 571e850ecbe14e52ace48008786b62f8--982a43d8344e4c6695941769f3198ffd 982a43d8344e4c6695941769f3198ffd--d5338ba598f842be886db0c4ece31825 06e93686cb724c209b4509bcc9c75a7b 982a43d8344e4c6695941769f3198ffd--06e93686cb724c209b4509bcc9c75a7b c3be5ac4821f4c49ba34ecac8e15b88d RX(theta₁₃) 06e93686cb724c209b4509bcc9c75a7b--c3be5ac4821f4c49ba34ecac8e15b88d edab2e7978404c87abdd6bd5e8282312 RY(theta₁₇) c3be5ac4821f4c49ba34ecac8e15b88d--edab2e7978404c87abdd6bd5e8282312 e84e39adad52418dbeef4f9e732a37cf RX(theta₂₁) edab2e7978404c87abdd6bd5e8282312--e84e39adad52418dbeef4f9e732a37cf 4b47890673424653b0d44f591b53400b X e84e39adad52418dbeef4f9e732a37cf--4b47890673424653b0d44f591b53400b 4b47890673424653b0d44f591b53400b--6a61106933c44c9fa2f2ad8daf976a7e 117790389a1242dd919b3128d9111e64 4b47890673424653b0d44f591b53400b--117790389a1242dd919b3128d9111e64 117790389a1242dd919b3128d9111e64--b7eb81185c714cab929d4c89843b5c72 5c636bc94e8e4ca4a8fe0ef9088ef6b5 688e0e21e5fc43078c59f8737b710a8d RX(theta₂) 04a6406e0cef4737aedac66211775a70--688e0e21e5fc43078c59f8737b710a8d 527b8f7bdf1b483f83da926a642f3101 3 54c1ce7388cf4bda9daa23e766da57a8 RY(theta₆) 688e0e21e5fc43078c59f8737b710a8d--54c1ce7388cf4bda9daa23e766da57a8 7f14e1da3d6e42c3a14129642fe91cab RX(theta₁₀) 54c1ce7388cf4bda9daa23e766da57a8--7f14e1da3d6e42c3a14129642fe91cab dba5a0d7883f4e4bbe5a49a80920558b 7f14e1da3d6e42c3a14129642fe91cab--dba5a0d7883f4e4bbe5a49a80920558b 84b8464ecab14d819277e50629d2f4b5 X dba5a0d7883f4e4bbe5a49a80920558b--84b8464ecab14d819277e50629d2f4b5 84b8464ecab14d819277e50629d2f4b5--06e93686cb724c209b4509bcc9c75a7b 2a9d68027f78408f89f32bf9e9bc6b5a RX(theta₁₄) 84b8464ecab14d819277e50629d2f4b5--2a9d68027f78408f89f32bf9e9bc6b5a d465a659cb114e44ba1696637be106bb RY(theta₁₈) 2a9d68027f78408f89f32bf9e9bc6b5a--d465a659cb114e44ba1696637be106bb 249c116a5b8347cca41fb1a68ed2c070 RX(theta₂₂) d465a659cb114e44ba1696637be106bb--249c116a5b8347cca41fb1a68ed2c070 494a73b50894429ab1646a30dfe4dea6 249c116a5b8347cca41fb1a68ed2c070--494a73b50894429ab1646a30dfe4dea6 087b726e749640e195747e312f4d4351 X 494a73b50894429ab1646a30dfe4dea6--087b726e749640e195747e312f4d4351 087b726e749640e195747e312f4d4351--117790389a1242dd919b3128d9111e64 087b726e749640e195747e312f4d4351--5c636bc94e8e4ca4a8fe0ef9088ef6b5 a386ab1bf0fc4a03be0c58839a5b7310 5addec61c87b41998db097dd1ba7b29b RX(theta₃) 527b8f7bdf1b483f83da926a642f3101--5addec61c87b41998db097dd1ba7b29b 8d192309ebed4a5bb02bcc2b569f7be1 RY(theta₇) 5addec61c87b41998db097dd1ba7b29b--8d192309ebed4a5bb02bcc2b569f7be1 9752fe796d134a3ba461e4f26a829cb6 RX(theta₁₁) 8d192309ebed4a5bb02bcc2b569f7be1--9752fe796d134a3ba461e4f26a829cb6 17fd39d9756f43f18613389e290520a8 X 9752fe796d134a3ba461e4f26a829cb6--17fd39d9756f43f18613389e290520a8 17fd39d9756f43f18613389e290520a8--dba5a0d7883f4e4bbe5a49a80920558b 9ad31f6d59074bb18dacd1b1435790f0 17fd39d9756f43f18613389e290520a8--9ad31f6d59074bb18dacd1b1435790f0 fc2763d1dfc34a409e424ff90fa1cbbf RX(theta₁₅) 9ad31f6d59074bb18dacd1b1435790f0--fc2763d1dfc34a409e424ff90fa1cbbf 26cdfd0cea77404aa174020ce31ef670 RY(theta₁₉) fc2763d1dfc34a409e424ff90fa1cbbf--26cdfd0cea77404aa174020ce31ef670 ebc9ee42532644dcae3225fa9ed2babe RX(theta₂₃) 26cdfd0cea77404aa174020ce31ef670--ebc9ee42532644dcae3225fa9ed2babe 89f61cb9c0df4289974ed37ffded6314 X ebc9ee42532644dcae3225fa9ed2babe--89f61cb9c0df4289974ed37ffded6314 89f61cb9c0df4289974ed37ffded6314--494a73b50894429ab1646a30dfe4dea6 8f7d24130da84900b9e74e473f21500b 89f61cb9c0df4289974ed37ffded6314--8f7d24130da84900b9e74e473f21500b 8f7d24130da84900b9e74e473f21500b--a386ab1bf0fc4a03be0c58839a5b7310

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_53a35136cc3441089778641affdd29ab Obs. cluster_e1c3231656d4427d837fee8d83f79fec cluster_c97301c6faea4fc790290716c094a9e8 Tower Chebyshev FM cluster_e1ec426753a24df493fde9bcf6b6dae9 Tower Chebyshev FM cluster_e84ab7d334f44d109492f51a7369b677 HEA 60296c19918e42cb8fd68e97feb72550 0 06de0a641df248589fd27e928b88f638 RX(1.0*acos(x)) 60296c19918e42cb8fd68e97feb72550--06de0a641df248589fd27e928b88f638 ce5a10b55343400186eb762eb8701cef 1 7391ba85e58d438c85e4ff6e9ec10b1c RX(theta₀) 06de0a641df248589fd27e928b88f638--7391ba85e58d438c85e4ff6e9ec10b1c 7b0a99ab04364122b424a24fdd7e18c3 RY(theta₄) 7391ba85e58d438c85e4ff6e9ec10b1c--7b0a99ab04364122b424a24fdd7e18c3 d89d3f76d2994cf99c07be24dd17ea3e RX(theta₈) 7b0a99ab04364122b424a24fdd7e18c3--d89d3f76d2994cf99c07be24dd17ea3e 356b85c521bf4331a433e2f9ce4a0bda d89d3f76d2994cf99c07be24dd17ea3e--356b85c521bf4331a433e2f9ce4a0bda 510db57339264bbd8cf9122c48b994a2 356b85c521bf4331a433e2f9ce4a0bda--510db57339264bbd8cf9122c48b994a2 5af1087ae314444789d38b1d99cfc361 RX(theta₁₂) 510db57339264bbd8cf9122c48b994a2--5af1087ae314444789d38b1d99cfc361 e1fa8738760e42ea921e78ca9f24a67d RY(theta₁₆) 5af1087ae314444789d38b1d99cfc361--e1fa8738760e42ea921e78ca9f24a67d 34bf9f739b7a4e5484637796f2b4399e RX(theta₂₀) e1fa8738760e42ea921e78ca9f24a67d--34bf9f739b7a4e5484637796f2b4399e 6898a666737240af8c268f704460398b 34bf9f739b7a4e5484637796f2b4399e--6898a666737240af8c268f704460398b 0f4c3111adc14f86824aab198be189e5 6898a666737240af8c268f704460398b--0f4c3111adc14f86824aab198be189e5 f4c6c15ab38e4e6fac3d91595b9c36cb 0f4c3111adc14f86824aab198be189e5--f4c6c15ab38e4e6fac3d91595b9c36cb 8f3af29c578b40dc8549956b31c6712c f4c6c15ab38e4e6fac3d91595b9c36cb--8f3af29c578b40dc8549956b31c6712c 2a42b193fb834441aac97a89bb23822c 4e30da2b06774557adf1b916bbcb1019 RX(2.0*acos(x)) ce5a10b55343400186eb762eb8701cef--4e30da2b06774557adf1b916bbcb1019 b32c7e468682425b9817f80cb4611958 2 55ba8e46d4c94548a6979d6a250e2c47 RX(theta₁) 4e30da2b06774557adf1b916bbcb1019--55ba8e46d4c94548a6979d6a250e2c47 84181e1ab77a4bed80cd97e2bfb65db4 RY(theta₅) 55ba8e46d4c94548a6979d6a250e2c47--84181e1ab77a4bed80cd97e2bfb65db4 ef84ac459d694d89bb42768e5fc2b051 RX(theta₉) 84181e1ab77a4bed80cd97e2bfb65db4--ef84ac459d694d89bb42768e5fc2b051 7044e787614f42f3b30592418df5cb67 X ef84ac459d694d89bb42768e5fc2b051--7044e787614f42f3b30592418df5cb67 7044e787614f42f3b30592418df5cb67--356b85c521bf4331a433e2f9ce4a0bda b883d8f5e5c743549af8d019e7346285 7044e787614f42f3b30592418df5cb67--b883d8f5e5c743549af8d019e7346285 2c2a66611ca94769ba8115d2d4e0f4f0 RX(theta₁₃) b883d8f5e5c743549af8d019e7346285--2c2a66611ca94769ba8115d2d4e0f4f0 574d1319081d47e3b5ea823d5326a50c RY(theta₁₇) 2c2a66611ca94769ba8115d2d4e0f4f0--574d1319081d47e3b5ea823d5326a50c 61918c53a4b945c580ed85854a8b3d25 RX(theta₂₁) 574d1319081d47e3b5ea823d5326a50c--61918c53a4b945c580ed85854a8b3d25 701a201322ad4dd4a196827cc7fd33d1 X 61918c53a4b945c580ed85854a8b3d25--701a201322ad4dd4a196827cc7fd33d1 701a201322ad4dd4a196827cc7fd33d1--6898a666737240af8c268f704460398b ab4f2b2127734c12867ec43479db0590 701a201322ad4dd4a196827cc7fd33d1--ab4f2b2127734c12867ec43479db0590 95a33f8e76a84c2e8b30259460ecd448 AddBlock ab4f2b2127734c12867ec43479db0590--95a33f8e76a84c2e8b30259460ecd448 95a33f8e76a84c2e8b30259460ecd448--2a42b193fb834441aac97a89bb23822c 2e0d6e62b9794b14a5f91603892c2f76 ed4d4c47e4ac4684ac5a0b97db51f982 RX(1.0*acos(2.0*y - 1.0)) b32c7e468682425b9817f80cb4611958--ed4d4c47e4ac4684ac5a0b97db51f982 be0846ce14b94a9288f1a1ae35c365f8 3 b583119851454e1e944c96f617d9c074 RX(theta₂) ed4d4c47e4ac4684ac5a0b97db51f982--b583119851454e1e944c96f617d9c074 c1cdf47b7cc7421eaa03edd4bf11814d RY(theta₆) b583119851454e1e944c96f617d9c074--c1cdf47b7cc7421eaa03edd4bf11814d fabbc32f1f99410a8e12cf99d9cfab9b RX(theta₁₀) c1cdf47b7cc7421eaa03edd4bf11814d--fabbc32f1f99410a8e12cf99d9cfab9b ffacbc2cc24c495db6090ec23c5b2270 fabbc32f1f99410a8e12cf99d9cfab9b--ffacbc2cc24c495db6090ec23c5b2270 756941dba6d3495ba486cf8f89981019 X ffacbc2cc24c495db6090ec23c5b2270--756941dba6d3495ba486cf8f89981019 756941dba6d3495ba486cf8f89981019--b883d8f5e5c743549af8d019e7346285 154703dbde044f5ea0edc455e9ad899b RX(theta₁₄) 756941dba6d3495ba486cf8f89981019--154703dbde044f5ea0edc455e9ad899b 486b30712af2408aaee14d103dade321 RY(theta₁₈) 154703dbde044f5ea0edc455e9ad899b--486b30712af2408aaee14d103dade321 cb2e4b72c28b447bbe0c2124c6dfe538 RX(theta₂₂) 486b30712af2408aaee14d103dade321--cb2e4b72c28b447bbe0c2124c6dfe538 7a776f55708e4479a5fd95303edccc10 cb2e4b72c28b447bbe0c2124c6dfe538--7a776f55708e4479a5fd95303edccc10 d5c4d0cc18c640b1a34e13dd8ca1e9e2 X 7a776f55708e4479a5fd95303edccc10--d5c4d0cc18c640b1a34e13dd8ca1e9e2 d5c4d0cc18c640b1a34e13dd8ca1e9e2--ab4f2b2127734c12867ec43479db0590 842cb5ee7d7947baae7a7e02550d4591 d5c4d0cc18c640b1a34e13dd8ca1e9e2--842cb5ee7d7947baae7a7e02550d4591 842cb5ee7d7947baae7a7e02550d4591--2e0d6e62b9794b14a5f91603892c2f76 ab229f8268664f0b9709613901505a47 5f985b1e05be4654b12b830027bf395c RX(2.0*acos(2.0*y - 1.0)) be0846ce14b94a9288f1a1ae35c365f8--5f985b1e05be4654b12b830027bf395c 42e13c563c334b299f1394799f7505d7 RX(theta₃) 5f985b1e05be4654b12b830027bf395c--42e13c563c334b299f1394799f7505d7 5017e072e5b641678527f6554bfef512 RY(theta₇) 42e13c563c334b299f1394799f7505d7--5017e072e5b641678527f6554bfef512 dbaa3e3efcc54743a8ee2761b110c692 RX(theta₁₁) 5017e072e5b641678527f6554bfef512--dbaa3e3efcc54743a8ee2761b110c692 8d8cf651d5b94c399dfdc188356c4148 X dbaa3e3efcc54743a8ee2761b110c692--8d8cf651d5b94c399dfdc188356c4148 8d8cf651d5b94c399dfdc188356c4148--ffacbc2cc24c495db6090ec23c5b2270 96210a58d82b49c99ef03e1b9f2243d5 8d8cf651d5b94c399dfdc188356c4148--96210a58d82b49c99ef03e1b9f2243d5 3d6d1436cf7c4ae4bd77a7362db1fcc7 RX(theta₁₅) 96210a58d82b49c99ef03e1b9f2243d5--3d6d1436cf7c4ae4bd77a7362db1fcc7 38d2c165b1b44bb98b45ba929acc2079 RY(theta₁₉) 3d6d1436cf7c4ae4bd77a7362db1fcc7--38d2c165b1b44bb98b45ba929acc2079 7af0e6abc3a2475aa766e2ee279828c4 RX(theta₂₃) 38d2c165b1b44bb98b45ba929acc2079--7af0e6abc3a2475aa766e2ee279828c4 3c31793de13d4528b1c9bdb0b603f7a3 X 7af0e6abc3a2475aa766e2ee279828c4--3c31793de13d4528b1c9bdb0b603f7a3 3c31793de13d4528b1c9bdb0b603f7a3--7a776f55708e4479a5fd95303edccc10 4f536b42613644b89177bad5f8b1d455 3c31793de13d4528b1c9bdb0b603f7a3--4f536b42613644b89177bad5f8b1d455 c5bbafbe626646ef96c29671bece7c03 4f536b42613644b89177bad5f8b1d455--c5bbafbe626646ef96c29671bece7c03 c5bbafbe626646ef96c29671bece7c03--ab229f8268664f0b9709613901505a47