英文:
Vector multiplication on a 2D array using Accelerate in Swift
问题
Accelerate works with flattened arrays, but you can achieve the desired element-wise vector multiplication on a 2D array in Swift using Accelerate by properly reshaping your arrays before performing the multiplication. Here's how you can do it:
import Foundation
import Accelerate
let a: [Float] = [3, 5, 8, 7, 2,
1, 4, 9, 1, 3,
2, 7, 3, 1, 2,
5, 4, 9, 1, 6,
4, 2, 9, 6, 7]
let b: [Float] = [2, 0.5, 9, 1, 18]
let numRows = 5 // Number of rows in the 2D array
let numCols = 5 // Number of columns in the 2D array
var c: [Float] = Array(repeating: 0, count: numRows * numCols)
vDSP_mtrans(a, 1, &a, 1, vDSP_Length(numCols), vDSP_Length(numRows))
vDSP_mmul(a, 1, b, 1, &c, 1, vDSP_Length(numCols), 1, vDSP_Length(numRows))
vDSP_mtrans(&c, 1, &c, 1, vDSP_Length(numRows), vDSP_Length(numCols))
print(c)
This code will properly reshape the arrays, perform the element-wise multiplication, and give you the correct result in the c
array.
英文:
I have the following NumPy example which does element-wise vector multiplication on a 2D array:
import numpy as np
a = np.array([[3, 5, 8, 7, 2],
[1, 4, 9, 1, 3],
[2, 7, 3, 1, 2],
[5, 4, 9, 1, 6],
[4, 2, 9, 6, 7]])
b = np.array([[2],
[0.5],
[9],
[1],
[18]])
c = a * b
print(c)
This prints the following:
[[ 6. 10. 16. 14. 4. ]
[ 0.5 2. 4.5 0.5 1.5]
[ 18. 63. 27. 9. 18. ]
[ 5. 4. 9. 1. 6. ]
[ 72. 36. 162. 108. 126. ]]
I'm trying to do this calculation in Swift using Accelerate as shown below:
import Foundation
import Accelerate
let a: [Float] = [3, 5, 8, 7, 2,
1, 4, 9, 1, 3,
2, 7, 3, 1, 2,
5, 4, 9, 1, 6,
4, 2, 9, 6, 7]
let b: [Float] = [2,
0.5,
9,
1,
18]
var c: [Float] = Array(repeating: 0, count: 25)
vDSP_vmul(a, 1, b, 1, &c, 1, 25)
print(c)
The Swift code prints the following which is not correct:
[6.0, 2.5, 72.0, 7.0, 36.0, 0.0, 0.0, 0.0, 1.104904e-39, 4.7331654e-30, 3.7740115e-24, 6.737052e-37, 1.806498e-35, 1.19422e-39, 5.1722454e-26, 5.9787867e-25, 2.7286e-41, 0.0, 0.0, 0.0, 1.6543612e-24, 0.0, 0.0, 5.533857e-39, 3.73e-43]
Accelerate works with flatten arrays whereas NumPy supports 2D arrays. So I'm not sure how to multiply the 2D array with a vector in Accelerate. Is there a different Accelerate function that I should use for this type of multiplication?
答案1
得分: 1
要将这作为列进行相乘,您需要使用步幅(stride)。如果您正在使用 Accelerate,那么您可能也想避免额外的分配。您可以使用 Array(unsafeUninitializedCapacity:)
来填充所有数据,如下所示:
let c = Array(unsafeUninitializedCapacity: a.count) { output, initializedCount in
a.withUnsafeBufferPointer { abuffer in
for i in b.indices {
vDSP_vmul(abuffer.baseAddress! + i, b.count, // 通过列大小逐步遍历 a
b, 1, // 逐个遍历 b
output.baseAddress! + i, b.count, // 通过列大小逐步遍历输出
vDSP_Length(b.count))
}
initializedCount = abuffer.count
}
}
// [6.0, 10.0, 16.0, 14.0, 4.0, 0.5, 2.0, 4.5, 0.5, 1.5, 18.0, 63.0, 27.0, 9.0, 18.0, 5.0, 4.0, 9.0, 1.0, 6.0, 72.0, 36.0, 162.0, 108.0, 126.0]
英文:
To multiply this as a column, you need to use a stride. If you're taking the trouble to use Accelerate, then you probably also want to avoid extra allocations. You can use Array(unsafeUninitializedCapacity:)
to fill in all the data like this:
let c = Array(unsafeUninitializedCapacity: a.count) { output, initializedCount in
a.withUnsafeBufferPointer { abuffer in
for i in b.indices {
vDSP_vmul(abuffer.baseAddress! + i, b.count, // stride through a by the column size
b, 1, // stride one-by-one through b
output.baseAddress! + i, b.count, // stride through the output by the column size
vDSP_Length(b.count))
}
initializedCount = abuffer.count
}
}
// [6.0, 10.0, 16.0, 14.0, 4.0, 0.5, 2.0, 4.5, 0.5, 1.5, 18.0, 63.0, 27.0, 9.0, 18.0, 5.0, 4.0, 9.0, 1.0, 6.0, 72.0, 36.0, 162.0, 108.0, 126.0]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论