<jupyter_start><jupyter_text>Ackley function\begin{equation*}f(x) = -20 \exp \left( -\frac{1}{5}\sqrt{ \frac{1}{d} \sum_{i=1}^{d} x_i^2 }\right) -\exp\left( \frac{1}{d} \sum_{i=1}^{d} \cos\left(2\pi x_i \right) \right) + 20 + e, \\f'(x) = \left(... , g\left(x_j\right), ...\right)^d, \\g(x_j) = 4\frac{x_j}{d\sqrt{ \frac{1}{2} \sum_{i=1}^{2} x_i^2 } } \exp \left( -\frac{1}{5}\sqrt{ \frac{1}{d} \sum_{i=1}^{d} x_i^2 }\right) +\frac{2\pi}{d} \sin(2\pi x_j) \exp\left( \frac{1}{d} \sum_{i=1}^{d} \cos\left(2\pi x_i \right) \right),\\f^*(x^*)=0, x^*=(0)^d\end{equation*}<jupyter_code>class ackley(objective_func):
    def __init__(self, dim=2):
        self.optimum = 0
        self.lim = 25
        self.dim = dim
        self.optimal = np.zeros((self.dim, ))
    def func(self, x):
        '''
        the period of local minimum along each axis is 1, integer coordinate (1,1), (2,3)... 
        x and y is interchangeable
        global minimum is 0 with arguments x=y=0
        local minimums far away from orgin are 20
        supremum is 20 + e - 1/e = 22.35
        symmetric along x=0, y=0, y=x lines
        disappearing global gradient when far away from optimal
        '''
        arg1 = -0.2 * np.sqrt(np.power(x, 2).mean())
        arg2 = np.cos(2*np.pi*x).mean()
        return -20. * np.exp(arg1) - np.exp(arg2) + 20. + np.e
    def dfunc(self, x):
        if np.linalg.norm(x) == 0:
            return x
        arg1 = -0.2 * np.sqrt(np.power(x, 2).mean())
        arg2 = np.cos(2*np.pi*x).mean()
        g = lambda xx: -0.8 * xx / arg1 * np.exp(arg1) / self.dim + 2 * np.pi * np.sin(2 * np.pi * xx) * np.exp(arg2) / self.dim
        return g(x)
    def get_optimal(self):
        return self.optimal
    def get_optimum(self):
        return self.optimum
a = ackley()
print("check func value: expected:", a.get_optimum(), ", actual:", a.func(a.get_optimal()))
print("check gradient: expected:[0,0], actual:",a.dfunc(a.get_optimal()))
a.visualise1d(lim=15, n=300)
a.visualise2d_section(50.0, 'x')
a.visualise2d_section(25, 'x')
a.visualise2d_section(0, 'x')
plt.title("original ackley, f(x1,0) cross section")
plt.xlabel("x1 axis")
plt.ylabel("function value")
a.visualise2d(lim=5, n=100)
plt.plot([0, 0], [-5, 5],  c='grey', lw=1, ls='-.')
plt.plot([-5, 5], [0, 0],  c='grey', lw=1, ls='-.')
plt.plot([-5, 5], [-5, 5], c='grey', lw=1, ls='-.')
plt.plot([-5, 5], [5, -5],  c='grey', lw=1, ls='-.')
a.visualise3d(lim=2, n=50)
a.visulise_gradient(lim=2, n=50)<jupyter_output><empty_output><jupyter_text>bukin function\begin{equation*}f(x) = 100 \sqrt{\left|x_2 - 0.01x_1^2\right|} + 0.01\left|x_1 + 10\right| \\f'(x) = \left(-x_1\frac{1}{\sqrt{\left|x_2 - 0.01x_1^2\right|}} sgn(x_2 - 0.01x_1^2) + 0.01 sgn(x_1+10), \;\;\frac{50}{\sqrt{\left|x_2 - 0.01x_1^2\right|}} sgn(x_2 - 0.01x_1^2) \right) \\f^*(x^*) = 0, x^*=(-10, 1)\end{equation*}<jupyter_code>class bukin(objective_func):
    '''
    non-disappearing gradient
    large gradient and uncontinuous gradient around ridge/local optimal
    optimum: 0
    optimal: (-10, 1)
    '''
    def __init__(self):
        self.optimal = np.array([-10, 1])
        self.optimum = 0
        self.lim = 15
    def func(self, x):
        return 100 * np.sqrt(np.abs(x[1] - 0.01 * x[0]**2)) + 0.01 * np.abs(x[0] + 10)
    def dfunc(self, x):
        arg1 = x[1] - 0.01 * x[0]**2
        arg2 = 50 / np.sqrt(np.abs(arg1)) * np.sign(arg1) if arg1 != 0 else 0
        return np.array([- 0.02 * x[0] * arg2 + 0.01 * np.sign(x[0] + 10), arg2])
    def get_optimal(self):
        return self.optimal
    def get_optimum(self):
        return self.optimum
b = bukin()
print("check func value: expected:", b.get_optimum(), ", actual:", b.func(b.get_optimal()))
print("check gradient: expected:[0,0], actual:", b.dfunc(b.get_optimal()))
b.visualise2d(lim=15, n=100)
plt.xlabel("x1 axis")
plt.ylabel("x2 axis")
plt.title("function value of bukin")
b.visualise2d_section(-10, 'y')
b.visualise2d_section(1, 'x')
b.visualise2d_section(0, 'x')
b.visualise3d(lim=15, n=30)
b.visulise_gradient(lim=15, n=50)
b.dfunc(np.array([100,1.1]))<jupyter_output><empty_output><jupyter_text>eggholder function\begin{equation*}f(x) = -\left( x_2 + 47 \right) \sin\left( \sqrt{\left|\frac{x_1}{2} + (x_2 + 47)\right|} \right) -x_1\sin\left( \sqrt{\left|x_1 - \left(x_2 + 47\right)\right|} \right) + 959.6407, \\|x_1|, |x_2| \leq 512 \\f'(x) = \left(-\sin \left( \sqrt{\left| x'_2 \right|} \right) - \frac{1}{2}(x_2 + 47)g(x'_1) - x_1 g(x'_2)     ,\;\; -\sin \left( \sqrt{\left| x'_1 \right|} \right) - (x_2 + 47)g(x'_1) + x_1 g(x'_2)   \right)\\g(x'_j) = \cos\left( \sqrt{\left|x'_j\right|} \right) \frac{1}{2\sqrt{\left|x'_j\right|}} sgn(x'_j)  \\x'_1 = \frac{x_1}{2} + (x_2 + 47), \\x'_2 = x_1 - (x_2 + 47)\\f^*(x^*)=0, x^*=(512, 404.2319)\end{equation*}<jupyter_code>class eggholder(objective_func):
    # evaluated domain: 
    def __init__(self):
        self.optimal = np.array([522, 413])
        self.optimum = 0
        self.lim = 550
    def func(self, x):
        if np.abs(x[0]) > self.lim or np.abs(x[1]) > self.lim:
            return 2e3
        arg1 = x[0]/2 + (x[1] + 47) 
        arg2 = x[0]   - (x[1] + 47)
        f = lambda xx: np.sin(np.sqrt(np.abs(xx)))
        return -(x[1] + 47) * f(arg1) - x[0] * f(arg2) + 976.873
    def dfunc(self, x):
        if np.abs(x[0]) > self.lim or np.abs(x[1]) > self.lim:
            return np.array([0, 0])
        arg1 = x[0]/2 + (x[1] + 47) 
        arg2 = x[0]   - (x[1] + 47)
        g = lambda xx: np.cos(np.sqrt(np.abs(xx)))/np.sqrt(np.abs(xx))/2*np.sign(xx)
        f1 = (x[1] + 47) * g(arg1)
        f2 = x[0] * g(arg2)
        return np.array([-f1/2 - np.sin(np.sqrt(np.abs(arg2))) - f2, \
                         -f1   - np.sin(np.sqrt(np.abs(arg1))) + f2])
    def get_optimal(self):
        return self.optimal
    def get_optimum(self):
        return self.optimum
e = eggholder()
e.get_optimal()
print("check func value: expected:", e.get_optimum(), ", actual:", e.func(e.get_optimal()))
print("check gradient: expected:[0,0], actual:", e.dfunc(e.get_optimal()))
e.visualise2d(lim=550, n=100)
e.visualise2d_section(e.get_optimal()[1], 'x')
e.visualise2d_section(e.get_optimal()[0], 'y')
e.visualise3d(lim=600, n=100)
e.visulise_gradient(lim=550, n=50)
e.visulise_gradient(lim=550, n=50)<jupyter_output><empty_output><jupyter_text>tuned Ackley function\begin{equation*}f(x) = -20 \exp\left(-\frac{1}{5} \sqrt{\frac{1}{d}\sum_{i=1}^d x_i^2}\right) - \frac{1}{10}\left(-\frac{1}{5} \sqrt{\frac{1}{d}\sum_{i=1}^d x_i^2}\right)^4  \exp\left( \frac{1}{2d}\sum_{i=1}^d \cos\left( \pi x_i\right)\right) + 20\\f'(x) = \left( g\left(x_1\right), \;\; g\left(x_2\right)\right), \\g(x_j) = 4\frac{x_j}{d\sqrt{ \frac{1}{d} \sum_{i=1}^{d} x_i^2 } } \exp \left( -\frac{1}{5}\sqrt{ \frac{1}{d} \sum_{i=1}^{d} x_i^2 }\right) \\+ \frac{\pi}{20d}\left(-\frac{1}{5} \sqrt{\frac{1}{d}\sum_{i=1}^d x_i^2}\right)^4 \sin(\pi x_j) \exp\left( \frac{1}{2d} \sum_{i=1}^{d} \cos\left(\pi x_i \right) \right)\\-\frac{4}{6250d^2}\exp\left( \frac{1}{2d} \sum_{i=1}^{d} \cos\left(\pi x_i \right) \right) \left(\sum_{i=1}^{d} x_i^2\right) x_j \\f^*(x^*) = e, x^*=(0,0)\end{equation*}<jupyter_code>class tuned_ackley(objective_func):
    # evaluated domain: circle with radius 19
    def __init__(self, lim=22, dim=2):
        self.optimum = 0
        self.lim = lim
        self.dim = dim
        self.optimal = np.zeros((self.dim, ))
    def func(self, x):
        '''
        the period of local minimum along each axis is 1, integer coordinate (1,1), (2,3)... 
        x and y is interchangeable
        global minimum is 0 with arguments x=y=0
        symmetric along x=0, y=0, y=x lines
        disappearing global gradient when far away from optimal
        '''
        if np.linalg.norm(x) > self.lim:
            return 5e1
        arg1 = -0.2 * np.sqrt(np.power(x, 2).mean())
        arg2 = 0.5 * np.cos(np.pi*x).mean()
        return -20. * np.exp(arg1) - 0.1 * arg1**4 * np.exp(arg2) + 20.
    def dfunc(self, x):
        if np.linalg.norm(x) == 0:
            return x
        elif np.linalg.norm(x) > self.lim:
            return np.zeros((self.dim, ))
        arg1 = -0.2 * np.sqrt(np.power(x, 2).mean())
        arg2 = 0.5 * np.cos(np.pi*x).mean()
        g = lambda xx: -0.8 * xx / arg1 * np.exp(arg1) / self.dim + np.pi/20 * arg1**4 * np.sin(np.pi * xx) * np.exp(arg2) / self.dim \
                         - 4 * xx/6250 * np.exp(arg2) * np.power(x, 2).sum() / self.dim**2
        return g(x)
    def get_optimal(self):
        return self.optimal
    def get_optimum(self):
        return self.optimum
    def visualise2d_section(self, pos, dire):
        super().visualise2d_section(pos, dire)
        '''   plt.plot([-25, 25], [15.67, 15.67], label='y=15.67')
        plt.plot([-25, 25], [3.63, 3.66], label='y=3.66')
        plt.plot([12.96, 12.96], [0, 50], label='x=12.96')
        plt.plot([22, 22], [0, 50], label='x=22')
  '''
        plt.plot([22, 22], [3.26, 25], c='#1f77b4')
        plt.plot([-22, -22], [3.26, 25], c='#1f77b4')
        
at = tuned_ackley()
print("check func value at optimal is", at.get_optimum(), "(optimuam): ", at.func(at.get_optimal()))
print("check gradient is (0,0): ",at.dfunc(at.get_optimal()))
at.func(np.array([22,0]))
at.func(np.zeros(10,))
at.visualise2d_section(0, 'x')
plt.title("tuned ackley, f(x1,0) cross section")
plt.xlabel("x1 axis")
plt.ylabel("function value")
at.visualize2d_section_gradient(0, 'x')
at.visualise3d(lim=25, n=150)
at.visualise2d(lim=25, n=150)
at.visulise_gradient(lim=25, n=51)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2264071981586106, 'fraction_numerical': 0.06852898095835949, 'mean_word_length': 2.906416019615856, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '348915', 'license': 'MIT', 'n_tokens_mistral': 4467, 'n_tokens_neox': 4087, 'n_words': 786, 'path': 'library/objective_function_class.ipynb', 'repo_name': 'huajian1069/non-convex_optimisation', 'size': '9558'}