Skip to content

Commit

Permalink
Merge pull request #2292 from lambday/develop
Browse files Browse the repository at this point in the history
added proper lapack check to address issue #2291
  • Loading branch information
lambday committed Jun 10, 2014
2 parents a58d12d + d194676 commit 0e4bf9f
Show file tree
Hide file tree
Showing 12 changed files with 48 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

using namespace shogun;


#ifdef HAVE_LAPACK
void kernel_choice_linear_time_mmd_opt_single()
{
/* Note that the linear time mmd is designed for large datasets. Results on
Expand Down Expand Up @@ -195,17 +195,20 @@ void kernel_choice_linear_time_mmd_opt_comb()

SG_UNREF(selection);
}
#endif // HAVE_LAPACK

int main(int argc, char** argv)
{
init_shogun_with_defaults();
// sg_io->set_loglevel(MSG_DEBUG);

#ifdef HAVE_LAPACK
/* select a single kernel for linear time MMD */
kernel_choice_linear_time_mmd_opt_single();

/* select combined kernels for linear time MMD */
kernel_choice_linear_time_mmd_opt_comb();
#endif

exit_shogun();
return 0;
Expand Down
25 changes: 10 additions & 15 deletions src/shogun/statistics/MMDKernelSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,23 @@ CMMDKernelSelection::CMMDKernelSelection()
init();
}

CMMDKernelSelection::CMMDKernelSelection(
CKernelTwoSampleTest* mmd)
CMMDKernelSelection::CMMDKernelSelection(CKernelTwoSampleTest* mmd)
{
init();

/* ensure that mmd contains an instance of a MMD related class */
REQUIRE(mmd, "CMMDKernelSelection::CMMDKernelSelection(): No MMD instance "
"provided!\n");
REQUIRE(mmd, "No MMD instance provided!\n");
REQUIRE(mmd->get_statistic_type()==S_LINEAR_TIME_MMD ||
mmd->get_statistic_type()==S_QUADRATIC_TIME_MMD,
"CMMDKernelSelection::CMMDKernelSelection(): provided instance "
"for kernel two sample testing has to be a MMD-based class! The "
"provided is of class \"%s\"\n", mmd->get_name());
"Provided instance for kernel two sample testing has to be a MMD-"
"based class! The provided is of class \"%s\"\n", mmd->get_name());

/* ensure that there is a combined kernel */
CKernel* kernel=mmd->get_kernel();
REQUIRE(kernel, "CMMDKernelSelection::CMMDKernelSelection(): underlying "
"\"%s\" has no kernel set!\n", mmd->get_name());
REQUIRE(kernel->get_kernel_type()==K_COMBINED, "CMMDKernelSelection::"
"CMMDKernelSelection(): kernel of underlying \"%s\" is of type \"%s\""
" but is has to be CCombinedKernel\n", mmd->get_name(),
kernel->get_name());
REQUIRE(kernel, "Underlying \"%s\" has no kernel set!\n", mmd->get_name());
REQUIRE(kernel->get_kernel_type()==K_COMBINED, "Kernel of underlying \"%s\" "
"is of type \"%s\" but is has to be CCombinedKernel\n",
mmd->get_name(), kernel->get_name());
SG_UNREF(kernel);

m_mmd=mmd;
Expand All @@ -65,7 +60,7 @@ void CMMDKernelSelection::init()

CKernel* CMMDKernelSelection::select_kernel()
{
SG_DEBUG("entering CMMDKernelSelection::select_kernel()\n")
SG_DEBUG("entering\n")

/* compute measures and return single kernel with maximum measure */
SGVector<float64_t> measures=compute_measures();
Expand All @@ -87,7 +82,7 @@ CKernel* CMMDKernelSelection::select_kernel()
CKernel* current=combined->get_kernel(max_idx);

SG_UNREF(combined);
SG_DEBUG("leaving CMMDKernelSelection::select_kernel()\n");
SG_DEBUG("leaving\n");

/* current is not SG_UNREF'ed nor SG_REF'ed since the counter needs to be
* incremented exactly by one */
Expand Down
2 changes: 1 addition & 1 deletion src/shogun/statistics/MMDKernelSelection.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class CMMDKernelSelection: public CSGObject
virtual CKernel* select_kernel();

/** @return name of the SGSerializable */
const char* get_name() const=0;
virtual const char* get_name() const=0;

private:

Expand Down
59 changes: 16 additions & 43 deletions src/shogun/statistics/MMDKernelSelectionComb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ void CMMDKernelSelectionComb::init()
#endif
}

CKernel* CMMDKernelSelectionComb::select_kernel()
{
/* cast is safe due to assertion in constructor */
CCombinedKernel* combined=(CCombinedKernel*)m_mmd->get_kernel();

/* optimise for kernel weights and set them */
SGVector<float64_t> weights=compute_measures();
combined->set_subkernel_weights(weights);

/* note that kernel is SG_REF'ed from getter above */
return combined;
}

#ifdef HAVE_LAPACK
/* no reference counting, use the static context constructor of SGMatrix */
SGMatrix<float64_t> CMMDKernelSelectionComb::m_Q=SGMatrix<float64_t>(false);
Expand All @@ -58,21 +71,7 @@ const float64_t* CMMDKernelSelectionComb::get_Q_col(uint32_t i)
/** helper function that prints current state */
void CMMDKernelSelectionComb::print_state(libqp_state_T state)
{
SG_SDEBUG("CMMDKernelSelectionComb::print_state: libqp state:"
" primal=%f\n", state.QP);
}

CKernel* CMMDKernelSelectionComb::select_kernel()
{
/* cast is safe due to assertion in constructor */
CCombinedKernel* combined=(CCombinedKernel*)m_mmd->get_kernel();

/* optimise for kernel weights and set them */
SGVector<float64_t> weights=compute_measures();
combined->set_subkernel_weights(weights);

/* note that kernel is SG_REF'ed from getter above */
return combined;
SG_SDEBUG("libqp state: primal=%f\n", state.QP);
}

SGVector<float64_t> CMMDKernelSelectionComb::solve_optimization(
Expand Down Expand Up @@ -111,9 +110,8 @@ SGVector<float64_t> CMMDKernelSelectionComb::solve_optimization(

if (!one_pos)
{
SG_WARNING("CMMDKernelSelectionComb::solve_optimization(): all mmd "
"estimates are negative. This is techically possible, although "
"extremely rare. Consider using different kernels. "
SG_WARNING("All mmd estimates are negative. This is techically possible,"
"although extremely rare. Consider using different kernels. "
"This combination will lead to a bad two-sample test. Since any"
"combination is bad, will now just return equally distributed "
"kernel weights\n");
Expand Down Expand Up @@ -170,29 +168,4 @@ SGVector<float64_t> CMMDKernelSelectionComb::solve_optimization(

return weights;
}
#else
CKernel* CMMDKernelSelectionComb::select_kernel()
{
SG_ERROR("CMMDKernelSelectionComb::select_kernel(): LAPACK needs to be "
"installed in order to use weight optimisation for combined "
"kernels!\n");
return NULL;
}

SGVector<float64_t> CMMDKernelSelectionComb::compute_measures()
{
SG_ERROR("CMMDKernelSelectionComb::select_kernel(): LAPACK needs to be "
"installed in order to use weight optimisation for combined "
"kernels!\n");
return SGVector<float64_t>();
}

SGVector<float64_t> CMMDKernelSelectionComb::solve_optimization(
SGVector<float64_t> mmds)
{
SG_ERROR("CMMDKernelSelectionComb::solve_optimization(): LAPACK needs to be "
"installed in order to use weight optimisation for combined "
"kernels!\n");
return SGVector<float64_t>();
}
#endif
19 changes: 2 additions & 17 deletions src/shogun/statistics/MMDKernelSelectionComb.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,6 @@ class CMMDKernelSelectionComb: public CMMDKernelSelection
/** Destructor */
virtual ~CMMDKernelSelectionComb();

#ifdef HAVE_LAPACK
/** Abstract method that computes weights of the selected combined kernel.
*
* @return weights of the selected kernel
*/
virtual SGVector<float64_t> compute_measures()=0;
#else
/** Abstract method that computes weights of the selected combined kernel.
* LAPACK needs to be installed for this method to work. Please install!
*
* @return Throws an error
*/
virtual SGVector<float64_t> compute_measures();
#endif

/** @return computes weights for the underlying kernel, sets them to it, and
* returns it (SG_REF'ed)
*
Expand All @@ -65,9 +50,10 @@ class CMMDKernelSelectionComb: public CMMDKernelSelection
virtual CKernel* select_kernel();

/** @return name of the SGSerializable */
const char* get_name() const=0;
virtual const char* get_name() const=0;

protected:
#ifdef HAVE_LAPACK
/** Solves the quadratic program
* \f[
* \min_\beta \{\beta^T Q \beta \quad \text{s.t.}\quad \beta^T \eta=1, \beta\succeq 0\},
Expand All @@ -82,7 +68,6 @@ class CMMDKernelSelectionComb: public CMMDKernelSelection
*/
virtual SGVector<float64_t> solve_optimization(SGVector<float64_t> mmds);

#ifdef HAVE_LAPACK
/** return pointer to i-th column of m_Q. Helper for libqp */
static const float64_t* get_Q_col(uint32_t i);

Expand Down
5 changes: 4 additions & 1 deletion src/shogun/statistics/MMDKernelSelectionCombMaxL2.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ class CMMDKernelSelectionCombMaxL2: public CMMDKernelSelectionComb
#endif

/** @return name of the SGSerializable */
const char* get_name() const { return "MMDKernelSelectionCombMaxL2"; }
virtual const char* get_name() const
{
return "MMDKernelSelectionCombMaxL2";
}
};

}
Expand Down
5 changes: 4 additions & 1 deletion src/shogun/statistics/MMDKernelSelectionCombOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ class CMMDKernelSelectionCombOpt: public CMMDKernelSelectionComb
#endif

/** @return name of the SGSerializable */
const char* get_name() const { return "MMDKernelSelectionCombOpt"; }
virtual const char* get_name() const
{
return "MMDKernelSelectionCombOpt";
}

private:
/** Initializer */
Expand Down
2 changes: 1 addition & 1 deletion src/shogun/statistics/MMDKernelSelectionMax.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class CMMDKernelSelectionMax: public CMMDKernelSelection
virtual SGVector<float64_t> compute_measures();

/** @return name of the SGSerializable */
const char* get_name() const { return "MMDKernelSelectionMax"; }
virtual const char* get_name() const { return "MMDKernelSelectionMax"; }
};

}
Expand Down
2 changes: 1 addition & 1 deletion src/shogun/statistics/MMDKernelSelectionMedian.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class CMMDKernelSelectionMedian: public CMMDKernelSelection
virtual CKernel* select_kernel();

/** @return name of the SGSerializable */
const char* get_name() const { return "MMDKernelSelectionMedian"; }
virtual const char* get_name() const { return "MMDKernelSelectionMedian"; }

private:
/* initialises and registers member variables */
Expand Down
2 changes: 1 addition & 1 deletion src/shogun/statistics/MMDKernelSelectionOpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class CMMDKernelSelectionOpt: public CMMDKernelSelection
virtual SGVector<float64_t> compute_measures();

/** @return name of the SGSerializable */
const char* get_name() const { return "MMDKernelSelectionOpt"; }
virtual const char* get_name() const { return "MMDKernelSelectionOpt"; }

private:
/** Initializer */
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/statistics/MMDKernelSelectionCombMaxL2_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

using namespace shogun;

#ifdef HAVE_LAPACK
TEST(MMDKernelSelectionCombMaxL2, select_kernel)
{
index_t m=8;
Expand Down Expand Up @@ -101,3 +102,4 @@ TEST(MMDKernelSelectionCombMaxL2, select_kernel)
SG_UNREF(selection);
SG_UNREF(result);
}
#endif // HAVE_LAPACK
2 changes: 2 additions & 0 deletions tests/unit/statistics/MMDKernelSelectionCombOpt_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

using namespace shogun;

#ifdef HAVE_LAPACK
TEST(MMDKernelSelectionCombOpt, select_kernel)
{
index_t m=8;
Expand Down Expand Up @@ -102,3 +103,4 @@ TEST(MMDKernelSelectionCombOpt, select_kernel)
SG_UNREF(selection);
SG_UNREF(result);
}
#endif // HAVE_LAPACK

0 comments on commit 0e4bf9f

Please sign in to comment.