Исходный код iOpt.evolvent.evolvent

import numpy as np
import math


[документация]class Evolvent: r"""Class Evolvent :param lower_bound_of_float_variables: array for lower bounds, А. :type lower_bound_of_float_variables: np.ndarray(shape = (1), dtype = np.double). :param upper_bound_of_float_variables: array for upper bounds, В. :type upper_bound_of_float_variables: np.ndarray(shape = (1), dtype = np.double). :param number_of_float_variables: dimension (N). :type number_of_float_variables: int. :param evolvent_density: evolvent density (m). :type evolvent_density: int. """ def __init__(self, lower_bound_of_float_variables: np.ndarray(shape=(1), dtype=np.double) = [], upper_bound_of_float_variables: np.ndarray(shape=(1), dtype=np.double) = [], number_of_float_variables: int = 1, evolvent_density: int = 10 ): self.number_of_float_variables = number_of_float_variables self.lower_bound_of_float_variables = np.copy(lower_bound_of_float_variables) self.upper_bound_of_float_variables = np.copy(upper_bound_of_float_variables) self.evolvent_density = evolvent_density self.nexpValue = 0 # nexpExtended self.nexpExtended: np.double = 1.0 # инициализируем массив y нулями self.yValues = np.zeros(self.number_of_float_variables, dtype=np.double) # np.ndarray(shape = (1), dtype = np.double) = [0,0] # y for i in range(0, self.number_of_float_variables): self.nexpExtended += self.nexpExtended # Установка границ # ----------------
[документация] def set_bounds(self, lower_bound_of_float_variables: np.ndarray(shape=(1), dtype=np.double) = [], upper_bound_of_float_variables: np.ndarray(shape=(1), dtype=np.double) = [] ): r"""Set bounds :param lower_bound_of_float_variables: array for lower bounds, А. :type lower_bound_of_float_variables: np.ndarray(shape = (1), dtype = np.double). :param upper_bound_of_float_variables: array for upper bounds, В. :type upper_bound_of_float_variables: np.ndarray(shape = (1), dtype = np.double). """ self.lower_bound_of_float_variables = np.copy(lower_bound_of_float_variables) self.upper_bound_of_float_variables = np.copy(upper_bound_of_float_variables)
[документация] def get_image(self, x: np.double ) -> np.ndarray(shape=(1), dtype=np.double): r"""Get image (x->y) :param x: value of *x*. :type x: np.double. :return: array of values *y*. :rtype: np.ndarray(shape = (1), dtype = np.double). """ self.__get_y_on_x(x) self.__transform_p_2_d() return np.copy(self.yValues)
[документация] def get_inverse_image(self, y: np.ndarray(shape=(1), dtype=np.double) ) -> np.double: r"""Get inverse image (y->x) :param y: value of *y*. :type y: np.ndarray(shape = (1), dtype = np.double). :return: value of *x*. :rtype: np.double:. """ self.yValues = np.copy(y) self.__transform_d_2_p() x = self.__get_x_on_y() return x
# ----------------------
[документация] def get_preimages(self, y: np.ndarray(shape=(1), dtype=np.double), ) -> np.double: r"""Get inverse image (y->x) :param y: value of *y*. :type y: np.ndarray(shape = (1), dtype = np.double). :return: value of *x*. :rtype: np.double:. """ self.yValues = np.copy(y) self.__transform_d_2_p() x = self.__get_x_on_y() return x
# Преобразование # -------------------------------- def __transform_p_2_d(self): for i in range(0, self.number_of_float_variables): self.yValues[i] = self.yValues[i] * ( self.upper_bound_of_float_variables[i] - self.lower_bound_of_float_variables[i]) + \ (self.upper_bound_of_float_variables[i] + self.lower_bound_of_float_variables[i]) / 2 # Преобразование # -------------------------------- def __transform_d_2_p(self): for i in range(0, self.number_of_float_variables): self.yValues[i] = (self.yValues[i] - ( self.upper_bound_of_float_variables[i] + self.lower_bound_of_float_variables[i]) / 2) / \ (self.upper_bound_of_float_variables[i] - self.lower_bound_of_float_variables[i]) # --------------------------------- def __get_y_on_x(self, _x: np.double) -> np.ndarray(shape=(1), dtype=np.double): if self.number_of_float_variables == 1: self.yValues[0] = _x - 0.5 return self.yValues iu: np.narray(shape=(1), dtype=np.int32) iv: np.narray(shape=(1), dtype=np.int32) node: np.int32 d: np.double = 0.0 # mn: np.int32 r: np.double iw: np.narray(shape=(1), dtype=np.int32) it: np.int32 i: np.int32 j: np.int32 iis: np.double d = _x r = 0.5 it = 0 # mn = self.evolvent_density * self.number_of_float_variables iw = np.ones(self.number_of_float_variables, dtype=np.int32) self.yValues = np.zeros(self.number_of_float_variables, dtype=np.double) iu = np.zeros(self.number_of_float_variables, dtype=np.int32) iv = np.zeros(self.number_of_float_variables, dtype=np.int32) for j in range(0, self.evolvent_density): if math.isclose(_x, 1.0): iis = self.nexpExtended - 1.0 d = 0.0 else: d *= self.nexpExtended iis = int(d) d -= iis # print(iis, self.number_of_float_variables) node = self.__calculate_node(iis, self.number_of_float_variables, iu, iv) # print(j, node) # заменить на () = () ! i = iu[0] iu[0] = iu[it] iu[it] = i i = iv[0] iv[0] = iv[it] iv[it] = i if node == 0: node = it elif node == it: node = 0 r *= 0.5 it = node for i in range(0, self.number_of_float_variables): iu[i] *= iw[i] iw[i] *= -iv[i] self.yValues[i] += r * iu[i] return np.copy(self.yValues) # --------------------------------- def __get_x_on_y(self) -> np.double: x: np.double if self.number_of_float_variables == 1: x = self.yValues[0] + 0.5 return x u: np.narray(shape=(1), dtype=np.int32) v: np.narray(shape=(1), dtype=np.int32) w: np.narray(shape=(1), dtype=np.int32) r: np.double = 0.0 i: np.int32 j: np.int32 it: np.int32 node: np.int32 r1: np.double iis: np.double w = np.ones(self.number_of_float_variables, dtype=np.int32) u = np.zeros(self.number_of_float_variables, dtype=np.int32) v = np.zeros(self.number_of_float_variables, dtype=np.int32) r = 0.5 r1 = 1.0 x = 0.0 it = 0 for j in range(0, self.evolvent_density): r *= 0.5 for i in range(0, self.number_of_float_variables): if self.yValues[i] < 0: u[i] = -1 else: u[i] = 1 self.yValues[i] -= r * u[i] u[i] *= w[i] i = u[0] u[0] = u[it] u[it] = i iis, node, v = self.__calculate_numbr(u, v) # print(u) # print(v) # print(iis, node) i = v[0] v[0] = v[it] v[it] = i for i in range(0, self.number_of_float_variables): w[i] *= -v[i] if node == 0: node = it elif node == it: node = 0 it = node r1 = r1 / self.nexpExtended x += r1 * iis return x # ----------------------------------------------------------------------------------------- def __calculate_numbr(self, u: np.ndarray(shape=(1), dtype=np.int32), v: np.ndarray(shape=(1), dtype=np.int32) ): i = 0 k1 = -1 k2 = 0 l1 = 0 node = 0 iis: np.double iff: np.double iff = self.nexpExtended iis = 0.0 for i in range(0, self.number_of_float_variables): iff /= 2 k2 = -k1 * u[i] v[i] = u[i] k1 = k2 if k2 < 0: node1 = i else: iis += iff node = i if math.isclose(iis, 0.0): node = self.number_of_float_variables - 1 else: v[self.number_of_float_variables - 1] = -v[self.number_of_float_variables - 1] if math.isclose(iis, self.nexpExtended - 1.0): node = self.number_of_float_variables - 1 else: if node1 == self.number_of_float_variables - 1: v[node] = -v[node] else: node = node1 s = iis return s, node, v # ----------------------------------------------------------------------------------------- def __calculate_node(self, iis: np.double, n: int, u: np.ndarray(shape=(1), dtype=np.int32), v: np.ndarray(shape=(1), dtype=np.int32), ): iq = 1 n1 = n - 1 node = 0 if math.isclose(iis, 0.0): node = n1 for i in range(0, n): u[i] = -1 v[i] = -1 elif math.isclose(iis, self.nexpExtended - 1.0): node = n1 u[0] = 1 v[0] = 1 for i in range(1, n): u[i] = -1 v[i] = -1 v[n1] = 1 else: iff = self.nexpExtended k1 = -1 for i in range(0, n): iff /= 2 if iis >= iff: # исправить сравнение! if math.isclose(iis, iff) and not math.isclose(iis, 1.0): node = i iq = -1 iis -= iff k2 = 1 else: k2 = -1 if math.isclose(iis, (iff - 1.0)) and not math.isclose(iis, 0.0): node = i iq = 1 j = -k1 * k2 v[i] = j u[i] = j k1 = k2 v[node] = v[node] * iq v[n1] = -v[n1] return node
# -----------------------------------------------------------------------------------------