PointSetKernel.h
Go to the documentation of this file.
1//===========================================================================
2/*!
3 *
4 *
5 * \brief Applies a kernel to two pointsets and comptues the average response
6 *
7 *
8 *
9 * \author T.Glasmachers, O. Krause, M. Tuma
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 * <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_POINT_SET_KERNEL_H
36#define SHARK_MODELS_KERNELS_POINT_SET_KERNEL_H
37
38
40
41namespace shark {
42
43
44/// \brief Normalized version of a kernel function
45///
46/// For a positive definite kernel k, the normalized kernel
47/// \f[ \tilde k(x, y) := \frac{k(x, y)}{\sqrt{k(x, x) \cdot k(y, y)}} \f]
48/// is again a positive definite kernel function.
49/// \ingroup kernels
50template<class InputType=RealVector>
51class PointSetKernel : public AbstractKernelFunction<typename Batch<InputType>::type >
52{
53private:
55
56 struct InternalState: public State{
57 std::vector<boost::shared_ptr<State> > state;
58
59 void resize(std::size_t sizeX1,std::size_t sizeX2, AbstractKernelFunction<InputType> const* base){
60 state.resize(sizeX1 * sizeX2);
61
62 for(std::size_t i = 0; i != state.size();++i){
63 state[i] = base->createState();
64 }
65 }
66 };
67public:
71
77
78 std::string name() const
79 { return "PointSetKernel<" + m_base->name() + ">"; }
80
81 RealVector parameterVector() const{
82 return m_base->parameterVector();
83 }
84
85 void setParameterVector(RealVector const& newParameters){
86 m_base->setParameterVector(newParameters);
87 }
88
89 std::size_t numberOfParameters() const{
90 return m_base->numberOfParameters();
91 }
92
93 ///\brief creates the internal state of the kernel
94 boost::shared_ptr<State> createState()const{
95 InternalState* state = new InternalState();
96 return boost::shared_ptr<State>(state);
97 }
98
99 ///evaluates \f$ k(x,y) \f$
100 ///
101 /// calculates
102 /// \f[ \tilde k(x, y) := \frac{k(x, y)}{\sqrt{k(x, x) \cdot k(y, y)}} \f]
104 RealMatrix response = (*m_base)(x1,x2);
105
106 return sum(response)/(response.size1() * response.size2());
107 }
108
109
110 void eval(ConstBatchInputReference const& batchX1, ConstBatchInputReference const& batchX2, RealMatrix& result, State& state) const{
111 InternalState& s = state.toState<InternalState>();
112
113 std::size_t sizeX1 = batchSize(batchX1);
114 std::size_t sizeX2 = batchSize(batchX2);
115 s.resize(sizeX1,sizeX2,m_base);
116 result.resize(sizeX1,sizeX2);
117 RealMatrix response;
118 for(std::size_t i = 0; i != sizeX1; ++i){
119 for(std::size_t j = 0; j != sizeX2; ++j){
120 m_base->eval(getBatchElement(batchX1,i),getBatchElement(batchX2,j),response,*s.state[i*sizeX2+j]);
121 result(i,j) = sum(response)/(response.size1() * response.size2());
122 }
123 }
124 }
125
126 void eval(ConstBatchInputReference const& batchX1, ConstBatchInputReference const& batchX2, RealMatrix& result) const{
127 std::size_t sizeX1 = batchSize(batchX1);
128 std::size_t sizeX2 = batchSize(batchX2);
129 result.resize(sizeX1,sizeX2);
130
131 RealMatrix response;
132 for(std::size_t i = 0; i != sizeX1; ++i){
133 for(std::size_t j = 0; j != sizeX2; ++j){
134 m_base->eval(getBatchElement(batchX1,i),getBatchElement(batchX2,j),response);
135 result(i,j) = sum(response)/(response.size1() * response.size2());
136 }
137 }
138 }
139
141 ConstBatchInputReference const& batchX1,
142 ConstBatchInputReference const& batchX2,
143 RealMatrix const& coefficients,
144 State const& state,
145 RealVector& gradient
146 ) const{
147 gradient.resize(numberOfParameters());
148 InternalState const& s = state.toState<InternalState>();
149 std::size_t sizeX1 = batchSize(batchX1);
150 std::size_t sizeX2 = batchSize(batchX2);
151
152 for(std::size_t i = 0; i != sizeX1; ++i){
153 for(std::size_t j = 0; j != sizeX2; ++j){
154 auto x1 = getBatchElement(batchX1,i);
155 auto x2 = getBatchElement(batchX2,j);
156 std::size_t size1 = batchSize(x1);
157 std::size_t size2 = batchSize(x2);
158 RealMatrix setCoeff(size1,size2, coefficients(i,j)/(size1 * size2));
159 RealVector grad;
160 m_base->weightedParameterDerivative(x1,x2,setCoeff,*s.state[i*sizeX2+j],grad);
161 noalias(gradient) += grad;
162 }
163 }
164 }
165
166protected:
167 /// kernel to normalize
169};
170
171}
172#endif