18 #include <eigen3/Eigen/Dense> 30 template <
typename T >
31 T StdDev(
const Eigen::Matrix< T, Eigen::Dynamic, 1 >& vect ) {
32 if( vect.size() == 0 ) {
33 return static_cast<T
>( 0 );
37 T n =
static_cast<T
>(0.0);
38 T sum =
static_cast<T
>(0.0);
39 T sum_sqr =
static_cast<T
>(0.0);
40 T variance =
static_cast<T
>(0.0);
42 for(
unsigned int i = 0; i < vect.size() ; i ++ ) {
44 n = n +
static_cast<T
>(1.0);
49 sum_sqr += ( x - K ) * ( x - K );
50 variance = ( sum_sqr - (sum*sum)/n)/( n -
static_cast<T
>(1.0) );
54 return std::sqrt( variance );
57 template <
typename T >
67 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
Normalize(
68 const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& mat ) {
70 auto mean = mat.colwise().mean();
71 auto std = ((mat.rowwise() - mean).array().square().colwise().sum() / (mat.rows() - 1)).sqrt();
73 return (mat.rowwise() - mean).array().rowwise() / std.array();
76 template<
typename T >
77 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
Normalize(
78 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& mat ) {
80 auto mean = mat.colwise().mean();
81 auto std = ((mat.rowwise() - mean).array().square().colwise().sum() / (mat.rows() - 1)).sqrt();
83 return (mat.rowwise() - mean).array().rowwise() / std.array();
86 template <
typename T >
92 const Eigen::Matrix<T, Eigen::Dynamic, 1 >& mat ) {
94 auto mean = mat.colwise().mean();
95 auto std = ((mat.rowwise() - mean).array().square().colwise().sum() / (mat.rows() - 1)).sqrt();
97 return (mat.rowwise() - mean).array().rowwise() / std.array();
100 template <
typename T >
106 Eigen::Matrix<T, Eigen::Dynamic, 1 >& mat ) {
108 auto mean = mat.colwise().mean();
109 auto std = ((mat.rowwise() - mean).array().square().colwise().sum() / (mat.rows() - 1)).sqrt();
111 return (mat.rowwise() - mean).array().rowwise() / std.array();
114 template<
typename T >
131 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
build_matrix(
unsigned int num_rows,
unsigned int num_cols, T (*mat_func)(
unsigned int,
unsigned int) ) {
133 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> mat( num_rows, num_cols );
135 for(
unsigned int i = 0; i < num_rows ; i ++ ) {
137 for(
unsigned int j = 0; j < num_cols ; j++ ) {
138 mat( i, j ) = (*mat_func)( i, j );
145 template<
typename T >
150 void sweep_matrix( Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>& mat, T (*mat_func)(
unsigned int,
unsigned int) ) {
152 for(
unsigned int i = 0; i < mat.rows() ; i ++ ) {
154 for(
unsigned int j = 0; j < mat.cols() ; j++ ) {
155 mat( i, j ) = (*mat_func)( i, j );
160 template <
typename T>
173 template <
typename T >
198 std::vector < T >
LogScaleVector( T lower_bound, T upper_bound,
unsigned int num_elements ) {
200 T min_elem =
static_cast<T
>( log10(lower_bound) );
201 T max_elem =
static_cast<T
>( log10(upper_bound) );
202 T delta = max_elem - min_elem;
204 std::vector < T > log_space_vector;
205 log_space_vector.reserve( num_elements );
207 for (
unsigned int i = 0; i < num_elements ; i ++ ) {
209 T step =
static_cast<T
>( i )/static_cast<T>( num_elements - 1 );
210 auto lin_step = delta*step + min_elem;
212 log_space_vector.push_back( static_cast<T>( std::pow( 10.0, lin_step ) ) );
215 return log_space_vector;
218 template <
typename T >
226 typedef T result_type;
227 T operator()( T x )
const {
228 return static_cast<T
>( x ==
static_cast<T
>( 0 ) );
233 template <
typename T>
247 return static_cast<T
>( T(0) < val ) - ( val < T(0) );
250 template <
typename T >
263 return std::max( x, static_cast<T>(0.0) );
266 template <
typename T >
277 T sgn_T =
static_cast<T
>(
sgn(x) );
278 return sgn_T*
pos_part( std::abs(x) - y );
281 template <
typename T >
302 typedef T result_type;
303 T operator()( T x )
const {
304 return soft_threshold<T>( x, lambda );
311 template <
typename T >
315 inline T
prox( T x, T lambda ) {
316 return ( std::abs(x) >= lambda )?( x -
sgn( x )*lambda ):( 0 );
319 template <
typename T >
320 Eigen::Matrix< T, Eigen::Dynamic, 1 > soft_threshold_mat(
321 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& mat,
324 Eigen::Matrix<T, Eigen::Dynamic, 1 > mat_x( mat.rows() );
327 for(
unsigned int i = 0; i < mat.rows() ; i ++ ) {
328 mat_x( i ) =
prox( mat( i ), lambda );
334 template <
typename T >
337 SupportSift( T C, T r_tilde, T n ) : cut_off( std::abs( static_cast<T>( 6 )*C*r_tilde/n ) ) {}
339 typedef T result_type;
340 T operator()( T x )
const {
341 return ( std::abs(x) >= cut_off )?(
static_cast<T
>( 1 ) ):(
static_cast<T
>( 0 ) );
348 template<
typename T >
349 Eigen::Matrix< int, Eigen::Dynamic, 1 > GenerateSupport(
350 const Eigen::Matrix<T, Eigen::Dynamic, 1 >& coefficients,
353 Eigen::Matrix< int, Eigen::Dynamic, 1 > support( coefficients.rows() );
355 for(
unsigned int i = 0; i < coefficients.size() ; i ++ ) {
356 T x = coefficients( i );
357 support( i ) = ( std::abs( x ) >= cut_off );
363 template <
typename T >
364 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > negative_index(
365 const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& mat_in,
368 unsigned int n = mat_in.rows();
369 unsigned int p = mat_in.cols();
387 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > left_half = mat_in.block( 0, 0, n, index - 1 );
388 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > right_half = mat_in.block( 0, index + 1, n, p );
390 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > out ( n, p - 1 );
391 out << left_half, right_half;
396 template <
typename T >
397 T duality_gap (
const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& X, \
398 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Y, \
399 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& Beta, \
404 Eigen::Matrix< T, Eigen::Dynamic, 1 > error = X*Beta - Y;
405 T error_sqr_norm = error.squaredNorm();
407 T f_beta = error_sqr_norm + r_stats_it*Beta.template lpNorm < 1 >();
413 T alternative = r_stats_it /( ( 2.0*X.transpose()*error ).
template lpNorm< Eigen::Infinity >() );
414 T alt_part_1 =
static_cast<T
>( Y.transpose()*error );
415 T alternative_0 = alt_part_1/( error_sqr_norm );
417 T s = std::min( std::max( alternative, alternative_0 ), -alternative );
419 Eigen::Matrix< T, Eigen::Dynamic, 1 > nu_part = ( - 2.0*s / r_stats_it ) * error + 2.0/r_stats_it*Y;
421 T d_nu = 0.25*
square( r_stats_it )*nu_part.squaredNorm() - Y.squaredNorm();
423 return f_beta + d_nu;
426 template <
typename T >
427 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > slice (
428 const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic >& org,
429 const std::vector< unsigned int >& indices ) {
431 Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > sliced ( org.rows(), indices.size() );
433 for(
unsigned int j = 0 ; j < indices.size() ; j++ ) {
434 sliced.col( j ) = org.col( indices[ j ] );
441 template <
typename T >
442 Eigen::Matrix< T, Eigen::Dynamic, 1 > slice (
443 const Eigen::Matrix< T, Eigen::Dynamic, 1 >& org,
444 const std::vector< unsigned int >& indices ) {
446 Eigen::Matrix< T, Eigen::Dynamic, 1 > sliced ( indices.size() );
448 for(
unsigned int j = 0 ; j < indices.size() ; j++ ) {
449 sliced[ j ] = org[ indices[ j ] ];
458 #endif // FOS_GENERICS_H
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > Normalize(const Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &mat)
Set the mean of a matrix to 0 and the standard deviation to 1.
T prox(T x, T lambda)
A functional equivalent of hdim::soft_threshold, but possibly faster.
std::vector< T > LogScaleVector(T lower_bound, T upper_bound, unsigned int num_elements)
Generate a vector of logarithmically equally spaced points.
T sgn(T val)
The sign function defined as.
Functor to convert vector of values into support vector.
SoftThres(T lambda_in)
Initialize proximal operator, note that the term lambda_in takes the place of 'y' in the definition o...
Soft Threshold functor used to apply hdim::soft_threshold to each element in a matrix or vector...
void sweep_matrix(Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > &mat, T(*mat_func)(unsigned int, unsigned int))
sweep_matrix
T square(T &val)
Compute the square of a value.
T soft_threshold(T x, T y)
The proximal ( soft thresholding ) operator defined as.
T pos_part(T x)
The positive part function defined as.
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > build_matrix(unsigned int num_rows, unsigned int num_cols, T(*mat_func)(unsigned int, unsigned int))
Generate a matrix using a function that depends on row and column indices.