import numpy as np
# credits: Soros Qin

def bt_lsearch2021(x, d, g, fname, *args):
    rho = 0.1
    gamma = 0.5
    
    # Ensure x, d, g are 1D numpy arrays
    x = np.asarray(x).flatten()
    d = np.asarray(d).flatten()
    g = np.asarray(g).flatten()
    
    a = 1.0
    t0 = rho * np.dot(g, d)
    f0 = fname(x, *args)
    
    xw = x + a * d
    f1 = fname(xw, *args)
    er = f1 - (f0 + a * t0)
    
    while er > 0:
        a *= gamma
        xw = x + a * d
        f1 = fname(xw, *args)
        er = f1 - (f0 + a * t0)
    
    # Ensure a is not too small
    if a < 1e-5:
        a = min(1e-5, 0.1 / np.linalg.norm(d))
    
    return a

