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

Last change on this file since 1000 was 1000, checked in by Jari Häkkinen, 14 years ago

trac moved to new location.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date ID
File size: 8.9 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  const DataLookup2D* KernelLookup::data(void) const
120  {
121    return kernel_->data().training_data(column_index_);
122  }
123
124
125  double KernelLookup::element(const DataLookup1D& vec, size_t i) const
126  {
127    return kernel_->element(vec, row_index_[i]);
128  }
129
130
131  double KernelLookup::element(const DataLookupWeighted1D& vec, size_t i) const
132  {
133    return kernel_->element(vec, row_index_[i]);
134  }
135
136
137  const KernelLookup* 
138  KernelLookup::selected(const std::vector<size_t>& inputs) const
139  {
140    const Kernel* kernel;
141    if (kernel_->weighted()){
142      const MatrixLookupWeighted* ml = 
143        dynamic_cast<const MatrixLookupWeighted*>(data());
144      assert(ml);
145      const MatrixLookupWeighted* ms = 
146        new MatrixLookupWeighted(*ml,inputs,true);
147      kernel = kernel_->make_kernel(*ms, false);
148    }
149    else {
150      const MatrixLookup* m = 
151        dynamic_cast<const MatrixLookup*>(data());
152      assert(m);
153      // matrix with selected features
154      const MatrixLookup* ms = new MatrixLookup(*m,inputs,true);
155      kernel = kernel_->make_kernel(*ms,true);
156    }
157    return new KernelLookup(*kernel, true);
158  }
159
160
161  const KernelLookup* KernelLookup::test_kernel(const MatrixLookup& data) const
162  {
163
164    assert(data.rows()==kernel_->data().rows());
165    if (!weighted()){
166      utility::matrix* data_all = 
167        new utility::matrix(data.rows(), row_index_.size()+data.columns());
168
169      for (size_t i=0; i<data_all->rows(); ++i) {
170
171        // first some columns from data in kernel_
172        for (size_t j=0; j<row_index_.size(); ++j){
173          (*data_all)(i,j) = kernel_->data()(i,row_index_[j]); 
174        }
175       
176        // last columns are equal to new data
177        for (size_t j=0;j<data.columns(); ++j){
178          (*data_all)(i,j+row_index_.size()) = data(i,j);
179        }
180      }
181      std::vector<size_t> column_index;
182      column_index.reserve(data.columns());
183      for (size_t i=0;i<data.columns(); ++i)
184        column_index.push_back(i+row_index_.size());
185
186      std::vector<size_t> row_index;
187      row_index.reserve(row_index_.size());
188      for (size_t i=0;i<row_index_.size(); ++i)
189        row_index.push_back(i);
190
191      const MatrixLookup* tmp = new MatrixLookup(*data_all, true);
192
193      const Kernel* kernel = 
194        kernel_->make_kernel(*tmp, true);
195
196      return new KernelLookup(*kernel, row_index, column_index, true);
197    }
198
199    // kernel_ holds MatrixLookupWeighted, hence new Kernel also
200    // should hold a MatrixLookupweighted.
201    utility::matrix* data_all = 
202      new utility::matrix(data.rows(), rows()+data.columns());
203    utility::matrix* weight_all = 
204      new utility::matrix(data.rows(), rows()+data.columns(), 1.0);
205    const MatrixLookupWeighted& kernel_data = 
206      dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
207
208    for (size_t i=0; i<data.rows(); ++i){
209
210      // first some columns from data in kernel_
211      for (size_t j=0; j<row_index_.size(); ++j){
212        (*data_all)(i,j) = kernel_data.data(i,row_index_[j]); 
213        (*weight_all)(i,j) = kernel_data.weight(i,row_index_[j]);
214      }
215
216      // last columns are equal to new data
217      for (size_t j=0;j<data.columns(); ++j){
218        (*data_all)(i,j+row_index_.size()) = data(i,j);
219      }
220    }
221    std::vector<size_t> column_index;
222    column_index.reserve(data.columns());
223    for (size_t i=0;i<data.columns(); ++i)
224      column_index.push_back(i+row_index_.size());
225
226    std::vector<size_t> row_index;
227    row_index.reserve(row_index_.size());
228    for (size_t i=0;i<row_index_.size(); ++i)
229      row_index.push_back(i);
230
231    MatrixLookupWeighted* tmp = new MatrixLookupWeighted(*data_all, 
232                                                         *weight_all, true);
233    const Kernel* kernel = kernel_->make_kernel(*tmp, true);
234    return new KernelLookup(*kernel, row_index_, column_index, true);
235  }
236
237
238
239  const KernelLookup* 
240  KernelLookup::test_kernel(const MatrixLookupWeighted& data) const
241  {
242    utility::matrix* data_all = 
243      new utility::matrix(data.rows(), rows()+data.columns());
244    utility::matrix* weight_all = 
245      new utility::matrix(data.rows(), rows()+data.columns(), 1.0);
246
247    if (weighted()){
248      const MatrixLookupWeighted& kernel_data = 
249        dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
250   
251      for (size_t i=0; i<data.rows(); ++i){
252        // first columns are equal to data in kernel_
253        for (size_t j=0; j<row_index_.size(); ++j){
254          (*data_all)(i,j) = kernel_data.data(i,row_index_[j]);
255          (*weight_all)(i,j) = kernel_data.weight(i,row_index_[j]);
256        }
257      }
258    }
259    else {
260
261        dynamic_cast<const MatrixLookupWeighted&>(kernel_->data());
262   
263      for (size_t i=0; i<data.rows(); ++i){
264        // first columns are equal to data in kernel_
265        for (size_t j=0; j<row_index_.size(); ++j)
266          (*data_all)(i,j) = kernel_->data()(i,row_index_[j]);
267      }
268    }
269
270    // last columns are equal to new data
271    for (size_t i=0; i<data.rows(); ++i){
272      for (size_t j=0;j<data.columns(); ++j){
273        (*data_all)(i,j+row_index_.size()) = data.data(i,j);
274        (*weight_all)(i,j+row_index_.size()) = data.weight(i,j);
275      }
276    }
277   
278    std::vector<size_t> column_index;
279    column_index.reserve(data.columns());
280    for (size_t i=0;i<data.columns(); ++i)
281      column_index.push_back(i+row_index_.size());
282    const Kernel* kernel = 
283      kernel_->make_kernel(MatrixLookupWeighted(*data_all, *weight_all, true));
284    return new KernelLookup(*kernel, row_index_, column_index, true);
285  }
286
287
288  const KernelLookup*
289  KernelLookup::training_data(const std::vector<size_t>& train) const
290  {
291    return new KernelLookup(*this,train,train);
292  }
293
294
295  const KernelLookup*
296  KernelLookup::validation_data(const std::vector<size_t>& train,
297                                const std::vector<size_t>& validation) const
298  {
299    return new KernelLookup(*this,train,validation);
300  }
301
302
303  bool KernelLookup::weighted(void) const
304  {
305    return kernel_->weighted();
306  }
307
308
309  double KernelLookup::operator()(size_t row, size_t column) const
310  {
311    return (*kernel_)(row_index_[row],column_index_[column]);
312  }
313
314}}} // of namespace classifier, yat, and theplu
Note: See TracBrowser for help on using the repository browser.