| 529 let quiet = iterator.is_quiet(); |
529 let quiet = iterator.is_quiet(); |
| 530 let op𝒟norm = op𝒟.opnorm_bound(); |
530 let op𝒟norm = op𝒟.opnorm_bound(); |
| 531 // We multiply tolerance by τ for FB since |
531 // We multiply tolerance by τ for FB since |
| 532 // our subproblems depending on tolerances are scaled by τ compared to the conditional |
532 // our subproblems depending on tolerances are scaled by τ compared to the conditional |
| 533 // gradient approach. |
533 // gradient approach. |
| 534 let mut tolerance = config.tolerance * τ * α; |
534 let tolerance = config.tolerance * τ * α; |
| 535 let mut ε = tolerance.initial(); |
535 let mut ε = tolerance.initial(); |
| 536 |
536 |
| 537 // Initialise operators |
537 // Initialise operators |
| 538 let preadjA = opA.preadjoint(); |
538 let preadjA = opA.preadjoint(); |
| 539 |
539 |
| 567 |
567 |
| 568 // Run the algorithm |
568 // Run the algorithm |
| 569 iterator.iterate(|state| { |
569 iterator.iterate(|state| { |
| 570 // Calculate subproblem tolerances, and update main tolerance for next iteration |
570 // Calculate subproblem tolerances, and update main tolerance for next iteration |
| 571 let τα = τ * α; |
571 let τα = τ * α; |
| 572 // if μ.len() == 0 /*state.iteration() == 1*/ { |
|
| 573 // let t = minus_τv.bounds().upper() * 0.001; |
|
| 574 // if t > 0.0 { |
|
| 575 // let (ξ, v_ξ) = minus_τv.maximise(t, config.refinement.max_steps); |
|
| 576 // if τα + ε > v_ξ && v_ξ > τα { |
|
| 577 // // The zero measure is already within bounds, so improve them |
|
| 578 // tolerance = config.tolerance * (v_ξ - τα); |
|
| 579 // ε = tolerance.initial(); |
|
| 580 // } |
|
| 581 // μ += DeltaMeasure { x : ξ, α : 0.0 }; |
|
| 582 // } else { |
|
| 583 // // Zero is the solution. |
|
| 584 // return Step::Terminated |
|
| 585 // } |
|
| 586 // } |
|
| 587 let target_bounds = Bounds(τα - ε, τα + ε); |
572 let target_bounds = Bounds(τα - ε, τα + ε); |
| 588 let merge_tolerance = config.merge_tolerance_mult * ε; |
573 let merge_tolerance = config.merge_tolerance_mult * ε; |
| 589 let merge_target_bounds = Bounds(τα - merge_tolerance, τα + merge_tolerance); |
574 let merge_target_bounds = Bounds(τα - merge_tolerance, τα + merge_tolerance); |
| 590 let inner_tolerance = ε * config.inner.tolerance_mult; |
575 let inner_tolerance = ε * config.inner.tolerance_mult; |
| 591 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
576 let refinement_tolerance = ε * config.refinement.tolerance_mult; |
| 592 let maximise_above = τα + ε * config.insertion_cutoff_factor; |
577 let maximise_above = τα + ε * config.insertion_cutoff_factor; |
| 593 let mut ε1 = ε; |
|
| 594 let ε_prev = ε; |
578 let ε_prev = ε; |
| 595 ε = tolerance.update(ε, state.iteration()); |
579 ε = tolerance.update(ε, state.iteration()); |
| 596 |
580 |
| 597 // Maximum insertion count and measure difference calculation depend on insertion style. |
581 // Maximum insertion count and measure difference calculation depend on insertion style. |
| 598 let (m, warn_insertions) = match (state.iteration(), config.bootstrap_insertions) { |
582 let (m, warn_insertions) = match (state.iteration(), config.bootstrap_insertions) { |
| 675 // the calculations in the beginning of the loop that v_ξ = (ω0-τv-𝒟μ)(ξ) = d(ξ), |
659 // the calculations in the beginning of the loop that v_ξ = (ω0-τv-𝒟μ)(ξ) = d(ξ), |
| 676 // where 𝒟μ is now distinct from μ0 after the insertions already performed. |
660 // where 𝒟μ is now distinct from μ0 after the insertions already performed. |
| 677 // We do not need to check lower bounds, as a solution of the finite-dimensional |
661 // We do not need to check lower bounds, as a solution of the finite-dimensional |
| 678 // subproblem should always satisfy them. |
662 // subproblem should always satisfy them. |
| 679 |
663 |
| 680 // // Find the mimimum over the support of μ. |
664 // If μ has some spikes, only find a maximum of d if it is above a threshold |
| 681 // let d_min_supp = d_max;μ.iter_spikes().filter_map(|&DeltaMeasure{ α, ref x }| { |
665 // defined by the refinment tolerance. |
| 682 // (α != F::ZERO).then(|| d.value(x)) |
666 let (ξ, v_ξ) = match d.maximise_above(maximise_above, refinement_tolerance, |
| 683 // }).reduce(F::min).unwrap_or(0.0); |
667 config.refinement.max_steps) { |
| 684 |
668 None => break 'insertion (true, d), |
| 685 let (ξ, v_ξ) = if false /* μ.len() == 0*/ /*count == 0 &&*/ { |
669 Some(res) => res, |
| 686 // If μ has no spikes, just find the maximum of d. Then adjust the tolerance, if |
|
| 687 // necessary, to adapt it to the problem. |
|
| 688 let (ξ, v_ξ) = d.maximise(refinement_tolerance, config.refinement.max_steps); |
|
| 689 //dbg!((τα, v_ξ, target_bounds.upper(), maximise_above)); |
|
| 690 if τα < v_ξ && v_ξ < target_bounds.upper() { |
|
| 691 ε1 = v_ξ - τα; |
|
| 692 ε *= ε1 / ε_prev; |
|
| 693 tolerance *= ε1 / ε_prev; |
|
| 694 } |
|
| 695 (ξ, v_ξ) |
|
| 696 } else { |
|
| 697 // If μ has some spikes, only find a maximum of d if it is above a threshold |
|
| 698 // defined by the refinment tolerance. |
|
| 699 match d.maximise_above(maximise_above, refinement_tolerance, |
|
| 700 config.refinement.max_steps) { |
|
| 701 None => break 'insertion (true, d), |
|
| 702 Some(res) => res, |
|
| 703 } |
|
| 704 }; |
670 }; |
| 705 |
|
| 706 // // Do a one final check whether we can stop already without inserting more points |
|
| 707 // // because `d` actually in bounds based on a more refined estimate. |
|
| 708 // if may_break && target_bounds.upper() >= v_ξ { |
|
| 709 // break (true, d) |
|
| 710 // } |
|
| 711 |
671 |
| 712 // Break if maximum insertion count reached |
672 // Break if maximum insertion count reached |
| 713 if count >= max_insertions { |
673 if count >= max_insertions { |
| 714 let in_bounds2 = target_bounds.upper() >= v_ξ; |
674 let in_bounds2 = target_bounds.upper() >= v_ξ; |
| 715 break 'insertion (in_bounds2, d) |
675 break 'insertion (in_bounds2, d) |
| 730 |
690 |
| 731 // Merge spikes |
691 // Merge spikes |
| 732 if state.iteration() % config.merge_every == 0 { |
692 if state.iteration() % config.merge_every == 0 { |
| 733 let n_before_merge = μ.len(); |
693 let n_before_merge = μ.len(); |
| 734 μ.merge_spikes(config.merging, |μ_candidate| { |
694 μ.merge_spikes(config.merging, |μ_candidate| { |
| 735 //println!("Merge attempt!"); |
|
| 736 let mut d = &minus_τv + op𝒟.preapply(μ_diff(&μ_candidate, &μ_base)); |
695 let mut d = &minus_τv + op𝒟.preapply(μ_diff(&μ_candidate, &μ_base)); |
| 737 |
696 |
| 738 if merge_target_bounds.superset(&d.bounds()) { |
697 if merge_target_bounds.superset(&d.bounds()) { |
| 739 //println!("…Early Ok"); |
|
| 740 return Some(()) |
698 return Some(()) |
| 741 } |
699 } |
| 742 |
700 |
| 743 let d_min_supp = μ_candidate.iter_spikes().filter_map(|&DeltaMeasure{ α, ref x }| { |
701 let d_min_supp = μ_candidate.iter_spikes().filter_map(|&DeltaMeasure{ α, ref x }| { |
| 744 (α != 0.0).then(|| d.apply(x)) |
702 (α != 0.0).then(|| d.apply(x)) |
| 745 }).reduce(F::min); |
703 }).reduce(F::min); |
| 746 |
704 |
| 747 if d_min_supp.map_or(true, |b| b >= merge_target_bounds.lower()) && |
705 if d_min_supp.map_or(true, |b| b >= merge_target_bounds.lower()) && |
| 748 d.has_upper_bound(merge_target_bounds.upper(), refinement_tolerance, |
706 d.has_upper_bound(merge_target_bounds.upper(), refinement_tolerance, |
| 749 config.refinement.max_steps) { |
707 config.refinement.max_steps) { |
| 750 //println!("…Ok"); |
|
| 751 Some(()) |
708 Some(()) |
| 752 } else { |
709 } else { |
| 753 //println!("…Fail"); |
|
| 754 None |
710 None |
| 755 } |
711 } |
| 756 }); |
712 }); |
| 757 debug_assert!(μ.len() >= n_before_merge); |
713 debug_assert!(μ.len() >= n_before_merge); |
| 758 merged += μ.len() - n_before_merge; |
714 merged += μ.len() - n_before_merge; |
| 775 plotter.plot_spikes( |
731 plotter.plot_spikes( |
| 776 format!("iter {} end; {}", state.iteration(), within_tolerances), &d, |
732 format!("iter {} end; {}", state.iteration(), within_tolerances), &d, |
| 777 "start".to_string(), Some(&minus_τv), |
733 "start".to_string(), Some(&minus_τv), |
| 778 Some(target_bounds), value_μ, |
734 Some(target_bounds), value_μ, |
| 779 ); |
735 ); |
| 780 // Calculate mean inner iterations and reset relevant counters |
736 // Calculate mean inner iterations and reset relevant counters. |
| 781 // Return the statistics |
737 // Return the statistics |
| 782 let res = IterInfo { |
738 let res = IterInfo { |
| 783 value : specialisation.calculate_fit(&μ, &residual) + α * value_μ.norm(Radon), |
739 value : specialisation.calculate_fit(&μ, &residual) + α * value_μ.norm(Radon), |
| 784 n_spikes : value_μ.len(), |
740 n_spikes : value_μ.len(), |
| 785 inner_iters, |
741 inner_iters, |
| 786 this_iters, |
742 this_iters, |
| 787 merged, |
743 merged, |
| 788 pruned, |
744 pruned, |
| 789 ε : ε_prev, |
745 ε : ε_prev, |
| 790 maybe_ε1 : Some(ε1), |
|
| 791 postprocessing: config.postprocessing.then(|| value_μ.clone()), |
746 postprocessing: config.postprocessing.then(|| value_μ.clone()), |
| 792 }; |
747 }; |
| 793 inner_iters = 0; |
748 inner_iters = 0; |
| 794 this_iters = 0; |
749 this_iters = 0; |
| 795 merged = 0; |
750 merged = 0; |