MonomialKernel.h
Go to the documentation of this file.
1//===========================================================================
2/*!
3 *
4 *
5 * \brief monomial (polynomial) kernel
6 *
7 *
8 *
9 * \author T.Glasmachers, O. Krause, M. Tuma
10 * \date 2012
11 *
12 *
13 * \par Copyright 1995-2017 Shark Development Team
14 *
15 * <BR><HR>
16 * This file is part of Shark.
17 * <https://shark-ml.github.io/Shark/>
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
35#ifndef SHARK_MODELS_KERNELS_MONOMIAL_KERNEL_H
36#define SHARK_MODELS_KERNELS_MONOMIAL_KERNEL_H
37
38
40namespace shark {
41
42
43/// \brief Monomial kernel. Calculates \f$ \left\langle x_1, x_2 \right\rangle^m_exponent \f$
44///
45/// \par
46/// The degree \f$ m_exponent \f$ is a non-trainable but configurable parameter.
47/// The default value is one - exactly the same as a LinearKernel.
48/// \ingroup kernels
49template<class InputType=RealVector>
50class MonomialKernel : public AbstractKernelFunction<InputType>
51{
52private:
54
55 struct InternalState: public State{
56 RealMatrix base;//stores the inner product of vectors x_1,x_j which is the base the late rused pow
57 RealMatrix exponentedProd;//pow(base,m_exponent)
58
59 void resize(std::size_t sizeX1, std::size_t sizeX2){
60 base.resize(sizeX1, sizeX2);
61 exponentedProd.resize(sizeX1, sizeX2);
62 }
63 };
64
65public:
79
80 /// \brief From INameable: return the class name.
81 std::string name() const
82 { return "MonomialKernel"; }
83
84 RealVector parameterVector() const{
85 return RealVector(0);
86 }
87 void setParameterVector(RealVector const& newParameters){
88 SIZE_CHECK(newParameters.size() == 0);
89 }
90 std::size_t numberOfParameters() const{
91 return 0;
92 }
93
94 ///\brief creates the internal state of the kernel
95 boost::shared_ptr<State> createState()const{
96 return boost::shared_ptr<State>(new InternalState());
97 }
98
99 /////////////////////////EVALUATION//////////////////////////////
101 SIZE_CHECK(x1.size() == x2.size());
102 double prod=inner_prod(x1, x2);
103 return std::pow(prod,m_exponent);
104 }
105
106 void eval(ConstBatchInputReference batchX1, ConstBatchInputReference batchX2, RealMatrix& result) const{
107 SIZE_CHECK(batchX1.size2() == batchX2.size2());
108 std::size_t sizeX1 = batchX1.size1();
109 std::size_t sizeX2 = batchX2.size1();
110 result.resize(sizeX1,sizeX2);
111 noalias(result) = prod(batchX1,trans(batchX2));
112 if(m_exponent != 1)
113 noalias(result) = pow(result,m_exponent);
114 }
115
116 void eval(ConstBatchInputReference batchX1, ConstBatchInputReference batchX2, RealMatrix& result, State& state) const{
117 SIZE_CHECK(batchX1.size2() == batchX2.size2());
118 std::size_t sizeX1 = batchX1.size1();
119 std::size_t sizeX2 = batchX2.size1();
120 result.resize(sizeX1,sizeX2);
121
122
123 InternalState& s = state.toState<InternalState>();
124 s.resize(sizeX1,sizeX2);
125
126 //calculate the inner product
127 noalias(s.base) = prod(batchX1,trans(batchX2));
128 //now do exponentiation
129 if(m_exponent != 1)
130 noalias(result) = pow(s.base,m_exponent);
131 else
132 noalias(result) = s.base;
133 //store also in state
134 noalias(s.exponentedProd) = result;
135
136 }
137
138 ////////////////////////DERIVATIVES////////////////////////////
139
143 RealMatrix const& coefficients,
144 State const& state,
145 RealVector& gradient
146 ) const{
147 SIZE_CHECK(batchX1.size2() == batchX2.size2());
148 gradient.resize(0);
149 }
150
154 RealMatrix const& coefficientsX2,
155 State const& state,
156 BatchInputType& gradient
157 ) const{
158
159 std::size_t sizeX1 = batchX1.size1();
160 std::size_t sizeX2 = batchX2.size1();
161 gradient.resize(sizeX1,batchX1.size2());
162 InternalState const& s = state.toState<InternalState>();
163
164 //internal checks
165 SIZE_CHECK(batchX1.size2() == batchX2.size2());
166 SIZE_CHECK(s.base.size1() == sizeX1);
167 SIZE_CHECK(s.base.size2() == sizeX2);
168 SIZE_CHECK(s.exponentedProd.size1() == sizeX1);
169 SIZE_CHECK(s.exponentedProd.size2() == sizeX2);
170
171 //first calculate weights(i,j) = coeff(i)*exp(i,j)/prod(i,j)
172 //we have to take the usual division by 0 into account
173 RealMatrix weights = coefficientsX2 * safe_div(s.exponentedProd,s.base,0.0);
174 //The derivative of input i of batch x1 is
175 //g = sum_j m_exponent*weights(i,j)*x2_j
176 //we now sum over j which is a matrix-matrix product
177 noalias(gradient) = m_exponent * prod(weights,batchX2);
178 }
179
180 void read(InArchive& ar){
181 ar >> m_exponent;
182 }
183
184 void write(OutArchive& ar) const{
185 ar << m_exponent;
186 }
187
188protected:
189 ///the exponent of the monomials
191};
192
195
196
197}
198#endif