#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Aug 20 14:52:26 2024

@author: sam
"""

import numpy as np

minimum = []

'''functions'''
def f(x):
    return x*np.cos(x) + x*np.sin(x/2)

def minbracket(f,a,b,N):
    h = (b-a)/N
    for i in range(1,int(N)):
        x = a+h*i
        if f(x)<f(x-h) and f(x)<f(x+h):
            minimum.append([x-h,x+h])
        else:
            continue
    
def goldensearch(f,a,b,tol):
    j = 0
    for i in minimum: #itterates through bracketed minimums from minbracket function
        a = i[0] #defines lower bound for each bracket, each itteration
        b = i[1] #upper bound
        while abs(b-a) > tol: #checks for tolerance
            Φ = (1+np.sqrt(5))/2 #define golden ratio
            c = b - (b-a)/Φ #new bound
            d = a + (b-a)/Φ #new bound
            if f(c)<f(d):
                b = d #d becomes new upper bound
            elif f(d)<f(c):
                a = c #c becomes new lower bound
        minimum[j] = [(a+b)/2] #takes midpoint of bound to be minimum, saves this to jth element of minimum
        j += 1 #move to next bracketed minimum in list

   

'''run code'''
a = -10
b = 10
N = 1e5
tol = 1e-5

minbracket(f,a,b,N)
goldensearch(f,a,b,tol)
for i in range(len(minimum)):
    print(minimum[i])