<jupyter_start><jupyter_text>Introduction to symbols<jupyter_code>The parameterisable parts of a diagram are represented by :term:`symbols <symbol>`; these are instances of the :py:class:`lambeq.ansatz.Symbol` class. Let's create a tensor diagram for a sentence:<jupyter_output><empty_output><jupyter_text>import warningswarnings.filterwarnings('ignore')from lambeq.ccg2discocat import DepCCGParserfrom lambeq.tensor import TensorAnsatzfrom lambeq.core.types import AtomicTypefrom discopy import Dim Define atomic typesN = AtomicType.NOUNS = AtomicType.SENTENCE Parse a sentenceparser = DepCCGParser()diagram = parser.sentence2diagram("John walks in the park") Apply a tensor ansatzansatz = TensorAnsatz({N: Dim(4), S: Dim(2)})tensor_diagram = ansatz(diagram)tensor_diagram.draw(figsize=(12,5), fontsize=12)<jupyter_code>.. note::
    
   Class :py:class:`.Symbol` inherits from class :py:class:`sympy.Symbol`.

The :term:`symbols <symbol>` of the diagram can be accessed by the ``free_symbols`` attribute:<jupyter_output><empty_output><jupyter_text>tensor_diagram.free_symbols<jupyter_code>Each symbol is associated with a specific size, which is defined from the applied ansatz.<jupyter_output><empty_output><jupyter_text>[(s, s.size) for s in tensor_diagram.free_symbols]<jupyter_code>For example, you see that preposition "in" has been assigned 256 dimensions, which is derived by multiplying the dimensions of each individual wire ($2 \cdot 4 \cdot 4 \cdot 2 \cdot 4$), nouns are assigned 4 dimensions, and the determiner 16 dimensions.

## Circuit symbols<jupyter_output><empty_output><jupyter_text>We will now convert the original diagram into a :term:`quantum circuit` and examine its parameters:<jupyter_code>from lambeq.circuit import IQPAnsatz

iqp_ansatz = IQPAnsatz({N: 1, S: 1}, n_layers=1)
circuit = iqp_ansatz(diagram)
circuit.draw(figsize=(12,8), fontsize=12)<jupyter_output><empty_output><jupyter_text>Let's see the :term:`symbols ` of the :term:`circuit ` and their sizes:<jupyter_code>[(s, s.size) for s in circuit.free_symbols]<jupyter_output><empty_output><jupyter_text>Note that all sizes are equal to 1; this is because the parameters of the :term:`circuit ` are numbers, defining rotation angles on :term:`qubits `.<jupyter_code>## From symbols to tensors<jupyter_output><empty_output><jupyter_text>In this section we will create actual tensors and associate them with the :term:`symbols ` of the diagram. In order to do this, we first need to fix the order of the symbols, since they are represented as a set. We can use ``sympy``'s ``default_sort_key`` for this purpose.<jupyter_code>from sympy import default_sort_key

parameters = sorted(tensor_diagram.free_symbols, key=default_sort_key)<jupyter_output><empty_output><jupyter_text>We will use `numpy` arrays for the tensors, initialised randomly:<jupyter_code>import numpy as np

tensors = [np.random.rand(p.size) for p in parameters]
print(tensors[0])<jupyter_output>[0.72853877 0.0489024  0.58544848 0.33123311]<jupyter_text>Associating the ``numpy`` arrays with the :term:`symbols ` in the diagram can be done by using the :py:meth:`~discopy.tensor.Tensor.lambdify` method:<jupyter_code>tensor_diagram_np = tensor_diagram.lambdify(*parameters)(*tensors)
print("Before lambdify:", tensor_diagram.boxes[0].data)
print("After lambdify:", tensor_diagram_np.boxes[0].data)<jupyter_output>Before lambdify: John__n
After lambdify: [0.72853877 0.0489024  0.58544848 0.33123311]<jupyter_text>To contract the :term:`tensor network` and compute a representation for the sentence, we will use :py:meth:`~discopy.tensor.Diagram.eval`.<jupyter_code>result = tensor_diagram_np.eval()
print(result)<jupyter_output>Tensor(dom=Dim(1), cod=Dim(2), array=[14.40077809, 13.14739668])<jupyter_text>.. note::       The result is a 2-dimensional array, based on the fact that we have assigned a dimension of 2 to the sentence space when applying the :term:`ansatz `.The result is an instance of the :py:class:`discopy.tensor.Tensor` class, and the array can be accessed via the ``array`` attribute.<jupyter_code>result.array<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10454655968879163, 'fraction_numerical': 0.030634573304157548, 'mean_word_length': 7.311111111111111, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '12', 'dir': 'jupyter-structured-clean-dedup', 'id': '40112', 'license': 'Apache-2.0', 'n_tokens_mistral': 1438, 'n_tokens_neox': 1327, 'n_words': 387, 'path': 'docs/tutorials/training-symbols.ipynb', 'repo_name': 'hwazni/lambeq', 'size': '4113'}