Skip to content

ghz

GHZ (Greenberger-Horne-Zeilinger) is used to represent a maximally entangled state.

In the GHZ state, the state of qubits are completely dependent on the state of other qubits. This state is an important part of quantum computing as it is commonly used in algorithms, protocols, error corrections, cryptography, etc.

ghz

ghz(dim: int, num_qubits: int, coeff: list[int] | None = None) -> ndarray

Generate a (generalized) GHZ state 1.

Returns a num_qubits-partite GHZ state acting on dim local dimensions, described in 1. For example, ghz(2, 3) returns the standard 3-qubit GHZ state on qubits. The output of this function is a dense NumPy array.

For a system of num_qubits qubits (i.e., dim = 2), the GHZ state can be written as

\[ |GHZ \rangle = \frac{1}{\sqrt{n}} \left(|0\rangle^{\otimes n} + |1 \rangle^{\otimes n} \right)). \]

Examples:

When dim = 2, and num_qubits = 3 this produces the standard GHZ state

\[ \frac{1}{\sqrt{2}} \left( |000 \rangle + |111 \rangle \right). \]

Using |toqito⟩, we can see that this yields the proper state.

from toqito.states import ghz
print(ghz(2, 3))

[[0.70710678] [0. ] [0. ] [0. ] [0. ] [0. ] [0. ] [0.70710678]]

As this function covers the generalized GHZ state, we can consider higher dimensions. For instance here is the GHZ state in \(\mathbb{C}^{4^{\otimes 7}}\) as

\[ \frac{1}{\sqrt{30}} \left(|0000000 \rangle + 2|1111111 \rangle + 3|2222222 \rangle + 4|3333333\rangle \right). \]

Raises:

  • ValueError

    Number of qubits is not a positive integer.

Parameters:

  • dim (int) –

    The local dimension.

  • num_qubits (int) –

    The number of parties (qubits/qudits)

  • coeff (list[int] | None, default: None ) –

    (default [1, 1, ..., 1])/sqrt(dim): a 1-by-dim vector of coefficients.

Returns:

  • ndarray

    Numpy vector array as GHZ state.

References

1 Greenberger, Daniel and Horne, Michael and Zeilinger, Anton. Going Beyond Bell's Theorem. (2007).

Source code in toqito/states/ghz.py
def ghz(dim: int, num_qubits: int, coeff: list[int] | None = None) -> np.ndarray:
    r"""Generate a (generalized) GHZ state [@Greenberger_2007_Going].

    Returns a `num_qubits`-partite GHZ state acting on `dim` local dimensions, described
    in [@Greenberger_2007_Going]. For example, `ghz(2, 3)` returns the standard 3-qubit GHZ state on
    qubits. The output of this function is a dense NumPy array.

    For a system of `num_qubits` qubits (i.e., `dim = 2`), the GHZ state can be written
    as

    \[
        |GHZ \rangle = \frac{1}{\sqrt{n}} \left(|0\rangle^{\otimes n} +
        |1 \rangle^{\otimes n} \right)).
    \]

    Examples:
        When `dim = 2`, and `num_qubits = 3` this produces the standard GHZ state

        \[
            \frac{1}{\sqrt{2}} \left( |000 \rangle + |111 \rangle \right).
        \]

        Using `|toqito⟩`, we can see that this yields the proper state.

        ```python exec="1" source="above"
        from toqito.states import ghz
        print(ghz(2, 3))
        ```

        As this function covers the generalized GHZ state, we can consider higher dimensions. For instance here
        is the GHZ
        state in \(\mathbb{C}^{4^{\otimes 7}}\) as

        \[
            \frac{1}{\sqrt{30}} \left(|0000000 \rangle + 2|1111111 \rangle +
            3|2222222 \rangle + 4|3333333\rangle \right).
        \]

    Raises:
        ValueError: Number of qubits is not a positive integer.

    Args:
        dim: The local dimension.
        num_qubits: The number of parties (qubits/qudits)
        coeff: (default `[1, 1, ..., 1])/sqrt(dim)`: a 1-by-`dim` vector of coefficients.

    Returns:
        Numpy vector array as GHZ state.

    """
    if dim < 1:
        raise ValueError("InvalidDim: `dim` must be at least 1.")
    if num_qubits < 1:
        raise ValueError("InvalidNumQubits: `num_qubits` must be at least 1.")

    if coeff is None:
        coeff = np.ones(dim)
    else:
        coeff = np.array(coeff)
    if len(coeff) != dim:
        raise ValueError("InvalidCoeff: The variable `coeff` must be a vector of length equal to `dim`.")

    # Normalize coefficients if they are not.
    norm = np.linalg.norm(coeff)
    if not np.isclose(norm, 1.0):
        coeff = coeff / norm

    # Initialize the GHZ state vector.
    ghz_state = np.zeros((dim**num_qubits, 1))
    # Fill the state vector with the corresponding coefficients.
    for i in range(dim):
        # Calculate the index for the tensor product state |i, i, ..., i>.
        index = sum(i * (dim**k) for k in range(num_qubits))
        ghz_state[index] = coeff[i]

    return ghz_state