//#####################################################################
// Copyright 2024, Craig Schroeder, Jing Jin.
// This file is part of PhysBAM whose distribution is governed by the license contained in the accompanying file PHYSBAM_COPYRIGHT.txt.
//#####################################################################
#ifndef __Coordinate_Descent__
#define __Coordinate_Descent__
#include <Core/Nonlinear_Equations/ITERATIVE_SOLVER.h>
#include <functional>

namespace PhysBAM{

template<class T,class TV>
TV Coordinate_Descent_Minimum( std::function<T(const TV&)> f, const TV& x0, T max_step, int max_iterations)
{
    TV x=x0;
    T y=f(x);
    for(int it=0;it<max_iterations;it++)
    {
        bool progress=false;
        for(int a=0;a<TV::m;a++)
        {
            auto fa=[&f, a, &x](T dx){return f(x.Add_Axis(a,dx));};

            T t=Golden_Minimum(fa,(T)0,max_step), y0=fa(t);
            if(y0>=y)
            {
                t=Golden_Minimum(fa,(T)0,-max_step);
                y0=fa(t);
            }
            if(y0>=y) continue;
            x(a)+=t;
            y=y0;
            progress=true;
        }
        if(!progress) return x;
    }
    return x;
}
}
#endif
