         sort()
     }
     
-    public func transpose() {
+    @discardableResult
+    public func transpose() -> ComputationalMatrix<R> {
         (rows, cols) = (cols, rows)
         align = (align == .Rows) ? .Cols : .Rows
-    }
-    
+        return self
+    }
+    
+    public func submatrix(rowRange: CountableRange<Int>) -> ComputationalMatrix<R> {
+        return submatrix(rowRange, 0 ..< cols)
+    }
+    
+    public func submatrix(colRange: CountableRange<Int>) -> ComputationalMatrix<R> {
+        return submatrix(0 ..< rows, colRange)
+    }
+    
+    public func submatrix(_ rowRange: CountableRange<Int>, _ colRange: CountableRange<Int>) -> ComputationalMatrix<R> {
+        assert(0 <= rowRange.lowerBound && rowRange.upperBound <= rows)
+        assert(0 <= colRange.lowerBound && colRange.upperBound <= cols)
+
+        switch align {
+        case .Rows:
+            let table = self.table
+                .filter { (i, _) in rowRange.contains(i) }
+                .map{ (i, list) in (i - rowRange.lowerBound,
+                                    list.flatMap{ (j, a) in colRange.contains(j) ? (j - colRange.lowerBound, a) : nil }) }
+            
+            return ComputationalMatrix(rowRange.upperBound - rowRange.lowerBound, colRange.upperBound - colRange.lowerBound, align, Dictionary(pairs: table))
+            
+        case .Cols:
+            let table = self.table
+                .filter { (j, _) in colRange.contains(j) }
+                .map{ (j, list) in (j - colRange.lowerBound,
+                                    list.flatMap{ (i, a) in rowRange.contains(i) ? (i - rowRange.lowerBound, a) : nil }) }
+            
+            let shit = Dictionary(pairs: table)
+            
+            print(self.table)
+            print(rowRange, colRange)
+            print(rowRange.upperBound - rowRange.lowerBound, colRange.upperBound - colRange.lowerBound)
+            print(shit)
+            
+            return ComputationalMatrix(rowRange.upperBound - rowRange.lowerBound, colRange.upperBound - colRange.lowerBound, align, Dictionary(pairs: table))
+        }
+    }
+    
+    public var isZero: Bool {
+        return table.isEmpty
+    }
+
     public var isDiagonal: Bool {
         return table.forAll { (i, list) in (list.count == 1) && list.first!.0 == i }
     }

        }
    }
    
    public static func identity(_ n: Int, align: ComputationalMatrixAlignment = .Rows) -> ComputationalMatrix<R> {
        let components = (0 ..< n).map{ i in MatrixComponent(i, i, R.identity)}
        return ComputationalMatrix(rows: n, cols: n, components: components, align: align)
    }
    
    @_specialize(where R == IntegerNumber)
    public static func ==(a: ComputationalMatrix<R>, b: ComputationalMatrix<R>) -> Bool {
        if (a.rows, a.cols) != (b.rows, b.cols) {

            }
            return (0 ..< x.count).forAll { i in x[i] == y[i] }
        }
    }
    
    public static func zero(rows: Int, cols: Int, align: ComputationalMatrixAlignment = .Rows) -> ComputationalMatrix<R> {
        return ComputationalMatrix(rows: rows, cols: cols, components: [], align: align)
    }
    
    public static func identity(_ n: Int, align: ComputationalMatrixAlignment = .Rows) -> ComputationalMatrix<R> {
        let components = (0 ..< n).map{ i in MatrixComponent(i, i, R.identity)}
        return ComputationalMatrix(rows: n, cols: n, components: components, align: align)
    }
    
    public func generateGrid() -> [R] {
