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

Last change on this file since 1090 was 1066, checked in by Peter, 13 years ago

Iterators for KernelLookup? - refs #267

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date ID
File size: 9.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 "../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    : DataLookup2D(own), kernel_(&kernel)
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    : DataLookup2D(row,column,owner), kernel_(&kernel)
54  {
55    // Checking that each row index is less than kernel.rows()
56    assert(row.empty() || 
57           *(std::max_element(row.begin(),row.end()))<kernel_->size());
58    // Checking that each column index is less than kernel.column()
59    assert(column.empty() || 
60           *(std::max_element(column.begin(),column.end()))<kernel_->size());
61  }
62
63
64  KernelLookup::KernelLookup(const KernelLookup& other, 
65                             const std::vector<size_t>& row, 
66                             const std::vector<size_t>& column)
67    : DataLookup2D(other,row,column), kernel_(other.kernel_)
68  {
69    ref_count_=other.ref_count_;
70    if (ref_count_)
71      ++(*ref_count_);
72  }
73 
74
75  KernelLookup::KernelLookup(const KernelLookup& other)
76    : DataLookup2D(other), kernel_(other.kernel_)
77  {
78    // Checking that no index is out of range
79    assert(row_index_.empty() || 
80           *(max_element(row_index_.begin(), row_index_.end()))<
81           kernel_->size());
82    assert(column_index_.empty() || 
83           *(max_element(column_index_.begin(), column_index_.end()))<
84           kernel_->size());
85    ref_count_=other.ref_count_;
86    if (ref_count_)
87      ++(*ref_count_);
88  }
89 
90
91  KernelLookup::KernelLookup(const KernelLookup& other, 
92                             const std::vector<size_t>& index, 
93                             const bool row)
94    : DataLookup2D(other,index,row), kernel_(other.kernel_)
95  {
96    assert(kernel_->size());
97
98    // Checking that no index is out of range
99    assert(row_index_.empty() || 
100           *(max_element(row_index_.begin(), row_index_.end()))<
101           kernel_->size());
102    assert(column_index_.empty() || 
103           *(max_element(column_index_.begin(), column_index_.end()))<
104           kernel_->size());
105    ref_count_=other.ref_count_;
106    if (ref_count_)
107      ++(*ref_count_);
108  }
109 
110
111  KernelLookup::~KernelLookup(void)
112  {
113    if (ref_count_)
114      if (!--(*ref_count_))
115        delete kernel_;
116  }
117
118
119  KernelLookup::const_iterator KernelLookup::begin(void) const
120  {
121    return const_iterator(const_iterator::iterator_type(*this, 0, 0), 1);
122  }
123
124
125  KernelLookup::const_iterator KernelLookup::begin_column(size_t i) const
126  {
127    return const_iterator(const_iterator::iterator_type(*this, 0, i), columns());
128  }
129
130
131  KernelLookup::const_iterator KernelLookup::begin_row(size_t i) const
132  {
133    return const_iterator(const_iterator::iterator_type(*this, i, 0), 1);
134  }
135
136
137  const DataLookup2D* KernelLookup::data(void) const
138  {
139    return kernel_->data().training_data(column_index_);
140  }
141
142
143  double KernelLookup::element(const DataLookup1D& vec, size_t i) const
144  {
145    return kernel_->element(vec, row_index_[i]);
146  }
147
148
149  double KernelLookup::element(const DataLookupWeighted1D& vec, size_t i) const
150  {
151    return kernel_->element(vec, row_index_[i]);
152  }
153
154
155  KernelLookup::const_iterator KernelLookup::end(void) const
156  {
157    return const_iterator(const_iterator::iterator_type(*this, rows(), 0), 1);
158  }
159
160
161  KernelLookup::const_iterator KernelLookup::end_column(size_t i) const
162  {
163    return const_iterator(const_iterator::iterator_type(*this, this->rows(), i),
164                          this->columns());
165  }
166
167
168  KernelLookup::const_iterator KernelLookup::end_row(size_t i) const
169  {
170    return const_iterator(const_iterator::iterator_type(*this, i+1, 0), 1);
171  }
172
173
174  const KernelLookup* 
175  KernelLookup::selected(const std::vector<size_t>& inputs) const
176  {
177    const Kernel* kernel;
178    if (kernel_->weighted()){
179      const MatrixLookupWeighted* ml = 
180        dynamic_cast<const MatrixLookupWeighted*>(data());
181      assert(ml);
182      const MatrixLookupWeighted* ms = 
183        new MatrixLookupWeighted(*ml,inputs,true);
184      kernel = kernel_->make_kernel(*ms, false);
185    }
186    else {
187      const MatrixLookup* m = 
188        dynamic_cast<const MatrixLookup*>(data());
189      assert(m);
190      // matrix with selected features
191      const MatrixLookup* ms = new MatrixLookup(*m,inputs,true);
192      kernel = kernel_->make_kernel(*ms,true);
193    }
194    return new KernelLookup(*kernel, true);
195  }
196
197
198  const KernelLookup* KernelLookup::test_kernel(const MatrixLookup& data) const
199  {
200
201    assert(data.rows()==kernel_->data().rows());
202    if (!weighted()){
203      utility::matrix* data_all = 
204        new utility::matrix(data.rows(), row_index_.size()+data.columns());
205
206      for (size_t i=0; i<data_all->rows(); ++i) {
207
208        // first some columns from data in kernel_
209        for (size_t j=0; j<row_index_.size(); ++j){
210          (*data_all)(i,j) = kernel_->data()(i,row_index_[j]); 
211        }
212       
213        // last columns are equal to new data
214        for (size_t j=0;j<data.columns(); ++j){
215          (*data_all)(i,j+row_index_.size()) = data(i,j);
216        }
217      }
218      std::vector<size_t> column_index;
219      column_index.reserve(data.columns());
220      for (size_t i=0;i<data.columns(); ++i)
221        column_index.push_back(i+row_index_.size());
222
223      std::vector<size_t> row_index;
224      row_index.reserve(row_index_.size());
225      for (size_t i=0;i<row_index_.size(); ++i)
226        row_index.push_back(i);
227
228      const MatrixLookup* tmp = new MatrixLookup(*data_all, true);
229
230      const Kernel* kernel = 
231        kernel_->make_kernel(*tmp, true);
232
233      return new KernelLookup(*kernel, row_index, column_index, true);
234    }
235
236    // kernel_ holds MatrixLookupWeighted, hence new Kernel also
237    // should hold a MatrixLookupweighted.
238    utility::matrix* data_all = 
239      new utility::matrix(data.rows(), rows()+data.columns());
240    utility::matrix* weight_all = 
241      new utility::matrix(data.rows(), rows()+data.columns(), 1.0);
242    const MatrixLookupWeighted& kernel_data = 
243      dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
244
245    for (size_t i=0; i<data.rows(); ++i){
246
247      // first some columns from data in kernel_
248      for (size_t j=0; j<row_index_.size(); ++j){
249        (*data_all)(i,j) = kernel_data.data(i,row_index_[j]); 
250        (*weight_all)(i,j) = kernel_data.weight(i,row_index_[j]);
251      }
252
253      // last columns are equal to new data
254      for (size_t j=0;j<data.columns(); ++j){
255        (*data_all)(i,j+row_index_.size()) = data(i,j);
256      }
257    }
258    std::vector<size_t> column_index;
259    column_index.reserve(data.columns());
260    for (size_t i=0;i<data.columns(); ++i)
261      column_index.push_back(i+row_index_.size());
262
263    std::vector<size_t> row_index;
264    row_index.reserve(row_index_.size());
265    for (size_t i=0;i<row_index_.size(); ++i)
266      row_index.push_back(i);
267
268    MatrixLookupWeighted* tmp = new MatrixLookupWeighted(*data_all, 
269                                                         *weight_all, true);
270    const Kernel* kernel = kernel_->make_kernel(*tmp, true);
271    return new KernelLookup(*kernel, row_index_, column_index, true);
272  }
273
274
275
276  const KernelLookup* 
277  KernelLookup::test_kernel(const MatrixLookupWeighted& data) const
278  {
279    utility::matrix* data_all = 
280      new utility::matrix(data.rows(), rows()+data.columns());
281    utility::matrix* weight_all = 
282      new utility::matrix(data.rows(), rows()+data.columns(), 1.0);
283
284    if (weighted()){
285      const MatrixLookupWeighted& kernel_data = 
286        dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
287   
288      for (size_t i=0; i<data.rows(); ++i){
289        // first columns are equal to data in kernel_
290        for (size_t j=0; j<row_index_.size(); ++j){
291          (*data_all)(i,j) = kernel_data.data(i,row_index_[j]);
292          (*weight_all)(i,j) = kernel_data.weight(i,row_index_[j]);
293        }
294      }
295    }
296    else {
297
298        dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
299   
300      for (size_t i=0; i<data.rows(); ++i){
301        // first columns are equal to data in kernel_
302        for (size_t j=0; j<row_index_.size(); ++j)
303          (*data_all)(i,j) = kernel_->data()(i,row_index_[j]);
304      }
305    }
306
307    // last columns are equal to new data
308    for (size_t i=0; i<data.rows(); ++i){
309      for (size_t j=0;j<data.columns(); ++j){
310        (*data_all)(i,j+row_index_.size()) = data.data(i,j);
311        (*weight_all)(i,j+row_index_.size()) = data.weight(i,j);
312      }
313    }
314   
315    std::vector<size_t> column_index;
316    column_index.reserve(data.columns());
317    for (size_t i=0;i<data.columns(); ++i)
318      column_index.push_back(i+row_index_.size());
319    const Kernel* kernel = 
320      kernel_->make_kernel(MatrixLookupWeighted(*data_all, *weight_all, true));
321    return new KernelLookup(*kernel, row_index_, column_index, true);
322  }
323
324
325  const KernelLookup*
326  KernelLookup::training_data(const std::vector<size_t>& train) const
327  {
328    return new KernelLookup(*this,train,train);
329  }
330
331
332  const KernelLookup*
333  KernelLookup::validation_data(const std::vector<size_t>& train,
334                                const std::vector<size_t>& validation) const
335  {
336    return new KernelLookup(*this,train,validation);
337  }
338
339
340  bool KernelLookup::weighted(void) const
341  {
342    return kernel_->weighted();
343  }
344
345
346  double KernelLookup::operator()(size_t row, size_t column) const
347  {
348    return (*kernel_)(row_index_[row],column_index_[column]);
349  }
350
351}}} // of namespace classifier, yat, and theplu
Note: See TracBrowser for help on using the repository browser.