| 230 // 2-norm, we estimate |
230 // 2-norm, we estimate |
| 231 // ‖A‖_{2,2} := sup_{‖x‖_2 ≤ 1} ‖Ax‖_2 ≤ sup_{‖x‖_1 ≤ C} ‖Ax‖_2 |
231 // ‖A‖_{2,2} := sup_{‖x‖_2 ≤ 1} ‖Ax‖_2 ≤ sup_{‖x‖_1 ≤ C} ‖Ax‖_2 |
| 232 // = C sup_{‖x‖_1 ≤ 1} ‖Ax‖_2 = C ‖A‖_{1,2}, |
232 // = C sup_{‖x‖_1 ≤ 1} ‖Ax‖_2 = C ‖A‖_{1,2}, |
| 233 // where C = √m satisfies ‖x‖_1 ≤ C ‖x‖_2. Since we are intested in ‖A_*A‖, no |
233 // where C = √m satisfies ‖x‖_1 ≤ C ‖x‖_2. Since we are intested in ‖A_*A‖, no |
| 234 // square root is needed when we scale: |
234 // square root is needed when we scale: |
| 235 let inner_τ = inner.τ0 / (findim_data.opAnorm_squared * F::cast_from(μ.len())); |
235 let normest = findim_data.opAnorm_squared * F::cast_from(μ.len()); |
| 236 let iters = quadratic_unconstrained(inner.method, &Ã, &g̃, self.α(), |
236 let iters = quadratic_unconstrained(&Ã, &g̃, self.α(), &mut x, |
| 237 &mut x, inner_τ, iterator); |
237 normest, inner, iterator); |
| 238 // Update masses of μ based on solution of finite-dimensional subproblem. |
238 // Update masses of μ based on solution of finite-dimensional subproblem. |
| 239 μ.set_masses_dvector(&x); |
239 μ.set_masses_dvector(&x); |
| 240 |
240 |
| 241 iters |
241 iters |
| 242 } |
242 } |
| 327 // 2-norm, we estimate |
327 // 2-norm, we estimate |
| 328 // ‖A‖_{2,2} := sup_{‖x‖_2 ≤ 1} ‖Ax‖_2 ≤ sup_{‖x‖_1 ≤ C} ‖Ax‖_2 |
328 // ‖A‖_{2,2} := sup_{‖x‖_2 ≤ 1} ‖Ax‖_2 ≤ sup_{‖x‖_1 ≤ C} ‖Ax‖_2 |
| 329 // = C sup_{‖x‖_1 ≤ 1} ‖Ax‖_2 = C ‖A‖_{1,2}, |
329 // = C sup_{‖x‖_1 ≤ 1} ‖Ax‖_2 = C ‖A‖_{1,2}, |
| 330 // where C = √m satisfies ‖x‖_1 ≤ C ‖x‖_2. Since we are intested in ‖A_*A‖, no |
330 // where C = √m satisfies ‖x‖_1 ≤ C ‖x‖_2. Since we are intested in ‖A_*A‖, no |
| 331 // square root is needed when we scale: |
331 // square root is needed when we scale: |
| 332 let inner_τ = inner.τ0 / (findim_data.opAnorm_squared * F::cast_from(μ.len())); |
332 let normest = findim_data.opAnorm_squared * F::cast_from(μ.len()); |
| 333 let iters = quadratic_nonneg(inner.method, &Ã, &g̃, self.α(), |
333 let iters = quadratic_nonneg(&Ã, &g̃, self.α(), &mut x, |
| 334 &mut x, inner_τ, iterator); |
334 normest, inner, iterator); |
| 335 // Update masses of μ based on solution of finite-dimensional subproblem. |
335 // Update masses of μ based on solution of finite-dimensional subproblem. |
| 336 μ.set_masses_dvector(&x); |
336 μ.set_masses_dvector(&x); |
| 337 |
337 |
| 338 iters |
338 iters |
| 339 } |
339 } |
| 478 }; |
478 }; |
| 479 |
479 |
| 480 inner_iters += reg.optimise_weights(&mut μ, opA, b, &findim_data, &config.inner, inner_it); |
480 inner_iters += reg.optimise_weights(&mut μ, opA, b, &findim_data, &config.inner, inner_it); |
| 481 |
481 |
| 482 // Merge spikes and update residual for next step and `if_verbose` below. |
482 // Merge spikes and update residual for next step and `if_verbose` below. |
| 483 let n_before_merge = μ.len(); |
483 let (r, count) = μ.merge_spikes_fitness(config.merging, |
| 484 residual = μ.merge_spikes_fitness(config.merging, |
484 |μ̃| opA.apply(μ̃) - b, |
| 485 |μ̃| opA.apply(μ̃) - b, |
485 A::Observable::norm2_squared); |
| 486 A::Observable::norm2_squared); |
486 residual = r; |
| 487 assert!(μ.len() >= n_before_merge); |
487 merged += count; |
| 488 merged += μ.len() - n_before_merge; |
|
| 489 |
488 |
| 490 |
489 |
| 491 // Prune points with zero mass |
490 // Prune points with zero mass |
| 492 let n_before_prune = μ.len(); |
491 let n_before_prune = μ.len(); |
| 493 μ.prune(); |
492 μ.prune(); |