209 lines
6.1 KiB
C
209 lines
6.1 KiB
C
#ifndef INCLUDED_C_COMPLEX_H
|
|
#define INCLUDED_C_COMPLEX_H
|
|
|
|
#ifndef INCLUDED_C_TYPES_H
|
|
#include <c_Types.h>
|
|
#endif /*INCLUDED_C_TYPES_H*/
|
|
|
|
#ifndef INCLUDED_MATH_H
|
|
#define INCLUDED_MATH_H
|
|
#include <math.h>
|
|
#endif /*INCLUDED_MATH_H*/
|
|
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
typedef struct {
|
|
double real;
|
|
double imag;
|
|
} c_Complex_t;
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Make(double real, double imag) {
|
|
c_Complex_t c;
|
|
c.real = real;
|
|
c.imag = imag;
|
|
return c;
|
|
}
|
|
|
|
/**
|
|
* @brief 从极坐标创建复数 (Polar to Rectangular)
|
|
* @param r 幅值 (Magnitude)
|
|
* @param theta 幅角 (Phase angle in radians)
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_FromPolar(double r, double theta) {
|
|
c_Complex_t c;
|
|
c.real = r * cos(theta);
|
|
c.imag = r * sin(theta);
|
|
return c;
|
|
}
|
|
|
|
/**
|
|
* @brief Adds two complex numbers: res = a + b
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Add(c_Complex_t a, c_Complex_t b) {
|
|
c_Complex_t res;
|
|
res.real = a.real + b.real;
|
|
res.imag = a.imag + b.imag;
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Subtracts two complex numbers: res = a - b
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Sub(c_Complex_t a, c_Complex_t b) {
|
|
c_Complex_t res;
|
|
res.real = a.real - b.real;
|
|
res.imag = a.imag - b.imag;
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief Multiplies two complex numbers: res = a * b
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Mul(c_Complex_t a, c_Complex_t b) {
|
|
c_Complex_t res;
|
|
res.real = a.real * b.real - a.imag * b.imag;
|
|
res.imag = a.real * b.imag + a.imag * b.real;
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief 复数除法: res = a / b
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Div(c_Complex_t a, c_Complex_t b) {
|
|
double denom = b.real * b.real + b.imag * b.imag;
|
|
if (denom == 0.0) {
|
|
return c_Complex_Make(0.0, 0.0); /* 健壮性防线:防止除以 0 导致崩溃 */
|
|
}
|
|
return c_Complex_Make(
|
|
(a.real * b.real + a.imag * b.imag) / denom,
|
|
(a.imag * b.real - a.real * b.imag) / denom
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @brief Computes the complex conjugate: res = real - i*imag
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Conjugate(c_Complex_t c) {
|
|
c_Complex_t res;
|
|
res.real = c.real;
|
|
res.imag = -c.imag;
|
|
return res;
|
|
}
|
|
|
|
/**
|
|
* @brief 计算复数的相反数 (Negate): res = -real - i*imag
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Negate(c_Complex_t c) {
|
|
return c_Complex_Make(-c.real, -c.imag);
|
|
}
|
|
|
|
/**
|
|
* @brief 计算复数的模长的平方 (Magnitude Squared / Norm)
|
|
* @note 避免了开方操作,适合用于比对大小以提升性能
|
|
*/
|
|
C_STATIC_FORCE_INLINE double c_Complex_Norm(c_Complex_t c) {
|
|
return c.real * c.real + c.imag * c.imag;
|
|
}
|
|
|
|
/**
|
|
* @brief 计算复数的模长 (Magnitude / Absolute Value)
|
|
*/
|
|
C_STATIC_FORCE_INLINE double c_Complex_Abs(c_Complex_t c) {
|
|
return sqrt(c.real * c.real + c.imag * c.imag);
|
|
}
|
|
|
|
/**
|
|
* @brief 计算复数的幅角 (Phase Angle / Argument)
|
|
* @return 返回介于 -PI 到 PI 之间的弧度值
|
|
*/
|
|
C_STATIC_FORCE_INLINE double c_Complex_Arg(c_Complex_t c) {
|
|
return atan2(c.imag, c.real);
|
|
}
|
|
|
|
/* ================================================================================================================== */
|
|
/* 标量混合运算接口 (Scalar & Complex Operations) */
|
|
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_AddScalar(c_Complex_t c, double s) {
|
|
return c_Complex_Make(c.real + s, c.imag);
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_SubScalar(c_Complex_t c, double s) {
|
|
return c_Complex_Make(c.real - s, c.imag);
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_MulScalar(c_Complex_t c, double s) {
|
|
return c_Complex_Make(c.real * s, c.imag * s);
|
|
}
|
|
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_DivScalar(c_Complex_t c, double s) {
|
|
if (s == 0.0) return c_Complex_Make(0.0, 0.0);
|
|
return c_Complex_Make(c.real / s, c.imag / s);
|
|
}
|
|
|
|
/* ================================================================================================================== */
|
|
/* 超越函数与幂运算接口 (Transcendental & Power Functions) */
|
|
|
|
/**
|
|
* @brief 复数的指数函数: e^c
|
|
* @note e^(x+iy) = e^x * (cos(y) + i*sin(y))
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Exp(c_Complex_t c) {
|
|
double exp_x = exp(c.real);
|
|
return c_Complex_Make(exp_x * cos(c.imag), exp_x * sin(c.imag));
|
|
}
|
|
|
|
/**
|
|
* @brief 复数的自然对数函数: ln(c)
|
|
* @note ln(c) = ln(|c|) + i*arg(c)
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Log(c_Complex_t c) {
|
|
return c_Complex_Make(log(c_Complex_Abs(c)), c_Complex_Arg(c));
|
|
}
|
|
|
|
/**
|
|
* @brief 复数的幂运算: base^exp
|
|
* @note a^b = exp(b * log(a))
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Pow(c_Complex_t base, c_Complex_t exponent) {
|
|
if (base.real == 0.0 && base.imag == 0.0) return c_Complex_Make(0.0, 0.0);
|
|
return c_Complex_Exp(c_Complex_Mul(exponent, c_Complex_Log(base)));
|
|
}
|
|
|
|
/**
|
|
* @brief 复数的实数幂运算: base^p (p 为实数标量)
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_PowScalar(c_Complex_t base, double p) {
|
|
if (base.real == 0.0 && base.imag == 0.0) return c_Complex_Make(0.0, 0.0);
|
|
double r = pow(c_Complex_Abs(base), p);
|
|
double theta = c_Complex_Arg(base) * p;
|
|
return c_Complex_FromPolar(r, theta);
|
|
}
|
|
|
|
/**
|
|
* @brief 复数开平方根: sqrt(c)
|
|
*/
|
|
C_STATIC_FORCE_INLINE c_Complex_t c_Complex_Sqrt(c_Complex_t c) {
|
|
double r = c_Complex_Abs(c);
|
|
double real_part = sqrt((r + c.real) / 2.0);
|
|
double imag_part = sqrt((r - c.real) / 2.0);
|
|
if (c.imag < 0.0) imag_part = -imag_part;
|
|
return c_Complex_Make(real_part, imag_part);
|
|
}
|
|
|
|
/* ================================================================================================================== */
|
|
/* 比较运算 (Comparison Interfaces) */
|
|
|
|
/**
|
|
* @brief 判断两个复数是否在允许的误差内相等
|
|
*/
|
|
C_STATIC_FORCE_INLINE bool c_Complex_Equals(c_Complex_t a, c_Complex_t b, double epsilon) {
|
|
return (fabs(a.real - b.real) <= epsilon) && (fabs(a.imag - b.imag) <= epsilon);
|
|
}
|
|
|
|
#endif /*INCLUDED_C_COMPLEX_H*/
|