Skip to content

Commit

Permalink
Merge pull request #4249 from karlnapf/feature/clone_with_tags
Browse files Browse the repository at this point in the history
Tag-based clone and some tests
  • Loading branch information
karlnapf committed Apr 15, 2018
2 parents e33a472 + 2c96990 commit f755ebe
Show file tree
Hide file tree
Showing 49 changed files with 327 additions and 1,697 deletions.
496 changes: 0 additions & 496 deletions src/shogun/base/Parameter.cpp

Large diffs are not rendered by default.

25 changes: 0 additions & 25 deletions src/shogun/base/Parameter.h
Expand Up @@ -56,31 +56,6 @@ struct TParameter
*/
bool load(CSerializableFile* file, const char* prefix="");

/** copy primitive type from source to target
*
* @param ptype the primitive type
* @param source from where to copy
* @param target where to copy to
*/
static bool copy_ptype(EPrimitiveType ptype, void* source, void* target);

/** copy structured type from source to target
*
* @param stype the structured type
* @param ptype the primitive type that the structured objects use
* @param source from where to copy
* @param target where to copy to
*/
static bool copy_stype(EStructType stype, EPrimitiveType ptype,
void* source, void* target);

/** copy this to parameter target
*
* @param target where this should be copied to
*/
bool copy(TParameter* target);


/** operator for comparison, (by string m_name) */
bool operator==(const TParameter& other) const;

Expand Down
70 changes: 24 additions & 46 deletions src/shogun/base/SGObject.cpp
Expand Up @@ -673,59 +673,33 @@ void CSGObject::build_gradient_parameter_dictionary(CMap<TParameter*, CSGObject*

CSGObject* CSGObject::clone()
{
SG_DEBUG("Constructing an empty instance of %s\n", get_name());
CSGObject* copy = create_empty();
SG_DEBUG("Starting to clone %s at %p.\n", get_name(), this);
SG_DEBUG("Constructing an empty instance of %s.\n", get_name());
CSGObject* clone = create_empty();
SG_DEBUG("Empty instance of %s created at %p.\n", get_name(), clone);

REQUIRE(
copy, "Could not create empty instance of %s. The reason for "
clone, "Could not create empty instance of %s. The reason for "
"this usually is that get_name() of the class returns something "
"wrong, that a class has a wrongly set generic type, or that it "
"lies outside the main source tree and does not have "
"CSGObject::create_empty() overridden.\n",
get_name());

SG_DEBUG("Cloning all parameters of %s\n", get_name());
if (!copy->clone_parameters(this))
{
SG_WARNING("Cloning parameters failed.\n");
}
else
for (const auto it : self->map)
{
SG_DEBUG("Done cloning.\n");
}

return copy;
}

bool CSGObject::clone_parameters(CSGObject* other)
{
REQUIRE(other, "Provided instance must be non-empty.\n");
index_t num_parameters = m_parameters->get_num_parameters();

REQUIRE(other->m_parameters->get_num_parameters() == num_parameters,
"Number of parameters of provided instance (%d) must match this instance (%d).\n",
other->m_parameters->get_num_parameters(), num_parameters);
REQUIRE(!strcmp(other->get_name(), get_name()),
"Name of provided instance (%s) must match this instance (%s).\n",
other->get_name(), get_name());
const BaseTag& tag = it.first;
const Any& own = it.second.get_value();

for (index_t i=0; i<num_parameters; ++i)
{
SG_DEBUG("Cloning parameter \"%s\" at index %d into this instance\n",
other->m_parameters->get_parameter(i)->m_name, i);
SG_SDEBUG(
"Cloning parameter %s::%s of type %s.\n", this->get_name(),
tag.name().c_str(), own.type().c_str());

if (!other->m_parameters->get_parameter(i)->copy(m_parameters->get_parameter(i)))
{
SG_WARNING("Cloning parameter \"%s\" (at index %d) of provided instance %s"
" into parameter \"%s\" of this instance %s failed.\n",
other->m_parameters->get_parameter(i)->m_name, i,
other->get_name(), m_parameters->get_parameter(i)->m_name,
get_name());
return false;
}
clone->get_parameter(tag).get_value().clone_from(own);
}

return true;
SG_DEBUG("Done cloning %s at %p, new object at %p.\n", get_name(), this, clone);
return clone;
}

void CSGObject::create_parameter(
Expand Down Expand Up @@ -868,6 +842,10 @@ class ToStringVisitor : public AnyVisitor
{
stream() << *v;
}
virtual void on(long double* v)
{
stream() << *v;
}
virtual void on(const CSGObject** v)
{
if (*v)
Expand Down Expand Up @@ -1006,13 +984,13 @@ bool CSGObject::equals(const CSGObject* other) const
/* Assumption: objects of same type have same set of tags. */
for (const auto it : self->map)
{
auto tag = it.first;
auto own = it.second;
auto given = other->get_parameter(tag);
const BaseTag& tag = it.first;
const Any& own = it.second.get_value();
const Any& given = other->get_parameter(tag).get_value();

SG_SDEBUG(
"Comparing parameter %s::%s of type %s.\n", this->get_name(),
tag.name().c_str(), own.get_value().type().c_str());
tag.name().c_str(), own.type().c_str());
if (own != given)
{
if (io->get_loglevel() <= MSG_DEBUG)
Expand All @@ -1022,11 +1000,11 @@ bool CSGObject::equals(const CSGObject* other) const

ss << "Own parameter " << this->get_name() << "::" << tag.name()
<< "=";
own.get_value().visit(visitor.get());
own.visit(visitor.get());

ss << " different from provided " << other->get_name()
<< "::" << tag.name() << "=";
given.get_value().visit(visitor.get());
given.visit(visitor.get());

SG_SDEBUG("%s\n", ss.str().c_str());
}
Expand Down
9 changes: 0 additions & 9 deletions src/shogun/base/SGObject.h
Expand Up @@ -698,15 +698,6 @@ class CSGObject
*/
virtual CSGObject* create_empty() const;

/** Iteratively clones all parameters of the provided instance into this instance.
* This will fail if the objects have different sets of registered parameters,
* or if they have a different type as defined by get_name().
*
* @param other object whose parameters are to be cloned into this instance
* @return true if cloning was successful
*/
bool clone_parameters(CSGObject* other);

private:
void set_global_objects();
void unset_global_objects();
Expand Down
25 changes: 13 additions & 12 deletions src/shogun/classifier/PluginEstimate.cpp
Expand Up @@ -20,18 +20,19 @@ CPluginEstimate::CPluginEstimate(float64_t pos_pseudo, float64_t neg_pseudo)
: CMachine(), m_pos_pseudo(1e-10), m_neg_pseudo(1e-10),
pos_model(NULL), neg_model(NULL), features(NULL)
{
m_parameters->add(&m_pos_pseudo,
"pos_pseudo","pseudo count for positive class");
m_parameters->add(&m_neg_pseudo,
"neg_pseudo", "pseudo count for negative class");

m_parameters->add((CSGObject**) &pos_model,
"pos_model", "LinearHMM modelling positive class.");
m_parameters->add((CSGObject**) &neg_model,
"neg_model", "LinearHMM modelling negative class.");

m_parameters->add((CSGObject**) &features,
"features", "String Features.");
SG_ADD(
&m_pos_pseudo, "pos_pseudo", "pseudo count for positive class",
MS_NOT_AVAILABLE);
SG_ADD(
&m_neg_pseudo, "neg_pseudo", "pseudo count for negative class",
MS_NOT_AVAILABLE);
SG_ADD(
&pos_model, "pos_model", "LinearHMM modelling positive class.",
MS_NOT_AVAILABLE);
SG_ADD(
&neg_model, "neg_model", "LinearHMM modelling negative class.",
MS_NOT_AVAILABLE);
SG_ADD(&features, "features", "String Features.", MS_NOT_AVAILABLE);
}

CPluginEstimate::~CPluginEstimate()
Expand Down
7 changes: 4 additions & 3 deletions src/shogun/classifier/svm/OnlineLibLinear.cpp
Expand Up @@ -63,9 +63,10 @@ void COnlineLibLinear::init()
Cn=1;
use_bias=false;

m_parameters->add(&C1, "C1", "C Cost constant 1.");
m_parameters->add(&C2, "C2", "C Cost constant 2.");
m_parameters->add(&use_bias, "use_bias", "Indicates if bias is used.");
SG_ADD(&C1, "C1", "C Cost constant 1.", MS_AVAILABLE);
SG_ADD(&C2, "C2", "C Cost constant 2.", MS_AVAILABLE);
SG_ADD(
&use_bias, "use_bias", "Indicates if bias is used.", MS_NOT_AVAILABLE);

PG = 0;
PGmax_old = CMath::INFTY;
Expand Down
23 changes: 13 additions & 10 deletions src/shogun/classifier/svm/OnlineSVMSGD.cpp
Expand Up @@ -204,14 +204,17 @@ void COnlineSVMSGD::init()
loss=new CHingeLoss();
SG_REF(loss);

m_parameters->add(&C1, "C1", "Cost constant 1.");
m_parameters->add(&C2, "C2", "Cost constant 2.");
m_parameters->add(&lambda, "lambda", "Regularization parameter.");
m_parameters->add(&wscale, "wscale", "W scale");
m_parameters->add(&bscale, "bscale", "b scale");
m_parameters->add(&epochs, "epochs", "epochs");
m_parameters->add(&skip, "skip", "skip");
m_parameters->add(&count, "count", "count");
m_parameters->add(&use_bias, "use_bias", "Indicates if bias is used.");
m_parameters->add(&use_regularized_bias, "use_regularized_bias", "Indicates if bias is regularized.");
SG_ADD(&C1, "C1", "Cost constant 1.", MS_AVAILABLE);
SG_ADD(&C2, "C2", "Cost constant 2.", MS_AVAILABLE);
SG_ADD(&lambda, "lambda", "Regularization parameter.", MS_AVAILABLE);
SG_ADD(&wscale, "wscale", "W scale", MS_NOT_AVAILABLE);
SG_ADD(&bscale, "bscale", "b scale", MS_NOT_AVAILABLE);
SG_ADD(&epochs, "epochs", "epochs", MS_NOT_AVAILABLE);
SG_ADD(&skip, "skip", "skip", MS_NOT_AVAILABLE);
SG_ADD(&count, "count", "count", MS_NOT_AVAILABLE);
SG_ADD(
&use_bias, "use_bias", "Indicates if bias is used.", MS_NOT_AVAILABLE);
SG_ADD(
&use_regularized_bias, "use_regularized_bias",
"Indicates if bias is regularized.", MS_NOT_AVAILABLE);
}
10 changes: 5 additions & 5 deletions src/shogun/classifier/svm/SGDQN.cpp
Expand Up @@ -224,9 +224,9 @@ void CSGDQN::init()
loss=new CHingeLoss();
SG_REF(loss);

m_parameters->add(&C1, "C1", "Cost constant 1.");
m_parameters->add(&C2, "C2", "Cost constant 2.");
m_parameters->add(&epochs, "epochs", "epochs");
m_parameters->add(&skip, "skip", "skip");
m_parameters->add(&count, "count", "count");
SG_ADD(&C1, "C1", "Cost constant 1.", MS_AVAILABLE);
SG_ADD(&C2, "C2", "Cost constant 2.", MS_AVAILABLE);
SG_ADD(&epochs, "epochs", "epochs", MS_AVAILABLE);
SG_ADD(&skip, "skip", "skip", MS_NOT_AVAILABLE);
SG_ADD(&count, "count", "count", MS_NOT_AVAILABLE);
}
19 changes: 11 additions & 8 deletions src/shogun/classifier/svm/SVMOcas.cpp
Expand Up @@ -345,14 +345,17 @@ void CSVMOcas::init()

primal_objective = 0.0;

m_parameters->add(&C1, "C1", "Cost constant 1.");
m_parameters->add(&C2, "C2", "Cost constant 2.");
m_parameters->add(&use_bias, "use_bias",
"Indicates if bias is used.");
m_parameters->add(&epsilon, "epsilon", "Convergence precision.");
m_parameters->add(&bufsize, "bufsize", "Maximum number of cutting planes.");
m_parameters->add((machine_int_t*) &method, "method",
"SVMOcas solver type.");
SG_ADD(&C1, "C1", "Cost constant 1.", MS_AVAILABLE);
SG_ADD(&C2, "C2", "Cost constant 2.", MS_AVAILABLE);
SG_ADD(
&use_bias, "use_bias", "Indicates if bias is used.", MS_NOT_AVAILABLE);
SG_ADD(&epsilon, "epsilon", "Convergence precision.", MS_NOT_AVAILABLE);
SG_ADD(
&bufsize, "bufsize", "Maximum number of cutting planes.",
MS_NOT_AVAILABLE);
SG_ADD(
(machine_int_t*)&method, "method", "SVMOcas solver type.",
MS_NOT_AVAILABLE);
}

float64_t CSVMOcas::compute_primal_objective() const
Expand Down
4 changes: 3 additions & 1 deletion src/shogun/clustering/GMM.cpp
Expand Up @@ -822,6 +822,8 @@ void CGMM::register_params()
{
//TODO serialization broken
//m_parameters->add((SGVector<CSGObject*>*) &m_components, "m_components", "Mixture components");
m_parameters->add(&m_coefficients, "m_coefficients", "Mixture coefficients.");
SG_ADD(
&m_coefficients, "m_coefficients", "Mixture coefficients.",
MS_NOT_AVAILABLE);
}

3 changes: 1 addition & 2 deletions src/shogun/converter/HashedDocConverter.cpp
Expand Up @@ -65,8 +65,7 @@ void CHashedDocConverter::init(CTokenizer* tzer, int32_t hash_bits, bool normali
MS_NOT_AVAILABLE);
SG_ADD(&should_normalize, "should_normalize", "Whether to normalize vectors or not",
MS_NOT_AVAILABLE);
m_parameters->add((CSGObject**) &tokenizer, "tokenizer",
"Tokenizer");
SG_ADD(&tokenizer, "tokenizer", "Tokenizer", MS_NOT_AVAILABLE);
}

const char* CHashedDocConverter::get_name() const
Expand Down
4 changes: 3 additions & 1 deletion src/shogun/distance/AttenuatedEuclideanDistance.cpp
Expand Up @@ -66,5 +66,7 @@ void CAttenuatedEuclideanDistance::init()
{
disable_sqrt=false;

m_parameters->add(&disable_sqrt, "disable_sqrt", "If sqrt shall not be applied.");
SG_ADD(
&disable_sqrt, "disable_sqrt", "If sqrt shall not be applied.",
MS_NOT_AVAILABLE);
}
7 changes: 5 additions & 2 deletions src/shogun/distance/CustomDistance.cpp
Expand Up @@ -123,9 +123,12 @@ void CCustomDistance::init()
upper_diagonal=false;

m_parameters->add_matrix(&dmatrix, &num_rows, &num_cols, "dmatrix", "Distance Matrix");
watch_param("dmatrix", &dmatrix, &num_rows, &num_cols);
watch_param(
"dmatrix", &dmatrix, &num_rows, &num_cols,
AnyParameterProperties("Distance Matrix"));

m_parameters->add(&upper_diagonal, "upper_diagonal", "Upper diagonal");
SG_ADD(
&upper_diagonal, "upper_diagonal", "Upper diagonal", MS_NOT_AVAILABLE);
}

void CCustomDistance::cleanup()
Expand Down
10 changes: 6 additions & 4 deletions src/shogun/distance/Distance.cpp
Expand Up @@ -259,10 +259,12 @@ void CDistance::init()
num_lhs=0;
num_rhs=0;

m_parameters->add((CSGObject**) &lhs, "lhs",
"Feature vectors to occur on left hand side.");
m_parameters->add((CSGObject**) &rhs, "rhs",
"Feature vectors to occur on right hand side.");
SG_ADD(
&lhs, "lhs", "Feature vectors to occur on left hand side.",
MS_NOT_AVAILABLE);
SG_ADD(
&rhs, "rhs", "Feature vectors to occur on right hand side.",
MS_NOT_AVAILABLE);
}

template <class T>
Expand Down
5 changes: 3 additions & 2 deletions src/shogun/distance/HammingWordDistance.cpp
Expand Up @@ -169,6 +169,7 @@ float64_t CHammingWordDistance::compute(int32_t idx_a, int32_t idx_b)
void CHammingWordDistance::init()
{
use_sign = false;
m_parameters->add(&use_sign, "use_sign",
"If signum(counts) is used instead of counts.");
SG_ADD(
&use_sign, "use_sign", "If signum(counts) is used instead of counts.",
MS_NOT_AVAILABLE);
}
5 changes: 2 additions & 3 deletions src/shogun/distance/KernelDistance.cpp
Expand Up @@ -69,7 +69,6 @@ void CKernelDistance::init()
kernel = NULL;
width = 0.0;

m_parameters->add(&width, "width", "Width of RBF Kernel");
m_parameters->add((CSGObject**) &kernel, "kernel",
"Kernel.");
SG_ADD(&width, "width", "Width of RBF Kernel", MS_AVAILABLE);
SG_ADD(&kernel, "kernel", "Kernel.", MS_NOT_AVAILABLE);
}
10 changes: 8 additions & 2 deletions src/shogun/distance/MahalanobisDistance.cpp
Expand Up @@ -110,7 +110,13 @@ void CMahalanobisDistance::init()
disable_sqrt=false;
use_mean=false;

m_parameters->add(&disable_sqrt, "disable_sqrt", "If sqrt shall not be applied.");
m_parameters->add(&use_mean, "use_mean", "If distance shall be computed between mean vector and vector from rhs or between lhs and rhs.");
SG_ADD(
&disable_sqrt, "disable_sqrt", "If sqrt shall not be applied.",
MS_NOT_AVAILABLE);
SG_ADD(
&use_mean, "use_mean", "If distance shall be computed between mean "
"vector and vector from rhs or between lhs and "
"rhs.",
MS_NOT_AVAILABLE);
}

10 changes: 5 additions & 5 deletions src/shogun/distributions/PositionalPWM.cpp
Expand Up @@ -124,11 +124,11 @@ void CPositionalPWM::compute_w(int32_t num_pos)

void CPositionalPWM::register_params()
{
m_parameters->add(&m_poim, "poim", "POIM Scoring Matrix");
m_parameters->add(&m_w, "w", "Scoring Matrix");
m_parameters->add(&m_pwm, "pwm", "Positional Weight Matrix.");
m_parameters->add(&m_sigma, "sigma", "Standard Deviation.");
m_parameters->add(&m_mean, "mean", "Mean.");
SG_ADD(&m_poim, "poim", "POIM Scoring Matrix", MS_NOT_AVAILABLE);
SG_ADD(&m_w, "w", "Scoring Matrix", MS_NOT_AVAILABLE);
SG_ADD(&m_pwm, "pwm", "Positional Weight Matrix.", MS_NOT_AVAILABLE);
SG_ADD(&m_sigma, "sigma", "Standard Deviation.", MS_NOT_AVAILABLE);
SG_ADD(&m_mean, "mean", "Mean.", MS_NOT_AVAILABLE);
}

void CPositionalPWM::compute_scoring(int32_t max_degree)
Expand Down

0 comments on commit f755ebe

Please sign in to comment.