Пример #1
0
    def apply_gradient(self, lincomb, component=None):
        r"""Compute the effect of the gradient operator :math:`-i \varepsilon^2 \nabla_x`
        on the linear combination :math:`\Upsilon` of Hagedorn wavepackets :math:`\Psi`.

        :param lincomb: The linear combination :math:`\Upsilon`.
        :type lincomb: A :py:class:`LinearCombinationOfHAWPs` instance.
        :param component: The index :math:`i` of the component :math:`\Phi_i`.
        :type component: Integer or ``None``.
        :return: One linear combination :math:`\Upsilon_d` containing the gradients
                 for the component :math:`\partial_{x_d}` for each space dimension
                 component :math:`d = 1, \ldots, D`.
        """
        D = lincomb.get_dimension()
        N = lincomb.get_number_components()
        J = lincomb.get_number_packets()
        Cj = squeeze(lincomb.get_coefficients())
        eps = lincomb.get_eps()
        G = GradientHAWP()

        new_lincombs = [LinearCombinationOfHAWPs(D, N, eps) for d in range(D)]

        # Handle each wavepacket individually
        for j in range(J):
            packet = lincomb.get_wavepacket(j)
            grads = G.apply_gradient(packet, component=component)

            for d, grad in enumerate(grads):
                new_lincombs[d].add_wavepacket(grad, Cj[j])

        return new_lincombs
Пример #2
0
    def __init__(self, innerproduct=None):
        r"""Initialize a new :py:class:`ObservablesHAWP` instance for observable computation
        of Hagedorn wavepackets.

        :param innerproduct: An inner product for computing the integrals. The inner product is only used for
                             the computation of the potential energy :math:`\langle \Psi | V(x) | \Psi \rangle`
                             but not for the kinetic energy.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.
        """
        # A innerproduct to compute the integrals
        if innerproduct is not None:
            self._innerproduct = innerproduct

        self._gradient = GradientHAWP()
Пример #3
0
    def __init__(self, innerproduct=None):
        r"""Initialize a new :py:class:`ObservablesMixedHAWP` instance for observable computation of
        Hagedorn wavepackets.

        :param innerproduct: An inner product for computing the integrals. The inner product is used
                             for the computation of all brakets
                             :math:`\langle \Psi | \cdot | \Psi^\prime \rangle`.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.

        .. note:: Make sure to use an inhomogeneous inner product here.
        """
        # A innerproduct to compute the integrals
        if innerproduct is not None:
            self._innerproduct = innerproduct

        self._gradient = GradientHAWP()
Пример #4
0
    def get_gradient_operator(self):
        r"""Return the :py:class:`Gradient` subclass suitable for
        computing gradients of this wavepacket.

        :return: A :py:class:`GradientHAWP` instance.
        """
        return GradientHAWP()
Пример #5
0
    def __init__(self, innerproduct=None):
        r"""Initialize a new :py:class:`ObservablesHAWP` instance for observable computation
        of Hagedorn wavepackets.

        :param innerproduct: An inner product for computing the integrals. The inner product is only used for
                             the computation of the potential energy :math:`\langle \Psi | V(x) | \Psi \rangle`
                             but not for the kinetic energy.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.
        """
        # A innerproduct to compute the integrals
        if innerproduct is not None:
            self._innerproduct = innerproduct

        self._gradient = GradientHAWP()
Пример #6
0
class ObservablesHAWP(Observables):
    r"""This class implements observable computation for Hagedorn wavepackets :math:`\Psi`.
    """

    def __init__(self, innerproduct=None):
        r"""Initialize a new :py:class:`ObservablesHAWP` instance for observable computation
        of Hagedorn wavepackets.

        :param innerproduct: An inner product for computing the integrals. The inner product is only used for
                             the computation of the potential energy :math:`\langle \Psi | V(x) | \Psi \rangle`
                             but not for the kinetic energy.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.
        """
        # A innerproduct to compute the integrals
        if innerproduct is not None:
            self._innerproduct = innerproduct

        self._gradient = GradientHAWP()


    def set_innerproduct(self, innerproduct):
        r"""Set the innerproduct.

        :param innerproduct: An innerproduct for computing the integrals. The inner product is only used for
                             the computation of the potential energy :math:`\langle \Psi | V(x) | \Psi \rangle`
                             but not for the kinetic energy.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.
        """
        self._innerproduct = innerproduct


    def norm(self, wavepacket, component=None, summed=False):
        r"""Calculate the :math:`L^2` norm :math:`\langle \Psi | \Psi \rangle` of the wavepacket :math:`\Psi`.

        .. note:: This method is just a shortcut and calls the :py:meth:`HagedornWavepacketBase.norm`
                  method of the given wavepacket.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the norm.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose norm is calculated.
                          The default value is ``None`` which means to compute the norms of all :math:`N` components.
        :type component: int or ``None``.
        :param summed: Whether to sum up the norms :math:`\langle \Phi_i | \Phi_i \rangle` of the
                       individual components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: The norm of :math:`\Psi` or the norm of :math:`\Phi_i` or a list with the :math:`N`
                 norms of all components. Depending on the values of ``component`` and ``summed``.
        """
        return wavepacket.norm(component=component, summed=summed)


    def kinetic_energy(self, wavepacket, component=None, summed=False):
        r"""Compute the kinetic energy :math:`E_{\text{kin}} := \langle \Psi | T | \Psi \rangle`
        of the different components :math:`\Phi_i` of the wavepacket :math:`\Psi`.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the kinetic energy.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose
                          kinetic energy we want to compute. If set to ``None`` the
                          computation is performed for all :math:`N` components.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the kinetic energies :math:`E_i` of the individual
                       components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: A list with the kinetic energies of the individual components or the
                 overall kinetic energy of the wavepacket. (Depending on the optional arguments.)
        """
        if component is None:
            N = wavepacket.get_number_components()
            components = range(N)
        else:
            components = [component]

        ekin = []

        for n in components:
            Kprime, cnew = self._gradient.apply_gradient(wavepacket, component=n, as_packet=False)
            ekin.append(0.5 * sum(sum(conjugate(cnew) * cnew, axis=1), axis=0))

        if summed is True:
            ekin = sum(ekin)
        elif component is not None:
            # Do not return a list for specific single components
            ekin = ekin[0]

        return ekin


    def potential_energy(self, wavepacket, potential, component=None, summed=False):
        r"""Compute the potential energy :math:`E_{\text{pot}} := \langle \Psi | V(x) | \Psi \rangle`
        of the different components :math:`\Phi_i` of the wavepacket :math:`\Psi`.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the potential energy.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param potential: The potential :math:`V(x)`. (Actually, not the potential object itself
                          but one of its ``V.evaluate_*`` methods.)
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose
                          potential energy we want to compute. If set to ``None`` the
                          computation is performed for all :math:`N` components.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the potential energies :math:`E_i` of the individual
                       components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: A list with the potential energies of the individual components or the
                 overall potential energy of the wavepacket. (Depending on the optional arguments.)
        """
        N = wavepacket.get_number_components()

        # TODO: Better take 'V' instead of 'V.evaluate_at' as argument?
        #f = partial(potential.evaluate_at, as_matrix=True)
        f = partial(potential, as_matrix=True)

        # Compute the brakets for each component
        if component is not None:
            epot = self._innerproduct.quadrature(wavepacket, operator=f, diag_component=component, eval_at_once=True)
        else:
            Q = self._innerproduct.quadrature(wavepacket, operator=f, eval_at_once=True)
            # And don't forget the summation in the matrix multiplication of 'operator' and 'ket'
            # TODO: Should this go inside the innerproduct?
            tmp = list(map(squeeze, Q))
            epot = [sum(tmp[i * N:(i + 1) * N]) for i in range(N)]

        if summed is True:
            epot = sum(epot)

        return epot
Пример #7
0
class ObservablesMixedHAWP(Observables):
    r"""This class implements the mixed case observable computation
    :math:`\langle \Psi | \cdot | \Psi^\prime \rangle` for Hagedorn
    wavepackets :math:`\Psi` where the bra :math:`\Psi` does not equal
    the ket :math:`\Psi^\prime`.
    """

    def __init__(self, innerproduct=None):
        r"""Initialize a new :py:class:`ObservablesMixedHAWP` instance for observable computation of
        Hagedorn wavepackets.

        :param innerproduct: An inner product for computing the integrals. The inner product is used
                             for the computation of all brakets
                             :math:`\langle \Psi | \cdot | \Psi^\prime \rangle`.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.

        .. note:: Make sure to use an inhomogeneous inner product here.
        """
        # A innerproduct to compute the integrals
        if innerproduct is not None:
            self._innerproduct = innerproduct

        self._gradient = GradientHAWP()


    def set_innerproduct(self, innerproduct):
        r"""Set the innerproduct.

        :param innerproduct: An inner product for computing the integrals. The inner product is used
                             for the computation of all brakets
                             :math:`\langle \Psi | \cdot | \Psi^\prime \rangle`.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.

        .. note:: Make sure to use an inhomogeneous inner product here.
        """
        self._innerproduct = innerproduct


    def overlap(self, pacbra, packet, component=None, summed=False):
        r"""Calculate the overlap :math:`\langle \Psi | \Psi^\prime \rangle` of the wavepackets
        :math:`\Psi` and :math:`\Psi^\prime`.

        :param pacbra: The wavepacket :math:`\Psi` which takes part in the overlap integral.
        :type pacbra: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param packet: The wavepacket :math:`\Psi^\prime` which takes part in the overlap integral.
        :type packet: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the components :math:`\Phi_i` of :math:`\Psi`
                          and :math:`\Phi_i^\prime` of :math:`\Psi^\prime` whose overlap is
                          computed. The default value is ``None`` which means to compute the
                          overlaps with all :math:`N` components involved.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the overlaps :math:`\langle \Phi_i | \Phi_i^\prime \rangle`
                       of the individual components :math:`\Phi_i` and :math:`\Phi_i^\prime`.
        :type summed: Boolean, default is ``False``.
        :return: The overlap of :math:`\Psi` with :math:`\Psi^\prime` or the overlap of :math:`\Phi_i`
                 with :math:`\Phi_i^\prime` or a list with the :math:`N` overlaps of all components.
                 (Depending on the optional arguments.)
        """
        return self._innerproduct.quadrature(pacbra, packet, diag_component=component, diagonal=True, summed=summed)


    def norm(self, wavepacket, component=None, summed=False):
        r"""Calculate the :math:`L^2` norm :math:`\langle \Psi | \Psi \rangle` of the wavepacket :math:`\Psi`.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the norm.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose norm is computed.
                          The default value is ``None`` which means to compute the norms of all :math:`N` components.
        :type component: int or ``None``.
        :param summed: Whether to sum up the norms :math:`\langle \Phi_i | \Phi_i \rangle` of the
                       individual components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: The norm of :math:`\Psi` or the norm of :math:`\Phi_i` or a list with the :math:`N`
                 norms of all components. (Depending on the optional arguments.)

        .. note:: This method just redirects to a call to :py:meth:`HagedornWavepacketBase.norm`.
        """
        return wavepacket.norm(component=component, summed=summed)


    def kinetic_overlap_energy(self, pacbra, packet, component=None, summed=False):
        r"""Compute the kinetic energy overlap :math:`\langle \Psi | T | \Psi^\prime \rangle`
        of the different components :math:`\Phi_i` and :math:`\Phi_i^\prime` of the
        wavepackets :math:`\Psi` and :math:`\Psi^\prime`.

        :param pacbra: The wavepacket :math:`\Psi` which takes part in the kinetic energy integral.
        :type pacbra: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param packet: The wavepacket :math:`\Psi^\prime` which takes part in the kinetic energy integral.
        :type packet: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the components :math:`\Phi_i` of :math:`\Psi`
                          and :math:`\Phi_i^\prime` of :math:`\Psi^\prime` which take part in the
                          kinetic energy integral. If set to ``None`` the computation is performed for
                          all :math:`N` components of :math:`\Psi` and :math:`\Psi^\prime`.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the kinetic energies :math:`E_i` of the individual
                       components :math:`\Phi_i` and :math:`\Phi_i^\prime`.
        :type summed: Boolean, default is ``False``.
        :return: A list of the kinetic energy overlap integrals of the individual components or
                 the overall kinetic energy overlap of the wavepackets. (Depending on the optional arguments.)
        """
        Nbra = pacbra.get_number_components()
        Nket = packet.get_number_components()
        if not Nbra == Nket:
            # TODO: Drop this requirement, should be easy when zip(...) exhausts
            raise ValueError("Number of components in bra (%d) and ket (%d) differs!" % (Nbra, Nket))

        if component is None:
            components = range(Nbra)
        else:
            components = [component]

        ekin = []

        for n in components:
            gradpacbra = self._gradient.apply_gradient(pacbra, component=n)
            gradpacket = self._gradient.apply_gradient(packet, component=n)
            Q = [self._innerproduct.quadrature(gpb, gpk, diag_component=n) for gpb, gpk in zip(gradpacbra, gradpacket)]
            ekin.append(0.5 * sum(Q))

        if summed is True:
            ekin = sum(ekin)
        elif component is not None:
            # Do not return a list for specific single components
            ekin = ekin[0]

        return ekin


    def kinetic_energy(self, wavepacket, component=None, summed=False):
        r"""Compute the kinetic energy :math:`E_{\text{kin}} := \langle \Psi | T | \Psi \rangle`
        of the different components :math:`\Phi_i` of the wavepacket :math:`\Psi`.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the kinetic energy.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose
                          kinetic energy we compute. If set to ``None`` the
                          computation is performed for all :math:`N` components.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the kinetic energies :math:`E_i` of the individual
                       components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: A list of the kinetic energies of the individual components or the
                 overall kinetic energy of the wavepacket. (Depending on the optional arguments.)

        .. note:: This method just expands to a call of the :py:meth:`ObservablesMixedHAWP.kinetic_overlap_energy`
                  method. Better use :py:meth:`ObservablesHAWP.kinetic_energy`.
        """
        return self.kinetic_overlap_energy(wavepacket, wavepacket, component=component, summed=summed)


    def potential_overlap_energy(self, pacbra, packet, potential, component=None, summed=False):
        r"""Compute the potential energy overlap :math:`\langle \Psi | V(x) | \Psi^\prime \rangle`
        of the different components :math:`\Phi_i` and :math:`\Phi_i^\prime` of the
        wavepackets :math:`\Psi` and :math:`\Psi^\prime`.

        :param pacbra: The wavepacket :math:`\Psi` which takes part in the potential energy integral.
        :type pacbra: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param packet: The wavepacket :math:`\Psi^\prime` which takes part in the potential energy integral.
        :type packet: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param potential: The potential :math:`V(x)`. (Actually, not the potential object itself
                          but one of its ``V.evaluate_*`` methods.)
        :param component: The index :math:`i` of the components :math:`\Phi_i` of :math:`\Psi`
                          and :math:`\Phi_i^\prime` of :math:`\Psi^\prime` which take part in the
                          potential energy integral. If set to ``None`` the computation is performed for
                          all :math:`N` components of :math:`\Psi` and :math:`\Psi^\prime`.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the potential energies :math:`E_i` of the individual
                       components :math:`\Phi_i` and :math:`\Phi_i^\prime`.
        :type summed: Boolean, default is ``False``.
        :return: A list of the potential energy overlap integrals of the individual components or
                 the overall potential energy overlap of the wavepackets. (Depending on the optional arguments.)
        """
        Nbra = pacbra.get_number_components()
        Nket = packet.get_number_components()
        if not Nbra == Nket:
            # TODO: Drop this requirement, should be easy when zip(...) exhausts
            raise ValueError("Number of components in bra (%d) and ket (%d) differs!" % (Nbra, Nket))

        # TODO: Better take 'V' instead of 'V.evaluate_at' as argument?
        #f = partial(potential.evaluate_at, as_matrix=True)
        f = partial(potential, as_matrix=True)

        # Compute the brakets for each component
        if component is not None:
            Q = self._innerproduct.quadrature(pacbra, packet, operator=f, diag_component=component, eval_at_once=True)
            Q = [squeeze(Q)]
        else:
            Q = self._innerproduct.quadrature(pacbra, packet, operator=f, eval_at_once=True)
            Q = list(map(squeeze, Q))

        # And don't forget the summation in the matrix multiplication of 'operator' and 'ket'
        # TODO: Should this go inside the innerproduct?
        epot = [sum(Q[i * Nket:(i + 1) * Nket]) for i in range(Nbra)]

        if summed is True:
            epot = sum(epot)
        elif component is not None:
            # Do not return a list for specific single components
            epot = epot[0]

        return epot


    def potential_energy(self, wavepacket, potential, component=None, summed=False):
        r"""Compute the potential energy :math:`E_{\text{pot}} := \langle \Psi | V(x) | \Psi \rangle`
        of the different components :math:`\Phi_i` of the wavepacket :math:`\Psi`.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the potential energy.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param potential: The potential :math:`V(x)`. (Actually, not the potential object itself
                          but one of its ``V.evaluate_*`` methods.)
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose
                          potential energy we compute. If set to ``None`` the
                          computation is performed for all :math:`N` components.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the potential energies :math:`E_i` of the individual
                       components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: A list of the potential energies of the individual components or the
                 overall potential energy of the wavepacket. (Depending on the optional arguments.)

        .. note:: This method just expands to a call of the :py:meth:`ObservablesMixedHAWP.potential_overlap_energy`
                  method. Better use :py:meth:`ObservablesHAWP.potential_energy`.
        """
        return self.potential_overlap_energy(wavepacket, wavepacket, potential, component=component, summed=summed)
Пример #8
0
class ObservablesHAWP(Observables):
    r"""This class implements observable computation for Hagedorn wavepackets :math:`\Psi`.
    """
    def __init__(self, innerproduct=None):
        r"""Initialize a new :py:class:`ObservablesHAWP` instance for observable computation
        of Hagedorn wavepackets.

        :param innerproduct: An inner product for computing the integrals. The inner product is only used for
                             the computation of the potential energy :math:`\langle \Psi | V(x) | \Psi \rangle`
                             but not for the kinetic energy.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.
        """
        # A innerproduct to compute the integrals
        if innerproduct is not None:
            self._innerproduct = innerproduct

        self._gradient = GradientHAWP()

    def set_innerproduct(self, innerproduct):
        r"""Set the innerproduct.

        :param innerproduct: An innerproduct for computing the integrals. The inner product is only used for
                             the computation of the potential energy :math:`\langle \Psi | V(x) | \Psi \rangle`
                             but not for the kinetic energy.
        :type innerproduct: A :py:class:`InnerProduct` subclass instance.
        """
        self._innerproduct = innerproduct

    def norm(self, wavepacket, component=None, summed=False):
        r"""Calculate the :math:`L^2` norm :math:`\langle \Psi | \Psi \rangle` of the wavepacket :math:`\Psi`.

        .. note:: This method is just a shortcut and calls the :py:meth:`HagedornWavepacketBase.norm`
                  method of the given wavepacket.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the norm.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose norm is calculated.
                          The default value is ``None`` which means to compute the norms of all :math:`N` components.
        :type component: int or ``None``.
        :param summed: Whether to sum up the norms :math:`\langle \Phi_i | \Phi_i \rangle` of the
                       individual components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: The norm of :math:`\Psi` or the norm of :math:`\Phi_i` or a list with the :math:`N`
                 norms of all components. Depending on the values of ``component`` and ``summed``.
        """
        return wavepacket.norm(component=component, summed=summed)

    def kinetic_energy(self, wavepacket, component=None, summed=False):
        r"""Compute the kinetic energy :math:`E_{\text{kin}} := \langle \Psi | T | \Psi \rangle`
        of the different components :math:`\Phi_i` of the wavepacket :math:`\Psi`.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the kinetic energy.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose
                          kinetic energy we want to compute. If set to ``None`` the
                          computation is performed for all :math:`N` components.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the kinetic energies :math:`E_i` of the individual
                       components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: A list with the kinetic energies of the individual components or the
                 overall kinetic energy of the wavepacket. (Depending on the optional arguments.)
        """
        if component is None:
            N = wavepacket.get_number_components()
            components = range(N)
        else:
            components = [component]

        ekin = []

        for n in components:
            Kprime, cnew = self._gradient.apply_gradient(wavepacket,
                                                         component=n,
                                                         as_packet=False)
            ekin.append(0.5 * sum(sum(conjugate(cnew) * cnew, axis=1), axis=0))

        if summed is True:
            ekin = sum(ekin)
        elif component is not None:
            # Do not return a list for specific single components
            ekin = ekin[0]

        return ekin

    def potential_energy(self,
                         wavepacket,
                         potential,
                         component=None,
                         summed=False):
        r"""Compute the potential energy :math:`E_{\text{pot}} := \langle \Psi | V(x) | \Psi \rangle`
        of the different components :math:`\Phi_i` of the wavepacket :math:`\Psi`.

        :param wavepacket: The wavepacket :math:`\Psi` of which we compute the potential energy.
        :type wavepacket: A :py:class:`HagedornWavepacketBase` subclass instance.
        :param potential: The potential :math:`V(x)`. (Actually, not the potential object itself
                          but one of its ``V.evaluate_*`` methods.)
        :param component: The index :math:`i` of the component :math:`\Phi_i` whose
                          potential energy we want to compute. If set to ``None`` the
                          computation is performed for all :math:`N` components.
        :type component: Integer or ``None``.
        :param summed: Whether to sum up the potential energies :math:`E_i` of the individual
                       components :math:`\Phi_i`.
        :type summed: Boolean, default is ``False``.
        :return: A list with the potential energies of the individual components or the
                 overall potential energy of the wavepacket. (Depending on the optional arguments.)
        """
        N = wavepacket.get_number_components()

        # TODO: Better take 'V' instead of 'V.evaluate_at' as argument?
        #f = partial(potential.evaluate_at, as_matrix=True)
        f = partial(potential, as_matrix=True)

        # Compute the brakets for each component
        if component is not None:
            epot = self._innerproduct.quadrature(wavepacket,
                                                 operator=f,
                                                 diag_component=component,
                                                 eval_at_once=True)
        else:
            Q = self._innerproduct.quadrature(wavepacket,
                                              operator=f,
                                              eval_at_once=True)
            # And don't forget the summation in the matrix multiplication of 'operator' and 'ket'
            # TODO: Should this go inside the innerproduct?
            tmp = list(map(squeeze, Q))
            epot = [sum(tmp[i * N:(i + 1) * N]) for i in range(N)]

        if summed is True:
            epot = sum(epot)

        return epot