| 1 /*! |
1 /*! |
| 2 This module provides [`RunnableExperiment`] for running chosen algorithms on a chosen experiment. |
2 This module provides [`RunnableExperiment`] for running chosen algorithms on a chosen experiment. |
| 3 */ |
3 */ |
| 4 |
4 |
| 5 use crate::fb::{pointsource_fb_reg, pointsource_fista_reg, FBConfig, InsertionConfig}; |
5 use crate::domain::{AdmissibleDomain, FullSpace}; |
| |
6 use crate::fb::{pointsource_fb_dom, pointsource_fista_reg, FBConfig, InsertionConfig}; |
| 6 use crate::forward_model::sensor_grid::{ |
7 use crate::forward_model::sensor_grid::{ |
| 7 //SensorGridBTFN, |
8 //SensorGridBTFN, |
| 8 Sensor, |
9 Sensor, |
| 9 SensorGrid, |
10 SensorGrid, |
| 10 SensorGridBT, |
11 SensorGridBT, |
| 11 Spread, |
12 Spread, |
| 12 }; |
13 }; |
| 13 use crate::forward_model::*; |
14 use crate::forward_model::*; |
| 14 use crate::forward_pdps::{pointsource_fb_pair, pointsource_forward_pdps_pair, ForwardPDPSConfig}; |
15 use crate::forward_pdps::{ |
| |
16 pointsource_fb_pair_dom, pointsource_forward_pdps_pair_dom, ForwardPDPSConfig, |
| |
17 }; |
| 15 use crate::frank_wolfe::{pointsource_fw_reg, FWConfig, FWVariant, RegTermFW}; |
18 use crate::frank_wolfe::{pointsource_fw_reg, FWConfig, FWVariant, RegTermFW}; |
| 16 use crate::kernels::*; |
19 use crate::kernels::*; |
| 17 use crate::measures::merging::{SpikeMerging, SpikeMergingMethod}; |
20 use crate::measures::merging::{SpikeMerging, SpikeMergingMethod}; |
| 18 use crate::measures::*; |
21 use crate::measures::*; |
| 19 use crate::pdps::{pointsource_pdps_reg, PDPSConfig}; |
22 use crate::pdps::{pointsource_pdps_reg, PDPSConfig}; |
| 22 ProxPenalty, ProxTerm, RadonSquared, StepLengthBound, StepLengthBoundPD, StepLengthBoundPair, |
25 ProxPenalty, ProxTerm, RadonSquared, StepLengthBound, StepLengthBoundPD, StepLengthBoundPair, |
| 23 }; |
26 }; |
| 24 use crate::regularisation::{NonnegRadonRegTerm, RadonRegTerm, Regularisation, SlidingRegTerm}; |
27 use crate::regularisation::{NonnegRadonRegTerm, RadonRegTerm, Regularisation, SlidingRegTerm}; |
| 25 use crate::seminorms::*; |
28 use crate::seminorms::*; |
| 26 use crate::sliding_fb::{ |
29 use crate::sliding_fb::{ |
| 27 pointsource_sliding_fb_dom, SlidingFBConfig, TransportConfig, TransportProxPenalty, |
30 pointsource_sliding_fb, SlidingFBConfig, TransportConfig, TransportProxPenalty, |
| 28 }; |
31 }; |
| 29 use crate::sliding_pdps::{ |
32 use crate::sliding_pdps::{ |
| 30 pointsource_sliding_fb_pair_dom, pointsource_sliding_pdps_pair_dom, SlidingPDPSConfig, |
33 pointsource_sliding_fb_pair_dom, pointsource_sliding_pdps_pair_dom, SlidingPDPSConfig, |
| 31 }; |
34 }; |
| 32 use crate::subproblem::{InnerMethod, InnerSettings}; |
35 use crate::subproblem::{InnerMethod, InnerSettings}; |
| 125 fitness_merging: cli.fitness_merging.unwrap_or(g.fitness_merging), |
128 fitness_merging: cli.fitness_merging.unwrap_or(g.fitness_merging), |
| 126 inner: override_inner(g.inner), |
129 inner: override_inner(g.inner), |
| 127 extra_weight_optimisation_steps: cli |
130 extra_weight_optimisation_steps: cli |
| 128 .extra_weight_optimisation_steps |
131 .extra_weight_optimisation_steps |
| 129 .unwrap_or(g.extra_weight_optimisation_steps), |
132 .unwrap_or(g.extra_weight_optimisation_steps), |
| |
133 random_insertions: cli.random_insertions.unwrap_or(g.random_insertions), |
| 130 tolerance: cli |
134 tolerance: cli |
| 131 .tolerance |
135 .tolerance |
| 132 .as_ref() |
136 .as_ref() |
| 133 .map(unpack_tolerance) |
137 .map(unpack_tolerance) |
| 134 .unwrap_or(g.tolerance), |
138 .unwrap_or(g.tolerance), |
| 987 /// `cont` gives a continuation attempt to find the algorithm matching the description `alg`. |
991 /// `cont` gives a continuation attempt to find the algorithm matching the description `alg`. |
| 988 pub fn run_fb<F, Dat, Reg, P, I, Plot, const N: usize>( |
992 pub fn run_fb<F, Dat, Reg, P, I, Plot, const N: usize>( |
| 989 f: &Dat, |
993 f: &Dat, |
| 990 reg: &Reg, |
994 reg: &Reg, |
| 991 prox_penalty: &P, |
995 prox_penalty: &P, |
| 992 init: ( |
996 init: (&AlgorithmConfig<F>, I, Plot, Option<RNDM<N, F>>, String), |
| 993 &AlgorithmConfig<F>, |
|
| 994 I, |
|
| 995 Plot, |
|
| 996 Option<RNDM<N, F>>, |
|
| 997 String, |
|
| 998 ), |
|
| 999 cont: impl FnOnce( |
997 cont: impl FnOnce( |
| 1000 (&AlgorithmConfig<F>, I, Plot, Option<RNDM<N, F>>, String), |
998 (&AlgorithmConfig<F>, I, Plot, Option<RNDM<N, F>>, String), |
| 1001 ) -> DynResult<RNDM<N, F>>, |
999 ) -> DynResult<RNDM<N, F>>, |
| 1002 ) -> DynResult<RNDM<N, F>> |
1000 ) -> DynResult<RNDM<N, F>> |
| 1003 where |
1001 where |
| 1009 RNDM<N, F>: SpikeMerging<F>, |
1007 RNDM<N, F>: SpikeMerging<F>, |
| 1010 Reg: SlidingRegTerm<Loc<N, F>, F>, |
1008 Reg: SlidingRegTerm<Loc<N, F>, F>, |
| 1011 P: TransportProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
1009 P: TransportProxPenalty<Loc<N, F>, Dat::DerivativeDomain, Reg, F> + StepLengthBound<F, Dat>, |
| 1012 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, RNDM<N, F>>, |
1010 Plot: Plotter<P::ReturnMapping, Dat::DerivativeDomain, RNDM<N, F>>, |
| 1013 { |
1011 { |
| 1014 run_fb_dom(f, reg, prox_penalty, init, None, cont) |
1012 run_fb_dom(f, reg, prox_penalty, init, &mut FullSpace, cont) |
| 1015 } |
1013 } |
| 1016 |
1014 |
| 1017 /// Runs FB-style algorithms if `alg` so requests and `prox_penalty` matches. |
1015 /// Runs FB-style algorithms if `alg` so requests and `prox_penalty` matches. |
| 1018 /// |
1016 /// |
| 1019 /// `cont` gives a continuation attempt to find the algorithm matching the description `alg`. |
1017 /// `cont` gives a continuation attempt to find the algorithm matching the description `alg`. |
| 1026 I, |
1024 I, |
| 1027 Plot, |
1025 Plot, |
| 1028 Option<RNDM<N, F>>, |
1026 Option<RNDM<N, F>>, |
| 1029 String, |
1027 String, |
| 1030 ), |
1028 ), |
| 1031 domain: Option<&P::Dom>, |
1029 domain: &mut impl AdmissibleDomain<Loc<N, F>>, |
| 1032 cont: impl FnOnce( |
1030 cont: impl FnOnce( |
| 1033 (&AlgorithmConfig<F>, I, Plot, Option<RNDM<N, F>>, String), |
1031 (&AlgorithmConfig<F>, I, Plot, Option<RNDM<N, F>>, String), |
| 1034 ) -> DynResult<RNDM<N, F>>, |
1032 ) -> DynResult<RNDM<N, F>>, |
| 1035 ) -> DynResult<RNDM<N, F>> |
1033 ) -> DynResult<RNDM<N, F>> |
| 1036 where |
1034 where |
| 1047 let pt = P::prox_type(); |
1045 let pt = P::prox_type(); |
| 1048 |
1046 |
| 1049 match alg { |
1047 match alg { |
| 1050 &AlgorithmConfig::FB(ref algconfig, prox_type) if prox_type == pt => { |
1048 &AlgorithmConfig::FB(ref algconfig, prox_type) if prox_type == pt => { |
| 1051 print!("{running}"); |
1049 print!("{running}"); |
| 1052 pointsource_fb_reg(f, reg, prox_penalty, algconfig, iterator, plotter, μ0) |
1050 pointsource_fb_dom( |
| |
1051 f, |
| |
1052 reg, |
| |
1053 prox_penalty, |
| |
1054 algconfig, |
| |
1055 iterator, |
| |
1056 plotter, |
| |
1057 μ0, |
| |
1058 domain, |
| |
1059 ) |
| 1053 } |
1060 } |
| 1054 &AlgorithmConfig::FISTA(ref algconfig, prox_type) if prox_type == pt => { |
1061 &AlgorithmConfig::FISTA(ref algconfig, prox_type) if prox_type == pt => { |
| 1055 print!("{running}"); |
1062 print!("{running}"); |
| 1056 pointsource_fista_reg(f, reg, prox_penalty, algconfig, iterator, plotter, μ0) |
1063 pointsource_fista_reg(f, reg, prox_penalty, algconfig, iterator, plotter, μ0) |
| 1057 } |
1064 } |
| 1058 &AlgorithmConfig::SlidingFB(ref algconfig, prox_type) if prox_type == pt => { |
1065 &AlgorithmConfig::SlidingFB(ref algconfig, prox_type) if prox_type == pt => { |
| 1059 print!("{running}"); |
1066 print!("{running}"); |
| 1060 pointsource_sliding_fb_dom(f, reg, prox_penalty, algconfig, iterator, plotter, μ0, domain) |
1067 pointsource_sliding_fb( |
| |
1068 f, |
| |
1069 reg, |
| |
1070 prox_penalty, |
| |
1071 algconfig, |
| |
1072 iterator, |
| |
1073 plotter, |
| |
1074 μ0, |
| |
1075 domain, |
| |
1076 ) |
| 1061 } |
1077 } |
| 1062 _ => cont((alg, iterator, plotter, μ0, running)), |
1078 _ => cont((alg, iterator, plotter, μ0, running)), |
| 1063 } |
1079 } |
| 1064 } |
1080 } |
| 1065 |
1081 |
| 1292 algorithms, |
1308 algorithms, |
| 1293 make_plotter, |
1309 make_plotter, |
| 1294 save_extra, |
1310 save_extra, |
| 1295 (μ0, z, y), |
1311 (μ0, z, y), |
| 1296 |p| { |
1312 |p| { |
| 1297 run_pdps_pair_dom(&f, ®, &RadonSquared, &opKz, &fnR, &fnH, p, None, |q| { |
1313 run_pdps_pair_dom( |
| 1298 run_pdps_pair_dom(&f, ®, &op𝒟, &opKz, &fnR, &fnH, q, None, |_| { |
1314 &f, |
| 1299 Err(NotImplemented.into()) |
1315 ®, |
| 1300 }) |
1316 &RadonSquared, |
| 1301 }) |
1317 &opKz, |
| |
1318 &fnR, |
| |
1319 &fnH, |
| |
1320 p, |
| |
1321 &mut FullSpace, |
| |
1322 |q| { |
| |
1323 run_pdps_pair_dom( |
| |
1324 &f, |
| |
1325 ®, |
| |
1326 &op𝒟, |
| |
1327 &opKz, |
| |
1328 &fnR, |
| |
1329 &fnH, |
| |
1330 q, |
| |
1331 &mut FullSpace, |
| |
1332 |_| Err(NotImplemented.into()), |
| |
1333 ) |
| |
1334 }, |
| |
1335 ) |
| 1302 .map(|Pair(μ, z)| (μ, z)) |
1336 .map(|Pair(μ, z)| (μ, z)) |
| 1303 }, |
1337 }, |
| 1304 ) |
1338 ) |
| 1305 } |
1339 } |
| 1306 (DataTermType::L222, Regularisation::NonnegRadon(α)) => { |
1340 (DataTermType::L222, Regularisation::NonnegRadon(α)) => { |
| 1312 algorithms, |
1346 algorithms, |
| 1313 make_plotter, |
1347 make_plotter, |
| 1314 save_extra, |
1348 save_extra, |
| 1315 (μ0, z, y), |
1349 (μ0, z, y), |
| 1316 |p| { |
1350 |p| { |
| 1317 run_pdps_pair_dom(&f, ®, &RadonSquared, &opKz, &fnR, &fnH, p, None, |q| { |
1351 run_pdps_pair_dom( |
| 1318 run_pdps_pair_dom(&f, ®, &op𝒟, &opKz, &fnR, &fnH, q, None, |_| { |
1352 &f, |
| 1319 Err(NotImplemented.into()) |
1353 ®, |
| 1320 }) |
1354 &RadonSquared, |
| 1321 }) |
1355 &opKz, |
| |
1356 &fnR, |
| |
1357 &fnH, |
| |
1358 p, |
| |
1359 &mut FullSpace, |
| |
1360 |q| { |
| |
1361 run_pdps_pair_dom( |
| |
1362 &f, |
| |
1363 ®, |
| |
1364 &op𝒟, |
| |
1365 &opKz, |
| |
1366 &fnR, |
| |
1367 &fnH, |
| |
1368 q, |
| |
1369 &mut FullSpace, |
| |
1370 |_| Err(NotImplemented.into()), |
| |
1371 ) |
| |
1372 }, |
| |
1373 ) |
| 1322 .map(|Pair(μ, z)| (μ, z)) |
1374 .map(|Pair(μ, z)| (μ, z)) |
| 1323 }, |
1375 }, |
| 1324 ) |
1376 ) |
| 1325 } |
1377 } |
| 1326 _ => Err(NotImplemented.into()), |
1378 _ => Err(NotImplemented.into()), |
| 1377 R: Prox<Z, Codomain = F>, |
1429 R: Prox<Z, Codomain = F>, |
| 1378 H: Conjugable<Y, F, Codomain = F>, |
1430 H: Conjugable<Y, F, Codomain = F>, |
| 1379 for<'b> H::Conjugate<'b>: Prox<Y>, |
1431 for<'b> H::Conjugate<'b>: Prox<Y>, |
| 1380 Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, |
1432 Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, |
| 1381 { |
1433 { |
| 1382 run_pdps_pair_dom(f, reg, prox_penalty, opKz, fnR, fnH, init, None, cont) |
1434 run_pdps_pair_dom( |
| |
1435 f, |
| |
1436 reg, |
| |
1437 prox_penalty, |
| |
1438 opKz, |
| |
1439 fnR, |
| |
1440 fnH, |
| |
1441 init, |
| |
1442 &mut FullSpace, |
| |
1443 cont, |
| |
1444 ) |
| 1383 } |
1445 } |
| 1384 |
1446 |
| 1385 pub fn run_pdps_pair_dom<F, S, Dat, Reg, Z, R, Y, KOpZ, H, P, I, Plot, const N: usize>( |
1447 pub fn run_pdps_pair_dom<F, S, Dat, Reg, Z, R, Y, KOpZ, H, P, I, Plot, const N: usize>( |
| 1386 f: &Dat, |
1448 f: &Dat, |
| 1387 reg: &Reg, |
1449 reg: &Reg, |
| 1394 I, |
1456 I, |
| 1395 Plot, |
1457 Plot, |
| 1396 (Option<RNDM<N, F>>, Z, Y), |
1458 (Option<RNDM<N, F>>, Z, Y), |
| 1397 String, |
1459 String, |
| 1398 ), |
1460 ), |
| 1399 domain: Option<&P::Dom>, |
1461 domain: &mut impl AdmissibleDomain<Loc<N, F>>, |
| 1400 cont: impl FnOnce( |
1462 cont: impl FnOnce( |
| 1401 ( |
1463 ( |
| 1402 &AlgorithmConfig<F>, |
1464 &AlgorithmConfig<F>, |
| 1403 I, |
1465 I, |
| 1404 Plot, |
1466 Plot, |
| 1434 let pt = P::prox_type(); |
1496 let pt = P::prox_type(); |
| 1435 |
1497 |
| 1436 match alg { |
1498 match alg { |
| 1437 &AlgorithmConfig::ForwardPDPS(ref algconfig, prox_type) if prox_type == pt => { |
1499 &AlgorithmConfig::ForwardPDPS(ref algconfig, prox_type) if prox_type == pt => { |
| 1438 print!("{running}"); |
1500 print!("{running}"); |
| 1439 pointsource_forward_pdps_pair( |
1501 pointsource_forward_pdps_pair_dom( |
| 1440 f, |
1502 f, |
| 1441 reg, |
1503 reg, |
| 1442 prox_penalty, |
1504 prox_penalty, |
| 1443 algconfig, |
1505 algconfig, |
| 1444 iterator, |
1506 iterator, |
| 1445 plotter, |
1507 plotter, |
| 1446 μ0zy, |
1508 μ0zy, |
| 1447 opKz, |
1509 opKz, |
| 1448 fnR, |
1510 fnR, |
| 1449 fnH, |
1511 fnH, |
| |
1512 domain, |
| 1450 ) |
1513 ) |
| 1451 } |
1514 } |
| 1452 &AlgorithmConfig::SlidingPDPS(ref algconfig, prox_type) if prox_type == pt => { |
1515 &AlgorithmConfig::SlidingPDPS(ref algconfig, prox_type) if prox_type == pt => { |
| 1453 print!("{running}"); |
1516 print!("{running}"); |
| 1454 pointsource_sliding_pdps_pair_dom( |
1517 pointsource_sliding_pdps_pair_dom( |
| 1506 R: Prox<Z, Codomain = F>, |
1569 R: Prox<Z, Codomain = F>, |
| 1507 Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, |
1570 Plot: Plotter<P::ReturnMapping, S, RNDM<N, F>>, |
| 1508 // We should not need to explicitly require this: |
1571 // We should not need to explicitly require this: |
| 1509 for<'b> &'b Loc<0, F>: Instance<Loc<0, F>>, |
1572 for<'b> &'b Loc<0, F>: Instance<Loc<0, F>>, |
| 1510 { |
1573 { |
| 1511 run_fb_pair_dom(f, reg, prox_penalty, fnR, init, None, cont) |
1574 run_fb_pair_dom(f, reg, prox_penalty, fnR, init, &mut FullSpace, cont) |
| 1512 } |
1575 } |
| 1513 |
1576 |
| 1514 pub fn run_fb_pair_dom<F, S, Dat, Reg, Z, R, P, I, Plot, const N: usize>( |
1577 pub fn run_fb_pair_dom<F, S, Dat, Reg, Z, R, P, I, Plot, const N: usize>( |
| 1515 f: &Dat, |
1578 f: &Dat, |
| 1516 reg: &Reg, |
1579 reg: &Reg, |
| 1554 let pt = P::prox_type(); |
1617 let pt = P::prox_type(); |
| 1555 |
1618 |
| 1556 match alg { |
1619 match alg { |
| 1557 &AlgorithmConfig::FB(ref algconfig, prox_type) if prox_type == pt => { |
1620 &AlgorithmConfig::FB(ref algconfig, prox_type) if prox_type == pt => { |
| 1558 print!("{running}"); |
1621 print!("{running}"); |
| 1559 pointsource_fb_pair(f, reg, prox_penalty, algconfig, iterator, plotter, μ0z, fnR) |
1622 pointsource_fb_pair_dom( |
| |
1623 f, |
| |
1624 reg, |
| |
1625 prox_penalty, |
| |
1626 algconfig, |
| |
1627 iterator, |
| |
1628 plotter, |
| |
1629 μ0z, |
| |
1630 fnR, |
| |
1631 domain, |
| |
1632 ) |
| 1560 } |
1633 } |
| 1561 &AlgorithmConfig::SlidingFB(ref algconfig, prox_type) if prox_type == pt => { |
1634 &AlgorithmConfig::SlidingFB(ref algconfig, prox_type) if prox_type == pt => { |
| 1562 print!("{running}"); |
1635 print!("{running}"); |
| 1563 pointsource_sliding_fb_pair_dom( |
1636 pointsource_sliding_fb_pair_dom( |
| 1564 f, |
1637 f, |