module MultidimensionalOptimizationMethods.Nesterov_sMethod

open DiffSharp
open FsAlg.Generic

open Types

let run (alpha: float) (betta: float) func initial_x (targetError: float) =
    let rec loop x_previous y_previous i =
        let x = y_previous - alpha * (dsharp.grad func y_previous)
        let y = x + betta * (x - x_previous)

        let actualError =
            (dsharp.grad func x).toArray1D () |> Vector.ofArray |> Vector.l2norm

        if targetError.CompareTo(actualError) > 0 then
            { ResultTensor = x
              StepsCount = i + 1
              Error = actualError }
        else
            loop x y (i + 1)

    loop initial_x initial_x 0
