jounce / surge Goto Github PK
View Code? Open in Web Editor NEWA Swift library that uses the Accelerate framework to provide high-performance functions for matrix math, digital signal processing, and image manipulation.
License: MIT License
A Swift library that uses the Accelerate framework to provide high-performance functions for matrix math, digital signal processing, and image manipulation.
License: MIT License
Using constrained extensions:
extension CollectionType where Generator.Element == Double {
func sum() -> Double { … }
}
let arrayOfDoubles: [Double] = [1.2, 2.3, 3.4]
arrayOfDoubles.sum()
In order to support a more stable library, we need a continuous integration system and a much more comprehensive set of tests.
Jmma, Android
/** Get a submatrix.
@param i0 Initial row index
@param i1 Final row index
@param j0 Initial column index
@param j1 Final column index
@return A(i0:i1,j0:j1)
@exception ArrayIndexOutOfBoundsException Submatrix indices
*/
public Matrix getMatrix (int i0, int i1, int j0, int j1) {
Matrix X = new Matrix(i1-i0+1,j1-j0+1);
double[][] B = X.getArray();
try {
for (int i = i0; i <= i1; i++) {
for (int j = j0; j <= j1; j++) {
B[i-i0][j-j0] = A[i][j];
}
}
} catch(ArrayIndexOutOfBoundsException e) {
throw new ArrayIndexOutOfBoundsException("Submatrix indices");
}
return X;
}
I'm currently evaluating several FFT implementations and I tried out your implementation (of the vDSP algorithm collection). After some reading there're two things I don't fully understand and I hope you might help us out here:
vDSP_fft_zrip
/ vDSP_fft_zripD
? I understand that your implementation works with real input vectors. So what's the benefit of not (!) using the "packed" implementation with the 'r' in the middle of the function name. The 'packed' implementation needs some additional packing / unpacking - but that's it.I'm specifically referring to the statement in https://github.com/jseales/numpy-style-fft-in-obj-c
The little 'r' somewhere in the middle of the function name is what designates it as the special fft designed to work with the packed up array. "vDSP_fft_zipD" with no 'r' is the complex version, and is easier to use because there are no packing and unpacking steps, but not as efficient, beautiful, or clever.
Certainly your implementation works, but it seems using the different method it should run faster or at least more efficient? On that note it's worth exploring the "in-place" variants of the methods as well.
conjugate symmetric fft
"half of the result" could be discarded anyhow (for real input values).Now that CocoaPods has been updated to support Swift (great job to everyone, by the way!) I'd love to see a podspec for Surge.
Versioning is out of date for swift package manager compatibility
I'm using Surge for a project, and I'm getting complaints about Surge not having Swift 3 syntax. It'd be nice to make a new tag since master branch supports it.
I am trying to create a Vector struct by wrapping the Matrix struct and asserting that the matrix is one dimensional. Thus I'd like to create a Vector constructor which constructs a Vector from a Matrix. However, the rows and columns Matrix properties are internal so I can't assert that columns is exactly 1. I've realized though that I can use Swift arrays to accomplish most vector operations but I think the point remains.
This is one use case in which I'd like to be able to access rows and columns from another module, but I can imagine others. Would it be possible to change make the rows and columns properties public? I can submit a pull request if you'd like.
Operator •
(dot product) is defined without precedence group, which by default assigns it to DefaultPrecedence group.
Per Swift docs,
DefaultPrecedence has no associativity and a precedence immediately higher than TernaryPrecedence
Probably it should be reasonable to have MultiplicationPrecedence for the dot product. Right now, such operations as 5.0 + b • c
result in error Adjacent operators are in unordered precedence groups 'AdditionPrecedence' and 'DefaultPrecedence'
.
Setting operator •
to MultiplicationPrecedence removes this error.
I'm digging through some old (2 yrs) repo by @dyashkir - and it's using a bespoke fork of Surge
it includes an initialization of a matrix by passing a valueFunc into it.
self.weightsInputToHidden = Matrix(rows: nodeCountHidden, columns: nodeCountInput, valueFunc: { return (drand48() - 0.5)
Is this kind of thing possible without do this? if so how? otherwise - would you please consider adding to this library? in mean time - I'll try to bring the old library up to date.
Thanks in advance
Hi Matt,
I'm just struggling with the need to perform matrix and vector operations in the context of associative matrices. Your Surge library seems to be pretty interesting (and usable!), however, it seems not yet to work on Swift 2. Do you plan a port in the near future?
Beside this, do you plan to enhance it with functions for matrix-vector functions, such as multiplying a matrix with a vector?
Best regards,
Hardy
When using numpy dividing an matrix by a vector is possible via broadcasting.
Any opinions on implementing broadcasting in Surge? Some thing similar to what numpy does.
https://docs.scipy.org/doc/numpy/user/basics.broadcasting.html
I've encountered the following error message when building Surge with Carthage. My environment is Xcode 9.2, and I have github "mattt/Surge" ~> 2.1.0
in the Cartfile. Not sure where the T.IndexDistance comes from. Thanks for the help
<project path>/Carthage/Checkouts/Surge/Sources/Surge/Matrix.swift:41:34: error: cannot convert value of type 'T.IndexDistance' to expected argument type 'Int'
self.init(rows: contents.count, columns: contents.first!.count, repeatedValue: 0.0)
~~~~~~~~~^~~~~
Int( )
I thin the correct code at https://github.com/mattt/Surge/blob/matrix-eigendecomposition/Source/Matrix.swift : 255
should refer to &workspace rather than &workspaceQuery
is that correct?
C
The current pod install version is 0.2.1, I think it's outdated. Can we bump it up the most recent version?
Surge is almost Carthage compatible. It looks like the only thing missing is marking the scheme for the Surge dynamic framework as "shared" in Xcode (then publishing a new release).
I get the warning when I try do pod update with podFile pod 'Surge', '~> 0.3.0'
!] Unable to satisfy the following requirements:
Surge (~> 0.3.0)
required by Podfile
Any plans to upgrade to Swift 2.0?
SPM 4.0 not work
Can be added to Arithmetic.swift
Or add initializers to create Matrix as row vector and column vector
Hi,
excellent library, there are examples ??
I would like to create an analyzer of the item using your library.
I do not find simple examples that have mic input (AV Foundation) and output the F0 using FFT or other algorithm.
Thank you
Hi Mattt,
When compiling Surge for the iPad 2 simulator or other 32-bit processor simulators, we get a bunch of compile-time errors along the lines of Use of unresolved identifier 'xyz'
, all Accelerate framework functions.
The problem is also described here: http://stackoverflow.com/questions/27114519/accessing-vdsp-from-swift-in-simulator-for-older-devices
Do you know of a workaround for this?
Thanks,
Geordie
I downloaded the framework and included in my xcode project and it seems to be working fine. However, I would like to access the matrix elements and I don't know how. Can someone help me?
//create arbitrary matrix, this works fine
var matrix : Matrix<Double> = Matrix<Double>([[4,7], [2,6]])
// I want to get the 4 but this doesn't work..
let rm11 = resultMatrix.subscript(row:1,col:1)
There seems to be an issue when initializing a matrix using an array. The backing grid does not contain the correct number of elements (e.g. rows*columns) in all cases.
examples:
Matrix([[1.0,2.0]])
results in a grid of [1.0, 2.0, 0.0] // contains 1 extra element
Matrix([[1.0,2.0,3.0]])
results in a grid of [1.0, 2.0, 3.0, 0.0, 0.0] // contains 2 extra elements
Matrix([[1.0,2.0],[1.0,2.0]])
results in a grid of [1.0, 2.0, 1.0, 2.0]
Matrix([[1.0,2.0, 3.0],[1.0,2.0, 3.0]])
results in a grid of [1.0, 2.0, 3.0, 1.0, 2.0, 3.0, 0.0, 0.0] // contains 2 extra elements
The problems seems to be caused by replaceSubrange. There seems to be a problem in the calculation for the half open range:
grid.replaceSubrange(i*n..<i*n+Swift.min(m, row.count), with: row)
The problem seems to be fixed by moving to a closed range using the same range calculation.
grid.replaceSubrange(i*n...i*n+Swift.min(m, row.count), with: row)
why isn't eigen solver in master branch?
import Surge
let X = Matrix<Float>([[1]])
let Y = Matrix<Float>([[]])
print("X")
print(X) // Ok
print("Y")
print(Y) // Ok
print("X*Y")
print(X*Y) // Hard crash
Output:
X
( 1.0 )
Y
( )
X*Y
ldb must be >= MAX(N,1): ldb=0 N=0ldc must be >= MAX(N,1): ldc=0 N=0BLAS error: Parameter number 11 passed to cblas_sgemm had an invalid value
When run like swift <script>.swift
, process prints that error msg and exits -1 (= 255), without printing a stacktrace. When run in Xcode, debugger doesn't activate.
Seems like Surge mul()
needs to guard against the rows=0 / columns=0 cases and return an appropriate empty Matrix, instead of letting blas crash?
is there a better way than using nslog ? are there any performance reports looked into?
looking for a report or mode to demonstrate performance gains.
I am able to get Surge to work as an iOS app and a Cocoa app but am unable to get it to work as a Command Line Tool. I followed all the same procedures as I did for the other apps but when I run the CLT, it (runtime) crashes with the following error:
dyld: Library not loaded: @rpath/libswiftAccelerate.dylib
Referenced from: /Users/norm/Library/Developer/Xcode/DerivedData/Surge_CLI-enrdshevubvulcaiimedbqrgxfrw/Build/Products/Debug/Surge.framework/Versions/A/Surge
Reason: image not found
I added the Accelerate.framework under Link Binary with Libraries but that did not solve the problem.
I was wondering if there was some workaround to get Surge working in a CLT.
I've just started of migrating my project to Xcode 10 and noticed that Surge (among many other dependencies) have problems when compiling for the arm64_32 architecture (used in Apple Watch Series 4).
Due to the weird nature of this chip (64-bit registers, but 32-bit pointer size) there's a conflict between the Swift's built-in Int
type and vDSP_Stride
typealias defined as:
typedef unsigned long vDSP_Length;
#if defined __arm64__ && !defined __LP64__
typedef long long vDSP_Stride;
#else
typedef long vDSP_Stride;
#endif
This results in errors such as:
Surge/Auxiliary.swift:92:43: error: cannot convert value of type 'Int' to expected argument type 'vDSP_Stride' (aka 'Int64')
vDSP_vclip(xm.pointer, xm.stride, y, z, rbp.baseAddress!, 1, numericCast(xm.count))
~~~^~~~~~
vDSP_Stride( )
Surge/Auxiliary.swift:106:44: error: cannot convert value of type 'Int' to expected argument type 'vDSP_Stride' (aka 'Int64')
vDSP_vclipD(xm.pointer, xm.stride, y, z, rbp.baseAddress!, 1, numericCast(xm.count))
~~~^~~~~~
vDSP_Stride( )
Surge/Auxiliary.swift:175:38: error: cannot convert value of type 'Int' to expected argument type 'vDSP_Stride' (aka 'Int64')
vDSP_vneg(xm.pointer, xm.stride, rbp.baseAddress!, 1, numericCast(xm.count))
~~~^~~~~~
vDSP_Stride( )
Surge/Auxiliary.swift:185:39: error: cannot convert value of type 'Int' to expected argument type 'vDSP_Stride' (aka 'Int64')
vDSP_vnegD(xm.pointer, xm.stride, rbp.baseAddress!, 1, numericCast(xm.count))
~~~^~~~~~
vDSP_Stride( )
Surge/Auxiliary.swift:251:42: error: cannot convert value of type 'Int' to expected argument type 'vDSP_Stride' (aka 'Int64')
vDSP_vthr(xm.pointer, xm.stride, y, rbp.baseAddress!, 1, numericCast(xm.count))
~~~^~~~~~
vDSP_Stride( )
Surge/Auxiliary.swift:264:43: error: cannot convert value of type 'Int' to expected argument type 'vDSP_Stride' (aka 'Int64')
do you plan support vDSP_DCT_Execute
Hi,
Just a question. Why are you scaling the magnitudes of the FFT by 2.0/Float(input.count)
? What does this number represent?
Thanks!
Hi,
I realized there is no methods to substract two matrix. Maybe it's related to Accelerate, that does not provide any method to substract matrix?
Maybe it makes sense to add a sub method and a - operator for matrix, that do something like :
add(lhs, mul(-1.0, rhs))
What do you think about this?
Hey Mattt - the two usage examples infer the arrays to be of type Int, but Surge.sum() and Surge.mul() expect type Double as their arguments. I forked and will submit a PR if you'd like.
Bart
import Surge
let n = [1, 2, 3, 4, 5]
let sum = Surge.sum(n) // 15.0
import Surge
let a = [1, 3, 5, 7]
let b = [2, 4, 6, 8]
let product = Surge.mul(a, b) // [2.0, 12.0, 30.0, 56.0]
I am attempting to plot a periodogram in Swift of a signal using Surge.
Code:
var fft_mat = Surge.pow(Surge.fft(signal), 2)
var const_mult = 2.0/Double(signal.count)
for var i in 0..<fft_mat.count { //multiply fft_mat by const_mult
fft_mat[i] = Float(const_mult) * fft_mat[i]
}
var pgram = fft_mat
Plotting pgram yields the following results
However, after loading and creating the exact same periodogram in Python I get a very different periodogram.
Code:
pgram = (2.0/len(signal)) * numpy.power(numpy.fft.fft(signal), 2)
Since I am using the exact same method to plot the periodogram (and the same data as well), I was wondering if there are some differences in the implementation of the Surge fft and numpy fft which might cause this issue?
In the process of investigating #82, I ran swiftlint
on the project and found 10 violations of the implicit_return
rule:
Loading configuration from '.swiftlint.yml'
Linting Swift files at paths
Linting 'HyperbolicTests.swift' (1/26)
Linting 'XCTestCase+Surge.swift' (2/26)
Linting 'AuxiliaryTests.swift' (3/26)
Linting 'ExponentialTests.swift' (4/26)
Linting 'MatrixTests.swift' (5/26)
Linting 'TrigonometricTests.swift' (6/26)
Linting 'ArithmeticTests.swift' (7/26)
Linting 'ConvolutionTests.swift' (8/26)
Linting 'PowerTests.swift' (9/26)
Linting 'Contents.swift' (10/26)
Linting 'Package.swift' (11/26)
Linting 'Exponential.swift' (12/26)
Linting 'ArraySliceUnsafeMemory.swift' (13/26)
Linting 'Statistics.swift' (14/26)
Linting 'Arithmetic.swift' (15/26)
Linting 'Power.swift' (16/26)
Linting 'Pointers.swift' (17/26)
Linting 'Auxiliary.swift' (18/26)
Linting 'FFT.swift' (19/26)
Linting 'UnsafeMutableMemory.swift' (20/26)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:29:9: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:30:13: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:41:9: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:42:13: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:55:9: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:56:13: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:57:17: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:69:9: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:70:13: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
/Users/mattt/Code/Surge/Sources/Surge/Pointers.swift:71:17: warning: Implicit Return Violation: Prefer implicit returns in closures. (implicit_return)
Linting 'Convolution.swift' (21/26)
Linting 'Trigonometric.swift' (22/26)
Linting 'Matrix.swift' (23/26)
Linting 'Hyperbolic.swift' (24/26)
Linting 'ArrayUnsafeMemory.swift' (25/26)
Linting 'UnsafeMemory.swift' (26/26)
Done linting! Found 10 violations, 0 serious in 26 files.
Currently, our CI is showing the build as passing, and project builds without warnings. Should we elevate linter diagnostics from its current advisory disposition to enforcement via a build phase or CI?
I use
pod 'Surge', '~> 0.2.1'
Hi,
I noticed the operator +
between two[Float]
s or two [Double]
s is overridden in Arithmetic.swift
.
However, I don't think this is a proper design since it changes the default behavior of swift.
For example, if I want to append one array to another, most people will do that in such way:
let arr: [Double] = [1.0, 2.0]
let newArr: [Double] = arr + [3.0]
We expect the newArr
will be [1.0, 2.0, 3.0]
, but with Surge
, it becomes [4.0]
.
It's hard to debug and to avoid it, we have to write something like this:
let arr: [Double] = [1.0, 2.0]
var newArr: [Double] = arr
newArr.append(3.0)
This forced us to use a variable, not a constant, which is not a good coding habit.
Any suggestions?
When I tried to perform subtraction between two matrices it seems that the "-" operator is not recognized. I did realize that there was no "sub" under the "Matrix" section in the README. But I also found the implementation code of the "-" operator in Matrix.swift. Why is it not available?
Thank you.
Hi,
In files where Surge is imported, the behavior of the + operator between arrays is modified by the library.
Normal Swift behavior : concatenation
[1.0, 2.0, 3.0] + [1.0, 2.0, 3.0] // [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
Surge overloaded behavior : addition
[1.0, 2.0, 3.0] + [1.0, 2.0, 3.0] // [2.0, 4.0, 6.0]
I don't know if it's a feature or a bug, but it took me 2 hours to find the problem after importing Surge into my code. So maybe it's a bad idea to overload this operator.
What do you think about removing this feature?
in Xcode 9,A compiler error:
Sequence' requires the types 'T' and 'ArraySlice' be equivalent
Is it compatible with Swift 3?
I built the Surge.framework but I cannot show the framework in the Finder. What to do?
How do I build the framework so that I can just put it into the Xcode project?
Thanks!
I use fft function for the real-time pitch detection , but troubled with the its memory consumption.
I perform fft about 60 times every one second, but memory is used at every function practice by number KB, as a result number GB is used immediately.
I write the program in swift and confirm that this memory leak happens in fft function.
Will there be the method not to increase memory consumption on using fft function many times?
fft関数を使ってリアルタイムピッチ検出に使用しているのですが、関数のメモリ使用量で困っています。
fftを一秒に60回ほど行うのですが、関数実行のたびにメモリが数KBづつ消費され、あっというまにGB単位のメモリが使われてしまいます。
プログラムはswiftで書いていて、このメモリリークがfft関数内で起きていることも確認しています。
fft関数を多用するにあたり、メモリ消費量を増加させない方法はあるのでしょうか?
I'd like to discuss adding support for the Float type to Surge. I've done this in apexskier/Surge on the float branch.
I was planning on using this to integrate Accelerate with SceneKit through Surge and a library I'm writing. I've since found that it's only necessary on 32 bit platforms, so I can see an argument against the extra code.
Any opinions?
Now I use at 2.1.0 Cannot invoke 'dist' with an argument list of type '([Float], y: [Float])' why?
/Users/jpope/Documents/gitWorkspace/Akari3/Carthage/Checkouts/Surge/Sources/Surge/Matrix.swift:432:13: error: Shorthand Operator Violation: Prefer shorthand operators (+=, -=, *=, /=) over doing the operation and assigning. (shorthand_operator)
/Users/jpope/Documents/gitWorkspace/Akari3/Carthage/Checkouts/Surge/Sources/Surge/Matrix.swift:460:13: error: Shorthand Operator Violation: Prefer shorthand operators (+=, -=, *=, /=) over doing the operation and assigning. (shorthand_operator)
using this repo -
carthage update --platform osx
https://github.com/daisukeokaoss/Akari3
Why doesn't surge use cblas for matrix multiplication?
This project is abandoned?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.