VecLab

Swift 中的实数/复数向量库。

兼容 Swift 6.0。

概述

VecLab 是一个 Swift 包,用于执行实数和复数向量运算,并提供 NumPy 和 MATLAB 风格的函数。

完整文档可以在 Swift Package Index 上找到。

示例用法

该库包含一个使用 Accelerate 的 FFT 函数,但这里有一个使用递归算法创建复数 FFT 的示例,以及其 NumPy 和 MATLAB 等效实现。

Swift

// 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
    }
}

这里分解了函数中的实数和复数向量运算

  1. x 是复数输入数组。
  2. omega 是复数指数。 Real.i 是虚数单位 i
  3. 测试输入 x 的长度是否可被 2 整除。
  4. k 是从 0, 1, 2,... n/2-1 的实数向量。
  5. womega 的向量 k 次幂的复数向量。
  6. u 是对偶数 x 进行递归调用的复数结果。
  7. v 是对奇数 x 进行递归调用的复数结果。
  8. 结果是 uv 的复数向量加法和减法的连接。
  9. 当输入数组中只有一个元素时,递归结束。 单个元素的 FFT 是其自身。

NumPy

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

MATLAB

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 的 RangeClosedRange 类型定义,但可以添加可选的 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