Skip to content

JOPT fails for state transfer problems in open systems #47

Open
@pmenczel

Description

@pmenczel

The following script sets up a simple example problem where a (dissipative) qubit should be transferred from the ground state to the excited state. Using JOPT, the optimize_pulses function raises a ValueError. (Note that the same example works fine with GOAT.)

import numpy as np
import qutip as qt
from qutip_qoc import Objective, optimize_pulses

from jax import jit, numpy

# --- Setup problem ---
Hd = qt.Qobj(np.diag([1, 2]))
c_ops = [np.sqrt(0.1) * qt.sigmam()]
Hc = qt.sigmax()

Ld = qt.liouvillian(H=Hd, c_ops=c_ops)
Lc = qt.liouvillian(Hc)

initial_state = qt.fock_dm(2, 0)
target_state = qt.fock_dm(2, 1)

times = np.linspace(0, 2 * np.pi, 250)

# --- Run JOPT ---
@jit
def sin_x(t, c, **kwargs):
    return c[0] * numpy.sin(c[1] * t)
L = [Ld, [Lc, sin_x]]

guess_params = [1, 0.5]

res_jopt = optimize_pulses(
    objectives = Objective(initial_state, L, target_state),
    control_parameters = {
        "ctrl_x": {"guess": guess_params, "bounds": [(-1, 1), (0, 2 * np.pi)]}
    },
    tlist = times,
    algorithm_kwargs = {
        "alg": "JOPT",
        "fid_err_targ": 0.001,
    },
)

The error message is as follows:

Traceback (most recent call last):
  File "/home/paulm/qutip/qutip-qoc/tmp/bug2.py", line 28, in <module>
    res_jopt = optimize_pulses(
        objectives = Objective(initial_state, L, target_state),
    ...<7 lines>...
        },
    )
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/qutip_qoc/pulse_optim.py", line 422, in optimize_pulses
    return _global_local_optimization(
        objectives,
    ...<7 lines>...
        qtrl_optimizers,
    )
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/qutip_qoc/_optimizer.py", line 359, in _global_local_optimization
    min_res = optimizer(
        func=multi_objective.goal_fun,
    ...<6 lines>...
        **optimizer_kwargs,
    )
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/_lib/_util.py", line 440, in wrapper
    return fun(*args, **kwargs)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_basinhopping.py", line 696, in basinhopping
    bh = BasinHoppingRunner(x0, wrapped_minimizer, take_step_wrapped,
                            accept_tests, disp=disp)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_basinhopping.py", line 78, in __init__
    minres = minimizer(self.x)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_basinhopping.py", line 294, in __call__
    return self.minimizer(self.func, x0, **self.kwargs)
           ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_minimize.py", line 738, in minimize
    res = _minimize_lbfgsb(fun, x0, args, jac, bounds,
                           callback=callback, **options)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_lbfgsb_py.py", line 386, in _minimize_lbfgsb
    sf = _prepare_scalar_function(fun, x0, jac=jac, args=args, epsilon=eps,
                                  bounds=bounds,
                                  finite_diff_rel_step=finite_diff_rel_step)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_optimize.py", line 291, in _prepare_scalar_function
    sf = ScalarFunction(fun, x0, args, grad, hess,
                        finite_diff_rel_step, bounds, epsilon=epsilon)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_differentiable_functions.py", line 223, in __init__
    self._update_fun()
    ~~~~~~~~~~~~~~~~^^
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_differentiable_functions.py", line 295, in _update_fun
    fx = self._wrapped_fun(self.x)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/scipy/optimize/_differentiable_functions.py", line 21, in wrapped
    fx = fun(np.copy(x), *args)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/qutip_qoc/objective.py", line 143, in goal_fun
    infid += self._weights[i] * alg.infidelity(params)
                                ~~~~~~~~~~~~~~^^^^^^^^
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/qutip_qoc/_jopt.py", line 153, in _infid
    diff_dag = Qobj(diff.data.adjoint(), dims=diff.dims)
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/qutip/core/qobj.py", line 279, in __init__
    self._initialize_data(arg, dims, copy)
    ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "/home/paulm/miniconda3/envs/qutip-master-qoc/lib/python3.13/site-packages/qutip/core/qobj.py", line 265, in _initialize_data
    raise ValueError('Provided dimensions do not match the data: ' +
                     f"{self._dims.shape} vs {self._data.shape}")
ValueError: Provided dimensions do not match the data: (4, 1) vs (1, 4)

This issue was discovered while creating the interactive test notebooks in #44

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggood first issueGood for newcomers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions