     }
     
     mutating func apply(_ s: EliminationStep<R>) {
-        s.applyTo(&result)
+        result.apply(s)
         process.append(s)
     }
     

    
    public var left: Matrix<R, n, n> {
        var Q = target.leftIdentity
        for s in eliminationProcess {
            switch s {
            case .AddRow(_, _, _), .InvRow(_), .SwapRows(_, _):
                s.applyTo(&Q)
            default: ()
            }
        }
        return Q
    }
    
    public var leftInverse: Matrix<R, n, n> {
        var Q = target.leftIdentity
        for s in eliminationProcess.reversed() {
            switch s {
            case .AddRow(_, _, _), .InvRow(_), .SwapRows(_, _):
                s.applyInverseTo(&Q)
            default: ()
            }
        }
        return Q
    }
    
    public var right: Matrix<R, m, m> {
        var P = target.rightIdentity
        for s in eliminationProcess {
            switch s {
            case .AddCol(_, _, _), .InvCol(_), .SwapCols(_, _):
                s.applyTo(&P)
            default: ()
            }
        }
        return P
    }
    
    public var rightInverse: Matrix<R, m, m> {
        var P = target.rightIdentity
        for s in eliminationProcess.reversed() {
            switch s {
            case .AddCol(_, _, _), .InvCol(_), .SwapCols(_, _):
                s.applyInverseTo(&P)
            default: ()
            }
        }
        return P
    }
    

            // TODO maybe implement NumberType or Comparable
            if R.self == IntegerNumber.self && (result[i0, j0] as! IntegerNumber) < 0 {
                if doRows {
                    self.apply(.MulRow(at: i0, by: -1))
                } else {
                    self.apply(.MulCol(at: j0, by: -1))
                }
            }
            
