module MultidimensionalOptimizationMethods.GradientDescentMethod

open DiffSharp
open FsAlg.Generic

open Types

let run (alpha: float) func initial_x (targetError: float) =
    let rec loop previous_x i =
        let gradient = dsharp.grad func previous_x
        let actualError = (gradient.toArray1D ()) |> Vector.ofArray |> Vector.l2norm

        if targetError.CompareTo(actualError) > 0 then
            { ResultTensor = previous_x
              StepsCount = i
              Error = actualError }
        else
            let x = previous_x - alpha * (dsharp.grad func previous_x)
            loop x (i + 1)

    loop initial_x 0
