 
 import Accelerate
 
-public struct Matrix {
+public struct Matrix<T where T: FloatingPointType, T: FloatLiteralConvertible> {
+    typealias Element = T
+
     let rows: Int
     let columns: Int
-    var grid: [Double]
-
-    public init(rows: Int, columns: Int, repeatedValue: Double) {
+    var grid: [Element]
+
+    public init(rows: Int, columns: Int, repeatedValue: Element) {
         self.rows = rows
         self.columns = columns
 
-        self.grid = [Double](count: rows * columns, repeatedValue: repeatedValue)
-    }
-
-    public init(_ contents: [[Double]]) {
+        self.grid = [Element](count: rows * columns, repeatedValue: repeatedValue)
+    }
+
+    public init(_ contents: [[Element]]) {
         let m: Int = contents.count
         let n: Int = contents[0].count
-        self.init(rows: m, columns: n, repeatedValue: 0.0)
+        let repeatedValue: Element = 0.0
+
+        self.init(rows: m, columns: n, repeatedValue: repeatedValue)
 
         for (i, row) in enumerate(contents) {
             grid.replaceRange(i*n..<i*n+min(m, row.count), with: row)
         }
     }
 
-    public subscript(row: Int, column: Int) -> Double {
+    public subscript(row: Int, column: Int) -> Element {
         get {
             assert(indexIsValidForRow(row, column: column))
             return grid[(row * columns) + column]

    return results
}

public func transpose(x: Matrix) -> Matrix {
    var results = Matrix(rows: x.columns, columns: x.rows, repeatedValue: 0.0)
    vDSP_mtransD(x.grid, 1, &(results.grid), 1, vDSP_Length(results.rows), vDSP_Length(results.columns))

    return results


    private func indexIsValidForRow(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }
}

