// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: MIT package grad import ( "math" "sourcedock.dev/petrbalvin/tensor/internal/core" ) // numericGrad estimates the gradient of a scalar function at a by // central differences, the reference the analytic backward is checked // against. func numericGrad(f func(a *core.Array) float64, a *core.Array) []float64 { n := a.Len() out := make([]float64, n) for i := range n { hi := 1e-6 up := cloneFlat(a) down := cloneFlat(a) up[i] += hi down[i] -= hi au, _ := core.FromFloats(up, a.Shape()...) ad, _ := core.FromFloats(down, a.Shape()...) out[i] = (f(au) - f(ad)) / (2 * hi) } return out } func cloneFlat(a *core.Array) []float64 { out := make([]float64, a.Len()) for i := range a.Len() { out[i] = a.FloatAt(i) } return out } func maxAbsDiff(a, b []float64) float64 { m := 0.0 for i := range a { if d := math.Abs(a[i] - b[i]); d > m { m = d } } return m }