Skip to content

Commit

Permalink
add CLabels::as_binary converter
Browse files Browse the repository at this point in the history
make some methods const, add copy constructors, add CBinaryLabels::from(...)
  • Loading branch information
karlnapf committed Mar 19, 2018
1 parent 5c7c5de commit 38e7e2f
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 9 deletions.
26 changes: 26 additions & 0 deletions src/shogun/labels/BinaryLabels.cpp
Expand Up @@ -10,13 +10,18 @@
#include <shogun/labels/BinaryLabels.h>
#include <shogun/mathematics/Statistics.h>
#include <shogun/lib/SGVector.h>
#include <shogun/base/range.h>

using namespace shogun;

CBinaryLabels::CBinaryLabels() : CDenseLabels()
{
}

CBinaryLabels::CBinaryLabels(const CBinaryLabels& orig) : CDenseLabels(orig)
{
}

CBinaryLabels::CBinaryLabels(int32_t num_labels) : CDenseLabels(num_labels)
{
}
Expand Down Expand Up @@ -149,3 +154,24 @@ CLabels* CBinaryLabels::shallow_subset_copy()

return shallow_copy_labels;
}

Some<CBinaryLabels> CBinaryLabels::from(const CDenseLabels* orig)
{
auto labels = orig->get_labels();
for (auto i : range(labels.vlen))
{
if (!CMath::fequals(labels[i], 1.0, 0.0) && !CMath::fequals(labels[i], -1.0, 0.0))
{
SG_SERROR("Label at index %d (%f), but must be either +1.0 or -1.0.\n", i, labels[i])
}
}
auto result = Some<CBinaryLabels>::from_raw(new CBinaryLabels(labels));
result->set_values(orig->get_values());
return result;
}

Some<CBinaryLabels> CBinaryLabels::from(const CMulticlassLabels* orig)
{
SG_SNOTIMPLEMENTED
return Some<CBinaryLabels>::from_raw(nullptr);
}
9 changes: 9 additions & 0 deletions src/shogun/labels/BinaryLabels.h
Expand Up @@ -14,6 +14,7 @@
#include <shogun/lib/common.h>
#include <shogun/labels/LabelTypes.h>
#include <shogun/labels/DenseLabels.h>
#include <shogun/labels/MulticlassLabels.h>

namespace shogun
{
Expand All @@ -36,6 +37,9 @@ class CBinaryLabels : public CDenseLabels
/** default constructor */
CBinaryLabels();

/** Copy constructor */
CBinaryLabels(const CBinaryLabels& orig);

/** constructor
*
* @param num_labels number of labels
Expand Down Expand Up @@ -112,6 +116,11 @@ class CBinaryLabels : public CDenseLabels
{
return "BinaryLabels";
}

#ifndef SWIG
static Some<CBinaryLabels> from(const CDenseLabels* orig);
static Some<CBinaryLabels> from(const CMulticlassLabels* orig);
#endif // SWIG
#ifndef SWIG // SWIG should skip this part
virtual CLabels* shallow_subset_copy();
#endif
Expand Down
13 changes: 10 additions & 3 deletions src/shogun/labels/DenseLabels.cpp
Expand Up @@ -14,6 +14,7 @@
#include <shogun/mathematics/Math.h>
#include <shogun/mathematics/linalg/LinalgNamespace.h>


using namespace shogun;

CDenseLabels::CDenseLabels()
Expand All @@ -22,6 +23,12 @@ CDenseLabels::CDenseLabels()
init();
}

CDenseLabels::CDenseLabels(const CDenseLabels& orig) : CLabels(orig)
{
init();
m_labels = orig.m_labels;
}

CDenseLabels::CDenseLabels(int32_t num_lab)
: CLabels()
{
Expand Down Expand Up @@ -77,15 +84,15 @@ void CDenseLabels::set_labels(SGVector<float64_t> v)
m_labels = v;
}

SGVector<float64_t> CDenseLabels::get_labels()
SGVector<float64_t> CDenseLabels::get_labels() const
{
if (m_subset_stack->has_subsets())
return get_labels_copy();

return m_labels;
}

SGVector<float64_t> CDenseLabels::get_labels_copy()
SGVector<float64_t> CDenseLabels::get_labels_copy() const
{
if (!m_subset_stack->has_subsets())
return m_labels.clone();
Expand Down Expand Up @@ -179,7 +186,7 @@ bool CDenseLabels::set_int_label(int32_t idx, int32_t label)
return false;
}

float64_t CDenseLabels::get_label(int32_t idx)
float64_t CDenseLabels::get_label(int32_t idx) const
{
int32_t real_num=m_subset_stack->subset_idx_conversion(idx);
ASSERT(m_labels.vector && idx<get_num_labels())
Expand Down
15 changes: 11 additions & 4 deletions src/shogun/labels/DenseLabels.h
Expand Up @@ -16,9 +16,11 @@
#include <shogun/labels/Labels.h>
#include <shogun/features/SubsetStack.h>


namespace shogun
{
class CFile;
class CBinaryLabels;

/** @brief Dense integer or floating point labels
*
Expand All @@ -34,6 +36,9 @@ class CDenseLabels : public CLabels
/** default constructor */
CDenseLabels();

/** Copy constructor */
CDenseLabels(const CDenseLabels& orig);

/** constructor
*
* @param num_labels number of labels
Expand Down Expand Up @@ -97,7 +102,7 @@ class CDenseLabels : public CLabels
*
* @return labels, a copy if a subset is set
*/
SGVector<float64_t> get_labels();
SGVector<float64_t> get_labels() const;

/** get label
*
Expand All @@ -106,7 +111,7 @@ class CDenseLabels : public CLabels
* @param idx index of label to get
* @return value of label
*/
float64_t get_label(int32_t idx);
float64_t get_label(int32_t idx) const;

/** get label
*
Expand Down Expand Up @@ -141,7 +146,7 @@ class CDenseLabels : public CLabels
*
* @return labels
*/
SGVector<float64_t> get_labels_copy();
SGVector<float64_t> get_labels_copy() const;

/** Getter for labels
*
Expand Down Expand Up @@ -256,7 +261,9 @@ class CDenseLabels : public CLabels
*
* @return label type (binary, multiclass, ...)
*/
virtual ELabelType get_label_type() const=0;
virtual ELabelType get_label_type() const override { return LT_DENSE_GENERIC; }

virtual const char* get_name() const override { return "DenseLabels"; }

public:
/** label designates classify reject */
Expand Down
2 changes: 2 additions & 0 deletions src/shogun/labels/LabelTypes.h
Expand Up @@ -24,5 +24,7 @@ enum ELabelType
LT_LATENT = 5,
/// sparse label class for multilabel classification (sets of labels)
LT_SPARSE_MULTILABEL = 6,
/// generic dense labels type
LT_DENSE_GENERIC = 7
};
#endif
36 changes: 35 additions & 1 deletion src/shogun/labels/Labels.cpp
Expand Up @@ -6,6 +6,9 @@
*/

#include <shogun/labels/Labels.h>
#include <shogun/labels/DenseLabels.h>
#include <shogun/labels/BinaryLabels.h>
#include <shogun/labels/MulticlassLabels.h>
#include <shogun/lib/common.h>
#include <shogun/io/SGIO.h>

Expand All @@ -17,6 +20,13 @@ CLabels::CLabels()
init();
}

CLabels::CLabels(const CLabels& orig)
{
m_current_values = orig.m_current_values;
m_subset_stack = orig.m_subset_stack;
SG_REF(m_subset_stack);
}

CLabels::~CLabels()
{
SG_UNREF(m_subset_stack);
Expand Down Expand Up @@ -90,7 +100,31 @@ void CLabels::set_values(SGVector<float64_t> values)
m_current_values = values;
}

SGVector<float64_t> CLabels::get_values()
SGVector<float64_t> CLabels::get_values() const
{
return m_current_values;
}

Some<CBinaryLabels> CLabels::as_binary() const
{
try
{
switch(get_label_type())
{
case LT_BINARY:
return Some<CBinaryLabels>::from_raw(new CBinaryLabels(*as<CBinaryLabels>()));
case LT_DENSE_GENERIC:
return CBinaryLabels::from(as<CDenseLabels>());
case LT_MULTICLASS:
return CBinaryLabels::from(as<CMulticlassLabels>());
default:
SG_NOTIMPLEMENTED
}
}
catch (const ShogunException& e)
{
SG_SERROR("Cannot convert %s to binary labels: \n", e.what(), get_name());
}

return Some<CBinaryLabels>::from_raw(nullptr);
}
13 changes: 12 additions & 1 deletion src/shogun/labels/Labels.h
Expand Up @@ -12,6 +12,7 @@
#include <shogun/lib/config.h>

#include <shogun/lib/common.h>
#include <shogun/base/some.h>
#include <shogun/base/SGObject.h>
#include <shogun/labels/LabelsFactory.h>
#include <shogun/labels/LabelTypes.h>
Expand All @@ -20,6 +21,8 @@

namespace shogun
{
class CBinaryLabels;

/** @brief The class Labels models labels, i.e. class assignments of objects.
*
* Labels is the base class for general Label objects.
Expand All @@ -42,9 +45,17 @@ class CLabels : public CSGObject
/** default constructor */
CLabels();

/* Copy constructor */
CLabels(const CLabels& orig);

/** destructor */
virtual ~CLabels();


#ifndef SWIG
/** Returns a new instance of labels of the specified type. */
virtual Some<CBinaryLabels> as_binary() const;
#endif
/** Make sure the label is valid, otherwise raise SG_ERROR.
*
* possible with subset
Expand Down Expand Up @@ -122,7 +133,7 @@ class CLabels : public CSGObject
*
* @return confidences
*/
virtual SGVector<float64_t> get_values();
virtual SGVector<float64_t> get_values() const;

#ifndef SWIG // SWIG should skip this part
virtual CLabels* shallow_subset_copy()
Expand Down

0 comments on commit 38e7e2f

Please sign in to comment.