         .init(impl.U)
     }
     
-    public var P: LeftPerm {
+    public var leftPermutation: LeftPermutation {
         .init(impl.P)
     }
 
-    public var Q: RightPerm {
+    public var rightPermutation: RightPermutation {
         .init(impl.Q)
-    }
-    
-    public var LU: (MatrixL, MatrixU) {
-        (L, U)
-    }
-    
-    public var PQ: (LeftPerm, RightPerm) {
-        (P, Q)
     }
     
     public var rank: Int {

        impl.nullity
    }
    
    public var image: Image {
        .init(impl.image)
    }
    
    public var kernel: Kernel {
        .init(impl.kernel)
    }
    
    public func solve<k>(_ b: MatrixInterface<Impl, n, k>) -> MatrixInterface<Impl, m, k>? {


public struct LUDecomposition<Impl: MatrixImpl_LU, n: SizeType, m: SizeType> {
    public typealias Matrix    = MatrixInterface<Impl, n, m>
    public typealias MatrixL   = MatrixInterface<Impl, n, DynamicSize>
    public typealias MatrixU   = MatrixInterface<Impl, DynamicSize, m>
    public typealias LeftPermutation  = MatrixInterface<Impl, n, n>
    public typealias RightPermutation = MatrixInterface<Impl, m, m>
    public typealias CodomainSub = MatrixInterface<Impl, n, DynamicSize>
    public typealias DomainSub   = MatrixInterface<Impl, m, DynamicSize>

    public let impl: Impl
    
