<commit_before># Copyright 2020 The TensorFlow Quantum Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""A collection of helper functions that are useful several places in tfq."""
import random
import itertools

import numpy as np
import sympy
import tensorflow as tf
import cirq

from tensorflow_quantum.core.proto import pauli_sum_pb2
from tensorflow_quantum.core.serialize import serializer


def get_supported_gates():
    """A helper to get the gates supported by tfq."""
    supported_gates = serializer.SERIALIZER.supported_gate_types()
    gate_arity_mapping_dict = dict()
    for gate in supported_gates:
        if gate is cirq.IdentityGate:
            g_num_qubits = 1
            g = gate(num_qubits=1)
        elif gate is cirq.FSimGate:
            g_num_qubits = 2
            g = gate(theta=0.123, phi=0.456)
        elif gate in serializer.PHASED_EIGEN_GATES_DICT:
            g = gate(phase_exponent=0.123)
            g_num_qubits = g.num_qubits()
        else:
            g = gate()
            g_num_qubits = gate().num_qubits()
        gate_arity_mapping_dict[g] = g_num_qubits
    return gate_arity_mapping_dict


def _apply_random_control(gate, all_qubits):
    """Returns a random controlled version of `gate`.

    Chooses a random subset s from `all_qubits` that does not intersect
    with `gate.qubits` and returns gate.controlled_by(s). Note that
    if no such set s can be found (size of s would be zero) then
    `gate` is returned unchanged.

    Args:
        gate: Gate to be promoted to a controlled gate with the
            `controlled_by` function in Cirq.
        all_qubits: All qubits used by the circuit which `gate`
            comes from.
    Returns:
        A new gate with a random subset of the set difference
        between all_qubits and gate.qubits controlling `gate`.
    """
    open_qubits = set(all_qubits) - set(gate.qubits)
    n_open = min(len(open_qubits), 3)
    if n_open == 0:
        # No open qubits to control. Return unmodified gate.
        return gate
    control_locs = random.sample(open_qubits, n_open)
    return gate.controlled_by(*control_locs)


def random_symbol_circuit(qubits,
                          symbols,
                          n_moments=15,
                          p=0.9,
                          include_scalars=True):
    """Generate a random circuit including some parameterized gates.

    Symbols are randomly included in the gates of the first `n_moments` moments
    of the resulting circuit.  Then, parameterized H gates are added as
    subsequent moments for any remaining unused symbols.
    """
    supported_gates = get_supported_gates()
    circuit = cirq.testing.random_circuit(qubits, n_moments, p, supported_gates)
    random_symbols = list(symbols)
    random.shuffle(random_symbols)
    location = 0

    for i in range(len(circuit)):
        op = random.choice(list(supported_gates.keys()))
        n_qubits = supported_gates[op]
        locs = tuple(random.sample(qubits, n_qubits))
        if isinstance(op, cirq.IdentityGate):
            circuit[:i] += op.on(*locs)
            continue
        full_gate = (op**(
            (np.random.random() if include_scalars else 1.0) *
            sympy.Symbol(random_symbols[location % len(random_symbols)]))).on(
                *locs)
        if np.random.random() < 0.5:
            # Add a control to this gate.
            full_gate = _apply_random_control(full_gate, qubits)

        circuit[:i] += full_gate<commit_msg>format.<commit_after># Copyright 2020 The TensorFlow Quantum Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""A collection of helper functions that are useful several places in tfq."""
import random
import itertools

import numpy as np
import sympy
import tensorflow as tf
import cirq

from tensorflow_quantum.core.proto import pauli_sum_pb2
from tensorflow_quantum.core.serialize import serializer


def get_supported_gates():
    """A helper to get the gates supported by tfq."""
    supported_gates = serializer.SERIALIZER.supported_gate_types()
    gate_arity_mapping_dict = dict()
    for gate in supported_gates:
        if gate is cirq.IdentityGate:
            g_num_qubits = 1
            g = gate(num_qubits=1)
        elif gate is cirq.FSimGate:
            g_num_qubits = 2
            g = gate(theta=0.123, phi=0.456)
        elif gate in serializer.PHASED_EIGEN_GATES_DICT:
            g = gate(phase_exponent=0.123)
            g_num_qubits = g.num_qubits()
        else:
            g = gate()
            g_num_qubits = gate().num_qubits()
        gate_arity_mapping_dict[g] = g_num_qubits
    return gate_arity_mapping_dict


def _apply_random_control(gate, all_qubits):
    """Returns a random controlled version of `gate`.

    Chooses a random subset s from `all_qubits` that does not intersect
    with `gate.qubits` and returns gate.controlled_by(s). Note that
    if no such set s can be found (size of s would be zero) then
    `gate` is returned unchanged.

    Args:
        gate: Gate to be promoted to a controlled gate with the
            `controlled_by` function in Cirq.
        all_qubits: All qubits used by the circuit which `gate`
            comes from.
    Returns:
        A new gate with a random subset of the set difference
        between all_qubits and gate.qubits controlling `gate`.
    """
    open_qubits = set(all_qubits) - set(gate.qubits)
    n_open = min(len(open_qubits), 3)
    if n_open == 0:
        # No open qubits to control. Return unmodified gate.
        return gate
    control_locs = random.sample(open_qubits, n_open)
    return gate.controlled_by(*control_locs)


def random_symbol_circuit(qubits,
                          symbols,
                          n_moments=15,
                          p=0.9,
                          include_scalars=True):
    """Generate a random circuit including some parameterized gates.

    Symbols are randomly included in the gates of the first `n_moments` moments
    of the resulting circuit.  Then, parameterized H gates are added as
    subsequent moments for any remaining unused symbols.
    """
    supported_gates = get_supported_gates()
    circuit = cirq.testing.random_circuit(qubits, n_moments, p, supported_gates)
    random_symbols = list(symbols)
    random.shuffle(random_symbols)
    location = 0

    for i in range(len(circuit)):
        op = random.choice(list(supported_gates.keys()))
        n_qubits = supported_gates[op]
        locs = tuple(random.sample(qubits, n_qubits))
        if isinstance(op, cirq.IdentityGate):
            circuit[:i] += op.on(*locs)
            continue
        working_symbol = sympy.Symbol(random_symbols[location %
                                                     len(random_symbols)])
        working_scalar = np.random.random() if include_scalars else 1.0
        full_gate = (op**(working_scalar * working_symbol)).on(*locs)
        if np.random.random() < 0.5:
            # Add a control to this gate.
            full_gate = _apply_random_control(full_gate, qubits)

        circuit[:i] += full_gate
{'fraction_non_alphanumeric': 0.09334621422533511, 'fraction_numerical': 0.0084530853761623, 'mean_word_length': 2.728950923007654, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5196320', 'n_tokens_mistral': 2416, 'n_tokens_neox': 2313, 'n_words': 781}