Add uniform symdiff selection and store symdiff in graph edges

- Add symdiff to edge tuple in _find_valid_edges() and store in graph
- Add --uniform-symdiff CLI option to make symdiff selection uniform
- Implement uniform selection in pathfinder by grouping edges by symdiff
- With uniform: path uses symdiff 2 and 4 roughly equally
- Without uniform: path uses mostly symdiff 4 (most common)
This commit is contained in:
Michael Winter 2026-03-27 10:05:14 +01:00
parent 74aa937ec2
commit 863423ca7a
3 changed files with 28 additions and 0 deletions

View file

@ -160,6 +160,7 @@ class HarmonicSpace:
cent_diffs,
voice_crossing,
is_directly_tunable,
symdiff,
) = edge_data
graph.add_edge(
c1,
@ -170,6 +171,7 @@ class HarmonicSpace:
cent_diffs=cent_diffs,
voice_crossing=voice_crossing,
is_directly_tunable=is_directly_tunable,
symdiff=symdiff,
)
# Compute c2 -> c1 independently
@ -182,6 +184,7 @@ class HarmonicSpace:
cent_diffs,
voice_crossing,
is_directly_tunable,
symdiff,
) = edge_data
graph.add_edge(
c2,
@ -192,6 +195,7 @@ class HarmonicSpace:
cent_diffs=cent_diffs,
voice_crossing=voice_crossing,
is_directly_tunable=is_directly_tunable,
symdiff=symdiff,
)
return graph
@ -318,6 +322,7 @@ class HarmonicSpace:
cent_diffs,
voice_crossing,
is_directly_tunable,
symdiff,
)
)

View file

@ -408,6 +408,11 @@ def main():
default=1,
help="Weight for target register factor (0=disabled, default: 1)",
)
parser.add_argument(
"--uniform-symdiff",
action="store_true",
help="Make symdiff selection uniform across range (ignore weight differences)",
)
parser.add_argument(
"--dims", type=int, default=7, help="Number of prime dimensions (4, 5, 7, or 8)"
)
@ -614,6 +619,9 @@ def main():
else:
weights_config["weight_target_register"] = 0 # disabled
# Uniform symdiff selection
weights_config["uniform_symdiff"] = args.uniform_symdiff
weights_config["max_path"] = args.max_path
path_obj = path_finder.find_stochastic_path(

View file

@ -54,6 +54,21 @@ class PathFinder:
if not out_edges:
break
# Group edges by symdiff for uniform selection
edges_by_symdiff = {}
for edge in out_edges:
symdiff = edge[2].get("symdiff", 0)
if symdiff not in edges_by_symdiff:
edges_by_symdiff[symdiff] = []
edges_by_symdiff[symdiff].append(edge)
# If uniform_symdiff, pick symdiff uniformly then use those edges
if weights_config.get("uniform_symdiff") and edges_by_symdiff:
import random
chosen_symdiff = random.choice(list(edges_by_symdiff.keys()))
out_edges = edges_by_symdiff[chosen_symdiff]
# Build candidates using Path's state and factor methods
candidates = path_obj.get_candidates(out_edges, path_obj.output_chords)