跳转至

向量运算

概述

一维向量算术运算——加、减、乘、除、开方、点积——支持步进访问。TinyMath 的基础层。

头文件: #include "tiny_vec.h"


平台分发

ESP32:委托给 ESP-DSP 库(dsps_* 函数),适用于连续访问(stride = 1)。 通用:回退到纯 C 循环。


架构

函数分为三个层级:

层级 函数
逐元素算术 addsubmuldiv(支持标量和步进)
开方 sqrtsqrtfinv_sqrtinv_sqrtf
点积 dotproddotprode(扩展步进)

通用参数

以下参数出现在多个函数中:

参数 类型 说明
input1input2 const float * 输入向量
output float * 输出向量(可与输入别名)
len int 要处理的元素数
C float 标量常数
stride* int 元素间距。1 = 连续(快速路径),> 1 = 步进访问
allow_divide_by_zero bool false 时除零返回错误;true 时返回 inf
dest float * 输出标量(用于点积)

逐元素算术

tiny_error_t tiny_vec_add_f32(const float *a, const float *b, float *c, int len,
                               int s1, int s2, int s_out);
tiny_error_t tiny_vec_sub_f32(/* 相同签名 */);
tiny_error_t tiny_vec_mul_f32(/* 相同签名 */);

运算: \(c_i = a_i \pm b_i\)\(c_i = a_i \cdot b_i\)

参数 说明
a, b, c 输入/输出向量
len 元素数量
s1, s2, s_out 每个向量的步进(1 = 连续)
tiny_error_t tiny_vec_addc_f32(const float *in, float *out, int len, float C,
                                int s_in, int s_out);
tiny_error_t tiny_vec_subc_f32(/* 相同签名 */);
tiny_error_t tiny_vec_mulc_f32(/* 相同签名 */);

运算: \(out_i = in_i \pm C\)\(out_i = in_i \cdot C\)

tiny_error_t tiny_vec_div_f32(const float *a, const float *b, float *c, int len,
                               int s1, int s2, int s_out, bool allow_div0);
tiny_error_t tiny_vec_divc_f32(const float *in, float *out, int len, float C,
                                int s_in, int s_out, bool allow_div0);

运算: \(c_i = a_i / b_i\)\(out_i = in_i / C\)

参数 说明
allow_div0 false 时除零返回 TINY_ERR_MATH_ZERO_DIVISIONtrue 时静默返回 inf

开方

tiny_error_t tiny_vec_sqrt_f32(const float *in, float *out, int len);
tiny_error_t tiny_vec_inv_sqrt_f32(const float *in, float *out, int len);

运算: \(out_i = \sqrt{in_i}\)\(out_i = 1 / \sqrt{in_i}\)

tiny_error_t tiny_vec_sqrtf_f32(const float *in, float *out, int len);
tiny_error_t tiny_vec_inv_sqrtf_f32(const float *in, float *out, int len);

运算: 同上,但在某些平台上可能使用更快的近似算法。ESP32 上委托给 dsps_sqrtf32_f32

何时使用快速变体

当速度比精度更重要时使用 sqrtf / inv_sqrtf(例如迭代算法中的归一化)。通常快 2-3 倍,相对误差约 \(\sim 10^{-4}\)


点积

tiny_error_t tiny_vec_dotprod_f32(const float *a, const float *b, float *dest, int len);

运算: \(dest = \sum_{i=0}^{len-1} a_i \cdot b_i\)

假设连续访问(两个向量的 stride = 1)。

tiny_error_t tiny_vec_dotprode_f32(const float *a, const float *b, float *dest, int len, int s1, int s2);

运算: 同上,但支持每个向量独立控制步进。

float a[4] = {1, 2, 3, 4};
float b[4] = {5, 6, 7, 8};
float result;
tiny_vec_dotprod_f32(a, b, &result, 4);
// result = 1*5 + 2*6 + 3*7 + 4*8 = 70

返回值

所有函数返回 tiny_error_t

代码 含义
TINY_OK 成功
TINY_ERR_MATH_NULL_POINTER 传入了空指针
TINY_ERR_MATH_INVALID_LENGTH len ≤ 0
TINY_ERR_MATH_ZERO_DIVISION 除零(仅当 allow_div0 = false 时)
TINY_ERR_MATH_NEGATIVE_SQRT sqrtinv_sqrt 的输入为负数