Reputation: 4389
How do I write a function for printing out the contents of SparseMatrix_Double for Swift 4?
I have the following code so far, however, the output is only correct some of the time.
Sometimes the array is accessing memory that's out of range giving [[1.06540896337e-313, 0.0], [0.0, 3.0]]
I suspect that the way I obtain the number of nonzeros
is wrong.
import Accelerate
func toString(_ A: SparseMatrix_Double) throws -> String {
if A.structure.rowCount > 100 || A.structure.columnCount > 100 {
print("Matrix is too big to display")
throw NSError(domain: "Matrix is too big to display", code: -1, userInfo: nil)
}
let rows = Int(A.structure.rowCount)
let columns = Int(A.structure.columnCount)
let nonzeros = A.structure.columnStarts[columns]
print("Row indices")
for i in 0..<nonzeros {
print("\(i): \(A.structure.rowIndices[i])")
}
print("Column starts")
for c in 0...columns {
print("\(c): \(A.structure.columnStarts[c])")
}
var M = Array(repeating: Array(repeating: 0.0, count: columns), count: rows)
var i = 0
var currentColumn: Int = 0
var nextColStarts = A.structure.columnStarts[1]
while currentColumn < (columns - 1) {
if i == nextColStarts {
currentColumn += 1
nextColStarts = A.structure.columnStarts[currentColumn + 1]
}
let rowIndex = Int(A.structure.rowIndices[i])
M[rowIndex][currentColumn] = A.data[i]
print("Setting \(rowIndex),\(currentColumn) [\(i)]")
i += 1
}
return M.description
}
var rows: [Int32] = [1]
var columns: [Int32] = [1]
var values: [Double] = [3.0]
let blockSize: UInt8 = 1
let blockCount = 8
let A = SparseConvertFromCoordinate(
2, 2,
blockCount, blockSize,
SparseAttributes_t(),
&rows, &columns,
&values
)
print(try? toString(A))
Upvotes: 1
Views: 231
Reputation: 2400
The code provided did not work for me as it wasn't printing all the elements in the sparse matrix. I changed it by looping over nonzero elements, which is the last element in the A.structure.columnStarts
array. This is the code to get an Array
from the SparseMatrix_Double
:
func getDoubleArray(from A: SparseMatrix_Double) -> [[Double]] {
let rows = Int(A.structure.rowCount)
let columns = Int(A.structure.columnCount)
let nnz = A.structure.columnStarts[Int(A.structure.columnCount)]
var M = Array(repeating: Array(repeating: 0.0, count: columns), count: rows)
var i = 0
var currentColumn: Int = 0
var nextColStarts = A.structure.columnStarts[1]
while i < nnz {
if i == nextColStarts {
currentColumn += 1
nextColStarts = A.structure.columnStarts[currentColumn + 1]
}
let rowIndex = Int(A.structure.rowIndices[i])
M[rowIndex][currentColumn] = A.data[i]
i += 1
}
return M
}
I then use this function to print the array:
func print2DArray<T>(_ array: [[T]]) {
for row in array {
print(row)
}
}
Upvotes: 0