Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/marcuspainter/veclab
Swift Real/Complex Vector DSP Library
https://github.com/marcuspainter/veclab
complex-numbers digital-signal-processing dsp fft matlab numpy swift
Last synced: 2 months ago
JSON representation
Swift Real/Complex Vector DSP Library
- Host: GitHub
- URL: https://github.com/marcuspainter/veclab
- Owner: marcuspainter
- License: mit
- Created: 2023-12-06T02:46:44.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-17T15:09:47.000Z (2 months ago)
- Last Synced: 2024-10-19T21:58:17.544Z (2 months ago)
- Topics: complex-numbers, digital-signal-processing, dsp, fft, matlab, numpy, swift
- Language: Swift
- Homepage: https://swiftpackageindex.com/marcuspainter/VecLab/documentation
- Size: 355 KB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# VecLab
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fmarcuspainter%2FVecLab%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/marcuspainter/VecLab)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fmarcuspainter%2FVecLab%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/marcuspainter/VecLab)A real/complex vector library in Swift.
Compatible with Swift 6.0.
## Overview
VecLab is a Swift Package for real and complex vector operations with NumPy and MATLAB-style functions.
- Overloaded arithmetic operators.
- Mixed real and complex, scalars and vectors.
- Basic MATLAB-style functions.
- Vectorized using Accelerate and vDSP.
- FFT of 2, 3 and 5 factors.Full documentation can be found on the [Swift Package Index](https://swiftpackageindex.com/marcuspainter/VecLab/documentation/veclab).
### Example Usage
The library includes an FFT function using Accelerate, but here is an example of creating a complex FFT using a recursive algorithm and its NumPy and MATLAB equivalents:
### Swift
```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
}
}
```
Here's a breakdown of the real and complex vector operations in the function:1. `x` is the complex input array.
2. `omega` is a complex exponential number. `Real.i` is the imaginary unit *i*.
3. Tests if the input `x` length is divisible by 2.
4. `k` is a real vector from 0, 1, 2,... n/2-1.
5. `w` is the complex vector of `omega` to the power of vector `k`.
6. `u` is the complex result of a recursive call with even `x`.
7. `v` is the complex result of a recursive call with odd `x`.
8. The result is the concatenation of the complex vector addition and subtraction of `u` and `v`.
9. The recursion ends when there is one element in the input array. The FFT of a single element is itself.### NumPy
```python
import numpy as npdef 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```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
```### Library Convention
The library works with existing Swift types, using only arrays and tuples. For convenience, these have been given type aliases for the underlying native types. Only the `Real` need be defined, the others are all derived from this type.
```swift
public typealias Real = Double
public typealias RealArray = [Real]
public typealias Complex = (Real, Real)
public typealias ComplexArray = ([Real], [Real])
```### Real Numbers
Real numbers are `Double` types.
### Real Arrays
Real arrays are just a normal Swift `Array` of `Double`.
### Complex Numbers
Complex numbers are defined as a tuple of two real numbers, representing the real and imaginary parts of the number.
```swift
let c = (10.0, 2.0)
```
### Complex ArraysA complex array consists of a tuple of two real arrays. This arrangement is sometimes known as split complex.
```swift
let realArray = [1.0, 2.0, 3.0, 4.0]
let imagArray = [1.0, 2.0, 3.0, 4.0]
let complexArray = (realArray, imagArray)
```### The Imaginary Unit
The imaginary unit, `i`, is defined as an extension to `Real`, similar to other constants such as pi. Alternatives are
as a extension of Double, Float and Int or a tuple of real and imaginary parts.These are all equivalent to 10+10i:
```swift
let c1 = 10 + 10 * Real.i
let c2 = 10 + 10.i
let c3 = (10, 10)
```
It can be used in any expression. This is a complex exponential:```swift
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))
```### Ranges
Ranges can be defined using the Swift `Range` or `ClosedRange` types but with the addition of an optional `by` value.
This has been implemented as an extension to the `Array` type.Swift style:
```swift
let t = [Double](0...<100)
let s = [Double](1...100, 2)
```VecLab style using the `vector` function:
```swift
let t = vector(0..<100)
let s = vector(1...100, 2)
```### Operators
Overloaded operators for scalar and vectors.
|Operator|Description|
|---|---|
|+| Add|
|-| Subtract|
|\*| Multiply|
|/| Divide|
|\*\*| Power|
|\*~|Right conjugate multiply: a \* conj(b)|
|~\*|Left conjugate multiply: conj(a) \* b|
| - |Unary minus|### Functions
|Group|Functions|
|---|---|
|Arrays|arange, cat, circshift, dot, flip, length, ones, paddata, repelem, resize, slice, trimdata, zeros|
|Basic| abs, all, any, cumsum, disp, iterate, norm, prod, sign, sum|
|Complex| abs, angle, conj, cplxpair, imag, real, unwrap, wrapTo2Pi, wrapToPi|
|Conversion| cart2pol, cart2sph, d2f, db2mag, db2pow, deg2rad, f2d, mag2db, pol2cart, pow2db, rad2deg, sph2cart|
|Discrete| factor, factorial, gcd, isprime, lcm, nextprime, nchoosek, perms, prevprime, primes|
|Exponents| exp, log, log2, log10, nextpow2, sqrt|
|FFT| dft, dftr, fft, fftr, fftshift, fftsymmetric, idft, idftr, ifft, ifftr, ifftshift|
|Filter| biquad, freqz, filter|
|Integration| diff, gradient, trapz|
|Interpolation| interp1, interpft, sincresample|
|Modulo| ceil, fix, floor, mod, rem, round, trunc|
|Optimization| fminbnd, fminsearch|
|Power| pow|
|Random| agwn, rand, randn, rng|
|Smoothing| hampel, medfilt1|
|Space| freqspace, linspace, logspace|
|Special| besseli0, sinc|
|Statistics| histcounts, max, maxindex, mean, median, min, minindex, mode, rms, stddev, variance|
|Timing| tic, toc, timeit|
|Trigonometry| acos, asin, atan, atan2, cos, sin, tan|
|Window| blackman, blackmanharris, flattopwin, gausswin, hamming, hann, kaiser, tukeywin, rectwin|