//=========================================================================== /*! * * * \brief Collection of functions dealing with typical tasks of kernels * * * \author O. Krause * \date 2007-2012 * * * \par Copyright 1995-2017 Shark Development Team * *

* This file is part of Shark. * * * Shark is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Shark is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Shark. If not, see . * */ //=========================================================================== #ifndef SHARK_MODELS_KERNELS_KERNELHELPERS_H #define SHARK_MODELS_KERNELS_KERNELHELPERS_H #include #include #include namespace shark{ /// \brief Calculates the regularized kernel gram matrix of the points stored inside a dataset. /// /// Regularization is applied by adding the regularizer on the diagonal /// \param kernel the kernel for which to calculate the kernel gram matrix /// \param dataset the set of points used in the gram matrix /// \param matrix the target kernel matrix /// \param regularizer the regularizer of the matrix which is always >= 0. default is 0. template void calculateRegularizedKernelMatrix( AbstractKernelFunctionconst& kernel, Data const& dataset, blas::matrix_expression& matrix, double regularizer = 0 ){ SHARK_RUNTIME_CHECK(regularizer >= 0, "regularizer must be >=0"); std::size_t B = dataset.numberOfBatches(); //get start of all batches in the matrix //also include the past the end position at the end std::vector batchStart(B+1,0); for(std::size_t i = 1; i != B+1; ++i){ batchStart[i] = batchStart[i-1]+ batchSize(dataset.batch(i-1)); } SIZE_CHECK(batchStart[B] == dataset.numberOfElements()); std::size_t N = batchStart[B];//number of elements ensure_size(matrix,N,N); for (std::size_t i=0; i(regularizer); } } } /// \brief Calculates the kernel gram matrix between two data sets. /// /// \param kernel the kernel for which to calculate the kernel gram matrix /// \param dataset1 the set of points corresponding to rows of the Gram matrix /// \param dataset2 the set of points corresponding to columns of the Gram matrix /// \param matrix the target kernel matrix template void calculateMixedKernelMatrix( AbstractKernelFunctionconst& kernel, Data const& dataset1, Data const& dataset2, blas::matrix_expression& matrix ){ std::size_t B1 = dataset1.numberOfBatches(); std::size_t B2 = dataset2.numberOfBatches(); //get start of all batches in the matrix //also include the past the end position at the end std::vector batchStart1(B1+1,0); for(std::size_t i = 1; i != B1+1; ++i){ batchStart1[i] = batchStart1[i-1]+ batchSize(dataset1.batch(i-1)); } std::vector batchStart2(B2+1,0); for(std::size_t i = 1; i != B2+1; ++i){ batchStart2[i] = batchStart2[i-1]+ batchSize(dataset2.batch(i-1)); } SIZE_CHECK(batchStart1[B1] == dataset1.numberOfElements()); SIZE_CHECK(batchStart2[B2] == dataset2.numberOfElements()); std::size_t N1 = batchStart1[B1];//number of elements std::size_t N2 = batchStart2[B2];//number of elements ensure_size(matrix,N1,N2); for (std::size_t i=0; i= 0. default is 0. /// \return the kernel gram matrix template RealMatrix calculateRegularizedKernelMatrix( AbstractKernelFunctionconst& kernel, Data const& dataset, double regularizer = 0 ){ SHARK_RUNTIME_CHECK(regularizer >= 0, "regularizer must be >=0"); RealMatrix M; calculateRegularizedKernelMatrix(kernel,dataset,M,regularizer); return M; } /// \brief Calculates the kernel gram matrix between two data sets. /// /// \param kernel the kernel for which to calculate the kernel gram matrix /// \param dataset1 the set of points corresponding to rows of the Gram matrix /// \param dataset2 the set of points corresponding to columns of the Gram matrix /// \return matrix the target kernel matrix template RealMatrix calculateMixedKernelMatrix( AbstractKernelFunctionconst& kernel, Data const& dataset1, Data const& dataset2 ){ RealMatrix M; calculateMixedKernelMatrix(kernel,dataset1,dataset2,M); return M; } /// \brief Efficiently calculates the weighted derivative of a Kernel Gram Matrix w.r.t the Kernel Parameters /// /// The formula is \f$ \sum_i \sum_j w_{ij} k(x_i,x_j)\f$ where w_ij are the weights of the gradient and x_i x_j are /// the datapoints defining the gram matrix and k is the kernel. For efficiency it is assumd that w_ij = w_ji. ///This method is only useful when the whole Kernel Gram Matrix neds to be computed to get the weights w_ij and ///only computing smaller blocks is not sufficient. /// \param kernel the kernel for which to calculate the kernel gram matrix /// \param dataset the set of points used in the gram matrix /// \param weights the weights of the derivative, they must be symmetric! /// \return the weighted derivative w.r.t the parameters. template RealVector calculateKernelMatrixParameterDerivative( AbstractKernelFunction const& kernel, Data const& dataset, WeightMatrix const& weights ){ std::size_t kp = kernel.numberOfParameters(); RealMatrix block;//stores the kernel results of the block which we need to compute to get the State :( RealVector kernelGradient(kp);//weighted gradient summed over the whole kernel matrix kernelGradient.clear(); //calculate the gradint blockwise taking symmetry into account. RealVector blockGradient(kp);//weighted gradient summed over the whole block boost::shared_ptr state = kernel.createState(); std::size_t startX = 0; for (std::size_t i=0; i