9.2 Functions

Objective and constraint functions can be defined via overloaded operations on variables and other functions. A function f is interpreted as a column vector, with length len(f) and with a value that depends on the values of its variables. Functions have two public attributes.

variables()

Returns a copy of the list of variables of the function.

value()

The function value. If any of the variables of f has value None, then f.value() returns None. Otherwise, it returns a dense ’d’ matrix of size (len(f),1) with the function value computed from the value attributes of the variables of f.

Three types of functions are supported: affine, convex piecewise-linear and concave piecewise-linear.

Affine functions represent vector valued functions of the form

f(x1,...,xn) = A1x1 + ⋅⋅⋅+ Anxn + b.

The coefficients can be scalars or dense or sparse matrices. The constant term is a scalar or a column vector.

Affine functions result from the following operations.

Unary operations
For a variable x, the unary operation +x results in an affine function with x as variable, coefficient 1.0, and constant term 0.0. The unary operation -x returns an affine function with x as variable, coefficient -1.0, and constant term 0.0. For an affine function f, +f is a copy of f, and -f is a copy of f with the signs of its coefficients and constant term reversed.
Addition and subtraction
Sums and differences of affine functions, variables and constants result in new affine functions. The constant terms in the sum can be of type integer or float, or dense or sparse ’d’ matrices with one column.

The rules for addition and subtraction follow the conventions for matrix addition and subtraction in sections 2.3 and 2.3, with variables and affine functions interpreted as dense ’d’ matrices with one column. In particular, a scalar term (integer, float, 1 by 1 dense ’d’ matrix, variable of length 1, or affine function of length 1) can be added to an affine function or variable of length greater than 1.

Multiplication
Suppose v is an affine function or a variable, and a is an integer, float, sparse or dense ’d’ matrix. The products a*v and v*a are valid affine functions whenever the product is allowed under the rules for matrix and scalar multiplication of sections 2.3 and 2.3, with v interpreted as a ’d’ matrix with one column. In particular, the product a*v is defined if a is a scalar (integer, float or 1 by 1 dense ’d’ matrix), or a matrix (dense or sparse) with a.size[1] = len(v). The operation v*a is defined if a is scalar, or if len(v) = 1 and a is a matrix with one column.
Inner products
The following two functions return scalar affine functions defined as inner products of a constant vector with a variable or affine function.

sum(v)

The argument is an affine function or a variable. The result is an affine function of length 1, with the sum of the components of the argument v.

dot(u,v)

If v is a variable or affine function and u is a ’d’ matrix of size (len(v),1), then dot(u,v) and dot(v,u) are equivalent to u.trans()*v.

If u and v are dense matrices, then dot(u,v) is equivalent to the function blas.dot(u,v) defined in section 3.2, i.e., it returns the inner product of the two matrices.

In the following example, the variable x has length 1 and y has length 2. The functions f and g are given by

           [   ]       [   ]
f(x,y)  =    2  x + y+   3  ,
           [ 2    ]      3 [      ]   [     ]
             1  3            1  1        1
g(x,y)  =    2  4  f(x,y)+   1  1  y+   - 1
           [  8 ]    [ 2 4 ]    [ 13 ]
        =    12  x +   3 5   y+   17  .
>>> from cvxopt.modeling import variable  
>>> x = variable(1,’x’)  
>>> y = variable(2,’y’)  
>>> f = 2*x + y + 3  
>>> A = matrix([[1., 2.], [3.,4.]])  
>>> b = matrix([1.,-1.])  
>>> g = A*f + sum(y) + b  
>>> print g  
affine function of length 2  
constant term:  
[ 1.30e+01]  
[ 1.70e+01]  
linear term: linear function of length 2  
coefficient of variable(2,’y’):  
[ 2.00e+00  4.00e+00]  
[ 3.00e+00  5.00e+00]  
coefficient of variable(1,’x’):  
[ 8.00e+00]  
[ 1.20e+01]

In-place operations
For an affine function f the operations f += u and f -= u, with u a constant, a variable or an affine function, are allowed if they do not change the length of f, i.e., if u has length len(f) or length 1. In-place multiplication f *= u and division f /= u are allowed if u is an integer, float, or 1 by 1 matrix.
Indexing and slicing
Variables and affine functions admit single-argument indexing of the four types described in section 2.4. The result of an indexing or slicing operation is an affine function.
>>> x = variable(4,’x’)  
>>> f = x[::2]  
>>> print f  
linear function of length 2  
linear term: linear function of length 2  
coefficient of variable(4,’x’):  
[ 1.00e+00     0         0         0    ]  
[    0         0      1.00e+00     0    ]  
>>> y = variable(3,’x’)  
>>> g = matrix(range(12),(3,4),’d’)*x - 3*y + 1  
>>> print g[0] + g[2]  
affine function of length 1  
constant term:  
[ 2.00e+00]  
linear term: linear function of length 1  
coefficient of variable(4,’x’):  
[ 2.00e+00  8.00e+00  1.40e+01  2.00e+01]  
coefficient of variable(3,’x’):  
[-3.00e+00     0     -3.00e+00]

The general expression of a convex piecewise-linear function is

                                   K∑
f(x1,...,xn) = b+ A1x1 + ⋅⋅⋅+ Anxn +   max(y1,y2,...,ymk).
                                   k=1

The maximum in this expression is a componentwise maximum of its vector arguments, which can be constant vectors, variables, affine functions or convex piecewise-linear functions. The general expression for a concave piecewise-linear function is

                                    K
f(x ,...,x ) = b+ A x  +⋅⋅⋅+ A x  + ∑  min(y ,y,...,y  ).
   1     n        1 1        n  n  k=1     1 2     mk

Here the arguments of the min() can be constants, variables, affine functions or concave piecewise-linear functions.

Piecewise-linear functions can be created using the following operations.

Maximum
If the arguments in f = max(y1,y2, …) do not include any variables or functions, then the Python built-in max() is evaluated.

If one or more of the arguments are variables or functions, max() returns a piecewise-linear function defined as the elementwise maximum of its arguments. In other words, f[k] = max(y1[k],y2[k], …) for k=0, …, len(f)-1. The length of f is equal to the maximum of the lengths of the arguments. Each argument must have length equal to len(f) or length one. Arguments with length one are interpreted as vectors of length len(f) with identical entries.

The arguments can be scalars of type integer or float, dense ’d’ matrices with one column, variables, affine functions or convex piecewise-linear functions.

With one argument, f = max(u) is interpreted as f = max(u[0],u[1],…, u[len(u)-1]).

Minimum
Similar to max() but returns a concave piecewise-linear function. The arguments can be scalars of type integer or float, dense ’d’ matrices with one column, variables, affine functions or concave piecewise-linear functions.
Absolute value
If u is a variable or affine function then f = abs(u) returns the convex piecewise-linear function max(u,-u).
Unary plus and minus
+f creates a copy of f. -f is a concave piecewise-linear function if f is convex and a convex piecewise-linear function if f is concave.
Addition and subtraction
Sums and differences involving piecewise-linear functions are allowed if they result in convex or concave functions. For example, one can add two convex or two concave functions, but not a convex and a concave function. The command sum(f) is equivalent to f[0] + f[1] + …+ f[len(f)-1].
Multiplication
Scalar multiplication a*f of a piecewise-linear function f is defined if a is an integer, float, 1 by 1 ’d’ matrix. Matrix-matrix multiplications a*f or f*a are only defined if a is a dense or sparse 1 by 1 matrix.
Indexing and slicing
Piecewise-linear functions admit single-argument indexing of the four types described in section 2.4. The result of an indexing or slicing operation is a new piecewise-linear function.

In the following example, f is the 1-norm of a vector variable x of length 10, g is its infinity-norm and h is the function

                          (
      ∑                   {  0       |u | ≤ 1
h(x) =   ϕ(x[k]),    ϕ(u) = ( |u|- 1   1 ≤ |u| ≤ 2
       k                     2|u|- 3  |u | ≥ 2.

>>> from cvxopt.modeling import variable, max  
>>> x = variable(10, ’x’)  
>>> f = sum(abs(x))  
>>> g = max(abs(x))  
>>> h = sum(max(0, abs(x)-1, 2*abs(x)-3))

In-place operations
If f is piecewise-linear then the in-place operations f += u, f -= u, f *= u, f /= u are defined if the corresponding expanded operations f = f+u, f = f-u, f = f*u and f = f/u are defined and if they do not change the length of f.