| 150 // TODO: maybe this PairNorm doesn't make sense here? |
150 // TODO: maybe this PairNorm doesn't make sense here? |
| 151 // let opAnorm = opA.opnorm_bound(PairNorm(Radon, L2, L2), L2); |
151 // let opAnorm = opA.opnorm_bound(PairNorm(Radon, L2, L2), L2); |
| 152 let bigθ = 0.0; //opKμ.transport_lipschitz_factor(L2Squared); |
152 let bigθ = 0.0; //opKμ.transport_lipschitz_factor(L2Squared); |
| 153 let bigM = 0.0; //opKμ.adjoint_product_bound(&op𝒟).unwrap().sqrt(); |
153 let bigM = 0.0; //opKμ.adjoint_product_bound(&op𝒟).unwrap().sqrt(); |
| 154 let nKz = opKz.opnorm_bound(L2, L2)?; |
154 let nKz = opKz.opnorm_bound(L2, L2)?; |
| |
155 let is_fb = nKz == 0.0; |
| 155 let ℓ = 0.0; |
156 let ℓ = 0.0; |
| 156 let idOpZ = IdOp::new(); |
157 let idOpZ = IdOp::new(); |
| 157 let opKz_adj = opKz.adjoint(); |
158 let opKz_adj = opKz.adjoint(); |
| 158 let (l, l_z) = Pair(prox_penalty, &idOpZ).step_length_bound_pair(&f)?; |
159 let (l, l_z) = Pair(prox_penalty, &idOpZ).step_length_bound_pair(&f)?; |
| 159 |
160 |
| 164 // with 1 > σ_p L_z and 1 > τ L. |
165 // with 1 > σ_p L_z and 1 > τ L. |
| 165 // |
166 // |
| 166 // To do so, we first solve σ_p and σ_d from standard PDPS step length condition |
167 // To do so, we first solve σ_p and σ_d from standard PDPS step length condition |
| 167 // ^^^^^ < 1. then we solve τ from the rest. |
168 // ^^^^^ < 1. then we solve τ from the rest. |
| 168 // If opKZ is the zero operator, then we set σ_d = 0 for τ to be calculated correctly below. |
169 // If opKZ is the zero operator, then we set σ_d = 0 for τ to be calculated correctly below. |
| 169 let σ_d = if nKz == 0.0 { 0.0 } else { config.σd0 / nKz }; |
170 let σ_d = if is_fb { 0.0 } else { config.σd0 / nKz }; |
| 170 let σ_p = config.σp0 / (l_z + config.σd0 * nKz); |
171 let σ_p = config.σp0 / (l_z + config.σd0 * nKz); |
| 171 // Observe that = 1 - ^^^^^^^^^^^^^^^^^^^^^ = 1 - σ_{p,0} |
172 // Observe that = 1 - ^^^^^^^^^^^^^^^^^^^^^ = 1 - σ_{p,0} |
| 172 // We get the condition τσ_d M (1-σ_p L_z) < (1-σ_{p,0})*(1-τ L) |
173 // We get the condition τσ_d M (1-σ_p L_z) < (1-σ_{p,0})*(1-τ L) |
| 173 // ⟺ τ [ σ_d M (1-σ_p L_z) + (1-σ_{p,0}) L ] < (1-σ_{p,0}) |
174 // ⟺ τ [ σ_d M (1-σ_p L_z) + (1-σ_{p,0}) L ] < (1-σ_{p,0}) |
| 174 let φ = 1.0 - config.σp0; |
175 let φ = 1.0 - config.σp0; |
| 291 |
292 |
| 292 // Merge spikes. |
293 // Merge spikes. |
| 293 // This crucially expects the merge routine to be stable with respect to spike locations, |
294 // This crucially expects the merge routine to be stable with respect to spike locations, |
| 294 // and not to performing any pruning. That is be to done below simultaneously for γ. |
295 // and not to performing any pruning. That is be to done below simultaneously for γ. |
| 295 if config.insertion.merge_now(&state) { |
296 if config.insertion.merge_now(&state) { |
| 296 stats.merged += prox_penalty.merge_spikes_no_fitness( |
297 stats.merged += prox_penalty.merge_spikes( |
| 297 &mut μ, |
298 &mut μ, |
| 298 &mut τv̆, |
299 &mut τv̆, |
| 299 &μ̆, |
300 &μ̆, |
| 300 τ, |
301 τ, |
| 301 ε, |
302 ε, |
| 302 &config.insertion, |
303 &config.insertion, |
| 303 ®, |
304 ®, |
| |
305 is_fb.then_some(|μ̃: &RNDM<N, F>| f.apply(Pair(μ̃, &z))), |
| 304 ); |
306 ); |
| 305 } |
307 } |
| 306 |
308 |
| 307 γ.prune_compat(&mut μ, &mut stats); |
309 γ.prune_compat(&mut μ, &mut stats); |
| 308 |
310 |