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(); |