跳转至

Cfloat — 复数运算

概述

轻量级 tiny_cfloat_t 复数类型及算术运算,专为 MCU 环境设计。TinyMath 依赖链中的 第 2 层

头文件: #include "tiny_cfloat.h"


为什么自定义复数类型?

ESP32-S3 没有硬件复数支持。标准 <complex.h> 类型较重(8–16 字节)且引入缓慢的数学库依赖。tiny_cfloat_t 是一个朴素的 struct:

typedef struct { float re; float im; } tiny_cfloat_t;  // 正好 8 字节

内联构造函数 tiny_cf(re, im) 零分配开销:

static inline tiny_cfloat_t tiny_cf(float re, float im)
{ tiny_cfloat_t z = {re, im}; return z; }

API 参考

函数 运算 复杂度
tiny_cf_add(a, b) \((a_r + b_r,\; a_i + b_i)\) \(O(1)\)
tiny_cf_sub(a, b) \((a_r - b_r,\; a_i - b_i)\) \(O(1)\)
tiny_cf_mul(a, b) \((a_r b_r - a_i b_i,\; a_r b_i + a_i b_r)\) \(O(1)\),4 乘 + 2 加
tiny_cf_div(a, b) \(\dfrac{a \cdot \overline{b}}{\|b\|^2}\) \(O(1)\),Smith 鲁棒算法
tiny_cf_conj(a) \((a_r,\; -a_i)\) \(O(1)\)
tiny_cfloat_t z1 = tiny_cf(3.0f, 4.0f);
tiny_cfloat_t z2 = tiny_cf(1.0f, 2.0f);

tiny_cfloat_t sum = tiny_cf_add(z1, z2);  // (4, 6)
tiny_cfloat_t prod = tiny_cf_mul(z1, z2); // (−5, 10)
函数 运算 说明
tiny_cf_from_polar(r, θ) \((r \cos\theta,\; r \sin\theta)\) 极坐标 → 笛卡尔坐标
tiny_cf_abs(z) \(\sqrt{z_r^2 + z_i^2}\) \((0,0)\) 返回 0
tiny_cf_arg(z) \(\operatorname{atan2}(z_i, z_r)\) \((0,0)\) 返回 0
tiny_cf_sqrt(z) \(\sqrt{z}\)(主分支) 使用 \(z_r \pm i\sqrt{\frac{\|z\| - z_r}{2}}\)
tiny_cf_log(z) \(\ln\|z\| + i \arg(z)\) 近零输入饱和到 \(-\infty\)
tiny_cfloat_t z = tiny_cf(0.0f, 1.0f);          // i
float mag = tiny_cf_abs(z);                      // 1.0
float arg = tiny_cf_arg(z);                      // π/2
tiny_cfloat_t sqrt_i = tiny_cf_sqrt(z);          // (0.707, 0.707)

除法:Smith 算法

tiny_cf_div 使用 Smith 鲁棒算法 避免溢出:

if (|b.re|  |b.im|) {
    k = b.im / b.re
    result = (a.re + k·a.im) / (b.re + k·b.im)  +  i·(a.im  k·a.re) / (b.re + k·b.im)
} else {
    k = b.re / b.im
    result = (a.re·k + a.im) / (b.im + k·b.re)  +  i·(a.im·k  a.re) / (b.im + k·b.re)
}

避免了计算中间值 \(|b|^2\),后者在大模数分母时可能溢出。

近零除法

|b| 小于 TINY_MATH_MIN_POSITIVE_INPUT_F32\(10^{-12}\)),函数返回 \(\pm\) TINY_MATH_LARGE_VALUE_F32 作为哨兵值。


返回值

所有函数按值返回(而非指针),使复合运算自然直观:

tiny_cfloat_t z = tiny_cf_sqrt(tiny_cf_add(a, b));