Skip to main content
IBM Quantum Platform

Expressões clássicas

qiskit.circuit.classical

Esse módulo contém uma representação exploratória de operações em tempo real sobre valores clássicos durante a execução do circuito.

Atualmente, apenas expressões simples em bits e registros que resultam em um valor booleano são suportadas, e elas são válidas apenas para uso nas condições de QuantumCircuit.if_test() (IfElseOp) e QuantumCircuit.while_loop() (WhileLoopOp), e no destino de QuantumCircuit.switch() (SwitchCaseOp).

Nota

Este é um módulo exploratório e, embora nos comprometamos com a política padrão de depreciação do Qiskit, esteja ciente de que o módulo terá um escopo deliberadamente limitado no início, e as primeiras versões podem não evoluir de forma limpa para a versão final. É possível que vários componentes desse módulo sejam substituídos (sujeitos a depreciações) em vez de aprimorados em um novo formato.

O sistema de tipos e a árvore de expressões serão expandidos com o tempo, e é possível que os tipos permitidos de algumas operações precisem mudar entre as versões do Qiskit à medida que os recursos de processamento clássico se desenvolvem.


Expressões

qiskit.circuit.classical.expr

Os componentes necessários para criar expressões são todos exportados do namespace expr dentro de qiskit.circuit.classicalportanto, você pode escolher se deseja usar o acesso qualificado (por exemplo expr.Value) ou importar os nomes de que você precisa diretamente e chamá-los sem o prefixo.

Há dois caminhos para a construção de expressões. As classes que formam a representação do sistema de expressão têm construtores que realizam verificação de tipo zero; cabe ao chamador garantir que eles estejam construindo objetos válidos. Para uma interface mais amigável para a construção direta, há funções auxiliares associadas à maioria das classes que fazem validação e inferência de tipos. Eles são descritos abaixo, em Construção.

Representação

O sistema de expressão é baseado na representação em árvore. Todos os nós da árvore são instâncias finais (não herdáveis) da classe base abstrata:

Expr

class qiskit.circuit.classical.expr.Expr

Bases: object

Classe base da raiz de todos os nós na árvore de expressão. O caso base nunca deve ser instanciado diretamente.

Isso não deve ser subclassificado pelos usuários; as subclasses formam os dados internos da representação das expressões, e não faz sentido adicionar mais fora do código da biblioteca do Qiskit.

Todas as subclasses são responsáveis por definir seu type atributo em seu __init__, e não devem chamar o inicializador da classe pai.

Esses objetos são mutáveis e não devem ser reutilizados em um local diferente sem uma cópia.

Todas as instâncias Expr definem um atributo booleano const , que indica se a expressão pode ser avaliada em tempo de compilação. A maioria das classes de expressão inferem isso durante a construção com base na constância de seus operandos.

A base para variáveis dinâmicas é a variável Varque pode ser uma variável de tempo real arbitrariamente digitada ou um invólucro em torno de uma variável Clbit ou ClassicalRegister.

Var

class qiskit.circuit.classical.expr.Var(var, type, *, name=None)

Bases: Expr

Uma variável clássica.

Essas variáveis assumem duas formas: uma variável de novo estilo que possui seu local de armazenamento e tem um nome associado; e uma variável de estilo antigo que envolve um Clbit ou ClassicalRegister que é propriedade de algum circuito que a contém. Em geral, a construção de variáveis para uso em programas deve usar Var.new() ou QuantumCircuit.add_var().

As variáveis são imutáveis após a criação, portanto, podem ser usadas como chaves de dicionário.

name

O nome da variável. Isso deve existir se o atributo backing var for um UUID,, ou seja, se for uma variável do novo estilo, e deve ser None `` se for uma variável do estilo antigo.

new

classmethod new(name, ty)

Gera uma nova variável nomeada que possui seu próprio armazenamento de apoio.

var

Uma referência ao armazenamento de dados de backup da Var instância. Ao migrar instâncias do Clbit tipo antigo ClassicalRegister para um Var, isso é exatamente o Clbit ou ClassicalRegister. Se a variável for uma variável clássica do novo estilo (aquela que possui seu próprio espaço de armazenamento, separado do antigo Clbit/ClassicalRegister modelo), este campo será um UUID para identificá-la de forma exclusiva.

Da mesma forma, os literais usados em expressões (como números inteiros) devem ser elevados a nós Value com tipos associados. A Value é sempre considerada uma expressão constante.

Valor

class qiskit.circuit.classical.expr.Value(value, type)

Bases: Expr

Um único valor escalar.

As variáveis de alongamento para uso em expressões de duração são representadas pelo nó Stretch nó.

Esticar

class qiskit.circuit.classical.expr.Stretch(var, name)

Bases: Expr

Uma variável de extensão.

Em geral, a construção de variáveis de extensão para uso em programas deve usar Stretch.new() ou QuantumCircuit.add_stretch()

name

O nome da variável de extensão.

new

classmethod new(name)

Gerar uma nova variável de extensão nomeada.

var

A UUID para identificar exclusivamente esse trecho.

As operações tradicionalmente associadas aos operadores pré, pós ou infixos na programação são representadas pelos operadores Unary e Binary conforme apropriado. Cada uma delas recebe um código de tipo de operação, que é exposto como enumerações dentro de cada classe como Unary.Op e Binary.Op respectivamente.

Unário

class qiskit.circuit.classical.expr.Unary(op, operand, type)

Bases: Expr

Uma expressão unária.

Parâmetros

  • op - O código de operação que descreve a operação que está sendo realizada.
  • operando - O operando da operação.
  • type - O tipo resolvido do resultado.
Op

class Op(*values)

Bases: Enum

Enumeração dos códigos de operação para operações unárias.

A negação bit a bit BIT_NOT usa um único bit ou um número inteiro sem sinal de largura conhecida e retorna um valor do mesmo tipo.

A negação lógica LOGIC_NOT recebe uma entrada que é implicitamente coagida a um booleano e retorna um booleano.

A negação aritmética NEGATE recebe como entrada um valor do tipo float ou duration e retorna um valor do mesmo tipo.

Binário

class qiskit.circuit.classical.expr.Binary(op, left, right, type)

Bases: Expr

Uma expressão binária.

Parâmetros

  • op - O código de operação que descreve a operação que está sendo realizada.
  • left - O operando do lado esquerdo.
  • right - O operando do lado direito.
  • type - O tipo resolvido do resultado.
Op

class Op(*values)

Bases: Enum

Enumeração dos códigos de operação para operações binárias.

As operações bit a bit BIT_AND, BIT_OR e BIT_XOR aplicam-se a dois operandos do mesmo tipo, que deve ser um bit único ou um inteiro sem sinal de largura fixa. O tipo resultante é o mesmo que os dois tipos de entrada.

As operações lógicas LOGIC_AND e LOGIC_OR primeiro coerem implicitamente seus argumentos para booleanos e, em seguida, aplicam a operação lógica. O tipo resultante é sempre booleano.

As relações matemáticas binárias EQUAL, NOT_EQUAL, LESS, LESS_EQUAL, GREATER e GREATER_EQUAL recebem números inteiros sem sinal (com uma conversão implícita para torná-los da mesma largura) e retornam um booleano.

As operações de bitshift SHIFT_LEFT e SHIFT_RIGHT podem receber tipos de contêineres do tipo bit (por exemplo, números inteiros sem sinal) como operando à esquerda e qualquer tipo de número inteiro como operando à direita. Em todos os casos, a largura do bit de saída é a mesma da entrada, e os zeros preenchem os espaços "expostos".

Os operadores aritméticos ADD binários, SUB, MUL, e DIV podem ser aplicados a dois números de precisão flutuante ou a dois inteiros sem sinal, os quais devem ser ajustados para terem a mesma largura durante a construção por meio de uma conversão de tipo. Os DIV operadores ADD, SUB, e podem ser aplicados a duas durações, resultando em outra duração ou em um número real no caso de DIV. O MUL operador também pode ser aplicado a uma duração e a um tipo numérico, resultando em outra duração. Por fim, o DIV operador pode ser usado para dividir uma duração por um valor numérico, resultando em uma duração.

Os tipos do tipo bit (inteiros sem sinal) podem ser indexados por tipos inteiros, representados por Index. O resultado é um único bit. A expressão resultante tem um local de memória associado (e, portanto, pode ser usada como um valor l para Storeetc.) se o destino também for um valor l.

Índice

class qiskit.circuit.classical.expr.Index(target, index, type)

Bases: Expr

Uma expressão de indexação.

Parâmetros

  • alvo - O objeto que está sendo indexado.
  • index - A expressão que faz a indexação.
  • type - O tipo resolvido do resultado.

Ao construir expressões, é preciso garantir que os tipos sejam válidos para a operação. As tentativas de construir expressões com tipos inválidos gerarão uma mensagem regular Python TypeError.

As expressões nesse sistema são definidas para atuar somente em determinados conjuntos de tipos. Entretanto, os valores podem ser convertidos em um supertipo adequado para atender aos requisitos de tipagem. Nesses casos, um nó na árvore de expressão é usado para representar a promoção. Em todos os casos em que as operações observam que "convertem implicitamente" ou "coagem" seus argumentos, a árvore de expressões deve ter esse nó representando a conversão.

Converter

class qiskit.circuit.classical.expr.Cast(operand, type, implicit=False)

Bases: Expr

Uma conversão de um tipo para outro, implícita no uso de uma expressão em um contexto diferente.

Construção

A construção direta da representação da árvore é verbosa e é fácil cometer um erro de digitação. Em muitos casos, grande parte da tipagem pode ser inferida, os valores escalares podem ser promovidos automaticamente para Value instâncias, e todas as promoções necessárias podem ser resolvidas em nós Cast adequados.

As funções e os métodos descritos nesta seção são uma maneira mais amigável de criar a árvore de expressões, mantendo-se próximos da representação interna. Todas essas funções elevarão automaticamente os valores escalares válidos do Python para o correspondente Var ou Value correspondentes e resolverão quaisquer conversões implícitas necessárias em seu nome. Se você quiser usar diretamente algum valor escalar como um nó Expr nó, você pode manualmente lift() manualmente.

lift

qiskit.circuit.classical.expr.lift(value, /, type=None)

GitHub

Eleve o endereço Python value para um Value ou Var.

Se for fornecido um type explícito, a digitação na saída refletirá isso.

Exemplos

Elevação de objetos de circuito simples para serem Var instâncias:

>>> from qiskit.circuit import Clbit, ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.lift(Clbit())
Var(<clbit>, Bool())
>>> expr.lift(ClassicalRegister(3, "c"))
Var(ClassicalRegister(3, "c"), Uint(3))

O tipo do valor de retorno pode ser alterado, caso o valor fornecido possa ser interpretado sem perda de informação como o tipo especificado (use cast() para realizar um conjunto completo de operações de conversão, incluindo aquelas com perda de informação):

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr, types
>>> expr.lift(ClassicalRegister(3, "c"), types.Uint(5))
Var(ClassicalRegister(3, "c"), Uint(5))
>>> expr.lift(5, types.Uint(4))
Value(5, Uint(4))

Parâmetros

Tipo de retorno

Expr

Normalmente, você deve criar instâncias que possuem memória Var usando o método QuantumCircuit.add_var() para declará-las em algum contexto de circuito, já que o método QuantumCircuit não aceitará um Expr que contenha variáveis que ainda não tenham sido declaradas nele, pois ele precisa saber como alocar o armazenamento e como a variável será inicializada. No entanto, se quiser fazer isso manualmente, você deve usar a chamada de baixo nível Var.new() de baixo nível para gerar com segurança uma variável nomeada para uso.

Você pode especificar manualmente as conversões nos casos em que a conversão é permitida na forma explícita, mas pode ter perdas (como a conversão de uma precisão maior Uint para um de menor precisão).

cast

qiskit.circuit.classical.expr.cast(operand, type, /)

GitHub

Cria uma conversão explícita do valor fornecido para o tipo fornecido.

Exemplos

Adicione um nó de conversão explícito que converte explicitamente um tipo de precisão maior em um de precisão menor:

>>> from qiskit.circuit.classical import expr, types
>>> value = expr.value(5, types.Uint(32))
>>> expr.cast(value, types.Uint(8))
Cast(Value(5, types.Uint(32)), types.Uint(8), implicit=False)

Parâmetros

Tipo de retorno

Expr

Há funções de construtor auxiliar para cada uma das operações unárias.

bit_not

qiskit.circuit.classical.expr.bit_not(operand, /)

GitHub

Cria um nó de expressão bit a bit 'not' a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando o valor em um nó Value se necessário.

Exemplos

Negação bit a bit de a ClassicalRegister:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_not(ClassicalRegister(3, "c"))
Unary(Unary.Op.BIT_NOT, Var(ClassicalRegister(3, 'c'), Uint(3)), Uint(3))

Parâmetros

operand (Any)

Tipo de retorno

Expr

logic_not

qiskit.circuit.classical.expr.logic_not(operand, /)

GitHub

Cria um nó de expressão "não" lógico a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando o valor para um nó Value se necessário.

Exemplos

Negação lógica de a ClassicalRegister:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.logic_not(ClassicalRegister(3, "c"))
Unary(Unary.Op.LOGIC_NOT, Cast(Var(ClassicalRegister(3, 'c'), Uint(3)), Bool(), implicit=True), Bool())

Parâmetros

operand (Any)

Tipo de retorno

Expr

negate

qiskit.circuit.classical.expr.negate(operand, /)

GitHub

Negar um nó de expressão a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando o valor a um Value nó, se necessário.

Exemplos

Negação de um número de ponto flutuante:

>>> from qiskit.circuit.classical import expr
>>> expr.negate(5.0)
Unary(Unary.Op.NEGATE, Value(5.0, Float()), Float())

Negação de uma duração:

>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.negate(Duration.dt(1000))
Unary(Unary.Op.NEGATE, Value(Duration.dt(1000), Duration()), Duration())

Parâmetros

operand (Any)

Tipo de retorno

Expr

Da mesma forma, as operações e relações binárias têm funções auxiliares definidas.

bit_and

qiskit.circuit.classical.expr.bit_and(left, right, /)

GitHub

Cria um nó de expressão bit a bit 'and' a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores em nós Value se necessário.

Exemplos

"e" bit a bit de um registro clássico e um literal de número inteiro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_and(ClassicalRegister(3, "c"), 0b111)
Binary(Binary.Op.BIT_AND, Var(ClassicalRegister(3, 'c'), Uint(3)), Value(7, Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

bit_or

qiskit.circuit.classical.expr.bit_or(left, right, /)

GitHub

Cria um nó de expressão "ou" bit a bit a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores em nós Value se necessário.

Exemplos

"Ou" bit a bit de um registro clássico e um literal de número inteiro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_or(ClassicalRegister(3, "c"), 0b101)
Binary(Binary.Op.BIT_OR, Var(ClassicalRegister(3, 'c'), Uint(3)), Value(5, Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

bit_xor

qiskit.circuit.classical.expr.bit_xor(left, right, /)

GitHub

Cria um nó de expressão bit a bit "exclusivo ou" a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores em nós Value se necessário.

Exemplos

"Ou exclusivo" bit a bit de um registro clássico e um literal inteiro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.bit_xor(ClassicalRegister(3, "c"), 0b101)
Binary(Binary.Op.BIT_XOR, Var(ClassicalRegister(3, 'c'), Uint(3)), Value(5, Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

logic_and

qiskit.circuit.classical.expr.logic_and(left, right, /)

GitHub

Cria um nó de expressão "e" lógico a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

"e" lógico de dois bits clássicos:

>>> from qiskit.circuit import Clbit
>>> from qiskit.circuit.classical import expr
>>> expr.logic_and(Clbit(), Clbit())
Binary(Binary.Op.LOGIC_AND, Var(<clbit 0>, Bool()), Var(<clbit 1>, Bool()), Bool())

Parâmetros

Tipo de retorno

Expr

logic_or

qiskit.circuit.classical.expr.logic_or(left, right, /)

GitHub

Cria um nó de expressão "ou" lógico a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

"Ou" lógico de dois bits clássicos

>>> from qiskit.circuit import Clbit
>>> from qiskit.circuit.classical import expr
>>> expr.logic_or(Clbit(), Clbit())
Binary(Binary.Op.LOGIC_OR, Var(<clbit 0>, Bool()), Var(<clbit 1>, Bool()), Bool())

Parâmetros

Tipo de retorno

Expr

equal

qiskit.circuit.classical.expr.equal(left, right, /)

GitHub

Cria um nó de expressão "igual" a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

Igualdade entre um registro clássico e um número inteiro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.equal(ClassicalRegister(3, "c"), 7)
Binary(Binary.Op.EQUAL, Var(ClassicalRegister(3, "c"), Uint(3)), Value(7, Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

not_equal

qiskit.circuit.classical.expr.not_equal(left, right, /)

GitHub

Cria um nó de expressão "não igual" a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

Desigualdade entre um registrador clássico e um número inteiro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.not_equal(ClassicalRegister(3, "c"), 7)
Binary(Binary.Op.NOT_EQUAL, Var(ClassicalRegister(3, "c"), Uint(3)), Value(7, Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

less

qiskit.circuit.classical.expr.less(left, right, /)

GitHub

Cria um nó de expressão "menor que" a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

Consulta se um registro clássico é menor que um número inteiro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.less(ClassicalRegister(3, "c"), 5)
Binary(Binary.Op.LESS, Var(ClassicalRegister(3, "c"), Uint(3)), Value(5, Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

less_equal

qiskit.circuit.classical.expr.less_equal(left, right, /)

GitHub

Cria um nó de expressão "menor que ou igual a" a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores em nós Value se necessário.

Exemplos

Consulta se um registro clássico é menor ou igual a outro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.less_equal(ClassicalRegister(3, "a"), ClassicalRegister(3, "b"))
Binary(Binary.Op.LESS_EQUAL, Var(ClassicalRegister(3, "a"), Uint(3)), Var(ClassicalRegister(3, "b"), Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

greater

qiskit.circuit.classical.expr.greater(left, right, /)

GitHub

Cria um nó de expressão "maior que" a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

Consulta se um registro clássico é maior que um número inteiro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.greater(ClassicalRegister(3, "c"), 5)
Binary(Binary.Op.GREATER, Var(ClassicalRegister(3, "c"), Uint(3)), Value(5, Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

greater_equal

qiskit.circuit.classical.expr.greater_equal(left, right, /)

GitHub

Cria um nó de expressão "maior que ou igual a" a partir do valor fornecido, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

Consulta se um registro clássico é maior ou igual a outro:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.greater_equal(ClassicalRegister(3, "a"), ClassicalRegister(3, "b"))
Binary(Binary.Op.GREATER_EQUAL, Var(ClassicalRegister(3, "a"), Uint(3)), Var(ClassicalRegister(3, "b"), Uint(3)), Uint(3))

Parâmetros

Tipo de retorno

Expr

shift_left

qiskit.circuit.classical.expr.shift_left(left, right, /, type=None)

GitHub

Cria um nó de expressão 'bitshift left' a partir dos dois valores fornecidos, resolvendo quaisquer conversões implícitas e elevando os valores em nós Value se necessário.

Se type for fornecido, o operando left será coagido a ele (se possível).

Exemplos

Deslocar o valor de uma variável autônoma para a esquerda em algum valor:

>>> from qiskit.circuit.classical import expr, types
>>> a = expr.Var.new("a", types.Uint(8))
>>> expr.shift_left(a, 4)
Binary(Binary.Op.SHIFT_LEFT, Var(<UUID>, Uint(8), name='a'), Value(4, Uint(3)), Uint(8))

Desloca um literal inteiro em um valor variável, forçando o tipo do literal:

>>> expr.shift_left(3, a, types.Uint(16))
Binary(Binary.Op.SHIFT_LEFT, Value(3, Uint(16)), Var(<UUID>, Uint(8), name='a'), Uint(16))

Parâmetros

Tipo de retorno

Expr

shift_right

qiskit.circuit.classical.expr.shift_right(left, right, /, type=None)

GitHub

Cria um nó de expressão 'bitshift right' a partir dos valores fornecidos, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Se type for fornecido, o operando left será coagido a ele (se possível).

Exemplos

Deslocar o valor de um registrador clássico para a direita por algum valor:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.shift_right(ClassicalRegister(8, "a"), 4)
Binary(Binary.Op.SHIFT_RIGHT, Var(ClassicalRegister(8, "a"), Uint(8)), Value(4, Uint(3)), Uint(8))

Parâmetros

Tipo de retorno

Expr

add

qiskit.circuit.classical.expr.add(left, right, /)

GitHub

Cria um nó de expressão de adição a partir dos valores fornecidos, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

Adição de dois números de ponto flutuante:

>>> from qiskit.circuit.classical import expr
>>> expr.add(5.0, 2.0)
Binary(Binary.Op.ADD, Value(5.0, Float()), Value(2.0, Float()), Float())

Adição de duas durações:

>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.add(Duration.dt(1000), Duration.dt(1000))
Binary(Binary.Op.ADD, Value(Duration.dt(1000), Duration()), Value(Duration.dt(1000), Duration()), Duration())

Parâmetros

Tipo de retorno

Expr

sub

qiskit.circuit.classical.expr.sub(left, right, /)

GitHub

Cria um nó de expressão de subtração a partir dos valores fornecidos, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Exemplos

Subtração de dois números de ponto flutuante:

>>> from qiskit.circuit.classical import expr
>>> expr.sub(5.0, 2.0)
Binary(Binary.Op.SUB, Value(5.0, Float()), Value(2.0, Float()), Float())

Subtração de duas durações:

>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.add(Duration.dt(1000), Duration.dt(1000))
Binary(Binary.Op.SUB, Value(Duration.dt(1000), Duration()), Value(Duration.dt(1000), Duration()), Duration())

Parâmetros

Tipo de retorno

Expr

mul

qiskit.circuit.classical.expr.mul(left, right)

GitHub

Cria um nó de expressão de multiplicação a partir dos valores fornecidos, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Isso pode ser usado para multiplicar operandos numéricos do mesmo tipo ou para multiplicar um operando de duração por um operando numérico.

Exemplos

Multiplicação de dois números de ponto flutuante:

>>> from qiskit.circuit.classical import expr
>>> expr.mul(5.0, 2.0)
Binary(Binary.Op.MUL, Value(5.0, Float()), Value(2.0, Float()), Float())

Multiplicação de uma duração por um float:

>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.mul(Duration.dt(1000), 0.5)
Binary(Binary.Op.MUL, Value(Duration.dt(1000), Duration()), Value(0.5, Float()), Duration())

Parâmetros

Tipo de retorno

Expr

div

qiskit.circuit.classical.expr.div(left, right)

GitHub

Cria um nó de expressão de divisão a partir dos valores fornecidos, resolvendo quaisquer conversões implícitas e elevando os valores para nós Value se necessário.

Isso pode ser usado para dividir operandos numéricos do mesmo tipo, para dividir um Duration operando por um operando numérico ou para dividir dois Duration que produz uma expressão do tipo Float.

Exemplos

Divisão de dois números de ponto flutuante:

>>> from qiskit.circuit.classical import expr
>>> expr.div(5.0, 2.0)
Binary(Binary.Op.DIV, Value(5.0, Float()), Value(2.0, Float()), Float())

Divisão de duas durações:

>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.div(Duration.dt(10000), Duration.dt(1000))
Binary(Binary.Op.DIV, Value(Duration.dt(10000), Duration()), Value(Duration.dt(1000), Duration()), Float())

Divisão de uma duração por um float:

>>> from qiskit.circuit import Duration
>>> from qiskit.circuit.classical import expr
>>> expr.div(Duration.dt(10000), 12.0)
Binary(Binary.Op.DIV, Value(Duration.dt(10000), Duration()), Value(12.0, types.Float()), Duration())

Parâmetros

Tipo de retorno

Expr

Você pode indexar em números inteiros sem sinal e bit-likes usando outro número inteiro sem sinal de qualquer largura. Isso inclui operações de armazenamento, se o destino do índice for gravável.

index

qiskit.circuit.classical.expr.index(target, index, /)

GitHub

Indexar no site target com o número inteiro fornecido index, elevando os valores em Value se necessário.

Isso pode ser usado como o destino de um Storese o target for um valor l.

Exemplos

Indexação em um registro clássico com um literal:

>>> from qiskit.circuit import ClassicalRegister
>>> from qiskit.circuit.classical import expr
>>> expr.index(ClassicalRegister(8, "a"), 3)
Index(Var(ClassicalRegister(8, "a"), Uint(8)), Value(3, Uint(2)), Bool())

Parâmetros

Tipo de retorno

Expr

O método legado do Qiskit para especificar condições de igualdade para uso em condicionais é usar um tuplo duplo de um Clbit ou ClassicalRegister e um número inteiro. Isso representa uma condição de igualdade exata, e não há como especificar outras relações. A função auxiliar lift_legacy_condition() converte esse formato legado na nova sintaxe de expressão.

lift_legacy_condition

qiskit.circuit.classical.expr.lift_legacy_condition(condition, /)

GitHub

Transforme uma condição de igualdade de duas tuplas legada em um novo estilo Expr.

Parâmetros

condition (tuple[qiskit.circuit.Clbit |qiskit.circuit.ClassicalRegister, int])

Tipo de retorno

Expr

Trabalhando com a árvore de expressões

Um consumidor típico da árvore de expressões deseja percorrer a árvore de forma recursiva, potencialmente com estado, agindo em cada nó de forma diferente, dependendo do seu tipo. Naturalmente, esse é um problema de despacho duplo; a lógica de "o que deve ser feito" provavelmente tem estado e os usuários devem ser livres para definir suas próprias operações, mas cada nó define "o que está sendo feito". Permitimos esse envio duplo fornecendo uma classe de visitante base para a árvore de expressões.

ExprVisitor

class qiskit.circuit.classical.expr.ExprVisitor

GitHub

Bases: Generic[_T_co]

Classe base para visitantes da Expr árvore. As subclasses devem substituir qualquer um dos métodos do visit_* que puderem manipular e devem ser organizadas de forma que métodos inexistentes nunca sejam chamados.

visit_binary

visit_binary(node, /)

GitHub

Parâmetros

node (Binary)

Tipo de retorno

_T_co

visit_cast

visit_cast(node, /)

GitHub

Parâmetros

node (Cast)

Tipo de retorno

_T_co

visit_generic

visit_generic(node, /)

GitHub

Parâmetros

node (Expr)

Tipo de retorno

_T_co

visit_index

visit_index(node, /)

GitHub

Parâmetros

node (Index)

Tipo de retorno

_T_co

visit_stretch

visit_stretch(node, /)

GitHub

Parâmetros

node (Stretch)

Tipo de retorno

_T_co

visit_unary

visit_unary(node, /)

GitHub

Parâmetros

node (Unary)

Tipo de retorno

_T_co

visit_value

visit_value(node, /)

GitHub

Parâmetros

node (Value)

Tipo de retorno

_T_co

visit_var

visit_var(node, /)

GitHub

Parâmetros

node (Var)

Tipo de retorno

_T_co

Os consumidores da árvore de expressões devem fazer uma subclasse do visitante e substituir os métodos visit_* que desejam manipular. Todos os métodos não substituídos chamarão visit_generic()que, a menos que seja substituído, gerará um RuntimeError para garantir que você esteja ciente de que novos nós foram adicionados à árvore de expressões que você ainda não está manipulando.

Para a conveniência de visitantes simples que só precisam inspecionar as variáveis em uma expressão e não a estrutura geral, o método iterador iter_vars() é fornecido.

iter_vars

qiskit.circuit.classical.expr.iter_vars(node)

GitHub

Obtém um iterador sobre os Var referenciados em qualquer nível no arquivo Expr.

Exemplos

Imprima o nome de cada ClassicalRegister encontrado:

from qiskit.circuit import ClassicalRegister
from qiskit.circuit.classical import expr

cr1 = ClassicalRegister(3, "a")
cr2 = ClassicalRegister(3, "b")

for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
    if isinstance(node.var, ClassicalRegister):
        print(node.var.name)
Veja Também

iter_identifiers()

Obtém um iterador sobre todos os nós identificadores na expressão, incluindo ambos Var e Stretch nós.

Parâmetros

node (Expr)

Tipo de retorno

Iterador[Var]

Para iterar sobre todas as variáveis, inclusive as variáveis de extensão, o método iterador iter_identifiers() é fornecido.

iter_identifiers

qiskit.circuit.classical.expr.iter_identifiers(node)

GitHub

Obter um iterador sobre o Var e Stretch referenciados em qualquer nível no nó Expr.

Exemplos

Imprima o nome de cada ClassicalRegister encontrado:

from qiskit.circuit import ClassicalRegister
from qiskit.circuit.classical import expr

cr1 = ClassicalRegister(3, "a")
cr2 = ClassicalRegister(3, "b")

for node in expr.iter_vars(expr.bit_and(expr.bit_not(cr1), cr2)):
    if isinstance(node.var, ClassicalRegister):
        print(node.var.name)
Veja Também

iter_vars()

Obtém um iterador sobre apenas os Var na expressão.

Parâmetros

node (Expr)

Tipo de retorno

Iterador[* Var* | Stretch ]

Duas expressões podem ser comparadas quanto à igualdade estrutural direta usando o operador incorporado Python == . Em geral, porém, é possível comparar duas expressões de forma um pouco mais semântica, permitindo que os nós Var dentro delas estejam vinculados a diferentes descrições de localização de memória entre dois circuitos diferentes. Nesse caso, é possível usar structurally_equivalent() com duas funções "chave" adequadas para fazer a comparação.

structurally_equivalent

qiskit.circuit.classical.expr.structurally_equivalent(left, right, left_var_key=None, right_var_key=None)

GitHub

Essas duas expressões têm exatamente a mesma estrutura de árvore, até alguma função-chave para os Var objetos?

Em outras palavras, essas duas expressões são exatamente as mesmas árvores, exceto que comparamos os campos Var.var chamando a função *_var_key apropriada neles e comparando a saída para igualdade. Essa função não permite nenhuma "equivalência" semântica, como afirmar que a == b é equivalente a b == a; a ordem de avaliação dos operandos poderia, em geral, fazer com que essa afirmação fosse falsa (considere as funções hipotéticas de extern que acessam o estado global).

Não há requisitos para as funções-chave, exceto o fato de que suas saídas devem ter métodos __eq__ gerais. Se uma função-chave retornar None, a variável será usada literalmente em seu lugar.

Parâmetros

  • left (Expr) – um dos nós Expr .
  • right (Expr) – o outro Expr nó.
  • left_var_key (Callable[[Any], Any] | None) – um chamável cuja saída deve ser usada na comparação de Var.var atributos. Se esse argumento for None ou sua saída for None para uma determinada variável em left, a variável será usada literalmente.
  • right_var_key (Callable[[Any], Any] | None) – o mesmo que left_var_key, mas usado nas variáveis em right em vez disso.

Tipo de retorno

bool

Exemplos

Comparação de duas expressões para equivalência estrutural, sem remapeamento das variáveis. Elas são diferentes porque as diferentes Clbit instâncias se comparam de forma diferente:

>>> from qiskit.circuit import Clbit
>>> from qiskit.circuit.classical import expr
>>> left_bits = [Clbit(), Clbit()]
>>> right_bits = [Clbit(), Clbit()]
>>> left = expr.logic_and(expr.logic_not(left_bits[0]), left_bits[1])
>>> right = expr.logic_and(expr.logic_not(right_bits[0]), right_bits[1])
>>> expr.structurally_equivalent(left, right)
False

Comparando as mesmas duas expressões, mas desta vez usando funções de mapeamento que associam os bits a índices simples:

>>> left_key = {var: i for i, var in enumerate(left_bits)}.get
>>> right_key = {var: i for i, var in enumerate(right_bits)}.get
>>> expr.structurally_equivalent(left, right, left_key, right_key)
True

Algumas expressões têm locais de memória associados, e outras podem ser puramente temporárias. Você pode usar is_lvalue() para determinar se uma expressão tem um local de memória associado.

is_lvalue

qiskit.circuit.classical.expr.is_lvalue(node, /)

GitHub

Retorna se essa expressão pode ser usada em posições de valor l, ou seja, se ela tem um local bem definido na memória, como um que possa ser gravado.

O fato de ser um valor l é necessário, mas não suficiente para que essa posição de memória seja gravável; é possível que um objeto maior que contenha essa posição de memória não permita a gravação a partir do escopo que tenta gravar nela. No entanto, isso seria uma propriedade de acesso do programa que a contém, e não uma propriedade inerente ao sistema de expressões.

Uma expressão constante nunca é um lvalue.

Exemplos

Os valores literais nunca são valores l; não há um local de memória associado (por exemplo) à constante 1:

>>> from qiskit.circuit.classical import expr
>>> expr.is_lvalue(expr.lift(2))
False

Var são sempre valores l, pois sempre têm algum local de memória associado:

>>> from qiskit.circuit.classical import types
>>> from qiskit.circuit import Clbit
>>> expr.is_lvalue(expr.Var.new("a", types.Bool()))
True
>>> expr.is_lvalue(expr.lift(Clbit()))
True

Atualmente, não há operações unárias ou binárias em variáveis que possam produzir uma expressão de valor l, mas é provável que, no futuro, seja adicionado algum tipo de operação de "indexação" que possa produzir valores l:

>>> a = expr.Var.new("a", types.Uint(8))
>>> b = expr.Var.new("b", types.Uint(8))
>>> expr.is_lvalue(a) and expr.is_lvalue(b)
True
>>> expr.is_lvalue(expr.bit_and(a, b))
False

Parâmetros

node (Expr)

Tipo de retorno

bool


typing

qiskit.circuit.classical.types

Representação

O sistema de tipos da árvore de expressões é exposto por meio desse módulo. Isso está intrinsecamente vinculado ao sistema de expressão no módulo expr já que a maioria das expressões só pode ser entendida com o contexto dos tipos em que atuam.

Todos os tipos são herdados de uma classe base abstrata:

Tipo

class qiskit.circuit.classical.types.Type

Bases: object

Classe base raiz de todos os nós na árvore de tipos. O caso base nunca deve ser instanciado diretamente.

Isso não deve ser subclassificado pelos usuários; as subclasses formam os dados internos da representação das expressões, e não faz sentido adicionar mais fora do código da biblioteca do Qiskit.

Os tipos devem ser considerados objetos imutáveis, e você não deve alterá-los. É permitido reutilizar um Type que você extrai de outro objeto sem copiá-lo e, geralmente, essa é a melhor abordagem para o desempenho. Type são projetados para serem pequenas quantidades de dados, e é melhor apontar para a mesma instância dos dados sempre que possível, em vez de alocar no heap uma nova versão da mesma coisa. Sempre que possível, os construtores de classe retornarão instâncias de singleton para facilitar isso.

O tipo Bool representa Clbit e os literais True e False, o tipo Uint tipo representa ClassicalRegister e Python inteiros, o tipo Float representa Python floats e o tipo Duration representa uma duração para uso em operações de circuito com reconhecimento de tempo.

bool

class qiskit.circuit.classical.types.Bool

Bases: Type

O tipo booleano. Isso tem exatamente dois valores: True e False.

uint

class qiskit.circuit.classical.types.Uint(width)

Bases: Type

Um número inteiro sem sinal de largura de bit fixa.

Valor flutuante

class qiskit.circuit.classical.types.Float

Bases: Type

Um número de ponto flutuante de dupla precisão IEEE-754.

No futuro, isso também poderá ser usado para representar outros floats de largura fixa.

Duração

class qiskit.circuit.classical.types.Duration

Bases: Type

Um período de tempo, possivelmente negativo.

Trabalhando com tipos

Há algumas funções adicionais nesses tipos documentadas nas seções subsequentes. Espera-se que eles sejam usados apenas em manipulações da árvore de expressões; os usuários que estão criando expressões usando a interface de construção voltada para o usuário não devem precisar usá-los.

Ordenação parcial de tipos

O sistema de tipos é equipado com uma ordenação parcial, em que a<ba < b é interpretado como " aa é um subtipo estrito de bb ". Observe que a ordenação parcial é um subconjunto do gráfico direcionado que descreve as operações de conversão explícitas permitidas entre os tipos. A ordenação parcial define quando um tipo pode ser interpretado diretamente, sem perdas, como outro.

A interface de baixo nível para consultar a relação de subtipagem é a função order() função.

order

qiskit.circuit.classical.types.order(left, right, /)

GitHub

Obtém a relação de ordenação entre os dois tipos como um valor de enumeração.

Exemplos

Compare dois Uint tipos de larguras diferentes:

>>> from qiskit.circuit.classical import types
>>> types.order(types.Uint(8), types.Uint(16))
Ordering.LESS

Compare dois tipos que não têm ordenação entre si:

>>> types.order(types.Uint(8), types.Bool())
Ordering.NONE

Parâmetros

Tipo de retorno

Pedidos

O valor de retorno é uma enumeração Ordering que descreve qual relação de subtipagem existe, se houver, entre os dois tipos.

Ordem

class qiskit.circuit.classical.types.Ordering(*values)

GitHub

Bases: Enum

Enumeração que lista as possíveis relações entre dois tipos. Os tipos têm apenas uma ordenação parcial, portanto, é possível que dois tipos não tenham nenhuma relação de subtipagem.

Observe que a relação de sub/supertipagem não é a mesma coisa que o fato de um tipo poder ser explicitamente convertido de um para outro.

Alguns métodos auxiliares são então definidos em termos desse nível baixo order() primitivo de baixo nível:

is_subtype

qiskit.circuit.classical.types.is_subtype(left, right, /, strict=False)

GitHub

A relação leftright\text{left} \le \text{right} é válida? Se não houver uma relação de ordem entre os dois tipos, o resultado será False. Se strict, então a igualdade também é proibida.

Exemplos

Verificar se um tipo é uma subclasse de outro:

>>> from qiskit.circuit.classical import types
>>> types.is_subtype(types.Uint(8), types.Uint(16))
True

Verificar se um tipo é uma subclasse estrita de outro:

>>> types.is_subtype(types.Bool(), types.Bool())
True
>>> types.is_subtype(types.Bool(), types.Bool(), strict=True)
False

Parâmetros

Tipo de retorno

bool

is_supertype

qiskit.circuit.classical.types.is_supertype(left, right, /, strict=False)

GitHub

A relação leftright\text{left} \ge \text{right} é válida? Se não houver uma relação de ordem entre os dois tipos, o resultado será False. Se strict, então a igualdade também é proibida.

Exemplos

Verifica se um tipo é uma superclasse de outro:

>>> from qiskit.circuit.classical import types
>>> types.is_supertype(types.Uint(8), types.Uint(16))
False

Verifica se um tipo é uma superclasse estrita de outro:

>>> types.is_supertype(types.Bool(), types.Bool())
True
>>> types.is_supertype(types.Bool(), types.Bool(), strict=True)
False

Parâmetros

Tipo de retorno

bool

greater

qiskit.circuit.classical.types.greater(left, right, /)

GitHub

Obtenha o maior dos dois tipos, supondo que haja uma relação de ordem entre eles. Tecnicamente, essa é uma versão um pouco restrita do conceito de "encontro" dos dois tipos, pois o valor de retorno deve ser uma das entradas. Na prática, no sistema de tipos, não há o conceito de um tipo "soma", portanto, o "encontro" existe se e somente se houver uma ordenação entre os dois tipos e for igual ao maior dos dois tipos.

Retorna

O maior dos dois tipos.

Aumentos

TypeError - se não houver relação de ordem entre os dois tipos.

Parâmetros

Tipo de retorno

Tipo

Exemplos

Encontre o maior de dois Uint tipos:

>>> from qiskit.circuit.classical import types
>>> types.greater(types.Uint(8), types.Uint(16))
types.Uint(16)

Conversão entre tipos

É comum precisar converter valores de um tipo em outro tipo. As regras de conversão para isso estão incorporadas no módulo types módulo. Você pode consultar os tipos de fundição usando cast_kind():

cast_kind

qiskit.circuit.classical.types.cast_kind(from_, to_, /)

GitHub

Determine o tipo de conversão que é necessário para passar do tipo esquerdo para o tipo direito.

Exemplos

>>> from qiskit.circuit.classical import types
>>> types.cast_kind(types.Bool(), types.Bool())
<CastKind.EQUAL: 1>
>>> types.cast_kind(types.Uint(8), types.Bool())
<CastKind.IMPLICIT: 2>
>>> types.cast_kind(types.Bool(), types.Uint(8))
<CastKind.LOSSLESS: 3>
>>> types.cast_kind(types.Uint(16), types.Uint(8))
<CastKind.DANGEROUS: 4>

Parâmetros

Tipo de retorno

CastKind

Os valores de retorno dessa função são uma enumeração que explica os tipos de conversão que são permitidos do tipo esquerdo para o tipo direito.

Observe que as conversões entre Float e Uint são considerados perigosos em qualquer direção e devem ser feitos explicitamente.

CastKind

class qiskit.circuit.classical.types.CastKind(*values)

GitHub

Bases: Enum

Um valor de retorno que indica o tipo de conversão que pode ocorrer de um tipo para outro.

Esta página foi útil?
Relate um bug, erro de digitação ou solicite conteúdo no GitHub.