Back to Cvxpy

Optimal Power and Bandwidth Allocation in a Gaussian Channel

doc/source/examples/applications/optimal_power_gaussian_channel_BV4.62.rst

1.8.24.3 KB
Original Source

Optimal Power and Bandwidth Allocation in a Gaussian Channel

by Robert Gowers, Roger Hill, Sami Al-Izzi, Timothy Pollington and Keith Briggs

from Boyd and Vandenberghe, Convex Optimization, exercise 4.62 page 210

Consider a system in which a central node transmits messages to :math:n receivers. Each receiver channel :math:i \in \{1,...,n\} has a transmit power :math:P_i and bandwidth :math:W_i. A fraction of the total power and bandwidth is allocated to each channel, such that :math:\sum_{i=1}^{n}P_i = P_{tot} and :math:\sum_{i=1}^{n}W_i = W_{tot}. Given some utility function of the bit rate of each channel, :math:u_i(R_i), the objective is to maximise the total utility :math:U = \sum_{i=1}^{n}u_i(R_i).

Assuming that each channel is corrupted by Gaussian white noise, the signal to noise ratio is given by :math:\beta_i P_i/W_i. This means that the bit rate is given by:

:math:R_i = \alpha_i W_i \log_2(1+\beta_iP_i/W_i)

where :math:\alpha_i and :math:\beta_i are known positive constants.

One of the simplest utility functions is the data rate itself, which also gives a convex objective function.

The optimisation problem can be thus be formulated as:

minimise :math:\sum_{i=1}^{n}-\alpha_i W_i \log_2(1+\beta_iP_i/W_i)

subject to :math:\sum_{i=1}^{n}P_i = P_{tot} \quad \sum_{i=1}^{n}W_i = W_{tot} \quad P \succeq 0 \quad W \succeq 0

Although this is a convex optimisation problem, it must be rewritten in DCP form since :math:P_i and :math:W_i are variables and DCP prohibits dividing one variable by another directly. In order to rewrite the problem in DCP format, we utilise the :math:\texttt{kl_div} function in CVXPY, which calculates the Kullback-Leibler divergence.

:math:\text{kl_div}(x,y) = x\log(x/y)-x+y

:math:-R_i = \text{kl_div}(\alpha_i W_i, \alpha_i(W_i+\beta_iP_i)) - \alpha_i\beta_iP_i

Now that the objective function is in DCP form, the problem can be solved using CVXPY.

.. code:: python

#!/usr/bin/env python3
# @author: R. Gowers, S. Al-Izzi, T. Pollington, R. Hill & K. Briggs

import numpy as np
import cvxpy as cp

.. code:: python

def optimal_power(n, a_val, b_val, P_tot=1.0, W_tot=1.0):
    # Input parameters: α and β are constants from R_i equation
    n = len(a_val)
    if n != len(b_val):
        print('alpha and beta vectors must have same length!')
        return 'failed', np.nan, np.nan, np.nan
    
    P = cp.Variable(shape=n)
    W = cp.Variable(shape=n)
    alpha = cp.Parameter(shape=n)
    beta = cp.Parameter(shape=n)
    alpha.value = np.array(a_val)
    beta.value = np.array(b_val)

    # This function will be used as the objective so must be DCP; 
    # i.e. elementwise multiplication must occur inside kl_div, 
    # not outside otherwise the solver does not know if it is DCP...
    R = cp.kl_div(cp.multiply(alpha, W),
                  cp.multiply(alpha, W + cp.multiply(beta, P))) - \
                  cp.multiply(alpha, cp.multiply(beta, P))

    objective = cp.Minimize(cp.sum(R))
    constraints = [P>=0.0,
                   W>=0.0,
                   cp.sum(P)-P_tot==0.0,
                   cp.sum(W)-W_tot==0.0]
    
    prob = cp.Problem(objective, constraints)
    prob.solve()
      
    return prob.status, -prob.value, P.value, W.value

Example

Consider the case where there are 5 channels, :math:n=5, :math:\alpha = \beta = (2.0,2.2,2.4,2.6,2.8), :math:P_{\text{tot}} = 0.5 and :math:W_{\text{tot}}=1.

.. code:: python

np.set_printoptions(precision=3)
n = 5               # number of receivers in the system

a_val = np.arange(10,n+10)/(1.0*n)  # α
b_val = np.arange(10,n+10)/(1.0*n)  # β
P_tot = 0.5
W_tot = 1.0
status, utility, power, bandwidth = optimal_power(n, a_val, b_val, P_tot, W_tot)

print('Status: {}'.format(status))
print('Optimal utility value = {:.4g}'.format(utility))
print('Optimal power level:\n{}'.format(power))
print('Optimal bandwidth:\n{}'.format(bandwidth))

.. parsed-literal::

Status: optimal
Optimal utility value = 2.451
Optimal power level:
[1.151e-09 1.708e-09 2.756e-09 5.788e-09 5.000e-01]
Optimal bandwidth:
[3.091e-09 3.955e-09 5.908e-09 1.193e-08 1.000e+00]