Regularizer.h
Go to the documentation of this file.
1 //===========================================================================
2 /*!
3  *
4  *
5  * \brief Regularizer
6  *
7  *
8  *
9  * \author T. Glasmachers
10  * \date 2010-2011
11  *
12  *
13  * \par Copyright 1995-2017 Shark Development Team
14  *
15  * <BR><HR>
16  * This file is part of Shark.
17  * <http://shark-ml.org/>
18  *
19  * Shark is free software: you can redistribute it and/or modify
20  * it under the terms of the GNU Lesser General Public License as published
21  * by the Free Software Foundation, either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * Shark is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU Lesser General Public License for more details.
28  *
29  * You should have received a copy of the GNU Lesser General Public License
30  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
33 //===========================================================================
34 #ifndef SHARK_OBJECTIVEFUNCTIONS_REGULARIZER_H
35 #define SHARK_OBJECTIVEFUNCTIONS_REGULARIZER_H
36 
37 
39 
40 namespace shark {
41 
42 
43 ///
44 /// \brief One-norm of the input as an objective function
45 ///
46 /// \par
47 /// The OneNormRegularizer is intended to be used together with other
48 /// objective functions within a CombinedObjectiveFunction, in order to
49 /// obtain a more smooth and more sparse solution.
50 ///
52 {
53 public:
54 
55  /// Constructor
56  OneNormRegularizer(std::size_t numVariables = 0):m_numberOfVariables(numVariables)
57  {
60  }
61 
62  /// \brief From INameable: return the class name.
63  std::string name() const
64  { return "OneNormRegularizer"; }
65 
66  std::size_t numberOfVariables()const{
67  return m_numberOfVariables;
68  }
69 
71  return true;
72  }
73 
75  m_numberOfVariables = numberOfVariables;
76  }
77 
78  void setMask(const RealVector& mask){
79  m_mask = mask;
80  }
81  const RealVector& mask()const{
82  return m_mask;
83  }
84  /// Evaluates the objective function.
85  double eval( RealVector const& input ) const{
86  if(m_mask.empty()){
87  return norm_1(input);
88  }
89  else
90  {
91  return norm_1(input * m_mask);
92  }
93  }
94 
95  /// Evaluates the objective function
96  /// and calculates its gradient.
97  double evalDerivative( RealVector const& input, FirstOrderDerivative & derivative ) const {
98  std::size_t ic = input.size();
99  derivative.resize(ic);
100  if(m_mask.empty()){
101  for (std::size_t i = 0; i != ic; i++){
102  derivative(i) = boost::math::sign(input(i));
103  }
104  }
105  else
106  {
107  SIZE_CHECK(m_mask.size() == input.size());
108  for (std::size_t i=0; i != ic; i++){
109  derivative(i) = m_mask(i)*boost::math::sign(input(i));
110  }
111  }
112  return eval(input);
113  }
114  double evalDerivative( RealVector const& input, SecondOrderDerivative & derivative ) const {
115  std::size_t ic = input.size();
116  derivative.gradient.resize(ic);
117  derivative.hessian.resize(ic,ic);
118  derivative.hessian.clear();
119  if(m_mask.empty()){
120  for (std::size_t i=0; i != ic; i++){
121  derivative.gradient(i) = boost::math::sign(input(i));
122  }
123  }
124  else
125  {
126  SIZE_CHECK(m_mask.size() == input.size());
127  for (std::size_t i=0; i != ic; i++){
128  derivative.gradient(i) = m_mask(i)*boost::math::sign(input(i));
129  }
130  }
131  return eval(input);
132  }
133 private:
134  RealVector m_mask;
135  std::size_t m_numberOfVariables;
136 };
137 
138 
139 ///
140 /// \brief Two-norm of the input as an objective function
141 ///
142 /// \par
143 /// The TwoNormRegularizer is intended to be used together with other
144 /// objective functions within a CombinedObjectiveFunction, in order to
145 /// obtain a more smooth solution.
146 ///
147 class TwoNormRegularizer : public AbstractObjectiveFunction<RealVector, double>
148 {
149 public:
150  typedef RealVector SearchPointType;
151  typedef double ResultType;
152 
154 
155  /// Constructor
156  TwoNormRegularizer(std::size_t numVariables = 0):m_numberOfVariables(numVariables)
157  {
160  }
161 
162  /// \brief From INameable: return the class name.
163  std::string name() const
164  { return "TwoNormRegularizer"; }
165 
166  std::size_t numberOfVariables()const{
167  return m_numberOfVariables;
168  }
169 
171  return true;
172  }
173 
175  m_numberOfVariables = numberOfVariables;
176  }
177 
178  void setMask(const RealVector& mask){
179  m_mask = mask;
180  }
181  const RealVector& mask()const{
182  return m_mask;
183  }
184 
185  /// Evaluates the objective function.
186  virtual double eval( RealVector const& input ) const
187  {
188  if(m_mask.empty()){
189  return 0.5*norm_sqr(input);
190  }
191  else{
192  return 0.5 * sum(m_mask*sqr(input));
193  }
194  }
195 
196  /// Evaluates the objective function
197  /// and calculates its gradient.
198  virtual double evalDerivative( RealVector const& input, FirstOrderDerivative & derivative ) const {
199  if(m_mask.empty()){
200  derivative = input;
201  }
202  else{
203  derivative = m_mask*input;
204  }
205  return eval(input);
206  }
207 
208  /// Evaluates the objective function
209  /// and calculates its gradient and
210  /// its Hessian.
211  virtual ResultType evalDerivative( const SearchPointType & input, SecondOrderDerivative & derivative )const {
212  derivative.gradient = input;
213  derivative.hessian = blas::identity_matrix<double>(input.size());
214  return 0.5 * norm_sqr(input);
215  }
216 private:
217  std::size_t m_numberOfVariables;
218  RealVector m_mask;
219 };
220 
221 
222 }
223 #endif // SHARK_CORE_REGULARIZER_H