<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def output_randomized_kronecker_to_pickle( left_matrix, right_matrix, train_indices_out_path, test_indices_out_path, train_metadata_out_path=None, test_metadata_out_path=None, remove_empty_rows=True):
 """Compute randomized Kronecker product and dump it on the fly. A standard Kronecker product between matrices A and B produces (if A's size is (m, n) and B's size is (p, q) then A Kronecker B has size (m p, n q)). Here we modify the standard Kronecker product expanding matrices in https://cs.stanford.edu/~jure/pubs/kronecker-jmlr10.pdf and randomize each block-wise operation a_ij B in the Kronecker product as in https://arxiv.org/pdf/1901.08910.pdf section III.4. The matrix we produce is where (w_ij) is a sequence of pseudo random numbers and F is randomized operator which will: 1) Shuffle rows and columns of B independently at random; 2) Dropout elements of B with a rate 1 - a_ij to compute F(a_ij, B, w_ij). (It is noteworthy that there is an abuse of notation above when writing F(a_ij, B, w_ij) as each block-wise operation will in fact consume multiple elements of the sequence (w_ij)). Args: left_matrix: sparse SciPy csr matrix with values in [0, 1]. right_matrix: sparse SciPy coo signed binary matrix. +1 values correspond to train set and -1 values correspond to test set. train_indices_out_path: path to output train file. The non zero indices of the resulting sparse matrix are dumped as a series of pickled records. As many shard will be created as there are rows in left matrix. The shard corresponding to row i in the left matrix has the suffix _i appended to its file name. Each shard contains a pickled list of list each of which corresponds to a users. test_indices_out_path: path to output train file. The non zero indices of the resulting sparse matrix are dumped as a series of pickled records. As many shard will be created as there are rows in left matrix. The shard corresponding to row i in the left matrix has the suffix _i appended to its file name. Each shard contains a pickled list of list each of which corresponds to a users. train_metadata_out_path: path to optional complementary output file containing the number of train rows (r), columns (c) and non zeros (nnz) in a pickled SparseMatrixMetadata named tuple. test_metadata_out_path: path to optional complementary output file containing the number of test rows (r), columns (c) and non zeros (nnz) in a pickled SparseMatrixMetadata named tuple. remove_empty_rows: whether to remove rows from the synthetic train and test matrices which are not present in the train or the test matrix. Returns: (metadata, train_metadata, test_metadata) triplet of SparseMatrixMetadata corresponding to the overall data set, train data set and test data set. """

  logging.info("Writing item sequences to pickle files %s and %s.",
               train_indices_out_path, test_indices_out_path)

  num_rows = 0
  num_removed_rows = 0
  num_cols = left_matrix.shape[1] * right_matrix.shape[1]
  num_interactions = 0

  num_train_interactions = 0
  num_test_interactions = 0

  if not set(right_matrix.data).issubset({-1, 1}):
    raise ValueError(
        "Values of sparse matrix should be -1 or 1 but are:",
        set(right_matrix.data))

  for i in xrange(left_matrix.shape[0]):

    (shard_num_removed_rows, shard_metadata, shard_train_metadata,
     shard_test_metadata) = _compute_and_write_row_block(
         i, left_matrix, right_matrix, train_indices_out_path,
         test_indices_out_path, remove_empty_rows)

    num_rows += shard_metadata.num_rows
    num_removed_rows += shard_num_removed_rows
    num_interactions += shard_metadata.num_interactions
    num_train_interactions += shard_train_metadata.num_interactions
    num_test_interactions += shard_test_metadata.num_interactions

    logging.info("%d total interactions written.", num_interactions)
    logging.info("%d total rows removed.", num_removed_rows)
    logging.info("%d total train interactions written.", num_train_interactions)
    logging.info("%d toal test interactions written.", num_test_interactions)

  logging.info("Done writing.")

  metadata = SparseMatrixMetadata(
      num_interactions=num_interactions,
      num_rows=num_rows, num_cols=num_cols)
  train_metadata = SparseMatrixMetadata(
      num_interactions=num_train_interactions,
      num_rows=num_rows, num_cols=num_cols)
  test_metadata = SparseMatrixMetadata(
      num_interactions=num_test_interactions,
      num_rows=num_rows, num_cols=num_cols)

  if train_metadata_out_path is not None:
    util.write_metadata_to_file(
        train_metadata, train_metadata_out_path, tag="train")
  if test_metadata_out_path is not None:
    util.write_metadata_to_file(
        test_metadata, test_metadata_out_path, tag="test")

  return metadata, train_metadata, test_metadata