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_b0c933e8bc604df8b77a3ea548ef7064 28da8439862d42bc84a99c15dff43aed 0 41c6494c4e204f33ac17ffcc0a5140ca 28da8439862d42bc84a99c15dff43aed--41c6494c4e204f33ac17ffcc0a5140ca 34e5f529487442e2ace41dca8e500cd9 1 f492162b5ef6469ca8a70cd6d3e50138 41c6494c4e204f33ac17ffcc0a5140ca--f492162b5ef6469ca8a70cd6d3e50138 42174fd028a1416898805909fcf7d060 3c0f67d37ee644aeb7d78e1f0f5ed25c AddBlock 34e5f529487442e2ace41dca8e500cd9--3c0f67d37ee644aeb7d78e1f0f5ed25c bf264b646d134618809c7081b002f75f 2 3c0f67d37ee644aeb7d78e1f0f5ed25c--42174fd028a1416898805909fcf7d060 e9b12a663b48483f9ef1405c67779fb7 2679d404434941868938110b53b6947d bf264b646d134618809c7081b002f75f--2679d404434941868938110b53b6947d b39938dd075a48b4bb6415652d1a3139 3 2679d404434941868938110b53b6947d--e9b12a663b48483f9ef1405c67779fb7 a126e3f14e064c12bff359b4f6d8de7f 0d65b26ff5e342f2b782643f01d5481d b39938dd075a48b4bb6415652d1a3139--0d65b26ff5e342f2b782643f01d5481d 0d65b26ff5e342f2b782643f01d5481d--a126e3f14e064c12bff359b4f6d8de7f

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_d139220ed849475eaafca01c6cfcf406 Tower Chebyshev FM cluster_2ddb1b95c04f43f9abe47d83a6b05441 Tower Chebyshev FM 1dfa59712ffd4c439781a20510a49c60 0 e906e757b7734ddca7239b673987afcd RX(1.0*acos(x)) 1dfa59712ffd4c439781a20510a49c60--e906e757b7734ddca7239b673987afcd 71d9be4208e84e81a6fe69c91d8adb09 1 f131f603fbab4b5b8bea432e4d0f45d7 e906e757b7734ddca7239b673987afcd--f131f603fbab4b5b8bea432e4d0f45d7 61600477880d443b8a5a5a68d5750e38 ccfd612a2ffa46a9a0ddaa27589dd5b4 RX(2.0*acos(x)) 71d9be4208e84e81a6fe69c91d8adb09--ccfd612a2ffa46a9a0ddaa27589dd5b4 8a493606a21d480190e2a395fb7a02fe 2 ccfd612a2ffa46a9a0ddaa27589dd5b4--61600477880d443b8a5a5a68d5750e38 8104be47524e49768bb3cbd647865562 42f37e5f372545d691e1300b42785ede RX(1.0*acos(2.0*y - 1.0)) 8a493606a21d480190e2a395fb7a02fe--42f37e5f372545d691e1300b42785ede a603feddd9c748d8ac66b7a0cadb37f5 3 42f37e5f372545d691e1300b42785ede--8104be47524e49768bb3cbd647865562 3eb1b163ad6443d18bf6f6b79df1376f 2359620bad164f0d9948a6c54fa081ae RX(2.0*acos(2.0*y - 1.0)) a603feddd9c748d8ac66b7a0cadb37f5--2359620bad164f0d9948a6c54fa081ae 2359620bad164f0d9948a6c54fa081ae--3eb1b163ad6443d18bf6f6b79df1376f

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 5bacdb13ff4a4b589bdb6c51c4751571 0 49874c6cca884485b4dec475cd12878e RX(theta₀) 5bacdb13ff4a4b589bdb6c51c4751571--49874c6cca884485b4dec475cd12878e 02275e279a754645ace0d6a1932e0ca2 1 f6114764fcf74b44be637ffe5285dd03 RY(theta₄) 49874c6cca884485b4dec475cd12878e--f6114764fcf74b44be637ffe5285dd03 5f5a442a717640d999688a275b117ed2 RX(theta₈) f6114764fcf74b44be637ffe5285dd03--5f5a442a717640d999688a275b117ed2 d7ce29ae94274c9394e0b6576962265e 5f5a442a717640d999688a275b117ed2--d7ce29ae94274c9394e0b6576962265e 4513ce18dd8f4b6eb3d8733937c8cc59 d7ce29ae94274c9394e0b6576962265e--4513ce18dd8f4b6eb3d8733937c8cc59 cb3cdcb2acdb4d1a873d323ed8045718 RX(theta₁₂) 4513ce18dd8f4b6eb3d8733937c8cc59--cb3cdcb2acdb4d1a873d323ed8045718 cd9e80c695d445d594ebfc38ddc1055b RY(theta₁₆) cb3cdcb2acdb4d1a873d323ed8045718--cd9e80c695d445d594ebfc38ddc1055b 68edca526a2d4e87a2da11844d799732 RX(theta₂₀) cd9e80c695d445d594ebfc38ddc1055b--68edca526a2d4e87a2da11844d799732 04421b52e2e442648ca6ceb92cabb732 68edca526a2d4e87a2da11844d799732--04421b52e2e442648ca6ceb92cabb732 fe7002a9961f45bbb80784c3979651c3 04421b52e2e442648ca6ceb92cabb732--fe7002a9961f45bbb80784c3979651c3 f97bfda232af41fa8abe24ad9a31767e fe7002a9961f45bbb80784c3979651c3--f97bfda232af41fa8abe24ad9a31767e 5bc47a965c564124a6dee5127f890486 f081a02a62684a3293de0e15df83d5e5 RX(theta₁) 02275e279a754645ace0d6a1932e0ca2--f081a02a62684a3293de0e15df83d5e5 c5c050bfb4fd4365a960eb9cfa138ab7 2 5eea16cd301449bb886f76d0287c519b RY(theta₅) f081a02a62684a3293de0e15df83d5e5--5eea16cd301449bb886f76d0287c519b 585d9320a86846e1a8e174af683196a8 RX(theta₉) 5eea16cd301449bb886f76d0287c519b--585d9320a86846e1a8e174af683196a8 027fef9dcca04f56894cf909f67fe9a7 X 585d9320a86846e1a8e174af683196a8--027fef9dcca04f56894cf909f67fe9a7 027fef9dcca04f56894cf909f67fe9a7--d7ce29ae94274c9394e0b6576962265e c110094a11fb4f2fafbf932cc29a70cf 027fef9dcca04f56894cf909f67fe9a7--c110094a11fb4f2fafbf932cc29a70cf a55facd7799343d8be10649822e27f53 RX(theta₁₃) c110094a11fb4f2fafbf932cc29a70cf--a55facd7799343d8be10649822e27f53 5819a34f31a84fb8a3c70f3fc9ca1e31 RY(theta₁₇) a55facd7799343d8be10649822e27f53--5819a34f31a84fb8a3c70f3fc9ca1e31 1477cfc95d1c4537a31c87255e36d1f8 RX(theta₂₁) 5819a34f31a84fb8a3c70f3fc9ca1e31--1477cfc95d1c4537a31c87255e36d1f8 ab5c3263709d4c5aab7c2c232d9f485a X 1477cfc95d1c4537a31c87255e36d1f8--ab5c3263709d4c5aab7c2c232d9f485a ab5c3263709d4c5aab7c2c232d9f485a--04421b52e2e442648ca6ceb92cabb732 ec424c128f90461898fc5115d4556c33 ab5c3263709d4c5aab7c2c232d9f485a--ec424c128f90461898fc5115d4556c33 ec424c128f90461898fc5115d4556c33--5bc47a965c564124a6dee5127f890486 649825fbaf21430bb3dfa569c982ab36 fbeb3ebade1640efa573b0ae04424574 RX(theta₂) c5c050bfb4fd4365a960eb9cfa138ab7--fbeb3ebade1640efa573b0ae04424574 fd9225bdb70445e8acd85610678e2798 3 308d639cf75a4d95a199c2161a07bb40 RY(theta₆) fbeb3ebade1640efa573b0ae04424574--308d639cf75a4d95a199c2161a07bb40 baca2e321d384ef7a47f7d0143100d97 RX(theta₁₀) 308d639cf75a4d95a199c2161a07bb40--baca2e321d384ef7a47f7d0143100d97 78c02692a057418a86cd96095b87d507 baca2e321d384ef7a47f7d0143100d97--78c02692a057418a86cd96095b87d507 f959b66d4e1646ef9dd6dbd7af2a6ffd X 78c02692a057418a86cd96095b87d507--f959b66d4e1646ef9dd6dbd7af2a6ffd f959b66d4e1646ef9dd6dbd7af2a6ffd--c110094a11fb4f2fafbf932cc29a70cf c7e93cdae98d4ba78a64c89f7636bfb8 RX(theta₁₄) f959b66d4e1646ef9dd6dbd7af2a6ffd--c7e93cdae98d4ba78a64c89f7636bfb8 394273f8570f4234988c220fbb832107 RY(theta₁₈) c7e93cdae98d4ba78a64c89f7636bfb8--394273f8570f4234988c220fbb832107 0581713da0b2405f853bf5b84af93932 RX(theta₂₂) 394273f8570f4234988c220fbb832107--0581713da0b2405f853bf5b84af93932 5746ec09ccae4a0bbd50aa03af6c075b 0581713da0b2405f853bf5b84af93932--5746ec09ccae4a0bbd50aa03af6c075b 7e490c64cfc941598bcf715f46a99151 X 5746ec09ccae4a0bbd50aa03af6c075b--7e490c64cfc941598bcf715f46a99151 7e490c64cfc941598bcf715f46a99151--ec424c128f90461898fc5115d4556c33 7e490c64cfc941598bcf715f46a99151--649825fbaf21430bb3dfa569c982ab36 2004b23a36fa4bdbbca906fad9c4d864 b7486466e0db4cd9af2d20f2d0bfb561 RX(theta₃) fd9225bdb70445e8acd85610678e2798--b7486466e0db4cd9af2d20f2d0bfb561 36e25eef0d4c4bd794e0498d1943eb95 RY(theta₇) b7486466e0db4cd9af2d20f2d0bfb561--36e25eef0d4c4bd794e0498d1943eb95 be64254ef7104f0a83109fbfaa90f4e7 RX(theta₁₁) 36e25eef0d4c4bd794e0498d1943eb95--be64254ef7104f0a83109fbfaa90f4e7 764f50ee2bac4f44b6dd8a97857972cf X be64254ef7104f0a83109fbfaa90f4e7--764f50ee2bac4f44b6dd8a97857972cf 764f50ee2bac4f44b6dd8a97857972cf--78c02692a057418a86cd96095b87d507 3c016a169b8644619174d05c84ebad39 764f50ee2bac4f44b6dd8a97857972cf--3c016a169b8644619174d05c84ebad39 81b67206264e45dc821864fcb718e9d6 RX(theta₁₅) 3c016a169b8644619174d05c84ebad39--81b67206264e45dc821864fcb718e9d6 289e77cad6e6470fb8b89493ff06385d RY(theta₁₉) 81b67206264e45dc821864fcb718e9d6--289e77cad6e6470fb8b89493ff06385d 7c6cfcb95c784377b9ae77a63a509e69 RX(theta₂₃) 289e77cad6e6470fb8b89493ff06385d--7c6cfcb95c784377b9ae77a63a509e69 29874b1bbaeb4e47ac35f5e5ce216333 X 7c6cfcb95c784377b9ae77a63a509e69--29874b1bbaeb4e47ac35f5e5ce216333 29874b1bbaeb4e47ac35f5e5ce216333--5746ec09ccae4a0bbd50aa03af6c075b 1ca14c1f7dcb48b994c28bb0a872f5be 29874b1bbaeb4e47ac35f5e5ce216333--1ca14c1f7dcb48b994c28bb0a872f5be 1ca14c1f7dcb48b994c28bb0a872f5be--2004b23a36fa4bdbbca906fad9c4d864

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_787b082e6e0a4287962399ab87a39ba7 Obs. cluster_05c56a24f719412ba518b715122203b9 cluster_2a2bbac8534c4211a789085839a3c68a Tower Chebyshev FM cluster_6d31f54b2f8d407f8479928c114feafd Tower Chebyshev FM cluster_0228a57dd6874c50aea7599dfbd37209 HEA d359d6e5439f4bbca0c6ceb5162f838b 0 5fc01998002d41c9aff98676e440b9bf RX(1.0*acos(x)) d359d6e5439f4bbca0c6ceb5162f838b--5fc01998002d41c9aff98676e440b9bf 34b9559631d24f3ca74f8ffc229fdfb3 1 199d9127f4524716b093c254d5f5a0e9 RX(theta₀) 5fc01998002d41c9aff98676e440b9bf--199d9127f4524716b093c254d5f5a0e9 2aae6520e9934a1fab1427962ffed408 RY(theta₄) 199d9127f4524716b093c254d5f5a0e9--2aae6520e9934a1fab1427962ffed408 271d5dc91a674fbca15ce66c246cfbf0 RX(theta₈) 2aae6520e9934a1fab1427962ffed408--271d5dc91a674fbca15ce66c246cfbf0 f45a2374008b442293c96c77d587a302 271d5dc91a674fbca15ce66c246cfbf0--f45a2374008b442293c96c77d587a302 1ce7798edc09482d9f6517a41934bd9d f45a2374008b442293c96c77d587a302--1ce7798edc09482d9f6517a41934bd9d a19c562f3b7644b3ab5b75f19d3efaf5 RX(theta₁₂) 1ce7798edc09482d9f6517a41934bd9d--a19c562f3b7644b3ab5b75f19d3efaf5 3a5cdec4b66c450590539b81384e40a4 RY(theta₁₆) a19c562f3b7644b3ab5b75f19d3efaf5--3a5cdec4b66c450590539b81384e40a4 cd81d9d0415641158d7dde68222c81d8 RX(theta₂₀) 3a5cdec4b66c450590539b81384e40a4--cd81d9d0415641158d7dde68222c81d8 4405ef4a508d49da90ada7bf40ca628b cd81d9d0415641158d7dde68222c81d8--4405ef4a508d49da90ada7bf40ca628b c30a5e4344e44a13988ca9cb1b7d2364 4405ef4a508d49da90ada7bf40ca628b--c30a5e4344e44a13988ca9cb1b7d2364 ada45497af88401f87912b80dc8b18ef c30a5e4344e44a13988ca9cb1b7d2364--ada45497af88401f87912b80dc8b18ef f1aaec73eba64a5ca24420ed6585563e ada45497af88401f87912b80dc8b18ef--f1aaec73eba64a5ca24420ed6585563e 1ece7777b0474b9cbb13399af7933a27 2c35d6d8143c44428f702b47cb3d420f RX(2.0*acos(x)) 34b9559631d24f3ca74f8ffc229fdfb3--2c35d6d8143c44428f702b47cb3d420f f19d8aec776c453c9001303cf68faf61 2 54efd96d2d9e4846abd5df983b08ec46 RX(theta₁) 2c35d6d8143c44428f702b47cb3d420f--54efd96d2d9e4846abd5df983b08ec46 0e25929ef27449eab01f4689f91902ff RY(theta₅) 54efd96d2d9e4846abd5df983b08ec46--0e25929ef27449eab01f4689f91902ff 7de7fd1168d64856a77b5a9766f8b0d6 RX(theta₉) 0e25929ef27449eab01f4689f91902ff--7de7fd1168d64856a77b5a9766f8b0d6 9592a904a4324e6585e94326c0dc55ac X 7de7fd1168d64856a77b5a9766f8b0d6--9592a904a4324e6585e94326c0dc55ac 9592a904a4324e6585e94326c0dc55ac--f45a2374008b442293c96c77d587a302 d2923bed73474a4d9ef4bd09ae1ba9df 9592a904a4324e6585e94326c0dc55ac--d2923bed73474a4d9ef4bd09ae1ba9df 4568cc92bdf84e4e80d674fa1173d132 RX(theta₁₃) d2923bed73474a4d9ef4bd09ae1ba9df--4568cc92bdf84e4e80d674fa1173d132 04d9faa2e05d4b50a507b7465879f6ed RY(theta₁₇) 4568cc92bdf84e4e80d674fa1173d132--04d9faa2e05d4b50a507b7465879f6ed 91bc9a6f3ca444269d9d7424366b508f RX(theta₂₁) 04d9faa2e05d4b50a507b7465879f6ed--91bc9a6f3ca444269d9d7424366b508f d10bb131a2424817bce5caec1cbe2bc8 X 91bc9a6f3ca444269d9d7424366b508f--d10bb131a2424817bce5caec1cbe2bc8 d10bb131a2424817bce5caec1cbe2bc8--4405ef4a508d49da90ada7bf40ca628b e0faeeb2bb6a4459939d183096fe538a d10bb131a2424817bce5caec1cbe2bc8--e0faeeb2bb6a4459939d183096fe538a 5bf7dd49e6d74ccea388fb30bf918161 AddBlock e0faeeb2bb6a4459939d183096fe538a--5bf7dd49e6d74ccea388fb30bf918161 5bf7dd49e6d74ccea388fb30bf918161--1ece7777b0474b9cbb13399af7933a27 7b365df54f594a0cbc8201391c86fa5b 3011e31d09614f9c9eb621f11f1832a8 RX(1.0*acos(2.0*y - 1.0)) f19d8aec776c453c9001303cf68faf61--3011e31d09614f9c9eb621f11f1832a8 6bb8beebea1740cfb27fcfdeee5dd513 3 e57c32648c9849228d4c122dda6d6891 RX(theta₂) 3011e31d09614f9c9eb621f11f1832a8--e57c32648c9849228d4c122dda6d6891 26d564478c1645c4a5df39afe8797091 RY(theta₆) e57c32648c9849228d4c122dda6d6891--26d564478c1645c4a5df39afe8797091 96cae7f9c79d438f92362953477079ac RX(theta₁₀) 26d564478c1645c4a5df39afe8797091--96cae7f9c79d438f92362953477079ac 29deea775991465381ab4fe930ab9759 96cae7f9c79d438f92362953477079ac--29deea775991465381ab4fe930ab9759 97e7440ab71a4040bd9b91e2d39ae74a X 29deea775991465381ab4fe930ab9759--97e7440ab71a4040bd9b91e2d39ae74a 97e7440ab71a4040bd9b91e2d39ae74a--d2923bed73474a4d9ef4bd09ae1ba9df 85944bb2e98f42388ae76849d124da95 RX(theta₁₄) 97e7440ab71a4040bd9b91e2d39ae74a--85944bb2e98f42388ae76849d124da95 79dad16f65944a209cd19d9f5468ea00 RY(theta₁₈) 85944bb2e98f42388ae76849d124da95--79dad16f65944a209cd19d9f5468ea00 e7bbb54816d543d2a08f542c20143a80 RX(theta₂₂) 79dad16f65944a209cd19d9f5468ea00--e7bbb54816d543d2a08f542c20143a80 70723447dab9413a8df8292e09ec18d0 e7bbb54816d543d2a08f542c20143a80--70723447dab9413a8df8292e09ec18d0 4dac7df66e7a4c51b1e24f6e54b59eff X 70723447dab9413a8df8292e09ec18d0--4dac7df66e7a4c51b1e24f6e54b59eff 4dac7df66e7a4c51b1e24f6e54b59eff--e0faeeb2bb6a4459939d183096fe538a c93a759f81ff47b78807233cbeb2f14b 4dac7df66e7a4c51b1e24f6e54b59eff--c93a759f81ff47b78807233cbeb2f14b c93a759f81ff47b78807233cbeb2f14b--7b365df54f594a0cbc8201391c86fa5b 14acd5a9e8e548abbba7f4750bd5ca3d e126ae63b6884cad9e22f0fcfc78e247 RX(2.0*acos(2.0*y - 1.0)) 6bb8beebea1740cfb27fcfdeee5dd513--e126ae63b6884cad9e22f0fcfc78e247 a76065ce056c46b5b35d084c87167f76 RX(theta₃) e126ae63b6884cad9e22f0fcfc78e247--a76065ce056c46b5b35d084c87167f76 00a2b8a6785f45328149868b18ddbe33 RY(theta₇) a76065ce056c46b5b35d084c87167f76--00a2b8a6785f45328149868b18ddbe33 ce62abe739cf4fc18a1a8e0ef492da44 RX(theta₁₁) 00a2b8a6785f45328149868b18ddbe33--ce62abe739cf4fc18a1a8e0ef492da44 d4fefef7355c4dba94165a59001d92d0 X ce62abe739cf4fc18a1a8e0ef492da44--d4fefef7355c4dba94165a59001d92d0 d4fefef7355c4dba94165a59001d92d0--29deea775991465381ab4fe930ab9759 25d8e192b82f4d7c9f2d1421b67fa0d4 d4fefef7355c4dba94165a59001d92d0--25d8e192b82f4d7c9f2d1421b67fa0d4 523ab97bae4c4d6a98d0467fb78ed0f0 RX(theta₁₅) 25d8e192b82f4d7c9f2d1421b67fa0d4--523ab97bae4c4d6a98d0467fb78ed0f0 da1f29f550ed4d4ca40897a4f2d8eb4c RY(theta₁₉) 523ab97bae4c4d6a98d0467fb78ed0f0--da1f29f550ed4d4ca40897a4f2d8eb4c 931c55974eb443be9b01af53185474e9 RX(theta₂₃) da1f29f550ed4d4ca40897a4f2d8eb4c--931c55974eb443be9b01af53185474e9 d15f976754334ebd92d81f806141784b X 931c55974eb443be9b01af53185474e9--d15f976754334ebd92d81f806141784b d15f976754334ebd92d81f806141784b--70723447dab9413a8df8292e09ec18d0 0837a75b45c24251a83f4db2a7ca8629 d15f976754334ebd92d81f806141784b--0837a75b45c24251a83f4db2a7ca8629 698babef224e41cda07f10bbdd11f742 0837a75b45c24251a83f4db2a7ca8629--698babef224e41cda07f10bbdd11f742 698babef224e41cda07f10bbdd11f742--14acd5a9e8e548abbba7f4750bd5ca3d