Variables y Parámetros

Variables

Este módulo ofrece herramientas para definir distintos tipos de variables:

Un ejemplo de creación de distintos tipos de variables:

from qilisdk.core.variables import BinaryVariable, Bitwise, Domain, SpinVariable, Variable

x = Variable("x", domain=Domain.REAL, bounds=(1, 2), encoding=Bitwise, precision=1e-1)
s = SpinVariable("s")
b = BinaryVariable("b")

Las variables continuas admiten indexación, donde cada índice hace referencia a un componente de la forma codificada en binario de la variable. Por ejemplo:

print(x.to_binary())

Salida:

(0.1) * x(0) + (0.2) * x(1) + (0.4) * x(2) + (0.30000000000000004) * x(3) + (1.0)

Para indexar la primera variable binaria de la representación binaria de x puede escribir: x[0]. Cada configuración de variable binaria genera un número en coma flotante dentro de los límites, según la precisión definida. Por ejemplo:

x.evaluate([0, 1, 0, 0])

Salida:

1.2

Parámetros

Muchos componentes de QiliSDK exponen parámetros simbólicos que pueden ser optimizados o reasignados en tiempo de ejecución. La clase Parameter representa un símbolo escalar con límites opcionales, y Parameterizable proporciona una API uniforme (get_parameter_names(), set_parameter_values()…) implementada por circuitos, planificaciones, modelos y más.

from qilisdk.core import Parameter

theta = Parameter("theta", value=0.5, bounds=(0.0, 1.0))
print(theta.value)     # 0.5
theta.set_value(0.75)
print(theta.bounds)    # (0.0, 1.0)

Los parámetros se comportan como variables simbólicas en expresiones algebraicas, de modo que se pueden combinar con otras variables y evaluar términos sin necesidad de pasar el parámetro explícitamente: su value almacenado se utiliza automáticamente.

Los objetos que heredan de Parameterizable recopilan todas las instancias de Parameter que encuentran. Por ejemplo:

from qilisdk.digital import Circuit, RX

circuit = Circuit(nqubits=1)
circuit.add(RX(0, theta=theta))

print(circuit.get_parameter_names())   # ['RX(0)_theta_0']
print(circuit.get_parameter_values())  # [0.75]
circuit.set_parameters({"RX(0)_theta_0": 0.9})

Todos los métodos auxiliares de parámetros aceptan un predicado where opcional para filtrar los parámetros expuestos. Esto es útil cuando se desea actualizar únicamente un subconjunto, como los parámetros entrenables.

trainable_values = circuit.get_parameter_values(where=lambda p: p.is_trainable)
circuit.set_parameter_values([0.3], where=lambda p: p.is_trainable)

Nota

Los objetos Parameterizable exponen el estado de los parámetros mediante get_parameters(), get_parameter_names(), get_parameter_values(), y los métodos set_* correspondientes. El acceso directo a .parameters no forma parte de la API pública.