src/regularisation.rs

changeset 72
e9a460a0e638
parent 63
7a8a55fd41c0
child 76
b921ed0ab99b
equal deleted inserted replaced
71:e2953ffd4e0b 72:e9a460a0e638
232 config: &InsertionConfig<F>, 232 config: &InsertionConfig<F>,
233 ) -> F 233 ) -> F
234 where 234 where
235 M: MinMaxMapping<Domain, F>; 235 M: MinMaxMapping<Domain, F>;
236 236
237 /// Convert bound on the regulariser to a bond on the Radon norm 237 /// Convert bound on the regulariser to a bound on the Radon norm
238 fn radon_norm_bound(&self, b: F) -> F; 238 fn radon_norm_bound(&self, b: F) -> F;
239
240 /// Returns true if $v$ is within the pointwise range of the subdifferential
241 fn subdiff_range(&self) -> Bounds<F>;
239 } 242 }
240 243
241 #[replace_float_literals(F::cast_from(literal))] 244 #[replace_float_literals(F::cast_from(literal))]
242 impl<F: Float + ToNalgebraRealField, const N: usize> RegTerm<Loc<N, F>, F> 245 impl<F: Float + ToNalgebraRealField, const N: usize> RegTerm<Loc<N, F>, F>
243 for NonnegRadonRegTerm<F> 246 for NonnegRadonRegTerm<F>
384 *dest = F::to_nalgebra_mixed(β); 387 *dest = F::to_nalgebra_mixed(β);
385 } 388 }
386 // Solve finite-dimensional subproblem. 389 // Solve finite-dimensional subproblem.
387 let inner_tolerance = ε * config.inner.tolerance_mult; 390 let inner_tolerance = ε * config.inner.tolerance_mult;
388 let inner_it = config.inner.iterator_options.stop_target(inner_tolerance); 391 let inner_it = config.inner.iterator_options.stop_target(inner_tolerance);
389 stats.inner_iters += 392 stats.inner_iters += l1squared_nonneg(&y, &g_na, τα, &mut x, &config.inner, inner_it);
390 l1squared_nonneg(&y, &g_na, τα, 1.0, &mut x, &config.inner, inner_it);
391 393
392 // Update masses of μ based on solution of finite-dimensional subproblem. 394 // Update masses of μ based on solution of finite-dimensional subproblem.
393 μ.set_masses_dvector(&x); 395 μ.set_masses_dvector(&x);
394 } 396 }
395 } 397 }
414 416
415 return { 417 return {
416 μ.both_matching(radon_μ).all(|(α, rα, x)| { 418 μ.both_matching(radon_μ).all(|(α, rα, x)| {
417 let v = -d.apply(x); // TODO: observe ad hoc negation here, after minus_τv 419 let v = -d.apply(x); // TODO: observe ad hoc negation here, after minus_τv
418 // switch to τv. 420 // switch to τv.
419 let (l1, u1) = match α.partial_cmp(&0.0).unwrap_or(Equal) { 421 let (l1, u1) = match α.total_cmp(&0.0) {
420 Greater => (τα, τα), 422 Greater => (τα, τα),
421 _ => (F::NEG_INFINITY, τα), 423 _ => (F::NEG_INFINITY, τα),
422 // Less should not happen; treated as Equal 424 // Less should not happen; treated as Equal
423 }; 425 };
424 let (l2, u2) = match rα.partial_cmp(&0.0).unwrap_or(Equal) { 426 let (l2, u2) = match rα.total_cmp(&0.0) {
425 Greater => (slack, slack), 427 Greater => (slack, slack),
426 Equal => (-slack, slack), 428 Equal => (-slack, slack),
427 Less => (-slack, -slack), 429 Less => (-slack, -slack),
428 }; 430 };
429 // TODO: both fail. 431 // TODO: both fail.
462 w(z) - w(y) 464 w(z) - w(y)
463 } 465 }
464 466
465 fn radon_norm_bound(&self, b: F) -> F { 467 fn radon_norm_bound(&self, b: F) -> F {
466 b / self.α() 468 b / self.α()
469 }
470
471 fn subdiff_range(&self) -> Bounds<F> {
472 Bounds(F::NEG_INFINITY, self.α())
467 } 473 }
468 } 474 }
469 475
470 #[replace_float_literals(F::cast_from(literal))] 476 #[replace_float_literals(F::cast_from(literal))]
471 impl<F: Float + ToNalgebraRealField, const N: usize> RegTerm<Loc<N, F>, F> for RadonRegTerm<F> { 477 impl<F: Float + ToNalgebraRealField, const N: usize> RegTerm<Loc<N, F>, F> for RadonRegTerm<F> {
642 let g_na = DVector::from_vec(g); 648 let g_na = DVector::from_vec(g);
643 // Solve finite-dimensional subproblem. 649 // Solve finite-dimensional subproblem.
644 let inner_tolerance = ε * config.inner.tolerance_mult; 650 let inner_tolerance = ε * config.inner.tolerance_mult;
645 let inner_it = config.inner.iterator_options.stop_target(inner_tolerance); 651 let inner_it = config.inner.iterator_options.stop_target(inner_tolerance);
646 stats.inner_iters += 652 stats.inner_iters +=
647 l1squared_unconstrained(&y, &g_na, τα, 1.0, &mut x, &config.inner, inner_it); 653 l1squared_unconstrained(&y, &g_na, τα, &mut x, &config.inner, inner_it);
648 654
649 // Update masses of μ based on solution of finite-dimensional subproblem. 655 // Update masses of μ based on solution of finite-dimensional subproblem.
650 μ.set_masses_dvector(&x); 656 μ.set_masses_dvector(&x);
651 } 657 }
652 } 658 }
730 } 736 }
731 737
732 fn radon_norm_bound(&self, b: F) -> F { 738 fn radon_norm_bound(&self, b: F) -> F {
733 b / self.α() 739 b / self.α()
734 } 740 }
735 } 741
742 fn subdiff_range(&self) -> Bounds<F> {
743 let α = self.α();
744 Bounds(-α, α)
745 }
746 }

mercurial