Skip to content

Instantly share code, notes, and snippets.

@Koshimizu-Takehito
Created July 17, 2020 02:10
Show Gist options
  • Save Koshimizu-Takehito/73ac76e719af91fa6ac0fe0c35e67c5c to your computer and use it in GitHub Desktop.
Save Koshimizu-Takehito/73ac76e719af91fa6ac0fe0c35e67c5c to your computer and use it in GitHub Desktop.
#if canImport(Foundation) && canImport(Accelerate)
import Foundation
import Accelerate
extension la_object_t {
public var rows: UInt { la_matrix_rows(self) }
public var cols: UInt { la_matrix_cols(self) }
public func array1D() -> [Double] {
var buffer = [Double](repeating: 0, count: Int(rows * cols))
_ = la_matrix_to_double_buffer(&buffer, cols, self)
return buffer
}
public func array2D() -> [[Double]] {
let rows = la_matrix_rows(self)
let cols = la_matrix_cols(self)
return [[Double]](unsafeUninitializedCapacity: Int(rows)) { buffer, count in
buffer.initialize(repeating: [])
var colsBuffer = [Double](repeating: 0, count: Int(cols))
for row in 0..<rows {
_ = la_matrix_to_double_buffer(&colsBuffer, cols, self[row, 0...cols-1])
buffer[Int(row)] = colsBuffer
}
count = Int(rows)
}
}
public subscript(rows: ClosedRange<UInt>, cols: ClosedRange<UInt>) -> la_object_t {
let index: (ClosedRange<UInt>) -> la_index_t = { la_index_t($0.lowerBound) }
let slice: (ClosedRange<UInt>) -> la_count_t = { $0.upperBound - $0.lowerBound + 1 }
return la_matrix_slice(self, index(rows), index(cols), 1, 1, slice(rows), slice(cols))
}
public subscript(row: UInt, cols: ClosedRange<UInt>) -> la_object_t {
self[row...row, cols]
}
public subscript(rows: ClosedRange<UInt>, col: UInt) -> la_object_t {
self[rows, col...col]
}
public subscript(row: UInt, col:UInt) -> la_object_t {
self[row...row, col...col]
}
func normL1() -> Double {
la_norm_as_double(self, la_norm_t(LA_L1_NORM))
}
func normL2() -> Double {
la_norm_as_double(self, la_norm_t(LA_L2_NORM))
}
}
extension Array where Element == [Double] {
func matrix(
hint: la_hint_t = la_hint_t(LA_NO_HINT),
attributes: la_attribute_t = la_attribute_t(LA_DEFAULT_ATTRIBUTES)
) -> la_object_t? {
guard count > 0 && self[0].count > 0 else { return nil }
let array = flatMap { $0 }
let cols = la_count_t(first!.count)
return array.matrix(cols: cols, hint: hint, attributes: attributes)
}
}
extension Array where Element == Double {
func matrix(
cols: la_count_t? = nil,
hint: la_hint_t = la_hint_t(LA_NO_HINT),
attributes: la_attribute_t = la_attribute_t(LA_DEFAULT_ATTRIBUTES)
) -> la_object_t? {
guard count > 0 else { return nil }
let cols = cols ?? la_count_t(sqrt(Double(count)))
let rows = la_count_t(count)/cols
return la_matrix_from_double_buffer(
self,
rows,
cols,
cols,
hint,
attributes
)
}
}
let array1D: [Double] = [
00,01,02,03,04,
10,11,12,13,14,
20,21,22,23,24,
30,31,32,33,34,
40,41,42,43,44
]
let array2D: [[Double]] = [
[00,01,02,03,04],
[10,11,12,13,14],
[20,21,22,23,24],
[30,31,32,33,34],
[40,41,42,43,44]
]
do {
let matrix1 = array1D.matrix()!
print(matrix1.array1D())
print(matrix1.array2D())
print(matrix1[1...3, 1].array2D())
print(matrix1[1, 1...3].array2D())
print(matrix1[2, 2].normL1())
}
do {
let matrix2 = array2D.matrix()!
print(matrix2.array1D())
print(matrix2.array2D())
print(matrix2[1...3, 1].array2D())
print(matrix2[1, 1...3].array2D())
print(matrix2[2, 2].normL1())
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment