Random truncation of MPS
Posted: 26 Jun 2025, 16:01
Hi Tenpy forum,
I have been trying to implement a random truncation scheme for MPS where we keep Schmidt values with a certain probability proportionate to the Schmidt value itself.
Here the code I wrote for it:
def truncate_random(S, options,seed=23):
"""Truncate Schmidt values by randomly selecting `chi_max` values with probability proportional to the Schmidt values."""
options = asConfig(options, "truncation")
chi_max = options.get('chi_max', 100, int)
if not np.any(S > 1.e-10):
warnings.warn("no Schmidt value above 1.e-10", stacklevel=2)
# Normalize probabilities
probabilities = S / np.sum(S)
rng = np.random.default_rng(seed=seed)
# Randomly select `chi_max` indices based on probabilities
#Ensure that chi_max is not greater than the number of non-zero probabilities.
non_zero_probabilities = np.count_nonzero(probabilities)
if chi_max > non_zero_probabilities:
chi_max = non_zero_probabilities
selected_indices = rng.choice(len(S), size=chi_max, replace=False, p=probabilities)
mask = np.zeros(len(S), dtype=bool)
mask[selected_indices] = True
norm_new = np.linalg.norm(S[mask])
return mask, norm_new, TruncationError.from_S(S[np.logical_not(mask)])
this function would be called instead of the usual truncate function in svd_theta function. I was just wondering if the above code is correct and if there is a better way to do it.
Thanks a lot for your help.
I have been trying to implement a random truncation scheme for MPS where we keep Schmidt values with a certain probability proportionate to the Schmidt value itself.
Here the code I wrote for it:
def truncate_random(S, options,seed=23):
"""Truncate Schmidt values by randomly selecting `chi_max` values with probability proportional to the Schmidt values."""
options = asConfig(options, "truncation")
chi_max = options.get('chi_max', 100, int)
if not np.any(S > 1.e-10):
warnings.warn("no Schmidt value above 1.e-10", stacklevel=2)
# Normalize probabilities
probabilities = S / np.sum(S)
rng = np.random.default_rng(seed=seed)
# Randomly select `chi_max` indices based on probabilities
#Ensure that chi_max is not greater than the number of non-zero probabilities.
non_zero_probabilities = np.count_nonzero(probabilities)
if chi_max > non_zero_probabilities:
chi_max = non_zero_probabilities
selected_indices = rng.choice(len(S), size=chi_max, replace=False, p=probabilities)
mask = np.zeros(len(S), dtype=bool)
mask[selected_indices] = True
norm_new = np.linalg.norm(S[mask])
return mask, norm_new, TruncationError.from_S(S[np.logical_not(mask)])
this function would be called instead of the usual truncate function in svd_theta function. I was just wondering if the above code is correct and if there is a better way to do it.
Thanks a lot for your help.