Skip to content

Commit

Permalink
systematically test CSGObject::equals
Browse files Browse the repository at this point in the history
  • Loading branch information
karlnapf committed Jan 22, 2018
1 parent 2b3a863 commit 85595dc
Show file tree
Hide file tree
Showing 5 changed files with 386 additions and 52 deletions.
22 changes: 21 additions & 1 deletion src/shogun/base/SGObject.h
Expand Up @@ -500,12 +500,32 @@ class CSGObject
*/
template <typename T>
void watch_param(
const std::string& name, T* value, AnyParameterProperties properties)
const std::string& name, T* value,
AnyParameterProperties properties =
AnyParameterProperties(MS_NOT_AVAILABLE, GRADIENT_NOT_AVAILABLE))
{
BaseTag tag(name);
create_parameter(tag, AnyParameter(make_any_ref(value), properties));
}

/** Puts a pointer to some parameter array into the parameter map.
*
* @param name name of the parameter array
* @param value pointer to the first element of the parameter array
* @param properties properties of the parameter (e.g. if model selection is
* supported)
*/
template <typename T, typename S>
void watch_param(
const std::string& name, T** value, S* len,
AnyParameterProperties properties =
AnyParameterProperties(MS_NOT_AVAILABLE, GRADIENT_NOT_AVAILABLE))
{
BaseTag tag(name);
create_parameter(
tag, AnyParameter(make_any_ref_array(value, len), properties));
}

public:
/** Updates the hash of current parameter combination */
virtual void update_parameter_hash();
Expand Down
33 changes: 28 additions & 5 deletions src/shogun/lib/SGString.cpp
Expand Up @@ -35,11 +35,34 @@ bool SGString<T>::operator==(const SGString & other) const
if (other.slen != slen)
return false;

for (int i = 0; i < slen; i++)
{
if (other.string[i] != string[i])
return false;
}
if (string != other.string)
return false;

return true;
}

template <class T>
bool SGString<T>::equals(const SGString& other) const
{
// avoid comparing elements when both are same.
// the case where both matrices are uninitialized is handled here as well.
if (*this == other)
return true;

// both empty
if (!(slen || other.slen))
return true;

// only one empty
if (!string || !other.string)
return false;

// different size
if (slen != other.slen)
return false;

// content
return std::equal(string, string + slen, other.string);

return true;
}
Expand Down
5 changes: 4 additions & 1 deletion src/shogun/lib/SGString.h
Expand Up @@ -35,9 +35,12 @@ template<class T> class SGString
/** copy constructor */
SGString(const SGString &orig);

/** equality operator */
/** @return true iff pointer and size are equal */
bool operator==(const SGString & other) const;

/** @return true iff content is equal */
bool equals(const SGString& other) const;

/** free string */
void free_string();

Expand Down
149 changes: 149 additions & 0 deletions tests/unit/base/MockObject.h
@@ -1,8 +1,157 @@
#include <shogun/base/SGObject.h>
#include <shogun/base/range.h>
#include <shogun/base/some.h>
#include <shogun/lib/SGMatrix.h>
#include <shogun/lib/SGSparseMatrix.h>
#include <shogun/lib/SGSparseVector.h>
#include <shogun/lib/SGString.h>
#include <shogun/lib/SGVector.h>

namespace shogun
{
/** @brief Mock class to test clone and equals for CSGObject.
* Serves as a parameter of type CSGObject for @see CCloneEqualsMock.
*/
template <class T>
class CCloneEqualsMockParameter : public CSGObject
{
public:
CCloneEqualsMockParameter()
{
m_was_cloned = false;
m_some_value = 1;

watch_param("some_value", &m_some_value);
}
const char* get_name() const
{
return "CloneEqualsMockParameter";
}

virtual CSGObject* clone()
{
auto* clone = new CCloneEqualsMockParameter<T>();
clone->m_was_cloned = true;
SG_REF(clone);
return clone;
}

bool m_was_cloned;
T m_some_value;
};

/** @brief Mock class to test clone and equals for CSGObject.
* Has members that cover (hopefully) all possibilities of parameters.
*/
template <class T>
class CCloneEqualsMock : public CSGObject
{
public:
CCloneEqualsMock()
{
m_basic = 1;
watch_param("basic", &m_basic);

m_object = new CCloneEqualsMockParameter<T>();
watch_param("object", &m_object);

m_sg_vector = SGVector<T>(2);
m_sg_vector.set_const(m_basic);
watch_param("sg_vector", &m_sg_vector);

m_sg_matrix = SGMatrix<T>(3, 4);
m_sg_matrix.set_const(m_basic);
watch_param("sg_matrix", &m_sg_matrix);

m_sg_sparse_vector = SGSparseVector<T>(4);
for (auto i : range(m_sg_sparse_vector.num_feat_entries))
{
SGSparseVectorEntry<T> entry;
entry.feat_index = i * 2;
entry.entry = 2;
m_sg_sparse_vector.features[i] = entry;
}
watch_param("sg_sparse_vector", &m_sg_sparse_vector);

m_sg_sparse_matrix =
SGSparseMatrix<T>(m_sg_sparse_vector.num_feat_entries, 6);
for (auto i : range(m_sg_sparse_matrix.num_vectors))
{
SGSparseVector<T> vec(m_sg_sparse_matrix.num_features);
for (auto j : range(vec.num_feat_entries))
{
SGSparseVectorEntry<T> entry;
entry.feat_index = i * 2;
entry.entry = 3;
vec.features[j] = entry;
}
m_sg_sparse_matrix.sparse_matrix[i] = vec;
}
watch_param("sg_sparse_matrix", &m_sg_sparse_matrix);

m_vector_basic_len = 5;
m_vector_basic = new T[m_vector_basic_len];
for (auto i : range(m_vector_basic_len))
m_vector_basic[i] = m_basic;
watch_param("vector_basic", &m_vector_basic, &m_vector_basic_len);

m_vector_sg_string_len = 7;
m_vector_sg_string = new SGString<T>[m_vector_sg_string_len];
for (auto i : range(m_vector_sg_string_len))
{
m_vector_sg_string[i] = SGString<T>(i + 1, true);
for (auto j : range(m_vector_sg_string[i].slen))
m_vector_sg_string[i].string[j] = 1;
}
watch_param(
"vector_sg_string", &m_vector_sg_string,
&m_vector_sg_string_len);

m_vector_object_len = 6;
m_vector_object =
new CCloneEqualsMockParameter<T>*[m_vector_object_len];
for (auto i : range(m_vector_object_len))
m_vector_object[i] = new CCloneEqualsMockParameter<T>();
watch_param(
"vector_object", &m_vector_object, &m_vector_object_len);
}

~CCloneEqualsMock()
{
delete m_object;
delete m_vector_basic;
for (auto i : range(m_vector_object_len))
delete m_vector_object[i];
delete m_vector_object;

for (auto i : range(m_vector_sg_string_len))
m_vector_sg_string[i].free_string();
delete m_vector_sg_string;
}

const char* get_name() const
{
return "CloneEqualsMock";
}

T m_basic;
CCloneEqualsMockParameter<T>* m_object;

SGVector<T> m_sg_vector;
SGMatrix<T> m_sg_matrix;

SGSparseVector<T> m_sg_sparse_vector;
SGSparseMatrix<T> m_sg_sparse_matrix;

T* m_vector_basic;
index_t m_vector_basic_len;

SGString<T>* m_vector_sg_string;
index_t m_vector_sg_string_len;

CCloneEqualsMockParameter<T>** m_vector_object;
index_t m_vector_object_len;
};

/** @brief Used to test the tags-parameter framework
* Allows testing of registering new member and avoiding
Expand Down

0 comments on commit 85595dc

Please sign in to comment.