Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #644 from puffin444/master
ARD versions of Linear and Gaussian Kernels. Gradient Testing.
  • Loading branch information
lisitsyn committed Jul 14, 2012
2 parents 1ab1290 + 3385475 commit eb98b84
Show file tree
Hide file tree
Showing 8 changed files with 608 additions and 7 deletions.
123 changes: 123 additions & 0 deletions src/shogun/kernel/GaussianARDKernel.cpp
@@ -0,0 +1,123 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* (W) 2012 Jacob Walker
*
* Adapted from WeightedDegreeRBFKernel.cpp
*
*/

#include <shogun/lib/common.h>
#include <shogun/kernel/GaussianARDKernel.h>
#include <shogun/features/Features.h>
#include <shogun/io/SGIO.h>

using namespace shogun;

CGaussianARDKernel::CGaussianARDKernel()
: CDotKernel()
{
init();
}


CGaussianARDKernel::CGaussianARDKernel(int32_t size, float64_t width)
: CDotKernel(size), m_width(width)
{
init();
}

CGaussianARDKernel::CGaussianARDKernel(CDenseFeatures<float64_t>* l,
CDenseFeatures<float64_t>* r,
int32_t size, float64_t width)
: CDotKernel(size), m_width(width)
{
init();
init(l,r);
}

void CGaussianARDKernel::init()
{
m_width = 2.0;
m_weights = SGVector<float64_t>();

SG_ADD(&m_weights, "weights", "Feature Weights", MS_AVAILABLE);
SG_ADD(&m_width, "width", "Kernel Width", MS_AVAILABLE);
}

CGaussianARDKernel::~CGaussianARDKernel()
{
CKernel::cleanup();
}

bool CGaussianARDKernel::init(CFeatures* l, CFeatures* r)
{
CDotKernel::init(l, r);

init_ft_weights();

SG_DEBUG("Initialized GaussianARDKernel (%p).\n", this);

return init_normalizer();
}

void CGaussianARDKernel::init_ft_weights()
{
int32_t alen, blen;

alen = ((CDenseFeatures<float64_t>*) lhs)->get_num_features();
blen = ((CDenseFeatures<float64_t>*) rhs)->get_num_features();

REQUIRE(alen==blen, "Number of Right and Left Hand "\
"Features Must be the Same./n");

m_weights = SGVector<float64_t>(alen);

for (int32_t i=0; i < alen; i++)
m_weights[i]=1.0;

SG_DEBUG("Initialized weights for LinearARDKernel (%p).\n", this);
}

void CGaussianARDKernel::set_weight(float64_t w, index_t i)
{
if (i > m_weights.vlen-1)
{
SG_ERROR("Index %i out of range for LinearARDKernel."\
"Number of features is %i.\n", i, m_weights.vlen);
}

m_weights[i]=w;
}

float64_t CGaussianARDKernel::get_weight(index_t i)
{
if (i > m_weights.vlen-1)
{
SG_ERROR("Index %i out of range for LinearARDKernel."\
"Number of features is %i.\n", i, m_weights.vlen);
}

return m_weights[i];
}

float64_t CGaussianARDKernel::compute(int32_t idx_a, int32_t idx_b)
{
SGVector<float64_t> avec
= ((CDenseFeatures<float64_t>*) lhs)->get_feature_vector(idx_a);
SGVector<float64_t> bvec
= ((CDenseFeatures<float64_t>*) rhs)->get_feature_vector(idx_b);

REQUIRE(avec.vlen==bvec.vlen, "Number of Right and Left Hand "\
"Features Must be the Same./n");

float64_t result=0;

for (index_t i = 0; i < avec.vlen; i++)
result += CMath::pow((avec[i]-bvec[i])*m_weights[i], 2);

return CMath::exp(-result/m_width);
}
147 changes: 147 additions & 0 deletions src/shogun/kernel/GaussianARDKernel.h
@@ -0,0 +1,147 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* (W) 2012 Jacob Walker
*
* Adapted from WeightedDegreeRBFKernel.h
*
*/

#ifndef GAUSSIANARDKERNEL_H_
#define GAUSSIANARDKERNEL_H_

#include <shogun/lib/common.h>
#include <shogun/kernel/DotKernel.h>
#include <shogun/features/DenseFeatures.h>

namespace shogun
{

class CGaussianARDKernel: public CDotKernel
{

public:
/** default constructor
*
*/
CGaussianARDKernel();

/** constructor
*
* @param size cache size
*/
CGaussianARDKernel(int32_t size, float64_t width);

/** constructor
*
* @param l features of left-hand side
* @param r features of right-hand side
* @param size cache size
*/
CGaussianARDKernel(CDenseFeatures<float64_t>* l, CDenseFeatures<float64_t>* r,
int32_t size=10, float64_t width = 2.0);

virtual ~CGaussianARDKernel();

/** initialize kernel
*
* @param l features of left-hand side
* @param r features of right-hand side
* @return if initializing was successful
*/
virtual bool init(CFeatures* l, CFeatures* r);

/** return what type of kernel we are
*
* @return kernel type LINEARARD
*/
virtual EKernelType get_kernel_type() { return K_GAUSSIANARD; }

/** return the kernel's name
*
* @return name LinearARDKernel
*/
inline virtual const char* get_name() const { return "GaussianARDKernel"; }


/** return feature class the kernel can deal with
*
* @return feature class SIMPLE
*/
inline virtual EFeatureClass get_feature_class() { return C_DENSE; }

/** return feature type the kernel can deal with
*
* @return float64_t feature type
*/
virtual EFeatureType get_feature_type() { return F_DREAL; }

/*Set weight of particular feature
*
* @param w weight to set
* @param i index of feature
*/
virtual void set_weight(float64_t w, index_t i);

/*Get weight of particular feature
*
* @param i index of feature
*
* @return weight of feature
*/
virtual float64_t get_weight(index_t i);

/** set the kernel's width
*
* @param w kernel width
*/
inline virtual void set_width(float64_t w)
{
m_width = w;
}

/** return the kernel's width
*
* @return kernel width
*/
inline virtual float64_t get_width() const
{
return m_width;
}

protected:

/** compute kernel function for features a and b
* idx_{a,b} denote the index of the feature vectors
* in the corresponding feature object
*
* @param idx_a index a
* @param idx_b index b
* @return computed kernel function at indices a,b
*/
virtual float64_t compute(int32_t idx_a, int32_t idx_b);

/** init feature weights
*
* @return if initialization was successful
*/
void init_ft_weights();

private:

void init();

protected:

/** weights */
SGVector<float64_t> m_weights;

/* kernel width */
float64_t m_width;
};

} /* namespace shogun */
#endif /* GAUSSIANARDKERNEL_H_ */
2 changes: 2 additions & 0 deletions src/shogun/kernel/Kernel.cpp
Expand Up @@ -753,6 +753,8 @@ void CKernel::list_kernel()
ENUM_CASE(K_JENSENSHANNON)
ENUM_CASE(K_DIRECTOR)
ENUM_CASE(K_PRODUCT)
ENUM_CASE(K_LINEARARD)
ENUM_CASE(K_GAUSSIANARD)
}

switch (get_feature_class())
Expand Down
4 changes: 3 additions & 1 deletion src/shogun/kernel/Kernel.h
Expand Up @@ -108,7 +108,9 @@ enum EKernelType
K_BESSEL = 460,
K_JENSENSHANNON = 470,
K_DIRECTOR = 480,
K_PRODUCT = 490
K_PRODUCT = 490,
K_LINEARARD = 500,
K_GAUSSIANARD = 510
};

/** kernel property */
Expand Down

0 comments on commit eb98b84

Please sign in to comment.