I'm solving a scientific question where I need to mix n
compounds in all possible ratios, and want to iterate over only those ratios that sum to unity for some given step size.
For example, for three compounds (n=3)
and a step size
of 0.25
I want to iterate over the following ratios
(0.00, 0.00, 1.00)
(0.00, 0.25, 0.75)
(0.00, 0.50, 0.50)
(0.00, 0.75, 0.25)
(0.00, 1.00, 0.00)
(0.25, 0.00, 0.75)
(0.25, 0.25, 0.50)
(0.25, 0.50, 0.25)
(0.25, 0.75, 0.00)
(0.50, 0.00, 0.50)
(0.50, 0.25, 0.25)
(0.50, 0.50, 0.00)
(0.75, 0.00, 0.25)
(0.75, 0.25, 0.00)
(1.00, 0.00, 0.00)
I looked at this related question, however, it seems like the solutions don't apply for my case.
The following code solves the problem by generating the above ratios, but inefficiently.
import itertools as it
import numpy as np
n = 3
step_size = 0.25
r_range = np.arange(0.0, 1.0+step_size, step_size)
for ratios in it.product(r_range, repeat=n):
if not np.isclose(sum(ratios), 1.0):
continue
print(ratios)
Is there an efficient and pythonic way to iterate over only those ratios that sum to unity for arbitrary n and step sizes?