From 5c35b41ced8859ca590c28308b188aa5d37d16b7 Mon Sep 17 00:00:00 2001 From: lambday Date: Fri, 13 May 2016 14:56:40 +0100 Subject: [PATCH] fixed clone subset stack bug in features util --- .../internals/FeaturesUtil.cpp | 69 +++++++++++++------ .../internals/FeaturesUtil.h | 8 +++ .../internals/FeaturesUtil_unittest.cc | 42 ++++++++--- 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/src/shogun/statistical_testing/internals/FeaturesUtil.cpp b/src/shogun/statistical_testing/internals/FeaturesUtil.cpp index 285059a3f76..9762c23bc93 100644 --- a/src/shogun/statistical_testing/internals/FeaturesUtil.cpp +++ b/src/shogun/statistical_testing/internals/FeaturesUtil.cpp @@ -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 feats_matrix(data, num_feats, num_vecs, false); shallow_copy=new CDenseFeatures(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(src_subset_stack->clone()); - std::stack> 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; @@ -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(src_subset_stack->clone()); + std::stack> 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 ref=stack.top(); + dst->add_subset(ref); + stack.pop(); + do + { + SGVector inds=stack.top(); + for (auto i=0, j=0; iadd_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"); +} diff --git a/src/shogun/statistical_testing/internals/FeaturesUtil.h b/src/shogun/statistical_testing/internals/FeaturesUtil.h index 639e3a6089b..760e5be3316 100644 --- a/src/shogun/statistical_testing/internals/FeaturesUtil.h +++ b/src/shogun/statistical_testing/internals/FeaturesUtil.h @@ -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); }; } diff --git a/tests/unit/statistical_testing/internals/FeaturesUtil_unittest.cc b/tests/unit/statistical_testing/internals/FeaturesUtil_unittest.cc index 8e5925ab8cb..5d48e79c007 100644 --- a/tests/unit/statistical_testing/internals/FeaturesUtil_unittest.cc +++ b/tests/unit/statistical_testing/internals/FeaturesUtil_unittest.cc @@ -49,10 +49,10 @@ TEST(FeaturesUtil, create_shallow_copy) auto feats=new CDenseFeatures(data); SGVector 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 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*>(FeaturesUtil::create_shallow_copy(feats)); @@ -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 src=feats->get_feature_matrix(); SGMatrix dst=shallow_copy->get_feature_matrix(); ASSERT(src.equals(dst)); @@ -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 data(dim, num_vec); + std::iota(data.matrix, data.matrix+dim*num_vec, 0); + + auto feats=new CDenseFeatures(data); + SGVector inds(5); + std::iota(inds.data(), inds.data()+inds.size(), 3); + feats->add_subset(inds); + SGVector inds2(2); + std::iota(inds2.data(), inds2.data()+inds2.size(), 1); + feats->add_subset(inds2); + + auto copy=new CDenseFeatures(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); +}