Commit graph

19 commits

Author SHA1 Message Date
Michael Winter dd9df2ad33 Fix Hamiltonian to track untransposed graph nodes
The Hamiltonian weight was comparing transposed output chords
against untransposed graph nodes, so they never matched.
Now tracks graph_path separately for correct Hamiltonian check.
2026-03-13 05:07:24 +01:00
Michael Winter 40a8996b4e Rename _calc_symdiff_expanded to _calc_symdiff
Since projection now happens in generate_connected_sets, the function is simpler.
2026-03-13 04:35:17 +01:00
Michael Winter 2df55d8c16 Fix outdated docstring in _build_movement_maps
Update docstring to reflect index-based movement format: {src_idx: dest_idx}
instead of old pitch-based format.
2026-03-13 04:33:17 +01:00
Michael Winter a5efc548e5 Clean up code: remove unused imports, variables, and functions
- Remove duplicate 'permutations' import
- Remove unused 'choice' import
- Remove unused '_check_melodic_threshold' function
- Remove unused 'sorted_permutation' variable
- Update outdated comments
- Simplify _initialize_chords return value
2026-03-13 04:27:55 +01:00
Michael Winter cfab07da88 Sort chords in generate_connected_sets and simplify voice crossing detection
- Sort pitches by frequency after projection in generate_connected_sets
- This ensures all chords in graph have bass-to-soprano ordering
- Simplified voice crossing check: verify destination is sorted after movement
- Since source is sorted, just check if adjacent pairs remain in order
- Fixed movement map indexing bug in precomputed voice crossing detection
2026-03-13 04:16:48 +01:00
Michael Winter ba3ded82d8 Fix voice crossing detection
- Replace index-based voice crossing check with pitch ordering comparison
- Now properly detects when voice ordering changes between chords
- This was causing edges with voice crossing to be incorrectly allowed
2026-03-13 01:25:18 +01:00
Michael Winter c63b6cb1d4 Add frequency output file (fundamental=100Hz) 2026-03-13 01:11:18 +01:00
Michael Winter b89ff9c184 Add hamiltonian weight to favor unvisited nodes
- Add 'hamiltonian' option to weights config (default True)
- In edge weight calculation: boost unvisited nodes (10x), penalize visited (0.1x)
- Path now extends longer before getting stuck
2026-03-13 01:06:57 +01:00
Michael Winter f04b1baa49 Fix import: move permutations to top-level 2026-03-13 00:59:22 +01:00
Michael Winter fa19b7877f Clean up unused code
- Remove unused methods: generate_connected_sets_with_edges,
  build_graph_lattice_method, _compute_edge_data_fast, _wrap_pitch, _toCHS
- Remove unused import: product from itertools
- Remove old notebook files: compact_sets_optimized_2.py, compact_sets_optimized_2.ipynb
- Keep session-ses_328e.md for reference

compact_sets.py: 1450 -> 1067 lines
2026-03-13 00:55:27 +01:00
Michael Winter c44dd60e83 Fix transposition deduplication and rename expand to project
- Deduplicate transpositions in _find_valid_edges using set comprehension
  to avoid processing same transposition multiple times
- Edge count now matches notebook (1414 vs 2828)
- Rename expand() to project() for clarity (project to [1,2) range)
- Fix SyntaxWarnings in docstrings (escape backslashes)
2026-03-13 00:28:34 +01:00
Michael Winter 69f08814a9 Store edge properties at build time: cent_diffs, voice_crossing, is_directly_tunable
- Add _is_directly_tunable method to check if changing pitches are adjacent to staying pitch
- Modify _find_valid_edges to compute and return edge properties
- Store all properties in graph edges at build time
- Simplify _calculate_edge_weights to read from edge data
- Rename voice_crossing config to voice_crossing_allowed (False = reject crossing)
2026-03-12 20:06:14 +01:00
Michael Winter b7b95bb849 Remove movement_size weight as redundant with melodic threshold 2026-03-12 19:41:48 +01:00
Michael Winter e13e9ba3bc Add voice crossing check - reject edges where voices cross
- Movement map must be identity (0->0, 1->1, 2->2) to pass
- If any voice moves to a different position, weight = 0
2026-03-12 19:19:47 +01:00
Michael Winter d4cdd86e85 Add voice-leading preservation with index-to-index movement mapping
- Change movement map from {pitch: {destination, cents}} to {src_idx: dest_idx}
- Track voice mapping cumulatively in pathfinder
- Reorder output pitches according to voice mapping
- Update weight calculation to compute cent_diffs from index mapping
- Melodic threshold now correctly filters edges based on actual movements
2026-03-12 19:14:33 +01:00
Michael Winter 2b422d55fe Fix output to preserve internal tuple order
- Remove sorted_by_frequency from write functions
- Output now uses internal chord._pitches order instead of sorted
2026-03-12 18:18:40 +01:00
Michael Winter ccf90d19e1 Fix movement tracking and add melodic threshold weights
- Add movement tracking to edges: {source: {destination, cent_difference}}
- Fix movement map to handle multiple changing pitches with permutations
- Remove melodic threshold from graph building (apply in weight calculation)
- Add melodic_threshold_min/max to weight config
- Add CLI args --melodic-min and --melodic-max
2026-03-12 17:44:54 +01:00
Michael Winter aeb1fd9982 Fix path finding to use cumulative transpositions
- Track cumulative transposition across steps so output = destination + (T1 + T2 + ... + TN)
- Fix symdiff calculation to use expanded (transposed) pitches instead of collapsed
- Update CLI from --change to --symdiff-min/symdiff-max
2026-03-12 16:59:44 +01:00
Michael Winter f2bcd37287 Add elegant OOP implementation with CLI
- New compact_sets.py with Pitch, Chord, HarmonicSpace classes
- Voice leading graph with change parameter (instead of symdiff)
- CLI: --change, --dims, --chord-size, --max-path, --seed
- Tests for core functionality
- .gitignore for Python/pytest
2026-03-10 16:13:41 +01:00