code: public Matrix select(int[] rowIndices, int[] columnIndices) {
          int m = rowIndices.length;
          int n = columnIndices.length;
  
          if (m == 0 || n == 0) {
              fail("No rows or columns selected.");
          }
  
          Matrix result = blankOfShape(m, n);
  
          for (int i = 0; i < m; i++) {
              for (int j = 0; j < n; j++) {
                  result.set(i, j, get(rowIndices[i], columnIndices[j]));
              }
          }
  
          return result;
      }
docs: Returns a new matrix with the selected rows and columns. This method can
  be used either return a specific subset of rows and/or columns or to
  permute the indices in an arbitrary order. The list of indices are
  allowed to contain duplicates indices. This is more general than slice()
  which selects only contiguous blocks. However, where applicable slice()
  is probably more efficient.
  
  @param rowIndices the array of row indices
  @param columnIndices the array of column indices
  
  @return the new matrix with the selected rows and columns
  
  @throws IllegalArgumentException if invalid row or column indices are provided