SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PyramidChi2.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) 2008-2009 Alexander Binder
8  * Copyright (C) 1999-2009 Fraunhofer Institute FIRST and Max-Planck-Society
9  */
10 
12 #include <shogun/lib/common.h>
15 #include <shogun/io/SGIO.h>
17 
18 using namespace shogun;
19 
21 : weights(NULL)
22 {
23  // this will produce an erro in kernel computation!
24  num_cells=0;
26  width=1;
28 }
29 
31  int32_t size, int32_t num_cells2,
32  float64_t* weights_foreach_cell2,
33  int32_t width_computation_type2,
34  float64_t width2)
35 : CDotKernel(size), num_cells(num_cells2),weights(NULL),
36 width_computation_type(width_computation_type2), width(width2),
37  num_randfeats_forwidthcomputation(-1)
38 {
39  if(num_cells<=0)
40  SG_ERROR("CPyramidChi2 Constructor fatal error: parameter num_cells2 NOT positive")
41  weights=SG_MALLOC(float64_t, num_cells);
42  if(weights_foreach_cell2)
43  {
44  for (int32_t i=0; i<num_cells; ++i)
45  weights[i]=weights_foreach_cell2[i];
46  }
47  else
48  { for (int32_t i=0; i<num_cells; ++i)
49  weights[i]=1;
50  }
51 
53  {
55  width=-1;
56  }
57 
58 
59 }
60 
62 {
63  // this will produce an erro in kernel computation!
64  num_cells=0;
66  width=1;
67 
69 
70  SG_FREE(weights);
71  weights=NULL;
72 
74 }
75 
76 bool CPyramidChi2::init(CFeatures* l, CFeatures* r)
77 {
78  CDotKernel::init(l, r);
79  return init_normalizer();
80 }
81 
84  int32_t size, int32_t num_cells2,
85  float64_t* weights_foreach_cell2,
86  int32_t width_computation_type2,
87  float64_t width2)
88 : CDotKernel(size), num_cells(num_cells2), weights(NULL),
89 width_computation_type(width_computation_type2), width(width2),
90  num_randfeats_forwidthcomputation(-1)
91 {
92  if(num_cells<=0)
93  SG_ERROR("CPyramidChi2 Constructor fatal error: parameter num_cells2 NOT positive")
94  weights=SG_MALLOC(float64_t, num_cells);
95  if(weights_foreach_cell2)
96  {
97  for (int32_t i=0; i<num_cells; ++i)
98  weights[i]=weights_foreach_cell2[i];
99  }
100  else
101  { for (int32_t i=0; i<num_cells; ++i)
102  weights[i]=1;
103  }
104 
105  if (width_computation_type>0 )
106  {
108  width=-1;
109  }
110 
111  init(l, r);
112 }
113 
115 {
116  cleanup();
117 }
118 
119 
120 
121 float64_t CPyramidChi2::compute(int32_t idx_a, int32_t idx_b)
122 {
123 
124  if(num_cells<=0)
125  SG_ERROR("CPyramidChi2::compute(...) fatal error: parameter num_cells NOT positive")
126 
127  int32_t alen, blen;
128  bool afree, bfree;
129 
130  float64_t* avec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a,
131  alen, afree);
132  float64_t* bvec=((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b,
133  blen, bfree);
134  if(alen!=blen)
135  SG_ERROR("CPyramidChi2::compute(...) fatal error: lhs feature dim != rhs feature dim")
136 
137  int32_t dims=alen/num_cells;
138 
139 
140  if(width<=0)
141  {
143  {
144 
145  //compute width
146  int32_t numind;
147 
149  {
151  }
152  else
153  {
154  numind= ((CDenseFeatures<float64_t>*) lhs)->get_num_vectors();
155  }
156  float64_t* featindices = SG_MALLOC(float64_t, numind);
157 
159  {
160  for(int32_t i=0; i< numind;++i)
161  featindices[i]=CMath::random(0, ((CDenseFeatures<float64_t>*) lhs)->get_num_vectors()-1);
162  }
163  else
164  {
165  for(int32_t i=0; i< numind;++i)
166  featindices[i]=i;
167  }
168 
169 
170  width=0;
171 
172  //get avec, get bvec only from lhs, do not free
173  for (int32_t li=0; li < numind;++li)
174  {
175  avec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(featindices[li],
176  alen, afree);
177  for (int32_t ri=0; ri <=li;++ri)
178  {
179  // lhs is right here!!!
180  bvec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(featindices[ri],
181  blen, bfree);
182 
183  float64_t result=0;
184  for (int32_t histoind=0; histoind<num_cells; ++histoind)
185  {
186  float64_t curweight=weights[histoind];
187 
188  for (int32_t i=0; i< dims; ++i)
189  {
190  int32_t index= histoind*dims+i;
191  if(avec[index] + bvec[index]>0)
192  {
193  result+= curweight*(avec[index] - bvec[index])*(avec[index]
194  - bvec[index])/(avec[index] + bvec[index]);
195  }
196  }
197  }
198  width+=result*2.0/((double)numind)/(numind+1.0);
199  }
200 
201  }
202  SG_FREE(featindices);
203  }
204  else
205  {
206  SG_ERROR("CPyramidChi2::compute(...) fatal error: width<=0")
207  }
208  }
209 
210 
211  //the actual kernel computation
212  avec=((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a,
213  alen, afree);
214  bvec=((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b,
215  blen, bfree);
216 
217  float64_t result=0;
218  for (int32_t histoind=0; histoind<num_cells; ++histoind)
219  {
220  float64_t curweight=weights[histoind];
221 
222  for (int32_t i=0; i< dims; ++i)
223  {
224  int32_t index= histoind*dims+i;
225  if(avec[index] + bvec[index]>0)
226  {
227  result+= curweight*(avec[index] - bvec[index])*(avec[index]
228  - bvec[index])/(avec[index] + bvec[index]);
229  }
230  }
231  }
232  result= CMath::exp(-result/width);
233 
234 
235  ((CDenseFeatures<float64_t>*) lhs)->free_feature_vector(avec, idx_a, afree);
236  ((CDenseFeatures<float64_t>*) rhs)->free_feature_vector(bvec, idx_b, bfree);
237 
238  return (result);
239 }
240 
241 void CPyramidChi2::setparams_pychi2(int32_t num_cells2,
242  float64_t* weights_foreach_cell2,
243  int32_t width_computation_type2,
244  float64_t width2)
245 {
246  num_cells=num_cells2;
247  width_computation_type=width_computation_type2;
248  width=width2;
250 
251  if(num_cells<=0)
252  SG_ERROR("CPyramidChi2::setparams_pychi2(...) fatal error: parameter num_cells2 NOT positive")
253  if(weights)
254  SG_FREE(weights);
255  weights=SG_MALLOC(float64_t, num_cells);
256  if(weights_foreach_cell2)
257  {
258  for (int32_t i=0; i<num_cells; ++i)
259  weights[i]=weights_foreach_cell2[i];
260  }
261  else
262  { for (int32_t i=0; i<num_cells; ++i)
263  weights[i]=1;
264  }
265 
266  if (width_computation_type>0 )
267  {
269  width=-1;
270  }
271 }

SHOGUN Machine Learning Toolbox - Documentation