Normalizer.h
Go to the documentation of this file.
1/*!
2 *
3 *
4 * \brief Model for scaling and translation of data vectors.
5 *
6 *
7 *
8 * \author T. Glasmachers
9 * \date 2013
10 *
11 *
12 * \par Copyright 1995-2017 Shark Development Team
13 *
14 * <BR><HR>
15 * This file is part of Shark.
16 * <https://shark-ml.github.io/Shark/>
17 *
18 * Shark is free software: you can redistribute it and/or modify
19 * it under the terms of the GNU Lesser General Public License as published
20 * by the Free Software Foundation, either version 3 of the License, or
21 * (at your option) any later version.
22 *
23 * Shark is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public License
29 * along with Shark. If not, see <http://www.gnu.org/licenses/>.
30 *
31 */
32#ifndef SHARK_MODELS_NORMALIZER_H
33#define SHARK_MODELS_NORMALIZER_H
34
36#include <shark/LinAlg/Base.h>
37
38
39namespace shark {
40
41
42///
43/// \brief "Diagonal" linear model for data normalization.
44///
45/// \par
46/// The Normalizer is a restricted and often more efficient variant of
47/// the LinearModel class. It restricts the linear model in two respects:
48/// (1) input and output dimension must agree,
49/// (2) computations are independent for each component.
50/// This is useful mostly for data normalization (therefore the name).
51/// The model's operation is of the form \f$ x \mapsto A x + b \f$ where
52/// A is a diagonal matrix. This reduces memory requirements to linear,
53/// which is why there is no sparse version of this model (as opposed to
54/// the more general linear model). Also, the addition of b is optional.
55///
56///
57/// \ingroup models
58template <class VectorType = RealVector>
59class Normalizer : public AbstractModel<VectorType, VectorType>
60{
61public:
64
67
68 /// \brief Construction from dimension
69 Normalizer(std::size_t dimension = 0, bool hasOffset = false)
70 { setStructure(dimension,hasOffset);}
71
72 /// \brief Construction from matrix and and optional offset vector
75
76
77 /// \brief From INameable: return the class name.
78 std::string name() const
79 { return "Normalizer"; }
80
81 /// \brief derivative storage object (empty for this model)
82 boost::shared_ptr<State> createState() const{
83 return boost::shared_ptr<State>(new EmptyState());
84 }
85
86 /// \brief check for the presence of an offset term
87 bool hasOffset() const{
88 return !m_b.empty();
89 }
90
91 /// \brief obtain the input dimension
93 return m_A.size();
94 }
95
96 /// \brief obtain the output dimension
98 return m_A.size();
99 }
100
101 /// \brief return the diagonal of the matrix
102 VectorType const& diagonal() const{
103 return m_A;
104 }
105
106 /// \brief return the offset vector
107 VectorType const& offset() const{
108 return m_b;
109 }
110
111 /// \brief obtain the parameter vector
113 return m_A | m_b;
114 }
115
116 /// \brief overwrite the parameter vector
117 void setParameterVector(VectorType const& newParameters){
118 SIZE_CHECK(newParameters.size() == numberOfParameters());
119 std::size_t dim = m_A.size();
120 noalias(m_A) = subrange(newParameters,0,dim);
121 noalias(m_b) = subrange(newParameters, dim, newParameters.size());
122 }
123
124 /// \brief return the number of parameter
125 std::size_t numberOfParameters() const{
126 return m_A.size() + m_b.size();
127 }
128
129 /// \brief overwrite structure and parameters
131 m_A = diagonal;
132 m_b = offset;
133 }
134
135 /// \brief overwrite structure and parameters
136 void setStructure(std::size_t dimension, bool hasOffset = false){
137 m_A.resize(dimension);
138 m_b.resize(hasOffset? dimension : 0);
139 }
140
141 using base_type::eval;
142
143 /// \brief Evaluate the model: output = matrix * input + offset.
144 void eval(BatchInputType const& input, BatchOutputType& output) const{
145 SIZE_CHECK(input.size2() == m_A.size());
146 output.resize(input.size1(), input.size2());
147 noalias(output) = input * repeat(m_A,input.size1());
148 if (hasOffset()){
149 noalias(output) += repeat(m_b,input.size1());
150 }
151 }
152
153 /// \brief Evaluate the model: output = matrix * input + offset.
154 void eval(BatchInputType const& input, BatchOutputType& output, State& state) const{
155 eval(input, output);
156 }
157
158 /// from ISerializable
159 void read(InArchive& archive){
160 archive & m_A;
161 archive & m_b;
162 }
163
164 /// from ISerializable
165 void write(OutArchive& archive) const{
166 archive & m_A;
167 archive & m_b;
168 }
169
170protected:
171 VectorType m_A; ///< matrix A (see class documentation)
172 VectorType m_b; ///< vector b (see class documentation)
173};
174
175
176}
177#endif