Giter VIP home page Giter VIP logo

swiftaccelerate's Introduction

SwiftAccelerate

This note provides a concise tutorial on how you may use Apple's Accelerate framework with the Swift programming language to perform vector/matrix manipulations, including matrix transposes, dot products, matrix inversions, etc. A playground illustrating all the functions discussed here is included. Also, a better formatted version can be accessed at here.

Linking Your Project Against Accelerate

  • Select your project by clicking on the blue icon in the top left corner.
  • In the TARGETS list (the panel in the middle), select the target you're compiling and then activate the Build Phases tab.
  • Click on the little triangle in front of Link Binary With Libraries.
  • Click on the + sign and select Accelerate.framework in the popup.

Importing Accelerate

Now that your project is linked against Accelerate, you can import it in your .swift file by issuing:

import Accelerate

Vector & Scalars

The general syntax for adding a scalar to a vector and for multiplying or dividing a vector by a scalar is as follows

vDSP_vs***D(vector, 1, &scalar, &result, 1, length_of_vector)

The 1s tells the function to operate on each element of the vector. If you replace 1 with 2, it'll operate on every other element instead. Needless to say, for most LA applications, you'll be sticking with 1, as we do for the rest of the tutorial. A few example should make everything crystal clear:

var v = [1.0, 2.0]
var s = 3.0
var vsresult = [Double](count : v.count, repeatedValue : 0.0)
vDSP_vsaddD(v, 1, &s, &vsresult, 1, vDSP_Length(v.count))
vsresult    // returns [4.0, 5.0]

vDSP_vsmulD(v, 1, &s, &vsresult, 1, vDSP_Length(v.count))
vsresult    // returns [3.0, 6.0]

vDSP_vsdivD(v, 1, &s, &vsresult, 1, vDSP_Length(v.count))
vsresult    // returns [0.333333333333333, 0.666666666666667]

Vector & Vector

Vector-vector operations pose no challenge to Accelerate and the associated functions look like

vDSP_v***D(vector_1, 1, vector_2, 1, &result, 1, length_of_vector)

Here are a few worked-out examples:

var v1 = [2.0, 5.0]
var v2 = [3.0, 4.0]
var vvresult = [Double](count : 2, repeatedValue : 0.0)
vDSP_vaddD(v1, 1, v2, 1, &vvresult, 1, vDSP_Length(v1.count))
vvresult    // returns [5.0, 9.0]

vDSP_vmulD(v1, 1, v2, 1, &vvresult, 1, vDSP_Length(v1.count))
vvresult    // returns [6.0, 20.0]

vDSP_vdivD(v1, 1, v2, 1, &vvresult, 1, vDSP_Length(v1.count))
vvresult    // returns [1.5, 0.8]

Dot Product

var v3 = [1.0, 2.0]
var v4 = [3.0, 4.0]
var dpresult = 0.0
vDSP_dotprD(v3, 1, v4, 1, &dpresult, vDSP_Length(v3.count))
dpresult    // returns 11.0

Matrix Multiplication

Matrices are passed into Accelerate as 1D arrays. As a result, matrix addition/subtraction is the same as vector addition/subtraction.

Matrix multiplication, on the other hand, is a bit more involved and requires this function:

vDSP_mmulD(matrix_1, 1, matrix_2, 1, &result, 1, 
           rows_of_matrix_1, columns_of_matrix_2, 
           columns_of_matrix_1_or_rows_of_matrix_2)

For example,

    var m1 = [ 3.0, 2.0, 4.0, 5.0, 6.0, 7.0 ]
    var m2 = [ 10.0, 20.0, 30.0, 30.0, 40.0, 50.0]
    var mresult = [Double](count : 9, repeatedValue : 0.0)

    vDSP_mmulD(m1, 1, m2, 1, &mresult, 1, 3, 3, 2)
    mresult    // returns [90.0, 140.0, 190.0, 280.0, 370.0, 270.0, 400.0, 530.0]

Matrix Transpose

Matrix transpose can be obtained with

    vDSP_mtransD(matrix, 1, &result, 1, number_of_rows_of_result, number_of_columns_of_result)  

Like this,

    var t = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
    var mtresult = [Double](count : t.count, repeatedValue : 0.0)
    vDSP_mtransD(t, 1, &mtresult, 1, 3, 2)
    mtresult    // returns [1.0, 4.0, 2.0, 5.0, 3.0, 6.0]

Matrix Inversion

Matrix inversion takes a bit more effort, but can be accomplished with the function below (see Stack Overflow):

    func invert(matrix : [Double]) -> [Double] {
        
        var inMatrix = matrix
        
        var pivot : __CLPK_integer = 0
        var workspace = 0.0
        var error : __CLPK_integer = 0
        
        var N = __CLPK_integer(sqrt(Double(matrix.count)))
        dgetrf_(&N, &N, &inMatrix, &N, &pivot, &error)
        
        if error != 0 {
            return inMatrix
        }
        
        dgetri_(&N, &inMatrix, &N, &pivot, &workspace, &N, &error)
        return inMatrix
    }


    var m = [1.0, 2.0, 3.0, 4.0]
    invert(m)    // returns [-2.0, 1.0, 1.5, -0.5]

swiftaccelerate's People

Contributors

haginile avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.