455 op𝒟 : &'a 𝒟, |
455 op𝒟 : &'a 𝒟, |
456 config : &FBConfig<F>, |
456 config : &FBConfig<F>, |
457 iterator : I, |
457 iterator : I, |
458 plotter : SeqPlotter<F, N> |
458 plotter : SeqPlotter<F, N> |
459 ) -> DiscreteMeasure<Loc<F, N>, F> |
459 ) -> DiscreteMeasure<Loc<F, N>, F> |
460 where F : Float + ToNalgebraRealField, |
460 where F : Float + ToNalgebraRealField<MixedType = F>, |
461 I : AlgIteratorFactory<IterInfo<F, N>>, |
461 I : AlgIteratorFactory<IterInfo<F, N>>, |
462 for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>, |
462 for<'b> &'b A::Observable : std::ops::Neg<Output=A::Observable>, |
463 //+ std::ops::Mul<F, Output=A::Observable>, <-- FIXME: compiler overflow |
463 //+ std::ops::Mul<F, Output=A::Observable>, <-- FIXME: compiler overflow |
464 A::Observable : std::ops::MulAssign<F>, |
464 A::Observable : std::ops::MulAssign<F>, |
465 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone, |
465 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone, |
519 iterator : I, |
519 iterator : I, |
520 mut plotter : SeqPlotter<F, N>, |
520 mut plotter : SeqPlotter<F, N>, |
521 mut residual : A::Observable, |
521 mut residual : A::Observable, |
522 mut specialisation : Spec, |
522 mut specialisation : Spec, |
523 ) -> DiscreteMeasure<Loc<F, N>, F> |
523 ) -> DiscreteMeasure<Loc<F, N>, F> |
524 where F : Float + ToNalgebraRealField, |
524 where F : Float + ToNalgebraRealField<MixedType=F>, |
525 I : AlgIteratorFactory<IterInfo<F, N>>, |
525 I : AlgIteratorFactory<IterInfo<F, N>>, |
526 Spec : FBSpecialisation<F, A::Observable, N>, |
526 Spec : FBSpecialisation<F, A::Observable, N>, |
527 A::Observable : std::ops::MulAssign<F>, |
527 A::Observable : std::ops::MulAssign<F>, |
528 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone, |
528 GA : SupportGenerator<F, N, SupportType = S, Id = usize> + Clone, |
529 A : ForwardModel<Loc<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>> |
529 A : ForwardModel<Loc<F, N>, F, PreadjointCodomain = BTFN<F, GA, BTA, N>> |
655 let à = op𝒟.findim_matrix(μ.iter_locations()); |
655 let à = op𝒟.findim_matrix(μ.iter_locations()); |
656 let g̃ = DVector::from_iterator(μ.len(), |
656 let g̃ = DVector::from_iterator(μ.len(), |
657 μ.iter_locations() |
657 μ.iter_locations() |
658 .map(|ζ| minus_τv.apply(ζ) + ω0.apply(ζ)) |
658 .map(|ζ| minus_τv.apply(ζ) + ω0.apply(ζ)) |
659 .map(F::to_nalgebra_mixed)); |
659 .map(F::to_nalgebra_mixed)); |
660 let mut x = μ.masses_dvector(); |
660 let mut x = μ.masses_mut(); |
661 |
661 |
662 // The gradient of the forward component of the inner objective is C^*𝒟Cx - g̃. |
662 // The gradient of the forward component of the inner objective is C^*𝒟Cx - g̃. |
663 // We have |C^*𝒟Cx|_2 = sup_{|z|_2 ≤ 1} ⟨z, C^*𝒟Cx⟩ = sup_{|z|_2 ≤ 1} ⟨Cz|𝒟Cx⟩ |
663 // We have |C^*𝒟Cx|_2 = sup_{|z|_2 ≤ 1} ⟨z, C^*𝒟Cx⟩ = sup_{|z|_2 ≤ 1} ⟨Cz|𝒟Cx⟩ |
664 // ≤ sup_{|z|_2 ≤ 1} |Cz|_ℳ |𝒟Cx|_∞ ≤ sup_{|z|_2 ≤ 1} |Cz|_ℳ |𝒟| |Cx|_ℳ |
664 // ≤ sup_{|z|_2 ≤ 1} |Cz|_ℳ |𝒟Cx|_∞ ≤ sup_{|z|_2 ≤ 1} |Cz|_ℳ |𝒟| |Cx|_ℳ |
665 // ≤ sup_{|z|_2 ≤ 1} |z|_1 |𝒟| |x|_1 ≤ sup_{|z|_2 ≤ 1} n |z|_2 |𝒟| |x|_2 |
665 // ≤ sup_{|z|_2 ≤ 1} |z|_1 |𝒟| |x|_1 ≤ sup_{|z|_2 ≤ 1} n |z|_2 |𝒟| |x|_2 |
670 let inner_it = config.inner.iterator_options.stop_target(inner_tolerance); |
670 let inner_it = config.inner.iterator_options.stop_target(inner_tolerance); |
671 inner_iters += quadratic_nonneg(config.inner.method, &Ã, &g̃, τ*α, &mut x, |
671 inner_iters += quadratic_nonneg(config.inner.method, &Ã, &g̃, τ*α, &mut x, |
672 inner_τ, inner_it); |
672 inner_τ, inner_it); |
673 |
673 |
674 // Update masses of μ based on solution of finite-dimensional subproblem. |
674 // Update masses of μ based on solution of finite-dimensional subproblem. |
675 μ.set_masses_dvector(&x); |
675 //μ.set_masses_dvector(&x); |
676 } |
676 } |
677 |
677 |
678 // Form d = ω0 - τv - 𝒟μ = -𝒟(μ - μ^k) - τv for checking the proximate optimality |
678 // Form d = ω0 - τv - 𝒟μ = -𝒟(μ - μ^k) - τv for checking the proximate optimality |
679 // conditions in the predual space, and finding new points for insertion, if necessary. |
679 // conditions in the predual space, and finding new points for insertion, if necessary. |
680 let mut d = &minus_τv + op𝒟.preapply(μ_diff(&μ, &μ_base)); |
680 let mut d = &minus_τv + op𝒟.preapply(μ_diff(&μ, &μ_base)); |