{"id":15716460,"url":"https://github.com/marcuspainter/veclab","last_synced_at":"2025-05-13T00:42:36.651Z","repository":{"id":211222907,"uuid":"728003097","full_name":"marcuspainter/VecLab","owner":"marcuspainter","description":"Swift Real/Complex Vector DSP Library ","archived":false,"fork":false,"pushed_at":"2024-10-17T15:09:47.000Z","size":364,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-19T21:58:17.544Z","etag":null,"topics":["complex-numbers","digital-signal-processing","dsp","fft","matlab","numpy","swift"],"latest_commit_sha":null,"homepage":"https://swiftpackageindex.com/marcuspainter/VecLab/documentation","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcuspainter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-06T02:46:44.000Z","updated_at":"2024-10-17T15:07:36.000Z","dependencies_parsed_at":null,"dependency_job_id":"433c5397-42a3-42eb-a5aa-5316c42b7e50","html_url":"https://github.com/marcuspainter/VecLab","commit_stats":null,"previous_names":["marcuspainter/veclab"],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuspainter%2FVecLab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuspainter%2FVecLab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuspainter%2FVecLab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuspainter%2FVecLab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcuspainter","download_url":"https://codeload.github.com/marcuspainter/VecLab/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221308274,"owners_count":16795579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["complex-numbers","digital-signal-processing","dsp","fft","matlab","numpy","swift"],"created_at":"2024-10-03T21:45:41.417Z","updated_at":"2025-05-13T00:42:36.643Z","avatar_url":"https://github.com/marcuspainter.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# VecLab\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fmarcuspainter%2FVecLab%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/marcuspainter/VecLab)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fmarcuspainter%2FVecLab%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/marcuspainter/VecLab)\n\nA real/complex vector library in Swift.\n\n## New Version 2.0\n\n- New `ComplexDouble` and `ComplexDoubleArray` structs.\n- Array range indexing and slicing.\n- `ComplexDoubleArray` conforms to collection protocol.\n\n## Overview\n\nVecLab is a Swift Package for real and complex vector operations with NumPy and MATLAB-style functions.\n\n- Overloaded arithmetic operators.\n- Mixed real and complex, scalars and vectors.\n- Basic MATLAB-style functions.\n- Vectorized using Accelerate and vDSP.\n- FFT of 2, 3 and 5 factors.\n\nFull documentation can be found on the [Swift Package Index](https://swiftpackageindex.com/marcuspainter/VecLab/documentation/veclab).\n\n### Example Usage\n\nThe library includes an FFT function using Accelerate, but here is an example of creating a complex FFT using a \nrecursive algorithm and its NumPy and MATLAB equivalents:\n\n### Swift\n\n```swift\n// FFTX Fast Finite Fourier Transform.\npublic func fftx(_ x: ComplexArray) -\u003e ComplexArray {\n    let n = length(x)\n    let omega = exp(-2.i * .pi / Double(n))\n    if rem(n, 2) == 0 {\n        // Recursive divide and conquer.\n        let k = vector(0 ... (n / 2 - 1))\n        let w = omega ** k\n        let u = fftx(x[0 ..\u003c n - 1, 2])\n        let v = w * fftx(x[1 ..\u003c n, 2])\n        return cat(u + v, u - v)\n    } else {\n        return x\n    }\n}\n```\nHere's a breakdown of the real and complex vector operations in the function:\n\n1. `x` is the complex input array.\n2. `omega` is a complex exponential number. `Real.i` is the imaginary unit *i*.\n3. Tests if the input `x` length is divisible by 2.\n4. `k` is a real vector from 0, 1, 2,... n/2-1.\n5. `w` is the complex vector of `omega` to the power of vector `k`.\n6. `u` is the complex result of a recursive call with even `x`.\n7. `v` is the complex result of a recursive call with odd `x`.\n8. The result is the concatenation of the complex vector addition and subtraction of `u` and `v`.\n9. The recursion ends when there is one element in the input array. The FFT of a single element is itself.\n\n### NumPy\n```python\nimport numpy as np\n\ndef fftx(x):\n    \"\"\"\n    FFTX Fast Finite Fourier Transform.\n    \"\"\"\n    n = len(x)\n    omega = np.exp(-2j * np.pi / n)\n    \n    if n % 2 == 0:\n        # Recursive divide and conquer\n        k = np.arange(n//2)\n        w = omega ** k\n        u = fftx(x[::2])\n        v = w * fftx(x[1::2])\n        y = np.concatenate([u + v, u - v])\n    else:\n        y = x\n    \n    return y\n```\n### MATLAB\n\n```matlab\nfunction y = fftx(x)\n% FFTX Fast Finite Fourier Transform.\nn = length(x);\nomega = exp(-2*pi*i/n);\nif rem(n,2) == 0\n    % Recursive divide and conquer.\n    k = (0:n/2-1)';\n    w = omega.^k;\n    u = fftx(x(1:2:n-1));\n    v = w.*fftx(x(2:2:n));\n    y = [u+v; u-v];\nelse\n    y = x\nend\n```\n\n### Library Convention\n\n```swift\npublic typealias Real = Double\npublic typealias RealArray = [Real]\npublic typealias Complex = ComplexDouble\npublic typealias ComplexArray = ComplexDoubleArray\n```\n\n### Real Numbers\n\nReal numbers are `Double` types.\n\n### Real Arrays\n\nReal arrays are just a normal Swift `Array` of `Double`.\n\n### Complex Numbers\n\nComplex numbers are defined as a struct `ComplexDouble` of two real numbers, representing the real and imaginary parts\n of the number. \n\n```swift\npublic struct ComplexDouble { \n    /// Real part.\n    public var real: Double\n    /// Imaginary part.\n    public var imag: Double\n}\n```\n### Complex Arrays\n\nA complex array now has its own struct type, `ComplexDouble`. It follows the Collection protocol and is not a true\nSwift array of `[ComplexDouble]`. Internally, the real and imaginary arrays are maintained for compatibility \nuse with vDSP vector functions which use the `DSPDoubleSplitComplex` type.\n \nThe collection can be indexed that returns a `ComplexDouble`. \n\n```swift\nlet realArray = [1.0, 2.0, 3.0, 4.0]\nlet imagArray = [1.0, 2.0, 3.0, 4.0]\nlet complexArray = ComplexArray(realArray, imagArray)\n```\n\n### The Imaginary Unit\n\nThe imaginary unit, `i`, is defined as an extension to `Real`, similar to other Swift constants such as pi. \nAlternatives are as a extension of Double, Float.\n\nThese are all equivalent to 2+3i:\n\n```swift\nlet c1 = 2.0 + 3.0 * Real.i\nlet c2 = 2.0 + 3.i\nlet c3 = Complex(2.0, 3.0)\n```\nIt can be used in any expression. This is a complex exponential:\n\n```swift\nlet phi = 100.0\nlet c1 = exp(Real.i * 2 * Real.pi * phi)\nlet c2 = exp(1.i * 2 * Real.pi * phi)\nlet c3 = exp(2.i * Real.pi * phi)\n```\n\n### Ranges\n\nRanges can be defined using the Swift `Range` or `ClosedRange` types but with the addition of an optional `by` value.\nThis has been implemented as an extension to the `Array` type.\n\nSwift style:\n\n```swift\nlet t = [Double](0...\u003c100)\nlet s = [Double](1...100, 2)\n```\n### Operators\n\nOverloaded operators for scalar and vectors.\n\n|Operator|Description|\n|---|---|\n|+| Add|\n|-| Subtract|\n|\\*| Multiply|\n|/| Divide|\n|\\*\\*| Power|\n|\\*~|Right conjugate multiply: a \\* conj(b)|\n|~\\*|Left conjugate multiply: conj(a) \\* b|\n| - |Unary minus|\n\n### Functions\n\n|Group|Functions|\n|---|---|\n|Arrays| arange, cat, circshift, dot, flip, length, ones, paddata, repelem, resize, slice, trimdata, zeros|\n|Basic| abs, cumsum, disp, iterate, norm, prod, sign, sum|\n|Complex| abs, angle, conj, cplxpair, imag, real, unwrap, wrapTo2Pi, wrapToPi|\n|Conversion| cart2pol, cart2sph, d2f, db2mag, db2pow, deg2rad, f2d, mag2db, pol2cart, pow2db, rad2deg, sph2cart|\n|Discrete| factor, factorial, gcd, isprime, lcm, nextprime, nchoosek, perms, prevprime, primes|\n|Exponents| exp, expi, log, log2, log10, nextpow2, sqrt|\n|FFT| dft, dftr, fft, fftr, fftshift, fftsymmetric, idft, idftr, ifft, ifftr, ifftshift|\n|Filter| biquad, freqz, filter|\n|Integration| diff, gradient, trapz|\n|Interpolation| interp1, interpft, sincresample|\n|Modulo| ceil, fix, floor, mod, rem, round, trunc|\n|Optimization| fminbnd, fminsearch|\n|Power| pow|\n|Random| awgn, rand, randn, rng|\n|Smoothing| hampel, medfilt1|\n|Space| freqspace, linspace, logspace|\n|Special| besseli0, sinc|\n|Statistics| histcounts, max, maxindex, mean, median, min, minindex, mode, rms, stddev, variance|\n|Timing| tic, toc, timeit|\n|Trigonometry| acos, asin, atan, atan2, cos, sin, tan|\n|Window| blackman, blackmanharris, flattopwin, gausswin, hamming, hann, kaiser, tukeywin, rectwin|\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcuspainter%2Fveclab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcuspainter%2Fveclab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcuspainter%2Fveclab/lists"}