public void computeMatrixCharacteristics(
      MatrixCharacteristics mc1,
      MatrixCharacteristics mc2,
      MatrixCharacteristics mc3,
      MatrixCharacteristics dimOut) {
    QuaternaryOperator qop = (QuaternaryOperator) optr;

    if (qop.wtype1 != null || qop.wtype4 != null) { // wsloss/wcemm
      // output size independent of chain type (scalar)
      dimOut.set(1, 1, mc1.getRowsPerBlock(), mc1.getColsPerBlock());
    } else if (qop.wtype2 != null || qop.wtype5 != null) { // wsigmoid/wumm
      // output size determined by main input
      dimOut.set(mc1.getRows(), mc1.getCols(), mc1.getRowsPerBlock(), mc1.getColsPerBlock());
    } else if (qop.wtype3 != null) { // wdivmm
      // note: cannot directly consume mc2 or mc3 for redwdivmm because rep instruction changed
      // the relevant dimensions; as a workaround the original dims are passed via nnz
      boolean mapwdivmm = _cacheU && _cacheV;
      long rank =
          qop.wtype3.isLeft()
              ? mapwdivmm ? mc3.getCols() : mc3.getNonZeros()
              : mapwdivmm ? mc2.getCols() : mc2.getNonZeros();
      MatrixCharacteristics mcTmp =
          qop.wtype3.computeOutputCharacteristics(mc1.getRows(), mc1.getCols(), rank);
      dimOut.set(mcTmp.getRows(), mcTmp.getCols(), mc1.getRowsPerBlock(), mc1.getColsPerBlock());
    }
  }