I want to generate a toy example to illustrate a convex piecewise linear function in python
, but I couldn't figure out the best way to do this. What I want to do is to indicate the number of lines and generate the function randomly.
A convex piecewise-linear function is defined as:
For instance, if I want to have four linear lines, then I want to generate something as shown below.
Since there are four lines. I need to generate four increasing random integers to determine the intervals in x-axis.
import random
import numpy as np
random.seed(1)
x_points = np.array(random.sample(range(1, 20), 4))
x_points.sort()
x_points = np.append(0, x_points)
x_points
[0 3 4 5 9]
I can now use the first two points and create a random linear function, but I don't know how I should continue from there to preserve the convexity. Note that a function is called convex if the line segment between any two points on the graph of the function does not lie below the graph between the two points.
Piecewise-linear functions are functions for which there are defined intervals over which the function is linear. Definition 1. A function f : Rn → R is a convex piecewise-linear if there exist c1,...,cN ∈ Rn. and d1,...,dN ∈ R s.t. f(x) = maxi∈[N] cT. i x + di.
Yes, it can be convex. Take f(x) = |x|. It is a piecewise convex function, and overall, convex. Similarly, g(x) = -|x| is piecewise convex but not convex overall, when you consider the linear sections together.
The slope increases monotonously by a random value from the range [0,1), starting from 0. The first y value is also zero, see the comments.
import numpy as np
np.random.seed(0)
x_points = np.random.randint(low=1, high=20, size=4)
x_points.sort()
x_points = np.append(0, x_points) # the first 0 point is 0
slopes = np.add.accumulate(np.random.random(size=3))
slopes = np.append(0,slopes) # the first slope is 0
y_incr = np.ediff1d(x_points)*slopes
y_points = np.add.accumulate(y_incr)
y_points = np.append(0,y_points) # the first y values is 0
A possible output looks like this:
print(x_points)
print(y_points)
# [ 0 1 4 13 16]
# [ 0. 0. 2.57383685 17.92061306 24.90689622]
To print this figure:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(x_points,y_points, '-o', label="convex piecewise-linear function")
ax.legend()
fig.patch.set_facecolor('white')
plt.show()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With