.. _embedding_sdk:

===============
Minor-Embedding 
===============

To solve an arbitrarily posed binary quadratic problem directly on a D-Wave
system requires mapping, called *minor embedding*, to the :ref:`topology_sdk` 
of the system's quantum processing unit (QPU). This preprocessing can be done 
by a composed sampler consisting of the 
:class:`~dwave.system.samplers.DWaveSampler()` and a composite that performs 
minor-embedding. (This step is handled automatically by 
:class:`~dwave.system.samplers.LeapHybridSampler()` and 
:doc:`dwave-hybrid </docs_hybrid/sdk_index>` reference samplers.)

For example, a simple two-variable :term:`bqm`,

.. math::

    E(\bf{s}) = - s_0 s_1
    \qquad\qquad s_i\in\{-1,+1\}

might be embedded to two connected qubits, such as 1929 and 1801 on a 
D-Wave 2000Q system:

.. figure:: ../_images/embedding_2var2qubits.png
	:align: left
	:name: Embedding2var2qubits
	:scale: 60 %
	:alt: Two-variable problem embedded into two qubits.

	Two-variable problem, shown on the left as a graph, is embedded in two connected qubits on a D-Wave 2000Q, shown on the right against the Chimera topology. Variable :math:`s_1`, highlighted in dark magenta, is represented by qubit number 1929 and variable :math:`s_0` is represented by qubit 1801. (This and similar images in this section are generated by Ocean's :doc:`problem inspector </docs_inspector/sdk_index>` tool.

In the D-Wave 2000Q :term:`Chimera` topology, most qubits are conencted
to six other qubits, so other valid minor-embeddings might be 
:math:`s_1=1929, s_0=1933` or :math:`s_0=1801, s_0=1807` 
or :math:`s_0=0, s_1=4`.

Chains
------

Larger problems often require chains because the 
:doc:`QPU topology <oceandocs:concepts/topology>` is not fully connected. 

For example, a fully-conected :math:`K_3` three-variable :term:`bqm`,

.. math::

    E(\bf{s}) = - s_0 s_1 + s_0 s_2 + s_1 s_2
    \qquad\qquad s_i\in\{-1,+1\}

cannot be represented by three qubits in the :term:`Chimera` topology---a
:math:`K_3` graph is not native to the Chimera graph. (Look at the Chimera 
"unit cell" shown in the :ref:`topology_sdk` section and notice there is no 
way to connect three qubits in a closed loop to form a triangle graph.)

Instead, a variable is represented by a *chain* of physical qubits:


.. figure:: ../_images/embedding_3var4qubits.png
	:align: left
	:name: Embedding3var4qubits
	:scale: 60 %
	:alt: Three-variable fully-connected problem embedded into four qubits.

	Three-variable :math:`K_3` fully-connected problem, shown on the left as a graph, is embedded in four qubits on a D-Wave 2000Q, shown on the right against the Chimera topology. Variable :math:`s_0`, highlighted in dark magenta, is represented by two qubits, numbers 251 and 253. 

The embedding above was derived from the hueristic used by 
:class:`~dwave.system.composites.EmbeddingComposite()`
on the working graph of a D-Wave 2000Q selected by :class:`~dwave.system.samplers.DWaveSampler()`: 

.. code-block:: python

   sampler = EmbeddingComposite(DWaveSampler()) 

Other qubits might have been chosen; for example, 

.. code-block:: python

   sampler = FixedEmbeddingComposite(DWaveSampler(solver={'qpu': True}),  
                  embedding={'s0': [0, 4, 7], 's1': [2], 's2': [3, 6]})

intentionally sets the embedding shown below to represent this same :math:`K_3` graph:

 .. figure:: ../_images/embedding_3var6qubits.png
	:align: left
	:name: Embedding3var6qubits
	:scale: 60 %
	:alt: Three-variable fully-connected problem embedded into six qubits.

	Three-variable :math:`K_3` fully-connected problem is embedded in six qubits on a D-Wave 2000Q. Variable :math:`s_0`, highlighted in dark magenta, is represented by three qubits, numbers 0, 4, and 7; Variable :math:`s_2` is represented by two qubits, numbers 3 and 6, shown with their connecting edge emphasized (and displaying a solution of :math:`+1`).

.. _concepts__chain_strength:

Chain Strength
--------------

For a chain of qubits to represent a variable, all its constituent qubits must return the 
same value for a sample. This is accomplished by setting a strong coupling to the edges
connecting these qubits. For the solutions shown above to the :math:`K_3` problem, the
default chain strength achieved identical values and the qubit chains properly represented
the variables of the problem.

However, that is not always the case. For the qubits in a chain to be likely to return identical 
values, the coupling strength for their connecting edges must be strong compared to 
the coupling with other qubits that influence non-identical outcomes.

For example, another three-variable :math:`K_3` fully-connected BQM,

.. math::

    E(\bf{s}) = - s_0 s_1 - s_0 s_2 + s_1 s_2
    \qquad\qquad s_i\in\{-1,+1\}

might be embedded on a D-Wave 2000Q QPU by representing one variable with two
qubits, for example:

.. code-block:: python

   sampler = FixedEmbeddingComposite(DWaveSampler(solver={'qpu': True}),  
                  embedding={'s0': [0, 4], 's1': [2], 's2': [7]})

This BQM has six ground states (best solutions). These are shown below---solved
by brute-force stepping through all possible configurations of values for the 
variables---with lowest energy of -1.0:

>>> bqm = dimod.BQM({}, {('s0', 's1'): -1, ('s0', 's2'): -1, ('s1', 's2'): 1}, 
...                      0, dimod.Vartype.SPIN)
>>> print(dimod.ExactSolver().sample(bqm))  # doctest: +SKIP
  s0 s1 s2 energy num_oc.
0 -1 -1 -1   -1.0       1
2 +1 +1 -1   -1.0       1
3 -1 +1 -1   -1.0       1
5 +1 +1 +1   -1.0       1
6 +1 -1 +1   -1.0       1
7 -1 -1 +1   -1.0       1
1 +1 -1 -1    3.0       1
4 -1 +1 +1    3.0       1
['SPIN', 8 rows, 8 samples, 3 variables]

In this case, solving on a quantum computer with the default chain strength
might not always sufficient:

>>> sampleset = sampler.sample(bqm, num_reads=1000)   # doctest: +SKIP
>>> print(sampleset)                                  # doctest: +SKIP
  s0 s1 s2 energy num_oc. chain_b.
0 -1 +1 -1   -1.0      85      0.0
1 -1 -1 +1   -1.0     147      0.0
2 +1 +1 -1   -1.0      81 0.333333
3 +1 -1 +1   -1.0      60      0.0
4 +1 +1 +1   -1.0     162      0.0
5 -1 -1 -1   -1.0     128      0.0
6 +1 -1 +1   -1.0      89 0.333333
7 +1 +1 -1   -1.0     248      0.0
['SPIN', 8 rows, 1000 samples, 3 variables]

The solutions of line 2 and 6 above shown a chains broken in a third of
the variables, meaning that for variable :math:`s_0` the two qubits representing
it did not return identical values. 

 .. figure:: ../_images/embedding_3var6groundstatesBroken.png
	:align: left
	:name: Embedding3var6qubitsGroundStatesBroken
	:scale: 60 %
	:alt: Three-variable fully-connected problem embedded into six qubits with a broken chain.

	Three-variable :math:`K_3` fully-connected problem is embedded in four qubits on a D-Wave 2000Q using the default chain strength. Variable :math:`s_0`, highlighted in dark magenta, is represented by two qubits, numbers 0 and 4. The displayed solution has a broken chain: qubit 0 returned a value of :math:`-1` (represented by a white dot) while qubit 4 returned a value of :math:`+1` (a blue dot). The logical representation of the problem, on the left, shows a half-white, half-blue dot to represent a value based on a broken chain. 

For information on handling embedding and chains, see the following documentation:

* :ref:`and`, :ref:`multi_gate`, and :ref:`inspector_graph_partitioning` examples

   Show through some simple examples how to embed and set chain strength.
* :std:doc:`minorminer <oceandocs:docs_minorminer/source/sdk_index>` tool

   Is the hueristic used by common Ocean embedding :term:`composite`\ s.
* :std:doc:`problem inspector <oceandocs:docs_inspector/sdk_index>` tool

   Visualizes embeddings.  
* :std:doc:`dwave-system <oceandocs:docs_system/reference/composites>` Composites section

   Provides embedding composites
  
* :std:doc:`dwave-system <oceandocs:docs_system/reference/embedding>` Embedding section
 
   Describes chain-related functionality.  



