【问题标题】:Elegant way to flatten a simd_float4x4 matrix展平 simd_float4x4 矩阵的优雅方法
【发布时间】:2019-10-08 21:38:01
【问题描述】:

我想将simd_float4x4simd_float3x3 矩阵展平为单个浮点元素数组。

对于我会使用的常规数组

let arr = [[1,2,3],[4,5,6],[7,8,9]]
print(arr.flatMap { $0 })

我怎样才能优雅地为simd_float4x4simd_float3x3 结构做到这一点?

我正在使用这个,

extension simd_float3x3 {
    var array: [Float] {
        return [columns.0.x, columns.0.y, columns.0.z,
                columns.1.x, columns.1.y, columns.1.z,
                columns.2.x, columns.2.y, columns.2.z]
    }
}

let arr = simd_float3x3.init()
print(arr.array.compactMap({$0}))

【问题讨论】:

    标签: arrays swift simd


    【解决方案1】:

    优雅在旁观者的眼中。到目前为止,我想出了这个:

    let s = simd_float3x3(simd_float3(1, 2, 3), simd_float3(4, 5, 6), simd_float3(7, 8, 9)) 
    
    let y = (0..<3).flatMap { x in (0..<3).map { y in s[x][y] } }
    
    print(y)
    
    [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
    

    【讨论】:

    • 这会是懒图的好机会吗?
    【解决方案2】:

    好吧,看起来向量 float3float4 已经有 map 实现(通过实现 Sequence/Collection 协议)。

    所以我们唯一应该做的就是为矩阵实现Collection

    extension simd_float3x3: Collection {
        public var startIndex: Int {
            return 0
        }
    
        public var endIndex: Int {
            return 3 // for `sims_float4x4` it would be 4, number of columns
        }
    
        public func index(after i: Int) -> Int {
            return i + 1
        }
    }
    

    现在我们可以这样做了:

    let matrix: simd_float3x3 = initCodeForTheMatrix()
    matrix.flatMap { $0 }
    

    您可以声明这个方便的子协议,以避免为所有矩阵类型输入相同的 startIndexindex(after:)

    public protocol SIMDCollection: Collection {}
    extension SIMDCollection {
        public var startIndex: Int {
            return 0
        }
    
        public func index(after i: Int) -> Int {
            return i + 1
        }
    }
    
    // And use it like this:
    extension simd_float3x3: SIMDCollection {
        public var endIndex: Int {
            return 3
        }
    }
    
    extension simd_float4x4: SIMDCollection {
        public var endIndex: Int {
            return 4
        }
    }
    
    extension simd_float3x2: SIMDCollection {
        public var endIndex: Int {
            return 3
        }
    }
    
    // etc
    

    它可以走得更远,因为endIndex 对于所有simd_floatX_Y 与相同的X 和任何Y 都是相同的。不管是*float* 还是*double* 或其他什么都无所谓。

    【讨论】:

      猜你喜欢
      • 2021-10-18
      • 1970-01-01
      • 2016-02-11
      • 2012-01-17
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多