code: def reduce_mat(mat, mag, r_matrix):
          
          max_j = abs(int(round(np.linalg.det(mat) / mag)))
          reduced = False
          for h in range(3):
              k = h + 1 if h + 1 < 3 else abs(2 - h)
              l = h + 2 if h + 2 < 3 else abs(1 - h)
              j = np.arange(-max_j, max_j + 1)
              for j1, j2 in itertools.product(j, repeat=2):
                  temp = mat[h] + j1 * mat[k] + j2 * mat[l]
                  if all([np.round(x, 5).is_integer() for x in list(temp / mag)]):
                      mat_copy = mat.copy()
                      mat_copy[h] = np.array([int(round(ele / mag)) for ele in temp])
                      new_mat = np.dot(mat_copy, np.linalg.inv(r_matrix.T))
                      if all([np.round(x, 5).is_integer() for x in list(np.ravel(new_mat))]):
                          reduced = True
                          mat[h] = np.array([int(round(ele / mag)) for ele in temp])
                          break
              if reduced:
                  break
  
          if not reduced:
              warnings.warn("Matrix reduction not performed, may lead to non-primitive gb cell.")
          return mat
docs: Reduce integer array mat's determinant mag times by linear combination
          of its row vectors, so that the new array after rotation (r_matrix) is
          still an integer array
  
          Args:
              mat (3 by 3 array): input matrix
              mag (integer): reduce times for the determinant
              r_matrix (3 by 3 array): rotation matrix
          Return:
              the reduced integer array