// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: MIT package linalg import ( "math" "math/cmplx" "sourcedock.dev/petrbalvin/tensor/internal/base" "sourcedock.dev/petrbalvin/tensor/internal/core" ) // scalar is the element type the generic kernels serve. type scalar interface { float64 | complex128 } // absComplex returns |z|, the shared magnitude used for tolerances. func absComplex(z complex128) float64 { return base.AbsComplex(z) } func absOf[T scalar](v T) float64 { switch x := any(v).(type) { case float64: return math.Abs(x) case complex128: return cmplx.Abs(x) } return 0 } // zeros allocates a zeroed array for internally derived shapes. The // error is part of the signature on purpose: a caller whose shape is // not provably valid must propagate the failure, not nil-deref. func zeros(dt core.Dtype, shape []int) (*core.Array, error) { return core.Zeros(dt, shape...) } // finiteF64 reports whether v is neither NaN nor infinite. func finiteF64(v float64) bool { return !math.IsNaN(v) && !math.IsInf(v, 0) } // vecFinite reports whether every entry of v is finite. func vecFinite(v []float64) bool { for _, x := range v { if !finiteF64(x) { return false } } return true } // isRealDtype reports whether a holds real (non-complex) numeric data. func isRealDtype(a *core.Array) bool { switch a.Dtype() { case core.Float, core.Float32, core.Int: return true } return false }