SHOGUN  v2.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ANOVAKernel.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) 2011 Andrew Tereskin
8  * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
9  */
10 
11 #include <math.h>
14 
15 using namespace shogun;
16 
17 CANOVAKernel::CANOVAKernel(): CDotKernel(0), cardinality(1.0)
18 {
19  init();
21 }
22 
23 CANOVAKernel::CANOVAKernel(int32_t cache, int32_t d)
24 : CDotKernel(cache), cardinality(d)
25 {
26  init();
28 }
29 
31  CDenseFeatures<float64_t>* l, CDenseFeatures<float64_t>* r, int32_t d, int32_t cache)
32  : CDotKernel(cache), cardinality(d)
33 {
34  init();
36  init(l, r);
37 }
38 
40 {
41  cleanup();
42 }
43 
45 {
46  cleanup();
47 
48  bool result = CDotKernel::init(l,r);
49 
52  return result;
53 }
54 
55 float64_t CANOVAKernel::compute(int32_t idx_a, int32_t idx_b)
56 {
57  return compute_rec1(idx_a, idx_b);
58 }
59 
60 float64_t CANOVAKernel::compute_rec1(int32_t idx_a, int32_t idx_b)
61 {
62  int32_t alen, blen;
63  bool afree, bfree;
64 
65  float64_t* avec=
66  ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a, alen, afree);
67  float64_t* bvec=
68  ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b, blen, bfree);
69  ASSERT(alen==blen);
70 
71  float64_t result = compute_recursive1(avec, bvec, alen);
72 
73  ((CDenseFeatures<float64_t>*) lhs)->free_feature_vector(avec, idx_a, afree);
74  ((CDenseFeatures<float64_t>*) rhs)->free_feature_vector(bvec, idx_b, bfree);
75 
76  return result;
77 }
78 
79 float64_t CANOVAKernel::compute_rec2(int32_t idx_a, int32_t idx_b)
80 {
81  int32_t alen, blen;
82  bool afree, bfree;
83 
84  float64_t* avec=
85  ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a, alen, afree);
86  float64_t* bvec=
87  ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b, blen, bfree);
88  ASSERT(alen==blen);
89 
90  float64_t result = compute_recursive2(avec, bvec, alen);
91 
92  ((CDenseFeatures<float64_t>*) lhs)->free_feature_vector(avec, idx_a, afree);
93  ((CDenseFeatures<float64_t>*) rhs)->free_feature_vector(bvec, idx_b, bfree);
94 
95  return result;
96 }
97 
99 {
101  DP=NULL;
102 
104  KD=NULL;
105  KS=NULL;
106  vec_pow=NULL;
107 }
108 
110 {
111  cleanup();
112 
113  ASSERT(lhs && rhs);
114  int32_t num_feat = ((CDenseFeatures<float64_t>*) lhs)->get_num_features();
115  ASSERT(num_feat == ((CDenseFeatures<float64_t>*) rhs)->get_num_features());
116 
117  //compute_recursive1
118  DP_len=(cardinality+1)*(num_feat+1);
120 
121  //compute_recursive2
124  vec_pow = SG_MALLOC(float64_t, num_feat);
125 }
126 
128 {
129  //compute_recursive1
130  SG_FREE(DP);
131  DP=NULL;
132  DP_len=0;
133 
134  //compute_recursive2
135  SG_FREE(KD);
136  KD=NULL;
137  SG_FREE(KS);
138  KS=NULL;
139  SG_FREE(vec_pow);
140  vec_pow=NULL;
141 }
142 
144 {
146  allocate_arrays();
147 }
148 
150 {
151  SG_ADD(&cardinality, "cardinality", "Kernel cardinality.", MS_AVAILABLE);
152 }
153 
154 
155 float64_t CANOVAKernel::compute_recursive1(float64_t* avec, float64_t* bvec, int32_t len)
156 {
157  ASSERT(DP);
158  int32_t d=cardinality;
159  int32_t offs=cardinality+1;
160 
161  ASSERT(DP_len==(len+1)*offs);
162 
163  for (int32_t j=0; j < len+1; j++)
164  DP[j] = 1.0;
165 
166  for (int32_t k=1; k < d+1; k++)
167  {
168  // TRAP d>len case
169  if (k-1>=len)
170  return 0.0;
171 
172  DP[k*offs+k-1] = 0;
173  for (int32_t j=k; j < len+1; j++)
174  DP[k*offs+j]=DP[k*offs+j-1]+avec[j-1]*bvec[j-1]*DP[(k-1)*offs+j-1];
175  }
176 
177  float64_t result=DP[d*offs+len];
178 
179  return result;
180 }
181 
182 float64_t CANOVAKernel::compute_recursive2(float64_t* avec, float64_t* bvec, int32_t len)
183 {
184  ASSERT(vec_pow);
185  ASSERT(KS);
186  ASSERT(KD);
187 
188  int32_t d=cardinality;
189  for (int32_t i=0; i < len; i++)
190  vec_pow[i] = 1;
191 
192  for (int32_t k=1; k < d+1; k++)
193  {
194  KS[k] = 0;
195  for (int32_t i=0; i < len; i++)
196  {
197  vec_pow[i] *= avec[i]*bvec[i];
198  KS[k] += vec_pow[i];
199  }
200  }
201 
202  KD[0] = 1;
203  for (int32_t k=1; k < d+1; k++)
204  {
205  float64_t sum = 0;
206  for (int32_t s=1; s < k+1; s++)
207  {
208  float64_t sign = 1.0;
209  if (s % 2 == 0)
210  sign = -1.0;
211 
212  sum += sign*KD[k-s]*KS[s];
213  }
214 
215  KD[k] = sum / k;
216  }
217  float64_t result=KD[d];
218 
219  return result;
220 }

SHOGUN Machine Learning Toolbox - Documentation