From 0849652c481321cac9db0df320d37f1d007b6eb7 Mon Sep 17 00:00:00 2001 From: Simon Humpohl Date: Thu, 28 Aug 2025 11:44:35 +0200 Subject: [PATCH 1/2] Make variable names more verbose and remove comments --- qupulse/utils/__init__.py | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/qupulse/utils/__init__.py b/qupulse/utils/__init__.py index 3ad983cc..817343d7 100644 --- a/qupulse/utils/__init__.py +++ b/qupulse/utils/__init__.py @@ -152,22 +152,20 @@ def to_next_multiple(sample_rate: ExpressionLike, quantum: int, #double negative for ceil division. return lambda duration: -(-(duration*sample_rate)//quantum) * (quantum/sample_rate) else: - qI = sp.Integer(quantum) - k = qI / sample_rate # factor to go from #quanta -> duration - mqI = sp.Integer(min_quanta) - - def _build_sym(d): - u = d*sample_rate/qI # "duration in quanta" (real) - ce = sp.ceiling(u) # number of quanta after rounding up - - # Enforce: 0 if d <= 0; else at least mqI quanta. - # max(mqI, ceil(u)) <=> mqI if u <= mqI, else ceil(u) - # do not evaluate right now because parameters could still be variable, - # then it's just overhead. - return sp.Piecewise( - (0, sp.Le(d, 0)), - (k*mqI, sp.Le(u, mqI)), - (k*ce, True) - , evaluate=False) - - return lambda duration: ExpressionScalar(_build_sym(duration)) \ No newline at end of file + # work with sympy + sample_rate = sample_rate.sympified_expression + duration_per_quantum = sp.Integer(quantum) / sample_rate + minimal_duration = duration_per_quantum * min_quanta + + def build_next_multiple(duration: ExpressionLike) -> ExpressionScalar: + duration = sp.sympify(duration) + rounded_up_duration = sp.ceiling(duration / duration_per_quantum) * duration_per_quantum + + next_multiple_sp = sp.Piecewise( + (0, sp.Le(duration, 0)), + (minimal_duration, sp.Le(duration, minimal_duration)), + (rounded_up_duration, True) + ) + return ExpressionScalar(next_multiple_sp) + + return build_next_multiple From 896b1ae5dcc624e152175c6e683f2995660acb41 Mon Sep 17 00:00:00 2001 From: Simon Humpohl Date: Wed, 3 Sep 2025 16:20:48 +0200 Subject: [PATCH 2/2] Adjust type hints to pad_to requirements and do piecewise evaluation based on the quanta --- qupulse/utils/__init__.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/qupulse/utils/__init__.py b/qupulse/utils/__init__.py index 817343d7..fa571537 100644 --- a/qupulse/utils/__init__.py +++ b/qupulse/utils/__init__.py @@ -131,7 +131,7 @@ def forced_hash(obj) -> int: def to_next_multiple(sample_rate: ExpressionLike, quantum: int, - min_quanta: Optional[int] = None) -> Callable[[ExpressionLike],ExpressionScalar]: + min_quanta: Optional[int] = None) -> Callable[[ExpressionScalar], ExpressionLike]: """Construct a helper function to expand a duration to one corresponding to valid sample multiples according to the arguments given. Useful e.g. for PulseTemplate.pad_to's 'to_new_duration'-argument. @@ -141,12 +141,13 @@ def to_next_multiple(sample_rate: ExpressionLike, quantum: int, quantum: number of samples to whose next integer multiple the duration shall be rounded up to. min_quanta: number of multiples of quantum not to fall short of. Returns: - A function that takes a duration (ExpressionLike) as input, and returns + A function that takes a duration as input, and returns a duration rounded up to the next valid samples count in given sample rate. The function returns 0 if duration==0, <0 is not checked if min_quanta is None. """ sample_rate = ExpressionScalar(sample_rate) + #is it more efficient to omit the Max call if not necessary? if min_quanta is None: #double negative for ceil division. @@ -157,14 +158,16 @@ def to_next_multiple(sample_rate: ExpressionLike, quantum: int, duration_per_quantum = sp.Integer(quantum) / sample_rate minimal_duration = duration_per_quantum * min_quanta - def build_next_multiple(duration: ExpressionLike) -> ExpressionScalar: + def build_next_multiple(duration: ExpressionScalar) -> ExpressionLike: duration = sp.sympify(duration) - rounded_up_duration = sp.ceiling(duration / duration_per_quantum) * duration_per_quantum + n_quanta = sp.ceiling(duration / duration_per_quantum) + rounded_up_duration = n_quanta * duration_per_quantum next_multiple_sp = sp.Piecewise( - (0, sp.Le(duration, 0)), - (minimal_duration, sp.Le(duration, minimal_duration)), - (rounded_up_duration, True) + (0, sp.Le(n_quanta, 0)), + (minimal_duration, sp.Le(n_quanta, min_quanta)), + (rounded_up_duration, True), + evaluate=False, ) return ExpressionScalar(next_multiple_sp)