geo_mean

class cvxpy.geo_mean(x, p=None, max_denom=1024)[source]

The (weighted) geometric mean of vector x, with optional powers given by p:

\[\left(x_1^{p_1} \cdots x_n^{p_n} \right)^{\frac{1}{\mathbf{1}^Tp}}\]

The powers p can be a list, tuple, or numpy.array of nonnegative int, float, or Fraction objects with nonzero sum.

If not specified, p defaults to a vector of all ones, giving the unweighted geometric mean

\[x_1^{1/n} \cdots x_n^{1/n}.\]

The geometric mean includes an implicit constraint that \(x_i \geq 0\) whenever \(p_i > 0\). If \(p_i = 0\), \(x_i\) will be unconstrained.

The only exception to this rule occurs when p has exactly one nonzero element, say, p_i, in which case geo_mean(x, p) is equivalent to x_i (without the nonnegativity constraint). A specific case of this is when \(x \in \mathbf{R}^1\).

Note

Generally, p cannot be represented exactly, so a rational, i.e., fractional, approximation must be made.

Internally, geo_mean immediately computes an approximate normalized weight vector \(w \approx p/\mathbf{1}^Tp\) and the geo_mean atom is represented as

\[x_1^{w_1} \cdots x_n^{w_n},\]

where the elements of w are Fraction objects that sum to exactly 1.

The maximum denominator used in forming the rational approximation is given by max_denom, which defaults to 1024, but can be adjusted to modify the accuracy of the approximations.

The approximating w and the approximation error can be found through the attributes geo_mean.w and geo_mean.approx_error.

Parameters:

x : cvxpy.Variable

A column or row vector whose elements we will take the geometric mean of.

p : Sequence (list, tuple, …) of int, float, or Fraction objects

A vector of weights for the weighted geometric mean

When p is a sequence of int and/or Fraction objects, w can often be an exact representation of the weights. An exact representation is sometimes possible when p has float elements with only a few decimal places.

max_denom : int

The maximum denominator to use in approximating p/sum(p) with geo_mean.w. If w is not an exact representation, increasing max_denom may offer a more accurate representation, at the cost of requiring more convex inequalities to represent the geometric mean.

Examples

The weights w can be seen from the string representation of the geo_mean object, or through the w attribute.

>>> from cvxpy import Variable, geo_mean, Problem, Maximize
>>> x = Variable(3, name='x')
>>> print(geo_mean(x))
geo_mean(x, (1/3, 1/3, 1/3))
>>> g = geo_mean(x, [1, 2, 1])
>>> g.w
(Fraction(1, 4), Fraction(1, 2), Fraction(1, 4))

Floating point numbers with few decimal places can sometimes be represented exactly. The approximation error between w and p/sum(p) is given by the approx_error attribute.

>>> import numpy as np
>>> x = Variable(4, name='x')
>>> p = np.array([.12, .34, .56, .78])
>>> g = geo_mean(x, p)
>>> g.w
(Fraction(1, 15), Fraction(17, 90), Fraction(14, 45), Fraction(13, 30))
>>> g.approx_error
0.0

In general, the approximation is not exact.

>>> p = [.123, .456, .789, .001]
>>> g = geo_mean(x, p)
>>> g.w
(Fraction(23, 256), Fraction(341, 1024), Fraction(295, 512), Fraction(1, 1024))
>>> 1e-4 <= g.approx_error <= 1e-3
True

The weight vector p can contain combinations of int, float, and Fraction objects.

>>> from fractions import Fraction
>>> x = Variable(4, name='x')
>>> g = geo_mean(x, [.1, Fraction(1,3), 0, 2])
>>> print(g)
geo_mean(x, (3/73, 10/73, 0, 60/73))
>>> g.approx_error <= 1e-10
True

Sequences of Fraction and int powers can often be represented exactly.

>>> p = [Fraction(1,17), Fraction(4,9), Fraction(1,3), Fraction(25,153)]
>>> x = Variable(4, name='x')
>>> print(geo_mean(x, p))
geo_mean(x, (1/17, 4/9, 1/3, 25/153))

Terms with a zero power will not have an implicit nonnegativity constraint.

>>> p = [1, 0, 1]
>>> x = Variable(3, name='x')
>>> obj = Maximize(geo_mean(x,p))
>>> constr = [sum(x) <= 1, -1 <= x, x <= 1]
>>> val = Problem(obj, constr).solve()
>>> x = np.array(x.value).flatten()
>>> print(x)
[ 1. -1.  1.]

Attributes

w tuple of Fractions A rational approximation of p/sum(p).
approx_error float The error in approximating p/sum(p) with w, given by \(\|p/\mathbf{1}^T p - w \|_\infty\)