Paw*_*ski 10 arrays vector multiplying swift
我需要将数组乘以另一个数组,就像数学中的向量一样.
例如:
__CODE__
__CODE__
__CODE__
我甚至无法弄清楚代码,我已经尝试逐个元素,但这对我来说似乎是一个解决方案,任何想法?(我是swift的初学者)
Mar*_*n R 21
"压缩"两个数组会产生一系列元组(a_i, b_i)
,然后可以按元素相乘:
let A = [1,2,3,4]
let B = [2,3,4,5]
let C = zip(A, B).map { $0 * $1 }
print(C) // [2, 6, 12, 20]
Run Code Online (Sandbox Code Playgroud)
(如果数组具有不同的长度,则zip静默地忽略较长数组的额外元素.)
正如@appzYourLife正确地说的那样,你也可以直接将乘法运算符作为参数传递map而不是闭包表达式:
let C = zip(A, B).map(*)
Run Code Online (Sandbox Code Playgroud)
如果您的矢量有4个组件,则可以使用iOS提供的超快simd(单指令多数据)指令.
它使用CPU执行并行计算.
给出了4个组成部分的2个向量 Int32
import simd
let a = int4(1, 2, 3, 4)
let b = int4(2, 3, 4, 5)
Run Code Online (Sandbox Code Playgroud)
你可以乘以每个组件
let res = a &* b // int4(2, 6, 12, 20)
Run Code Online (Sandbox Code Playgroud)
如Martin R所述,该模块也提供了阵列
float(s)或阵列.double(s)simd
对于矢量乘法的话题,另一种选择(除了整齐的simd由@ appzYourLife的回答覆盖)正在使用的加速框架。在这种情况下,特别是VDSP方法 vDSP_vmul和vDSP_vmuld,
Run Code Online (Sandbox Code Playgroud)func vDSP_vmul(UnsafePointer<Float>, vDSP_Stride, UnsafePointer<Float>, vDSP_Stride, UnsafeMutablePointer<Float>, vDSP_Stride, vDSP_Length) func vDSP_vmulD(UnsafePointer<Double>, vDSP_Stride, UnsafePointer<Double>, vDSP_Stride, UnsafeMutablePointer<Double>, vDSP_Stride, vDSP_Length)
例如,后者用于两个Double值向量的逐元素乘法:
import Accelerate
let a = [1.5, 2.5, 16.5, 7.5, 3.0]
let b = [3.0, 4.5, 0.25, 3.5, 6.25]
var result = [Double](repeating: 0.0, count: a.count)
if a.count == b.count {
vDSP_vmulD(a, 1, b, 1, &result, 1, vDSP_Length(a.count))
print(result) // [4.5, 11.25, 4.125, 26.25, 18.75]
}
Run Code Online (Sandbox Code Playgroud)
请注意,使用Accelerate并不像其他方法那样用户友好且安全,因为要vDSP_vmulD捕获的向量参数被捕获为不安全的指针(UnsafePointer<Double>),因此我们有责任确保输入向量的长度相同,并且结果向量在乘以向量之前正确分配vDSP_vmulD。