Home

Awesome

Surge

Build Status GitHub license Carthage compatible SPM compatible CocoaPods

Surge is a Swift library that uses the Accelerate framework to provide high-performance functions for matrix math, digital signal processing, and image manipulation.

Accelerate exposes SIMD instructions available in modern CPUs to significantly improve performance of certain calculations. Because of its relative obscurity and inconvenient APIs, Accelerate is not commonly used by developers, which is a shame, since many applications could benefit from these performance optimizations.

Surge aims to bring Accelerate to the mainstream, making it as easy (and nearly as fast, in most cases) to perform computation over a set of numbers as for a single member.

Though, keep in mind: Accelerate is not a silver bullet. Under certain conditions, such as performing simple calculations over a small data set, Accelerate can be out-performed by conventional algorithms. Always benchmark to determine the performance characteristics of each potential approach.


Curious about the name Surge? Back in the mid 90's, Apple, IBM, and Motorola teamed up to create AltiVec (a.k.a the Velocity Engine), which provided a SIMD instruction set for the PowerPC architecture. When Apple made the switch to Intel CPUs, AltiVec was ported to the x86 architecture and rechristened Accelerate. The derivative of Accelerate (and second derivative of Velocity) is known as either jerk, jolt, surge, or lurch, hence the name of this library.


Installation

The infrastructure and best practices for distributing Swift libraries are currently in flux during this beta period of Swift & Xcode. In the meantime, you can add Surge as a git submodule, drag the Surge.xcodeproj file into your Xcode project, and add Surge.framework as a dependency for your target.

Surge uses Swift 5. This means that your code has to be written in Swift 5 due to current binary compatibility limitations.

License

Surge is available under the MIT license. See the LICENSE file for more info.

Swift Package Manager

To use Swift Package Manager add Surge to your Package.swift file:

let package = Package(
    name: "myproject",
    dependencies: [
        .package(url: "https://github.com/mattt/Surge.git", .upToNextMajor(from: "2.0.0")),
    ],
    targets: [
        .target(
            name: "myproject",
            dependencies: ["Surge"]),
    ]
)

Then run swift build.

CocoaPods

To use CocoaPods add Surge to your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Surge', '~> 2.0.0'
end

Then run pod install.

Carthage

To use Carthage add Surge to your Cartfile:

github "mattt/Surge" ~> 2.0.0

Then run carthage update and use the framework in Carthage/Build/<platform>.


Usage

Computing Sum of [Double]

import Surge

let n = [1.0, 2.0, 3.0, 4.0, 5.0]
let sum = Surge.sum(n) // 15.0

Computing Product of Two [Double]s

import Surge

let a = [1.0, 3.0, 5.0, 7.0]
let b = [2.0, 4.0, 6.0, 8.0]

let product = Surge.mul(a, b) // [2.0, 12.0, 30.0, 56.0]

Inventory

General Arithmetic Operations

Addition

<details open> <summary> Addition functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)add.+ (infix).+= (infix)
(Array, Scalar)add+ (infix)+= (infix)
(Matrix, Matrix)add+ (infix)n/a
(Matrix, Scalar)n/a+ (infix)n/a
(Vector, Vector)add+ (infix)+= (infix)
(Vector, Scalar)add+ (infix)+= (infix)
<!-- Internal use only: | In-Place Function | |-------------------| | `addInPlace` | | `addInPlace` | | n/a | | n/a | | `addInPlace` | | `addInPlace` | --> <!-- FIXME: `add` for `(Array, Array)` should be called `eladd`/`.+`, no? --> <!-- FIXME: Missing `add` function for `(Matrix, Scalar)`. --> <!-- FIXME: Missing `add` functions/operators for `(Matrix, Vector)`. --> <!-- FIXME: Missing `addInPlace` function for `(Matrix, Scalar)` & `(Matrix, Matrix)`. --> </details>

Subtraction

<details open> <summary> Subtraction functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)sub.- (infix).-= (infix)
(Array, Scalar)sub- (infix)-= (infix)
(Matrix, Matrix)sub- (infix)n/a
(Matrix, Scalar)n/an/an/a
(Vector, Vector)sub- (infix)-= (infix)
(Vector, Scalar)sub- (infix)-= (infix)
<!-- Internal use only: | In-Place Function | |-------------------| | `subInPlace` | | `subInPlace` | | n/a | | n/a | | `subInPlace` | | `subInPlace` | --> <!-- FIXME: `sub` for `(Array, Array)` should be called `elsub`/`.-`, no? --> <!-- FIXME: Missing `sub` function/operator for `(Matrix, Scalar)`. --> <!-- FIXME: Missing `sub` functions/operators for `(Matrix, Vector)`. --> <!-- FIXME: Missing `subInPlace` function for `(Matrix, Scalar)` & `(Matrix, Matrix)`. --> </details>

Multiplication

<details open> <summary> Multiplication functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)mul.* (infix).*= (infix)
(Array, Scalar)mul* (infix)*= (infix)
(Matrix, Matrix)mul* (infix)n/a
(Matrix, Vector)mul* (infix)n/a
(Matrix, Scalar)mul* (infix)n/a
(Vector, Matrix)mul* (infix)n/a
(Vector, Scalar)mul* (infix)*= (infix)
(Scalar, Array)mul* (infix)n/a
(Scalar, Matrix)mul* (infix)n/a
(Scalar, Vector)mul* (infix)n/a
<!-- Internal use only: | In-Place Function | |-------------------| | `mulInPlace` | | `mulInPlace` | | n/a | | n/a | | n/a | | n/a | | `mulInPlace` | | n/a | | n/a | | n/a | --> </details>

Element-wise multiplication

<details open> <summary> Element-wise multiplication functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Matrix, Matrix)elmuln/an/a
(Vector, Vector)elmul.* (infix).*= (infix)
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | `elmulInPlace` | --> <!-- FIXME: The does not seem to be a `.*` implemented for `(Matrix, Matrix)`. --> </details>

Division

<details open> <summary> Division functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)div./ (infix)./= (infix)
(Array, Scalar)div/ (infix)/= (infix)
(Matrix, Matrix)div/ (infix)n/a
(Matrix, Scalar)n/a/ (infix)n/a
(Vector, Scalar)div/ (infix)/= (infix)
<!-- Internal use only: | In-Place Function | |-------------------| | `divInPlace` | | `divInPlace` | | n/a | | n/a | | `divInPlace` | --> <!-- FIXME: Func `div` of `(Array, Array)` should be called `eldiv`, no? --> <!-- FIXME: Missing `div` function for `(Matrix, Scalar)`. --> </details>

Element-wise Division

<details open> <summary> Element-wise multiplication functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Vector, Vector)eldiv./ (infix)./= (infix)
<!-- Internal use only: | In-Place Function | |-------------------| | `eldivInPlace` | --> </details>

Modulo

<details open> <summary> Modulo functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)mod.% (infix)n/a
(Array, Scalar)mod% (infix)n/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | --> <!-- FIXME: Do we need `mod` functions/operators for `Matrix`? --> <!-- FIXME: Do we need `mod` functions/operators for `Vector`? --> </details>

Remainder

<details open> <summary> Remainder functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)remaindern/an/a
(Array, Scalar)remaindern/an/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | --> <!-- FIXME: Do we need `remainder` functions /operators for `Matrix`? --> <!-- FIXME: Do we need `remainder` functions /operators for `Vector`? --> </details>

Square Root

<details open> <summary> Square root functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array)sqrtn/an/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | --> <!-- FIXME: The seems to be a variant `func sqrt<MI, MO>(_ x: MI, into results: inout MO)` that could be made into a `sqrtInPlace`--> <!-- FIXME: Do we need `sqrt` functions/operators for `Matrix`? --> <!-- FIXME: Do we need `sqrt` functions/operators for `Vector`? --> </details>

Summation

<details open> <summary> Sum functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array)sumn/an/a
(Matrix)sumn/an/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | --> <!-- FIXME: Do we need `sum` functions/operators for `Vector`? --> </details>

Dot Product

<details open> <summary> Dot product functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)dot (infix)n/a
(Vector, Vector)dot (infix)n/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | --> <!-- FIXME: Do we need `dot` functions/operators for `Matrix`? --> </details>

Distance

<details open> <summary> Distance functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)distn/an/a
(Vector, Vector)distn/an/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | -->

Squared Distance

<details open> <summary> Squared distance functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)distSqn/an/a
(Vector, Vector)distSqn/an/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | --> </details>

Power

<details open> <summary> Power functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array, Array)pow** (infix)n/a
(Array, Scalar)pow** (infix)n/a
(Matrix, Scalar)pow** (infix)n/a
(Vector, Vector)pown/an/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | | n/a | | n/a | --> <!-- FIXME: Shouldn't the `pow`/`**` function/operator of `(Array, Array)` be `elpow`/`.**`? --> <!-- FIXME: Shouldn't the `pow`/`**` function/operator of `(Vector, Vector)` be `elpow`/`.**`? --> <!-- FIXME: The does not seem to be a corresponding `.**` operator implemented. --> <!-- FIXME: Do we need `pow` functions/operators for `(Vector, Scalar)`? -->

Exponential

<details open> <summary> Exponential functions & operators </summary>
ArgumentsFunctionOperatorIn-Place Operator
(Array)expn/an/a
(Matrix)expn/an/a
(Vector)expn/an/a
<!-- Internal use only: | In-Place Function | |-------------------| | n/a | | n/a | | n/a | --> </details>

Trigonometric Operations

<details open> <summary> Trigonometric functions & operators </summary>

Sine/Cosine/Tangent

ArgumentsFunctionOperation
(Array)sinSine
(Array)cosCosine
(Array)tanTangent
(Array)sincosSine & Cosine

Arc Sine/Cosine/Tangent

ArgumentsFunctionOperation
(Array)asinArc Sine
(Array)acosArc Cosine
(Array)atanArc Tangent

Hyperbolic Sine/Cosine/Tangent

ArgumentsFunctionOperation
(Array)sinhHyperbolic Sine
(Array)coshHyperbolic Cosine
(Array)tanhHyperbolic Tangent

Inverse Hyperbolic Sine/Cosine/Tangent

ArgumentsFunctionOperation
(Array)asinhInverse Hyperbolic Sine
(Array)acoshInverse Hyperbolic Cosine
(Array)atanhInverse Hyperbolic Tangent

Radians ↔︎ Degrees

ArgumentsFunctionOperation
(Array)rad2degRadians to Degrees
(Array)deg2radDegrees to Radians
</details>

Exponential Function

<details open> <summary> Exponential functions & operators </summary>
ArgumentsFunctionOperation
(Array)expBase-e Exponential Function
(Array)exp2Base-2 Exponential Function
</details>

Logarithm

<details open> <summary> Exponential functions & operators </summary>
ArgumentsFunctionOperation
(Array)logBase-e Logarithm
(Array)log2Base-2 Logarithm
(Array)log10Base-10 Logarithm
(Array)logbBase-b Logarithm
</details>

Statistical Operations

<details open> <summary> Statistical functions & operators </summary>

Summation

ArgumentsFunctionOperation
(Array)sumSummation
(Array)asumAbsolute Summation

Minimum/Maximum

ArgumentsFunctionOperation
(Array)minMinimum
(Array)maxMaximum

Mean/Variance

ArgumentsFunctionOperation
(Array)meanMean
(Array)meamgMean of Magnitudes
(Array)measqMean of Squares
(Array)varianceVariance
(Array)stdStandard Deviation
</details>

Auxiliary Functions

<details open> <summary> Auxiliary functions & operators </summary>

Rounding Functions

ArgumentsFunctionOperation
(Array)ceilCeiling
(Array)floorFlooring
(Array)roundRounding
(Array)truncInteger truncation

Absolute value

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Array)absn/an/an/a

Signum function

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Array)copysignn/an/an/a

Multiplicative inverse

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Array)recn/an/an/a
</details>

Matrix-specific Operations

<details open> <summary> Matrix-specific functions & operators </summary>

Matrix Inversion

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Matrix)invn/an/an/a

Matrix Transposition

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Matrix)transposen/a (postfix)n/a

Matrix Determinant

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Matrix)detn/an/an/a

Eigen Decomposition

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Matrix)eigenDecomposen/an/an/a
</details>

DSP-specific Operations

<details open> <summary> Fast fourier transform functions & operators </summary>

Fast Fourier Transform

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Array)fftn/an/an/a

Convolution

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Array, Array)convn/an/an/a

Cross-Correlation

ArgumentsFunctionIn-Place FunctionOperatorIn-Place Operator
(Array, Array)xcorrn/an/an/a
(Array)xcorrn/an/an/a
</details>