HDIM  1.0.0
Packages for High Dimensional Linear Regression
subgradient_descent.hpp
1 #ifndef SUBGRADIENT_DESCENT_H
2 #define SUBGRADIENT_DESCENT_H
3 
4 // C System-Headers
5 //
6 // C++ System headers
7 //
8 // Eigen Headers
9 #include <eigen3/Eigen/Dense>
10 #include <eigen3/Eigen/Core>
11 // Boost Headers
12 //
13 // SPAMS Headers
14 //
15 // OpenMP Headers
16 //
17 // Project Specific Headers
18 #include "../../Generic/generics.hpp"
19 #include "../../Generic/debug.hpp"
20 #include "../solver.hpp"
21 #include "../screeningsolver.hpp"
22 
23 namespace hdim {
24 
25 //template< typename T >
26 //using MatrixT = Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >;
27 
28 //template< typename T >
29 //using VectorT = Eigen::Matrix< T, Eigen::Dynamic, 1 >;
30 
31 namespace internal {
32 
33 template < typename T, typename Base = internal::Solver<T> >
34 
39 class SubGradientSolver : public Base {
40 
41  public:
42  SubGradientSolver( T L = 0.1 );
44 
45  protected:
46 
47  T f_beta (
48  const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
49  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
50  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta );
51 
52  T f_beta_tilda (
53  const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
54  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
55  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta,
56  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta_prime,
57  T L );
58 
59  Eigen::Matrix< T, Eigen::Dynamic, 1 > update_beta_ista (
60  const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
61  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
62  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta,
63  T L,
64  T thres );
65 
66  const T L_0;
67 
68 };
69 
70 template < typename T, typename Base >
72  static_assert(std::is_floating_point< T >::value,\
73  "Subgradient descent methods can only be used with floating point types.");
74 }
75 
76 template < typename T, typename Base >
78 
79 template < typename T, typename Base >
81  const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
82  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
83  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta ) {
84 
85  return (X*Beta - Y).squaredNorm();
86 
87 }
88 
89 template < typename T, typename Base >
91  const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
92  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
93  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta,
94  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta_prime,
95  T L ) {
96 
97  Eigen::Matrix< T, Eigen::Dynamic, 1 > f_beta = X*Beta_prime - Y;
98  T taylor_term_0 = f_beta.squaredNorm();
99 
100  Eigen::Matrix< T, Eigen::Dynamic, 1 > f_grad = 2.0*X.transpose()*( f_beta );
101  Eigen::Matrix< T, Eigen::Dynamic, 1 > beta_diff = ( Beta - Beta_prime );
102 
103  T taylor_term_1 = f_grad.transpose()*beta_diff;
104 
105  T taylor_term_2 = L/2.0*beta_diff.squaredNorm();
106 
107  return taylor_term_0 + taylor_term_1 + taylor_term_2;
108 }
109 
110 template < typename T, typename Base >
111 Eigen::Matrix< T, Eigen::Dynamic, 1 > SubGradientSolver< T, Base >::update_beta_ista (
112  const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X,
113  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y,
114  const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta,
115  T L,
116  T thres ) {
117 
118  Eigen::Matrix< T, Eigen::Dynamic, 1 > f_grad = 2.0*( X.transpose()*( X*Beta - Y ) );
119  Eigen::Matrix< T, Eigen::Dynamic, 1 > beta_to_modify = Beta - (1.0/L)*f_grad;
120 
121  return beta_to_modify.unaryExpr( SoftThres<T>( thres/L ) );
122 
123 }
124 
125 }
126 
127 }
128 
129 #endif // SUBGRADIENT_DESCENT_H
Definition: fos.hpp:18
Abstract base class for Sub-Gradient Descent algorithms ,such as ISTA and FISTA, with backtracking li...
Soft Threshold functor used to apply hdim::soft_threshold to each element in a matrix or vector...
Definition: generics.hpp:288