#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Nov  6 18:08:39 2024

@author: amriksen
"""

import numpy as np
import matplotlib.pyplot as plt

# Define the multivariate function and its gradient
def f(x, y):
    return (x - 3)**2 + (y + 2)**2

def grad_f(x, y):
    df_dx = 2 * (x - 3)
    df_dy = 2 * (y + 2)
    return np.array([df_dx, df_dy])

# Incremental Gradient Descent
def incremental_gradient_descent(starting_point, learning_rate=0.1, n_iterations=50):
    point = np.array(starting_point)
    points_history = [point]
    
    for i in range(n_iterations):
        gradient = grad_f(point[0], point[1])
        point = point - learning_rate * gradient
        points_history.append(point)
    
    return np.array(points_history)

# Initial parameters
starting_point = (-6, 5)
learning_rate = 0.1
n_iterations = 50

# Run incremental gradient descent
points_history = incremental_gradient_descent(starting_point, learning_rate, n_iterations)

# Create contour plot of the function
x_vals = np.linspace(-7, 7, 100)
y_vals = np.linspace(-7, 7, 100)
X, Y = np.meshgrid(x_vals, y_vals)
Z = f(X, Y)

plt.figure(figsize=(10, 6))
plt.contour(X, Y, Z, levels=30, cmap="viridis")
plt.plot(points_history[:, 0], points_history[:, 1], 'ro-', markersize=3, label="Path of Incremental Gradient Descent")
plt.scatter(3, -2, color='blue', marker='x', s=100, label="Minimum (3, -2)")
plt.xlabel("x")
plt.ylabel("y")
plt.title("Incremental Gradient Descent Path on Contour Plot")
plt.legend()
plt.show()