Commit graph

15 commits

Author SHA1 Message Date
Michael Winter 62e6a75f4f Add harmonic compactness factor
- Compute sum of harmonic distances between all pitch pairs
- Lower sum = more compact chord = higher probability
- Uses pitch_difference() to get diff, then log2(n*d) for distance
- Add CLI arg: --weight-harmonic-compactness
2026-04-04 18:44:23 +02:00
Michael Winter 65e3a64a0c Add RGR voice movement factor
- Track consecutive voice change selections (change_counts)
- Favor voices that have been selected to change multiple times
- Block selection when threshold reached (default: 5)
- Add CLI args: --weight-rgr-voice-movement, --rgr-voice-movement-threshold
2026-04-04 16:53:44 +02:00
Michael Winter 3e0f2bc906 Add target register oscillations, amplitude, and fix negative target_register 2026-03-30 20:47:20 +02:00
Michael Winter 74aa937ec2 Add --target-register-power option to curve target register progression 2026-03-26 15:41:41 +01:00
Michael Winter d0bd15574d Fix asymmetric connectivity in voice leading graph
- Compute both c1→c2 and c2→c1 edges independently using _find_valid_edges()
- Fix _is_directly_tunable to properly reorder c2_transposed using movement map
- Clean up unused valid_pairings code in _build_movement_maps
- Add edge_data field to PathStep for debugging
2026-03-23 18:46:14 +01:00
Michael Winter e4b6d2cfdc Rename 'target range' to 'target register' throughout
- CLI: --target-range -> --target-register
- CLI: --weight-target-range -> --weight-target-register
- Config keys: target_range -> target_register
- Update README, tests, and all internal references
2026-03-17 14:11:21 +01:00
Michael Winter 146918c596 final weight is now product of factors raised to an exponent rather than sum 2026-03-17 08:41:18 +01:00
Michael Winter 7809fa5a76 Refactor: Move factor methods to Path class, add normalized_scores
- Move all _factor_* methods from pathfinder.py to path.py
- Add get_candidates() and compute_weights() to Path class
- Simplify step() to just commit chosen candidate
- Add normalized_scores field for consistent influence calculation
- Remove duplicate transposition/voice_map logic between get_candidates and step
- dca_voice_movement and target_range now use destination_chord directly
2026-03-16 18:59:13 +01:00
Michael Winter 482f2b0df5 Refactor: Rename sustain/last_visited fields for consistency 2026-03-16 17:35:07 +01:00
Michael Winter 861d012a95 Refactor: Unify Candidate and PathStep, fix DCA Hamiltonian
- Remove Candidate class, use PathStep for both hypothetical and actual steps
- Simplify Path.step() to accept a PathStep
- Fix DCA Hamiltonian to return visit_count directly instead of normalized score
- Tests pass and DCA properly discriminates
2026-03-16 16:53:22 +01:00
Michael Winter 400f970858 Rename graph.py to pathfinder.py
- Rename graph.py to pathfinder.py for clearer naming
- Update all imports
- Test CLI and tests pass
2026-03-16 16:13:19 +01:00
Michael Winter 1926930c3d Refactor PathStep to represent edges with source/destination and before/after state
- Add callback and interval parameters to find_stochastic_path() for adaptive weights
- Add get_influence() method to compute weighted score contribution per factor
- Rename graph_node/output_chord to source_node/destination_node/source_chord/destination_chord
- Rename voice_stay_count to sustain_count_before/after
- Rename node_visit_counts to last_visited_count_before/after
- Remove redundant internal state from Path - derive from steps
- Each PathStep now fully self-contained with before/after state
2026-03-16 14:00:10 +01:00
Michael Winter c682a1df02 Fix voice stay count to match master behavior
Changed voice stay count calculation in Path.step() to compare
by position (position i with position i) instead of tracking
voice identity. This makes dca_voice_movement factor behave
identically to master.
2026-03-16 02:27:21 +01:00
Michael Winter f2b785c98e Encapsulate voice-leading in Path.step()
- Move transposition, voice mapping into Path.step()
- Add node_visit_counts and voice_stay_count to each PathStep
- Fix voice tracking to use voice identity, not position
- Clean up unused last_graph_nodes code
- Full encapsulation: Path handles all voice-leading state
2026-03-16 01:11:15 +01:00
Michael Winter 66669de00f Add Path and Candidate classes for path state tracking
- Add src/path.py with Path and PathStep classes
- Path stores initial_chord, steps, weights_config
- PathStep stores graph_node, output_chord, transposition, movements, scores, candidates
- Refactor find_stochastic_path to use candidates approach
- Separate _build_candidates (raw scores) from _compute_weights
- Simplify return type to Path only (graph_chords available via property)
- Update io.py to use new Path API
2026-03-16 00:39:32 +01:00