Skip to content

Commit

Permalink
fixed clone subset stack bug in features util
Browse files Browse the repository at this point in the history
  • Loading branch information
lambday authored and karlnapf committed Jul 4, 2016
1 parent af0b2bf commit b45d490
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 29 deletions.
69 changes: 48 additions & 21 deletions src/shogun/statistical_testing/internals/FeaturesUtil.cpp
Expand Up @@ -57,27 +57,7 @@ CFeatures* FeaturesUtil::create_shallow_copy(CFeatures* other)
SG_SDEBUG("Using underlying feature matrix with %d dimensions and %d feature vectors!\n", num_feats, num_vecs);
SGMatrix<float64_t> feats_matrix(data, num_feats, num_vecs, false);
shallow_copy=new CDenseFeatures<float64_t>(feats_matrix);

// clone the subsets if there are any
CSubsetStack* src_subset_stack=casted->get_subset_stack();
if (src_subset_stack->has_subsets())
{
SG_SDEBUG("Subset present, cloning the subsets!\n");
CSubsetStack* subset_stack=static_cast<CSubsetStack*>(src_subset_stack->clone());
std::stack<SGVector<index_t>> stack;
while (subset_stack->has_subsets())
{
stack.push(subset_stack->get_last_subset()->get_subset_idx());
subset_stack->remove_subset();
}
SG_UNREF(subset_stack);
while (!stack.empty())
{
shallow_copy->add_subset(stack.top());
stack.pop();
}
}
SG_UNREF(src_subset_stack);
clone_subset_stack(other, shallow_copy);
}
else
SG_SNOTIMPLEMENTED;
Expand Down Expand Up @@ -120,3 +100,50 @@ CFeatures* FeaturesUtil::create_merged_copy(CFeatures* feats_a, CFeatures* feats
SG_SDEBUG("Leaving!\n");
return merged_copy;
}

void FeaturesUtil::clone_subset_stack(CFeatures* src, CFeatures* dst)
{
SG_SDEBUG("Entering!\n");
CSubsetStack* src_subset_stack=src->get_subset_stack();
if (src_subset_stack->has_subsets())
{
SG_SDEBUG("Subset present, cloning the subsets!\n");
CSubsetStack* subset_stack=static_cast<CSubsetStack*>(src_subset_stack->clone());
std::stack<SGVector<index_t>> stack;
while (subset_stack->has_subsets())
{
stack.push(subset_stack->get_last_subset()->get_subset_idx());
subset_stack->remove_subset();
}
SG_UNREF(subset_stack);
SG_SDEBUG("Number of subsets to be added is %d!\n", stack.size());
if (stack.size()>1)
{
SGVector<index_t> ref=stack.top();
dst->add_subset(ref);
stack.pop();
do
{
SGVector<index_t> inds=stack.top();
for (auto i=0, j=0; i<ref.size() && j<inds.size(); ++i)
{
if (ref[i]==inds[j])
inds[j++]=i;
}
dst->add_subset(inds);
inds=ref;
stack.pop();
} while (!stack.empty());
}
else
{
while (!stack.empty())
{
dst->add_subset(stack.top());
stack.pop();
}
}
}
SG_UNREF(src_subset_stack);
SG_SDEBUG("Leaving!\n");
}
8 changes: 8 additions & 0 deletions src/shogun/statistical_testing/internals/FeaturesUtil.h
Expand Up @@ -66,6 +66,14 @@ struct FeaturesUtil
* vectors of feats_a.num_vectors+feats_b.num_vectors.
*/
static CFeatures* create_merged_copy(CFeatures* feats_a, CFeatures* feats_b);

/**
* This copies the subset stack from the src features object to the dst.
*
* @param src The source features object
* @param dst The destination features object
*/
static void clone_subset_stack(CFeatures* src, CFeatures* dst);
};

}
Expand Down
42 changes: 34 additions & 8 deletions tests/unit/statistical_testing/internals/FeaturesUtil_unittest.cc
Expand Up @@ -49,10 +49,10 @@ TEST(FeaturesUtil, create_shallow_copy)

auto feats=new CDenseFeatures<float64_t>(data);
SGVector<index_t> inds(5);
std::iota(inds.data(), inds.data()+inds.size(), 0);
std::iota(inds.data(), inds.data()+inds.size(), 3);
feats->add_subset(inds);
SGVector<index_t> inds2(2);
std::iota(inds2.data(), inds2.data()+inds2.size(), 0);
std::iota(inds2.data(), inds2.data()+inds2.size(), 1);
feats->add_subset(inds2);

auto shallow_copy=static_cast<CDenseFeatures<float64_t>*>(FeaturesUtil::create_shallow_copy(feats));
Expand All @@ -62,12 +62,6 @@ TEST(FeaturesUtil, create_shallow_copy)
ASSERT_TRUE(dim==num_feats);
ASSERT_TRUE(num_vec==num_vecs);

auto src_subset_stack=feats->get_subset_stack();
auto dst_subset_stack=shallow_copy->get_subset_stack();
ASSERT_TRUE(src_subset_stack->equals(dst_subset_stack));
SG_UNREF(src_subset_stack);
SG_UNREF(dst_subset_stack);

SGMatrix<float64_t> src=feats->get_feature_matrix();
SGMatrix<float64_t> dst=shallow_copy->get_feature_matrix();
ASSERT(src.equals(dst));
Expand Down Expand Up @@ -113,3 +107,35 @@ TEST(FeaturesUtil, create_merged_copy)
SG_UNREF(feats_a);
SG_UNREF(feats_b);
}

TEST(FeaturesUtil, clone_subset_stack)
{
const index_t dim=2;
const index_t num_vec=10;

SGMatrix<float64_t> data(dim, num_vec);
std::iota(data.matrix, data.matrix+dim*num_vec, 0);

auto feats=new CDenseFeatures<float64_t>(data);
SGVector<index_t> inds(5);
std::iota(inds.data(), inds.data()+inds.size(), 3);
feats->add_subset(inds);
SGVector<index_t> inds2(2);
std::iota(inds2.data(), inds2.data()+inds2.size(), 1);
feats->add_subset(inds2);

auto copy=new CDenseFeatures<float64_t>(data);
FeaturesUtil::clone_subset_stack(feats, copy);

auto src_subset_stack=feats->get_subset_stack();
auto dst_subset_stack=copy->get_subset_stack();
ASSERT_TRUE(src_subset_stack->equals(dst_subset_stack));
SG_UNREF(src_subset_stack);
SG_UNREF(dst_subset_stack);

copy->remove_all_subsets();
SG_UNREF(copy);

feats->remove_all_subsets();
SG_UNREF(feats);
}

0 comments on commit b45d490

Please sign in to comment.