許多繁重的資料任務以及最佳化問題都可歸結為在多維陣列上執行計算。今天,我們想與你分享適合此類計算的基礎庫——Multik。
Multik同時提供多維陣列資料結構和數學運算的實現。該庫具有簡單明瞭的API,並提供了最佳化過的效能。
使用Multik
事不宜遲,這裡是一些用到Multik的操作
建立多維陣列
建立向量:
val a = mk.ndarray(mk[1, 2, 3])
/* [1, 2, 3] */
透過集合建立向量:
val myList = listOf(1, 2, 3)
val a = mk.ndarray(myList)
/* [1, 2, 3] */
建立矩陣(二維陣列):
val m = mk.ndarray(mk[myList, myList])
/*
[[1, 2, 3],
[1, 2, 3]]
*/
建立全是0且固定長度的矩陣:
mk.empty<Double, D2>(3, 4)
/*
[[0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0],
[0.0, 0.0, 0.0, 0.0]]
*/
建立一個單位矩陣(對角線為1,其餘設定為0):
val e = mk.identity<Double>(3) // create an identity array of shape (3, 3)
/*
[[1.0, 0.0, 0.0],
[0.0, 1.0, 0.0],
[0.0, 0.0, 1.0]]
*/
建立3維陣列(multik最多支援4維):
mk.d3array(2, 2, 3) { it * it }
/*
[[[0, 1, 4],
[9, 16, 25]],
[[36, 49, 64],
[81, 100, 121]]]
*/
在多維陣列上執行數學運算
val a = mk.ndarray(mk[mk[1.0,2.0], mk[3.0,4.0]])
val b = mk.identity<Double>(2)
a + b
/*
[[2.0, 2.0],
[3.0, 5.0]]
*/
a - b
/*
[[0.0, 2.0],
[3.0, 3.0]]
*/
b / a
/*
[[1.0, 0.0],
[0.0, 0.25]]
*/
b * a
/*
[[1.0, 0.0],
[0.0, 4.0]]
*/
按元素進行數學運算
mk.math.sin(a) // element-wise sin
mk.math.cos(a) // element-wise cos
mk.math.log(b) // element-wise natural logarithm
mk.math.exp(b) // element-wise exp
mk.linalg.dot(a, b) // dot product
彙總函式
mk.math.sum(a) // array-wise sum
mk.math.min(b) // array-wise minimum elements
mk.math.cumSum(b, axis=1) // cumulative sum of the elements
mk.stat.mean(a) // mean
mk.stat.median(b) // median
遍歷操作
a.filter { it > 3 } // select all elements that are larger than 3
b.map { (it * it).toInt() } // return squares
a.groupNdarrayBy { it % 2 } // group elements by condition
a.sorted() // sort elements
索引/切片/迴圈
a[2] // select the element at the 2 index for a vector
b[1, 2] // select the element at row 1 column 2
b[1] // select row 1
b[0.r..2, 1] // select elements at rows 0 and 1 in column 1
b[0..1..1] // select all elements at row 0
for (el in b) {
print("$el, ") // 1.5, 2.1, 3.0, 4.0, 5.0, 6.0,
}
// for n-dimensional
val q = b.asDNArray()
for (index in q.multiIndices) {
print("${q[index]}, ") // 1.5, 2.1, 3.0, 4.0, 5.0, 6.0,
}
Multik架構
最初,我們嘗試將Kotlin繫結新增到現有解決方案,例如NumPy。然而,事實證明這很笨重且引入了不必要的環境複雜性,而且對開銷來說幾乎沒有任何好處。結果我們放棄了這種方案,並從頭開始了Multik。
在Multik中,資料結構以及其上操作的實現是分離的,你需要將它們作為單獨的依賴項新增到專案中。無論你決定在專案中使用哪種實現,該方案提供了一致的API。那麼這些不同的實現是什麼?
當前,有三種不同的方案:
multik-jvm
:數學運算的Kotlin/JVM實現。multik-native
:C ++實現。 OpenBLAS用於線性代數。multik-default
:預設實現,它結合了原生和JVM實現以達到最優效能。 當然你也可以自己實現!
Multik仍處於開發的早期階段,我們期待你的反饋,功能想法和貢獻!該專案的GitHub倉庫,嘗試Multik,讓我們知道你在未來版本中想看到什麼。謝謝!