Created
July 17, 2020 02:10
-
-
Save Koshimizu-Takehito/73ac76e719af91fa6ac0fe0c35e67c5c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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