Thanks, `new Array[Double](C)` is indeed preferable here.  I rewrote these lines into this:

    val weightPerLabel = new Array[Double](C)
    val weightMatrix = new Array[Array[Double]](C)

    for ((label, (_, labelWeight, weights)) <- collected) {
      weightPerLabel(label) = labelWeight - logDenom
      weightMatrix(label) = weights
    }

With the `for` loop, we only need to traverse `collected` once, while using `Array.tabulate` requires two traversal, once for `weightPerLabel`, once for `weightMatrix`, since it can't operates on multiple arrays within a single pass.