| 170 | 169 | 
| 171     // Run the algorithm | 170     // Run the algorithm | 
| 172     for state in iterator.iter_init(|| full_stats(&residual, &μ, &z, ε, stats.clone())) { | 171     for state in iterator.iter_init(|| full_stats(&residual, &μ, &z, ε, stats.clone())) { | 
| 173         // Calculate initial transport | 172         // Calculate initial transport | 
| 174         let Pair(mut τv, τz) = opA.preadjoint().apply(residual * τ); | 173         let Pair(mut τv, τz) = opA.preadjoint().apply(residual * τ); | 
| 175         let z_base = z.clone(); |  | 
| 176         let μ_base = μ.clone(); | 174         let μ_base = μ.clone(); | 
| 177 | 175 | 
| 178         // Construct μ^{k+1} by solving finite-dimensional subproblems and insert new spikes. | 176         // Construct μ^{k+1} by solving finite-dimensional subproblems and insert new spikes. | 
| 179         let (maybe_d, _within_tolerances) = prox_penalty.insert_and_reweigh( | 177         let (maybe_d, _within_tolerances) = prox_penalty.insert_and_reweigh( | 
| 180             &mut μ, &mut τv, &μ_base, None, | 178             &mut μ, &mut τv, &μ_base, None, | 
| 181             τ, ε, &config.insertion, | 179             τ, ε, &config.insertion, | 
| 182             ®, &state, &mut stats, | 180             ®, &state, &mut stats, | 
| 183         ); | 181         ); | 
| 184 | 182 | 
| 185         // // Merge spikes. | 183         // Merge spikes. | 
| 186         // // This expects the prune below to prune γ. | 184         // This crucially expects the merge routine to be stable with respect to spike locations, | 
| 187         // // TODO: This may not work correctly in all cases. | 185         // and not to performing any pruning. That is be to done below simultaneously for γ. | 
| 188         // let ins = &config.insertion; | 186         // Merge spikes. | 
| 189         // if ins.merge_now(&state) { | 187         // This crucially expects the merge routine to be stable with respect to spike locations, | 
| 190         //     if let SpikeMergingMethod::None = ins.merging { | 188         // and not to performing any pruning. That is be to done below simultaneously for γ. | 
| 191         //     } else { | 189         let ins = &config.insertion; | 
| 192         //         stats.merged += μ.merge_spikes(ins.merging, |μ_candidate| { | 190         if ins.merge_now(&state) { | 
| 193         //             let ν = μ_candidate.sub_matching(&γ1)-&μ_base_minus_γ0; | 191             stats.merged += prox_penalty.merge_spikes_no_fitness( | 
| 194         //             let mut d = &τv̆ + op𝒟.preapply(ν); | 192                 &mut μ, &mut τv, &μ_base, None, τ, ε, ins, ®, | 
| 195         //             reg.verify_merge_candidate(&mut d, μ_candidate, τ, ε, ins) | 193                 //Some(|μ̃ : &RNDM<F, N>| calculate_residual(Pair(μ̃, &z), opA, b).norm2_squared_div2()), | 
| 196         //         }); | 194             ); | 
| 197         //     } | 195         } | 
| 198         // } |  | 
| 199 | 196 | 
| 200         // Prune spikes with zero weight. | 197         // Prune spikes with zero weight. | 
| 201         stats.pruned += prune_with_stats(&mut μ); | 198         stats.pruned += prune_with_stats(&mut μ); | 
| 202 | 199 | 
| 203         // Do z variable primal update | 200         // Do z variable primal update | 
| 204         z.axpy(-σ_p/τ, τz, 1.0); // TODO: simplify nasty factors | 201         let mut z_new = τz; | 
| 205         opKz.adjoint().gemv(&mut z, -σ_p, &y, 1.0); | 202         opKz.adjoint().gemv(&mut z_new, -σ_p, &y, -σ_p/τ); | 
| 206         z = fnR.prox(σ_p, z); | 203         z_new = fnR.prox(σ_p, z_new + &z); | 
| 207         // Do dual update | 204         // Do dual update | 
| 208         // opKμ.gemv(&mut y, σ_d*(1.0 + ω), &μ, 1.0);    // y = y + σ_d K[(1+ω)(μ,z)^{k+1}] | 205         // opKμ.gemv(&mut y, σ_d*(1.0 + ω), &μ, 1.0);    // y = y + σ_d K[(1+ω)(μ,z)^{k+1}] | 
| 209         opKz.gemv(&mut y, σ_d*(1.0 + ω), &z, 1.0); | 206         opKz.gemv(&mut y, σ_d*(1.0 + ω), &z_new, 1.0); | 
| 210         // opKμ.gemv(&mut y, -σ_d*ω, μ_base, 1.0);// y = y + σ_d K[(1+ω)(μ,z)^{k+1} - ω (μ,z)^k]-b | 207         // opKμ.gemv(&mut y, -σ_d*ω, μ_base, 1.0);// y = y + σ_d K[(1+ω)(μ,z)^{k+1} - ω (μ,z)^k]-b | 
| 211         opKz.gemv(&mut y, -σ_d*ω, z_base, 1.0);// y = y + σ_d K[(1+ω)(μ,z)^{k+1} - ω (μ,z)^k]-b | 208         opKz.gemv(&mut y, -σ_d*ω, z, 1.0);// y = y + σ_d K[(1+ω)(μ,z)^{k+1} - ω (μ,z)^k]-b | 
| 212         y = starH.prox(σ_d, y); | 209         y = starH.prox(σ_d, y); | 
|  | 210         z = z_new; | 
| 213 | 211 | 
| 214         // Update residual | 212         // Update residual | 
| 215         residual = calculate_residual(Pair(&μ, &z), opA, b); | 213         residual = calculate_residual(Pair(&μ, &z), opA, b); | 
| 216 | 214 | 
| 217         // Update step length parameters | 215         // Update step length parameters |