Skip to content

Commit

Permalink
Modify get_feature_vector to support on-the-fly preprocessors
Browse files Browse the repository at this point in the history
  • Loading branch information
vinx13 committed Jul 15, 2018
1 parent 20d4650 commit 2fe8de3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 40 deletions.
64 changes: 27 additions & 37 deletions src/shogun/features/DenseFeatures.cpp
Expand Up @@ -114,58 +114,48 @@ template<class ST> ST* CDenseFeatures<ST>::get_feature_vector(int32_t num, int32

len = num_features;

if (feature_matrix.matrix)
{
dofree = false;
return &feature_matrix.matrix[real_num * int64_t(num_features)];
}

ST* feat = NULL;
dofree = false;

if (feature_cache)
if (feature_matrix.matrix)
{
feat = &feature_matrix.matrix[real_num * int64_t(num_features)];
}
else
{
feat = feature_cache->lock_entry(real_num);
if (feature_cache)
feat = feature_cache->lock_entry(real_num);

if (feat)
return feat;
else
if (!feat)
feat = feature_cache->set_entry(real_num);
if (!feat)
{
dofree = true;
feat = compute_feature_vector(num, len, feat);
}
}

if (!feat)
dofree = true;
feat = compute_feature_vector(num, len, feat);

if (get_num_preprocessors())
{
int32_t tmp_len = len;
ST* tmp_feat_before = feat;
ST* tmp_feat_after = NULL;
SGVector<ST> feat_vec(feat, len, false);

for (int32_t i = 0; i < get_num_preprocessors(); i++)
for (auto i = 0; i < get_num_preprocessors(); i++)
{
CDensePreprocessor<ST>* p =
(CDensePreprocessor<ST>*) get_preprocessor(i);
auto preprocessor =
get_preprocessor(i)->as<CDensePreprocessor<ST>>();
// temporary hack
SGVector<ST> applied = p->apply_to_feature_vector(
SGVector<ST>(tmp_feat_before, tmp_len));
tmp_feat_after = applied.vector;
SG_UNREF(p);

if (i != 0) // delete feature vector, except for the the first one, i.e., feat
SG_FREE(tmp_feat_before);
tmp_feat_before = tmp_feat_after;
}
SGVector<ST> applied =
preprocessor->apply_to_feature_vector(feat_vec);

// note: tmp_feat_after should be checked as it is used by memcpy
if (tmp_feat_after)
{
sg_memcpy(feat, tmp_feat_after, sizeof(ST) * tmp_len);
SG_FREE(tmp_feat_after);

len = tmp_len;
if (i == 0)
free_feature_vector(feat_vec.vector, num, dofree);
feat_vec = applied;
}

feat = SG_MALLOC(ST, feat_vec.vlen);
sg_memcpy(feat, feat_vec.vector, feat_vec.vlen * sizeof(ST));
dofree = true;
len = feat_vec.vlen;
}
return feat;
}
Expand Down
6 changes: 3 additions & 3 deletions tests/unit/preprocessor/NormOne_unittest.cc
Expand Up @@ -57,13 +57,13 @@ TEST_F(NormOne, transform)
TEST_F(NormOne, apply_to_vector)
{
transformer->fit(feats);
feats->add_preprocessor(transformer);

for (auto i : range(num_vectors))
{
SGVector<float64_t> v = feats->get_feature_vector(i);
auto result = transformer->apply_to_feature_vector(v);
SGVector<float64_t> result = feats->get_feature_vector(i);
ASSERT_EQ(result.vlen, num_features);
for (auto j : range(v.vlen))
for (auto j : range(result.vlen))
{
EXPECT_DOUBLE_EQ(result[j], matrix(j, i) / norm[i]);
}
Expand Down

0 comments on commit 2fe8de3

Please sign in to comment.