                 return "\(self[i, j])"
             }).joined(separator: ", ")
         }).joined(separator: "; ") + "]"
+    }
+
+    public var alignedDescription: String {
+        return "[\t" + (0 ..< rows).map({ i in
+            return (0 ..< cols).map({ j in
+                return "\(self[i, j])"
+            }).joined(separator: ",\t")
+        }).joined(separator: "\n\t") + "]"
     }
 }
 

public typealias RowVector<R: Ring, m: _Int> = Matrix<R, _1, m>

public extension Matrix {
    public func rowVector(_ i: Int) -> RowVector<R, m> {
        return RowVector<R, m>(rows: 1, cols: cols){(_, j) -> R in
            return self[i, j]

        return (0 ..< cols).map { colVector($0) }
    }
    
    func submatrix<m0: _Int>(colsInRange c: CountableRange<Int>) -> Matrix<R, n, m0> {
        return Matrix<R, n, m0>(rows: self.rows, cols: c.upperBound - c.lowerBound) {
            self[$0, $1 + c.lowerBound]
        }
    }
    
    func submatrix<n0: _Int>(rowsInRange r: CountableRange<Int>) -> Matrix<R, n0, m> {
        return Matrix<R, n0, m>(rows: r.upperBound - r.lowerBound, cols: self.cols) {
            self[$0 + r.lowerBound, $1]
        }
    }
    
    func submatrix<n0: _Int, m0: _Int>(inRange: (rows: CountableRange<Int>, cols: CountableRange<Int>)) -> Matrix<R, n0, m0> {
        let (r, c) = inRange
        return Matrix<R, n0, m0>(rows: r.upperBound - r.lowerBound, cols: c.upperBound - c.lowerBound) {
            self[$0 + r.lowerBound, $1 + c.lowerBound]
        }
    }
