         return .init(size: a.size, data: a.data.merging(b.data, uniquingKeysWith: +).exclude{ $0.value.isZero })
     }
     
+    @inlinable
     public static prefix func - (a: Self) -> Self {
         a.mapNonZeroEntries{ (_, _, a) in -a }
     }
     
+    @inlinable
     public static func -(a: Self, b: Self) -> Self {
         assert(a.size == b.size)
         return a + (-b)
     }
     
+    @inlinable
     public static func * (r: R, a: DefaultMatrixImpl<R>) -> Self {
         a.mapNonZeroEntries{ (_, _, a) in r * a }
     }
     
+    @inlinable
     public static func * (a: DefaultMatrixImpl<R>, r: R) -> Self {
         a.mapNonZeroEntries{ (_, _, a) in a * r }
-    }
-    
-    public static func *(a: Self, b: Self) -> Self {
-        mulColBased(a, b)
     }
     
     @_specialize(where R == 𝐙)
     @_specialize(where R == 𝐐)
     @_specialize(where R == 𝐅₂)
-    public static func mulRowBased(_ a: Self, _ b: Self) -> Self {
-        assert(a.size.cols == b.size.rows)
-        
-        //       k              j
-        //                    |          |
-        //  i>|  a    *  |  k>| b   *    |
-        //                    |          |
-        //                    | *      * |
-        //                    |          |
-        //
-        //                         ↓
-        //                      j
-        //                  i>| *   *  * |
-        
-        let aRows = a.data.group{ (e, _) in e.row } // [row : [index : value]]
-        let bRows = b.data.group{ (e, _) in e.row }
-        
-        let data =
-        Array(aRows).parallelFlatMap { (i, ai) -> [(Index, R)] in
-            ai.flatMap { (a_idx, a) -> [(Index, R)] in
-                let k = a_idx.col
-                guard let bk = bRows[k] else {
-                    return []
-                }
-                return bk.map { (b_idx, b) in
-                    let j = b_idx.col
-                    return ( Index(i, j), a * b )
-                }
-            }
-        }
-        
-        return .init(
-            size: (a.size.rows, b.size.cols),
-            data: Dictionary(data, uniquingKeysWith: +).exclude { $0.value.isZero }
-        )
-    }
     
-    @_specialize(where R == 𝐙)
-    @_specialize(where R == 𝐐)
-    @_specialize(where R == 𝐅₂)
-    private static func mulColBased(_ a: Self, _ b: Self) -> Self {
+    public static func *(a: Self, b: Self) -> Self {
         assert(a.size.cols == b.size.rows)
         
         //      k              j        j

        }
    }
    
    public var numberOfNonZeros: Int {
        data.count
    }

//  Created by Taketo Sano on 2021/05/14.
//

//  Implemented with DOK (dictionary of keys) format.
//  https://en.wikipedia.org/wiki/Sparse_matrix#Dictionary_of_keys_(DOK)
//  Not intended for fast computation.

public struct DefaultMatrixImpl<R: Ring>: SparseMatrixImpl {
    public typealias BaseRing = R
    public typealias Data = [Index : R]
    
    public var size: (rows: Int, cols: Int)
    public private(set) var data: Data
    
    private init(size: MatrixSize, data: Data) {
        assert(size.0 >= 0)
