SHOGUN  6.0.0
ExponentialARDKernel.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) 2015 Wu Lin
8  * Written (W) 2012 Jacob Walker
9  *
10  * Adapted from WeightedDegreeRBFKernel.cpp
11  */
12 
18 
19 using namespace shogun;
20 
22 {
23  init();
24 }
25 
27 {
29 }
30 
31 void CExponentialARDKernel::init()
32 {
34 
37 
38  m_weights_rows=1.0;
39  m_weights_cols=1.0;
40 
41 
42  SG_ADD(&m_log_weights, "log_weights", "Feature weights in log domain", MS_AVAILABLE,
44 
45  SG_ADD(&m_weights_rows, "weights_rows", "Row of feature weights", MS_NOT_AVAILABLE);
46  SG_ADD(&m_weights_cols, "weights_cols", "Column of feature weights", MS_NOT_AVAILABLE);
47  SG_ADD((int *)(&m_ARD_type), "type", "ARD kernel type", MS_NOT_AVAILABLE);
48 
50  SG_ADD(&m_weights_raw, "weights_raw", "Features weights in standard domain", MS_NOT_AVAILABLE);
51 
52 }
53 
55 {
56  REQUIRE(hs, "Features not set!\n");
57  CDenseFeatures<float64_t> * dense_hs=dynamic_cast<CDenseFeatures<float64_t> *>(hs);
58  if (dense_hs)
59  return dense_hs->get_feature_vector(idx);
60 
61  CDotFeatures * dot_hs=dynamic_cast<CDotFeatures *>(hs);
62  REQUIRE(dot_hs, "Kernel only supports DotFeatures\n");
63  return dot_hs->get_computed_dot_feature_vector(idx);
64 
65 }
66 
67 
69 {
70  REQUIRE(weights.num_rows>0 && weights.num_cols>0, "Weights matrix is non-empty\n");
71  if (weights.num_rows==1)
72  {
73  if(weights.num_cols>1)
74  {
75  SGVector<float64_t> vec(weights.matrix,weights.num_cols,false);
76  set_vector_weights(vec);
77  }
78  else
79  set_scalar_weights(weights[0]);
80  }
81  else
82  set_matrix_weights(weights);
83 }
84 
86 {
88  {
90  {
93  [ ](float64_t& value)
94  {
95  return CMath::exp(value);
96  });
97  }
98  else if (m_ARD_type==KT_FULL)
99  {
102  index_t offset=0;
103  for (int i=0;i<m_weights_raw.num_cols && i<m_weights_raw.num_rows;i++)
104  {
106  std::copy(m_log_weights.vector+offset,m_log_weights.vector+offset+m_weights_raw.num_rows-i,begin+i);
107  begin[i]=CMath::exp(begin[i]);
108  offset+=m_weights_raw.num_rows-i;
109  }
110  }
111  else
112  {
113  SG_ERROR("Unsupported ARD type\n");
114  }
116  }
117 }
118 
120 {
123 }
124 
126 {
127  REQUIRE(weight>0, "Scalar (%f) weight should be positive\n",weight);
131 
132  m_weights_rows=1.0;
133  m_weights_cols=1.0;
134 }
135 
137 {
138  REQUIRE(rhs==NULL && lhs==NULL,
139  "Setting vector weights must be before initialize features\n");
140  REQUIRE(weights.vlen>0, "Vector weight should be non-empty\n");
142  for(index_t i=0; i<weights.vlen; i++)
143  {
144  REQUIRE(weights[i]>0, "Each entry of vector weight (v[%d]=%f) should be positive\n",
145  i,weights[i]);
146  m_log_weights[i]=CMath::log(weights[i]);
147  }
149 
150  m_weights_rows=1.0;
151  m_weights_cols=weights.vlen;
152 }
153 
155 {
156  REQUIRE(rhs==NULL && lhs==NULL,
157  "Setting matrix weights must be before initialize features\n");
158  REQUIRE(weights.num_cols>0, "Matrix weight should be non-empty");
159  REQUIRE(weights.num_rows>=weights.num_cols,
160  "Number of row (%d) must be not less than number of column (%d)",
161  weights.num_rows, weights.num_cols);
162 
163  m_weights_rows=weights.num_rows;
164  m_weights_cols=weights.num_cols;
168 
169  index_t offset=0;
170  for (int i=0; i<weights.num_cols && i<weights.num_rows; i++)
171  {
172  float64_t* begin=weights.get_column_vector(i);
173  REQUIRE(begin[i]>0, "The diagonal entry of matrix weight (w(%d,%d)=%f) should be positive\n",
174  i,i,begin[i]);
175  std::copy(begin+i,begin+weights.num_rows,m_log_weights.vector+offset);
176  m_log_weights[offset]=CMath::log(m_log_weights[offset]);
177  offset+=weights.num_rows-i;
178  }
179 }
180 
182 {
183  init();
184 }
185 
187  CDotFeatures* r, int32_t size) : CDotKernel(size)
188 {
189  init();
190  init(l,r);
191 }
192 
193 bool CExponentialARDKernel::init(CFeatures* l, CFeatures* r)
194 {
195  cleanup();
196  CDotKernel::init(l, r);
197  int32_t dim=((CDotFeatures*) l)->get_dim_feature_space();
198  if (m_ARD_type==KT_FULL)
199  {
200  REQUIRE(m_weights_rows==dim, "Dimension mismatch between features (%d) and weights (%d)\n",
201  dim, m_weights_rows);
202  }
203  else if (m_ARD_type==KT_DIAG)
204  {
205  REQUIRE(m_log_weights.vlen==dim, "Dimension mismatch between features (%d) and weights (%d)\n",
206  dim, m_log_weights.vlen);
207  }
208  return init_normalizer();
209 }
210 
211 
213 {
214  REQUIRE(m_ARD_type==KT_FULL || m_ARD_type==KT_DIAG, "This method only supports vector weights or matrix weights\n");
216  if (m_ARD_type==KT_FULL)
217  {
219  index_t offset=0;
220  // TODO: investigate a better way to make this
221  // block thread-safe
222  SGVector<float64_t> log_weights = m_log_weights.clone();
223  //can be done it in parallel
224  for (index_t i=0;i<m_weights_rows && i<m_weights_cols;i++)
225  {
226  SGMatrix<float64_t> weights(log_weights.vector+offset,1,m_weights_rows-i,false);
227  weights[0]=CMath::exp(weights[0]);
228  SGMatrix<float64_t> rtmp(vec.vector+i,vec.vlen-i,1,false);
230  weights[0]=CMath::log(weights[0]);
231  res[i]=s[0];
232  offset+=m_weights_rows-i;
233  }
234  }
235  else
236  {
237  SGMatrix<float64_t> rtmp(vec.vector,vec.vlen,1,false);
239  [ ](float64_t& value)
240  {
241  return CMath::exp(value);
242  });
243  res=linalg::element_prod(weights, rtmp);
244  }
245  return res;
246 }
247 
249  float64_t & scalar_weight)
250 {
251  SGMatrix<float64_t> right;
252 
253  if (m_ARD_type==KT_SCALAR)
254  {
255  right=SGMatrix<float64_t>(vec.vector,vec.vlen,1,false);
256  scalar_weight*=CMath::exp(m_log_weights[0]);
257  }
258  else if (m_ARD_type==KT_DIAG || m_ARD_type==KT_FULL)
259  right=get_weighted_vector(vec);
260  else
261  {
262  SG_ERROR("Unsupported ARD type\n");
263  }
264  return right;
265 }
266 
268 {
269  REQUIRE(lhs, "Left features not set!\n");
270  REQUIRE(rhs, "Right features not set!\n");
271 
272  if (m_ARD_type!=KT_SCALAR)
273  {
274  REQUIRE(index>=0, "Index (%d) must be non-negative\n",index);
275  REQUIRE(index<m_log_weights.vlen, "Index (%d) must be within #dimension of weights (%d)\n",
276  index, m_log_weights.vlen);
277  }
278 }
virtual void cleanup()
Definition: Kernel.cpp:156
SGVector< float64_t > m_log_weights
virtual void update_parameter_hash()
Definition: SGObject.cpp:281
int32_t index_t
Definition: common.h:72
virtual SGMatrix< float64_t > compute_right_product(SGVector< float64_t >vec, float64_t &scalar_weight)
virtual void set_weights(SGMatrix< float64_t > weights)
#define SG_ERROR(...)
Definition: SGIO.h:128
#define REQUIRE(x,...)
Definition: SGIO.h:205
auto elementwise_compute(Operand operand, UnaryOp unary_op) -> typename Operand::template container_type< decltype(unary_op(operand.data()[0]))>
virtual void set_scalar_weights(float64_t weight)
Features that support dot products among other operations.
Definition: DotFeatures.h:44
SGMatrix< float64_t > get_weighted_vector(SGVector< float64_t > vec)
ST * get_feature_vector(int32_t num, int32_t &len, bool &dofree)
SGMatrix< float64_t > m_weights_raw
Template class DotKernel is the base class for kernels working on DotFeatures.
Definition: DotKernel.h:31
T * get_column_vector(index_t col) const
Definition: SGMatrix.h:140
virtual SGMatrix< float64_t > get_weights()
double float64_t
Definition: common.h:60
virtual SGVector< float64_t > get_feature_vector(int32_t idx, CFeatures *hs)
index_t num_rows
Definition: SGMatrix.h:463
index_t num_cols
Definition: SGMatrix.h:465
void set_const(T const_elem)
Definition: SGVector.cpp:184
virtual bool init_normalizer()
Definition: Kernel.cpp:151
void matrix_prod(SGMatrix< T > &A, SGVector< T > &b, SGVector< T > &result, bool transpose=false)
virtual void check_weight_gradient_index(index_t index)
CFeatures * rhs
feature vectors to occur on right hand side
virtual void set_vector_weights(SGVector< float64_t > weights)
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
CFeatures * lhs
feature vectors to occur on left hand side
The class Features is the base class of all feature objects.
Definition: Features.h:68
static float64_t exp(float64_t x)
Definition: Math.h:616
static float64_t log(float64_t v)
Definition: Math.h:917
SGVector< float64_t > get_computed_dot_feature_vector(int32_t num)
void set_const(T const_elem)
Definition: SGMatrix.cpp:209
virtual void set_matrix_weights(SGMatrix< float64_t > weights)
#define SG_ADD(...)
Definition: SGObject.h:94
void element_prod(Block< SGMatrix< T >> &a, Block< SGMatrix< T >> &b, SGMatrix< T > &result)
virtual bool parameter_hash_changed()
Definition: SGObject.cpp:295
SGVector< T > clone() const
Definition: SGVector.cpp:247
index_t vlen
Definition: SGVector.h:545

SHOGUN Machine Learning Toolbox - Documentation