// SPDX-FileCopyrightText: © 2026 Vladimir Zorin // SPDX-License-Identifier: LicenseRef-OWL-1.0-or-later // Licensed under OWL v1.0+. See LICENSE. #include "mneme.h" #include /* Simple loops — the compiler auto-vectorizes these to SSE/AVX on x86_64. No hand-written SIMD needed for the expected scale (<100K vectors). */ float mneme_vec_dot(const float *a, const float *b, int dim) { float sum = 0.0f; for (int i = 0; i < dim; i++) sum += a[i] * b[i]; return sum; } float mneme_vec_cosine(const float *a, const float *b, int dim) { float dot = 0.0f, na = 0.0f, nb = 0.0f; for (int i = 0; i < dim; i++) { dot += a[i] * b[i]; na += a[i] * a[i]; nb += b[i] * b[i]; } float denom = sqrtf(na) * sqrtf(nb); if (denom < 1e-30f) return 1.0f; /* degenerate: treat as orthogonal */ return 1.0f - dot / denom; } float mneme_vec_l2(const float *a, const float *b, int dim) { float sum = 0.0f; for (int i = 0; i < dim; i++) { float d = a[i] - b[i]; sum += d * d; } return sqrtf(sum); } void mneme_vec_normalize(float *v, int dim) { float sum = 0.0f; for (int i = 0; i < dim; i++) sum += v[i] * v[i]; float inv = 1.0f / sqrtf(sum); if (!isfinite(inv)) return; for (int i = 0; i < dim; i++) v[i] *= inv; }