def add_to_Nk(Nk0: np.array, binom_table: np.ndarray, binom_index: int)->np.array: """ Дополняет индексы положительных базисных векторов так, чтобы составленная из них матрица была квадратной :param Nk0: массив индексов положительных переменных :param binom_table: биномиальная таблица, созданная функцией `utils.binomial_grid` :param binom_index: номер итерации смены базиса от 0 до C[|Nk_plus|,m-|Nk0|] :return: индексы из `Nk0`, которые надо добавить к `Nk_plus`, чтобы получить квадратную матрицу """ return subset_by_index(Nk0, binom_table, binom_index)
def add_to_Nk(Nk0: np.array, binom_table: np.ndarray, binom_index: int) -> np.array: """ Augments indices of positive basis vectors so that they form a square matrix when put together :param Nk0: an array of indices of positive vectors :param binom_table: binomial table created by `utils.binomial_grid` method :param binom_index: iteration of basis change (0 to C[|Nk_plus|,m-|Nk0|]) :return: indices from `Nk0` that should be added to `Nk_plus` in order to make a square matrix from vectors with those indices """ return subset_by_index(Nk0, binom_table, binom_index)
def find_all_svs(cf: NpCanonicalForm): binom_table = binomial_grid(cf.n, cf.m) N = np.array(list(range(cf.n))) for idx in range(binom_table[-1, -1]): Nk = subset_by_index(N, binom_table, idx) AMNk = np.array([cf.A[:, i] for i in Nk]).T if np.abs(np.linalg.det(AMNk)) > 1e-3: xNk = np.matmul(np.linalg.inv(AMNk), cf.b) if np.min(xNk) < 0: continue xN = np.zeros(cf.n) for i in range(len(Nk)): xN[Nk[i]] = xNk[i] yield xN
def starting_vector(cf: CanonicalForm) -> np.array: binom_table = binomial_grid(cf.n, cf.m) N = np.array(list(range(cf.n))) for idx in range(binom_table[-1, -1]): Nk = subset_by_index(N, binom_table, idx) AMNk = np.array([cf.A[:, i] for i in Nk]).T if np.linalg.det(AMNk) != 0: xNk = np.matmul(np.linalg.inv(AMNk), cf.b) if np.min(xNk) < 0: continue # we need only vectors with all positive components xN = np.zeros(cf.n) for i in range(len(Nk)): xN[Nk[i]] = xNk[i] return xN logging.info("error, initial vector not found!") return np.zeros(cf.n)
def find_min_sv(cf: CanonicalForm, target_function: Callable[[np.array], float], abs_tolerance: float = 1e-3) -> BruteForceResult: binom_table = binomial_grid(cf.n, cf.m) N = np.array(list(range(cf.n))) min_sv, inv_AMNk_min, Nk_min = None, None, None for idx in range(binom_table[-1, -1]): Nk = subset_by_index(N, binom_table, idx) AMNk = np.array([cf.A[:, i] for i in Nk]).T if np.abs(np.linalg.det(AMNk)) > abs_tolerance: inv_AMNk = np.linalg.inv(AMNk) xNk = np.matmul(inv_AMNk, cf.b) if np.min(xNk) < 0: continue xN = np.zeros(cf.n) for i in range(len(Nk)): xN[Nk[i]] = xNk[i] if min_sv is None or target_function(xN) < target_function(min_sv): min_sv, inv_AMNk_min, Nk_min = xN, inv_AMNk, Nk return BruteForceResult(min_sv, inv_AMNk_min, Nk_min)