def run_all_gradients(f, g, start, eps):
    res, it, _ = gradient_descent(f, g, start, eps, None)
    print("LinearStepSearch\n    ans =", list(res),
          "\n    amount of iterations =", it)
    res_, it, _ = gradient_descent(f, g, start, eps, BisectionSearcher)
    print("BisectionSearcher\n    ans =", list(res_),
          "\n    amount of iterations =", it)
    res_, it, _ = gradient_descent(f, g, start, eps, GoldenRatioSearcher)
    print("GoldenRatioSearcher\n    ans =", list(res_),
          "\n    amount of iterations =", it)
    res_, it, _ = gradient_descent(f, g, start, eps, FibonacciSearcher)
    print("FibonacciSearcher\n    ans =", list(res_),
          "\n    amount of iterations =", it)
    return res
def task7():
    n_range = range(3, 20)
    k_range = [2, 3, 4, 5, 10, 20, 25, 50, 100, 150, 200, 250, 500, 1000]
    zs = []
    random.seed(12856)
    for n in n_range:
        tmp = []
        max_its = 0
        for k_ in k_range:
            k = k_
            m = generate_matrix(n, k)
            # print(get_condition_number(m))
            f = f_by_matrix(m)
            f_grad = f_grad_by_matrix(m)
            start = np.ones(n) * 1
            res, it, path = gradient_descent(f, f_grad, start, 1e-9,
                                             BisectionSearcher)
            tmp.append(it)
        print(tmp)
        zs.append(tmp)
    zs = np.array(zs)
    cs = plt.imshow(zs,
                    interpolation='bicubic',
                    cmap=plt.get_cmap("hot"),
                    origin='lower')
    plt.show()
def draw_descent_steps(func,
                       grad,
                       start,
                       searcher,
                       eps,
                       color="white",
                       show=False,
                       name=""):
    res, it, path = gradient_descent(func, grad, start, eps, searcher)
    distance = np.linalg.norm(start - res)
    xlims = (res[0] - distance, res[0] + distance)
    ylims = (res[1] - distance, res[1] + distance)
    if show:
        draw_double_arg_function(func, xlims, ylims)
    plt.xlim(xlims[0], xlims[1])
    plt.ylim(ylims[0], ylims[1])
    plt.xlabel("X")
    plt.ylabel("Y")
    plt.title("Iterations: " + str(it) + ", Root:\n%.9f\n%.9f" %
              (res[0], res[1]))
    prev_step = None
    for step in path:
        if prev_step is not None:
            plt.plot([prev_step[0], step[0]], [prev_step[1], step[1]],
                     linewidth=1,
                     c=color)
            plt.scatter(step[0], step[1], c=color, s=3)
        else:
            plt.scatter(step[0], step[1], c=color, s=3, label=name)
        prev_step = step
    if show:
        plt.legend()
        # plt.savefig("D:/res/" + name)
        plt.show()
def draw_all_descent_steps(func, grad, grad2, start, eps, single=True):
    if single:
        start = np.array(start)
        res, it, path = gradient_descent(func, grad, start, eps, None)
        distance = np.linalg.norm(start - res)
        xlims = (res[0] - distance, res[0] + distance)
        ylims = (res[1] - distance, res[1] + distance)
        draw_double_arg_function(func, xlims, ylims)
        delta = 1
        draw_descent_steps(func, grad, start, None, eps, "white", False,
                           "LinearSearcher")
        draw_descent_steps(func, grad, start + [delta, 0], BisectionSearcher,
                           eps, "red", False, "BisectionSearcher")
        draw_descent_steps(func, grad, start + [2 * delta, 0],
                           GoldenRatioSearcher, eps, "green", False,
                           "GoldenRatioSearcher")
        draw_descent_steps(func, grad, start + [3 * delta, 0],
                           FibonacciSearcher, eps, "blue", False,
                           "FibonacciSearcher")
        draw_const_descent_steps(func, grad, start + [4 * delta, 0], eps,
                                 "yellow", False, "Const, step = 1e-2")
        draw_newton_steps(func, grad, grad2, start + [5 * delta, 0], eps,
                          "orange", False, "Newton")

        plt.legend()
        plt.show()
    else:
        draw_descent_steps(func, grad, start, None, eps, "white", True,
                           "LinearSearcher")
        draw_descent_steps(func, grad, start, BisectionSearcher, eps, "red",
                           True, "BisectionSearcher")
        draw_descent_steps(func, grad, start, GoldenRatioSearcher, eps,
                           "green", True, "GoldenRatioSearcher")
        draw_descent_steps(func, grad, start, FibonacciSearcher, eps, "blue",
                           True, "FibonacciSearcher")
        draw_const_descent_steps(func, grad, start, eps, "yellow", True,
                                 "Const, step = 1e-2")
        draw_newton_steps(func, grad, grad2, start, eps, "orange", True,
                          "Newton")
 def minimize(self, x):
     result, iters, _ = gradient_descent(self.func, self.grad, x, self.eps,
                                         self.searcher, self.stop_criterion)
     self.iters += iters
     return result