         
         self.align = align
         
-        switch align {
-        case .Rows:
-            rowTable = [:]
-            for (j, list) in colTable {
-                for (i, a) in list {
-                    set(i, j, a)
-                }
-            }
-            colTable = nil
-        case .Cols:
-            colTable = [:]
-            for (i, list) in rowTable {
-                for (j, a) in list {
-                    set(i, j, a)
-                }
-            }
-            rowTable = nil
-        }
+        let copy = table
+        self.table = [:]
+        
+        for (i, list) in copy {
+            for (j, a) in list {
+                set(j, i, a)
+            }
+        }
+        
         sort()
     }
     
+    public func transpose() {
+        (rows, cols) = (cols, rows)
+        align = (align == .Rows) ? .Cols : .Rows
+    }
+    
+    public var isDiagonal: Bool {
+        return table.forAll { (i, list) in (list.count == 1) && list.first!.0 == i }
+    }
+    
+    public var diagonal: [R] {
+        return table.keys.sorted().flatMap { i -> R? in
+            table[i]!.first.flatMap{ (j, a) -> R? in (i == j) ? a : nil }
+        }
+    }
+    
     public static func *(a: ComputationalMatrix<R>, b: ComputationalMatrix<R>) -> ComputationalMatrix<R> {
-        assert(a.cols == b.rows)
+        assert(a.rows == b.cols)
         
         let result = ComputationalMatrix<R>(rows: a.rows, cols: b.cols, components: [])
         

}

public final class ComputationalMatrix<R: Ring>: Equatable, CustomStringConvertible {
    public let rows: Int
    public let cols: Int
    
    internal var align: ComputationalMatrixAlignment
    internal var rowTable: [Int: [(col: Int, value: R)]]!
    internal var colTable: [Int: [(row: Int, value: R)]]!

    public subscript(i: Int, j: Int) -> R {
        switch align {
        case .Rows :
            return rowTable[i]?.first{ $0.col == j }?.value ?? 0 // TODO use binary search
        case .Cols:
            return colTable[j]?.first{ $0.row == i }?.value ?? 0 // TODO use binary search
        }
    }
    
    public convenience init<n, m>(_ a: Matrix<n, m, R>, align: ComputationalMatrixAlignment = .Rows) {

        self.cols = cols
        
        self.align = align
        self.table = [:]
        
        for (i, j, a) in components {
            if a == R.zero {
                continue
            }
            (align == .Rows) ? set(i, j, a) : set(j, i, a)
        }
        sort()
    }
    
    internal func set(_ i: Int, _ j: Int, _ a: R) {
        assert(a != R.zero)
        
        if table[i] == nil {
            table[i] = []
        }
        table[i]!.append( (j, a) )
    }

    internal func sort() {
        for (i, list) in table {
            table[i] = list.sorted{ (e1, e2) in e1.0 < e2.0 }
        }
    }
    
