Does QubitUnitary accept ArrayBox?

Hello,

I’m trying to optimise a circuit involving the use of a parametrised qml.QubitUnitary operation, but in doing so the autograd-part is parsing an ArrayBox as the matrix input. And I get the follewing error:

TypeError: QubitUnitary: Array parameter expected, got <class 'autograd.numpy.numpy_boxes.ArrayBox'>.

Here’s an examples:

@qml.qnode(device)
def mean _photon_gaussian(t):
    matrix = np.array([
        [0, np.exp(1j*t)],
        [np.exp(1j*t), 0]
    ])
    qml.QubitUnitary(matrix, wires=0)
    return qml.expval(qml.PauliZ(0))

def cost(t):
    return mean_photon_gaussian(t=t)

opt = qml.GradientDescentOptimizer(stepsize=0.1)
steps = 20
params = 0.015

for i in range(steps):
    # update the circuit parameters
    params = opt.step(cost, params)

    print("Cost after step {:5d}: {:8f}".format(i + 1, cost(t=params)))

And trace:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/emil/.pycharm_helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/home/emil/.pycharm_helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/emil/pycharm_project/gate_approximation/pennylane_ArrayBox_test.py", line 26, in <module>
    params = opt.step(cost, params)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/optimize/gradient_descent.py", line 64, in step
    g = self.compute_grad(objective_fn, x, grad_fn=grad_fn)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/optimize/gradient_descent.py", line 88, in compute_grad
    g = autograd.grad(objective_fn)(x)  # pylint: disable=no-value-for-parameter
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/wrap_util.py", line 20, in nary_f
    return unary_operator(unary_f, x, *nary_op_args, **nary_op_kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/differential_operators.py", line 25, in grad
    vjp, ans = _make_vjp(fun, x)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/core.py", line 10, in make_vjp
    end_value, end_node =  trace(start_node, fun, x)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/tracer.py", line 10, in trace
    end_box = fun(start_box)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/wrap_util.py", line 15, in unary_f
    return fun(*subargs, **kwargs)
  File "/home/emil/pycharm_project/gate_approximation/pennylane_ArrayBox_test.py", line 17, in cost
    return mean_photon_gaussian(t=t)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/decorator.py", line 66, in wrapper
    return qnode(*args, **kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/qnode.py", line 606, in __call__
    return self.evaluate(args, **kwargs)  # args as one tuple
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/tracer.py", line 48, in f_wrapped
    return f_raw(*args, **kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/qnode.py", line 641, in evaluate
    self.construct(args, kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/qnode.py", line 292, in construct
    res = self.func(*variables, **keyword_values)
  File "/home/emil/pycharm_project/gate_approximation/pennylane_ArrayBox_test.py", line 12, in mean_photon_gaussian
    qml.QubitUnitary(matrix, wires=0)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/operation.py", line 552, in __init__
    super().__init__(*params, wires=wires, do_queue=do_queue)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/operation.py", line 267, in __init__
    self.check_domain(p)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/operation.py", line 334, in check_domain
    raise TypeError('{}: Array parameter expected, got {}.'.format(self.name, type(p)))
TypeError: QubitUnitary: Array parameter expected, got <class 'autograd.numpy.numpy_boxes.ArrayBox'>.

Does qml.QubitUnitary only accept fixed input?

Thanks in advance,
Emil

Ok. That was not the problem, but rather

return mean_photon_gaussian(t=t)

should not use a kwarg but rather:

return mean_photon_gaussian(t)

But now I get:

Traceback (most recent call last):
File "/home/emil/miniconda3/envs/QC/lib/python3.6/code.py", line 91, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "/home/emil/.pycharm_helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/home/emil/.pycharm_helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/home/emil/pycharm_project/gate_approximation/pennylane_ArrayBox_test.py", line 42, in <module>
    params = opt.step(cost, params)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/optimize/gradient_descent.py", line 64, in step
    g = self.compute_grad(objective_fn, x, grad_fn=grad_fn)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/optimize/gradient_descent.py", line 88, in compute_grad
    g = autograd.grad(objective_fn)(x)  # pylint: disable=no-value-for-parameter
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/wrap_util.py", line 20, in nary_f
    return unary_operator(unary_f, x, *nary_op_args, **nary_op_kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/differential_operators.py", line 25, in grad
    vjp, ans = _make_vjp(fun, x)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/core.py", line 10, in make_vjp
    end_value, end_node =  trace(start_node, fun, x)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/tracer.py", line 10, in trace
    end_box = fun(start_box)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/wrap_util.py", line 15, in unary_f
    return fun(*subargs, **kwargs)
  File "/home/emil/pycharm_project/gate_approximation/pennylane_ArrayBox_test.py", line 31, in cost
    return mean_photon_gaussian(t)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/decorator.py", line 66, in wrapper
    return qnode(*args, **kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/qnode.py", line 606, in __call__
    return self.evaluate(args, **kwargs)  # args as one tuple
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/tracer.py", line 44, in f_wrapped
    ans = f_wrapped(*argvals, **kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/tracer.py", line 48, in f_wrapped
    return f_raw(*args, **kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/qnode.py", line 641, in evaluate
    self.construct(args, kwargs)
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/pennylane/qnode.py", line 292, in construct
    res = self.func(*variables, **keyword_values)
  File "/home/emil/pycharm_project/gate_approximation/pennylane_ArrayBox_test.py", line 21, in mean_photon_gaussian
    [0, np.exp(1j*t)],
  File "/home/emil/miniconda3/envs/QC/lib/python3.6/site-packages/autograd/tracer.py", line 48, in f_wrapped
    return f_raw(*args, **kwargs)
TypeError: loop of ufunc does not support argument 0 of type Variable which has no callable exp method

So numpy expressions cannot cooperate with Variables during gradient calculation?

Hi @M_il!

qml.QubitUnitary() was initially coded up to only allow non-differentiable numeric matrices. It might be possible to modify it to allow the behaviour you are looking for above — I’ll look into it and get back to you!

The gate you are trying to implement can be written as

\exp( i Z t/2) \exp( i X) \exp(- i Z t/2)

which you can code directly into pennylane