alpaqa 1.0.0a10
Nonconvex constrained optimization
Loading...
Searching...
No Matches
nuclear-norm.hpp
Go to the documentation of this file.
1#pragma once
2
4#include <Eigen/SVD>
5
6namespace alpaqa::functions {
7
8template <Config Conf>
9using DefaultSVD = Eigen::BDCSVD<typename Conf::mat,
10 Eigen::ComputeThinU | Eigen::ComputeThinV>;
11
12/// Nuclear norm (ℓ₁-norm of singular values).
13/// @ingroup grp_Functions
14template <Config Conf, class SVD = DefaultSVD<Conf>>
17
18 /// Construct without pre-allocation.
20 if (λ < 0 || !std::isfinite(λ))
21 throw std::invalid_argument("NuclearNorm::λ must be nonnegative");
22 }
23 /// Construct with pre-allocation.
25 : λ{λ}, svd{rows, cols}, singular_values{svd.singularValues().size()} {
26 if (λ < 0 || !std::isfinite(λ))
27 throw std::invalid_argument("NuclearNorm::λ must be nonnegative");
28 }
29
31 SVD svd;
33
34 real_t prox(crmat in, rmat out, real_t γ = 1) {
35 if (λ == 0) {
36 out = in;
37 return 0;
38 }
39 svd.compute(in);
40 const length_t n = svd.singularValues().size();
41#if 0
43 real_t value = l1.prox(svd.singularValues(), singular_values, γ);
44#else
45 auto step = vec::Constant(n, λ * γ);
46 singular_values = vec::Zero(n).cwiseMax(svd.singularValues() - step);
47 real_t value = λ * γ * singular_values.template lpNorm<1>();
48#endif
49 auto it0 = std::find(singular_values.begin(), singular_values.end(), 0);
50 index_t rank = it0 - singular_values.begin();
51 using Eigen::placeholders::all, Eigen::seqN;
52 auto sel = seqN(0, rank);
53 auto &&U = svd.matrixU(), &&V = svd.matrixV();
54 out.noalias() = U(all, sel) * singular_values(sel).asDiagonal() *
55 V.transpose()(sel, all);
56 return value;
57 }
58
60 crmat in, rmat out, real_t γ) {
61 return self.prox(std::move(in), std::move(out), γ);
62 }
63};
64
65} // namespace alpaqa::functions
#define USING_ALPAQA_CONFIG(Conf)
Definition: config.hpp:54
Eigen::BDCSVD< typename Conf::mat, Eigen::ComputeThinU|Eigen::ComputeThinV > DefaultSVD
std::decay_t< decltype(Tag)> tag_t
Definition: tag-invoke.hpp:74
typename Conf::crmat crmat
Definition: config.hpp:73
typename Conf::rmat rmat
Definition: config.hpp:72
typename Conf::real_t real_t
Definition: config.hpp:63
typename Conf::index_t index_t
Definition: config.hpp:75
typename Conf::length_t length_t
Definition: config.hpp:74
typename Conf::vec vec
Definition: config.hpp:64
real_t prox(crmat in, rmat out, real_t γ=1)
Definition: l1-norm.hpp:45
Nuclear norm (ℓ₁-norm of singular values).
real_t prox(crmat in, rmat out, real_t γ=1)
NuclearNorm(real_t λ=1)
Construct without pre-allocation.
NuclearNorm(real_t λ, length_t rows, length_t cols)
Construct with pre-allocation.
friend real_t alpaqa_tag_invoke(tag_t< alpaqa::prox >, NuclearNorm &self, crmat in, rmat out, real_t γ)