1 #ifndef SCREENINGSOLVER_HPP 2 #define SCREENINGSOLVER_HPP 9 #include <eigen3/Eigen/Dense> 10 #include <eigen3/Eigen/Core> 18 #include "../Generic/generics.hpp" 19 #include "../Generic/debug.hpp" 20 #include "../Screening/screening_rules.hpp" 21 #include "abstractsolver.hpp" 27 template <
typename T >
39 virtual Eigen::Matrix< T, Eigen::Dynamic, 1 >
operator()(
40 const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
41 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
42 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta_0,
44 unsigned int num_iterations );
46 virtual Eigen::Matrix< T, Eigen::Dynamic, 1 >
operator()(
47 const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
48 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
49 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta_0,
51 T duality_gap_target );
55 virtual Eigen::Matrix< T, Eigen::Dynamic, 1 > update_rule(
56 const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
57 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
58 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta_0,
63 template <
typename T >
68 template <
typename T >
72 template <
typename T >
74 const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
75 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
76 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta_0,
78 T duality_gap_target ) {
80 const T lambda_half = lambda / 2.0;
82 Eigen::Matrix< T, Eigen::Dynamic, 1 > Beta = Beta_0;
84 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > X_A = X;
85 Eigen::Matrix< T, Eigen::Dynamic, 1 > Beta_A = Beta;
87 std::vector< unsigned int > active_set, inactive_set;
90 std::vector< unsigned int > universe ( X.cols() );
91 std::iota ( std::begin(universe), std::end(universe) , 0 );
93 T duality_gap_2 =
static_cast<T
>( 0 );
95 bool optim_continue =
true;
96 unsigned int counter = 0;
98 while( optim_continue ) {
100 Eigen::Matrix< T, Eigen::Dynamic, 1 > nu = DualPoint( X_A, Y, Beta_A, lambda_half );
101 duality_gap_2 = DualityGap2( X_A, Y, Beta_A, nu, lambda_half );
103 if( duality_gap_2 <= duality_gap_target ) {
104 optim_continue =
false;
107 if( counter % 10 == 0 ) {
109 T radius = std::sqrt( 2.0 * duality_gap_2 /
square( lambda ) );
110 active_set = SafeActiveSet( X, nu, radius );
112 X_A = slice( X, active_set );
113 Beta_A = slice( Beta, active_set );
115 std::set_difference( universe.begin(),
119 std::inserter(inactive_set, inactive_set.begin()) );
122 Beta_A = update_rule( X_A, Y, Beta_A, lambda );
124 for(
unsigned int x = 0; x < active_set.size() ; x++ ) {
126 unsigned int active_index = active_set[ x ];
127 Beta( active_index ) = Beta_A[ x ];
131 for(
const auto& inactive_index : inactive_set ) {
132 Beta( inactive_index ) = 0.0;
145 template <
typename T >
147 const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
148 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
149 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta_0,
151 unsigned int num_iterations ) {
153 const T lambda_half = lambda / 2.0;
155 Eigen::Matrix< T, Eigen::Dynamic, 1 > Beta = Beta_0;
157 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > X_A = X;
158 Eigen::Matrix< T, Eigen::Dynamic, 1 > Beta_A = Beta;
161 std::vector< unsigned int > active_set, inactive_set;
164 std::vector< unsigned int > universe ( X.cols() );
165 std::iota ( std::begin(universe), std::end(universe) , 0 );
167 T duality_gap_2 =
static_cast<T
>( 0 );
169 for(
unsigned int i = 0; i < num_iterations ; i++ ) {
171 Eigen::Matrix< T, Eigen::Dynamic, 1 > nu = DualPoint( X_A, Y, Beta_A, lambda_half );
172 duality_gap_2 = DualityGap2( X_A, Y, Beta_A, nu, lambda_half );
176 T radius = std::sqrt( 2.0 * duality_gap_2 /
square( lambda ) );
177 active_set = SafeActiveSet( X, nu, radius );
179 X_A = slice( X, active_set );
180 Beta_A = slice( Beta, active_set );
182 std::set_difference( universe.begin(),
186 std::inserter(inactive_set, inactive_set.begin()) );
189 Beta_A = update_rule( X_A, Y, Beta_A, lambda );
191 for(
unsigned int x = 0; x < active_set.size() ; x++ ) {
193 unsigned int active_index = active_set[ x ];
194 Beta( active_index ) = Beta_A[ x ];
198 for(
const auto& inactive_index : inactive_set ) {
199 Beta( inactive_index ) = 0.0;
214 #endif // SCREENINGSOLVER_HPP
virtual Eigen::Matrix< T, Eigen::Dynamic, 1 > operator()(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &X, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &Y, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &Beta_0, T lambda, unsigned int num_iterations)
Run the AbstractSolver for a fixed number of steps, specified by num_iterations.
#define DEBUG_PRINT(x,...)
T square(T &val)
Compute the square of a value.
Abstract base class for all iterative solvers.
Abstract base class for Solvers that use GAP SAFE screening rules.