我需要将数组乘以另一个数组,就像数学中的向量一样。
例如为:
Sub copystatus()
Dim LR As Long
Dim LC As Integer
Dim LB As Long
Dim ws As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim cLista As String
Application.ScreenUpdating = False
Application.EnableEvents = False
Set ws = ThisWorkbook.sheets("totale")
Set ws2 = ThisWorkbook.sheets("liste")
LR = ws.Cells(Rows.Count, 5).End(xlUp).Row
LC = ws2.Cells(Rows.Count, 2).End(xlUp).Row
With ws
For x = 2 To LR
For i = 2 To LC
If .Cells(x, 5).value = ws2.Cells(i, 2).value Then
cLista = ws2.Cells(i, 1).value
Set ws3 = ThisWorkbook.sheets(cLista)
On Error GoTo ErrorHandler
LB = ws3.Cells(Rows.Count, 1).End(xlUp).Row
ws3.Rows(LB + 1).value = .Rows(x).value
ws3.Rows(1).value = .Rows(1).value
End If
Next i
Next x
End With
Application.ScreenUpdating = True
Application.EnableEvents = True
ErrorHandler:
End Sub
A = [1,2,3,4]
B = [2,3,4,5]
我甚至无法弄清楚代码,我已经尝试逐个元素地执行此操作,但这对我来说似乎是一个混乱的解决方案,任何想法? (我是swift的初学者)
答案 0 :(得分:17)
"正在压缩"这两个数组给出了一系列元组(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]
(如果数组的长度不同,则zip
会静默忽略较长数组的额外元素。)
正如@appzYourLife正确说的那样,你也可以传递乘法
operator直接作为map
的参数而不是闭包表达式:
let C = zip(A, B).map(*)
答案 1 :(得分:6)
如果您的矢量有4个组件,则可以使用iOS提供的超快simd
(单指令多数据)指令。
它使用CPU执行并行计算。
给出2个Int32
import simd
let a = int4(1, 2, 3, 4)
let b = int4(2, 3, 4, 5)
你可以将每个组件相乘
let res = a &* b // int4(2, 6, 12, 20)
如 Martin R 所述,
float(s)
模块也提供了double(s)
或simd
的数组。
答案 2 :(得分:5)
对于向量乘法的主题,另一个替代方案(除the neat simd
covered by @appzYourLife's answer之外)正在使用Accelerate framework。在这种情况下,特别是vDSP methods vDSP_vmul
和vDSP_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)
例如,后者用于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]
}
请注意,使用Accelerate不像其他方法那样用户友好且安全,因为vDSP_vmulD
的向量参数被捕获为不安全指针(UnsafePointer<Double>
),并且我们有责任确保输入向量具有相同的长度,以及在向量乘以vDSP_vmulD
之前正确分配结果向量。
答案 3 :(得分:1)
使用Swift 5,您可以使用以下方法之一来解决您的问题。
以下Playground示例代码显示了使用SIMD4
的逐元素乘法:
let vector1 = SIMD4(1, 2, 3, 4)
let vector2 = SIMD4(2, 3, 4, 5)
let vector3 = vector1 &* vector2
print(vector3) // prints: SIMD4<Int>(2, 6, 12, 20)
请注意,SIMD
协议符合ExpressibleByArrayLiteral
。因此,您可以使用数组文字初始化向量:
var vector1: SIMD4 = [1, 2, 3, 4]
let vector2: SIMD4 = [2, 3, 4, 5]
vector1 &*= vector2
print(vector1) // prints: SIMD4<Int>(2, 6, 12, 20)
Numeric
和ExpressibleByArrayLiteral
协议的自定义类型您可以构建自己的符合Numeric
和ExpressibleByArrayLiteral
的自定义类型。以下Playground示例代码展示了如何实现和使用它:
struct Vector {
let x, y: Int
init(_ x: Int, _ y: Int) {
self.x = x
self.y = y
}
}
extension Vector: AdditiveArithmetic {
static var zero: Vector {
return Vector(0, 0)
}
static func +(lhs: Vector, rhs: Vector) -> Vector {
return Vector(lhs.x + rhs.x, lhs.y + rhs.y)
}
static func +=(lhs: inout Vector, rhs: Vector) {
lhs = lhs + rhs
}
static func -(lhs: Vector, rhs: Vector) -> Vector {
return Vector(lhs.x - rhs.x, lhs.y - rhs.y)
}
static func -=(lhs: inout Vector, rhs: Vector) {
lhs = lhs - rhs
}
}
extension Vector: ExpressibleByIntegerLiteral {
init(integerLiteral value: Int) {
x = value
y = value
}
}
import Darwin
extension Vector: Numeric {
var magnitude: Int {
// Implement according to your needs
return Int(Darwin.sqrt(Double(x * x + y * y)))
}
init?<T>(exactly source: T) where T : BinaryInteger {
guard let source = source as? Int else {
return nil
}
x = source
y = source
}
static func *(lhs: Vector, rhs: Vector) -> Vector {
return Vector(lhs.x * rhs.y, lhs.y * rhs.x)
}
static func *=(lhs: inout Vector, rhs: Vector) {
lhs = lhs * rhs
}
}
extension Vector: ExpressibleByArrayLiteral {
init(arrayLiteral elements: Int...) {
assert(elements.count == 2, "arrayLiteral should have exactly 2 elements")
self.x = elements[0]
self.y = elements[1]
}
}
用法:
let vector1 = Vector(1, 2)
let vector2 = Vector(2, 3)
let vector3 = vector1 * vector2
print(vector3) // prints: Vector(x: 3, y: 4)
let vector1: Vector = [1, 2]
let vector2: Vector = [2, 3]
let vector3 = vector1 * vector2
print(vector3) // prints: Vector(x: 3, y: 4)
答案 4 :(得分:0)
let A = [1,2,3,4]
let B = [2,3,4,5]
var C = [Int]()
A.enumerated().forEach{ index, value in
return C.append(value * B[index])
}