From a377558f891454c019c3f223b96d41785abe1648 Mon Sep 17 00:00:00 2001 From: Michael Winter Date: Sat, 18 Apr 2026 15:33:49 +0200 Subject: [PATCH] Fix weight values allowing 0 and add normalization floor --- src/path.py | 21 +++++++++++---------- webapp/generate.html | 14 +++++++------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/path.py b/src/path.py index 9af2f71..4b1a916 100644 --- a/src/path.py +++ b/src/path.py @@ -77,6 +77,8 @@ class Path: source_chord = path_chords[-1] candidates = [] + threshold = self.weights_config.get("rgr_voice_movement_threshold", 5) + for edge in out_edges: source_node = edge[0] destination_node = edge[1] @@ -174,6 +176,8 @@ class Path: next_cents = destination_chord.pitches[voice_idx].to_cents() if curr_cents != next_cents: change_after[voice_idx] += 1 + if change_after[voice_idx] >= threshold: + change_after[voice_idx] = 0 step = PathStep( source_node=source_node, @@ -219,7 +223,10 @@ class Path: total = sum(values) if total == 0 or len(set(values)) <= 1: return None - return [v / total for v in values] + min_value = 0.01 + adjusted = [max(v, min_value) for v in values] + total_adjusted = sum(adjusted) + return [v / total_adjusted for v in adjusted] melodic_norm = sum_normalize(melodic_values) contrary_norm = sum_normalize(contrary_values) @@ -261,7 +268,7 @@ class Path: if target_norm: w *= target_norm[i] * config.get("weight_target_register", 1) - step.weight = w**16 + step.weight = w**8 weights.append(w) step.normalized_scores = { @@ -335,7 +342,7 @@ class Path: num_moving = num_up + num_down if num_moving < 2: - return 0.0 + return 1.0 ideal_up = num_moving / 2 distance = abs(num_up - ideal_up) @@ -376,7 +383,6 @@ class Path: candidate_cents = [p.to_cents() for p in destination_chord.pitches] sum_changing = 0 - sum_all = sum(sustain_counts) for voice_idx in range(num_voices): if current_cents[voice_idx] != candidate_cents[voice_idx]: @@ -406,8 +412,6 @@ class Path: if num_voices == 0: return 1.0 - threshold = config.get("rgr_voice_movement_threshold", 5) - current_cents = [p.to_cents() for p in source_chord.pitches] candidate_cents = [p.to_cents() for p in destination_chord.pitches] @@ -415,10 +419,7 @@ class Path: for voice_idx in range(num_voices): if current_cents[voice_idx] != candidate_cents[voice_idx]: - count = change_counts[voice_idx] - if count >= threshold: - return 0.0 - sum_repeating += count + sum_repeating += change_counts[voice_idx] return sum_repeating diff --git a/webapp/generate.html b/webapp/generate.html index dd0b687..493f42e 100644 --- a/webapp/generate.html +++ b/webapp/generate.html @@ -524,14 +524,14 @@ allowVoiceCrossing: document.getElementById('allowVoiceCrossing').checked, disableDirectTuning: document.getElementById('disableDirectTuning').checked, uniformSymdiff: document.getElementById('uniformSymdiff').checked, - weightMelodic: parseFloat(document.getElementById('weightMelodic').value) || 1, - weightContraryMotion: parseFloat(document.getElementById('weightContraryMotion').value) || 0, - weightDcaHamiltonian: parseFloat(document.getElementById('weightDcaHamiltonian').value) || 1, - weightDcaVoiceMovement: parseFloat(document.getElementById('weightDcaVoiceMovement').value) || 1, - weightRgrVoiceMovement: parseFloat(document.getElementById('weightRgrVoiceMovement').value) || 0, + weightMelodic: (() => { const v = parseFloat(document.getElementById('weightMelodic').value); return isNaN(v) ? 1 : v; })(), + weightContraryMotion: (() => { const v = parseFloat(document.getElementById('weightContraryMotion').value); return isNaN(v) ? 0 : v; })(), + weightDcaHamiltonian: (() => { const v = parseFloat(document.getElementById('weightDcaHamiltonian').value); return isNaN(v) ? 1 : v; })(), + weightDcaVoiceMovement: (() => { const v = parseFloat(document.getElementById('weightDcaVoiceMovement').value); return isNaN(v) ? 1 : v; })(), + weightRgrVoiceMovement: (() => { const v = parseFloat(document.getElementById('weightRgrVoiceMovement').value); return isNaN(v) ? 0 : v; })(), rgrVoiceMovementThreshold: parseInt(document.getElementById('rgrVoiceMovementThreshold').value) || 5, - weightHarmonicCompactness: parseFloat(document.getElementById('weightHarmonicCompactness').value) || 0, - weightTargetRegister: parseFloat(document.getElementById('weightTargetRegister').value) || 1, + weightHarmonicCompactness: (() => { const v = parseFloat(document.getElementById('weightHarmonicCompactness').value); return isNaN(v) ? 0 : v; })(), + weightTargetRegister: (() => { const v = parseFloat(document.getElementById('weightTargetRegister').value); return isNaN(v) ? 1 : v; })(), cacheDir: document.getElementById('cacheDir').value || 'cache', rebuildCache: document.getElementById('rebuildCache').checked, noCache: document.getElementById('noCache').checked,