Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
added python protocol for SGVector
  • Loading branch information
gsomix committed Aug 10, 2012
1 parent baebab2 commit 796f3f0
Show file tree
Hide file tree
Showing 6 changed files with 556 additions and 73 deletions.
100 changes: 100 additions & 0 deletions examples/undocumented/python_modular/features_director_dot_modular.py
@@ -0,0 +1,100 @@
import numpy
try:
from shogun.Features import DirectorDotFeatures
from shogun.Library import RealVector
except ImportError:
print "recompile shogun with --enable-swig-directors"
import sys
sys.exit(0)

from tools.load import LoadMatrix
lm=LoadMatrix()

traindat = lm.load_numbers('../data/fm_train_real.dat')
testdat = lm.load_numbers('../data/fm_test_real.dat')
label_traindat = lm.load_labels('../data/label_train_twoclass.dat')

parameter_list = [[traindat,testdat,label_traindat,0.9,1e-3],[traindat,testdat,label_traindat,0.8,1e-2]]

class NumpyFeatures(DirectorDotFeatures):

# variables
data=numpy.empty((1,1))

# constructor
def __init__(self, d):
DirectorDotFeatures.__init__(self)
self.data = d

# overloaded methods
def add_to_dense_sgvec(self, alpha, vec_idx1, vec2, abs):
vec2+=alpha*numpy.abs(self.data[:,vec_idx1])

def dot(self, vec_idx1, df, vec_idx2):
return numpy.dot(self.data[:,vec_idx1], (df.get_computed_dot_feature_matrix())[:,vec_idx2])

def get_num_vectors(self):
return self.data.shape[1]

def get_dim_feature_space(self):
return self.data.shape[0]

# operators
def __add__(self, other):
return NumpyFeatures(self.data+other.data)

def __sub__(self, other):
return NumpyFeatures(self.data-other.data)

def __iadd__(self, other):
return NumpyFeatures(self.data+other.data)

def __isub__(self, other):
return NumpyFeatures(self.data-other.data)

def features_director_dot_modular (fm_train_real, fm_test_real,
label_train_twoclass, C, epsilon):

from shogun.Features import RealFeatures, SparseRealFeatures, BinaryLabels
from shogun.Classifier import LibLinear, L2R_L2LOSS_SVC_DUAL
from shogun.Mathematics import Math_init_random
Math_init_random(17)

feats_train=RealFeatures(fm_train_real)
feats_test=RealFeatures(fm_test_real)
labels=BinaryLabels(label_train_twoclass)

b = RealVector()
print b

dfeats_train=NumpyFeatures(fm_train_real)
dfeats_test=NumpyFeatures(fm_test_real)

print feats_train.get_computed_dot_feature_matrix()
print dfeats_train.get_computed_dot_feature_matrix()

svm=LibLinear(C, feats_train, labels)
svm.set_liblinear_solver_type(L2R_L2LOSS_SVC_DUAL)
svm.set_epsilon(epsilon)
svm.set_bias_enabled(True)
svm.train()

svm.set_features(feats_test)
svm.apply().get_labels()
predictions = svm.apply()

dsvm=LibLinear(C, dfeats_train, labels)
dsvm.set_liblinear_solver_type(L2R_L2LOSS_SVC_DUAL)
dsvm.set_epsilon(epsilon)
dsvm.set_bias_enabled(True)
dsvm.train()

dsvm.set_features(dfeats_test)
dsvm.apply().get_labels()
dpredictions = dsvm.apply()

return predictions, svm, predictions.get_labels()

if __name__=='__main__':
print('DirectorLinear')
features_director_dot_modular(*parameter_list[0])
16 changes: 16 additions & 0 deletions src/interfaces/modular/Library.i
Expand Up @@ -6,8 +6,13 @@
*
* Written (W) 2009 Soeren Sonnenburg
* Copyright (C) 2009 Fraunhofer Institute FIRST and Max-Planck-Society
* Copyright (c) 2012 Evgeniy Andreev (gsomix)
*/

#ifndef SWIGPYTHON
#define PYPROTO_SGVECTOR(class_name, type_name, format_str, typecode)
#endif

%rename(Cache) CCache;
%rename(ListElement) CListElement;
%rename(List) CList;
Expand Down Expand Up @@ -237,46 +242,57 @@ namespace shogun
#endif

#ifdef USE_BOOL
PYPROTO_SGVECTOR(BoolVector, bool, "?\0", NPY_BOOL)
%template(BoolVector) SGVector<bool>;
SERIALIZABLE_DUMMY(SGVector<bool>);
#endif
#ifdef USE_CHAR
PYPROTO_SGVECTOR(CharVector, char, "c\0", NPY_STRING)
%template(CharVector) SGVector<char>;
SERIALIZABLE_DUMMY(SGVector<char>);
#endif
#ifdef USE_UINT8
PYPROTO_SGVECTOR(ByteVector, uint8_t, "B\0", NPY_UINT8)
%template(ByteVector) SGVector<uint8_t>;
SERIALIZABLE_DUMMY(SGVector<uint8_t>);
#endif
#ifdef USE_UINT16
PYPROTO_SGVECTOR(WordVector, uint16_t, "H\0", NPY_UINT16)
%template(WordVector) SGVector<uint16_t>;
SERIALIZABLE_DUMMY(SGVector<uint16_t>);
#endif
#ifdef USE_INT16
PYPROTO_SGVECTOR(ShortVector, int16_t, "h\0", NPY_INT16)
%template(ShortVector) SGVector<int16_t>;
SERIALIZABLE_DUMMY(SGVector<int16_t>);
#endif
#ifdef USE_INT32
PYPROTO_SGVECTOR(IntVector, int32_t, "i\0", NPY_INT32)
%template(IntVector) SGVector<int32_t>;
SERIALIZABLE_DUMMY(SGVector<int32_t>);
#endif
#ifdef USE_UINT32
PYPROTO_SGVECTOR(UIntVector, uint32_t, "I\0", NPY_UINT32)
%template(UIntVector) SGVector<uint32_t>;
SERIALIZABLE_DUMMY(SGVector<uint32_t>);
#endif
#ifdef USE_INT64
PYPROTO_SGVECTOR(LongIntVector, int64_t, "l\0", NPY_INT64)
%template(LongIntVector) SGVector<int64_t>;
SERIALIZABLE_DUMMY(SGVector<int64_t>);
#endif
#ifdef USE_UINT64
PYPROTO_SGVECTOR(ULongIntVector, uint64_t, "L\0", NPY_UINT64)
%template(ULongIntVector) SGVector<uint64_t>;
SERIALIZABLE_DUMMY(SGVector<uint64_t>);
#endif
#ifdef USE_FLOAT32
PYPROTO_SGVECTOR(ShortRealVector, float64_t, "f\0", NPY_FLOAT32)
%template(ShortRealVector) SGVector<float32_t>;
SERIALIZABLE_DUMMY(SGVector<float32_t>);
#endif
#ifdef USE_FLOAT64
PYPROTO_SGVECTOR(RealVector, float64_t, "d\0", NPY_FLOAT64)
%template(RealVector) SGVector<float64_t>;
SERIALIZABLE_DUMMY(SGVector<float64_t>);
#endif
Expand Down
Expand Up @@ -4,82 +4,12 @@
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This code is inspired by the python numpy.i typemaps, from John Hunter
* and Bill Spotz that in turn is based on enthought/kiva/agg/src/numeric.i,
* author unknown.
*
* It goes further by supporting strings of arbitrary types, sparse matrices
* and ways to return arbitrariliy shaped matrices.
*
* Copyright (C) 2012 Evgeniy Andreev (gsomix)
*/

#ifdef SWIGPYTHON

/* Helper functions */
%wrapper
%{
void get_slice_in_bounds(Py_ssize_t* ilow, Py_ssize_t* ihigh, Py_ssize_t max_idx)
{
if (*ilow<0)
{
*ilow=0;
}
else if (*ilow>max_idx)
{
*ilow = max_idx;
}
if (*ihigh<*ilow)
{
*ihigh=*ilow;
}
else if (*ihigh>max_idx)
{
*ihigh=max_idx;
}
}

Py_ssize_t get_idx_in_bounds(Py_ssize_t idx, Py_ssize_t max_idx)
{
if (idx>=max_idx || idx<-max_idx)
{
PyErr_SetString(PyExc_IndexError, "index out of bounds");
return -1;
}
else if (idx<0)
return idx+max_idx;

return idx;
}

int parse_tuple_item(PyObject* item, Py_ssize_t length,
Py_ssize_t* ilow, Py_ssize_t* ihigh,
Py_ssize_t* step, Py_ssize_t* slicelength)
{
if (PySlice_Check(item))
{
PySlice_GetIndicesEx((PySliceObject*) item, length, ilow, ihigh, step, slicelength);
get_slice_in_bounds(ilow, ihigh, length);

return 2;
}
else if (PyInt_Check(item) || PyArray_IsScalar(item, Integer) ||
PyLong_Check(item) || (PyIndex_Check(item) && !PySequence_Check(item)))
{
npy_intp idx;
idx = PyArray_PyIntAsIntp(item);
idx = get_idx_in_bounds(idx, length);

*ilow=idx;
*ihigh=idx+1;

return 1;
}

return 0;
}

%}
%include "ProtoHelper.i"

/* Numeric operators for DenseFeatures */
%define NUMERIC_DENSEFEATURES(class_name, type_name, format_str, operator_name, operator)
Expand Down Expand Up @@ -120,7 +50,6 @@ PyObject* class_name ## _inplace ## operator_name ## (PyObject *self, PyObject *
// checking that buffer is right
if (view.ndim != 2)
{
printf("%d\n", view.ndim);
SWIG_exception_fail(SWIG_ArgError(res1), "same dimension is needed");
}

Expand Down
64 changes: 64 additions & 0 deletions src/interfaces/python_modular/ProtoHelper.i
@@ -0,0 +1,64 @@
/* Helper functions */
%wrapper
%{
void get_slice_in_bounds(Py_ssize_t* ilow, Py_ssize_t* ihigh, Py_ssize_t max_idx)
{
if (*ilow<0)
{
*ilow=0;
}
else if (*ilow>max_idx)
{
*ilow = max_idx;
}
if (*ihigh<*ilow)
{
*ihigh=*ilow;
}
else if (*ihigh>max_idx)
{
*ihigh=max_idx;
}
}

Py_ssize_t get_idx_in_bounds(Py_ssize_t idx, Py_ssize_t max_idx)
{
if (idx>=max_idx || idx<-max_idx)
{
PyErr_SetString(PyExc_IndexError, "index out of bounds");
return -1;
}
else if (idx<0)
return idx+max_idx;

return idx;
}

int parse_tuple_item(PyObject* item, Py_ssize_t length,
Py_ssize_t* ilow, Py_ssize_t* ihigh,
Py_ssize_t* step, Py_ssize_t* slicelength)
{
if (PySlice_Check(item))
{
PySlice_GetIndicesEx((PySliceObject*) item, length, ilow, ihigh, step, slicelength);
get_slice_in_bounds(ilow, ihigh, length);

return 2;
}
else if (PyInt_Check(item) || PyArray_IsScalar(item, Integer) ||
PyLong_Check(item) || (PyIndex_Check(item) && !PySequence_Check(item)))
{
npy_intp idx;
idx = PyArray_PyIntAsIntp(item);
idx = get_idx_in_bounds(idx, length);

*ilow=idx;
*ihigh=idx+1;

return 1;
}

return 0;
}

%}

0 comments on commit 796f3f0

Please sign in to comment.