diff --git a/dlib/svm/empirical_kernel_map.h b/dlib/svm/empirical_kernel_map.h index b2e6513a9..8e46bf0b3 100644 --- a/dlib/svm/empirical_kernel_map.h +++ b/dlib/svm/empirical_kernel_map.h @@ -5,6 +5,7 @@ #include "../matrix.h" #include "empirical_kernel_map_abstract.h" +#include "linearly_independent_subset_finder.h" #include #include "../algs.h" #include "kernel_matrix.h" @@ -71,6 +72,25 @@ namespace dlib load_impl(kernel_, vector_to_matrix(basis_samples)); } + void load( + const linearly_independent_subset_finder& lisf + ) + { + // make sure requires clause is not broken + DLIB_ASSERT(lisf.dictionary_size() > 0, + "\tvoid empirical_kernel_map::load(linearly_independent_subset_finder)" + << "\n\t You have to give a non-empty set of basis_samples" + << "\n\t this: " << this + ); + + kernel = lisf.get_kernel(); + weights = trans(chol(lisf.get_inv_kernel_marix())); + basis.resize(lisf.dictionary_size()); + for (unsigned long i = 0; i < basis.size(); ++i) + basis[i] = lisf[i]; + + } + const kernel_type get_kernel ( ) const { diff --git a/dlib/svm/empirical_kernel_map_abstract.h b/dlib/svm/empirical_kernel_map_abstract.h index c91f16c43..e4dd53d13 100644 --- a/dlib/svm/empirical_kernel_map_abstract.h +++ b/dlib/svm/empirical_kernel_map_abstract.h @@ -7,6 +7,7 @@ #include "../matrix.h" #include "kernel_abstract.h" #include "function_abstract.h" +#include "linearly_independent_subset_finder_abstract.h" #include namespace dlib @@ -142,6 +143,27 @@ namespace dlib If this happens then this object will revert back to its initial value. !*/ + void load( + const linearly_independent_subset_finder& lisf + ); + /*! + requires + - lisf.dictionary_size() > 0 + ensures + - #out_vector_size() == lisf.dictionary_size() + - #get_kernel() == lisf.get_kernel() + - Uses the dictionary vectors from lisf as a basis set. Thus, this function + constructs a map between normal sample_type objects and the subspace of + the kernel feature space defined by the given kernel and the given set + of basis samples. So after this function has been called you will be + able to project sample_type objects into kernel feature space and obtain + the resulting vector as a regular column matrix. + throws + - empirical_kernel_map_error + This exception is thrown if we are unable to create a kernel map. + If this happens then this object will revert back to its initial value. + !*/ + const kernel_type get_kernel ( ) const; /*! diff --git a/dlib/svm/linearly_independent_subset_finder.h b/dlib/svm/linearly_independent_subset_finder.h index 404e04c7c..d2432ea32 100644 --- a/dlib/svm/linearly_independent_subset_finder.h +++ b/dlib/svm/linearly_independent_subset_finder.h @@ -108,7 +108,7 @@ namespace dlib K.set_size(0,0); } - void add ( + bool add ( const sample_type& x ) { @@ -126,7 +126,9 @@ namespace dlib K(0,0) = kx; dictionary.push_back(x); + return true; } + return false; } else { @@ -220,6 +222,11 @@ namespace dlib dictionary.push_back(x); } + return true; + } + else + { + return false; } } } @@ -285,6 +292,18 @@ namespace dlib return dictionary[index]; } + const matrix& get_kernel_matrix ( + ) const + { + return K; + } + + const matrix& get_inv_kernel_marix ( + ) const + { + return K_inv; + } + private: typedef std_allocator alloc_sample_type; diff --git a/dlib/svm/linearly_independent_subset_finder_abstract.h b/dlib/svm/linearly_independent_subset_finder_abstract.h index 61d54ea9e..69ee33397 100644 --- a/dlib/svm/linearly_independent_subset_finder_abstract.h +++ b/dlib/svm/linearly_independent_subset_finder_abstract.h @@ -112,19 +112,22 @@ namespace dlib - clears out all the data (e.g. #dictionary_size() == 0) !*/ - void add ( + bool add ( const sample_type& x ); /*! ensures - if (x is linearly independent of the vectors already in this object) then - adds x into the dictionary + - returns true - if (dictionary_size() < max_dictionary_size()) then - #dictionary_size() == dictionary_size() + 1 - else - #dictionary_size() == dictionary_size() (i.e. the number of vectors in this object doesn't change) - the least linearly independent vector in this object is removed + - else + - returns false !*/ void swap ( @@ -161,6 +164,25 @@ namespace dlib vectors in this object. !*/ + const matrix& get_kernel_matrix ( + ) const; + /*! + ensures + - returns a matrix K such that: + - K.nr() == K.nc() == dictionary_size() + - K == kernel_matrix(get_kernel(), get_dictionary()) + i.e. K == the kernel matrix for the dictionary vectors + !*/ + + const matrix& get_inv_kernel_marix ( + ) const; + /*! + ensures + - if (dictionary_size() != 0) + - returns inv(get_kernel_matrix()) + - else + - returns an empty matrix + !*/ }; // ----------------------------------------------------------------------------------------