

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Desarrollo de su primer circuito
<a name="braket-get-started-run-circuit"></a>

Una vez lanzada la instancia de cuaderno, ábrala con una interfaz de Jupyter estándar. Para ello, seleccione el cuaderno que acaba de crear.

![\[Interfaz de cuadernos que muestra una instancia de bloc de notas existente nombrada amazon-braket-test con su estado InService y su URL.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/console-page.png)


Las instancias de cuaderno de Amazon Braket vienen preinstaladas con el SDK de Amazon Braket y todas sus dependencias. Comience por crear un nuevo cuaderno con kernel de `conda_braket`.

![\[Interfaz de lanzamiento para cuadernos, consola y otras herramientas como terminal, archivo de texto, archivo Markdown, archivo Python, con el entorno Python conda_braket resaltado.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/jupyter-open.png)


Por ejemplo, puede empezar con un simple “¡Hola, mundo\$1” . Primero, desarrolle un circuito que prepare un estado de Bell y, a continuación, ejecute ese circuito en diferentes dispositivos para obtener los resultados.

Comience por importar el Comience por importar los módulos del SDK de Amazon Braket y defina un circuito simpleBRAKETlong; los módulos SDK y defina un circuito básico de Bell State.

```
import boto3
from braket.aws import AwsDevice
from braket.devices import LocalSimulator
from braket.circuits import Circuit

# Create the circuit
bell = Circuit().h(0).cnot(0, 1)
```

Puede ver el circuito con este comando:

```
print(bell)
```

```
T  : │  0  │  1  │
      ┌───┐       
q0 : ─┤ H ├───●───
      └───┘   │   
            ┌─┴─┐ 
q1 : ───────┤ X ├─
            └───┘ 
T  : │  0  │  1  │
```

 **Ejecución del circuito en el simulador local** 

A continuación, elija el dispositivo cuántico en el que ejecutar el circuito. El SDK de Amazon Braket incluye un simulador local para la creación rápida de prototipos y pruebas. Recomendamos utilizar el simulador local para circuitos más pequeños, que pueden ser de hasta 25 qubits (según el hardware local).

Para crear una instancia de simulador local:

```
# Instantiate the local simulator
local_sim = LocalSimulator()
```

Para ejecutar el circuito:

```
# Run the circuit
result = local_sim.run(bell, shots=1000).result()
counts = result.measurement_counts
print(counts)
```

Debería ver un resultado similar al siguiente:

```
Counter({'11': 503, '00': 497})
```

El estado de Bell específico que ha preparado es una superposición igual de \$100⟩ y \$111⟩, y una distribución aproximadamente igual (hasta el ruido de shot) de 00 y 11 como resultados de medición, según se espera.

 **Ejecución del circuito en un simulador bajo demanda** 

Amazon Braket también proporciona acceso a un simulador de alto rendimiento bajo demanda, SV1, para ejecutar circuitos más grandes. SV1 es un simulador de vector de estado bajo demanda que permite simular circuitos cuánticos de hasta 34 qubits. Encontrará más información SV1 en la sección [Dispositivos compatibles](braket-devices.md) y en la AWS consola. Cuando ejecuta tareas cuánticas en SV1 (y en TN1 o en cualquier QPU), los resultados de la tarea cuántica se almacenan en un bucket de S3 en su cuenta. Si no especifica ningún bucket, el SDK de Braket crea un bucket predeterminado `amazon-braket-{region}-{accountID}` para usted. Para obtener más información, consulte [Administración del acceso a Amazon Braket](braket-manage-access.md).

**nota**  
Rellene el nombre real y existente de su bucket en donde el siguiente ejemplo muestra `amazon-braket-s3-demo-bucket` como el nombre del bucket. Los nombres de los buckets de Amazon Braket siempre comienzan por `amazon-braket-` seguido de otros caracteres identificativos que añada. Si necesita información sobre cómo configurar un bucket de S3, consulte [Introducción a Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/GetStartedWithS3.html).

```
# Get the account ID
aws_account_id = boto3.client("sts").get_caller_identity()["Account"]

# The name of the bucket
my_bucket = "amazon-braket-s3-demo-bucket"

# The name of the folder in the bucket
my_prefix = "simulation-output"
s3_folder = (my_bucket, my_prefix)
```

Para ejecutar un circuito en SV1, debe proporcionar la ubicación del bucket de S3 que seleccionó previamente como argumento posicional en la llamada de `.run()`.

```
# Choose the cloud-based on-demand simulator to run your circuit
device = AwsDevice("arn:aws:braket:::device/quantum-simulator/amazon/sv1")

# Run the circuit
task = device.run(bell, s3_folder, shots=100)

# Display the results
print(task.result().measurement_counts)
```

La consola de Amazon Braket proporciona más información sobre su tarea cuántica. Diríjase a la pestaña **Tareas cuánticas** de la consola y su tarea cuántica debería aparecer en la parte superior de la lista. Como alternativa, puede buscar su tarea cuántica utilizando el identificador único de la tarea cuántica u otros criterios.

**nota**  
Transcurridos 90 días, Amazon Braket elimina automáticamente todas las tareas cuánticas IDs y otros metadatos asociados a sus tareas cuánticas. Para obtener más información consulte [Retención de datos](https://docs.aws.amazon.com/braket/latest/developerguide/security.html#braket-data-retention).

 **Ejecución en una QPU** 

Con Amazon Braket, puede ejecutar el ejemplo anterior de circuito cuántico en una computadora cuántica física simplemente cambiando una línea de código. Amazon Braket proporciona acceso a una variedad de dispositivos con unidades de procesamiento cuántico (QPU). Puede encontrar información sobre los distintos dispositivos y las ventanas de disponibilidad en la sección [Dispositivos compatibles](braket-devices.md) y en la AWS consola, en la pestaña **Dispositivos**. En el siguiente ejemplo se muestra cómo crear instancias de un dispositivo de IQM.

```
# Choose the IQM hardware to run your circuit
device = AwsDevice("arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet")
```

O elija un dispositivo de IonQ con este código:

```
# Choose the Ionq device to run your circuit
device = AwsDevice("arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1")
```

Después de seleccionar un dispositivo y antes de ejecutar su carga de trabajo, puede consultar la profundidad de la cola del dispositivo con el siguiente código para determinar el número de tareas cuánticas o trabajos híbridos. Además, los clientes pueden ver las profundidades de cola específicas de cada dispositivo en la página Dispositivos de la Amazon Braket Management Console. 

```
# Print your queue depth
print(device.queue_depth().quantum_tasks)
# Returns the number of quantum tasks queued on the device
# {<QueueType.NORMAL: 'Normal'>: '0', <QueueType.PRIORITY: 'Priority'>: '0'}

print(device.queue_depth().jobs)
# Returns the number of hybrid jobs queued on the device
# '2'
```

Al ejecutar la tarea, el SDK de Amazon Braket sondea para obtener un resultado (con un tiempo de espera predeterminado de 5 días). Puede cambiar este valor predeterminado modificando el parámetro `poll_timeout_seconds` en el comando `.run()`, como se muestra en el siguiente ejemplo. Tenga en cuenta que si el tiempo de espera de sondeo es demasiado corto, es posible que los resultados no se devuelvan dentro del tiempo de sondeo, como cuando una QPU no está disponible y se devuelve un error de tiempo de espera local. Puede reiniciar el sondeo llamando a la función `task.result()`.

```
# Define quantum task with 1 day polling timeout
task = device.run(bell, s3_folder, poll_timeout_seconds=24*60*60)
print(task.result().measurement_counts)
```

Además, después de enviar su tarea cuántica o trabajo híbrido, puede llamar a la función `queue_position()` para comprobar su posición en la cola.

```
print(task.queue_position().queue_position)
# Return the number of quantum tasks queued ahead of you
# '2'
```

# Desarrollo de sus primeros algoritmos cuánticos
<a name="braket-explore-algorithm-library"></a>

La biblioteca de algoritmos de Amazon Braket es un catálogo de algoritmos cuánticos preconstruidos escritos en Python. Ejecute estos algoritmos tal como están o utilícelos como punto de partida para desarrollar algoritmos más complejos. Puede acceder a la biblioteca de algoritmos desde la consola de Braket. Para obtener más información, consulte la [Biblioteca de algoritmos del GitHub de Braket](https://github.com/aws-samples/amazon-braket-algorithm-library).

![\[La página de la biblioteca de algoritmos de Amazon Braket muestra una lista de algoritmos cuánticos prediseñados, como Berstein Vazirani, Deutsch-Jozsa, el algoritmo de Grover y el algoritmo de optimización aproximada cuántica, con breves descripciones.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/AlgorithmLibrary.png)


La consola de Braket proporciona una descripción de cada algoritmo disponible en la biblioteca de algoritmos. Elija un GitHub enlace para ver los detalles de cada algoritmo o seleccione **Abrir bloc de notas** para abrir o crear un bloc de notas que contenga todos los algoritmos disponibles. Si elige la opción de cuaderno, podrá encontrar la biblioteca de algoritmos de Braket en la carpeta raíz de su cuaderno.

# Construcción de circuitos en el SDK
<a name="braket-constructing-circuit"></a>

En esta sección se proporcionan ejemplos sobre cómo definir un circuito, ver las puertas disponibles, extender un circuito y ver las puertas compatibles con cada dispositivo. También contiene instrucciones sobre cómo realizar la asignación manual de qubits, indicar al compilador que ejecute los circuitos exactamente como se ha definido y construir circuitos ruidosos con un simulador de ruido.

También puedes trabajar al nivel del pulso en Braket para varias puertas, con algunas QPUs. Para obtener más información, consulte [Control de pulsos en Amazon Braket](braket-pulse-control.md).

**Topics**
+ [

## Puertas y circuitos
](#braket-gates)
+ [

## Conjuntos de programas
](#braket-program-set)
+ [

## Medición parcial
](#braket-partial-measurement)
+ [

## Asignación manual de qubit
](#manual-qubit-allocation)
+ [

## Compilación verbatim
](#verbatim-compilation)
+ [

## Simulación de ruido
](#noise-simulation)

## Puertas y circuitos
<a name="braket-gates"></a>

Las puertas y circuitos cuánticos se definen en la clase de [https://github.com/aws/amazon-braket-sdk-python/blob/main/src/braket/circuits/circuit.py](https://github.com/aws/amazon-braket-sdk-python/blob/main/src/braket/circuits/circuit.py) del SDK de Python de Amazon Braket. Desde el SDK, puede crear una instancia de un nuevo objeto de circuito llamando a `Circuit()`.

 **Ejemplo: Definir un circuito** 

El ejemplo comienza definiendo un circuito de muestra de cuatro qubits (etiquetados `q0`, `q1`, `q2` y `q3`) que consisten en puertas Hadamard estándar de un solo qubit y puertas CNOT de dos qubits. Puede visualizar este circuito llamando a la función `print`, como se muestra en el siguiente ejemplo.

```
# Import the circuit module
from braket.circuits import Circuit

# Define circuit with 4 qubits
my_circuit = Circuit().h(range(4)).cnot(control=0, target=2).cnot(control=1, target=3)
print(my_circuit)
```

```
T  : │  0  │     1     │
      ┌───┐             
q0 : ─┤ H ├───●─────────
      └───┘   │         
      ┌───┐   │         
q1 : ─┤ H ├───┼─────●───
      └───┘   │     │   
      ┌───┐ ┌─┴─┐   │   
q2 : ─┤ H ├─┤ X ├───┼───
      └───┘ └───┘   │   
      ┌───┐       ┌─┴─┐ 
q3 : ─┤ H ├───────┤ X ├─
      └───┘       └───┘ 
T  : │  0  │     1     │
```

 **Ejemplo: Definir un circuito parametrizado** 

En este ejemplo, definimos un circuito con puertas que dependen de parámetros libres. Podemos especificar los valores de estos parámetros para crear un circuito nuevo o, al enviar el circuito, para que se ejecute como una tarea cuántica en determinados dispositivos.

```
from braket.circuits import Circuit, FreeParameter

# Define a FreeParameter to represent the angle of a gate
alpha = FreeParameter("alpha")

# Define a circuit with three qubits
my_circuit = Circuit().h(range(3)).cnot(control=0, target=2).rx(0, alpha).rx(1, alpha)
print(my_circuit)
```

Puede crear un circuito nuevo no parametrizado a partir de uno parametrizado proporcionando un único argumento `float` (que será el valor que tomarán todos los parámetros libres) o argumentos de palabra clave que especifiquen el valor de cada parámetro del circuito, como se indica a continuación.

```
my_fixed_circuit = my_circuit(1.2)
my_fixed_circuit = my_circuit(alpha=1.2)
print(my_fixed_circuit)
```

Tenga en cuenta que `my_circuit` no está modificado, por lo que puede usarlo para crear instancias de muchos circuitos nuevos con valores de parámetros fijos.

 **Ejemplo: Modificar las puertas de un circuito** 

En el siguiente ejemplo se define un circuito con puertas que utilizan modificadores de control y potencia. Puede utilizar estas modificaciones para crear nuevas puertas, como la puerta de `Ry` controlada.

```
from braket.circuits import Circuit

# Create a bell circuit with a controlled x gate
my_circuit = Circuit().h(0).x(control=0, target=1)

# Add a multi-controlled Ry gate of angle .13
my_circuit.ry(angle=.13, target=2, control=(0, 1))

# Add a 1/5 root of X gate
my_circuit.x(0, power=1/5)

print(my_circuit)
```

Los modificadores de puerta solo son compatibles con el simulador local.

 **Ejemplo: Consultar todas las puertas disponibles** 

En el siguiente ejemplo se muestra cómo ver todas las puertas disponibles en Amazon Braket.

```
from braket.circuits import Gate
# Print all available gates in Amazon Braket
gate_set = [attr for attr in dir(Gate) if attr[0].isupper()]
print(gate_set)
```

El resultado de este código muestra una lista de todas las puertas.

```
['CCNot', 'CNot', 'CPhaseShift', 'CPhaseShift00', 'CPhaseShift01', 'CPhaseShift10', 'CSwap', 'CV', 'CY', 'CZ', 'ECR', 'GPhase', 'GPi', 'GPi2', 'H', 'I', 'ISwap', 'MS', 'PRx', 'PSwap', 'PhaseShift', 'PulseGate', 'Rx', 'Ry', 'Rz', 'S', 'Si', 'Swap', 'T', 'Ti', 'U', 'Unitary', 'V', 'Vi', 'X', 'XX', 'XY', 'Y', 'YY', 'Z', 'ZZ']
```

Cualquiera de estas puertas se puede añadir a un circuito llamando al método correspondiente a ese tipo de circuito. Por ejemplo, llamar a `circ.h(0)` para añadir una puerta Hadamard a al primer qubit.

**nota**  
Las puertas están colocadas en su sitio y en el siguiente ejemplo se añaden todas las puertas enumeradas en el ejemplo anterior al mismo circuito.

```
circ = Circuit()
# toffoli gate with q0, q1 the control qubits and q2 the target.
circ.ccnot(0, 1, 2)
# cnot gate
circ.cnot(0, 1)
# controlled-phase gate that phases the |11> state, cphaseshift(phi) = diag((1,1,1,exp(1j*phi))), where phi=0.15 in the examples below
circ.cphaseshift(0, 1, 0.15)
# controlled-phase gate that phases the |00> state, cphaseshift00(phi) = diag([exp(1j*phi),1,1,1])
circ.cphaseshift00(0, 1, 0.15)
# controlled-phase gate that phases the |01> state, cphaseshift01(phi) = diag([1,exp(1j*phi),1,1])
circ.cphaseshift01(0, 1, 0.15)
# controlled-phase gate that phases the |10> state, cphaseshift10(phi) = diag([1,1,exp(1j*phi),1])
circ.cphaseshift10(0, 1, 0.15)
# controlled swap gate
circ.cswap(0, 1, 2)
# swap gate
circ.swap(0,1)
# phaseshift(phi)= diag([1,exp(1j*phi)])
circ.phaseshift(0,0.15)
# controlled Y gate
circ.cy(0, 1)
# controlled phase gate
circ.cz(0, 1)
# Echoed cross-resonance gate applied to q0, q1
circ = Circuit().ecr(0,1)
# X rotation with angle 0.15
circ.rx(0, 0.15)
# Y rotation with angle 0.15
circ.ry(0, 0.15)
# Z rotation with angle 0.15
circ.rz(0, 0.15)
# Hadamard gates applied to q0, q1, q2
circ.h(range(3))
# identity gates applied to q0, q1, q2
circ.i([0, 1, 2])
# iswap gate, iswap = [[1,0,0,0],[0,0,1j,0],[0,1j,0,0],[0,0,0,1]]
circ.iswap(0, 1)
# pswap gate, PSWAP(phi) = [[1,0,0,0],[0,0,exp(1j*phi),0],[0,exp(1j*phi),0,0],[0,0,0,1]]
circ.pswap(0, 1, 0.15)
# X gate applied to q1, q2
circ.x([1, 2])
# Y gate applied to q1, q2
circ.y([1, 2])
# Z gate applied to q1, q2
circ.z([1, 2])
# S gate applied to q0, q1, q2
circ.s([0, 1, 2])
# conjugate transpose of S gate applied to q0, q1
circ.si([0, 1])
# T gate applied to q0, q1
circ.t([0, 1])
# conjugate transpose of T gate applied to q0, q1
circ.ti([0, 1])
# square root of not gate applied to q0, q1, q2
circ.v([0, 1, 2])
# conjugate transpose of square root of not gate applied to q0, q1, q2
circ.vi([0, 1, 2])
# exp(-iXX theta/2)
circ.xx(0, 1, 0.15)
# exp(i(XX+YY) theta/4), where theta=0.15 in the examples below
circ.xy(0, 1, 0.15)
# exp(-iYY theta/2)
circ.yy(0, 1, 0.15)
# exp(-iZZ theta/2)
circ.zz(0, 1, 0.15)
# IonQ native gate GPi with angle 0.15 applied to q0
circ.gpi(0, 0.15)
# IonQ native gate GPi2 with angle 0.15 applied to q0
circ.gpi2(0, 0.15)
# IonQ native gate MS with angles 0.15, 0.15, 0.15 applied to q0, q1
circ.ms(0, 1, 0.15, 0.15, 0.15)
```

Además del conjunto de puertas predefinido, también puede aplicar puertas unitarias autodefinidas al circuito. Pueden ser puertas de un solo qubit (como se muestra en el siguiente código fuente) o puertas de varios qubit aplicadas a los qubits definidos por el parámetro `targets`.

```
import numpy as np

# Apply a general unitary
my_unitary = np.array([[0, 1],[1, 0]])
circ.unitary(matrix=my_unitary, targets=[0])
```

 **Ejemplo: Ampliar los circuitos existentes** 

Puede ampliar los circuitos existentes añadiendo instrucciones. Una `Instruction` es una directiva cuántica que describe la tarea cuántica que se debe realizar en un dispositivo cuántico. Los operadores de la `Instruction` incluyen objetos del tipo `Gate` únicamente.

```
# Import the Gate and Instruction modules
from braket.circuits import Gate, Instruction

# Add instructions directly.
circ = Circuit([Instruction(Gate.H(), 4), Instruction(Gate.CNot(), [4, 5])])

# Or with add_instruction/add functions
instr = Instruction(Gate.CNot(), [0, 1])
circ.add_instruction(instr)
circ.add(instr)

# Specify where the circuit is appended
circ.add_instruction(instr, target=[3, 4])
circ.add_instruction(instr, target_mapping={0: 3, 1: 4})

# Print the instructions
print(circ.instructions)
# If there are multiple instructions, you can print them in a for loop
for instr in circ.instructions:
     print(instr)

# Instructions can be copied
new_instr = instr.copy()
# Appoint the instruction to target
new_instr = instr.copy(target=[5, 6])
new_instr = instr.copy(target_mapping={0: 5, 1: 6})
```

 **Ejemplo: Ver las puertas que admite cada dispositivo** 

Los simuladores admiten todas las puertas del SDK de Braket, pero los dispositivos QPU admiten un subconjunto más pequeño. Puede encontrar las puertas compatibles de un dispositivo en las propiedades del dispositivo. A continuación se muestra un ejemplo con un dispositivo IonQ:

```
# Import the device module
from braket.aws import AwsDevice

device = AwsDevice("arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1")

# Get device name
device_name = device.name
# Show supportedQuantumOperations (supported gates for a device)
device_operations = device.properties.dict()['action']['braket.ir.openqasm.program']['supportedOperations']
print('Quantum Gates supported by {}:\n {}'.format(device_name, device_operations))
```

```
Quantum Gates supported by Aria 1:
 ['x', 'y', 'z', 'h', 's', 'si', 't', 'ti', 'v', 'vi', 'rx', 'ry', 'rz', 'cnot', 'swap', 'xx', 'yy', 'zz']
```

Es posible que las puertas compatibles deban compilarse en puertas nativas antes de que puedan ejecutarse en hardware cuántico. Cuando envía un circuito, Amazon Braket realiza esta compilación automáticamente.

 **Ejemplo: Recuperar mediante programación la fidelidad de las puertas nativas compatibles con un dispositivo** 

Puede ver la información de fidelidad en la página **Dispositivos** de la consola de Braket. A veces resulta útil acceder a la misma información de forma programática. El siguiente código muestra cómo extraer la fidelidad de las dos puertas de qubit de una QPU.

```
# Import the device module
from braket.aws import AwsDevice
 
device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3") 

# Specify the qubits 
a=10 
b=11
edge_properties_entry = device.properties.standardized.twoQubitProperties['10-11'].twoQubitGateFidelity
gate_name = edge_properties_entry[0].gateName
fidelity = edge_properties_entry[0].fidelity
print(f"Fidelity of the {gate_name} gate between qubits {a} and {b}: {fidelity}")
```

## Conjuntos de programas
<a name="braket-program-set"></a>

Los conjuntos de programas ejecutan de manera eficiente varios circuitos cuánticos en una sola tarea cuántica. En esa tarea, puede enviar hasta 100 circuitos cuánticos o un solo circuito paramétrico con hasta 100 conjuntos de parámetros diferentes. Esta operación minimiza el tiempo entre las ejecuciones subsiguientes de los circuitos y reduce la sobrecarga de procesamiento de las tareas cuánticas. Actualmente, los conjuntos de programas son compatibles con Amazon Braket Local Simulator y otros AQT dispositivosIQM. Rigetti

**Definir un ProgramSet**

El siguiente primer ejemplo de código muestra cómo desarrollar un `ProgramSet` utilizando circuitos parametrizados y circuitos sin parámetros.

```
from braket.aws import AwsDevice
from braket.circuits import Circuit, FreeParameter
from braket.program_sets.circuit_binding import CircuitBinding
from braket.program_sets import ProgramSet

# Initialize the quantum device
device = AwsDevice("arn:aws:braket:eu-north-1::device/qpu/iqm/Garnet")

# Define circuits
circ1 = Circuit().h(0).cnot(0, 1)
circ2 = Circuit().rx(0, 0.785).ry(1, 0.393).cnot(1, 0)
circ3 = Circuit().t(0).t(1).cz(0, 1).s(0).cz(1, 2).s(1).s(2)
parameterize_circuit = Circuit().rx(0, FreeParameter("alpha")).cnot(0, 1).ry(1, FreeParameter("beta"))

# Create circuit bindings with different parameters
circuit_binding = CircuitBinding(
    circuit=parameterize_circuit,
    input_sets={
            'alpha': (0.10, 0.11, 0.22, 0.34, 0.45),
            'beta': (1.01, 1.01, 1.03, 1.04, 1.04),
    })

# Creating the program set
program_set_1 = ProgramSet([
    circ1,
    circ2,
    circ3,
    circuit_binding,
])
```

Este conjunto de programas contiene cuatro programas únicos: `circ1`, `circ2`, `circ3` y `circuit_binding`. El programa `circuit_binding` se ejecuta con cinco vínculos de parámetros diferentes, lo que crea cinco ejecutables. Los otros tres programas sin parámetros crean un ejecutable cada uno. Esto da como resultado un total de ocho ejecutables, como se muestra en la imagen siguiente.

![\[ProgramSet estructura con cuatro circuitos, donde c4 utiliza CircuitBinding para procesar cinco conjuntos de entradas.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/program_set1.png)


El siguiente segundo ejemplo de código muestra cómo utilizar el método `product()` para adjuntar el mismo conjunto de observables a cada ejecutable del conjunto de programas.

```
from braket.circuits.observables import I, X, Y, Z

observables = [Z(0) @ Z(1), X(0) @ X(1), Z(0) @ X(1), X(0) @ Z(1)]

program_set_2 = ProgramSet.product(
    circuits=[circ1, circ2, circuit_binding],
    observables=observables
)
```

En el caso de los programas sin parámetros, cada observable se mide para cada circuito. En el caso de los programas paramétricos, cada observable se mide para cada conjunto de entradas, como se muestra en la siguiente imagen.

![\[ProgramSet.product muestra la ejecución paralela de tres circuitos, con c3 utilizando CircuitBinding para procesar cinco conjuntos de entradas con cinco observables cada uno.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/program_set2.png)


En el tercer ejemplo de código siguiente se muestra cómo utilizar el método `zip()` para emparejar observables individuales con conjuntos de parámetros específicos en el `ProgramSet`.

```
program_set_3 = ProgramSet.zip(
    circuits=circuit_binding,
    observables=observables + [Y(0) @ Y(1)]
)
```

![\[ProgramSet.zip con una CircuitBinding demostración de cinco ejecuciones paralelas utilizando un circuito compartido con observables individuales por conjunto de entradas.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/program_set3.png)


En lugar de `CircuitBinding()`, puede comprimir directamente una lista de observables con una lista de circuitos y conjuntos de entradas. 

```
program_set_4 = ProgramSet.zip(
    circuits=[circ1, circ2, circ3],
    input_sets=[{}, {}, {}],
    observables=observables[:3]
)
```

![\[ProgramSet.zip que muestra la ejecución paralela de siete circuitos con su correspondiente conjunto de entradas individuales y observables individuales.\]](http://docs.aws.amazon.com/es_es/braket/latest/developerguide/images/program_set4.png)


Para obtener más información y ejemplos de conjuntos de programas, consulta la [carpeta de conjuntos de programas](https://github.com/amazon-braket/amazon-braket-examples/tree/main/examples/braket_features/program_sets) en Github. amazon-braket-examples

**Cómo inspeccionar y ejecutar un conjunto de programas en un dispositivo**

El número de ejecutables de un conjunto de programas es igual al número de circuitos vinculados a parámetros únicos. Calcule el número total de shots y ejecutables de circuitos mediante el siguiente ejemplo de código.

```
# Number of shots per executable
shots = 10
num_executables = program_set_1.total_executables

# Calculate total number of shots across all executables
total_num_shots = shots*num_executables
```

**nota**  
Con los conjuntos de programas, se paga una tarifa única por tarea y una tarifa por shot basada en el número total de shots en todos los circuitos de un conjunto de programas.

Para ejecutar el conjunto de programas, use el siguiente ejemplo de código.

```
# Run the program set
task = device.run(
   program_set_1, shots=total_num_shots,
)
```

Al utilizar dispositivos Rigetti, su conjunto de programas puede permanecer en el estado `RUNNING` mientras las tareas estén parcialmente terminadas y parcialmente en cola. Para obtener resultados más rápidos, considere enviar su conjunto de programas como [Trabajo híbrido](braket-jobs-first.md).

**Analizando los resultados**

Ejecute el siguiente código para analizar y medir los resultados de los ejecutables en un `ProgramSet`.

```
# Get the results from a program set 
result = task.result()

# Get the first executbable
first_program = result[0] 
first_executable = first_program[0]

# Inspect the results of the first executable
measurements_from_first_executable = first_executable.measurements
print(measurements_from_first_executable)
```

## Medición parcial
<a name="braket-partial-measurement"></a>

En lugar de medir todos los qubits de un circuito cuántico, utilice la medición parcial para medir qubits individuales o un subconjunto de qubits. 

**nota**  
Las características adicionales, como la medición del circuito medio y las operaciones de prealimentación, están disponibles como capacidades experimentales. Consulte [Acceso a circuitos dinámicos en dispositivos IQM](braket-experimental-capabilities.md#braket-access-dynamic-circuits).

**Ejemplo: Medir un subconjunto de qubits**

El siguiente ejemplo de código muestra una medición parcial midiendo solo qubit 0 en un circuito de estado de Bell.

```
from braket.devices import LocalSimulator
from braket.circuits import Circuit

# Use the local state vector simulator
device = LocalSimulator()

# Define an example bell circuit and measure qubit 0
circuit = Circuit().h(0).cnot(0, 1).measure(0)

# Run the circuit
task = device.run(circuit, shots=10)

# Get the results
result = task.result()

# Print the circuit and measured qubits
print(circuit)
print()
print("Measured qubits: ", result.measured_qubits)
```

## Asignación manual de qubit
<a name="manual-qubit-allocation"></a>

Cuando ejecuta un circuito cuántico en computadoras cuánticas desde Rigetti, puede utilizar opcionalmente la asignación manual de qubit para controlar qué qubits se utilizan para su algoritmo. La [consola de Amazon Braket](https://console.aws.amazon.com/braket/home) y el [SDK de Amazon Braket](https://github.com/aws/amazon-braket-sdk-python) le ayudan a inspeccionar los datos de calibración más recientes de la unidad de procesamiento cuántico (QPU) que haya seleccionado, de modo que pueda seleccionar los mejores qubits para su experimento.

La asignación manual de qubit le permite ejecutar los circuitos con mayor precisión e investigar las propiedades de qubit individuales. Los investigadores y usuarios avanzados optimizan el diseño de sus circuitos basándose en los últimos datos de calibración de dispositivos y pueden obtener resultados más precisos.

En el siguiente ejemplo se muestra cómo asignar qubits de forma explícita.

```
# Import the device module
from braket.aws import AwsDevice

device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3")
circ = Circuit().h(0).cnot(0, 7)  # Indices of actual qubits in the QPU

# Set up S3 bucket (where results are stored)
my_bucket = "amazon-braket-s3-demo-bucket" # The name of the bucket
my_prefix = "your-folder-name" # The name of the folder in the bucket
s3_location = (my_bucket, my_prefix)

my_task = device.run(circ, s3_location, shots=100, disable_qubit_rewiring=True)
```

Para obtener más información, consulte [los ejemplos de Amazon Braket sobre GitHub](https://github.com/aws/amazon-braket-examples), o más específicamente, este cuaderno: [Asignación de qubits](https://github.com/aws/amazon-braket-examples/blob/main/examples/braket_features/Allocating_Qubits_on_QPU_Devices.ipynb) en dispositivos QPU.

## Compilación verbatim
<a name="verbatim-compilation"></a>

Cuando ejecuta un circuito cuántico en computadoras cuánticas basadas en puertas, puede indicar al compilador que ejecute sus circuitos exactamente como se ha definido sin ninguna modificación. Mediante la compilación verbatim, puede especificar que un circuito completo se conserve exactamente como se ha especificado o que solo se conserven partes específicas del mismo (solo compatible con Rigetti). Al desarrollar algoritmos para la evaluación comparativa de hardware o protocolos de mitigación de errores, es necesario tener la opción de especificar con exactitud las puertas y los diseños de circuitos que se ejecutan en el hardware. La compilación verbatim le permite controlar directamente el proceso de compilación desactivando determinados pasos de optimización, lo que garantiza que sus circuitos funcionen exactamente según lo diseñado.

La compilación literal es compatible con los Rigetti dispositivosAQT, IonQIQM, y requiere el uso de puertas nativas. Cuando utilice la compilación verbatim, es recomendable comprobar la topología del dispositivo para asegurarse de que las puertas se llaman sobre qubits conectados y que el circuito utiliza las puertas nativas compatibles con el hardware. En el siguiente ejemplo se muestra cómo acceder mediante programación a la lista de puertas nativas admitidas por un dispositivo.

```
device.properties.paradigm.nativeGateSet
```

Para Rigetti, el recableado de qubit debe desactivarse configurando `disableQubitRewiring=True` para el uso con la compilación verbatim. Si `disableQubitRewiring=False` se establece cuando se utilizan cuadros verbatim en una compilación, el circuito cuántico no pasa la validación y no se ejecuta.

Si la compilación verbatim se habilita para un circuito y se ejecuta en una QPU que no la admite, se genera un error que indica que una operación no compatible ha provocado el fallo de la tarea. A medida que más hardware cuántico admita de forma nativa las funciones del compilador, se ampliará esta característica para incluir estos dispositivos. Los dispositivos que admiten la compilación verbatim la incluyen como operación compatible cuando se consulta con el siguiente código.

```
from braket.aws import AwsDevice
from braket.device_schema.device_action_properties import DeviceActionType
device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3")
device.properties.action[DeviceActionType.OPENQASM].supportedPragmas
```

No hay ningún costo adicional asociado al uso de la compilación verbatim. Se le seguirán cobrando las tareas cuánticas ejecutadas en dispositivos QPU de Braket, instancias de cuaderno y simuladores bajo demanda según las tarifas actuales especificadas en la página de [precios de Amazon Braket](https://aws.amazon.com/braket/pricing/). Para obtener más información, consulte el cuaderno de ejemplos de [compilación verbatim](https://github.com/aws/amazon-braket-examples/blob/main/examples/braket_features/Verbatim_Compilation.ipynb).

**nota**  
Si utilizas OpenQASM para escribir los circuitos de los IonQ dispositivos AQT y, además, deseas mapear tu circuito directamente a los cúbits físicos, tendrás que usar el parámetro, `#pragma braket verbatim` ya que OpenQasm ignora el `disableQubitRewiring` indicador.

## Simulación de ruido
<a name="noise-simulation"></a>

Para crear una instancia de simulador de ruido local, puede cambiar el backend de la siguiente manera.

```
# Import the device module
from braket.aws import AwsDevice

device = LocalSimulator(backend="braket_dm")
```

Puede desarrollar circuitos ruidosos de dos maneras:

1. Desarrolle el circuito ruidoso de abajo hacia arriba.

1. Tome un circuito existente sin ruido e inyecte ruido en él.

En el siguiente ejemplo se muestran los enfoques utilizando un circuito básico con ruido despolarizante y un canal Kraus personalizado.

```
import scipy.stats
import numpy as np

# Bottom up approach
# Apply depolarizing noise to qubit 0 with probability of 0.1
circ = Circuit().x(0).x(1).depolarizing(0, probability=0.1)

# Create an arbitrary 2-qubit Kraus channel
E0 = scipy.stats.unitary_group.rvs(4) * np.sqrt(0.8)
E1 = scipy.stats.unitary_group.rvs(4) * np.sqrt(0.2)
K = [E0, E1]

# Apply a two-qubit Kraus channel to qubits 0 and 2
circ = circ.kraus([0, 2], K)
```

```
from braket.circuits import Noise

# Inject noise approach
# Define phase damping noise
noise = Noise.PhaseDamping(gamma=0.1)
# The noise channel is applied to all the X gates in the circuit
circ = Circuit().x(0).y(1).cnot(0, 2).x(1).z(2)
circ_noise = circ.copy()
circ_noise.apply_gate_noise(noise, target_gates=Gate.X)
```

Ejecutar un circuito ofrece la misma experiencia de usuario que antes, como se muestra en los dos ejemplos siguientes.

 **Ejemplo 1** 

```
task = device.run(circ, shots=100)
```

O

 **Ejemplo 2** 

```
task = device.run(circ_noise, shots=100)
```

Para ver más ejemplos, consulte el [ejemplo del simulador de ruido introductorio de Braket](https://github.com/aws/amazon-braket-examples/blob/main/examples/braket_features/Simulating_Noise_On_Amazon_Braket.ipynb). 

# Inspección del circuito
<a name="braket-inspecting-circut"></a>

Los circuitos cuánticos de Amazon Braket tienen un concepto de pseudotiempo denominado `Moments`. Cada qubit puede experimentar una sola puerta por `Moment`. El objetivo de `Moments` es facilitar el direccionamiento de los circuitos y sus puertas y proporcionar una estructura temporal.

**nota**  
Por lo general, los Momentos no se corresponden con el tiempo real en el que se ejecutan las puertas en una QPU.

La profundidad de un circuito viene dada por el número total de Momentos en ese circuito. Puede ver la profundidad del circuito al llamar al método `circuit.depth`, como se muestra en el siguiente ejemplo.

```
from braket.circuits import Circuit

# Define a circuit with parametrized gates
circ = Circuit().rx(0, 0.15).ry(1, 0.2).cnot(0, 2).zz(1, 3, 0.15).x(0)
print(circ)
print('Total circuit depth:', circ.depth)
```

```
T  : │     0      │        1         │  2  │
      ┌──────────┐                    ┌───┐ 
q0 : ─┤ Rx(0.15) ├───●────────────────┤ X ├─
      └──────────┘   │                └───┘ 
      ┌──────────┐   │   ┌──────────┐       
q1 : ─┤ Ry(0.20) ├───┼───┤ ZZ(0.15) ├───────
      └──────────┘   │   └────┬─────┘       
                   ┌─┴─┐      │             
q2 : ──────────────┤ X ├──────┼─────────────
                   └───┘      │             
                         ┌────┴─────┐       
q3 : ────────────────────┤ ZZ(0.15) ├───────
                         └──────────┘       
T  : │     0      │        1         │  2  │
Total circuit depth: 3
```

La profundidad de circuito total del circuito anterior es 3 (mostrados como Momentos `0`, `1` y`2`). Puede comprobar la operación de la puerta en cada Momento.

 `Moments` funciona como un diccionario de pares de *clave-valor*.
+ La clave es `MomentsKey()`, la cual contiene pseudotiempo e información de qubit.
+ El valor se asigna en el tipo de `Instructions()`.

```
moments = circ.moments
for key, value in moments.items():
    print(key)
    print(value, "\n")
```

```
MomentsKey(time=0, qubits=QubitSet([Qubit(0)]), moment_type=<MomentType.GATE: 'gate'>, noise_index=0, subindex=0)
Instruction('operator': Rx('angle': 0.15, 'qubit_count': 1), 'target': QubitSet([Qubit(0)]), 'control': QubitSet([]), 'control_state': (), 'power': 1) 

MomentsKey(time=0, qubits=QubitSet([Qubit(1)]), moment_type=<MomentType.GATE: 'gate'>, noise_index=0, subindex=0)
Instruction('operator': Ry('angle': 0.2, 'qubit_count': 1), 'target': QubitSet([Qubit(1)]), 'control': QubitSet([]), 'control_state': (), 'power': 1) 

MomentsKey(time=1, qubits=QubitSet([Qubit(0), Qubit(2)]), moment_type=<MomentType.GATE: 'gate'>, noise_index=0, subindex=0)
Instruction('operator': CNot('qubit_count': 2), 'target': QubitSet([Qubit(0), Qubit(2)]), 'control': QubitSet([]), 'control_state': (), 'power': 1) 

MomentsKey(time=1, qubits=QubitSet([Qubit(1), Qubit(3)]), moment_type=<MomentType.GATE: 'gate'>, noise_index=0, subindex=0)
Instruction('operator': ZZ('angle': 0.15, 'qubit_count': 2), 'target': QubitSet([Qubit(1), Qubit(3)]), 'control': QubitSet([]), 'control_state': (), 'power': 1) 

MomentsKey(time=2, qubits=QubitSet([Qubit(0)]), moment_type=<MomentType.GATE: 'gate'>, noise_index=0, subindex=0)
Instruction('operator': X('qubit_count': 1), 'target': QubitSet([Qubit(0)]), 'control': QubitSet([]), 'control_state': (), 'power': 1)
```

También puede añadir puertas a un circuito que a través de `Moments`.

```
from braket.circuits import Instruction, Gate

new_circ = Circuit()
instructions = [Instruction(Gate.S(), 0),
                Instruction(Gate.CZ(), [1, 0]),
                Instruction(Gate.H(), 1)
                ]

new_circ.moments.add(instructions)
print(new_circ)
```

```
T  : │  0  │  1  │  2  │
      ┌───┐ ┌───┐       
q0 : ─┤ S ├─┤ Z ├───────
      └───┘ └─┬─┘       
              │   ┌───┐ 
q1 : ─────────●───┤ H ├─
                  └───┘ 
T  : │  0  │  1  │  2  │
```

# Lista de tipos de resultados
<a name="braket-result-types"></a>

Amazon Braket puede devolver diferentes tipos de resultados cuando se mide un circuito utilizando `ResultType`. Un circuito puede devolver los siguientes tipos de resultados.
+  `AdjointGradient` devuelve el gradiente (derivado de vector) del valor esperado de un observable proporcionado. Este observable actúa sobre un objetivo determinado con respecto a parámetros específicos utilizando el método de diferenciación adjunta. Solo puede usar este método cuando shots = 0.
+  `Amplitude` devuelve la amplitud de los estados cuánticos especificados en la función de onda de salida. Solo está disponible en los simuladores SV1 y locales.
+  `Expectation` devuelve el valor esperado de un observable dado, que se puede especificar con la clase `Observable`, que se presenta más adelante en este capítulo. Para medir el observable, se debe especificar el objetivo qubits utilizado y el número de objetivos especificados debe ser igual al número de qubits sobre los que actúa el observable. Si no se especifican objetivos, el observable debe operar solo en 1 qubit y se aplica a todos los qubits en paralelo.
+  `Probability` devuelve las probabilidades de medir estados básicos computacionales. Si no se especifica ningún objetivo, `Probability` devuelve la probabilidad de medir todos los estados base. Si se especifican los objetivos, solo se devuelven las probabilidades marginales de los vectores base en los qubits especificados. Los simuladores gestionados QPUs están limitados a un máximo de 15 qubits y los simuladores locales están limitados al tamaño de la memoria del sistema.
+  `Reduced density matrix` devuelve una matriz de densidad para un subsistema de los qubits objetivo especificados de un sistema de qubits. Para limitar el tamaño de este tipo de resultado, Braket limita el número de qubits objetivo a un máximo de 8.
+  `StateVector` devuelve el vector de estado completo. Está disponible en el simulador local.
+  `Sample` devuelve los recuentos de mediciones de un conjunto de qubit objetivo especificado y observable. Si no se especifican objetivos, el observable debe operar solo en 1 qubit y se aplica a todos los qubits en paralelo. Si se especifican objetivos, el número de objetivos especificados debe ser igual al número de qubits sobre el que actúa el observable.
+  `Variance` devuelve la varianza (`mean([x-mean(x)]2)`) del conjunto de qubit objetivo especificado y el observable como el tipo de resultado solicitado. Si no se especifican objetivos, el observable debe operar solo en 1 qubit y se aplica a todos los qubits en paralelo. De lo contrario, el número de objetivos especificados debe ser igual al número de qubits objetivo a los que se puede aplicar el observable.

 **Los tipos de resultados admitidos para los distintos proveedores son los siguientes:** 


|  |  |  |  |  |  |  |  |  | 
| --- |--- |--- |--- |--- |--- |--- |--- |--- |
|  |  Sim local  |   SV1   |   DM1   |   TN1   |   AQT   |   IonQ   |   IQM   |   Rigetti   | 
|  Gradiente adjunto  |  N  |  Y  |  N  |  N  |  N  |  N  |  N  |  N  | 
|  Amplitude  |  Y  |  Y  |  N  |  N  |  N  |  N  |  N  |  N  | 
|  Expectativa  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  | 
|  Probability  |  Y  |  Y  |  Y  |  N  |  Y  |  Y  |  Y  |  Y  | 
|  Matriz de densidad reducida  |  Y  |  N  |  Y  |  N  |  N  |  N  |  N  |  N  | 
|  Vector de estado  |  Y  |  N  |  N  |  N  |  N  |  N  |  N  |  N  | 
|  Muestra  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  | 
|  Varianza  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  |  Y  | 

Puede comprobar los tipos de resultados compatibles examinando las propiedades del dispositivo, como se muestra en el siguiente ejemplo.

```
from braket.aws import AwsDevice

device = AwsDevice("arn:aws:braket:us-west-1::device/qpu/rigetti/Ankaa-3")

# Print the result types supported by this device
for iter in device.properties.action['braket.ir.openqasm.program'].supportedResultTypes:
    print(iter)
```

```
name='Sample' observables=['x', 'y', 'z', 'h', 'i'] minShots=10 maxShots=50000
name='Expectation' observables=['x', 'y', 'z', 'h', 'i'] minShots=10 maxShots=50000
name='Variance' observables=['x', 'y', 'z', 'h', 'i'] minShots=10 maxShots=50000
name='Probability' observables=None minShots=10 maxShots=50000
```

Para llamar a `ResultType`, añádalo a un circuito, como se muestra en el siguiente ejemplo.

```
from braket.circuits import Circuit, Observable

circ = Circuit().h(0).cnot(0, 1).amplitude(state=["01", "10"])
circ.probability(target=[0, 1])
circ.probability(target=0)
circ.expectation(observable=Observable.Z(), target=0)
circ.sample(observable=Observable.X(), target=0)
circ.state_vector()
circ.variance(observable=Observable.Z(), target=0)

# Print one of the result types assigned to the circuit
print(circ.result_types[0])
```

**nota**  
Los diferentes dispositivos cuánticos proporcionan resultados en varios formatos. Por ejemplo, los dispositivos Rigetti devuelven mediciones, mientras que los dispositivos IonQ ofrecen probabilidades. El SDK de Amazon Braket ofrece una propiedad de medición para todos los resultados. Sin embargo, en el caso de los dispositivos que devuelven probabilidades, estas mediciones se calculan posteriormente y se basan en las probabilidades, ya que las mediciones por shot no están disponibles. Para determinar si un resultado se ha computado posteriormente, compruebe las `measurements_copied_from_device` en el objeto de resultado. Esta operación se detalla en el archivo [gate\$1model\$1quantum\$1task\$1result.py](https://github.com/aws/amazon-braket-sdk-python/blob/ca5b08dada4839ca31c012ff50aa20b656fd1879/src/braket/tasks/gate_model_quantum_task_result.py#L70-L72) del repositorio del SDK GitHub de Amazon Braket.

## Observables
<a name="braket-result-types-observables"></a>

La clase `Observable` de Amazon Braket le permite medir un observable específico. 

Solo puede aplicar un único observable no identitario a cada qubit. Se produce un error si se especifican dos o más observables no identitarios diferentes para el mismo qubit. Para este propósito, cada factor de un producto tensorial cuenta como un observable individual. Esto significa que puede tener varios productos tensoriales en el mismo qubit, siempre y cuando los factores que actúen en el qubit sigan siendo los mismos.

Es posible escalar un observable y añadir otros observables (escalados o no). Esto crea una `Sum` que se puede usar en el tipo de resultado `AdjointGradient`.

La clase `Observable` incluye los siguientes observables.

```
import numpy as np

Observable.I()
Observable.H()
Observable.X()
Observable.Y()
Observable.Z()

# Get the eigenvalues of the observable
print("Eigenvalue:", Observable.H().eigenvalues)
# Or rotate the basis to be computational basis
print("Basis rotation gates:", Observable.H().basis_rotation_gates)

# Get the tensor product of the observable for the multi-qubit case
tensor_product = Observable.Y() @ Observable.Z()
# View the matrix form of an observable by using
print("The matrix form of the observable:\n", Observable.Z().to_matrix())
print("The matrix form of the tensor product:\n", tensor_product.to_matrix())

# Factorize an observable in the tensor form
print("Factorize an observable:", tensor_product.factors)

# Self-define observables, given it is a Hermitian
print("Self-defined Hermitian:", Observable.Hermitian(matrix=np.array([[0, 1], [1, 0]])))

print("Sum of other (scaled) observables:", 2.0 * Observable.X() @ Observable.X() + 4.0 * Observable.Z() @ Observable.Z())
```

```
Eigenvalue: [ 1. -1.]
Basis rotation gates: (Ry('angle': -0.7853981633974483, 'qubit_count': 1),)
The matrix form of the observable:
 [[ 1.+0.j  0.+0.j]
 [ 0.+0.j -1.+0.j]]
The matrix form of the tensor product:
 [[ 0.+0.j  0.+0.j  0.-1.j  0.+0.j]
 [ 0.+0.j -0.+0.j  0.+0.j  0.+1.j]
 [ 0.+1.j  0.+0.j  0.+0.j  0.+0.j]
 [ 0.+0.j  0.-1.j  0.+0.j -0.+0.j]]
Factorize an observable: (Y('qubit_count': 1), Z('qubit_count': 1))
Self-defined Hermitian: Hermitian('qubit_count': 1, 'matrix': [[0.+0.j 1.+0.j], [1.+0.j 0.+0.j]])
Sum of other (scaled) observables: Sum(TensorProduct(X('qubit_count': 1), X('qubit_count': 1)), TensorProduct(Z('qubit_count': 1), Z('qubit_count': 1)))
```

## Parameters
<a name="braket-result-types-parameters"></a>

Los circuitos pueden incorporar parámetros libres. Estos parámetros libres solo deben construirse una vez para ejecutarse varias veces y pueden utilizarse para calcular gradientes. 

Cada parámetro libre utiliza un nombre codificado en cadena que se utiliza para lo siguiente: 
+ Establecer valores de parámetros
+ Identificar qué parámetros utilizar

```
from braket.circuits import Circuit, FreeParameter, observables
from braket.parametric import FreeParameter

theta = FreeParameter("theta")
phi = FreeParameter("phi")
circ = Circuit().h(0).rx(0, phi).ry(0, phi).cnot(0, 1).xx(0, 1, theta)
```

## Gradiente adjunto
<a name="braket-result-types-adjoint-gradient"></a>

El dispositivo SV1 calcula el gradiente adjunto de un valor esperado observable, incluido el hamiltoniano multitérmino. Para diferenciar los parámetros, especifique su nombre (en formato de cadena) o por referencia directa.

```
from braket.aws import AwsDevice
from braket.devices import Devices

device = AwsDevice(Devices.Amazon.SV1)

circ.adjoint_gradient(observable=3 * Observable.Z(0) @ Observable.Z(1) - 0.5 * observables.X(0), parameters = ["phi", theta])
```

Al transferir valores de parámetros fijos como argumentos a un circuito parametrizado, se eliminarán los parámetros libres. La ejecución de este circuito con `AdjointGradient` produce un error, ya que los parámetros libres ya no existen. El siguiente ejemplo de código demuestra el uso correcto e incorrecto:

```
# Will error, as no free parameters will be present
#device.run(circ(0.2), shots=0)

# Will succeed
device.run(circ, shots=0, inputs={'phi': 0.2, 'theta': 0.2})
```