1

I'm looking for vector (fast) code that does what matlab find function does without loops. find returns both value and index for a given function. Swift's filter, map or reduce do not return indices.

example

X = [18 3 1 11; 8 10 11 3; 9 14 6 1; 4 3 15 21]

[row,col] = find(X>0 & X<10,3)

row =

     2
     3
     4


col =

     1
     1
     1

From the matlab docs

[row,col] = find(___) returns the row and column subscripts of each nonzero element in array X using any of the input arguments in previous syntaxes.

  • *"find returns both value and index ..."* I cannot see that from your example or the Matlab documentation, the result are only row/column indices. – Do you need a method for "matrices" (which are not a built-in Swift type) or just for arrays (aka "vectors") ? – Martin R May 06 '15 at 21:05
  • For now, I'd be happy to get started with vectors and then move up to matrices. – μολὼν.λαβέ May 06 '15 at 21:12
  • Have you looked into Accelerate framework. I don't have all methods in memory, but you might find something performant there – Volker May 06 '15 at 21:15
  • I spent some time grepping through the docs but didn't find results for vector but I think there could be for a matrix??? It was a bit confusing reading it. – μολὼν.λαβέ May 06 '15 at 21:17

2 Answers2

1

enumerate() returns a sequence of index/element pairs which can be filtered:

let vec = [18, 3, 1, 11, 8, 10, 11, 3, 9]
let result = filter(enumerate(vec), { (idx, elem) in elem > 2 && elem < 10 } )
println(result) // [(1, 3), (4, 8), (7, 3), (8, 9)]

Or, if you only want the indices:

let indexes = filter(enumerate(vec), { (idx, elem) in elem > 2 && elem < 10 } ).map { $0.0 }
println(indexes) // [1, 4, 7, 8]
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Great, to move on to a matrix, would you need to pull in the accelerate framework? – μολὼν.λαβέ May 06 '15 at 21:15
  • 1
    @GAlexander: You *can* represent a matrix as a nested array, see http://stackoverflow.com/questions/24051490/multidimensional-arrays-in-swift, http://stackoverflow.com/questions/28936824/what-is-the-syntax-for-multidimensional-array-in-swift or similar threads. The methods from the Accelerate framework are probably faster, but they use pure C data types, which makes it a bit more difficult to use them in Swift functions like `filter`. I do not have much experience with Accelerate, so I cannot advise you on that. – Martin R May 06 '15 at 21:23
  • I am using them. for FFT with Swift arrays. Should work well. – Volker May 06 '15 at 21:43
  • @Volker: Has Accelerate methods to find indices of vector/matrix elements satisfying a predicate? – Martin R May 06 '15 at 21:46
  • @MartinR as in my comment to the question i don't have the full functions in memory, but when browsing last I think I slaw one chance . Might have needed to functions like a threshold one first and then the index/value extraction. I might be wrong, though. – Volker May 07 '15 at 05:32
0

The Swift Matrix Library may be appropriate here. It implements argwhere along with many scientific functions.

This library was inspired by Python and Matlab. This framework calls the Accelerate framework from Swift and hence is pretty speedy (speed tests can be found in Speed).

Further features can be found in Examples but it provides the following features:

  • provides an ndarray and matrix class. All mathematical operators (+-*/) call Accelerate functions.
  • "Simple math" functions (pow/log/exp/sqrt/etc) on ndarray or matrix call Accelerate
  • allows access to easy initing functions (ones/zeros/etc)
  • More complex math can also be found: eig, svd, fft, solve, dot, inv are all implemented.

Installation details can be found in Install.

(note: I am the author)

Community
  • 1
  • 1
Scott
  • 2,568
  • 1
  • 27
  • 39