Swift 中的实数/复数向量库。
兼容 Swift 6.0。
VecLab 是一个 Swift 包,用于执行实数和复数向量运算,并提供 NumPy 和 MATLAB 风格的函数。
完整文档可以在 Swift Package Index 上找到。
该库包含一个使用 Accelerate 的 FFT 函数,但这里有一个使用递归算法创建复数 FFT 的示例,以及其 NumPy 和 MATLAB 等效实现。
// FFTX Fast Finite Fourier Transform.
public func fftx(_ x: ComplexArray) -> ComplexArray {
let n = length(x)
let omega = exp(-2 * Real.pi * 1.i / Real(n))
if rem(n, 2) == 0 {
// Recursive divide and conquer.
let k = vector(0 ... (n / 2 - 1))
let w = omega ** k
let u = fftx(slice(x, 0 ..< n - 1, 2))
let v = w * fftx(slice(x, 1 ..< n, 2))
return cat(u + v, u - v)
} else {
return x
}
}
这里分解了函数中的实数和复数向量运算
x
是复数输入数组。omega
是复数指数。 Real.i
是虚数单位 i。x
的长度是否可被 2 整除。k
是从 0, 1, 2,... n/2-1 的实数向量。w
是 omega
的向量 k
次幂的复数向量。u
是对偶数 x
进行递归调用的复数结果。v
是对奇数 x
进行递归调用的复数结果。u
和 v
的复数向量加法和减法的连接。import numpy as np
def fftx(x):
"""
FFTX Fast Finite Fourier Transform.
"""
n = len(x)
omega = np.exp(-2j * np.pi / n)
if n % 2 == 0:
# Recursive divide and conquer
k = np.arange(n//2)
w = omega ** k
u = fftx(x[::2])
v = w * fftx(x[1::2])
y = np.concatenate([u + v, u - v])
else:
y = x
return y
function y = fftx(x)
% FFTX Fast Finite Fourier Transform.
n = length(x);
omega = exp(-2*pi*i/n);
if rem(n,2) == 0
% Recursive divide and conquer.
k = (0:n/2-1)';
w = omega.^k;
u = fftx(x(1:2:n-1));
v = w.*fftx(x(2:2:n));
y = [u+v; u-v];
else
y = x
end
该库使用现有的 Swift 类型,仅使用数组和元组。 为了方便起见,这些类型被赋予了底层原生类型的类型别名。 只需要定义 Real
类型,其他类型都由此类型派生而来。
public typealias Real = Double
public typealias RealArray = [Real]
public typealias Complex = (Real, Real)
public typealias ComplexArray = ([Real], [Real])
实数是 Double
类型。
实数数组只是普通的 Swift Double
数组。
复数定义为两个实数的元组,表示复数的实部和虚部。
let c = (10.0, 2.0)
复数数组由两个实数数组的元组组成。 这种排列有时被称为分裂复数。
let realArray = [1.0, 2.0, 3.0, 4.0]
let imagArray = [1.0, 2.0, 3.0, 4.0]
let complexArray = (realArray, imagArray)
虚数单位 i
被定义为 Real
的扩展,类似于其他常量,如 pi。 其他选择是作为 Double、Float 和 Int 的扩展,或作为实部和虚部的元组。
这些都等价于 10+10i
let c1 = 10 + 10 * Real.i
let c2 = 10 + 10.i
let c3 = (10, 10)
它可以在任何表达式中使用。 这是一个复数指数
let phi = 100.0
let c1 = exp(Real.i * 2 * Real.pi * phi)
let c2 = exp(1.i * 2 * Real.pi * phi)
let c3 = exp(2.i * Real.pi * phi)
let c4 = exp((0, 2) * Real.pi * phi)
let c5 = exp((0, 2 * Real.pi) * phi)
let c6 = exp((0, 2 * Real.pi * phi))
范围可以使用 Swift 的 Range
或 ClosedRange
类型定义,但可以添加可选的 by
值。 这已作为 Array
类型的扩展实现。
Swift 风格
let t = [Double](0...<100)
let s = [Double](1...100, 2)
VecLab 风格,使用 vector
函数
let t = vector(0..<100)
let s = vector(1...100, 2)
用于标量和向量的重载运算符。
运算符 | 描述 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
** | 幂 |
*~ | 右共轭乘法:a * conj(b) |
~* | 左共轭乘法:conj(a) * b |
- | 一元负号 |
分组 | 函数 |
---|---|
数组 | arange, cat, circshift, dot, flip, length, ones, paddata, repelem, resize, slice, trimdata, zeros |
基本 | abs, all, any, cumsum, disp, iterate, norm, prod, sign, sum |
复数 | abs, angle, conj, cplxpair, imag, real, unwrap, wrapTo2Pi, wrapToPi |
转换 | cart2pol, cart2sph, d2f, db2mag, db2pow, deg2rad, f2d, mag2db, pol2cart, pow2db, rad2deg, sph2cart |
离散 | factor, factorial, gcd, isprime, lcm, nextprime, nchoosek, perms, prevprime, primes |
指数 | exp, log, log2, log10, nextpow2, sqrt |
FFT | dft, dftr, fft, fftr, fftshift, fftsymmetric, idft, idftr, ifft, ifftr, ifftshift |
滤波器 | biquad, freqz, filter |
积分 | diff, gradient, trapz |
插值 | interp1, interpft, sincresample |
模运算 | ceil, fix, floor, mod, rem, round, trunc |
优化 | fminbnd, fminsearch |
幂 | pow |
随机数 | awgn, rand, randn, rng |
平滑 | hampel, medfilt1 |
空间 | freqspace, linspace, logspace |
特殊 | besseli0, sinc |
统计 | histcounts, max, maxindex, mean, median, min, minindex, mode, rms, stddev, variance |
计时 | tic, toc, timeit |
三角函数 | acos, asin, atan, atan2, cos, sin, tan |
窗函数 | blackman, blackmanharris, flattopwin, gausswin, hamming, hann, kaiser, tukeywin, rectwin |