diff --git a/Sources/Surge/Auxiliary.swift b/Sources/Surge/Auxiliary Functions/Auxiliary.swift similarity index 98% rename from Sources/Surge/Auxiliary.swift rename to Sources/Surge/Auxiliary Functions/Auxiliary.swift index 0bd217ac..09fea3e7 100644 --- a/Sources/Surge/Auxiliary.swift +++ b/Sources/Surge/Auxiliary Functions/Auxiliary.swift @@ -20,7 +20,7 @@ import Accelerate -// MARK: Absolute Value +// MARK: - Absolute Value /// Elemen-wise absolute value. /// @@ -50,7 +50,7 @@ public func abs(_ x: C) -> [Float] where C.Element == return results } -// MARK: Ceiling +// MARK: - Ceiling /// Elemen-wise ceiling. /// @@ -80,7 +80,7 @@ public func ceil(_ x: C) -> [Double] where C.Element return results } -// MARK: Clip +// MARK: - Clip public func clip(_ x: C, low: Float, high: Float) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) @@ -110,7 +110,7 @@ public func clip(_ x: C, low: Double, high: Double) - return results } -// MARK: Copy Sign +// MARK: - Copy Sign /// - Warning: does not support memory stride (assumes stride is 1). public func copysign(sign: S, magnitude: M) -> [Float] where S.Element == Float, M.Element == Float { @@ -136,7 +136,7 @@ public func copysign(sign: return results } -// MARK: Floor +// MARK: - Floor /// Elemen-wise floor. /// @@ -166,7 +166,7 @@ public func floor(_ x: C) -> [Double] where C.Element return results } -// MARK: Negate +// MARK: - Negate public func neg(_ x: C) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) @@ -188,7 +188,7 @@ public func neg(_ x: C) -> [Double] where C.Element = return results } -// MARK: Reciprocal +// MARK: - Reciprocal /// - Warning: does not support memory stride (assumes stride is 1). public func rec(_ x: C) -> [Float] where C.Element == Float { @@ -214,7 +214,7 @@ public func rec(_ x: C) -> [Double] where C.Element = return results } -// MARK: Round +// MARK: - Round /// - Warning: does not support memory stride (assumes stride is 1). public func round(_ x: C) -> [Float] where C.Element == Float { @@ -240,7 +240,7 @@ public func round(_ x: C) -> [Double] where C.Element return results } -// MARK: Threshold +// MARK: - Threshold public func threshold(_ x: C, low: Float) -> [Float] where C.Element == Float { var results = [Float](repeating: 0.0, count: numericCast(x.count)) @@ -268,7 +268,7 @@ public func threshold(_ x: C, low: Double) -> [Double return results } -// MARK: Truncate +// MARK: - Truncate /// - Warning: does not support memory stride (assumes stride is 1). public func trunc(_ x: C) -> [Float] where C.Element == Float { diff --git a/Sources/Surge/Convolution.swift b/Sources/Surge/Digital Signal Processing/Convolution.swift similarity index 98% rename from Sources/Surge/Convolution.swift rename to Sources/Surge/Digital Signal Processing/Convolution.swift index c6aa8eee..7c85ae85 100644 --- a/Sources/Surge/Convolution.swift +++ b/Sources/Surge/Digital Signal Processing/Convolution.swift @@ -20,7 +20,7 @@ import Accelerate -// MARK: Convolution +// MARK: - Convolution /// Convolution of a signal [x], with a kernel [k]. The signal must be at least as long as the kernel. public func conv(_ x: X, _ k: K) -> [Float] where X.Element == Float, K.Element == Float { @@ -68,7 +68,7 @@ public func conv(_ x: X, _ return result } -// MARK: Cross-Correlation +// MARK: - Cross-Correlation /// Cross-correlation of a signal [x], with another signal [y]. The signal [y] /// is padded so that it is the same length as [x]. @@ -124,7 +124,7 @@ public func xcorr(_ x: X, return result } -// MARK: Auto-correlation +// MARK: - Auto-correlation /// Auto-correlation of a signal [x] public func xcorr(_ x: X) -> [Float] where X.Element == Float { diff --git a/Sources/Surge/FFT.swift b/Sources/Surge/Digital Signal Processing/FFT.swift similarity index 99% rename from Sources/Surge/FFT.swift rename to Sources/Surge/Digital Signal Processing/FFT.swift index 6c09b84b..85ac2427 100644 --- a/Sources/Surge/FFT.swift +++ b/Sources/Surge/Digital Signal Processing/FFT.swift @@ -20,7 +20,7 @@ import Accelerate -// MARK: Fast Fourier Transform +// MARK: - Fast Fourier Transform public func fft(_ input: [Float]) -> [Float] { var real = [Float](input) diff --git a/Sources/Surge/Exponential/Exponential.swift b/Sources/Surge/Exponential/Exponential.swift new file mode 100644 index 00000000..0ce481cb --- /dev/null +++ b/Sources/Surge/Exponential/Exponential.swift @@ -0,0 +1,73 @@ +// Copyright © 2014-2018 the Surge contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Accelerate + +// MARK: - Exponentiation + +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexpf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexp(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +// MARK: - Square Exponentiation + +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp2(_ x: X) -> [Float] where X.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexp2f(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func exp2(_ x: X) -> [Double] where X.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvexp2(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} diff --git a/Sources/Surge/Arithmetic.swift b/Sources/Surge/General Arithmetic/Arithmetic.swift similarity index 62% rename from Sources/Surge/Arithmetic.swift rename to Sources/Surge/General Arithmetic/Arithmetic.swift index 64c22694..d0a43401 100644 --- a/Sources/Surge/Arithmetic.swift +++ b/Sources/Surge/General Arithmetic/Arithmetic.swift @@ -20,30 +20,38 @@ import Accelerate -// MARK: Addition - -public func add(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Collections must have the same size") - var results = [Float](y) - x.withUnsafeMemory { xm in - results.withUnsafeMutableBufferPointer { rbp in - cblas_saxpy(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), rbp.baseAddress, 1) +// MARK: - Addition + +public func add(_ lhs: L, _ rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Collections must have the same size") + var results = [Float](rhs) + lhs.withUnsafeMemory { lhsMemory in + results.withUnsafeMutableBufferPointer { bufferPointer in + cblas_saxpy(numericCast(lhsMemory.count), 1.0, lhsMemory.pointer, numericCast(lhsMemory.stride), bufferPointer.baseAddress, 1) } } return results } -public func add(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Collections must have the same size") - var results = [Double](y) - x.withUnsafeMemory { xm in - results.withUnsafeMutableBufferPointer { rbp in - cblas_daxpy(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), rbp.baseAddress, 1) +public func add(_ lhs: L, _ rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Collections must have the same size") + var results = [Double](rhs) + lhs.withUnsafeMemory { lhsMemory in + results.withUnsafeMutableBufferPointer { bufferPointer in + cblas_daxpy(numericCast(lhsMemory.count), 1.0, lhsMemory.pointer, numericCast(lhsMemory.stride), bufferPointer.baseAddress, 1) } } return results } +public func .+ (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + return add(lhs, rhs) +} + +public func .+ (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + return add(lhs, rhs) +} + public func add(_ lhs: L, _ rhs: Float) -> [Float] where L.Element == Float { return add(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } @@ -52,7 +60,15 @@ public func add(_ lhs: L, _ rhs: Double) -> [Double] return add(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -// MARK: Addition: In Place +public func + (lhs: L, rhs: Float) -> [Float] where L.Element == Float { + return add(lhs, rhs) +} + +public func + (lhs: L, rhs: Double) -> [Double] where L.Element == Double { + return add(lhs, rhs) +} + +// MARK: - Addition: In Place func addInPlace(_ lhs: inout L, _ rhs: R) where L.Element == Float, R.Element == Float { lhs.withUnsafeMutableMemory { lm in @@ -70,6 +86,14 @@ func addInPlace(_ l } } +public func .+= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { + return addInPlace(&lhs, rhs) +} + +public func .+= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { + return addInPlace(&lhs, rhs) +} + func addInPlace(_ lhs: inout L, _ rhs: Float) where L.Element == Float { lhs.withUnsafeMutableMemory { lm in var scalar = rhs @@ -84,30 +108,46 @@ func addInPlace(_ lhs: inout L, _ rhs: Double) } } -// MARK: Subtraction +public func +=(lhs: inout L, rhs: Float) where L.Element == Float { + return addInPlace(&lhs, rhs) +} + +public func +=(lhs: inout L, rhs: Double) where L.Element == Double { + return addInPlace(&lhs, rhs) +} + +// MARK: - Subtraction -public func sub(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Collections must have the same size") - var results = [Float](y) - x.withUnsafeMemory { xm in - results.withUnsafeMutableBufferPointer { rbp in - catlas_saxpby(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), -1, rbp.baseAddress, 1) +public func sub(_ lhs: L, _ rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Collections must have the same size") + var results = [Float](rhs) + lhs.withUnsafeMemory { lhsMemory in + results.withUnsafeMutableBufferPointer { bufferPointer in + catlas_saxpby(numericCast(lhsMemory.count), 1.0, lhsMemory.pointer, numericCast(lhsMemory.stride), -1, bufferPointer.baseAddress, 1) } } return results } -public func sub(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Collections must have the same size") - var results = [Double](y) - x.withUnsafeMemory { xm in - results.withUnsafeMutableBufferPointer { rbp in - catlas_daxpby(numericCast(xm.count), 1.0, xm.pointer, numericCast(xm.stride), -1, rbp.baseAddress, 1) +public func sub(_ lhs: L, _ rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Collections must have the same size") + var results = [Double](rhs) + lhs.withUnsafeMemory { lhsMemory in + results.withUnsafeMutableBufferPointer { bufferPointer in + catlas_daxpby(numericCast(lhsMemory.count), 1.0, lhsMemory.pointer, numericCast(lhsMemory.stride), -1, bufferPointer.baseAddress, 1) } } return results } +public func .- (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + return sub(lhs, rhs) +} + +public func .- (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + return sub(lhs, rhs) +} + public func sub(_ lhs: L, _ rhs: Float) -> [Float] where L.Element == Float { return sub(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } @@ -116,7 +156,15 @@ public func sub(_ lhs: L, _ rhs: Double) -> [Double] return sub(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -// MARK: Subtraction: In Place +public func - (lhs: L, rhs: Float) -> [Float] where L.Element == Float { + return sub(lhs, rhs) +} + +public func - (lhs: L, rhs: Double) -> [Double] where L.Element == Double { + return sub(lhs, rhs) +} + +// MARK: - Subtraction: In Place func subInPlace(_ lhs: inout L, _ rhs: R) where L.Element == Float, R.Element == Float { lhs.withUnsafeMutableMemory { lm in @@ -134,6 +182,14 @@ func subInPlace(_ l } } +public func .-= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { + return subInPlace(&lhs, rhs) +} + +public func .-= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { + return subInPlace(&lhs, rhs) +} + func subInPlace(_ lhs: inout L, _ rhs: Float) where L.Element == Float { lhs.withUnsafeMutableMemory { lm in var scalar = -rhs @@ -148,30 +204,46 @@ func subInPlace(_ lhs: inout L, _ rhs: Double) } } -// MARK: Multiplication +public func -=(lhs: inout L, rhs: Float) where L.Element == Float { + return subInPlace(&lhs, rhs) +} -public func mul(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - var results = [Float](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vDSP_vmul(xm.pointer, numericCast(xm.stride), ym.pointer, numericCast(ym.stride), rbp.baseAddress!, 1, numericCast(xm.count)) +public func -=(lhs: inout L, rhs: Double) where L.Element == Double { + return subInPlace(&lhs, rhs) +} + +// MARK: - Multiplication + +public func mul(_ lhs: L, _ rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + var results = [Float](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vDSP_vmul(lhsMemory.pointer, numericCast(lhsMemory.stride), rhsMemory.pointer, numericCast(rhsMemory.stride), bufferPointer.baseAddress!, 1, numericCast(lhsMemory.count)) } return results } } -public func mul(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - var results = [Double](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vDSP_vmulD(xm.pointer, numericCast(xm.stride), ym.pointer, numericCast(ym.stride), rbp.baseAddress!, 1, numericCast(xm.count)) +public func mul(_ lhs: L, _ rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + var results = [Double](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vDSP_vmulD(lhsMemory.pointer, numericCast(lhsMemory.stride), rhsMemory.pointer, numericCast(rhsMemory.stride), bufferPointer.baseAddress!, 1, numericCast(lhsMemory.count)) } return results } } +public func .* (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + return mul(lhs, rhs) +} + +public func .* (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + return mul(lhs, rhs) +} + public func mul(_ lhs: L, _ rhs: Float) -> [Float] where L.Element == Float { return mul(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } @@ -180,15 +252,15 @@ public func mul(_ lhs: L, _ rhs: Double) -> [Double] return mul(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -public func mul(_ lhs: Float, _ rhs: R) -> [Float] where R.Element == Float { - return mul([Float](repeating: lhs, count: numericCast(rhs.count)), rhs) +public func * (lhs: L, rhs: Float) -> [Float] where L.Element == Float { + return mul(lhs, rhs) } -public func mul(_ lhs: Double, _ rhs: R) -> [Double] where R.Element == Double { - return mul([Double](repeating: lhs, count: numericCast(rhs.count)), rhs) +public func * (lhs: L, rhs: Double) -> [Double] where L.Element == Double { + return mul(lhs, rhs) } -// MARK: Multiplication: In Place +// MARK: - Multiplication: In Place func mulInPlace(_ lhs: inout L, _ rhs: R) where L.Element == Float, R.Element == Float { lhs.withUnsafeMutableMemory { lm in @@ -206,6 +278,14 @@ func mulInPlace(_ l } } +public func .*= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { + return mulInPlace(&lhs, rhs) +} + +public func .*= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { + return mulInPlace(&lhs, rhs) +} + func mulInPlace(_ lhs: inout L, _ rhs: Float) where L.Element == Float { lhs.withUnsafeMutableMemory { lm in var scalar = rhs @@ -220,32 +300,48 @@ func mulInPlace(_ lhs: inout L, _ rhs: Double) } } -// MARK: Division +public func *=(lhs: inout L, rhs: Float) where L.Element == Float { + return mulInPlace(&lhs, rhs) +} + +public func *=(lhs: inout L, rhs: Double) where L.Element == Double { + return mulInPlace(&lhs, rhs) +} + +// MARK: - Division /// Elemen-wise vector division. -public func div(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - var results = [Float](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vDSP_vdiv(ym.pointer, numericCast(ym.stride), xm.pointer, numericCast(xm.stride), rbp.baseAddress!, 1, numericCast(xm.count)) +public func div(_ lhs: L, _ rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + var results = [Float](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vDSP_vdiv(rhsMemory.pointer, numericCast(rhsMemory.stride), lhsMemory.pointer, numericCast(lhsMemory.stride), bufferPointer.baseAddress!, 1, numericCast(lhsMemory.count)) } return results } } /// Elemen-wise vector division. -public func div(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - var results = [Double](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vDSP_vdivD(ym.pointer, numericCast(ym.stride), xm.pointer, numericCast(xm.stride), rbp.baseAddress!, 1, numericCast(xm.count)) +public func div(_ lhs: L, _ rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + var results = [Double](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vDSP_vdivD(rhsMemory.pointer, numericCast(rhsMemory.stride), lhsMemory.pointer, numericCast(lhsMemory.stride), bufferPointer.baseAddress!, 1, numericCast(lhsMemory.count)) } return results } } +public func ./ (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + return div(lhs, rhs) +} + +public func ./ (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + return div(lhs, rhs) +} + public func div(_ lhs: L, _ rhs: Float) -> [Float] where L.Element == Float { return div(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } @@ -254,7 +350,15 @@ public func div(_ lhs: L, _ rhs: Double) -> [Double] return div(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -// MARK: Division: In Place +public func / (lhs: L, rhs: Float) -> [Float] where L.Element == Float { + return div(lhs, rhs) +} + +public func / (lhs: L, rhs: Double) -> [Double] where L.Element == Double { + return div(lhs, rhs) +} + +// MARK: - Division: In Place func divInPlace(_ lhs: inout L, _ rhs: R) where L.Element == Float, R.Element == Float { lhs.withUnsafeMutableMemory { lm in @@ -272,6 +376,14 @@ func divInPlace(_ l } } +public func ./= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { + return divInPlace(&lhs, rhs) +} + +public func ./= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { + return divInPlace(&lhs, rhs) +} + func divInPlace(_ lhs: inout L, _ rhs: Float) where L.Element == Float { lhs.withUnsafeMutableMemory { lm in var scalar = rhs @@ -286,18 +398,26 @@ func divInPlace(_ lhs: inout L, _ rhs: Double) } } -// MARK: Modulo +public func /=(lhs: inout L, rhs: Float) where L.Element == Float { + return divInPlace(&lhs, rhs) +} + +public func /=(lhs: inout L, rhs: Double) where L.Element == Double { + return divInPlace(&lhs, rhs) +} + +// MARK: - Modulo /// Elemen-wise modulo. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func mod(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvfmodf(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) +public func mod(_ lhs: L, _ rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + precondition(lhsMemory.stride == 1 && rhsMemory.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vvfmodf(bufferPointer.baseAddress!, lhsMemory.pointer, rhsMemory.pointer, [numericCast(lhsMemory.count)]) } return results } @@ -306,18 +426,26 @@ public func mod(_ x: X, _ /// Elemen-wise modulo. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func mod(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvfmod(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) +public func mod(_ lhs: L, _ rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + precondition(lhsMemory.stride == 1 && rhsMemory.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vvfmod(bufferPointer.baseAddress!, lhsMemory.pointer, rhsMemory.pointer, [numericCast(lhsMemory.count)]) } return results } } +public func .% (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + return mod(lhs, rhs) +} + +public func .% (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + return mod(lhs, rhs) +} + public func mod(_ lhs: L, _ rhs: Float) -> [Float] where L.Element == Float { return mod(lhs, [Float](repeating: rhs, count: numericCast(lhs.count))) } @@ -326,18 +454,26 @@ public func mod(_ lhs: L, _ rhs: Double) -> [Double] return mod(lhs, [Double](repeating: rhs, count: numericCast(lhs.count))) } -// MARK: Remainder +public func % (lhs: L, rhs: Float) -> [Float] where L.Element == Float { + return mod(lhs, rhs) +} + +public func % (lhs: L, rhs: Double) -> [Double] where L.Element == Double { + return mod(lhs, rhs) +} + +// MARK: - Remainder /// Elemen-wise remainder. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func remainder(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvremainderf(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) +public func remainder(_ lhs: L, _ rhs: R) -> [Float] where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + precondition(lhsMemory.stride == 1 && rhsMemory.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vvremainderf(bufferPointer.baseAddress!, lhsMemory.pointer, rhsMemory.pointer, [numericCast(lhsMemory.count)]) } return results } @@ -346,38 +482,38 @@ public func remainder(_ x: /// Elemen-wise remainder. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func remainder(_ x: X, _ y: Y) -> [Double] where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Collections must have the same size") - return withUnsafeMemory(x, y) { xm, ym in - precondition(xm.stride == 1 && ym.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(xm.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvremainder(rbp.baseAddress!, xm.pointer, ym.pointer, [numericCast(xm.count)]) +public func remainder(_ lhs: L, _ rhs: R) -> [Double] where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Collections must have the same size") + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + precondition(lhsMemory.stride == 1 && rhsMemory.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(lhsMemory.count)) + results.withUnsafeMutableBufferPointer { bufferPointer in + vvremainder(bufferPointer.baseAddress!, lhsMemory.pointer, rhsMemory.pointer, [numericCast(lhsMemory.count)]) } return results } } -// MARK: Square Root +// MARK: - Square Root /// Elemen-wise square root. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func sqrt(_ x: C) -> [Float] where C.Element == Float { - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - sqrt(x, into: &results) +public func sqrt(_ lhs: C) -> [Float] where C.Element == Float { + var results = [Float](repeating: 0.0, count: numericCast(lhs.count)) + sqrt(lhs, into: &results) return results } /// Elemen-wise square root with custom output storage. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func sqrt(_ x: MI, into results: inout MO) where MI.Element == Float, MO.Element == Float { - return x.withUnsafeMemory { xm in +public func sqrt(_ lhs: MI, into results: inout MO) where MI.Element == Float, MO.Element == Float { + return lhs.withUnsafeMemory { lhsMemory in results.withUnsafeMutableMemory { rm in - precondition(xm.stride == 1 && rm.stride == 1, "sqrt doesn't support step values other than 1") - precondition(rm.count >= xm.count, "`results` doesnt have enough capacity to store the results") - vvsqrtf(rm.pointer, xm.pointer, [numericCast(xm.count)]) + precondition(lhsMemory.stride == 1 && rm.stride == 1, "sqrt doesn't support step values other than 1") + precondition(rm.count >= lhsMemory.count, "`results` doesnt have enough capacity to store the results") + vvsqrtf(rm.pointer, lhsMemory.pointer, [numericCast(lhsMemory.count)]) } } } @@ -385,277 +521,89 @@ public func sqrt( /// Elemen-wise square root. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func sqrt(_ x: C) -> [Double] where C.Element == Double { - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - sqrt(x, into: &results) +public func sqrt(_ lhs: C) -> [Double] where C.Element == Double { + var results = [Double](repeating: 0.0, count: numericCast(lhs.count)) + sqrt(lhs, into: &results) return results } /// Elemen-wise square root with custom output storage. /// /// - Warning: does not support memory stride (assumes stride is 1). -public func sqrt(_ x: MI, into results: inout MO) where MI.Element == Double, MO.Element == Double { - return x.withUnsafeMemory { xm in +public func sqrt(_ lhs: MI, into results: inout MO) where MI.Element == Double, MO.Element == Double { + return lhs.withUnsafeMemory { lhsMemory in results.withUnsafeMutableMemory { rm in - precondition(xm.stride == 1 && rm.stride == 1, "sqrt doesn't support step values other than 1") - precondition(rm.count >= xm.count, "`results` doesnt have enough capacity to store the results") - vvsqrt(rm.pointer, xm.pointer, [numericCast(xm.count)]) + precondition(lhsMemory.stride == 1 && rm.stride == 1, "sqrt doesn't support step values other than 1") + precondition(rm.count >= lhsMemory.count, "`results` doesnt have enough capacity to store the results") + vvsqrt(rm.pointer, lhsMemory.pointer, [numericCast(lhsMemory.count)]) } } } -// MARK: Dot Product +// MARK: - Dot Product -public func dot(_ x: X, _ y: Y) -> Float where X.Element == Float, Y.Element == Float { - return withUnsafeMemory(x, y) { xm, ym in - precondition(xm.count == ym.count, "Vectors must have equal count") +public func dot(_ lhs: L, _ rhs: R) -> Float where L.Element == Float, R.Element == Float { + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + precondition(lhsMemory.count == rhsMemory.count, "Vectors must have equal count") var result: Float = 0.0 withUnsafeMutablePointer(to: &result) { pointer in - vDSP_dotpr(xm.pointer, numericCast(xm.stride), ym.pointer, numericCast(ym.stride), pointer, numericCast(xm.count)) + vDSP_dotpr(lhsMemory.pointer, numericCast(lhsMemory.stride), rhsMemory.pointer, numericCast(rhsMemory.stride), pointer, numericCast(lhsMemory.count)) } return result } } -public func dot(_ x: X, _ y: Y) -> Double where X.Element == Double, Y.Element == Double { - return withUnsafeMemory(x, y) { xm, ym in - precondition(xm.count == ym.count, "Vectors must have equal count") +public func dot(_ lhs: L, _ rhs: R) -> Double where L.Element == Double, R.Element == Double { + return withUnsafeMemory(lhs, rhs) { lhsMemory, rhsMemory in + precondition(lhsMemory.count == rhsMemory.count, "Vectors must have equal count") var result: Double = 0.0 withUnsafeMutablePointer(to: &result) { pointer in - vDSP_dotprD(xm.pointer, numericCast(xm.stride), ym.pointer, numericCast(ym.stride), pointer, numericCast(xm.count)) + vDSP_dotprD(lhsMemory.pointer, numericCast(lhsMemory.stride), rhsMemory.pointer, numericCast(rhsMemory.stride), pointer, numericCast(lhsMemory.count)) } return result } } +infix operator •: MultiplicationPrecedence + +public func • (lhs: L, rhs: R) -> Double where L.Element == Double, R.Element == Double { + return dot(lhs, rhs) +} + +public func • (lhs: L, rhs: R) -> Float where L.Element == Float, R.Element == Float { + return dot(lhs, rhs) +} + // MARK: - Distance -public func dist(_ x: X, _ y: Y) -> Float where X.Element == Float, Y.Element == Float { - return sqrt(distSq(x, y)) +public func dist(_ lhs: L, _ rhs: R) -> Float where L.Element == Float, R.Element == Float { + return sqrt(distSq(lhs, rhs)) } -public func dist(_ x: X, _ y: Y) -> Double where X.Element == Double, Y.Element == Double { - return sqrt(distSq(x, y)) +public func dist(_ lhs: L, _ rhs: R) -> Double where L.Element == Double, R.Element == Double { + return sqrt(distSq(lhs, rhs)) } -public func distSq(_ x: X, _ y: Y) -> Float where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Vectors must have equal count") - let sub = x .- y - var squared = [Float](repeating: 0.0, count: numericCast(x.count)) +public func distSq(_ lhs: L, _ rhs: R) -> Float where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Vectors must have equal count") + let sub = lhs .- rhs + var squared = [Float](repeating: 0.0, count: numericCast(lhs.count)) squared.withUnsafeMutableBufferPointer { bufferPointer in - vDSP_vsq(sub, 1, bufferPointer.baseAddress!, 1, numericCast(x.count)) + vDSP_vsq(sub, 1, bufferPointer.baseAddress!, 1, numericCast(lhs.count)) } return sum(squared) } -public func distSq(_ x: X, _ y: Y) -> Double where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Vectors must have equal count") - let sub = x .- y - var squared = [Double](repeating: 0.0, count: numericCast(x.count)) +public func distSq(_ lhs: L, _ rhs: R) -> Double where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Vectors must have equal count") + let sub = lhs .- rhs + var squared = [Double](repeating: 0.0, count: numericCast(lhs.count)) squared.withUnsafeMutableBufferPointer { bufferPointer in - vDSP_vsqD(sub, 1, bufferPointer.baseAddress!, 1, numericCast(x.count)) + vDSP_vsqD(sub, 1, bufferPointer.baseAddress!, 1, numericCast(lhs.count)) } return sum(squared) } - -// MARK: - Operators - -// MARK: Elemen-wise addition - -infix operator .+: AdditionPrecedence -infix operator .+=: AssignmentPrecedence - -public func .+= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { - return addInPlace(&lhs, rhs) -} - -public func .+= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { - return addInPlace(&lhs, rhs) -} - -public func .+ (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { - return add(lhs, rhs) -} - -public func .+ (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { - return add(lhs, rhs) -} - -// MARK: Scalar addition - -public func +=(lhs: inout L, rhs: Float) where L.Element == Float { - return addInPlace(&lhs, rhs) -} - -public func +=(lhs: inout L, rhs: Double) where L.Element == Double { - return addInPlace(&lhs, rhs) -} - -public func + (lhs: L, rhs: Float) -> [Float] where L.Element == Float { - return add(lhs, rhs) -} - -public func + (lhs: L, rhs: Double) -> [Double] where L.Element == Double { - return add(lhs, rhs) -} - -// MARK: Element-wise subtraction - -infix operator .-: AdditionPrecedence -infix operator .-=: AssignmentPrecedence - -public func .-= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { - return subInPlace(&lhs, rhs) -} - -public func .-= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { - return subInPlace(&lhs, rhs) -} - -public func .- (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { - return sub(lhs, rhs) -} - -public func .- (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { - return sub(lhs, rhs) -} - -// MARK: Scalar subtraction - -public func -=(lhs: inout L, rhs: Float) where L.Element == Float { - return subInPlace(&lhs, rhs) -} - -public func -=(lhs: inout L, rhs: Double) where L.Element == Double { - return subInPlace(&lhs, rhs) -} - -public func - (lhs: L, rhs: Float) -> [Float] where L.Element == Float { - return sub(lhs, rhs) -} - -public func - (lhs: L, rhs: Double) -> [Double] where L.Element == Double { - return sub(lhs, rhs) -} - -// MARK: Element-wise division - -infix operator ./: MultiplicationPrecedence -infix operator ./=: AssignmentPrecedence - -public func ./= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { - return divInPlace(&lhs, rhs) -} - -public func ./= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { - return divInPlace(&lhs, rhs) -} - -public func ./ (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { - return div(lhs, rhs) -} - -public func ./ (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { - return div(lhs, rhs) -} - -// MARK: Scalar division - -public func /=(lhs: inout L, rhs: Float) where L.Element == Float { - return divInPlace(&lhs, rhs) -} - -public func /=(lhs: inout L, rhs: Double) where L.Element == Double { - return divInPlace(&lhs, rhs) -} - -public func / (lhs: L, rhs: Float) -> [Float] where L.Element == Float { - return div(lhs, rhs) -} - -public func / (lhs: L, rhs: Double) -> [Double] where L.Element == Double { - return div(lhs, rhs) -} - -// MARK: Element-wise multiplication - -infix operator .*: MultiplicationPrecedence -infix operator .*=: AssignmentPrecedence - -public func .*= (lhs: inout L, rhs: R) where L.Element == Float, R.Element == Float { - return mulInPlace(&lhs, rhs) -} - -public func .*= (lhs: inout L, rhs: R) where L.Element == Double, R.Element == Double { - return mulInPlace(&lhs, rhs) -} - -public func .* (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { - return mul(lhs, rhs) -} - -public func .* (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { - return mul(lhs, rhs) -} - -// MARK: Scalar multiplication - -public func *=(lhs: inout L, rhs: Float) where L.Element == Float { - return mulInPlace(&lhs, rhs) -} - -public func *=(lhs: inout L, rhs: Double) where L.Element == Double { - return mulInPlace(&lhs, rhs) -} - -public func * (lhs: L, rhs: Float) -> [Float] where L.Element == Float { - return mul(lhs, rhs) -} - -public func * (lhs: L, rhs: Double) -> [Double] where L.Element == Double { - return mul(lhs, rhs) -} - -public func * (lhs: Float, rhs: R) -> [Float] where R.Element == Float { - return mul(lhs, rhs) -} - -public func * (lhs: Double, rhs: R) -> [Double] where R.Element == Double { - return mul(lhs, rhs) -} - -// MARK: Modulo - -infix operator .%: MultiplicationPrecedence -infix operator .%=: AssignmentPrecedence - -public func .% (lhs: L, rhs: R) -> [Float] where L.Element == Float, R.Element == Float { - return mod(lhs, rhs) -} - -public func .% (lhs: L, rhs: R) -> [Double] where L.Element == Double, R.Element == Double { - return mod(lhs, rhs) -} - -public func % (lhs: L, rhs: Float) -> [Float] where L.Element == Float { - return mod(lhs, rhs) -} - -public func % (lhs: L, rhs: Double) -> [Double] where L.Element == Double { - return mod(lhs, rhs) -} - -// MARK: Dot product - -infix operator •: MultiplicationPrecedence -public func • (lhs: L, rhs: R) -> Double where L.Element == Double, R.Element == Double { - return dot(lhs, rhs) -} - -public func • (lhs: L, rhs: R) -> Float where L.Element == Float, R.Element == Float { - return dot(lhs, rhs) -} diff --git a/Sources/Surge/Power.swift b/Sources/Surge/General Arithmetic/Power.swift similarity index 99% rename from Sources/Surge/Power.swift rename to Sources/Surge/General Arithmetic/Power.swift index ab94acb0..6d083a31 100644 --- a/Sources/Surge/Power.swift +++ b/Sources/Surge/General Arithmetic/Power.swift @@ -20,7 +20,7 @@ import Accelerate -// MARK: Power +// MARK: - Power /// - Warning: does not support memory stride (assumes stride is 1). public func pow(_ x: X, _ y: Y) -> [Float] where X.Element == Float, Y.Element == Float { diff --git a/Sources/Surge/Hyperbolic.swift b/Sources/Surge/Hyperbolic.swift deleted file mode 100644 index 30bbca15..00000000 --- a/Sources/Surge/Hyperbolic.swift +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright © 2014-2018 the Surge contributors -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import Accelerate - -// MARK: Hyperbolic Sine - -/// - Warning: does not support memory stride (assumes stride is 1). -public func sinh(_ x: X) -> [Float] where X.Iterator.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvsinhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func sinh(_ x: X) -> [Double] where X.Iterator.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvsinh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -// MARK: Hyperbolic Cosine - -/// - Warning: does not support memory stride (assumes stride is 1). -public func cosh(_ x: X) -> [Float] where X.Iterator.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvcoshf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func cosh(_ x: X) -> [Double] where X.Iterator.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvcosh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -// MARK: Hyperbolic Tangent - -/// - Warning: does not support memory stride (assumes stride is 1). -public func tanh(_ x: X) -> [Float] where X.Iterator.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvtanhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func tanh(_ x: X) -> [Double] where X.Iterator.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvtanh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -// MARK: Inverse Hyperbolic Sine - -/// - Warning: does not support memory stride (assumes stride is 1). -public func asinh(_ x: X) -> [Float] where X.Iterator.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvasinhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func asinh(_ x: X) -> [Double] where X.Iterator.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvasinh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -// MARK: Inverse Hyperbolic Cosine - -/// - Warning: does not support memory stride (assumes stride is 1). -public func acosh(_ x: X) -> [Float] where X.Iterator.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvacoshf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func acosh(_ x: X) -> [Double] where X.Iterator.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvacosh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -// MARK: Inverse Hyperbolic Tangent - -/// - Warning: does not support memory stride (assumes stride is 1). -public func atanh(_ x: X) -> [Float] where X.Iterator.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvatanhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func atanh(_ x: X) -> [Double] where X.Iterator.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvatanh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} diff --git a/Sources/Surge/Matrix.swift b/Sources/Surge/Linear Algebra/Matrix.swift similarity index 63% rename from Sources/Surge/Matrix.swift rename to Sources/Surge/Linear Algebra/Matrix.swift index 201f7668..7a4ddf40 100644 --- a/Sources/Surge/Matrix.swift +++ b/Sources/Surge/Linear Algebra/Matrix.swift @@ -260,252 +260,278 @@ public func == (lhs: Matrix, rhs: Matrix) -> Bool { return lhs.rows == rhs.rows && lhs.columns == rhs.columns && lhs.grid == rhs.grid } -// MARK: - +// MARK: - Addition -public func add(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.rows == y.rows && x.columns == y.columns, "Matrix dimensions not compatible with addition") +public func add(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrix dimensions not compatible with addition") - var results = y + var results = rhs results.grid.withUnsafeMutableBufferPointer { pointer in - cblas_saxpy(Int32(x.grid.count), 1.0, x.grid, 1, pointer.baseAddress!, 1) + cblas_saxpy(Int32(lhs.grid.count), 1.0, lhs.grid, 1, pointer.baseAddress!, 1) } return results } -public func add(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.rows == y.rows && x.columns == y.columns, "Matrix dimensions not compatible with addition") +public func add(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrix dimensions not compatible with addition") - var results = y + var results = rhs results.grid.withUnsafeMutableBufferPointer { pointer in - cblas_daxpy(Int32(x.grid.count), 1.0, x.grid, 1, pointer.baseAddress!, 1) + cblas_daxpy(Int32(lhs.grid.count), 1.0, lhs.grid, 1, pointer.baseAddress!, 1) } return results } -public func sub(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.rows == y.rows && x.columns == y.columns, "Matrix dimensions not compatible with subtraction") - - var results = y - results.grid.withUnsafeMutableBufferPointer { pointer in - catlas_saxpby(Int32(x.grid.count), 1.0, x.grid, 1, -1, pointer.baseAddress!, 1) - } +public func + (lhs: Matrix, rhs: Matrix) -> Matrix { + return add(lhs, rhs) +} - return results +public func + (lhs: Matrix, rhs: Matrix) -> Matrix { + return add(lhs, rhs) } -public func sub(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.rows == y.rows && x.columns == y.columns, "Matrix dimensions not compatible with subtraction") +// MARK: - Subtraction - var results = y +public func sub(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrix dimensions not compatible with subtraction") + + var results = rhs results.grid.withUnsafeMutableBufferPointer { pointer in - catlas_daxpby(Int32(x.grid.count), 1.0, x.grid, 1, -1, pointer.baseAddress!, 1) + catlas_saxpby(Int32(lhs.grid.count), 1.0, lhs.grid, 1, -1, pointer.baseAddress!, 1) } return results } -public func mul(_ alpha: Float, _ x: Matrix) -> Matrix { - var results = x +public func sub(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrix dimensions not compatible with subtraction") + + var results = rhs results.grid.withUnsafeMutableBufferPointer { pointer in - cblas_sscal(Int32(x.grid.count), alpha, pointer.baseAddress!, 1) + catlas_daxpby(Int32(lhs.grid.count), 1.0, lhs.grid, 1, -1, pointer.baseAddress!, 1) } return results } -public func mul(_ alpha: Double, _ x: Matrix) -> Matrix { - var results = x - results.grid.withUnsafeMutableBufferPointer { pointer in - cblas_dscal(Int32(x.grid.count), alpha, pointer.baseAddress!, 1) - } +public func - (lhs: Matrix, rhs: Matrix) -> Matrix { + return sub(lhs, rhs) +} - return results +public func - (lhs: Matrix, rhs: Matrix) -> Matrix { + return sub(lhs, rhs) } -public func mul(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.columns == y.rows, "Matrix dimensions not compatible with multiplication") - if x.rows == 0 || x.columns == 0 || y.columns == 0 { - return Matrix(rows: x.rows, columns: y.columns, repeatedValue: 0.0) +// MARK: - Multiplication + +public func mul(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.columns == rhs.rows, "Matrix dimensions not compatible with multiplication") + if lhs.rows == 0 || lhs.columns == 0 || rhs.columns == 0 { + return Matrix(rows: lhs.rows, columns: rhs.columns, repeatedValue: 0.0) } - var results = Matrix(rows: x.rows, columns: y.columns, repeatedValue: 0.0) + var results = Matrix(rows: lhs.rows, columns: rhs.columns, repeatedValue: 0.0) results.grid.withUnsafeMutableBufferPointer { pointer in - cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, Int32(x.rows), Int32(y.columns), Int32(x.columns), 1.0, x.grid, Int32(x.columns), y.grid, Int32(y.columns), 0.0, pointer.baseAddress!, Int32(y.columns)) + cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, Int32(lhs.rows), Int32(rhs.columns), Int32(lhs.columns), 1.0, lhs.grid, Int32(lhs.columns), rhs.grid, Int32(rhs.columns), 0.0, pointer.baseAddress!, Int32(rhs.columns)) } return results } -public func mul(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.columns == y.rows, "Matrix dimensions not compatible with multiplication") - if x.rows == 0 || x.columns == 0 || y.columns == 0 { - return Matrix(rows: x.rows, columns: y.columns, repeatedValue: 0.0) +public func mul(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.columns == rhs.rows, "Matrix dimensions not compatible with multiplication") + if lhs.rows == 0 || lhs.columns == 0 || rhs.columns == 0 { + return Matrix(rows: lhs.rows, columns: rhs.columns, repeatedValue: 0.0) } - var results = Matrix(rows: x.rows, columns: y.columns, repeatedValue: 0.0) + var results = Matrix(rows: lhs.rows, columns: rhs.columns, repeatedValue: 0.0) results.grid.withUnsafeMutableBufferPointer { pointer in - cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, Int32(x.rows), Int32(y.columns), Int32(x.columns), 1.0, x.grid, Int32(x.columns), y.grid, Int32(y.columns), 0.0, pointer.baseAddress!, Int32(y.columns)) + cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, Int32(lhs.rows), Int32(rhs.columns), Int32(lhs.columns), 1.0, lhs.grid, Int32(lhs.columns), rhs.grid, Int32(rhs.columns), 0.0, pointer.baseAddress!, Int32(rhs.columns)) } return results } -public func mul(_ x: Matrix, _ y: Vector) -> Vector { - precondition(x.columns == y.dimensions, "Matrix and vector dimensions not compatible with multiplication") - if x.rows == 0 || x.columns == 0 || y.dimensions == 0 { - return Vector(dimensions: x.rows, repeatedValue: 0.0) +public func * (lhs: Matrix, rhs: Matrix) -> Matrix { + return mul(lhs, rhs) +} + +public func * (lhs: Matrix, rhs: Matrix) -> Matrix { + return mul(lhs, rhs) +} + +public func mul(_ lhs: Matrix, _ rhs: Vector) -> Vector { + precondition(lhs.columns == rhs.dimensions, "Matrix and vector dimensions not compatible with multiplication") + if lhs.rows == 0 || lhs.columns == 0 || rhs.dimensions == 0 { + return Vector(dimensions: lhs.rows, repeatedValue: 0.0) } - var results = Vector(dimensions: x.rows, repeatedValue: 0.0) + var results = Vector(dimensions: lhs.rows, repeatedValue: 0.0) results.scalars.withUnsafeMutableBufferPointer { pointer in - cblas_sgemv(CblasRowMajor, CblasNoTrans, Int32(x.rows), Int32(x.columns), 1.0, x.grid, Int32(x.columns), y.scalars, 1, 0.0, pointer.baseAddress!, 1) + cblas_sgemv(CblasRowMajor, CblasNoTrans, Int32(lhs.rows), Int32(lhs.columns), 1.0, lhs.grid, Int32(lhs.columns), rhs.scalars, 1, 0.0, pointer.baseAddress!, 1) } return results } -public func mul(_ x: Matrix, _ y: Vector) -> Vector { - precondition(x.columns == y.dimensions, "Matrix and vector dimensions not compatible with multiplication") - if x.rows == 0 || x.columns == 0 || y.dimensions == 0 { - return Vector(dimensions: y.dimensions, repeatedValue: 0.0) +public func mul(_ lhs: Matrix, _ rhs: Vector) -> Vector { + precondition(lhs.columns == rhs.dimensions, "Matrix and vector dimensions not compatible with multiplication") + if lhs.rows == 0 || lhs.columns == 0 || rhs.dimensions == 0 { + return Vector(dimensions: rhs.dimensions, repeatedValue: 0.0) } - var results = Vector(dimensions: x.rows, repeatedValue: 0.0) + var results = Vector(dimensions: lhs.rows, repeatedValue: 0.0) results.scalars.withUnsafeMutableBufferPointer { pointer in - cblas_dgemv(CblasRowMajor, CblasNoTrans, Int32(x.rows), Int32(x.columns), 1.0, x.grid, Int32(x.columns), y.scalars, 1, 0.0, pointer.baseAddress!, 1) + cblas_dgemv(CblasRowMajor, CblasNoTrans, Int32(lhs.rows), Int32(lhs.columns), 1.0, lhs.grid, Int32(lhs.columns), rhs.scalars, 1, 0.0, pointer.baseAddress!, 1) } return results } -public func mul(_ x: Vector, _ y: Matrix) -> Vector { - precondition(y.rows == x.dimensions, "Matrix and vector dimensions not compatible with multiplication") - if y.rows == 0 || y.columns == 0 || x.dimensions == 0 { - return Vector(dimensions: y.rows, repeatedValue: 0.0) - } +public func * (lhs: Matrix, rhs: Vector) -> Vector { + return mul(lhs, rhs) +} - var results = Vector(dimensions: y.columns, repeatedValue: 0.0) - results.scalars.withUnsafeMutableBufferPointer { pointer in - cblas_sgemv(CblasRowMajor, CblasTrans, Int32(y.rows), Int32(y.columns), 1.0, y.grid, Int32(y.columns), x.scalars, 1, 0.0, pointer.baseAddress!, 1) - } +public func * (lhs: Matrix, rhs: Vector) -> Vector { + return mul(lhs, rhs) +} - return results +// MARK: - Element-wise Multiplication + +public func elmul(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrix must have the same dimensions") + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = lhs.grid .* rhs.grid + return result } -public func mul(_ x: Vector, _ y: Matrix) -> Vector { - precondition(y.rows == x.dimensions, "Matrix and vector dimensions not compatible with multiplication") - if y.rows == 0 || y.columns == 0 || x.dimensions == 0 { - return Vector(dimensions: y.rows, repeatedValue: 0.0) - } +public func elmul(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + precondition(lhs.rows == rhs.rows && lhs.columns == rhs.columns, "Matrix must have the same dimensions") + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = lhs.grid .* rhs.grid + return result +} - var results = Vector(dimensions: y.columns, repeatedValue: 0.0) - results.scalars.withUnsafeMutableBufferPointer { pointer in - cblas_dgemv(CblasRowMajor, CblasTrans, Int32(y.rows), Int32(y.columns), 1.0, y.grid, Int32(y.columns), x.scalars, 1, 0.0, pointer.baseAddress!, 1) - } +// MARK: - Division - return results +public func div(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + let yInv = inv(rhs) + precondition(lhs.columns == yInv.rows, "Matrix dimensions not compatible") + return mul(lhs, yInv) +} + +public func div(_ lhs: Matrix, _ rhs: Matrix) -> Matrix { + let yInv = inv(rhs) + precondition(lhs.columns == yInv.rows, "Matrix dimensions not compatible") + return mul(lhs, yInv) } -public func elmul(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.rows == y.rows && x.columns == y.columns, "Matrix must have the same dimensions") - var result = Matrix(rows: x.rows, columns: x.columns, repeatedValue: 0.0) - result.grid = x.grid .* y.grid +public func / (lhs: Matrix, rhs: Matrix) -> Matrix { + return div(lhs, rhs) +} + +public func / (lhs: Matrix, rhs: Matrix) -> Matrix { + return div(lhs, rhs) +} + +public func div(_ lhs: Matrix, _ rhs: Double) -> Matrix { + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = lhs.grid / rhs return result } -public func elmul(_ x: Matrix, _ y: Matrix) -> Matrix { - precondition(x.rows == y.rows && x.columns == y.columns, "Matrix must have the same dimensions") - var result = Matrix(rows: x.rows, columns: x.columns, repeatedValue: 0.0) - result.grid = x.grid .* y.grid +public func div(_ lhs: Matrix, _ rhs: Float) -> Matrix { + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = lhs.grid / rhs return result } -public func div(_ x: Matrix, _ y: Matrix) -> Matrix { - let yInv = inv(y) - precondition(x.columns == yInv.rows, "Matrix dimensions not compatible") - return mul(x, yInv) +public func / (lhs: Matrix, rhs: Double) -> Matrix { + return div(lhs, rhs) } -public func div(_ x: Matrix, _ y: Matrix) -> Matrix { - let yInv = inv(y) - precondition(x.columns == yInv.rows, "Matrix dimensions not compatible") - return mul(x, yInv) +public func / (lhs: Matrix, rhs: Float) -> Matrix { + return div(lhs, rhs) } -public func pow(_ x: Matrix, _ y: Double) -> Matrix { - var result = Matrix(rows: x.rows, columns: x.columns, repeatedValue: 0.0) - result.grid = pow(x.grid, y) +// MARK: - Power + +public func pow(_ lhs: Matrix, _ rhs: Double) -> Matrix { + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = pow(lhs.grid, rhs) return result } -public func pow(_ x: Matrix, _ y: Float) -> Matrix { - var result = Matrix(rows: x.rows, columns: x.columns, repeatedValue: 0.0) - result.grid = pow(x.grid, y) +public func pow(_ lhs: Matrix, _ rhs: Float) -> Matrix { + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = pow(lhs.grid, rhs) return result } -public func exp(_ x: Matrix) -> Matrix { - var result = Matrix(rows: x.rows, columns: x.columns, repeatedValue: 0.0) - result.grid = exp(x.grid) +// MARK: - Exponential + +public func exp(_ lhs: Matrix) -> Matrix { + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = exp(lhs.grid) return result } -public func exp(_ x: Matrix) -> Matrix { - var result = Matrix(rows: x.rows, columns: x.columns, repeatedValue: 0.0) - result.grid = exp(x.grid) +public func exp(_ lhs: Matrix) -> Matrix { + var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + result.grid = exp(lhs.grid) return result } -public func sum(_ x: Matrix, axies: MatrixAxies = .column) -> Matrix { +// MARK: - Summation +public func sum(_ lhs: Matrix, axies: MatrixAxies = .column) -> Matrix { switch axies { case .column: - var result = Matrix(rows: 1, columns: x.columns, repeatedValue: 0.0) - for i in 0..(rows: 1, columns: lhs.columns, repeatedValue: 0.0) + for i in 0..(rows: x.rows, columns: 1, repeatedValue: 0.0) - for i in 0..(rows: lhs.rows, columns: 1, repeatedValue: 0.0) + for i in 0.., axies: MatrixAxies = .column) -> Matrix { - +public func sum(_ lhs: Matrix, axies: MatrixAxies = .column) -> Matrix { switch axies { case .column: - var result = Matrix(rows: 1, columns: x.columns, repeatedValue: 0.0) - for i in 0..(rows: 1, columns: lhs.columns, repeatedValue: 0.0) + for i in 0..(rows: x.rows, columns: 1, repeatedValue: 0.0) - for i in 0..(rows: lhs.rows, columns: 1, repeatedValue: 0.0) + for i in 0..) -> Matrix { - precondition(x.rows == x.columns, "Matrix must be square") +// MARK: - Inverse - var results = x +public func inv(_ lhs: Matrix) -> Matrix { + precondition(lhs.rows == lhs.columns, "Matrix must be square") - var ipiv = [__CLPK_integer](repeating: 0, count: x.rows * x.rows) - var lwork = __CLPK_integer(x.columns * x.columns) + var results = lhs + + var ipiv = [__CLPK_integer](repeating: 0, count: lhs.rows * lhs.rows) + var lwork = __CLPK_integer(lhs.columns * lhs.columns) var work = [CFloat](repeating: 0.0, count: Int(lwork)) var error: __CLPK_integer = 0 - var nc = __CLPK_integer(x.columns) + var nc = __CLPK_integer(lhs.columns) withUnsafeMutablePointers(&nc, &lwork, &error) { nc, lwork, error in withUnsafeMutableMemory(&ipiv, &work, &(results.grid)) { ipiv, work, grid in @@ -519,16 +545,16 @@ public func inv(_ x: Matrix) -> Matrix { return results } -public func inv(_ x: Matrix) -> Matrix { - precondition(x.rows == x.columns, "Matrix must be square") +public func inv(_ lhs: Matrix) -> Matrix { + precondition(lhs.rows == lhs.columns, "Matrix must be square") - var results = x + var results = lhs - var ipiv = [__CLPK_integer](repeating: 0, count: x.rows * x.rows) - var lwork = __CLPK_integer(x.columns * x.columns) + var ipiv = [__CLPK_integer](repeating: 0, count: lhs.rows * lhs.rows) + var lwork = __CLPK_integer(lhs.columns * lhs.columns) var work = [CDouble](repeating: 0.0, count: Int(lwork)) var error: __CLPK_integer = 0 - var nc = __CLPK_integer(x.columns) + var nc = __CLPK_integer(lhs.columns) withUnsafeMutablePointers(&nc, &lwork, &error) { nc, lwork, error in withUnsafeMutableMemory(&ipiv, &work, &(results.grid)) { ipiv, work, grid in @@ -542,31 +568,43 @@ public func inv(_ x: Matrix) -> Matrix { return results } -public func transpose(_ x: Matrix) -> Matrix { - var results = Matrix(rows: x.columns, columns: x.rows, repeatedValue: 0.0) +// MARK: - Transpose + +public func transpose(_ lhs: Matrix) -> Matrix { + var results = Matrix(rows: lhs.columns, columns: lhs.rows, repeatedValue: 0.0) results.grid.withUnsafeMutableBufferPointer { pointer in - vDSP_mtrans(x.grid, 1, pointer.baseAddress!, 1, vDSP_Length(x.columns), vDSP_Length(x.rows)) + vDSP_mtrans(lhs.grid, 1, pointer.baseAddress!, 1, vDSP_Length(lhs.columns), vDSP_Length(lhs.rows)) } return results } -public func transpose(_ x: Matrix) -> Matrix { - var results = Matrix(rows: x.columns, columns: x.rows, repeatedValue: 0.0) +public func transpose(_ lhs: Matrix) -> Matrix { + var results = Matrix(rows: lhs.columns, columns: lhs.rows, repeatedValue: 0.0) results.grid.withUnsafeMutableBufferPointer { pointer in - vDSP_mtransD(x.grid, 1, pointer.baseAddress!, 1, vDSP_Length(x.columns), vDSP_Length(x.rows)) + vDSP_mtransD(lhs.grid, 1, pointer.baseAddress!, 1, vDSP_Length(lhs.columns), vDSP_Length(lhs.rows)) } return results } +public postfix func ′ (value: Matrix) -> Matrix { + return transpose(value) +} + +public postfix func ′ (value: Matrix) -> Matrix { + return transpose(value) +} + +// MARK: - Determinant + /// Computes the matrix determinant. -public func det(_ x: Matrix) -> Float? { - var decomposed = x - var pivots = [__CLPK_integer](repeating: 0, count: min(x.rows, x.columns)) +public func det(_ lhs: Matrix) -> Float? { + var decomposed = lhs + var pivots = [__CLPK_integer](repeating: 0, count: min(lhs.rows, lhs.columns)) var info = __CLPK_integer() - var m = __CLPK_integer(x.rows) - var n = __CLPK_integer(x.columns) + var m = __CLPK_integer(lhs.rows) + var n = __CLPK_integer(lhs.columns) _ = withUnsafeMutableMemory(&pivots, &(decomposed.grid)) { ipiv, grid in withUnsafeMutablePointers(&m, &n, &info) { m, n, info in sgetrf_(m, n, grid.pointer, m, ipiv.pointer, info) @@ -589,12 +627,12 @@ public func det(_ x: Matrix) -> Float? { } /// Computes the matrix determinant. -public func det(_ x: Matrix) -> Double? { - var decomposed = x - var pivots = [__CLPK_integer](repeating: 0, count: min(x.rows, x.columns)) +public func det(_ lhs: Matrix) -> Double? { + var decomposed = lhs + var pivots = [__CLPK_integer](repeating: 0, count: min(lhs.rows, lhs.columns)) var info = __CLPK_integer() - var m = __CLPK_integer(x.rows) - var n = __CLPK_integer(x.columns) + var m = __CLPK_integer(lhs.rows) + var n = __CLPK_integer(lhs.columns) _ = withUnsafeMutableMemory(&pivots, &(decomposed.grid)) { ipiv, grid in withUnsafeMutablePointers(&m, &n, &info) { m, n, info in dgetrf_(m, n, grid.pointer, m, ipiv.pointer, info) @@ -616,6 +654,8 @@ public func det(_ x: Matrix) -> Double? { return det } +// MARK: - Eigen-Decomposition + // Convert the result of dgeev into an array of complex numbers // See Intel's documentation on column-major results for sample code that this // is based on: @@ -645,12 +685,12 @@ private func buildEigenVector /// The decomposition may result in complex numbers, represented by (Float, Float), which /// are the (real, imaginary) parts of the complex number. /// - Parameters: -/// - x: a square matrix +/// - lhs: a square matrix /// - Returns: a struct with the eigen values and left and right eigen vectors using (Float, Float) /// to represent a complex number. -public func eigenDecompose(_ x: Matrix) throws -> MatrixEigenDecompositionResult { - var input = Matrix(rows: x.rows, columns: x.columns, repeatedValue: 0.0) - input.grid = x.grid.map { Double($0) } +public func eigenDecompose(_ lhs: Matrix) throws -> MatrixEigenDecompositionResult { + var input = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) + input.grid = lhs.grid.map { Double($0) } let decomposition = try eigenDecompose(input) return MatrixEigenDecompositionResult( @@ -664,17 +704,17 @@ public func eigenDecompose(_ x: Matrix) throws -> MatrixEigenDecompositio /// The decomposition may result in complex numbers, represented by (Double, Double), which /// are the (real, imaginary) parts of the complex number. /// - Parameters: -/// - x: a square matrix +/// - lhs: a square matrix /// - Returns: a struct with the eigen values and left and right eigen vectors using (Double, Double) /// to represent a complex number. -public func eigenDecompose(_ x: Matrix) throws -> MatrixEigenDecompositionResult { - guard x.rows == x.columns else { +public func eigenDecompose(_ lhs: Matrix) throws -> MatrixEigenDecompositionResult { + guard lhs.rows == lhs.columns else { throw EigenDecompositionError.matrixNotSquare } - // dgeev_ needs column-major matrices, so transpose x. - var matrixGrid: [__CLPK_doublereal] = transpose(x).grid - var matrixRowCount = __CLPK_integer(x.rows) + // dgeev_ needs column-major matrices, so transpose lhs. + var matrixGrid: [__CLPK_doublereal] = transpose(lhs).grid + var matrixRowCount = __CLPK_integer(lhs.rows) let matrixColCount = matrixRowCount var eigenValueCount = matrixRowCount var leftEigenVectorCount = matrixRowCount @@ -704,92 +744,5 @@ public func eigenDecompose(_ x: Matrix) throws -> MatrixEigenDecompositi throw EigenDecompositionError.matrixNotDecomposable } - return MatrixEigenDecompositionResult(rowCount: x.rows, eigenValueRealParts: eigenValueRealParts, eigenValueImaginaryParts: eigenValueImaginaryParts, leftEigenVectorWork: leftEigenVectorWork, rightEigenVectorWork: rightEigenVectorWork) -} - -// MARK: - Operators - -public func + (lhs: Matrix, rhs: Matrix) -> Matrix { - return add(lhs, rhs) -} - -public func + (lhs: Matrix, rhs: Matrix) -> Matrix { - return add(lhs, rhs) -} - -public func - (lhs: Matrix, rhs: Matrix) -> Matrix { - return sub(lhs, rhs) -} - -public func - (lhs: Matrix, rhs: Matrix) -> Matrix { - return sub(lhs, rhs) -} - -public func + (lhs: Matrix, rhs: Float) -> Matrix { - return Matrix(rows: lhs.rows, columns: lhs.columns, grid: lhs.grid + rhs) -} - -public func + (lhs: Matrix, rhs: Double) -> Matrix { - return Matrix(rows: lhs.rows, columns: lhs.columns, grid: lhs.grid + rhs) -} - -public func * (lhs: Float, rhs: Matrix) -> Matrix { - return mul(lhs, rhs) -} - -public func * (lhs: Double, rhs: Matrix) -> Matrix { - return mul(lhs, rhs) -} - -public func * (lhs: Matrix, rhs: Matrix) -> Matrix { - return mul(lhs, rhs) -} - -public func * (lhs: Matrix, rhs: Matrix) -> Matrix { - return mul(lhs, rhs) -} - -public func * (lhs: Matrix, rhs: Vector) -> Vector { - return mul(lhs, rhs) -} - -public func * (lhs: Matrix, rhs: Vector) -> Vector { - return mul(lhs, rhs) -} - -public func * (lhs: Vector, rhs: Matrix) -> Vector { - return mul(lhs, rhs) -} - -public func * (lhs: Vector, rhs: Matrix) -> Vector { - return mul(lhs, rhs) -} - -public func / (lhs: Matrix, rhs: Matrix) -> Matrix { - return div(lhs, rhs) -} - -public func / (lhs: Matrix, rhs: Matrix) -> Matrix { - return div(lhs, rhs) -} - -public func / (lhs: Matrix, rhs: Double) -> Matrix { - var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) - result.grid = lhs.grid / rhs - return result -} - -public func / (lhs: Matrix, rhs: Float) -> Matrix { - var result = Matrix(rows: lhs.rows, columns: lhs.columns, repeatedValue: 0.0) - result.grid = lhs.grid / rhs - return result -} - -postfix operator ′ -public postfix func ′ (value: Matrix) -> Matrix { - return transpose(value) -} - -public postfix func ′ (value: Matrix) -> Matrix { - return transpose(value) + return MatrixEigenDecompositionResult(rowCount: lhs.rows, eigenValueRealParts: eigenValueRealParts, eigenValueImaginaryParts: eigenValueImaginaryParts, leftEigenVectorWork: leftEigenVectorWork, rightEigenVectorWork: rightEigenVectorWork) } diff --git a/Sources/Surge/Linear Algebra/Scalar.swift b/Sources/Surge/Linear Algebra/Scalar.swift new file mode 100644 index 00000000..99e7ea3b --- /dev/null +++ b/Sources/Surge/Linear Algebra/Scalar.swift @@ -0,0 +1,81 @@ +// Copyright © 2014-2019 the Surge contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Accelerate + +// MARK: - Multiplication + +public func mul(_ lhs: Float, _ rhs: R) -> [Float] where R.Element == Float { + return mul([Float](repeating: lhs, count: numericCast(rhs.count)), rhs) +} + +public func mul(_ lhs: Double, _ rhs: R) -> [Double] where R.Element == Double { + return mul([Double](repeating: lhs, count: numericCast(rhs.count)), rhs) +} + +public func * (lhs: Float, rhs: R) -> [Float] where R.Element == Float { + return mul(lhs, rhs) +} + +public func * (lhs: Double, rhs: R) -> [Double] where R.Element == Double { + return mul(lhs, rhs) +} + +public func mul(_ lhs: Float, _ rhs: Vector) -> Vector { + return Vector(mul(lhs, rhs.scalars)) +} + +public func mul(_ lhs: Double, _ rhs: Vector) -> Vector { + return Vector(mul(lhs, rhs.scalars)) +} + +public func * (lhs: Float, rhs: Vector) -> Vector { + return mul(lhs, rhs) +} + +public func * (lhs: Double, rhs: Vector) -> Vector { + return mul(lhs, rhs) +} + +public func mul(_ lhs: Float, _ rhs: Matrix) -> Matrix { + var results = rhs + results.grid.withUnsafeMutableBufferPointer { pointer in + cblas_sscal(Int32(rhs.grid.count), lhs, pointer.baseAddress!, 1) + } + + return results +} + +public func mul(_ lhs: Double, _ rhs: Matrix) -> Matrix { + var results = rhs + results.grid.withUnsafeMutableBufferPointer { pointer in + cblas_dscal(Int32(rhs.grid.count), lhs, pointer.baseAddress!, 1) + } + + return results +} + +public func * (lhs: Float, rhs: Matrix) -> Matrix { + return mul(lhs, rhs) +} + +public func * (lhs: Double, rhs: Matrix) -> Matrix { + return mul(lhs, rhs) +} diff --git a/Sources/Surge/Linear Algebra/Vector.swift b/Sources/Surge/Linear Algebra/Vector.swift new file mode 100644 index 00000000..fbb73e9a --- /dev/null +++ b/Sources/Surge/Linear Algebra/Vector.swift @@ -0,0 +1,525 @@ +// Copyright © 2014-2018 the contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Accelerate + +public struct Vector where Scalar: FloatingPoint, Scalar: ExpressibleByFloatLiteral { + public let dimensions: Int + + public var scalars: [Scalar] { + didSet { + precondition(self.scalars.count == self.dimensions) + } + } + + // MARK: - Initialize + + public init(dimensions: Int, repeatedValue: Scalar) { + let scalars = Array(repeating: repeatedValue, count: dimensions) + self.init(scalars) + } + + public init(_ contents: T) where T.Element == Scalar { + let scalars: [Scalar] + if let array = contents as? [Scalar] { + scalars = array + } else { + scalars = Array(contents) + } + self.dimensions = scalars.count + self.scalars = scalars + } +} + +// MARK: - ExpressibleByArrayLiteral + +extension Vector: ExpressibleByArrayLiteral { + public init(arrayLiteral elements: Scalar...) { + self.init(elements) + } +} + +// MARK: - CustomStringConvertible + +extension Vector: CustomStringConvertible { + public var description: String { + return self.scalars.map({ "\($0)" }).joined(separator: "\t") + } +} + +// MARK: - Sequence + +extension Vector: Sequence { + public func makeIterator() -> AnyIterator { + return AnyIterator(self.scalars.makeIterator()) + } +} + +// MARK: - Collection + +extension Vector: Collection { + public subscript(_ dimension: Int) -> Scalar { + get { + return self.scalars[dimension] + } + + set { + self.scalars[dimension] = newValue + } + } + + public var startIndex: Int { + return self.scalars.startIndex + } + + public var endIndex: Int { + return self.scalars.endIndex + } + + public func index(after i: Int) -> Int { + return self.scalars.index(after: i) + } +} + +// MARK: - Equatable + +extension Vector: Equatable {} +public func == (lhs: Vector, rhs: Vector) -> Bool { + return lhs.scalars == rhs.scalars +} + +// MARK: - Addition + +public func add(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with addition") + + return Vector(add(lhs.scalars, rhs.scalars)) +} + +public func add(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with addition") + + return Vector(add(lhs.scalars, rhs.scalars)) +} + +public func + (lhs: Vector, rhs: Vector) -> Vector { + return add(lhs, rhs) +} + +public func + (lhs: Vector, rhs: Vector) -> Vector { + return add(lhs, rhs) +} + +public func add(_ lhs: Vector, _ rhs: Float) -> Vector { + return Vector(add(lhs.scalars, rhs)) +} + +public func add(_ lhs: Vector, _ rhs: Double) -> Vector { + return Vector(add(lhs.scalars, rhs)) +} + +public func + (lhs: Vector, rhs: Float) -> Vector { + return add(lhs, rhs) +} + +public func + (lhs: Vector, rhs: Double) -> Vector { + return add(lhs, rhs) +} + +// MARK: - Addition: In Place + +public func addInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with addition") + + return addInPlace(&lhs.scalars, rhs.scalars) +} + +public func addInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with addition") + + return addInPlace(&lhs.scalars, rhs.scalars) +} + +public func += (lhs: inout Vector, rhs: Vector) { + return addInPlace(&lhs, rhs) +} + +public func += (lhs: inout Vector, rhs: Vector) { + return addInPlace(&lhs, rhs) +} + +public func addInPlace(_ lhs: inout Vector, _ rhs: Float) { + return addInPlace(&lhs.scalars, rhs) +} + +public func addInPlace(_ lhs: inout Vector, _ rhs: Double) { + return addInPlace(&lhs.scalars, rhs) +} + +public func += (lhs: inout Vector, rhs: Float) { + return addInPlace(&lhs, rhs) +} + +public func += (lhs: inout Vector, rhs: Double) { + return addInPlace(&lhs, rhs) +} + +// MARK: - Subtraction + +public func sub(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with subtraction") + + return Vector(sub(lhs.scalars, rhs.scalars)) +} + +public func sub(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with subtraction") + + return Vector(sub(lhs.scalars, rhs.scalars)) +} + +public func - (lhs: Vector, rhs: Vector) -> Vector { + return sub(lhs, rhs) +} + +public func - (lhs: Vector, rhs: Vector) -> Vector { + return sub(lhs, rhs) +} + +public func sub(_ lhs: Vector, _ rhs: Float) -> Vector { + return Vector(sub(lhs.scalars, rhs)) +} + +public func sub(_ lhs: Vector, _ rhs: Double) -> Vector { + return Vector(sub(lhs.scalars, rhs)) +} + +public func - (lhs: Vector, rhs: Float) -> Vector { + return sub(lhs, rhs) +} + +public func - (lhs: Vector, rhs: Double) -> Vector { + return sub(lhs, rhs) +} + +// MARK: - Subtraction: In Place + +public func subInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with subtraction") + + return subInPlace(&lhs.scalars, rhs.scalars) +} + +public func subInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with subtraction") + + return subInPlace(&lhs.scalars, rhs.scalars) +} + +public func -= (lhs: inout Vector, rhs: Vector) { + return subInPlace(&lhs, rhs) +} + +public func -= (lhs: inout Vector, rhs: Vector) { + return subInPlace(&lhs, rhs) +} + +public func subInPlace(_ lhs: inout Vector, _ rhs: Float) { + return subInPlace(&lhs.scalars, rhs) +} + +public func subInPlace(_ lhs: inout Vector, _ rhs: Double) { + return subInPlace(&lhs.scalars, rhs) +} + +public func -= (lhs: inout Vector, rhs: Float) { + return subInPlace(&lhs, rhs) +} + +public func -= (lhs: inout Vector, rhs: Double) { + return subInPlace(&lhs, rhs) +} + +// MARK: - Multiplication + +public func mul(_ lhs: Vector, _ rhs: Float) -> Vector { + return Vector(mul(lhs.scalars, rhs)) +} + +public func mul(_ lhs: Vector, _ rhs: Double) -> Vector { + return Vector(mul(lhs.scalars, rhs)) +} + +public func * (lhs: Vector, rhs: Float) -> Vector { + return mul(lhs, rhs) +} + +public func * (lhs: Vector, rhs: Double) -> Vector { + return mul(lhs, rhs) +} + +public func mul(_ lhs: Vector, _ rhs: Matrix) -> Vector { + precondition(rhs.rows == lhs.dimensions, "Matrix and vector dimensions not compatible with multiplication") + if rhs.rows == 0 || rhs.columns == 0 || lhs.dimensions == 0 { + return Vector(dimensions: rhs.rows, repeatedValue: 0.0) + } + + var results = Vector(dimensions: rhs.columns, repeatedValue: 0.0) + results.scalars.withUnsafeMutableBufferPointer { pointer in + cblas_sgemv(CblasRowMajor, CblasTrans, Int32(rhs.rows), Int32(rhs.columns), 1.0, rhs.grid, Int32(rhs.columns), lhs.scalars, 1, 0.0, pointer.baseAddress!, 1) + } + + return results +} + +public func mul(_ lhs: Vector, _ rhs: Matrix) -> Vector { + precondition(rhs.rows == lhs.dimensions, "Matrix and vector dimensions not compatible with multiplication") + if rhs.rows == 0 || rhs.columns == 0 || lhs.dimensions == 0 { + return Vector(dimensions: rhs.rows, repeatedValue: 0.0) + } + + var results = Vector(dimensions: rhs.columns, repeatedValue: 0.0) + results.scalars.withUnsafeMutableBufferPointer { pointer in + cblas_dgemv(CblasRowMajor, CblasTrans, Int32(rhs.rows), Int32(rhs.columns), 1.0, rhs.grid, Int32(rhs.columns), lhs.scalars, 1, 0.0, pointer.baseAddress!, 1) + } + + return results +} + +public func * (lhs: Vector, rhs: Matrix) -> Vector { + return mul(lhs, rhs) +} + +public func * (lhs: Vector, rhs: Matrix) -> Vector { + return mul(lhs, rhs) +} + +// MARK: - Multiplication: In Place + +public func mulInPlace(_ lhs: inout Vector, _ rhs: Float) { + return mulInPlace(&lhs.scalars, rhs) +} + +public func mulInPlace(_ lhs: inout Vector, _ rhs: Double) { + return mulInPlace(&lhs.scalars, rhs) +} + +public func *= (lhs: inout Vector, rhs: Float) { + return mulInPlace(&lhs, rhs) +} + +public func *= (lhs: inout Vector, rhs: Double) { + return mulInPlace(&lhs, rhs) +} + +// MARK: - Division + +public func div(_ lhs: Vector, _ rhs: Float) -> Vector { + return Vector(div(lhs.scalars, rhs)) +} + +public func div(_ lhs: Vector, _ rhs: Double) -> Vector { + return Vector(div(lhs.scalars, rhs)) +} + +public func / (lhs: Vector, rhs: Double) -> Vector { + return div(lhs, rhs) +} + +public func / (lhs: Vector, rhs: Float) -> Vector { + return div(lhs, rhs) +} + +// MARK: - Division: In Place + +public func divInPlace(_ lhs: inout Vector, _ rhs: Float) { + return divInPlace(&lhs.scalars, rhs) +} + +public func divInPlace(_ lhs: inout Vector, _ rhs: Double) { + return divInPlace(&lhs.scalars, rhs) +} + +public func /= (lhs: inout Vector, rhs: Float) { + return divInPlace(&lhs, rhs) +} + +public func /= (lhs: inout Vector, rhs: Double) { + return divInPlace(&lhs, rhs) +} + +// MARK: - Element-wise Multiplication + +public func elmul(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise multiplication") + + return Vector(mul(lhs.scalars, rhs.scalars)) +} + +public func elmul(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise multiplication") + + return Vector(mul(lhs.scalars, rhs.scalars)) +} + +public func .* (lhs: Vector, rhs: Vector) -> Vector { + return elmul(lhs, rhs) +} + +public func .* (lhs: Vector, rhs: Vector) -> Vector { + return elmul(lhs, rhs) +} + +// MARK: - Element-wise Multiplication: In Place + +public func elmulInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise multiplication") + + return mulInPlace(&lhs.scalars, rhs.scalars) +} + +public func elmulInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise multiplication") + + return mulInPlace(&lhs.scalars, rhs.scalars) +} + +public func .*= (lhs: inout Vector, rhs: Vector) { + return elmulInPlace(&lhs, rhs) +} + +public func .*= (lhs: inout Vector, rhs: Vector) { + return elmulInPlace(&lhs, rhs) +} + +// MARK: - Element-wise Division + +public func eldiv(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise division") + + return Vector(div(lhs.scalars, rhs.scalars)) +} + +public func eldiv(_ lhs: Vector, _ rhs: Vector) -> Vector { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise division") + + return Vector(div(lhs.scalars, rhs.scalars)) +} + +public func ./ (lhs: Vector, rhs: Vector) -> Vector { + return eldiv(lhs, rhs) +} + +public func ./ (lhs: Vector, rhs: Vector) -> Vector { + return eldiv(lhs, rhs) +} + +// MARK: - Element-wise Division: In Place + +public func eldivInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise division") + + return divInPlace(&lhs.scalars, rhs.scalars) +} + +public func eldivInPlace(_ lhs: inout Vector, _ rhs: Vector) { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with element-wise division") + + return divInPlace(&lhs.scalars, rhs.scalars) +} + +public func ./= (lhs: inout Vector, rhs: Vector) { + return eldivInPlace(&lhs, rhs) +} + +public func ./= (lhs: inout Vector, rhs: Vector) { + return eldivInPlace(&lhs, rhs) +} + +// MARK: - Dot Product + +public func dot(_ lhs: Vector, _ rhs: Vector) -> Double { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with dot product") + + return dot(lhs.scalars, rhs.scalars) +} + +public func dot(_ lhs: Vector, _ rhs: Vector) -> Float { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with dot product") + + return dot(lhs.scalars, rhs.scalars) +} + +infix operator •: MultiplicationPrecedence +public func • (lhs: Vector, rhs: Vector) -> Double { + return dot(lhs, rhs) +} + +public func • (lhs: Vector, rhs: Vector) -> Float { + return dot(lhs, rhs) +} + +// MARK: - Power + +public func pow(_ lhs: Vector, _ rhs: Double) -> Vector { + return Vector(pow(lhs.scalars, rhs)) +} + +public func pow(_ lhs: Vector, _ rhs: Float) -> Vector { + return Vector(pow(lhs.scalars, rhs)) +} + +// MARK: - Exponential + +public func exp(_ lhs: Vector) -> Vector { + return Vector(exp(lhs.scalars)) +} + +public func exp(_ lhs: Vector) -> Vector { + return Vector(exp(lhs.scalars)) +} + +// MARK: - Distance + +public func dist(_ lhs: Vector, _ rhs: Vector) -> Double { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with distance calculation") + + return dist(lhs.scalars, rhs.scalars) +} + +public func dist(_ lhs: Vector, _ rhs: Vector) -> Float { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with distance calculation") + + return dist(lhs.scalars, rhs.scalars) +} + +// MARK: - Distance Squared + +public func distSq(_ lhs: Vector, _ rhs: Vector) -> Double { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with distance calculation") + + return distSq(lhs.scalars, rhs.scalars) +} + +public func distSq(_ lhs: Vector, _ rhs: Vector) -> Float { + precondition(lhs.dimensions == rhs.dimensions, "Vector dimensions not compatible with distance calculation") + + return distSq(lhs.scalars, rhs.scalars) +} diff --git a/Sources/Surge/Exponential.swift b/Sources/Surge/Logarithm/Logarithm.swift similarity index 68% rename from Sources/Surge/Exponential.swift rename to Sources/Surge/Logarithm/Logarithm.swift index 6bc92e79..bfa7f3d5 100644 --- a/Sources/Surge/Exponential.swift +++ b/Sources/Surge/Logarithm/Logarithm.swift @@ -20,59 +20,7 @@ import Accelerate -// MARK: Exponentiation - -/// - Warning: does not support memory stride (assumes stride is 1). -public func exp(_ x: X) -> [Float] where X.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvexpf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func exp(_ x: X) -> [Double] where X.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvexp(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -// MARK: Square Exponentiation - -/// - Warning: does not support memory stride (assumes stride is 1). -public func exp2(_ x: X) -> [Float] where X.Element == Float { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Float](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvexp2f(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -/// - Warning: does not support memory stride (assumes stride is 1). -public func exp2(_ x: X) -> [Double] where X.Element == Double { - return x.withUnsafeMemory { xm in - precondition(xm.stride == 1, "\(#function) does not support strided memory access") - var results = [Double](repeating: 0.0, count: numericCast(x.count)) - results.withUnsafeMutableBufferPointer { rbp in - vvexp2(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) - } - return results - } -} - -// MARK: Natural Logarithm +// MARK: - Natural Logarithm /// - Warning: does not support memory stride (assumes stride is 1). public func log(_ x: X) -> [Float] where X.Element == Float { @@ -98,7 +46,7 @@ public func log(_ x: X) -> [Double] where X.Element = } } -// MARK: Base-2 Logarithm +// MARK: - Base-2 Logarithm /// - Warning: does not support memory stride (assumes stride is 1). public func log2(_ x: X) -> [Float] where X.Element == Float { @@ -124,7 +72,7 @@ public func log2(_ x: X) -> [Double] where X.Element } } -// MARK: Base-10 Logarithm +// MARK: - Base-10 Logarithm /// - Warning: does not support memory stride (assumes stride is 1). public func log10(_ x: X) -> [Float] where X.Element == Float { @@ -150,7 +98,7 @@ public func log10(_ x: X) -> [Double] where X.Element } } -// MARK: Logarithmic Exponentiation +// MARK: - Logarithmic Exponentiation /// - Warning: does not support memory stride (assumes stride is 1). public func logb(_ x: X) -> [Float] where X.Element == Float { diff --git a/Sources/Surge/Statistics.swift b/Sources/Surge/Statistics/Statistics.swift similarity index 62% rename from Sources/Surge/Statistics.swift rename to Sources/Surge/Statistics/Statistics.swift index 5dae45ad..d07fe030 100644 --- a/Sources/Surge/Statistics.swift +++ b/Sources/Surge/Statistics/Statistics.swift @@ -20,11 +20,11 @@ import Accelerate -// MARK: Sum +// MARK: - Sum -public func sum(_ x: C) -> Float where C.Element == Float { +public func sum(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_sve(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -32,9 +32,9 @@ public func sum(_ x: C) -> Float where C.Element == F return result } -public func sum(_ x: C) -> Double where C.Element == Double { +public func sum(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_sveD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -42,25 +42,25 @@ public func sum(_ x: C) -> Double where C.Element == return result } -// MARK: Sum of Absolute Values +// MARK: - Sum of Absolute Values -public func asum(_ x: C) -> Float where C.Element == Float { - return x.withUnsafeMemory { xm in +public func asum(_ lhs: C) -> Float where C.Element == Float { + return lhs.withUnsafeMemory { xm in cblas_sasum(numericCast(xm.count), xm.pointer, numericCast(xm.stride)) } } -public func asum(_ x: C) -> Double where C.Element == Double { - return x.withUnsafeMemory { xm in +public func asum(_ lhs: C) -> Double where C.Element == Double { + return lhs.withUnsafeMemory { xm in cblas_dasum(numericCast(xm.count), xm.pointer, numericCast(xm.stride)) } } -// MARK: Sum of Square Values +// MARK: - Sum of Square Values -public func sumsq(_ x: C) -> Float where C.Element == Float { +public func sumsq(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_svesq(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -68,9 +68,9 @@ public func sumsq(_ x: C) -> Float where C.Element == return result } -public func sumsq(_ x: C) -> Double where C.Element == Double { +public func sumsq(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_svesqD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -78,11 +78,11 @@ public func sumsq(_ x: C) -> Double where C.Element = return result } -// MARK: Maximum +// MARK: - Maximum -public func max(_ x: C) -> Float where C.Element == Float { +public func max(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_maxv(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -90,9 +90,9 @@ public func max(_ x: C) -> Float where C.Element == F return result } -public func max(_ x: C) -> Double where C.Element == Double { +public func max(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_maxvD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -100,11 +100,11 @@ public func max(_ x: C) -> Double where C.Element == return result } -// MARK: Minimum +// MARK: - Minimum -public func min(_ x: C) -> Float where C.Element == Float { +public func min(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_minv(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -112,9 +112,9 @@ public func min(_ x: C) -> Float where C.Element == F return result } -public func min(_ x: C) -> Double where C.Element == Double { +public func min(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_minvD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -122,11 +122,11 @@ public func min(_ x: C) -> Double where C.Element == return result } -// MARK: Mean +// MARK: - Mean -public func mean(_ x: C) -> Float where C.Element == Float { +public func mean(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_meanv(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -134,9 +134,9 @@ public func mean(_ x: C) -> Float where C.Element == return result } -public func mean(_ x: C) -> Double where C.Element == Double { +public func mean(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_meanvD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -144,11 +144,11 @@ public func mean(_ x: C) -> Double where C.Element == return result } -// MARK: Mean Magnitude +// MARK: - Mean Magnitude -public func meamg(_ x: C) -> Float where C.Element == Float { +public func meamg(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_meamgv(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -156,9 +156,9 @@ public func meamg(_ x: C) -> Float where C.Element == return result } -public func meamg(_ x: C) -> Double where C.Element == Double { +public func meamg(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_meamgvD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -166,11 +166,11 @@ public func meamg(_ x: C) -> Double where C.Element = return result } -// MARK: Mean Square Value +// MARK: - Mean Square Value -public func measq(_ x: C) -> Float where C.Element == Float { +public func measq(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_measqv(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -178,9 +178,9 @@ public func measq(_ x: C) -> Float where C.Element == return result } -public func measq(_ x: C) -> Double where C.Element == Double { +public func measq(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_measqvD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -188,11 +188,11 @@ public func measq(_ x: C) -> Double where C.Element = return result } -// MARK: Root Mean Square Value +// MARK: - Root Mean Square Value -public func rmsq(_ x: C) -> Float where C.Element == Float { +public func rmsq(_ lhs: C) -> Float where C.Element == Float { var result: Float = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_rmsqv(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -200,9 +200,9 @@ public func rmsq(_ x: C) -> Float where C.Element == return result } -public func rmsq(_ x: C) -> Double where C.Element == Double { +public func rmsq(_ lhs: C) -> Double where C.Element == Double { var result: Double = 0.0 - x.withUnsafeMemory { xm in + lhs.withUnsafeMemory { xm in withUnsafeMutablePointer(to: &result) { pointer in vDSP_rmsqvD(xm.pointer, numericCast(xm.stride), pointer, numericCast(xm.count)) } @@ -210,36 +210,36 @@ public func rmsq(_ x: C) -> Double where C.Element == return result } -// MARK: Standard deviation +// MARK: - Standard deviation /// Computes the standard deviation, a measure of the spread of deviation. -public func std(_ x: X) -> Float where X.Element == Float { - let diff = x - mean(x) +public func std(_ lhs: L) -> Float where L.Element == Float { + let diff = lhs - mean(lhs) let variance = measq(diff) return sqrt(variance) } /// Computes the standard deviation, a measure of the spread of deviation. -public func std(_ x: X) -> Double where X.Element == Double { - let diff = x - mean(x) +public func std(_ lhs: L) -> Double where L.Element == Double { + let diff = lhs - mean(lhs) let variance = measq(diff) return sqrt(variance) } -// MARK: Linear regression +// MARK: - Linear regression /// Performs linear regression /// /// - Parameters: -/// - x: Array of x-values -/// - y: Array of y-values +/// - lhs: Array of lhs-values +/// - rhs: Array of rhs-values /// - Returns: The slope and intercept of the regression line -public func linregress(_ x: X, _ y: Y) -> (slope: Float, intercept: Float) where X.Element == Float, Y.Element == Float { - precondition(x.count == y.count, "Vectors must have equal count") - let meanx = mean(x) - let meany = mean(y) - let meanxy = mean(x .* y) - let meanx_sqr = measq(x) +public func linregress(_ lhs: L, _ rhs: R) -> (slope: Float, intercept: Float) where L.Element == Float, R.Element == Float { + precondition(lhs.count == rhs.count, "Vectors must have equal count") + let meanx = mean(lhs) + let meany = mean(rhs) + let meanxy = mean(lhs .* rhs) + let meanx_sqr = measq(lhs) let slope = (meanx * meany - meanxy) / (meanx * meanx - meanx_sqr) let intercept = meany - slope * meanx @@ -249,15 +249,15 @@ public func linregress(_ x /// Performs linear regression /// /// - Parameters: -/// - x: Array of x-values -/// - y: Array of y-values +/// - lhs: Array of lhs-values +/// - rhs: Array of rhs-values /// - Returns: The slope and intercept of the regression line -public func linregress(_ x: X, _ y: Y) -> (slope: Double, intercept: Double) where X.Element == Double, Y.Element == Double { - precondition(x.count == y.count, "Vectors must have equal count") - let meanx = mean(x) - let meany = mean(y) - let meanxy = mean(x .* y) - let meanx_sqr = measq(x) +public func linregress(_ lhs: L, _ rhs: R) -> (slope: Double, intercept: Double) where L.Element == Double, R.Element == Double { + precondition(lhs.count == rhs.count, "Vectors must have equal count") + let meanx = mean(lhs) + let meany = mean(rhs) + let meanxy = mean(lhs .* rhs) + let meanx_sqr = measq(lhs) let slope = (meanx * meany - meanxy) / (meanx * meanx - meanx_sqr) let intercept = meany - slope * meanx diff --git a/Sources/Surge/Trigonometric.swift b/Sources/Surge/Trigonometry/Trigonometric.swift similarity index 62% rename from Sources/Surge/Trigonometric.swift rename to Sources/Surge/Trigonometry/Trigonometric.swift index f18f57ff..9f43e8c1 100644 --- a/Sources/Surge/Trigonometric.swift +++ b/Sources/Surge/Trigonometry/Trigonometric.swift @@ -20,7 +20,7 @@ import Accelerate -// MARK: Sine-Cosine +// MARK: - Sine-Cosine /// - Warning: does not support memory stride (assumes stride is 1). public func sincos(_ x: X) -> (sin: [Float], cos: [Float]) where X.Element == Float { @@ -48,7 +48,7 @@ public func sincos(_ x: X) -> (sin: [Double], cos: [D } } -// MARK: Sine +// MARK: - Sine /// - Warning: does not support memory stride (assumes stride is 1). public func sin(_ x: X) -> [Float] where X.Element == Float { @@ -74,7 +74,7 @@ public func sin(_ x: X) -> [Double] where X.Element = } } -// MARK: Cosine +// MARK: - Cosine /// - Warning: does not support memory stride (assumes stride is 1). public func cos(_ x: X) -> [Float] where X.Element == Float { @@ -100,7 +100,7 @@ public func cos(_ x: X) -> [Double] where X.Element = } } -// MARK: Tangent +// MARK: - Tangent /// - Warning: does not support memory stride (assumes stride is 1). public func tan(_ x: X) -> [Float] where X.Element == Float { @@ -126,7 +126,7 @@ public func tan(_ x: X) -> [Double] where X.Element = } } -// MARK: Arcsine +// MARK: - Arcsine /// - Warning: does not support memory stride (assumes stride is 1). public func asin(_ x: X) -> [Float] where X.Element == Float { @@ -152,7 +152,7 @@ public func asin(_ x: X) -> [Double] where X.Element } } -// MARK: Arccosine +// MARK: - Arccosine /// - Warning: does not support memory stride (assumes stride is 1). public func acos(_ x: X) -> [Float] where X.Element == Float { @@ -178,7 +178,7 @@ public func acos(_ x: X) -> [Double] where X.Element } } -// MARK: Arctangent +// MARK: - Arctangent /// - Warning: does not support memory stride (assumes stride is 1). public func atan(_ x: X) -> [Float] where X.Element == Float { @@ -206,7 +206,7 @@ public func atan(_ x: X) -> [Double] where X.Element // MARK: - -// MARK: Radians to Degrees +// MARK: - Radians to Degrees /// - Warning: does not support memory stride (assumes stride is 1). func rad2deg(_ x: X) -> [Float] where X.Element == Float { @@ -234,7 +234,7 @@ func rad2deg(_ x: X) -> [Double] where X.Element == D } } -// MARK: Degrees to Radians +// MARK: - Degrees to Radians /// - Warning: does not support memory stride (assumes stride is 1). func deg2rad(_ x: X) -> [Float] where X.Element == Float { @@ -261,3 +261,159 @@ func deg2rad(_ x: X) -> [Double] where X.Element == D return results } } + +// MARK: - Hyperbolic Sine + +/// - Warning: does not support memory stride (assumes stride is 1). +public func sinh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvsinhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func sinh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvsinh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +// MARK: - Hyperbolic Cosine + +/// - Warning: does not support memory stride (assumes stride is 1). +public func cosh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvcoshf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func cosh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvcosh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +// MARK: - Hyperbolic Tangent + +/// - Warning: does not support memory stride (assumes stride is 1). +public func tanh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvtanhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func tanh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvtanh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +// MARK: - Inverse Hyperbolic Sine + +/// - Warning: does not support memory stride (assumes stride is 1). +public func asinh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvasinhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func asinh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvasinh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +// MARK: - Inverse Hyperbolic Cosine + +/// - Warning: does not support memory stride (assumes stride is 1). +public func acosh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvacoshf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func acosh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvacosh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +// MARK: - Inverse Hyperbolic Tangent + +/// - Warning: does not support memory stride (assumes stride is 1). +public func atanh(_ x: X) -> [Float] where X.Iterator.Element == Float { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Float](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvatanhf(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} + +/// - Warning: does not support memory stride (assumes stride is 1). +public func atanh(_ x: X) -> [Double] where X.Iterator.Element == Double { + return x.withUnsafeMemory { xm in + precondition(xm.stride == 1, "\(#function) does not support strided memory access") + var results = [Double](repeating: 0.0, count: numericCast(x.count)) + results.withUnsafeMutableBufferPointer { rbp in + vvatanh(rbp.baseAddress!, xm.pointer, [numericCast(xm.count)]) + } + return results + } +} diff --git a/Sources/Surge/ArrayUnsafeMemory.swift b/Sources/Surge/Utilities/Array+Extensions.swift similarity index 100% rename from Sources/Surge/ArrayUnsafeMemory.swift rename to Sources/Surge/Utilities/Array+Extensions.swift diff --git a/Sources/Surge/ArraySliceUnsafeMemory.swift b/Sources/Surge/Utilities/ArraySlice+Extensions.swift similarity index 100% rename from Sources/Surge/ArraySliceUnsafeMemory.swift rename to Sources/Surge/Utilities/ArraySlice+Extensions.swift diff --git a/Sources/Surge/Utilities/OperatorPrecedences.swift b/Sources/Surge/Utilities/OperatorPrecedences.swift new file mode 100644 index 00000000..227fa8b4 --- /dev/null +++ b/Sources/Surge/Utilities/OperatorPrecedences.swift @@ -0,0 +1,54 @@ +// Copyright © 2014-2019 the Surge contributors +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +// MARK: - Element-wise Addition + +infix operator .+: AdditionPrecedence +infix operator .+=: AssignmentPrecedence + +// MARK: - Element-wise Subtraction + +infix operator .-: AdditionPrecedence +infix operator .-=: AssignmentPrecedence + +// MARK: - Element-wise Multiplication + +infix operator .*: MultiplicationPrecedence +infix operator .*=: AssignmentPrecedence + +// MARK: - Element-wise Division + +infix operator ./: MultiplicationPrecedence +infix operator ./=: AssignmentPrecedence + +// MARK: - Element-wise Modulo + +infix operator .%: MultiplicationPrecedence +infix operator .%=: AssignmentPrecedence + +// MARK: - Dot product + +infix operator •: MultiplicationPrecedence + +// MARK: - Matrix Transpose + +postfix operator ′ diff --git a/Sources/Surge/Pointers.swift b/Sources/Surge/Utilities/Pointers.swift similarity index 98% rename from Sources/Surge/Pointers.swift rename to Sources/Surge/Utilities/Pointers.swift index 92be6c14..0b6e75db 100644 --- a/Sources/Surge/Pointers.swift +++ b/Sources/Surge/Utilities/Pointers.swift @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -// MARK: 2 Parameter +// MARK: - 2 Parameter /// Invokes the given closure with pointers to the given arguments (2 parameter version). /// @@ -44,7 +44,7 @@ public func withUnsafeMutablePointers(_ a: inout A, _ b: inout B, } } -// MARK: 3 Parameter +// MARK: - 3 Parameter /// Invokes the given closure with pointers to the given arguments (3 parameter version). /// diff --git a/Sources/Surge/UnsafeMemory.swift b/Sources/Surge/Utilities/UnsafeMemory.swift similarity index 82% rename from Sources/Surge/UnsafeMemory.swift rename to Sources/Surge/Utilities/UnsafeMemory.swift index 767f4454..aeb2476a 100644 --- a/Sources/Surge/UnsafeMemory.swift +++ b/Sources/Surge/Utilities/UnsafeMemory.swift @@ -72,14 +72,14 @@ public protocol UnsafeMemoryAccessible: Collection { func withUnsafeMemory(_ body: (UnsafeMemory) throws -> Result) rethrows -> Result } -public func withUnsafeMemory(_ x: X, _ body: (UnsafeMemory) throws -> Result) rethrows -> Result { - return try x.withUnsafeMemory(body) +public func withUnsafeMemory(_ lhs: L, _ body: (UnsafeMemory) throws -> Result) rethrows -> Result { + return try lhs.withUnsafeMemory(body) } -public func withUnsafeMemory(_ x: X, _ y: Y, _ body: (UnsafeMemory, UnsafeMemory) throws -> Result) rethrows -> Result { - return try x.withUnsafeMemory { xm in - try y.withUnsafeMemory { ym in - try body(xm, ym) +public func withUnsafeMemory(_ lhs: L, _ rhs: R, _ body: (UnsafeMemory, UnsafeMemory) throws -> Result) rethrows -> Result { + return try lhs.withUnsafeMemory { lhsMemory in + try rhs.withUnsafeMemory { rhsMemory in + try body(lhsMemory, rhsMemory) } } } diff --git a/Sources/Surge/UnsafeMutableMemory.swift b/Sources/Surge/Utilities/UnsafeMutableMemory.swift similarity index 70% rename from Sources/Surge/UnsafeMutableMemory.swift rename to Sources/Surge/Utilities/UnsafeMutableMemory.swift index b2cc206b..9269fd2e 100644 --- a/Sources/Surge/UnsafeMutableMemory.swift +++ b/Sources/Surge/Utilities/UnsafeMutableMemory.swift @@ -72,23 +72,23 @@ public protocol UnsafeMutableMemoryAccessible: UnsafeMemoryAccessible { mutating func withUnsafeMutableMemory(_ body: (UnsafeMutableMemory) throws -> Result) rethrows -> Result } -public func withUnsafeMutableMemory(_ x: inout X, _ body: (UnsafeMutableMemory) throws -> Result) rethrows -> Result { - return try x.withUnsafeMutableMemory(body) +public func withUnsafeMutableMemory(_ lhs: inout L, _ body: (UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try lhs.withUnsafeMutableMemory(body) } -public func withUnsafeMutableMemory(_ x: inout X, _ y: inout Y, _ body: (UnsafeMutableMemory, UnsafeMutableMemory) throws -> Result) rethrows -> Result { - return try x.withUnsafeMutableMemory { xm in - try y.withUnsafeMutableMemory { ym in - try body(xm, ym) +public func withUnsafeMutableMemory(_ lhs: inout L, _ rhs: inout R, _ body: (UnsafeMutableMemory, UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try lhs.withUnsafeMutableMemory { lhsMemory in + try rhs.withUnsafeMutableMemory { rhsMemory in + try body(lhsMemory, rhsMemory) } } } -public func withUnsafeMutableMemory(_ x: inout X, _ y: inout Y, _ z: inout Z, _ body: (UnsafeMutableMemory, UnsafeMutableMemory, UnsafeMutableMemory) throws -> Result) rethrows -> Result { - return try x.withUnsafeMutableMemory { xm in - try y.withUnsafeMutableMemory { ym in +public func withUnsafeMutableMemory(_ lhs: inout L, _ rhs: inout R, _ z: inout Z, _ body: (UnsafeMutableMemory, UnsafeMutableMemory, UnsafeMutableMemory) throws -> Result) rethrows -> Result { + return try lhs.withUnsafeMutableMemory { lhsMemory in + try rhs.withUnsafeMutableMemory { rhsMemory in try z.withUnsafeMutableMemory { zm in - try body(xm, ym, zm) + try body(lhsMemory, rhsMemory, zm) } } } diff --git a/Sources/Surge/Vector.swift b/Sources/Surge/Vector.swift deleted file mode 100644 index 4016d8c9..00000000 --- a/Sources/Surge/Vector.swift +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright © 2014-2018 the contributors -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -import Accelerate - -public struct Vector where Scalar: FloatingPoint, Scalar: ExpressibleByFloatLiteral { - public let dimensions: Int - - public var scalars: [Scalar] { - didSet { - precondition(self.scalars.count == self.dimensions) - } - } - - // MARK: - Initialize - - public init(dimensions: Int, repeatedValue: Scalar) { - let scalars = Array(repeating: repeatedValue, count: dimensions) - self.init(scalars) - } - - public init(_ contents: T) where T.Element == Scalar { - let scalars: [Scalar] - if let array = contents as? [Scalar] { - scalars = array - } else { - scalars = Array(contents) - } - self.dimensions = scalars.count - self.scalars = scalars - } -} - -// MARK: - ExpressibleByArrayLiteral - -extension Vector: ExpressibleByArrayLiteral { - public init(arrayLiteral elements: Scalar...) { - self.init(elements) - } -} - -// MARK: - CustomStringConvertible - -extension Vector: CustomStringConvertible { - public var description: String { - return self.scalars.map({ "\($0)" }).joined(separator: "\t") - } -} - -// MARK: - Sequence - -extension Vector: Sequence { - public func makeIterator() -> AnyIterator { - return AnyIterator(self.scalars.makeIterator()) - } -} - -// MARK: - Collection - -extension Vector: Collection { - public subscript(_ dimension: Int) -> Scalar { - get { - return self.scalars[dimension] - } - - set { - self.scalars[dimension] = newValue - } - } - - public var startIndex: Int { - return self.scalars.startIndex - } - - public var endIndex: Int { - return self.scalars.endIndex - } - - public func index(after i: Int) -> Int { - return self.scalars.index(after: i) - } -} - -// MARK: - Equatable - -extension Vector: Equatable {} -public func == (lhs: Vector, rhs: Vector) -> Bool { - return lhs.scalars == rhs.scalars -} - -// MARK: - Addition - -public func add(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with addition") - - return Vector(add(x.scalars, y.scalars)) -} - -public func add(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with addition") - - return Vector(add(x.scalars, y.scalars)) -} - -public func add(_ x: Vector, _ y: Float) -> Vector { - return Vector(add(x.scalars, y)) -} - -public func add(_ x: Vector, _ y: Double) -> Vector { - return Vector(add(x.scalars, y)) -} - -// MARK: Addition: In Place - -public func addInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with addition") - - return addInPlace(&x.scalars, y.scalars) -} - -public func addInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with addition") - - return addInPlace(&x.scalars, y.scalars) -} - -public func addInPlace(_ x: inout Vector, _ y: Float) { - return addInPlace(&x.scalars, y) -} - -public func addInPlace(_ x: inout Vector, _ y: Double) { - return addInPlace(&x.scalars, y) -} - -// MARK: Subtraction - -public func sub(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with subtraction") - - return Vector(sub(x.scalars, y.scalars)) -} - -public func sub(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with subtraction") - - return Vector(sub(x.scalars, y.scalars)) -} - -public func sub(_ x: Vector, _ y: Float) -> Vector { - return Vector(sub(x.scalars, y)) -} - -public func sub(_ x: Vector, _ y: Double) -> Vector { - return Vector(sub(x.scalars, y)) -} - -// MARK: Subtraction: In Place - -public func subInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with subtraction") - - return subInPlace(&x.scalars, y.scalars) -} - -public func subInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with subtraction") - - return subInPlace(&x.scalars, y.scalars) -} - -public func subInPlace(_ x: inout Vector, _ y: Float) { - return subInPlace(&x.scalars, y) -} - -public func subInPlace(_ x: inout Vector, _ y: Double) { - return subInPlace(&x.scalars, y) -} - -// MARK: Multiplication - -public func mul(_ x: Float, _ y: Vector) -> Vector { - return Vector(mul(x, y.scalars)) -} - -public func mul(_ x: Double, _ y: Vector) -> Vector { - return Vector(mul(x, y.scalars)) -} - -public func mul(_ x: Vector, _ y: Float) -> Vector { - return Vector(mul(x.scalars, y)) -} - -public func mul(_ x: Vector, _ y: Double) -> Vector { - return Vector(mul(x.scalars, y)) -} - -// MARK: Multiplication: In Place - -public func mulInPlace(_ x: inout Vector, _ y: Float) { - return mulInPlace(&x.scalars, y) -} - -public func mulInPlace(_ x: inout Vector, _ y: Double) { - return mulInPlace(&x.scalars, y) -} - -// MARK: Division - -public func div(_ x: Vector, _ y: Float) -> Vector { - return Vector(div(x.scalars, y)) -} - -public func div(_ x: Vector, _ y: Double) -> Vector { - return Vector(div(x.scalars, y)) -} - -// MARK: Division: In Place - -public func divInPlace(_ x: inout Vector, _ y: Float) { - return divInPlace(&x.scalars, y) -} - -public func divInPlace(_ x: inout Vector, _ y: Double) { - return divInPlace(&x.scalars, y) -} - -// MARK: Element-wise Multiplication - -public func elmul(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise multiplication") - - return Vector(mul(x.scalars, y.scalars)) -} - -public func elmul(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise multiplication") - - return Vector(mul(x.scalars, y.scalars)) -} - -// MARK: Element-wise Multiplication: In Place - -public func elmulInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise multiplication") - - return mulInPlace(&x.scalars, y.scalars) -} - -public func elmulInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise multiplication") - - return mulInPlace(&x.scalars, y.scalars) -} - -// MARK: Element-wise Division - -public func eldiv(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise division") - - return Vector(div(x.scalars, y.scalars)) -} - -public func eldiv(_ x: Vector, _ y: Vector) -> Vector { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise division") - - return Vector(div(x.scalars, y.scalars)) -} - -// MARK: Element-wise Division: In Place - -public func eldivInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise division") - - return divInPlace(&x.scalars, y.scalars) -} - -public func eldivInPlace(_ x: inout Vector, _ y: Vector) { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with element-wise division") - - return divInPlace(&x.scalars, y.scalars) -} - -// MARK: Dot Product - -public func dot(_ x: Vector, _ y: Vector) -> Double { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with dot product") - - return dot(x.scalars, y.scalars) -} - -public func dot(_ x: Vector, _ y: Vector) -> Float { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with dot product") - - return dot(x.scalars, y.scalars) -} - -public func pow(_ x: Vector, _ y: Double) -> Vector { - return Vector(pow(x.scalars, y)) -} - -public func pow(_ x: Vector, _ y: Float) -> Vector { - return Vector(pow(x.scalars, y)) -} - -public func exp(_ x: Vector) -> Vector { - return Vector(exp(x.scalars)) -} - -public func exp(_ x: Vector) -> Vector { - return Vector(exp(x.scalars)) -} - -// MARK: Distance - -public func dist(_ x: Vector, _ y: Vector) -> Double { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with distance calculation") - - return dist(x.scalars, y.scalars) -} - -public func dist(_ x: Vector, _ y: Vector) -> Float { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with distance calculation") - - return dist(x.scalars, y.scalars) -} - -public func distSq(_ x: Vector, _ y: Vector) -> Double { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with distance calculation") - - return distSq(x.scalars, y.scalars) -} - -public func distSq(_ x: Vector, _ y: Vector) -> Float { - precondition(x.dimensions == y.dimensions, "Vector dimensions not compatible with distance calculation") - - return distSq(x.scalars, y.scalars) -} - -// MARK: - Operators - -public func + (lhs: Vector, rhs: Vector) -> Vector { - return add(lhs, rhs) -} - -public func + (lhs: Vector, rhs: Vector) -> Vector { - return add(lhs, rhs) -} - -public func + (lhs: Vector, rhs: Float) -> Vector { - return add(lhs, rhs) -} - -public func + (lhs: Vector, rhs: Double) -> Vector { - return add(lhs, rhs) -} - -public func += (lhs: inout Vector, rhs: Vector) { - return addInPlace(&lhs, rhs) -} - -public func += (lhs: inout Vector, rhs: Vector) { - return addInPlace(&lhs, rhs) -} - -public func += (lhs: inout Vector, rhs: Float) { - return addInPlace(&lhs, rhs) -} - -public func += (lhs: inout Vector, rhs: Double) { - return addInPlace(&lhs, rhs) -} - -public func - (lhs: Vector, rhs: Vector) -> Vector { - return sub(lhs, rhs) -} - -public func - (lhs: Vector, rhs: Vector) -> Vector { - return sub(lhs, rhs) -} - -public func - (lhs: Vector, rhs: Float) -> Vector { - return sub(lhs, rhs) -} - -public func - (lhs: Vector, rhs: Double) -> Vector { - return sub(lhs, rhs) -} - -public func -= (lhs: inout Vector, rhs: Vector) { - return subInPlace(&lhs, rhs) -} - -public func -= (lhs: inout Vector, rhs: Vector) { - return subInPlace(&lhs, rhs) -} - -public func -= (lhs: inout Vector, rhs: Float) { - return subInPlace(&lhs, rhs) -} - -public func -= (lhs: inout Vector, rhs: Double) { - return subInPlace(&lhs, rhs) -} - -public func * (lhs: Float, rhs: Vector) -> Vector { - return mul(lhs, rhs) -} - -public func * (lhs: Double, rhs: Vector) -> Vector { - return mul(lhs, rhs) -} - -public func * (lhs: Vector, rhs: Float) -> Vector { - return mul(lhs, rhs) -} - -public func * (lhs: Vector, rhs: Double) -> Vector { - return mul(lhs, rhs) -} - -public func *= (lhs: inout Vector, rhs: Float) { - return mulInPlace(&lhs, rhs) -} - -public func *= (lhs: inout Vector, rhs: Double) { - return mulInPlace(&lhs, rhs) -} - -public func / (lhs: Vector, rhs: Double) -> Vector { - return div(lhs, rhs) -} - -public func / (lhs: Vector, rhs: Float) -> Vector { - return div(lhs, rhs) -} - -public func /= (lhs: inout Vector, rhs: Float) { - return divInPlace(&lhs, rhs) -} - -public func /= (lhs: inout Vector, rhs: Double) { - return divInPlace(&lhs, rhs) -} - -public func .* (lhs: Vector, rhs: Vector) -> Vector { - return elmul(lhs, rhs) -} - -public func .* (lhs: Vector, rhs: Vector) -> Vector { - return elmul(lhs, rhs) -} - -public func .*= (lhs: inout Vector, rhs: Vector) { - return elmulInPlace(&lhs, rhs) -} - -public func .*= (lhs: inout Vector, rhs: Vector) { - return elmulInPlace(&lhs, rhs) -} - -public func ./ (lhs: Vector, rhs: Vector) -> Vector { - return eldiv(lhs, rhs) -} - -public func ./ (lhs: Vector, rhs: Vector) -> Vector { - return eldiv(lhs, rhs) -} - -public func ./= (lhs: inout Vector, rhs: Vector) { - return eldivInPlace(&lhs, rhs) -} - -public func ./= (lhs: inout Vector, rhs: Vector) { - return eldivInPlace(&lhs, rhs) -} - -// MARK: Dot product - -infix operator •: MultiplicationPrecedence -public func • (lhs: Vector, rhs: Vector) -> Double { - return dot(lhs, rhs) -} - -public func • (lhs: Vector, rhs: Vector) -> Float { - return dot(lhs, rhs) -} diff --git a/Surge.xcodeproj/project.pbxproj b/Surge.xcodeproj/project.pbxproj index 56c8e00d..a0b42188 100644 --- a/Surge.xcodeproj/project.pbxproj +++ b/Surge.xcodeproj/project.pbxproj @@ -14,7 +14,6 @@ 614AD33A1FC0AF72002BFE1C /* Convolution.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944D1F762B58002A4AD2 /* Convolution.swift */; }; 614AD33B1FC0AF72002BFE1C /* Exponential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944E1F762B58002A4AD2 /* Exponential.swift */; }; 614AD33C1FC0AF72002BFE1C /* FFT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944F1F762B58002A4AD2 /* FFT.swift */; }; - 614AD33D1FC0AF72002BFE1C /* Hyperbolic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394501F762B58002A4AD2 /* Hyperbolic.swift */; }; 614AD33E1FC0AF72002BFE1C /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394511F762B58002A4AD2 /* Matrix.swift */; }; 614AD33F1FC0AF72002BFE1C /* Pointers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394521F762B58002A4AD2 /* Pointers.swift */; }; 614AD3401FC0AF72002BFE1C /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; @@ -35,7 +34,6 @@ 614AD36B1FC0B0CC002BFE1C /* Convolution.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944D1F762B58002A4AD2 /* Convolution.swift */; }; 614AD36C1FC0B0CC002BFE1C /* Exponential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944E1F762B58002A4AD2 /* Exponential.swift */; }; 614AD36D1FC0B0CC002BFE1C /* FFT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944F1F762B58002A4AD2 /* FFT.swift */; }; - 614AD36E1FC0B0CC002BFE1C /* Hyperbolic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394501F762B58002A4AD2 /* Hyperbolic.swift */; }; 614AD36F1FC0B0CC002BFE1C /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394511F762B58002A4AD2 /* Matrix.swift */; }; 614AD3701FC0B0CC002BFE1C /* Pointers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394521F762B58002A4AD2 /* Pointers.swift */; }; 614AD3711FC0B0CC002BFE1C /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; @@ -55,7 +53,6 @@ 614AD38D1FC0B134002BFE1C /* Convolution.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944D1F762B58002A4AD2 /* Convolution.swift */; }; 614AD38E1FC0B134002BFE1C /* Exponential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944E1F762B58002A4AD2 /* Exponential.swift */; }; 614AD38F1FC0B134002BFE1C /* FFT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944F1F762B58002A4AD2 /* FFT.swift */; }; - 614AD3901FC0B134002BFE1C /* Hyperbolic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394501F762B58002A4AD2 /* Hyperbolic.swift */; }; 614AD3911FC0B134002BFE1C /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394511F762B58002A4AD2 /* Matrix.swift */; }; 614AD3921FC0B134002BFE1C /* Pointers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394521F762B58002A4AD2 /* Pointers.swift */; }; 614AD3931FC0B134002BFE1C /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; @@ -69,7 +66,6 @@ 615394581F762B59002A4AD2 /* Convolution.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944D1F762B58002A4AD2 /* Convolution.swift */; }; 615394591F762B59002A4AD2 /* Exponential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944E1F762B58002A4AD2 /* Exponential.swift */; }; 6153945A1F762B59002A4AD2 /* FFT.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6153944F1F762B58002A4AD2 /* FFT.swift */; }; - 6153945B1F762B59002A4AD2 /* Hyperbolic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394501F762B58002A4AD2 /* Hyperbolic.swift */; }; 6153945C1F762B59002A4AD2 /* Matrix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394511F762B58002A4AD2 /* Matrix.swift */; }; 6153945D1F762B59002A4AD2 /* Pointers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394521F762B58002A4AD2 /* Pointers.swift */; }; 6153945E1F762B59002A4AD2 /* Power.swift in Sources */ = {isa = PBXBuildFile; fileRef = 615394531F762B58002A4AD2 /* Power.swift */; }; @@ -88,18 +84,30 @@ 61E930B9207002EA00694FCB /* UnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930B7207002EA00694FCB /* UnsafeMemory.swift */; }; 61E930BA207002EA00694FCB /* UnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930B7207002EA00694FCB /* UnsafeMemory.swift */; }; 61E930BB207002EA00694FCB /* UnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930B7207002EA00694FCB /* UnsafeMemory.swift */; }; - 61E930BD2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; - 61E930BE2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; - 61E930BF2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; - 61E930C02070104600694FCB /* ArrayUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */; }; + 61E930BD2070104600694FCB /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* Array+Extensions.swift */; }; + 61E930BE2070104600694FCB /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* Array+Extensions.swift */; }; + 61E930BF2070104600694FCB /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* Array+Extensions.swift */; }; + 61E930C02070104600694FCB /* Array+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930BC2070104600694FCB /* Array+Extensions.swift */; }; 61E930C22070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; 61E930C32070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; 61E930C42070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; 61E930C52070B69300694FCB /* UnsafeMutableMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */; }; - 61E930C82070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; - 61E930C92070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; - 61E930CA2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; - 61E930CB2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */; }; + 61E930C82070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySlice+Extensions.swift */; }; + 61E930C92070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySlice+Extensions.swift */; }; + 61E930CA2070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySlice+Extensions.swift */; }; + 61E930CB2070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E930C72070BCCD00694FCB /* ArraySlice+Extensions.swift */; }; + CAEC79BF2319274F00516E10 /* OperatorPrecedences.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79B72319244D00516E10 /* OperatorPrecedences.swift */; }; + CAEC79C02319275000516E10 /* OperatorPrecedences.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79B72319244D00516E10 /* OperatorPrecedences.swift */; }; + CAEC79C12319275000516E10 /* OperatorPrecedences.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79B72319244D00516E10 /* OperatorPrecedences.swift */; }; + CAEC79C22319275100516E10 /* OperatorPrecedences.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79B72319244D00516E10 /* OperatorPrecedences.swift */; }; + CAEC79C423192FE300516E10 /* Scalar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79C323192FE300516E10 /* Scalar.swift */; }; + CAEC79C5231930EC00516E10 /* Scalar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79C323192FE300516E10 /* Scalar.swift */; }; + CAEC79C6231930ED00516E10 /* Scalar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79C323192FE300516E10 /* Scalar.swift */; }; + CAEC79C7231930ED00516E10 /* Scalar.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79C323192FE300516E10 /* Scalar.swift */; }; + CAEC79D22319343100516E10 /* Logarithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79D12319343100516E10 /* Logarithm.swift */; }; + CAEC79D32319343100516E10 /* Logarithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79D12319343100516E10 /* Logarithm.swift */; }; + CAEC79D42319343100516E10 /* Logarithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79D12319343100516E10 /* Logarithm.swift */; }; + CAEC79D52319343100516E10 /* Logarithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAEC79D12319343100516E10 /* Logarithm.swift */; }; CAFE5DA522F9EC1D00A34887 /* XCTAssert+Surge.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE5DA422F9EC1D00A34887 /* XCTAssert+Surge.swift */; }; CAFE5DA622F9EC1D00A34887 /* XCTAssert+Surge.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE5DA422F9EC1D00A34887 /* XCTAssert+Surge.swift */; }; CAFE5DA722F9EC1D00A34887 /* XCTAssert+Surge.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAFE5DA422F9EC1D00A34887 /* XCTAssert+Surge.swift */; }; @@ -147,13 +155,12 @@ 614AD3541FC0B001002BFE1C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 614AD3591FC0B001002BFE1C /* SurgeTests-tvOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SurgeTests-tvOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 614AD3821FC0B125002BFE1C /* Surge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Surge.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 6152A42020719E9200043627 /* Statistics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Statistics.swift; sourceTree = ""; }; + 6152A42020719E9200043627 /* Statistics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Statistics.swift; sourceTree = ""; }; 6153944B1F762B58002A4AD2 /* Arithmetic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Arithmetic.swift; sourceTree = ""; }; 6153944C1F762B58002A4AD2 /* Auxiliary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Auxiliary.swift; sourceTree = ""; }; 6153944D1F762B58002A4AD2 /* Convolution.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Convolution.swift; sourceTree = ""; }; 6153944E1F762B58002A4AD2 /* Exponential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Exponential.swift; sourceTree = ""; }; 6153944F1F762B58002A4AD2 /* FFT.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FFT.swift; sourceTree = ""; }; - 615394501F762B58002A4AD2 /* Hyperbolic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Hyperbolic.swift; sourceTree = ""; }; 615394511F762B58002A4AD2 /* Matrix.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Matrix.swift; sourceTree = ""; }; 615394521F762B58002A4AD2 /* Pointers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pointers.swift; sourceTree = ""; }; 615394531F762B58002A4AD2 /* Power.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Power.swift; sourceTree = ""; }; @@ -171,10 +178,13 @@ 61A0AD7F1F70D99B00B99FFB /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 61A0AD801F70D99B00B99FFB /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 61A0AD811F70D99B00B99FFB /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; - 61E930B7207002EA00694FCB /* UnsafeMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsafeMemory.swift; sourceTree = ""; }; - 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayUnsafeMemory.swift; sourceTree = ""; }; - 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsafeMutableMemory.swift; sourceTree = ""; }; - 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArraySliceUnsafeMemory.swift; sourceTree = ""; }; + 61E930B7207002EA00694FCB /* UnsafeMemory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeMemory.swift; sourceTree = ""; }; + 61E930BC2070104600694FCB /* Array+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Array+Extensions.swift"; sourceTree = ""; }; + 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeMutableMemory.swift; sourceTree = ""; }; + 61E930C72070BCCD00694FCB /* ArraySlice+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ArraySlice+Extensions.swift"; sourceTree = ""; }; + CAEC79B72319244D00516E10 /* OperatorPrecedences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OperatorPrecedences.swift; sourceTree = ""; }; + CAEC79C323192FE300516E10 /* Scalar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scalar.swift; sourceTree = ""; }; + CAEC79D12319343100516E10 /* Logarithm.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logarithm.swift; sourceTree = ""; }; CAFE5DA422F9EC1D00A34887 /* XCTAssert+Surge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "XCTAssert+Surge.swift"; sourceTree = ""; }; CAFE5DA822F9ED3A00A34887 /* Vector.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vector.swift; sourceTree = ""; }; CAFE5DAD22F9ED4900A34887 /* VectorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VectorTests.swift; sourceTree = ""; }; @@ -253,22 +263,15 @@ isa = PBXGroup; children = ( 615394541F762B58002A4AD2 /* Surge.h */, - 6153944B1F762B58002A4AD2 /* Arithmetic.swift */, - 61E930C72070BCCD00694FCB /* ArraySliceUnsafeMemory.swift */, - 61E930BC2070104600694FCB /* ArrayUnsafeMemory.swift */, - 6153944C1F762B58002A4AD2 /* Auxiliary.swift */, - 6153944D1F762B58002A4AD2 /* Convolution.swift */, - 6153944E1F762B58002A4AD2 /* Exponential.swift */, - 6153944F1F762B58002A4AD2 /* FFT.swift */, - 615394501F762B58002A4AD2 /* Hyperbolic.swift */, - 615394511F762B58002A4AD2 /* Matrix.swift */, - 615394521F762B58002A4AD2 /* Pointers.swift */, - 615394531F762B58002A4AD2 /* Power.swift */, - 6152A42020719E9200043627 /* Statistics.swift */, - 615394551F762B58002A4AD2 /* Trigonometric.swift */, - 61E930B7207002EA00694FCB /* UnsafeMemory.swift */, - 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */, - CAFE5DA822F9ED3A00A34887 /* Vector.swift */, + CAEC79CB2319336500516E10 /* Auxiliary Functions */, + CAEC79C92319333E00516E10 /* Digital Signal Processing */, + CAEC79CF2319340300516E10 /* Exponential */, + CAEC79CA2319335100516E10 /* General Arithmetic */, + CAEC79CD2319338F00516E10 /* Linear Algebra */, + CAEC79D02319343100516E10 /* Logarithm */, + CAEC79CC2319337700516E10 /* Statistics */, + CAEC79CE231933D700516E10 /* Trigonometry */, + CAEC79C8231932E900516E10 /* Utilities */, ); path = Surge; sourceTree = ""; @@ -291,6 +294,87 @@ path = SurgeTests; sourceTree = ""; }; + CAEC79C8231932E900516E10 /* Utilities */ = { + isa = PBXGroup; + children = ( + 61E930BC2070104600694FCB /* Array+Extensions.swift */, + 61E930C72070BCCD00694FCB /* ArraySlice+Extensions.swift */, + CAEC79B72319244D00516E10 /* OperatorPrecedences.swift */, + 615394521F762B58002A4AD2 /* Pointers.swift */, + 61E930B7207002EA00694FCB /* UnsafeMemory.swift */, + 61E930C12070B69300694FCB /* UnsafeMutableMemory.swift */, + ); + path = Utilities; + sourceTree = ""; + }; + CAEC79C92319333E00516E10 /* Digital Signal Processing */ = { + isa = PBXGroup; + children = ( + 6153944D1F762B58002A4AD2 /* Convolution.swift */, + 6153944F1F762B58002A4AD2 /* FFT.swift */, + ); + path = "Digital Signal Processing"; + sourceTree = ""; + }; + CAEC79CA2319335100516E10 /* General Arithmetic */ = { + isa = PBXGroup; + children = ( + 6153944B1F762B58002A4AD2 /* Arithmetic.swift */, + 615394531F762B58002A4AD2 /* Power.swift */, + ); + path = "General Arithmetic"; + sourceTree = ""; + }; + CAEC79CB2319336500516E10 /* Auxiliary Functions */ = { + isa = PBXGroup; + children = ( + 6153944C1F762B58002A4AD2 /* Auxiliary.swift */, + ); + path = "Auxiliary Functions"; + sourceTree = ""; + }; + CAEC79CC2319337700516E10 /* Statistics */ = { + isa = PBXGroup; + children = ( + 6152A42020719E9200043627 /* Statistics.swift */, + ); + path = Statistics; + sourceTree = ""; + }; + CAEC79CD2319338F00516E10 /* Linear Algebra */ = { + isa = PBXGroup; + children = ( + CAEC79C323192FE300516E10 /* Scalar.swift */, + CAFE5DA822F9ED3A00A34887 /* Vector.swift */, + 615394511F762B58002A4AD2 /* Matrix.swift */, + ); + path = "Linear Algebra"; + sourceTree = ""; + }; + CAEC79CE231933D700516E10 /* Trigonometry */ = { + isa = PBXGroup; + children = ( + 615394551F762B58002A4AD2 /* Trigonometric.swift */, + ); + path = Trigonometry; + sourceTree = ""; + }; + CAEC79CF2319340300516E10 /* Exponential */ = { + isa = PBXGroup; + children = ( + 6153944E1F762B58002A4AD2 /* Exponential.swift */, + ); + path = Exponential; + sourceTree = ""; + }; + CAEC79D02319343100516E10 /* Logarithm */ = { + isa = PBXGroup; + children = ( + CAEC79D12319343100516E10 /* Logarithm.swift */, + ); + path = Logarithm; + sourceTree = ""; + }; F84A6AAF19A9A72F007B53E1 /* Tests */ = { isa = PBXGroup; children = ( @@ -702,19 +786,21 @@ files = ( 614AD33E1FC0AF72002BFE1C /* Matrix.swift in Sources */, 61E930C32070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, - 61E930C92070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, + 61E930C92070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */, + CAEC79D32319343100516E10 /* Logarithm.swift in Sources */, 614AD3391FC0AF72002BFE1C /* Auxiliary.swift in Sources */, 614AD3411FC0AF72002BFE1C /* Trigonometric.swift in Sources */, 614AD3381FC0AF72002BFE1C /* Arithmetic.swift in Sources */, - 614AD33D1FC0AF72002BFE1C /* Hyperbolic.swift in Sources */, 614AD33A1FC0AF72002BFE1C /* Convolution.swift in Sources */, 614AD33F1FC0AF72002BFE1C /* Pointers.swift in Sources */, 614AD33C1FC0AF72002BFE1C /* FFT.swift in Sources */, CAFE5DAA22F9ED3A00A34887 /* Vector.swift in Sources */, - 61E930BE2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930BE2070104600694FCB /* Array+Extensions.swift in Sources */, 61E930B9207002EA00694FCB /* UnsafeMemory.swift in Sources */, + CAEC79C5231930EC00516E10 /* Scalar.swift in Sources */, 614AD3401FC0AF72002BFE1C /* Power.swift in Sources */, 6152A42220719E9200043627 /* Statistics.swift in Sources */, + CAEC79C02319275000516E10 /* OperatorPrecedences.swift in Sources */, 614AD33B1FC0AF72002BFE1C /* Exponential.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -743,19 +829,21 @@ files = ( 614AD36F1FC0B0CC002BFE1C /* Matrix.swift in Sources */, 61E930C42070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, - 61E930CA2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, + 61E930CA2070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */, + CAEC79D42319343100516E10 /* Logarithm.swift in Sources */, 614AD36A1FC0B0CC002BFE1C /* Auxiliary.swift in Sources */, 614AD3721FC0B0CC002BFE1C /* Trigonometric.swift in Sources */, 614AD3691FC0B0CC002BFE1C /* Arithmetic.swift in Sources */, - 614AD36E1FC0B0CC002BFE1C /* Hyperbolic.swift in Sources */, 614AD36B1FC0B0CC002BFE1C /* Convolution.swift in Sources */, 614AD3701FC0B0CC002BFE1C /* Pointers.swift in Sources */, 614AD36D1FC0B0CC002BFE1C /* FFT.swift in Sources */, CAFE5DAB22F9ED3A00A34887 /* Vector.swift in Sources */, - 61E930BF2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930BF2070104600694FCB /* Array+Extensions.swift in Sources */, 61E930BA207002EA00694FCB /* UnsafeMemory.swift in Sources */, + CAEC79C6231930ED00516E10 /* Scalar.swift in Sources */, 614AD3711FC0B0CC002BFE1C /* Power.swift in Sources */, 6152A42320719E9200043627 /* Statistics.swift in Sources */, + CAEC79C12319275000516E10 /* OperatorPrecedences.swift in Sources */, 614AD36C1FC0B0CC002BFE1C /* Exponential.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -784,19 +872,21 @@ files = ( 614AD3911FC0B134002BFE1C /* Matrix.swift in Sources */, 61E930C52070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, - 61E930CB2070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, + 61E930CB2070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */, + CAEC79D52319343100516E10 /* Logarithm.swift in Sources */, 614AD38C1FC0B134002BFE1C /* Auxiliary.swift in Sources */, 614AD3941FC0B134002BFE1C /* Trigonometric.swift in Sources */, 614AD38B1FC0B134002BFE1C /* Arithmetic.swift in Sources */, - 614AD3901FC0B134002BFE1C /* Hyperbolic.swift in Sources */, 614AD38D1FC0B134002BFE1C /* Convolution.swift in Sources */, 614AD3921FC0B134002BFE1C /* Pointers.swift in Sources */, 614AD38F1FC0B134002BFE1C /* FFT.swift in Sources */, CAFE5DAC22F9ED3A00A34887 /* Vector.swift in Sources */, - 61E930C02070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930C02070104600694FCB /* Array+Extensions.swift in Sources */, 61E930BB207002EA00694FCB /* UnsafeMemory.swift in Sources */, + CAEC79C7231930ED00516E10 /* Scalar.swift in Sources */, 614AD3931FC0B134002BFE1C /* Power.swift in Sources */, 6152A42420719E9200043627 /* Statistics.swift in Sources */, + CAEC79C22319275100516E10 /* OperatorPrecedences.swift in Sources */, 614AD38E1FC0B134002BFE1C /* Exponential.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -825,19 +915,21 @@ files = ( 6153945C1F762B59002A4AD2 /* Matrix.swift in Sources */, 61E930C22070B69300694FCB /* UnsafeMutableMemory.swift in Sources */, - 61E930C82070BCCD00694FCB /* ArraySliceUnsafeMemory.swift in Sources */, + 61E930C82070BCCD00694FCB /* ArraySlice+Extensions.swift in Sources */, + CAEC79D22319343100516E10 /* Logarithm.swift in Sources */, 615394571F762B59002A4AD2 /* Auxiliary.swift in Sources */, 615394601F762B59002A4AD2 /* Trigonometric.swift in Sources */, 615394561F762B59002A4AD2 /* Arithmetic.swift in Sources */, - 6153945B1F762B59002A4AD2 /* Hyperbolic.swift in Sources */, 615394581F762B59002A4AD2 /* Convolution.swift in Sources */, 6153945D1F762B59002A4AD2 /* Pointers.swift in Sources */, 6153945A1F762B59002A4AD2 /* FFT.swift in Sources */, CAFE5DA922F9ED3A00A34887 /* Vector.swift in Sources */, - 61E930BD2070104600694FCB /* ArrayUnsafeMemory.swift in Sources */, + 61E930BD2070104600694FCB /* Array+Extensions.swift in Sources */, 61E930B8207002EA00694FCB /* UnsafeMemory.swift in Sources */, + CAEC79C423192FE300516E10 /* Scalar.swift in Sources */, 6153945E1F762B59002A4AD2 /* Power.swift in Sources */, 6152A42120719E9200043627 /* Statistics.swift in Sources */, + CAEC79BF2319274F00516E10 /* OperatorPrecedences.swift in Sources */, 615394591F762B59002A4AD2 /* Exponential.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tests/SurgeTests/ArithmeticTests.swift b/Tests/SurgeTests/ArithmeticTests.swift index 6ab52a15..b2049430 100644 --- a/Tests/SurgeTests/ArithmeticTests.swift +++ b/Tests/SurgeTests/ArithmeticTests.swift @@ -35,7 +35,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.add(lhs, rhs) + actual = lhs .+ rhs } let expected = Swift.zip(lhs, rhs).map { $0 + $1 } @@ -51,7 +51,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.add(lhs, rhs) + actual = lhs .+ rhs } let expected = Swift.zip(lhs, rhs).map { $0 + $1 } @@ -67,7 +67,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.sub(lhs, rhs) + actual = lhs .- rhs } let expected = Swift.zip(lhs, rhs).map { $0 - $1 } @@ -83,7 +83,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.sub(lhs, rhs) + actual = lhs .- rhs } let expected = Swift.zip(lhs, rhs).map { $0 - $1 } @@ -99,7 +99,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.mul(lhs, rhs) + actual = lhs .* rhs } let expected = Swift.zip(lhs, rhs).map { $0 * $1 } @@ -115,7 +115,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.mul(lhs, rhs) + actual = lhs .* rhs } let expected = Swift.zip(lhs, rhs).map { $0 * $1 } @@ -131,7 +131,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.div(lhs, rhs) + actual = lhs ./ rhs } let expected = Swift.zip(lhs, rhs).map { $0 / $1 } @@ -147,7 +147,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.div(lhs, rhs) + actual = lhs ./ rhs } let expected = Swift.zip(lhs, rhs).map { $0 / $1 } @@ -163,7 +163,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.mod(lhs, rhs) + actual = lhs .% rhs } let expected = Swift.zip(lhs, rhs).map { fmod($0, $1) } @@ -179,7 +179,7 @@ class ArithmeticTests: XCTestCase { var actual: [Scalar] = [] measure { - actual = Surge.mod(lhs, rhs) + actual = lhs .% rhs } let expected = Swift.zip(lhs, rhs).map { fmod($0, $1) } @@ -257,7 +257,7 @@ class ArithmeticTests: XCTestCase { var actual: Scalar = 0 measure { - actual = Surge.dot(lhs, rhs) + actual = lhs • rhs } let expected = Swift.zip(lhs, rhs).reduce(0) { @@ -275,7 +275,7 @@ class ArithmeticTests: XCTestCase { var actual: Scalar = 0 measure { - actual = Surge.dot(lhs, rhs) + actual = lhs • rhs } let expected = Swift.zip(lhs, rhs).reduce(0) { @@ -304,11 +304,11 @@ class ArithmeticTests: XCTestCase { let values = (0...n).map { _ in Double(arc4random()) / Double(UInt32.max) } var actual = 0.0 measure { - actual = sum(values[0.. = [ + let lhs: Matrix = [ [1] ] - let y: Matrix = [ + let rhs: Matrix = [ [] ] - let result = x * y + let result = lhs * rhs XCTAssertEqual(result.rows, 1) XCTAssertEqual(result.columns, 0)