Skip to content

Commit c0f17bd

Browse files
committed
fix(periodic): add stepped continuation fallback and commit test examples
- Add stepped parameter continuation fallback for fold branch tracking
1 parent 2d4da07 commit c0f17bd

3 files changed

Lines changed: 63 additions & 10 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ref/
1010
*.py[cod]
1111

1212
# Generated frontend artifacts
13+
node_modules/
1314
frontend/node_modules/
1415
frontend/dist/
1516
frontend/pkg/

Cargo.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ repository = "https://github.com/namvdo/set-valued-viz"
1010
[lib]
1111
crate-type = ["cdylib", "rlib"]
1212

13+
[[example]]
14+
name = "imperial_core_lab"
15+
test = false
16+
17+
[[example]]
18+
name = "imperial_practice"
19+
test = true
20+
1321
[dependencies]
1422
nalgebra = "0.33.0"
1523
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }

src/boundary_map/periodic/sweep.rs

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -494,23 +494,62 @@ fn correct_henon_seed_at_params(
494494
)
495495
}
496496

497-
/// Correct cached Hénon periodic orbits directly at the target parameters.
498-
///
499-
/// The old parameter arguments remain in the public interface for compatibility
500-
/// with the existing Rust/Wasm worker protocol. Simple continuation does not use
501-
/// them because it does not interpolate a parameter path.
497+
fn continue_henon_seed_stepped(
498+
seed: ExtendedPoint,
499+
period: usize,
500+
old_params: HenonContinuationParams,
501+
new_params: HenonContinuationParams,
502+
residual_threshold: f64,
503+
) -> Option<ExtendedPoint> {
504+
if let Some(fp) = correct_henon_seed_at_params(seed, period, new_params, residual_threshold) {
505+
return Some(fp);
506+
}
507+
508+
let da = new_params.a - old_params.a;
509+
let db = new_params.b - old_params.b;
510+
let de = new_params.epsilon - old_params.epsilon;
511+
512+
let dist = da.abs().max(db.abs()).max(de.abs());
513+
if dist < 1e-8 {
514+
return None;
515+
}
516+
517+
let step_size = 0.002;
518+
let num_steps = ((dist / step_size).ceil() as usize).clamp(2, 100);
519+
520+
let mut current_seed = seed;
521+
for step in 1..=num_steps {
522+
let t = step as f64 / num_steps as f64;
523+
let interim_params = HenonContinuationParams {
524+
a: old_params.a + t * da,
525+
b: old_params.b + t * db,
526+
epsilon: old_params.epsilon + t * de,
527+
};
528+
current_seed =
529+
correct_henon_seed_at_params(current_seed, period, interim_params, residual_threshold)?;
530+
}
531+
Some(current_seed)
532+
}
533+
534+
/// Correct cached Hénon periodic orbits at the target parameters, stepping along
535+
/// the parameter path if direct correction fails.
502536
pub fn continue_henon_orbits_from_previous(
503537
previous_orbits: &[FoundPeriodicOrbit],
504-
_old_a: f64,
505-
_old_b: f64,
506-
_old_epsilon: f64,
538+
old_a: f64,
539+
old_b: f64,
540+
old_epsilon: f64,
507541
new_a: f64,
508542
new_b: f64,
509543
new_epsilon: f64,
510544
max_period: usize,
511545
residual_threshold: f64,
512546
) -> PeriodicOrbitDatabase {
513547
let residual_threshold = sanitize_residual_threshold(residual_threshold);
548+
let old_params = HenonContinuationParams {
549+
a: old_a,
550+
b: old_b,
551+
epsilon: old_epsilon,
552+
};
514553
let new_params = HenonContinuationParams {
515554
a: new_a,
516555
b: new_b,
@@ -527,8 +566,13 @@ pub fn continue_henon_orbits_from_previous(
527566
continue;
528567
};
529568

530-
let corrected =
531-
correct_henon_seed_at_params(seed, orbit.period, new_params, residual_threshold);
569+
let corrected = continue_henon_seed_stepped(
570+
seed,
571+
orbit.period,
572+
old_params,
573+
new_params,
574+
residual_threshold,
575+
);
532576

533577
if let Some(fp) = corrected {
534578
try_add_orbit_generic(

0 commit comments

Comments
 (0)