Skip to content

TypeError: ParameterExpression with unbound parameters (set()) cannot be cast to a float. #9187

@mafaldaramoa

Description

@mafaldaramoa

Environment

  • Qiskit Terra version: 0.21.0
  • Python version: 3.9.12
  • Operating system: Windows 11 Home

What is happening?

Creating and evaluating a Trotter evolution circuit for certain operators raises an error. The error message indicates that the ParameterExpression has unbound parameters, even though this is not the case.

This issue has similarities with #7507, but it's not the same. The proposed solution in there (forcing the parameter to a float in PauliEvolutionGate.validate_parameter) does not work in this case.

How can we reproduce the issue?

from qiskit.circuit import Parameter
from qiskit.opflow import PauliTrotterEvolution, Suzuki
from qiskit.opflow import X, Y

operator = (0.5j * X^X^Y^X) 
param = Parameter('θ')

ev_op = (1j*operator*param).exp_i()

exp_operator = (PauliTrotterEvolution().convert(ev_op))
circuit = exp_operator

bound_circuit = circuit.bind_parameters({param: -0.1})
bound_circuit.eval()

What should happen?

  • The error message should be accurate. As is, it doesn't allow one to identify the problem, because the set of parameters is in fact empty (as the message itself shows).
  • bound_circuit should be evaluated without errors.

Any suggestions?

The problem seems to arise in the _apply_operation method of ParameterExpression. When our (yet unbound) param is multiplied by the numeric coefficient (1j * 0.5j, simplified to 0.5 + 0j), the values of the relevant local variables inside that method are as follows:

> other_expr # Numeric coefficient (class: complex)
(-0.5+0j)
> self_expr # Coefficient of the ParameterExpression (class: symengine.lib.symengine_wrapper.Symbol)
θ
> expr
(-0.5 + 0.0*I)*θ

Later when the parameter θ is bound to -0.1, the attribute _symbol_expr associated with the ParameterExpression is -0.1*(-0.5 + 0.0*I). Casting this to a float is what gives an error (RuntimeError: Not Implemented). The error doesn't occur if _symbol_expr is -0.1*(-0.5).

Naively, doing

if numpy.isreal(other_expr):
    other_expr = numpy.real(other_expr)

in _apply_operation fixes the issue.

Alternatively, the error doesn't occur if we change the code the reproduces the problem into

operator = (0.5 * X^X^Y^X) 
param = Parameter('θ')

ev_op = (operator*param).exp_i()

i.e., if the coefficient is real to begin with. However, this seems a bit rigid, as we might want to define operators with imaginary coefficients.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions