Variables y Parámetros
Variables
Este módulo ofrece herramientas para definir distintos tipos de variables:
Variables Continuascon los siguientes parámetros personalizables:Dominio: Especifica el tipo de variable, uno de
REAL,INTEGER,POSITIVE_INTEGER,BINARY, oSPIN.Límites: Define el rango de valores permitidos de la variable.
Codificación: Especifica cómo se representa la variable mediante codificaciones binarias, una de:
Bitwise,DomainWall, oOneHot.Precisión: Aplicable al dominio
Domain.REAL; define la resolución (p. ej., precisión de punto flotante).
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.