Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Improved arpack wrapper, introduced LLTSA
  • Loading branch information
lisitsyn committed Oct 23, 2011
1 parent 2b57730 commit e74284b
Show file tree
Hide file tree
Showing 16 changed files with 692 additions and 930 deletions.
1 change: 1 addition & 0 deletions examples/undocumented/libshogun/Makefile
Expand Up @@ -48,6 +48,7 @@ TARGETS = basic_minimal classifier_libsvm classifier_minimal_svm \
converter_diffusionmaps \
converter_laplacianeigenmaps \
converter_neighborhoodpreservingembedding \
converter_linearlocaltangentspacealignment \

all: $(TARGETS)

Expand Down
@@ -0,0 +1,39 @@
/*
* 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.
*
* Written (W) 2011 Sergey Lisitsyn
* Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
*/

#include <shogun/base/init.h>
#include <shogun/features/SimpleFeatures.h>
#include <shogun/converter/LinearLocalTangentSpaceAlignment.h>

using namespace shogun;

int main(int argc, char** argv)
{
init_shogun();

int N = 100;
int dim = 3;
float64_t* matrix = new double[N*dim];
for (int i=0; i<N*dim; i++)
matrix[i] = i;

CSimpleFeatures<double>* features = new CSimpleFeatures<double>(SGMatrix<double>(matrix,dim,N));
SG_REF(features);
CLinearLocalTangentSpaceAlignment* lltsa = new CLinearLocalTangentSpaceAlignment();
lltsa->set_target_dim(2);
lltsa->set_k(4);
lltsa->parallel->set_num_threads(4);
CSimpleFeatures<double>* embedding = lltsa->embed(features);
SG_UNREF(embedding);
SG_UNREF(lltsa);
SG_UNREF(features);
exit_shogun();
return 0;
}
@@ -0,0 +1,25 @@
from tools.load import LoadMatrix

lm=LoadMatrix()
data = lm.load_numbers('../data/fm_train_real.dat')

parameter_list = [[data,10],[data,20]]

def converter_linearlocaltangentspacealignment_modular(data,k):
from shogun.Features import RealFeatures
from shogun.Converter import LinearLocalTangentSpaceAlignment

features = RealFeatures(data)

converter = LinearLocalTangentSpaceAlignment()
converter.set_target_dim(1)
converter.set_k(k)
converter.apply(features)

return features


if __name__=='__main__':
print 'LinearLocalTangentSpaceAlignment'
converter_linearlocaltangentspacealignment_modular(*parameter_list[0])

2 changes: 2 additions & 0 deletions src/interfaces/modular/Converter.i
Expand Up @@ -12,6 +12,7 @@
%rename(LocallyLinearEmbedding) CLocallyLinearEmbedding;
%rename(NeighborhoodPreservingEmbedding) CNeighborhoodPreservingEmbedding;
%rename(LocalTangentSpaceAlignment) CLocalTangentSpaceAlignment;
%rename(LinearLocalTangentSpaceAlignment) CLinearLocalTangentSpaceAlignment;
%rename(HessianLocallyLinearEmbedding) CHessianLocallyLinearEmbedding;
%rename(KernelLocallyLinearEmbedding) CKernelLocallyLinearEmbedding;
%rename(KernelLocalTangentSpaceAlignment) CKernelLocalTangentSpaceAlignment;
Expand All @@ -27,6 +28,7 @@
%include <shogun/converter/LocallyLinearEmbedding.h>
%include <shogun/converter/NeighborhoodPreservingEmbedding.h>
%include <shogun/converter/LocalTangentSpaceAlignment.h>
%include <shogun/converter/LinearLocalTangentSpaceAlignment.h>
%include <shogun/converter/HessianLocallyLinearEmbedding.h>
%include <shogun/converter/KernelLocallyLinearEmbedding.h>
%include <shogun/converter/KernelLocalTangentSpaceAlignment.h>
Expand Down
1 change: 1 addition & 0 deletions src/interfaces/modular/Converter_includes.i
Expand Up @@ -4,6 +4,7 @@
#include <shogun/converter/LocallyLinearEmbedding.h>
#include <shogun/converter/NeighborhoodPreservingEmbedding.h>
#include <shogun/converter/LocalTangentSpaceAlignment.h>
#include <shogun/converter/LinearLocalTangentSpaceAlignment.h>
#include <shogun/converter/HessianLocallyLinearEmbedding.h>
#include <shogun/converter/KernelLocallyLinearEmbedding.h>
#include <shogun/converter/KernelLocalTangentSpaceAlignment.h>
Expand Down
6 changes: 3 additions & 3 deletions src/shogun/converter/LaplacianEigenmaps.cpp
Expand Up @@ -163,9 +163,9 @@ CFeatures* CLaplacianEigenmaps::apply(CFeatures* features)
// using ARPACK DS{E,A}UPD
int eigenproblem_status = 0;
float64_t* eigenvalues_vector = SG_MALLOC(float64_t,m_target_dim+1);
arpack_xsxupd<float64_t>(W_matrix,D_diag_vector,N,m_target_dim+1,"LA",3,false,-1e-9,0.0,
eigenvalues_vector,W_matrix,eigenproblem_status);
ASSERT(eigenproblem_status==0);
arpack_dsxupd(W_matrix,D_diag_vector,true,N,m_target_dim+1,"LA",true,3,false,-1e-9,0.0,
eigenvalues_vector,W_matrix,eigenproblem_status);
if (eigenproblem_status!=0) SG_ERROR("DSXUPD failed with code %d\n",eigenproblem_status);
SG_FREE(eigenvalues_vector);
#else
// using LAPACK DSYGVX
Expand Down
104 changes: 104 additions & 0 deletions src/shogun/converter/LinearLocalTangentSpaceAlignment.cpp
@@ -0,0 +1,104 @@
/*
* 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.
*
* Written (W) 2011 Sergey Lisitsyn
* Copyright (C) 2011 Sergey Lisitsyn
*/

#include <shogun/converter/LinearLocalTangentSpaceAlignment.h>
#ifdef HAVE_LAPACK
#include <shogun/mathematics/arpack.h>
#include <shogun/mathematics/lapack.h>
#include <shogun/mathematics/Math.h>
#include <shogun/io/SGIO.h>
#include <shogun/lib/Time.h>
#include <shogun/distance/Distance.h>
#include <shogun/lib/Signal.h>

using namespace shogun;

CLinearLocalTangentSpaceAlignment::CLinearLocalTangentSpaceAlignment() :
CLocalTangentSpaceAlignment()
{
}

CLinearLocalTangentSpaceAlignment::~CLinearLocalTangentSpaceAlignment()
{
}

const char* CLinearLocalTangentSpaceAlignment::get_name() const
{
return "LinearLocalTangentSpaceAlignment";
}

SGMatrix<float64_t> CLinearLocalTangentSpaceAlignment::construct_embedding(CFeatures* features, SGMatrix<float64_t> matrix, int dimension)
{
CSimpleFeatures<float64_t>* simple_features = (CSimpleFeatures<float64_t>*)features;
ASSERT(simple_features);
int i,j;

int N;
int dim;
float64_t* feature_matrix;
simple_features->get_feature_matrix(&feature_matrix,&dim,&N);
ASSERT(dimension<=dim);
float64_t* XTM = SG_MALLOC(float64_t, dim*N);
float64_t* lhs_M = SG_MALLOC(float64_t, dim*dim);
float64_t* rhs_M = SG_MALLOC(float64_t, dim*dim);
CMath::center_matrix(matrix.matrix,N,N);

cblas_dgemm(CblasColMajor,CblasNoTrans,CblasNoTrans,dim,N,N,1.0,feature_matrix,dim,matrix.matrix,N,0.0,XTM,dim);
cblas_dgemm(CblasColMajor,CblasNoTrans,CblasTrans,dim,dim,N,1.0,XTM,dim,feature_matrix,dim,0.0,lhs_M,dim);

float64_t* mean_vector = SG_CALLOC(float64_t, dim);
for (i=0; i<N; i++)
cblas_daxpy(dim,1.0,feature_matrix+i*dim,1,mean_vector,1);

cblas_dscal(dim,1.0/N,mean_vector,1);

for (i=0; i<N; i++)
cblas_daxpy(dim,-1.0,mean_vector,1,feature_matrix+i*dim,1);

SG_FREE(mean_vector);

cblas_dgemm(CblasColMajor,CblasNoTrans,CblasTrans,dim,dim,N,1.0,feature_matrix,dim,feature_matrix,dim,0.0,rhs_M,dim);

for (i=0; i<dim; i++) rhs_M[i*dim+i] += 1e-6;

float64_t* evals = SG_MALLOC(float64_t, dim);
float64_t* evectors = SG_MALLOC(float64_t, dimension*dim);
int32_t info = 0;
#ifdef HAVE_ARPACK
arpack_dsxupd(lhs_M,rhs_M,false,dim,dimension,"LA",false,3,true,m_nullspace_shift,0.0,
evals,evectors,info);
#else
wrap_dsygvx(1,'V','U',dim,lhs_M,dim,rhs_M,dim,dim-dimension+1,dim,evals,evectors,&info);
#endif
SG_FREE(lhs_M);
SG_FREE(rhs_M);
SG_FREE(evals);
if (info!=0) SG_ERROR("Failed to solve eigenproblem (%d)\n",info);

for (i=0; i<dimension/2; i++)
{
cblas_dswap(dim,evectors+i*dim,1,evectors+(dimension-i-1)*dim,1);
}

cblas_dgemm(CblasColMajor,CblasTrans,CblasNoTrans,N,dimension,dim,1.0,feature_matrix,dim,evectors,dim,0.0,XTM,N);
SG_FREE(evectors);
SG_FREE(feature_matrix);

float64_t* new_features = SG_MALLOC(float64_t, dimension*N);
for (i=0; i<dimension; i++)
{
for (j=0; j<N; j++)
new_features[j*dimension+i] = XTM[i*N+j];
}
SG_FREE(XTM);
return SGMatrix<float64_t>(new_features,dimension,N);
}

#endif /* HAVE_LAPACK */
54 changes: 54 additions & 0 deletions src/shogun/converter/LinearLocalTangentSpaceAlignment.h
@@ -0,0 +1,54 @@
/*
* 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.
*
* Written (W) 2011 Sergey Lisitsyn
* Copyright (C) 2011 Sergey Lisitsyn
*/

#ifndef LINEARLOCALTANGENTSPACEALIGNMENT_H_
#define LINEARLOCALTANGENTSPACEALIGNMENT_H_
#include <shogun/lib/config.h>
#ifdef HAVE_LAPACK
#include <shogun/converter/LocalTangentSpaceAlignment.h>
#include <shogun/features/Features.h>
#include <shogun/features/SimpleFeatures.h>
#include <shogun/distance/Distance.h>

namespace shogun
{

class CFeatures;
class CDistance;

/** @brief LinearLocalTangentSpaceAlignment
*/
class CLinearLocalTangentSpaceAlignment: public CLocalTangentSpaceAlignment
{
public:

/** constructor */
CLinearLocalTangentSpaceAlignment();

/** destructor */
virtual ~CLinearLocalTangentSpaceAlignment();

/** get name */
virtual const char* get_name() const;

protected:

/** constructs embedding
* @param simple features to be used
* @param matrix weight matrix
* @param dimension dimension of embedding
* @return null-space approximation feature matrix
*/
virtual SGMatrix<float64_t> construct_embedding(CFeatures* features, SGMatrix<float64_t> matrix, int dimension);
};
}

#endif /* HAVE_LAPACK */
#endif /* LINEARLOCALTANGENTSPACEALIGNMENT_H_ */
8 changes: 4 additions & 4 deletions src/shogun/converter/LocallyLinearEmbedding.cpp
Expand Up @@ -493,10 +493,10 @@ SGMatrix<float64_t> CLocallyLinearEmbedding::construct_embedding(CFeatures* feat
#endif
// using ARPACK (faster)
eigenvalues_vector = SG_MALLOC(float64_t, dimension+1);
#ifdef HAVE_ARPACK
arpack_xsxupd<float64_t>(matrix.matrix,NULL,N,dimension+1,"LA",3,true,m_nullspace_shift,0.0,
eigenvalues_vector,matrix.matrix,eigenproblem_status);
#endif
#ifdef HAVE_ARPACK
arpack_dsxupd(matrix.matrix,NULL,false,N,dimension+1,"LA",true,3,true,m_nullspace_shift,0.0,
eigenvalues_vector,matrix.matrix,eigenproblem_status);
#endif
if (eigenproblem_status)
SG_ERROR("ARPACK failed with code: %d", eigenproblem_status);
nullspace_features = SG_MALLOC(float64_t, N*dimension);
Expand Down
4 changes: 2 additions & 2 deletions src/shogun/converter/MultidimensionalScaling.cpp
Expand Up @@ -186,8 +186,8 @@ SGMatrix<float64_t> CMultidimensionalScaling::classic_embedding(SGMatrix<float64
// using ARPACK
float64_t* eigenvalues_vector = SG_MALLOC(float64_t, m_target_dim);
// solve eigenproblem with ARPACK (faster)
arpack_xsxupd<float64_t>(distance_matrix.matrix,NULL,N,m_target_dim,"LM",1,false,0.0,0.0,
eigenvalues_vector,replace_feature_matrix,eigenproblem_status);
arpack_dsxupd(distance_matrix.matrix,NULL,false,N,m_target_dim,"LM",false,1,false,0.0,0.0,
eigenvalues_vector,replace_feature_matrix,eigenproblem_status);
// check for failure
ASSERT(eigenproblem_status == 0);
// reverse eigenvectors order
Expand Down

0 comments on commit e74284b

Please sign in to comment.