docs: public static DMatrixSparseCSC concatRows(DMatrixSparseCSC top , DMatrixSparseCSC bottom ,
                                                @Nullable DMatrixSparseCSC out )
      {
          if( top.numCols != bottom.numCols )
              throw new MatrixDimensionException("Number of columns must match. "+stringShapes(top,bottom));
          if( out == null )
              out = new DMatrixSparseCSC(0,0,0);
  
          out.reshape(top.numRows+bottom.numRows,top.numCols,top.nz_length+bottom.nz_length);
          out.nz_length = top.nz_length+bottom.nz_length;
  
          int index = 0;
          for (int i = 0; i < top.numCols; i++) {
              int top0 = top.col_idx[i];
              int top1 = top.col_idx[i+1];
  
              int bot0 = bottom.col_idx[i];
              int bot1 = bottom.col_idx[i+1];
  
              int out0 = out.col_idx[i];
              int out1 = out0 + top1-top0 + bot1-bot0;
              out.col_idx[i+1] = out1;
  
              for (int j = top0; j < top1; j++ , index++) {
                  out.nz_values[index] = top.nz_values[j];
                  out.nz_rows[index] = top.nz_rows[j];
              }
              for (int j = bot0; j < bot1; j++ , index++) {
                  out.nz_values[index] = bottom.nz_values[j];
                  out.nz_rows[index] = top.numRows + bottom.nz_rows[j];
              }
          }
          out.indicesSorted = false;
  
          return out;
      }