import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy import optimize


# this script checks for the prevalence values that yield the maximum or minimum values of smoothness;
# the result indicates any linear distribution (not only the uniform) satisfies this requirement

def sharpness(p):
    return 0.5 * sum((-p_prev + 2*p_i - p_next)**2 for p_prev, p_i, p_next in zip(p[:-2], p[1:-1], p[2:]))

def smoothness(p):
    return 1-sharpness(p)

nclasses = 5
uniform_distribution = np.random.rand(nclasses) #np.full(fill_value=1/nclasses, shape=nclasses)
uniform_distribution /= uniform_distribution.sum()

bounds = tuple((0, 1) for x in range(nclasses))  # values in [0,1]
constraints = ({'type': 'eq', 'fun': lambda x: 1 - sum(x)})  # values summing up to 1
r = optimize.minimize(sharpness, x0=uniform_distribution, method='SLSQP', bounds=bounds, constraints=constraints)

print(f'minimum of sharpness function {r.x}')

r = optimize.minimize(smoothness, x0=uniform_distribution, method='SLSQP', bounds=bounds, constraints=constraints)
print(f'maximum of sharpness function {r.x}')