function _multiplyDenseMatrixDenseMatrix(a, b) {
    // a dense
    var adata = a._data;
    var asize = a._size;
    var adt = a._datatype; // b dense

    var bdata = b._data;
    var bsize = b._size;
    var bdt = b._datatype; // rows & columns

    var arows = asize[0];
    var acolumns = asize[1];
    var bcolumns = bsize[1]; // datatype

    var dt; // addScalar signature to use

    var af = addScalar; // multiplyScalar signature to use

    var mf = multiplyScalar; // process data types

    if (adt && bdt && adt === bdt && typeof adt === 'string') {
      // datatype
      dt = adt; // find signatures that matches (dt, dt)

      af = typed.find(addScalar, [dt, dt]);
      mf = typed.find(multiplyScalar, [dt, dt]);
    } // result


    var c = []; // loop matrix a rows

    for (var i = 0; i < arows; i++) {
      // current row
      var row = adata[i]; // initialize row array

      c[i] = []; // loop matrix b columns

      for (var j = 0; j < bcolumns; j++) {
        // sum (avoid initializing sum to zero)
        var sum = mf(row[0], bdata[0][j]); // loop matrix a columns

        for (var x = 1; x < acolumns; x++) {
          // multiply & accumulate
          sum = af(sum, mf(row[x], bdata[x][j]));
        }

        c[i][j] = sum;
      }
    } // return matrix


    return new DenseMatrix({
      data: c,
      size: [arows, bcolumns],
      datatype: dt
    });
  }
C = A * B

@param {Matrix} a            DenseMatrix    (MxN)
@param {Matrix} b            DenseMatrix    (NxC)

@return {Matrix}             DenseMatrix    (MxC)