SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CombinedDotFeatures.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2009-2010 Soeren Sonnenburg
8  * Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  * Copyright (C) 2010 Berlin Institute of Technology
10  */
11 
13 #include <shogun/io/SGIO.h>
15 
16 using namespace shogun;
17 
19 {
20  init();
21 
22  feature_list=new CList(true);
24 }
25 
27 : CDotFeatures(orig), num_vectors(orig.num_vectors),
28  num_dimensions(orig.num_dimensions)
29 {
30  init();
31 
32  feature_list=new CList(true);
33 }
34 
36 {
37  return new CCombinedDotFeatures(*this);
38 }
39 
41 {
42  delete feature_list;
43 }
44 
46 {
47  SG_INFO( "BEGIN COMBINED DOTFEATURES LIST (%d, %d) - ", num_vectors, num_dimensions);
48  this->list_feature_obj();
49 
50  CListElement* current = NULL ;
52 
53  while (f)
54  {
55  f->list_feature_obj();
56  f=get_next_feature_obj(current);
57  }
58 
59  SG_INFO( "END COMBINED DOTFEATURES LIST (%d, %d) - ", num_vectors, num_dimensions);
60  this->list_feature_obj();
61 }
62 
64 {
65  CListElement* current = NULL ;
67 
68  int32_t dim=0;
69  int32_t vec=-1;
70 
71  while (f)
72  {
73  dim+= f->get_dim_feature_space();
74  if (vec==-1)
75  vec=f->get_num_vectors();
76  else if (vec != f->get_num_vectors())
77  {
78  f->list_feature_obj();
79  SG_ERROR("Number of vectors (%d) mismatches in above feature obj (%d)\n", vec, f->get_num_vectors());
80  }
81 
82  SG_UNREF(f);
83 
84  f=get_next_feature_obj(current);
85  }
86 
87  num_dimensions=dim;
88  num_vectors=vec;
89  SG_DEBUG("vecs=%d, dims=%d\n", num_vectors, num_dimensions);
90 }
91 
92 float64_t CCombinedDotFeatures::dot(int32_t vec_idx1, CDotFeatures* df, int32_t vec_idx2)
93 {
94  float64_t result=0;
95 
96  ASSERT(df);
100 
101  CListElement* current1 = NULL;
102  CDotFeatures* f1=get_first_feature_obj(current1);
103 
104  CListElement* current2 = NULL;
105  CDotFeatures* f2=cf->get_first_feature_obj(current2);
106 
107  while (f1 && f2)
108  {
109  result += f1->dot(vec_idx1, f2,vec_idx2) *
112 
113  SG_UNREF(f1);
114  SG_UNREF(f2);
115  f1=get_next_feature_obj(current1);
116  f2=cf->get_next_feature_obj(current2);
117  }
118 
119  // check that both have same number of feature objects inside
120  ASSERT(f1 == NULL && f2 == NULL);
121 
122  return result;
123 }
124 
125 float64_t CCombinedDotFeatures::dense_dot(int32_t vec_idx1, const float64_t* vec2, int32_t vec2_len)
126 {
127  float64_t result=0;
128 
129  CListElement* current = NULL ;
131  uint32_t offs=0;
132 
133  while (f)
134  {
135  int32_t dim = f->get_dim_feature_space();
136  result += f->dense_dot(vec_idx1, vec2+offs, dim)*f->get_combined_feature_weight();
137  offs += dim;
138 
139  SG_UNREF(f);
140  f=get_next_feature_obj(current);
141  }
142 
143  return result;
144 }
145 
146 void CCombinedDotFeatures::dense_dot_range(float64_t* output, int32_t start, int32_t stop, float64_t* alphas, float64_t* vec, int32_t dim, float64_t b)
147 {
148  if (stop<=start)
149  return;
150  ASSERT(dim==num_dimensions);
151 
152  CListElement* current = NULL;
154  uint32_t offs=0;
155  bool first=true;
156  int32_t num=stop-start;
157  float64_t* tmp=SG_MALLOC(float64_t, num);
158 
159  while (f)
160  {
161  int32_t f_dim = f->get_dim_feature_space();
162  if (first)
163  {
164  f->dense_dot_range(output, start, stop, alphas, vec+offs, f_dim, b);
165  first=false;
166  }
167  else
168  {
169  f->dense_dot_range(tmp, start, stop, alphas, vec+offs, f_dim, b);
170  for (int32_t i=0; i<num; i++)
171  output[i]+=tmp[i];
172  }
173  offs += f_dim;
174 
175  SG_UNREF(f);
176  f=get_next_feature_obj(current);
177  }
178  SG_FREE(tmp);
179 }
180 
181 void CCombinedDotFeatures::dense_dot_range_subset(int32_t* sub_index, int32_t num, float64_t* output, float64_t* alphas, float64_t* vec, int32_t dim, float64_t b)
182 {
183  if (num<=0)
184  return;
185  ASSERT(dim==num_dimensions);
186 
187  CListElement* current = NULL;
189  uint32_t offs=0;
190  bool first=true;
191  float64_t* tmp=SG_MALLOC(float64_t, num);
192 
193  while (f)
194  {
195  int32_t f_dim = f->get_dim_feature_space();
196  if (first)
197  {
198  f->dense_dot_range_subset(sub_index, num, output, alphas, vec+offs, f_dim, b);
199  first=false;
200  }
201  else
202  {
203  f->dense_dot_range_subset(sub_index, num, tmp, alphas, vec+offs, f_dim, b);
204  for (int32_t i=0; i<num; i++)
205  output[i]+=tmp[i];
206  }
207  offs += f_dim;
208 
209  SG_UNREF(f);
210  f=get_next_feature_obj(current);
211  }
212  SG_FREE(tmp);
213 }
214 
215 void CCombinedDotFeatures::add_to_dense_vec(float64_t alpha, int32_t vec_idx1, float64_t* vec2, int32_t vec2_len, bool abs_val)
216 {
217  CListElement* current = NULL ;
219  uint32_t offs=0;
220 
221  while (f)
222  {
223  int32_t dim = f->get_dim_feature_space();
224  f->add_to_dense_vec(alpha*f->get_combined_feature_weight(), vec_idx1, vec2+offs, dim, abs_val);
225  offs += dim;
226 
227  SG_UNREF(f);
228  f=get_next_feature_obj(current);
229  }
230 }
231 
233 {
234  combined_feature_iterator* it=SG_MALLOC(combined_feature_iterator, 1);
235 
236  it->current=NULL;
237  it->f=get_first_feature_obj(it->current);
238  it->iterator=it->f->get_feature_iterator(vector_index);
239  it->vector_index=vector_index;
240  return it;
241 }
242 
243 bool CCombinedDotFeatures::get_next_feature(int32_t& index, float64_t& value, void* iterator)
244 {
245  ASSERT(iterator);
246  combined_feature_iterator* it = (combined_feature_iterator*) iterator;
247 
248  while (it->f)
249  {
250  if (it->f->get_next_feature(index, value, it->iterator))
251  {
253  return true;
254  }
255 
256  it->f->free_feature_iterator(it->iterator);
257  it->f=get_next_feature_obj(it->current);
258  if (it->f)
259  it->iterator=it->f->get_feature_iterator(it->vector_index);
260  else
261  it->iterator=NULL;
262  }
263  return false;
264 }
265 
267 {
268  if (iterator)
269  {
270  combined_feature_iterator* it = (combined_feature_iterator*) iterator;
271  if (it->iterator && it->f)
272  it->f->free_feature_iterator(it->iterator);
273  SG_FREE(it);
274  }
275 }
276 
278 {
280 }
281 
283 {
284  return (CDotFeatures*) feature_list->get_first_element(current);
285 }
286 
288 {
290 }
291 
293 {
294  return (CDotFeatures*) feature_list->get_next_element(current);
295 }
296 
298 {
300 }
301 
303 {
304  ASSERT(obj);
305  bool result=feature_list->insert_element(obj);
307  return result;
308 }
309 
311 {
312  ASSERT(obj);
313  bool result=feature_list->append_element(obj);
315  return result;
316 }
317 
319 {
321  if (f)
322  {
323  SG_UNREF(f);
325  return true;
326  }
327  else
328  return false;
329 }
330 
332 {
333  return feature_list->get_num_elements();
334 }
335 
337 {
338  CListElement* current = NULL ;
340  int32_t result=0;
341 
342  while (f)
343  {
344  result+=f->get_nnz_features_for_vector(num);
345 
346  SG_UNREF(f);
347  f=get_next_feature_obj(current);
348  }
349 
350  return result;
351 }
352 
354 {
355  int32_t num_weights = get_num_feature_obj();
356  ASSERT(num_weights > 0);
357 
358  float64_t* weights=SG_MALLOC(float64_t, num_weights);
359 
360  CListElement* current = NULL;
361  CDotFeatures* f = get_first_feature_obj(current);
362 
363  int32_t i = 0;
364  while (f)
365  {
366  weights[i] = f->get_combined_feature_weight();
367 
368  SG_UNREF(f);
369  f = get_next_feature_obj(current);
370  i++;
371  }
372  return SGVector<float64_t>(weights,num_weights);
373 }
374 
376 {
377  int32_t i = 0;
378  CListElement* current = NULL ;
379  CDotFeatures* f = get_first_feature_obj(current);
380 
381  ASSERT(weights.vlen==get_num_feature_obj());
382 
383  while(f)
384  {
385  f->set_combined_feature_weight(weights[i]);
386 
387  SG_UNREF(f);
388  f = get_next_feature_obj(current);
389  i++;
390  }
391 }
392 
393 void CCombinedDotFeatures::init()
394 {
395  m_parameters->add(&num_dimensions, "num_dimensions",
396  "Total number of dimensions.");
397  m_parameters->add(&num_vectors, "num_vectors",
398  "Total number of vectors.");
400  "feature_list", "Feature list.");
401 }
402 

SHOGUN Machine Learning Toolbox - Documentation