# Buggy code
def build_preconditioner(A, c_op_list=[], **kwargs):
    """Constructs a iLU preconditioner necessary for solving for
    the steady state density matrix using the iterative linear solvers
    in the 'steadystate' function.

    Parameters
    ----------
    A : qobj
        A Hamiltonian or Liouvillian operator.

    c_op_list : list
        A list of collapse operators.

    return_info : bool, optional, default = False
        Return a dictionary of solver-specific infomation about the
        solution and how it was obtained.

    use_rcm : bool, optional, default = False
        Use reverse Cuthill-Mckee reordering to minimize fill-in in the
        LU factorization of the Liouvillian.

    use_wbm : bool, optional, default = False
        Use Weighted Bipartite Matching reordering to make the Liouvillian
        diagonally dominant.  This is useful for iterative preconditioners
        only, and is set to ``True`` by default when finding a preconditioner.

    weight : float, optional
        Sets the size of the elements used for adding the unity trace condition
        to the linear solvers.  This is set to the average abs value of the
        Liouvillian elements if not specified by the user.

    method : str, default = 'iterative'
        Tells the preconditioner what type of Liouvillian to build for
        iLU factorization.  For direct iterative methods use 'iterative'.
        For power iterative methods use 'power'.

    permc_spec : str, optional, default='COLAMD'
        Column ordering used internally by superLU for the
        'direct' LU decomposition method. Options include 'COLAMD' and
        'NATURAL'. If using RCM then this is set to 'NATURAL' automatically
        unless explicitly specified.

    fill_factor : float, optional, default = 100
        Specifies the fill ratio upper bound (>=1) of the iLU
        preconditioner.  Lower values save memory at the cost of longer
        execution times and a possible singular factorization.

    drop_tol : float, optional, default = 1e-4
        Sets the threshold for the magnitude of preconditioner
        elements that should be dropped.  Can be reduced for a courser
        factorization at the cost of an increased number of iterations, and a
        possible singular factorization.

    diag_pivot_thresh : float, optional, default = None
        Sets the threshold between [0,1] for which diagonal
        elements are considered acceptable pivot points when using a
        preconditioner.  A value of zero forces the pivot to be the diagonal
        element.

    ILU_MILU : str, optional, default = 'smilu_2'
        Selects the incomplete LU decomposition method algoithm used in
        creating the preconditoner. Should only be used by advanced users.

    Returns
    -------
    lu : object
        Returns a SuperLU object representing iLU preconditioner.

    info : dict, optional
        Dictionary containing solver-specific information.
    """
    ss_args = _default_steadystate_args()
    ss_args["method"] = "iterative"
    for key in kwargs.keys():
        if key in ss_args.keys():
            ss_args[key] = kwargs[key]
        else:
            raise Exception(
                "Invalid keyword argument '" + key + "' passed to steadystate."
            )

    # Set column perm to NATURAL if using RCM and not specified by user
    if ss_args["use_rcm"] and ("permc_spec" not in kwargs.keys()):
        ss_args["permc_spec"] = "NATURAL"

    L = _steadystate_setup(A, c_op_list)
    # Set weight parameter to avg abs val in L if not set explicitly
    if "weight" not in kwargs.keys():
        ss_args["weight"] = np.mean(np.abs(L.data.data.max()))
        ss_args["info"]["weight"] = ss_args["weight"]

    n = int(np.sqrt(L.shape[0]))
    if ss_args["method"] == "iterative":
        L, perm, perm2, rev_perm, ss_args = _steadystate_LU_liouvillian(L, ss_args)
    elif ss_args["method"] == "power":
        L, perm, perm2, rev_perm, ss_args = _steadystate_power_liouvillian(L, ss_args)
    else:
        raise Exception("Invalid preconditioning method.")

    M, ss_args = _iterative_precondition(L, n, ss_args)

    if ss_args["return_info"]:
        return M, ss_args["info"]
    else:
        return M


# Traceback (ValueError)
..................................................
======================================================================
ERROR: Steady state: Thermal qubit - power-gmres solver
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/shahnawaz/miniconda3/lib/python3.6/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/Users/shahnawaz/dev/qutip/qutip/tests/test_steadystate.py", line 145, in test_qubit_power_gmres
rho_ss = steadystate(H, c_op_list, method='power-gmres')
File "/Users/shahnawaz/dev/qutip/qutip/steadystate.py", line 298, in steadystate
return _steadystate_power(A, ss_args)
File "/Users/shahnawaz/dev/qutip/qutip/steadystate.py", line 863, in _steadystate_power
v = v / la.norm(v, np.inf)
File "/Users/shahnawaz/miniconda3/lib/python3.6/site-packages/scipy/linalg/misc.py", line 137, in norm
a = np.asarray_chkfinite(a)
File "/Users/shahnawaz/miniconda3/lib/python3.6/site-packages/numpy/lib/function_base.py", line 1233, in asarray_chkfinite
"array must not contain infs or NaNs")
ValueError: array must not contain infs or NaNs

----------------------------------------------------------------------
Ran 561 tests in 576.175s

FAILED (SKIP=19, errors=1)

# Fixed code
def build_preconditioner(A, c_op_list=[], **kwargs):
    """Constructs a iLU preconditioner necessary for solving for
    the steady state density matrix using the iterative linear solvers
    in the 'steadystate' function.

    Parameters
    ----------
    A : qobj
        A Hamiltonian or Liouvillian operator.

    c_op_list : list
        A list of collapse operators.

    return_info : bool, optional, default = False
        Return a dictionary of solver-specific infomation about the
        solution and how it was obtained.

    use_rcm : bool, optional, default = False
        Use reverse Cuthill-Mckee reordering to minimize fill-in in the
        LU factorization of the Liouvillian.

    use_wbm : bool, optional, default = False
        Use Weighted Bipartite Matching reordering to make the Liouvillian
        diagonally dominant.  This is useful for iterative preconditioners
        only, and is set to ``True`` by default when finding a preconditioner.

    weight : float, optional
        Sets the size of the elements used for adding the unity trace condition
        to the linear solvers.  This is set to the average abs value of the
        Liouvillian elements if not specified by the user.

    method : str, default = 'iterative'
        Tells the preconditioner what type of Liouvillian to build for
        iLU factorization.  For direct iterative methods use 'iterative'.
        For power iterative methods use 'power'.

    permc_spec : str, optional, default='COLAMD'
        Column ordering used internally by superLU for the
        'direct' LU decomposition method. Options include 'COLAMD' and
        'NATURAL'. If using RCM then this is set to 'NATURAL' automatically
        unless explicitly specified.

    fill_factor : float, optional, default = 100
        Specifies the fill ratio upper bound (>=1) of the iLU
        preconditioner.  Lower values save memory at the cost of longer
        execution times and a possible singular factorization.

    drop_tol : float, optional, default = 1e-4
        Sets the threshold for the magnitude of preconditioner
        elements that should be dropped.  Can be reduced for a courser
        factorization at the cost of an increased number of iterations, and a
        possible singular factorization.

    diag_pivot_thresh : float, optional, default = None
        Sets the threshold between [0,1] for which diagonal
        elements are considered acceptable pivot points when using a
        preconditioner.  A value of zero forces the pivot to be the diagonal
        element.

    ILU_MILU : str, optional, default = 'smilu_2'
        Selects the incomplete LU decomposition method algoithm used in
        creating the preconditoner. Should only be used by advanced users.

    Returns
    -------
    lu : object
        Returns a SuperLU object representing iLU preconditioner.

    info : dict, optional
        Dictionary containing solver-specific information.
    """
    ss_args = _default_steadystate_args()
    ss_args["method"] = "iterative"
    for key in kwargs.keys():
        if key in ss_args.keys():
            ss_args[key] = kwargs[key]
        else:
            raise Exception(
                "Invalid keyword argument '" + key + "' passed to steadystate."
            )

    # Set column perm to NATURAL if using RCM and not specified by user
    if ss_args["use_rcm"] and ("permc_spec" not in kwargs.keys()):
        ss_args["permc_spec"] = "NATURAL"

    L = _steadystate_setup(A, c_op_list)
    # Set weight parameter to avg abs val in L if not set explicitly
    if "weight" not in kwargs.keys():
        ss_args["weight"] = np.mean(np.abs(L.data.data.max()))
        ss_args["info"]["weight"] = ss_args["weight"]

    n = int(np.sqrt(L.shape[0]))
    if ss_args["method"] == "iterative":
        ss_list = _steadystate_LU_liouvillian(L, ss_args)
        L, perm, perm2, rev_perm, ss_args = ss_list
    elif ss_args["method"] == "power":
        ss_list = _steadystate_power_liouvillian(L, ss_args)
        L, perm, perm2, rev_perm, ss_args = ss_list
    else:
        raise Exception("Invalid preconditioning method.")

    M, ss_args = _iterative_precondition(L, n, ss_args)

    if ss_args["return_info"]:
        return M, ss_args["info"]
    else:
        return M