yat/classifier/KernelLookup.cc

Code
Comments
Other
Rev Date Author Line
331 01 Jun 05 peter 1 // $Id$
330 01 Jun 05 peter 2
675 10 Oct 06 jari 3 /*
2119 12 Dec 09 peter 4   Copyright (C) 2005, 2006, 2007, 2008 Jari Häkkinen, Peter Johansson
2861 03 Oct 12 peter 5   Copyright (C) 2010, 2012 Peter Johansson
330 01 Jun 05 peter 6
1437 25 Aug 08 peter 7   This file is part of the yat library, http://dev.thep.lu.se/yat
330 01 Jun 05 peter 8
675 10 Oct 06 jari 9   The yat library is free software; you can redistribute it and/or
675 10 Oct 06 jari 10   modify it under the terms of the GNU General Public License as
1486 09 Sep 08 jari 11   published by the Free Software Foundation; either version 3 of the
675 10 Oct 06 jari 12   License, or (at your option) any later version.
675 10 Oct 06 jari 13
675 10 Oct 06 jari 14   The yat library is distributed in the hope that it will be useful,
675 10 Oct 06 jari 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
675 10 Oct 06 jari 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
675 10 Oct 06 jari 17   General Public License for more details.
675 10 Oct 06 jari 18
675 10 Oct 06 jari 19   You should have received a copy of the GNU General Public License
1487 10 Sep 08 jari 20   along with yat. If not, see <http://www.gnu.org/licenses/>.
675 10 Oct 06 jari 21 */
675 10 Oct 06 jari 22
2881 18 Nov 12 peter 23 #include <config.h>
2881 18 Nov 12 peter 24
680 11 Oct 06 jari 25 #include "KernelLookup.h"
680 11 Oct 06 jari 26 #include "MatrixLookup.h"
680 11 Oct 06 jari 27 #include "MatrixLookupWeighted.h"
2861 03 Oct 12 peter 28 #include "yat/utility/Deleter.h"
1121 22 Feb 08 peter 29 #include "yat/utility/Matrix.h"
1581 15 Oct 08 peter 30 #include "yat/utility/MatrixWeighted.h"
675 10 Oct 06 jari 31
537 05 Mar 06 peter 32 #include <cassert>
482 02 Jan 06 peter 33
330 01 Jun 05 peter 34 namespace theplu {
680 11 Oct 06 jari 35 namespace yat {
720 26 Dec 06 jari 36 namespace classifier {
330 01 Jun 05 peter 37
545 06 Mar 06 peter 38   KernelLookup::KernelLookup(const Kernel& kernel, const bool own)
2861 03 Oct 12 peter 39     : kernel_(&kernel, utility::Deleter(own))
463 16 Dec 05 peter 40   {
1134 23 Feb 08 peter 41     column_index_ = utility::Index(kernel.size());
1127 22 Feb 08 peter 42     row_index_=column_index_;
463 16 Dec 05 peter 43   }
720 26 Dec 06 jari 44
720 26 Dec 06 jari 45
537 05 Mar 06 peter 46   KernelLookup::KernelLookup(const Kernel& kernel,
2861 03 Oct 12 peter 47                              const utility::Index& row,
1134 23 Feb 08 peter 48                              const utility::Index& column,
566 16 Mar 06 peter 49                              const bool owner)
2861 03 Oct 12 peter 50     : column_index_(column),
2861 03 Oct 12 peter 51       kernel_(&kernel, utility::Deleter(owner)),
1132 23 Feb 08 peter 52       row_index_(row)
537 05 Mar 06 peter 53   {
1127 22 Feb 08 peter 54     // Checking that each row index is less than kernel.rows()
1134 23 Feb 08 peter 55     assert(validate(row_index_));
1127 22 Feb 08 peter 56     // Checking that each column index is less than kernel.column()
1134 23 Feb 08 peter 57     assert(validate(column_index_));
537 05 Mar 06 peter 58   }
537 05 Mar 06 peter 59
537 05 Mar 06 peter 60
2861 03 Oct 12 peter 61    KernelLookup::KernelLookup(const KernelLookup& other,
2861 03 Oct 12 peter 62                              const utility::Index& row,
1134 23 Feb 08 peter 63                              const utility::Index& column)
1132 23 Feb 08 peter 64     : kernel_(other.kernel_)
446 15 Dec 05 peter 65   {
1134 23 Feb 08 peter 66     row_index_ = utility::Index(other.row_index_, row);
1134 23 Feb 08 peter 67     column_index_ = utility::Index(other.column_index_, column);
446 15 Dec 05 peter 68   }
537 05 Mar 06 peter 69
2861 03 Oct 12 peter 70
640 07 Sep 06 peter 71    KernelLookup::KernelLookup(const KernelLookup& other)
2861 03 Oct 12 peter 72     : column_index_(other.column_index_), kernel_(other.kernel_),
1132 23 Feb 08 peter 73       row_index_(other.row_index_)
537 05 Mar 06 peter 74   {
1134 23 Feb 08 peter 75     // Checking that each row index is less than kernel.rows()
1134 23 Feb 08 peter 76     assert(validate(row_index_));
1134 23 Feb 08 peter 77     // Checking that each column index is less than kernel.column()
1134 23 Feb 08 peter 78     assert(validate(column_index_));
537 05 Mar 06 peter 79   }
537 05 Mar 06 peter 80
2861 03 Oct 12 peter 81
2861 03 Oct 12 peter 82    KernelLookup::KernelLookup(const KernelLookup& other,
2861 03 Oct 12 peter 83                              const utility::Index& index,
559 11 Mar 06 peter 84                              const bool row)
1132 23 Feb 08 peter 85     : kernel_(other.kernel_)
559 11 Mar 06 peter 86   {
1132 23 Feb 08 peter 87     if (row){
1134 23 Feb 08 peter 88       row_index_ = utility::Index(other.row_index_, index);
1132 23 Feb 08 peter 89       column_index_= other.column_index_;
1132 23 Feb 08 peter 90     }
1132 23 Feb 08 peter 91     else{
1134 23 Feb 08 peter 92       column_index_ = utility::Index(other.column_index_, index);
1132 23 Feb 08 peter 93       row_index_= other.row_index_;
1132 23 Feb 08 peter 94     }
1127 22 Feb 08 peter 95     assert(kernel_->size());
1127 22 Feb 08 peter 96
1134 23 Feb 08 peter 97     // Checking that each row index is less than kernel.rows()
1134 23 Feb 08 peter 98     assert(validate(row_index_));
1134 23 Feb 08 peter 99     // Checking that each column index is less than kernel.column()
1134 23 Feb 08 peter 100     assert(validate(column_index_));
559 11 Mar 06 peter 101   }
559 11 Mar 06 peter 102
2861 03 Oct 12 peter 103
537 05 Mar 06 peter 104   KernelLookup::~KernelLookup(void)
537 05 Mar 06 peter 105   {
537 05 Mar 06 peter 106   }
537 05 Mar 06 peter 107
330 01 Jun 05 peter 108
1066 10 Feb 08 peter 109   KernelLookup::const_iterator KernelLookup::begin(void) const
1066 10 Feb 08 peter 110   {
1066 10 Feb 08 peter 111     return const_iterator(const_iterator::iterator_type(*this, 0, 0), 1);
1066 10 Feb 08 peter 112   }
1066 10 Feb 08 peter 113
1066 10 Feb 08 peter 114
2861 03 Oct 12 peter 115   KernelLookup::const_column_iterator
1105 18 Feb 08 peter 116   KernelLookup::begin_column(size_t i) const
1066 10 Feb 08 peter 117   {
1105 18 Feb 08 peter 118     return const_column_iterator(const_column_iterator::iterator_type(*this,
2861 03 Oct 12 peter 119                                                                       0,i),
1105 18 Feb 08 peter 120                                  columns());
1066 10 Feb 08 peter 121   }
1066 10 Feb 08 peter 122
1066 10 Feb 08 peter 123
1105 18 Feb 08 peter 124   KernelLookup::const_row_iterator KernelLookup::begin_row(size_t i) const
1066 10 Feb 08 peter 125   {
1105 18 Feb 08 peter 126     return const_row_iterator(const_row_iterator::iterator_type(*this,i,0), 1);
1066 10 Feb 08 peter 127   }
1066 10 Feb 08 peter 128
1066 10 Feb 08 peter 129
1132 23 Feb 08 peter 130   size_t KernelLookup::columns(void) const
1132 23 Feb 08 peter 131   {
1132 23 Feb 08 peter 132     return column_index_.size();
1132 23 Feb 08 peter 133   }
1132 23 Feb 08 peter 134
1132 23 Feb 08 peter 135
1206 05 Mar 08 peter 136   MatrixLookup KernelLookup::data(void) const
720 26 Dec 06 jari 137   {
1206 05 Mar 08 peter 138     assert(!weighted());
1206 05 Mar 08 peter 139     return MatrixLookup(kernel_->data(), column_index_, false);
720 26 Dec 06 jari 140   }
482 02 Jan 06 peter 141
482 02 Jan 06 peter 142
1206 05 Mar 08 peter 143   MatrixLookupWeighted KernelLookup::data_weighted(void) const
1165 26 Feb 08 peter 144   {
1206 05 Mar 08 peter 145     assert(weighted());
2223 19 Mar 10 peter 146     using utility::Index; // just to avoid long line
2861 03 Oct 12 peter 147     return MatrixLookupWeighted(kernel_->data_weighted(),
2861 03 Oct 12 peter 148                                 Index(kernel_->data_weighted().rows()),
2223 19 Mar 10 peter 149                                 column_index_);
1165 26 Feb 08 peter 150   }
1165 26 Feb 08 peter 151
1165 26 Feb 08 peter 152
720 26 Dec 06 jari 153   double KernelLookup::element(const DataLookup1D& vec, size_t i) const
720 26 Dec 06 jari 154   {
720 26 Dec 06 jari 155     return kernel_->element(vec, row_index_[i]);
720 26 Dec 06 jari 156   }
482 02 Jan 06 peter 157
720 26 Dec 06 jari 158
720 26 Dec 06 jari 159   double KernelLookup::element(const DataLookupWeighted1D& vec, size_t i) const
720 26 Dec 06 jari 160   {
720 26 Dec 06 jari 161     return kernel_->element(vec, row_index_[i]);
720 26 Dec 06 jari 162   }
720 26 Dec 06 jari 163
720 26 Dec 06 jari 164
1066 10 Feb 08 peter 165   KernelLookup::const_iterator KernelLookup::end(void) const
1066 10 Feb 08 peter 166   {
1066 10 Feb 08 peter 167     return const_iterator(const_iterator::iterator_type(*this, rows(), 0), 1);
1066 10 Feb 08 peter 168   }
1066 10 Feb 08 peter 169
1066 10 Feb 08 peter 170
1105 18 Feb 08 peter 171   KernelLookup::const_column_iterator KernelLookup::end_column(size_t i) const
1066 10 Feb 08 peter 172   {
2861 03 Oct 12 peter 173     return const_column_iterator(const_column_iterator::iterator_type(*this,
1105 18 Feb 08 peter 174                                                                       rows(),i),
1105 18 Feb 08 peter 175                                  columns());
1066 10 Feb 08 peter 176   }
1066 10 Feb 08 peter 177
1066 10 Feb 08 peter 178
1105 18 Feb 08 peter 179   KernelLookup::const_row_iterator KernelLookup::end_row(size_t i) const
1066 10 Feb 08 peter 180   {
1105 18 Feb 08 peter 181     return const_row_iterator(const_row_iterator::iterator_type(*this,i+1,0),1);
1066 10 Feb 08 peter 182   }
1066 10 Feb 08 peter 183
1066 10 Feb 08 peter 184
1132 23 Feb 08 peter 185   size_t KernelLookup::rows(void) const
1132 23 Feb 08 peter 186   {
1132 23 Feb 08 peter 187     return row_index_.size();
1132 23 Feb 08 peter 188   }
1132 23 Feb 08 peter 189
1132 23 Feb 08 peter 190
1206 05 Mar 08 peter 191   KernelLookup KernelLookup::selected(const utility::Index& inputs) const
545 06 Mar 06 peter 192   {
746 11 Feb 07 peter 193     const Kernel* kernel;
746 11 Feb 07 peter 194     if (kernel_->weighted()){
2861 03 Oct 12 peter 195       const MatrixLookupWeighted* ms =
2861 03 Oct 12 peter 196         new MatrixLookupWeighted(data_weighted(),inputs,
2223 19 Mar 10 peter 197                                  utility::Index(data_weighted().columns()));
1206 05 Mar 08 peter 198       kernel = kernel_->make_kernel(*ms, true);
746 11 Feb 07 peter 199     }
746 11 Feb 07 peter 200     else {
746 11 Feb 07 peter 201       // matrix with selected features
1206 05 Mar 08 peter 202       const MatrixLookup* ms = new MatrixLookup(data(),inputs,true);
746 11 Feb 07 peter 203       kernel = kernel_->make_kernel(*ms,true);
746 11 Feb 07 peter 204     }
1206 05 Mar 08 peter 205     return KernelLookup(*kernel, true);
545 06 Mar 06 peter 206   }
545 06 Mar 06 peter 207
658 25 Sep 06 peter 208
1206 05 Mar 08 peter 209   KernelLookup KernelLookup::test_kernel(const MatrixLookup& data) const
658 25 Sep 06 peter 210   {
658 25 Sep 06 peter 211     if (!weighted()){
1165 26 Feb 08 peter 212       assert(data.rows()==kernel_->data().rows());
2861 03 Oct 12 peter 213       utility::Matrix* data_all =
1121 22 Feb 08 peter 214         new utility::Matrix(data.rows(), row_index_.size()+data.columns());
659 26 Sep 06 peter 215
659 26 Sep 06 peter 216       for (size_t i=0; i<data_all->rows(); ++i) {
659 26 Sep 06 peter 217
659 26 Sep 06 peter 218         // first some columns from data in kernel_
659 26 Sep 06 peter 219         for (size_t j=0; j<row_index_.size(); ++j){
2861 03 Oct 12 peter 220           (*data_all)(i,j) = kernel_->data()(i,row_index_[j]);
659 26 Sep 06 peter 221         }
2861 03 Oct 12 peter 222
658 25 Sep 06 peter 223         // last columns are equal to new data
659 26 Sep 06 peter 224         for (size_t j=0;j<data.columns(); ++j){
658 25 Sep 06 peter 225           (*data_all)(i,j+row_index_.size()) = data(i,j);
659 26 Sep 06 peter 226         }
658 25 Sep 06 peter 227       }
658 25 Sep 06 peter 228       std::vector<size_t> column_index;
658 25 Sep 06 peter 229       column_index.reserve(data.columns());
658 25 Sep 06 peter 230       for (size_t i=0;i<data.columns(); ++i)
658 25 Sep 06 peter 231         column_index.push_back(i+row_index_.size());
659 26 Sep 06 peter 232
659 26 Sep 06 peter 233       std::vector<size_t> row_index;
659 26 Sep 06 peter 234       row_index.reserve(row_index_.size());
659 26 Sep 06 peter 235       for (size_t i=0;i<row_index_.size(); ++i)
659 26 Sep 06 peter 236         row_index.push_back(i);
659 26 Sep 06 peter 237
659 26 Sep 06 peter 238       const MatrixLookup* tmp = new MatrixLookup(*data_all, true);
659 26 Sep 06 peter 239
2861 03 Oct 12 peter 240       const Kernel* kernel =
659 26 Sep 06 peter 241         kernel_->make_kernel(*tmp, true);
659 26 Sep 06 peter 242
2861 03 Oct 12 peter 243       return KernelLookup(*kernel, utility::Index(row_index),
1206 05 Mar 08 peter 244                           utility::Index(column_index), true);
658 25 Sep 06 peter 245     }
658 25 Sep 06 peter 246
1165 26 Feb 08 peter 247     assert(data.rows()==kernel_->data_weighted().rows());
658 25 Sep 06 peter 248     // kernel_ holds MatrixLookupWeighted, hence new Kernel also
658 25 Sep 06 peter 249     // should hold a MatrixLookupweighted.
2861 03 Oct 12 peter 250     utility::MatrixWeighted* x_all =
1581 15 Oct 08 peter 251       new utility::MatrixWeighted(data.rows(), rows()+data.columns());
1165 26 Feb 08 peter 252     const MatrixLookupWeighted& kernel_data = kernel_->data_weighted();
658 25 Sep 06 peter 253
658 25 Sep 06 peter 254     for (size_t i=0; i<data.rows(); ++i){
659 26 Sep 06 peter 255
659 26 Sep 06 peter 256       // first some columns from data in kernel_
658 25 Sep 06 peter 257       for (size_t j=0; j<row_index_.size(); ++j){
2861 03 Oct 12 peter 258         (*x_all)(i,j) = kernel_data(i,row_index_[j]);
658 25 Sep 06 peter 259       }
659 26 Sep 06 peter 260
658 25 Sep 06 peter 261       // last columns are equal to new data
658 25 Sep 06 peter 262       for (size_t j=0;j<data.columns(); ++j){
1581 15 Oct 08 peter 263         (*x_all)(i,j+row_index_.size()).data() = data(i,j);
658 25 Sep 06 peter 264       }
658 25 Sep 06 peter 265     }
658 25 Sep 06 peter 266     std::vector<size_t> column_index;
658 25 Sep 06 peter 267     column_index.reserve(data.columns());
658 25 Sep 06 peter 268     for (size_t i=0;i<data.columns(); ++i)
658 25 Sep 06 peter 269       column_index.push_back(i+row_index_.size());
659 26 Sep 06 peter 270
659 26 Sep 06 peter 271     std::vector<size_t> row_index;
659 26 Sep 06 peter 272     row_index.reserve(row_index_.size());
659 26 Sep 06 peter 273     for (size_t i=0;i<row_index_.size(); ++i)
659 26 Sep 06 peter 274       row_index.push_back(i);
659 26 Sep 06 peter 275
1581 15 Oct 08 peter 276     MatrixLookupWeighted* tmp = new MatrixLookupWeighted(*x_all, true);
659 26 Sep 06 peter 277     const Kernel* kernel = kernel_->make_kernel(*tmp, true);
1201 05 Mar 08 peter 278
1201 05 Mar 08 peter 279
2861 03 Oct 12 peter 280     return KernelLookup(*kernel, row_index_,
1206 05 Mar 08 peter 281                         utility::Index(column_index), true);
658 25 Sep 06 peter 282   }
658 25 Sep 06 peter 283
658 25 Sep 06 peter 284
658 25 Sep 06 peter 285
1206 05 Mar 08 peter 286   KernelLookup KernelLookup::test_kernel(const MatrixLookupWeighted& data) const
658 25 Sep 06 peter 287   {
2861 03 Oct 12 peter 288     utility::MatrixWeighted* x_all =
1581 15 Oct 08 peter 289       new utility::MatrixWeighted(data.rows(), rows()+data.columns());
658 25 Sep 06 peter 290
658 25 Sep 06 peter 291     if (weighted()){
1165 26 Feb 08 peter 292       const MatrixLookupWeighted& kernel_data = kernel_->data_weighted();
2861 03 Oct 12 peter 293
658 25 Sep 06 peter 294       for (size_t i=0; i<data.rows(); ++i){
658 25 Sep 06 peter 295         // first columns are equal to data in kernel_
658 25 Sep 06 peter 296         for (size_t j=0; j<row_index_.size(); ++j){
1581 15 Oct 08 peter 297           (*x_all)(i,j) = kernel_data(i,row_index_[j]);
658 25 Sep 06 peter 298         }
658 25 Sep 06 peter 299       }
658 25 Sep 06 peter 300     }
658 25 Sep 06 peter 301     else {
658 25 Sep 06 peter 302
658 25 Sep 06 peter 303       for (size_t i=0; i<data.rows(); ++i){
658 25 Sep 06 peter 304         // first columns are equal to data in kernel_
658 25 Sep 06 peter 305         for (size_t j=0; j<row_index_.size(); ++j)
1581 15 Oct 08 peter 306           (*x_all)(i,j).data() = kernel_->data()(i,row_index_[j]);
658 25 Sep 06 peter 307       }
658 25 Sep 06 peter 308     }
658 25 Sep 06 peter 309
658 25 Sep 06 peter 310     // last columns are equal to new data
658 25 Sep 06 peter 311     for (size_t i=0; i<data.rows(); ++i){
658 25 Sep 06 peter 312       for (size_t j=0;j<data.columns(); ++j){
1581 15 Oct 08 peter 313         (*x_all)(i,j+row_index_.size()) = data(i,j);
658 25 Sep 06 peter 314       }
658 25 Sep 06 peter 315     }
2861 03 Oct 12 peter 316
658 25 Sep 06 peter 317     std::vector<size_t> column_index;
658 25 Sep 06 peter 318     column_index.reserve(data.columns());
658 25 Sep 06 peter 319     for (size_t i=0;i<data.columns(); ++i)
658 25 Sep 06 peter 320       column_index.push_back(i+row_index_.size());
2861 03 Oct 12 peter 321     const Kernel* kernel =
1581 15 Oct 08 peter 322       kernel_->make_kernel(MatrixLookupWeighted(*x_all, true));
2861 03 Oct 12 peter 323     return KernelLookup(*kernel, row_index_,
1206 05 Mar 08 peter 324                         utility::Index(column_index), true);
658 25 Sep 06 peter 325   }
658 25 Sep 06 peter 326
720 26 Dec 06 jari 327
1167 26 Feb 08 peter 328   /*
720 26 Dec 06 jari 329   const KernelLookup*
1134 23 Feb 08 peter 330   KernelLookup::training_data(const utility::Index& train) const
720 26 Dec 06 jari 331   {
1127 22 Feb 08 peter 332     return new KernelLookup(*this,train,train);
720 26 Dec 06 jari 333   }
1167 26 Feb 08 peter 334   */
720 26 Dec 06 jari 335
720 26 Dec 06 jari 336
1134 23 Feb 08 peter 337   bool KernelLookup::validate(const utility::Index& index) const
1134 23 Feb 08 peter 338   {
1134 23 Feb 08 peter 339     for (size_t i=0; i<index.size(); ++i)
1134 23 Feb 08 peter 340       if (index[i]>=kernel_->size())
1134 23 Feb 08 peter 341         return false;
1134 23 Feb 08 peter 342     return true;
1134 23 Feb 08 peter 343   }
1134 23 Feb 08 peter 344
1134 23 Feb 08 peter 345
720 26 Dec 06 jari 346   bool KernelLookup::weighted(void) const
720 26 Dec 06 jari 347   {
720 26 Dec 06 jari 348     return kernel_->weighted();
720 26 Dec 06 jari 349   }
720 26 Dec 06 jari 350
720 26 Dec 06 jari 351
2861 03 Oct 12 peter 352   KernelLookup::const_reference
1549 06 Oct 08 peter 353   KernelLookup::operator()(size_t row, size_t column) const
720 26 Dec 06 jari 354   {
720 26 Dec 06 jari 355     return (*kernel_)(row_index_[row],column_index_[column]);
720 26 Dec 06 jari 356   }
720 26 Dec 06 jari 357
680 11 Oct 06 jari 358 }}} // of namespace classifier, yat, and theplu