開發者指南:透過 Swift 重新認識Accelerate Framework


iOS SDK中隱藏的幾個沒有被充分利用和不太受歡迎的框架,但其中有一些可以是相當實用且省時的工具,Accelerate Framework就是其中一個,它可用於Swift和Obj-C,Accelerate Framework讓開發人員在大規模的數學和圖像計算工作上更容易,優化任務處理的性能,因此,它廣泛應用於機器學習的領域。該框架包含用於向量和矩陣數學、數位信號處理、大量處理和圖像處理的各種C API。如果這聽起來很複雜,別擔心。你不需要知道很多數學,只要你明白這些概念。

Credit:以下文章是由Jeff Biggus開發程式碼的相關評論,讀者可以參考原始的GitHub連結

首先,我們來到Xcode並創建一個新的playground,可以命名為任何你想要的名稱,並將平台設置為macOS,創建playground之後,請選擇所有內容並將其刪除,這樣就可以有一個乾淨的工作,在這個playground頂部請輸入以下內容來import下列這些函式庫。

現在我們準備開始用Accelerate框架編寫程式碼了!

accelerate-playgrounds

BLAS(Basic Linear Algebra Subroutines:基本線性代數子程序)

<在第一個例子中,我們將討論如何解決一個常見的線性代數方程式:

其中”A”是常數,x和y是一個矩陣。如果你不知道什麼是矩陣或向量也不用擔心,矩陣基本上是數組,行數是1或列數是1的矩陣又可分別稱為行向量和列向量,所以開始前,首先我們需要定義我們的向量。

在上面的代碼中,我們定義了我們的向量x和y,分別為數字 1,2,3 3,4,5 的數組,有了向量x和y,現在來定義的常數,在這個例子中,我決定使用10,但你可以使用任何數字,接下來,我們要計算一下:

現在複製下面給的函式。

cblas_saxpy(_:_:_:_:_:_:)是一個函式,它計算一個常數乘以一個向量加一個向量,這正是我們想要的。參數定義(按順序):

  • 向量中的元素個數
  • 常數A
  • “x”向量
  • “x”向量中的stride(兩個元素的距離)
  • “y”向量
  • “y”向量中的stride。

BLAS-sample

在第二個例子中,我們將使用內積乘以向量:

我們將使用與前面範例相同的向量,把y重新設置為原來的樣子,然後我們將使用函數cblas_sdot(_:_:_:_:_:)乘以兩個向量。

該函數的參數類似於cblas_saxpy(_:_:_:_:_:_:)函數,唯一的區別是,由於我們乘以2個向量,所以不存在常數的參數,對於BLAS函式庫中的更多功能,讀者有興趣可以查看此處

LAPACK (Linear Algebra Package:線性代數套件)

LAPACK並不是一個由Apple發行Accelerate framework內的標準函式庫,但Swift支援它,這是一個好消息,因為LAPACK有很多優點,在下一個例子中,我們將解決聯立方程式,要解決的3個方程式如下:

  1. 7x+5y-3z = 16
  2. 3x-5y+2z= -8
  3. 5x+3y-7z= 0

將以下程式碼複製到你的playground。

我們來看看程式碼,結果會出現什麼。

  • 第1行:我們正在使用以下等式定義一個LAInt類型。
  • 第7行:現在,我們定義矩陣A和向量B,它將保存我們聯立方程式中的常數。(矩陣A將存放方程式左側的常數,向量B將存放方程式右側的常數)
  • 第9行:我們定義要解決的聯立方程式個數。
  • 第15行:現在,我們定義了一些變量,這些變量將被放入sgesv_(_:_:_:_:_:_:_:_:)子程式的參數中。
  • 第17行:我們執行sgesv子程式。參數定義(按順序):求解線性方程的數量,向量B中的列數,矩陣A係數,矩陣A中的列,置換矩陣,向量B係數,向量B中的列元素,和outputOK。
  • 第20行:確定此變量計算是否正常。如果outputOk = 0,則計算成功,否則方程式不能被解決。

如果所有的計算都正確,那麼當輸入b時,輸出應該是[1,3,2],這些是x,y和z的解答。

LAPACK sample

simd (Single Instruction Multiple Data:單指令多數據)

simd也是Accelerate框架之外的另一個函式庫,它能與Swift兼容,這個函式庫簡化了許多數學計算,還記得BLAS第一個例子?我們必須使用cblas_saxpy(_:_:_:_:_:_:)函式,其實,這邊有一個更簡單的方法來執行計算:

為了避免變量的重疊,我們來將x、y轉變為p、q。首先,通過定義向量p和q來完成。

現在….神奇的事情發生了:

就這樣而已!這比使用cblas_saxpy(_:_:_:_:_:_:)容易得多,雖然這個例子比較簡單,但simd更常用於2D,3D和4D數學和幾何,它也適合與其他函式庫搭配使用,如ModelIO、SpriteKit、Metal等。但是,由於這些數學過於複雜,所以本篇教程中不會碰到。

simd-sample

vecLib

vecLib是一個函式庫,它包含可以抽象向量處理函式庫的函數,如果你在應用程序中使用向量指令,建議你使用這些功能,以便程式碼可以輸出到不同的CPU架構,我們從複製以下代碼開始,我們只需要定義一個創建Float數組的函數:

在第一個例子中,我們將計算一個向量的絕對值。例如,如果我定義了一個向量A = [-3,-2,-5,-10],則通過該函數後,向量應該讀取[3,2,5,10],我們將用於完成此計算的函數是vvfabsf(_:_:_:)

現在首先要做的是定義參數,我們需要的參數有一個包含每個集合中的元素個數的整數、一個input array和一個output array。

我們已經定義完參數了,現在只剩下一件事了:將參數插進函式中!

如果一切正常,你得到的輸出結果應該會是[3,2,5,10]!

在第二個例子中,我們將使用vvintf(_:_:_:)函式截斷向量中的數字,將程式碼複製並貼到你的playground裡面:

與前面的例子類似,我們首先定義vvfabsf函式所需的參數。然後,我們只需要將它們插入該函式裡面。

現在這邊給讀者一個小挑戰!看你能否通過使用vvsqrtf(_:_:_:) 函式並定義參數,可以將16,9,4和1放在一個向量中,然後找到它們的平方根?

提示: 它與前面的例子非常類似!

希望讀者都能夠完成挑戰!但是如果你無法完成也不用擔心!這是比較進階的東西,如果你第一次嘗試無法順利解題也沒關係。
下列程式碼就是如何找到16,9,4和1平方根的方法。

cSquareRoots的輸出應為[4,3,2,1]。

接著來介紹vecLib的最後一個例子:如果採用vvrecf(_:_:_:)這個逆向轉換函式,看看你能否針對一個包含四個分數[1/3, 2/5, 1/8, -3/1]的向量,將其中元素的分子與分母交換後轉為新的數值?參數與前面的例子相同。

希望讀者都能順利完成這個範例,這個例子的程式碼如下:

這四個例子只是快速瀏覽在開發應用程序中使用vecLib的可能性,還有更多的函式可以用來完成你的數學計算需求。有關vecLib函式庫中可用的更多功能和子程式,請查看Apple Developer的官方vecLib文檔

vvintf-sample

vDSP

vDSP是一個支援C和Swift API的函式庫,用在單一向量執行常用的程序,與先前的函式庫類似,讀者可以使用此函式庫執行矩陣和向量算術…但我認為那些已經足夠了,所以讓我們嘗試一下不同的東西,假設你有一組描述路徑的點,我們每一步離起點有多遠?使用vDSP解決這個問題非常簡單,因為我們在vDSP函式庫中有幾個計算距離功能!

我們首先在NSBezierPath上定義幾個點。

請注意我們的點全部聚焦在y軸上。如此一來,在以後仔細驗證計算時,對我們來說會更容易。現在,我們將用於計算距離的函數是vDSP_vdist(_:_:_:_:_:_:_:)。參數定義:x值,x的stride,y值,y的stride,輸出向量結果,輸出向量結果的stride以及要處理元素的數量。

現在,很難確認我們是對的…但是請忍受一下,如果你注意一下上列各個點,會發現每個點都是用前一個點添加10做為下一個點。所以按照升序規則,我們的距離是10,20,30 …等等。 因此,由於我們增加相同的常數,如果繪製這些點,將得到一個線性圖。如果在輸出控制台中點擊(10 times)旁邊的小眼睛圖標,應該出現看到下圖結果。

graph

如果我們想計算出移動的全部距離怎麼辦?只需要計算10 + 20 + 30 + blah blah blah,我們是軟體工程師…不會想耗神逐一計算到80。我們可以透過程式碼,讓電腦幫我們完成這些事,並給我們正確的輸出結果,要計算總距離,只需輸入以下程式碼。

就這麼簡單!你應該會看到360這個輸出數值。

總結

這就是本教程中關於Accelerate的所有內容,這是該框架中大部分的數學計算。還有兩個更重要的函式庫:BNNS (Basic Neural Network Subroutines:基本神經網絡子程序)vImage(圖像上的向量計算)。但是,如果我在本教程中介紹它們,那篇幅可能會太過冗長。此外,我認為我們今天已經學習到足夠的數學,其他的函式庫待下一次再來研究。

以供參考,你可以在GitHub下載完整的Xcode playground檔案。

有關Accelerate框架的更多詳細資訊,可以參考Accelerate官方文檔

譯者簡介:陳奕先-過去為平面財經記者,專跑產業新聞,2015年起跨進軟體開發世界,希望在不同領域中培養新的視野,於新創學校ALPHA Camp畢業後,積極投入iOS程式開發,目前任職於國內電商公司。聯絡方式:電郵[email protected]

FB : https://www.facebook.com/yishen.chen.54
Twitter : https://twitter.com/YeEeEsS

原文Introduction to the Accelerate Framework in Swift


Sai Kambampati 是程式開發員,生活於美國加州薩克拉門托,於2017獲得Apple's WWDC獎學金。精於 Swift及Python語言,渴望自家開發人工智能產品。閒時喜歡觀看Netflix、做健身或是遛漣圖書館中。請到推特追蹤 @Sai_K1065 。

blog comments powered by Disqus
訂閲電子報

訂閲電子報

AppCoda致力於發佈優質iOS程式教學,你不必每天上站,輸入你的電子郵件地址訂閱網站的最新教學文章。每當有新文章發佈,我們會使用電子郵件通知你。

已收你的指示。請你檢查你的電郵,我們已寄出一封認證信,點擊信中鏈結才算完成訂閱。

Shares
Share This