Swift:如何将数组乘以数组(Math:vector by vector)

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)

  • 只是一个非常微小的改进:`map {$ 0*$ 1}`可以变成`map(*)` (7认同)
  • @GurjitSingh:`let sum = C.reduce(0, +)` (2认同)

Luc*_*tti 6

单指令多数据

如果您的矢量有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


dfr*_*fri 5

加快框架

对于矢量乘法的话题,另一种选择(除了整齐的simd由@ appzYourLife的回答覆盖)正在使用的加速框架。在这种情况下,特别是VDSP方法 vDSP_vmulvDSP_vmuld

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)
Run Code Online (Sandbox Code Playgroud)

例如,后者用于两个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