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; |