source: trunk/yat/classifier/KernelLookup.cc @ 1133

Last change on this file since 1133 was 1133, checked in by Peter, 14 years ago

using SmartPtr? in KernelLookup? rather than doing the ref count myself

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date ID
File size: 10.8 KB
Line 
1// $Id$
2
3/*
4  Copyright (C) 2005, 2006, 2007 Jari Häkkinen, Peter Johansson
5
6  This file is part of the yat library, http://trac.thep.lu.se/yat
7
8  The yat library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version.
12
13  The yat library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21  02111-1307, USA.
22*/
23
24#include "KernelLookup.h"
25#include "DataLookup2D.h"
26#include "MatrixLookup.h"
27#include "MatrixLookupWeighted.h"
28#include "yat/utility/Matrix.h"
29
30#include <cassert>
31#ifndef NDEBUG
32#include <algorithm>
33#endif
34
35namespace theplu {
36namespace yat {
37namespace classifier {
38
39  KernelLookup::KernelLookup(const Kernel& kernel, const bool own)
40    : kernel_(utility::SmartPtr<const Kernel>(&kernel, own))
41  {
42    column_index_.reserve(kernel.size());
43    for(size_t i=0; i<kernel.size(); i++)
44      column_index_.push_back(i);
45    row_index_=column_index_;
46  }
47
48
49  KernelLookup::KernelLookup(const Kernel& kernel,
50                             const std::vector<size_t>& row, 
51                             const std::vector<size_t>& column,
52                             const bool owner)
53    : column_index_(column), 
54      kernel_(utility::SmartPtr<const Kernel>(&kernel, owner)),
55      row_index_(row)
56  {
57    // Checking that each row index is less than kernel.rows()
58    assert(row.empty() || 
59           *(std::max_element(row.begin(),row.end()))<kernel_->size());
60    // Checking that each column index is less than kernel.column()
61    assert(column.empty() || 
62           *(std::max_element(column.begin(),column.end()))<kernel_->size());
63  }
64
65
66  KernelLookup::KernelLookup(const KernelLookup& other, 
67                             const std::vector<size_t>& row, 
68                             const std::vector<size_t>& column)
69    : kernel_(other.kernel_)
70  {
71    assert(row_index_.empty());
72    row_index_.reserve(row.size());
73    for (size_t i=0; i<row.size(); i++) {
74      assert(row[i]<other.row_index_.size());
75      row_index_.push_back(other.row_index_[row[i]]);
76    }
77    assert(column_index_.empty());
78    column_index_.reserve(column.size());
79    for (size_t i=0; i<column.size(); i++) {
80      assert(column[i]<other.column_index_.size());
81      column_index_.push_back(other.column_index_[column[i]]);
82    }
83  }
84 
85
86  KernelLookup::KernelLookup(const KernelLookup& other)
87    : column_index_(other.column_index_), kernel_(other.kernel_), 
88      row_index_(other.row_index_)
89  {
90    // Checking that no index is out of range
91    assert(row_index_.empty() || 
92           *(max_element(row_index_.begin(), row_index_.end()))<
93           kernel_->size());
94    assert(column_index_.empty() || 
95           *(max_element(column_index_.begin(), column_index_.end()))<
96           kernel_->size());
97  }
98 
99
100  KernelLookup::KernelLookup(const KernelLookup& other, 
101                             const std::vector<size_t>& index, 
102                             const bool row)
103    : kernel_(other.kernel_)
104  {
105    if (row){
106      assert(row_index_.empty());
107      row_index_.reserve(index.size());
108      for (size_t i=0; i<index.size(); i++) {
109        assert(index[i]<other.row_index_.size());
110        row_index_.push_back(other.row_index_[index[i]]);
111      }
112      column_index_= other.column_index_;
113    }
114    else{
115      assert(column_index_.empty());
116      column_index_.reserve(index.size());
117      for (size_t i=0; i<index.size(); i++) {
118        column_index_.push_back(other.column_index_[index[i]]);
119      }
120      row_index_= other.row_index_;
121    }
122    assert(kernel_->size());
123
124    // Checking that no index is out of range
125    assert(row_index_.empty() || 
126           *(max_element(row_index_.begin(), row_index_.end()))<
127           kernel_->size());
128    assert(column_index_.empty() || 
129           *(max_element(column_index_.begin(), column_index_.end()))<
130           kernel_->size());
131  }
132 
133
134  KernelLookup::~KernelLookup(void)
135  {
136  }
137
138
139  KernelLookup::const_iterator KernelLookup::begin(void) const
140  {
141    return const_iterator(const_iterator::iterator_type(*this, 0, 0), 1);
142  }
143
144
145  KernelLookup::const_column_iterator
146  KernelLookup::begin_column(size_t i) const
147  {
148    return const_column_iterator(const_column_iterator::iterator_type(*this,
149                                                                      0,i), 
150                                 columns());
151  }
152
153
154  KernelLookup::const_row_iterator KernelLookup::begin_row(size_t i) const
155  {
156    return const_row_iterator(const_row_iterator::iterator_type(*this,i,0), 1);
157  }
158
159
160  size_t KernelLookup::columns(void) const
161  {
162    return column_index_.size();
163  }
164
165
166  const DataLookup2D* KernelLookup::data(void) const
167  {
168    return kernel_->data().training_data(column_index_);
169  }
170
171
172  double KernelLookup::element(const DataLookup1D& vec, size_t i) const
173  {
174    return kernel_->element(vec, row_index_[i]);
175  }
176
177
178  double KernelLookup::element(const DataLookupWeighted1D& vec, size_t i) const
179  {
180    return kernel_->element(vec, row_index_[i]);
181  }
182
183
184  KernelLookup::const_iterator KernelLookup::end(void) const
185  {
186    return const_iterator(const_iterator::iterator_type(*this, rows(), 0), 1);
187  }
188
189
190  KernelLookup::const_column_iterator KernelLookup::end_column(size_t i) const
191  {
192    return const_column_iterator(const_column_iterator::iterator_type(*this, 
193                                                                      rows(),i),
194                                 columns());
195  }
196
197
198  KernelLookup::const_row_iterator KernelLookup::end_row(size_t i) const
199  {
200    return const_row_iterator(const_row_iterator::iterator_type(*this,i+1,0),1);
201  }
202
203
204  size_t KernelLookup::rows(void) const
205  {
206    return row_index_.size();
207  }
208
209
210  const KernelLookup* 
211  KernelLookup::selected(const std::vector<size_t>& inputs) const
212  {
213    const Kernel* kernel;
214    if (kernel_->weighted()){
215      const MatrixLookupWeighted* ml = 
216        dynamic_cast<const MatrixLookupWeighted*>(data());
217      assert(ml);
218      const MatrixLookupWeighted* ms = 
219        new MatrixLookupWeighted(*ml,inputs,true);
220      kernel = kernel_->make_kernel(*ms, false);
221    }
222    else {
223      const MatrixLookup* m = 
224        dynamic_cast<const MatrixLookup*>(data());
225      assert(m);
226      // matrix with selected features
227      const MatrixLookup* ms = new MatrixLookup(*m,inputs,true);
228      kernel = kernel_->make_kernel(*ms,true);
229    }
230    return new KernelLookup(*kernel, true);
231  }
232
233
234  const KernelLookup* KernelLookup::test_kernel(const MatrixLookup& data) const
235  {
236
237    assert(data.rows()==kernel_->data().rows());
238    if (!weighted()){
239      utility::Matrix* data_all = 
240        new utility::Matrix(data.rows(), row_index_.size()+data.columns());
241
242      for (size_t i=0; i<data_all->rows(); ++i) {
243
244        // first some columns from data in kernel_
245        for (size_t j=0; j<row_index_.size(); ++j){
246          (*data_all)(i,j) = kernel_->data()(i,row_index_[j]); 
247        }
248       
249        // last columns are equal to new data
250        for (size_t j=0;j<data.columns(); ++j){
251          (*data_all)(i,j+row_index_.size()) = data(i,j);
252        }
253      }
254      std::vector<size_t> column_index;
255      column_index.reserve(data.columns());
256      for (size_t i=0;i<data.columns(); ++i)
257        column_index.push_back(i+row_index_.size());
258
259      std::vector<size_t> row_index;
260      row_index.reserve(row_index_.size());
261      for (size_t i=0;i<row_index_.size(); ++i)
262        row_index.push_back(i);
263
264      const MatrixLookup* tmp = new MatrixLookup(*data_all, true);
265
266      const Kernel* kernel = 
267        kernel_->make_kernel(*tmp, true);
268
269      return new KernelLookup(*kernel, row_index, column_index, true);
270    }
271
272    // kernel_ holds MatrixLookupWeighted, hence new Kernel also
273    // should hold a MatrixLookupweighted.
274    utility::Matrix* data_all = 
275      new utility::Matrix(data.rows(), rows()+data.columns());
276    utility::Matrix* weight_all = 
277      new utility::Matrix(data.rows(), rows()+data.columns(), 1.0);
278    const MatrixLookupWeighted& kernel_data = 
279      dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
280
281    for (size_t i=0; i<data.rows(); ++i){
282
283      // first some columns from data in kernel_
284      for (size_t j=0; j<row_index_.size(); ++j){
285        (*data_all)(i,j) = kernel_data.data(i,row_index_[j]); 
286        (*weight_all)(i,j) = kernel_data.weight(i,row_index_[j]);
287      }
288
289      // last columns are equal to new data
290      for (size_t j=0;j<data.columns(); ++j){
291        (*data_all)(i,j+row_index_.size()) = data(i,j);
292      }
293    }
294    std::vector<size_t> column_index;
295    column_index.reserve(data.columns());
296    for (size_t i=0;i<data.columns(); ++i)
297      column_index.push_back(i+row_index_.size());
298
299    std::vector<size_t> row_index;
300    row_index.reserve(row_index_.size());
301    for (size_t i=0;i<row_index_.size(); ++i)
302      row_index.push_back(i);
303
304    MatrixLookupWeighted* tmp = new MatrixLookupWeighted(*data_all, 
305                                                         *weight_all, true);
306    const Kernel* kernel = kernel_->make_kernel(*tmp, true);
307    return new KernelLookup(*kernel, row_index_, column_index, true);
308  }
309
310
311
312  const KernelLookup* 
313  KernelLookup::test_kernel(const MatrixLookupWeighted& data) const
314  {
315    utility::Matrix* data_all = 
316      new utility::Matrix(data.rows(), rows()+data.columns());
317    utility::Matrix* weight_all = 
318      new utility::Matrix(data.rows(), rows()+data.columns(), 1.0);
319
320    if (weighted()){
321      const MatrixLookupWeighted& kernel_data = 
322        dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
323   
324      for (size_t i=0; i<data.rows(); ++i){
325        // first columns are equal to data in kernel_
326        for (size_t j=0; j<row_index_.size(); ++j){
327          (*data_all)(i,j) = kernel_data.data(i,row_index_[j]);
328          (*weight_all)(i,j) = kernel_data.weight(i,row_index_[j]);
329        }
330      }
331    }
332    else {
333
334        dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
335   
336      for (size_t i=0; i<data.rows(); ++i){
337        // first columns are equal to data in kernel_
338        for (size_t j=0; j<row_index_.size(); ++j)
339          (*data_all)(i,j) = kernel_->data()(i,row_index_[j]);
340      }
341    }
342
343    // last columns are equal to new data
344    for (size_t i=0; i<data.rows(); ++i){
345      for (size_t j=0;j<data.columns(); ++j){
346        (*data_all)(i,j+row_index_.size()) = data.data(i,j);
347        (*weight_all)(i,j+row_index_.size()) = data.weight(i,j);
348      }
349    }
350   
351    std::vector<size_t> column_index;
352    column_index.reserve(data.columns());
353    for (size_t i=0;i<data.columns(); ++i)
354      column_index.push_back(i+row_index_.size());
355    const Kernel* kernel = 
356      kernel_->make_kernel(MatrixLookupWeighted(*data_all, *weight_all, true));
357    return new KernelLookup(*kernel, row_index_, column_index, true);
358  }
359
360
361  const KernelLookup*
362  KernelLookup::training_data(const std::vector<size_t>& train) const
363  {
364    return new KernelLookup(*this,train,train);
365  }
366
367
368  const KernelLookup*
369  KernelLookup::validation_data(const std::vector<size_t>& train,
370                                const std::vector<size_t>& validation) const
371  {
372    return new KernelLookup(*this,train,validation);
373  }
374
375
376  bool KernelLookup::weighted(void) const
377  {
378    return kernel_->weighted();
379  }
380
381
382  double KernelLookup::operator()(size_t row, size_t column) const
383  {
384    return (*kernel_)(row_index_[row],column_index_[column]);
385  }
386
387}}} // of namespace classifier, yat, and theplu
Note: See TracBrowser for help on using the repository browser.