vectores una todos sumar suma multiplicacion matriz matrices los extraer elementos con codigo ciclos arrays swift vector multiplying

arrays - una - Cómo multiplicar dos matrices por elementos



suma elementos de una matriz (5)

Acelerar el marco

Para el tema de la multiplicación de vectores, otra alternativa (además del simd cubierto por la respuesta de @ appzYourLife ) está haciendo uso del marco Acelerar . En este caso, específicamente los métodos vDSP_vmul y 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)

Por ejemplo, este último utilizado para la multiplicación elemento por elemento de dos vectores de valores 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] }

Tenga en cuenta que usar Accelerate no es tan fácil de usar y seguro como los métodos alternativos, ya que los argumentos vectoriales para vDSP_vmulD se capturan como punteros inseguros ( UnsafePointer<Double> ), y es nuestra responsabilidad asegurarnos de que los vectores de entrada sean de la misma longitud , así como que el vector resultante se asigne correctamente antes de la multiplicación del vector por vDSP_vmulD .

Necesito multiplicar una matriz por otra matriz en cuanto a elementos, al igual que el producto Hadamard de vectores en matemáticas. Por ejemplo:

A = [1,2,3,4] B = [2,3,4,5] C = A*B = [2,6,12,20]

Ni siquiera puedo descifrar el código, he intentado hacerlo elemento por elemento, pero esto me parece una solución demasiado desordenada, ¿alguna idea?


Instrucción única Datos múltiples

Si sus vectores tienen exactamente 4 componentes, puede usar las instrucciones simd ( Single Instruction Multiple Data ) proporcionadas por iOS.

Utiliza la CPU para realizar cálculos paralelos.

Dados 2 vectores de 4 componentes de Int32

import simd let a = int4(1, 2, 3, 4) let b = int4(2, 3, 4, 5)

puedes multiplicar cada componente

let res = a &* b // int4(2, 6, 12, 20)

Como señaló Martin R , el módulo simd también proporciona una matriz de float(s) o de double(s) .


Al "comprimir" las dos matrices se obtiene una secuencia de tuplas (a_i, b_i) que luego se pueden multiplicar por elementos:

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]

(Si las matrices tienen una longitud diferente, zip ignora silenciosamente los elementos adicionales de la matriz más larga).

Como @appzYourLife dijo correctamente, también puede pasar el operador de multiplicación directamente como un argumento para map lugar de una expresión de cierre:

let C = zip(A, B).map(*)


Con Swift 5, puede usar una de las siguientes formas para resolver su problema.

# 1 Usando tipos de vectores SIMD

El siguiente código de muestra de Playground muestra una multiplicación por elementos usando 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)

Tenga en cuenta que el protocolo SIMD ajusta a ExpressibleByArrayLiteral . Por lo tanto, puede inicializar su vector usando una matriz literal:

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)

# 2 Usar un tipo personalizado que se ajuste a los protocolos Numeric y ExpressibleByArrayLiteral

Puede crear su propio tipo personalizado que se ajuste a Numeric y ExpressibleByArrayLiteral . El siguiente código de muestra de Playground muestra cómo implementarlo y usarlo:

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] } }

Uso:

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)


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]) }