From e0dc2b62a7a19ec4885f68d4bd4efde213283c20 Mon Sep 17 00:00:00 2001 From: Heiko Strathmann Date: Tue, 6 Feb 2018 16:41:53 +0000 Subject: [PATCH 1/4] CSGObject::put SWIG attempt via explicit methods --- examples/meta/src/meta_api/kwargs.sg | 15 ++++++--------- src/interfaces/swig/SGBase.i | 19 ------------------- src/shogun/base/SGObject.cpp | 17 +++++++++++++++++ src/shogun/base/SGObject.h | 27 +++++++++++++++------------ 4 files changed, 38 insertions(+), 40 deletions(-) diff --git a/examples/meta/src/meta_api/kwargs.sg b/examples/meta/src/meta_api/kwargs.sg index c9af0892a01..e6582a91f8f 100644 --- a/examples/meta/src/meta_api/kwargs.sg +++ b/examples/meta/src/meta_api/kwargs.sg @@ -22,17 +22,14 @@ # This also fails (keywords not allowed outside initialisation variables) #kernel_factory("GaussianKernel", a=glob_fun(ordinary_argument)) +# doesnt work in ruby (TODO, don't allow in meta grammar) +# KernelMachine svm2 = kernel_machine("LibSVM", kernel=kernel("GaussianKernel")) + + # Real example # ------------ -# The following lines fail in Octave because of a float literal issue -#KernelMachine svm = kernel_machine("LibSVM", C1=2.0) -#GaussianKernel k(log_width=2.0) -#k.put("log_width", 4.0) - -# The following line fails in Python because of a bool literal issue -#GaussianKernel k2(log_width=14.0, lhs_equals_rhs=True) +Kernel k = kernel("GaussianKernel") +KernelMachine svm = kernel_machine("LibSVM", kernel=k) -# The following line currently gives a type error -#svm.put("kernel", k) diff --git a/src/interfaces/swig/SGBase.i b/src/interfaces/swig/SGBase.i index 29ba0601f35..bfc9b39820a 100644 --- a/src/interfaces/swig/SGBase.i +++ b/src/interfaces/swig/SGBase.i @@ -508,22 +508,3 @@ copy_reg._reconstructor=_sg_reconstructor %} #endif /* SWIGPYTHON */ - -%include -%include -%include - -%define SUPPORT_TAG(camel_type, short_type, type) - %template(Tag ## camel_type) shogun::Tag; - %template(put) shogun::CSGObject::put; - %template(put) shogun::CSGObject::put; - %template(put) shogun::CSGObject::put; - %template(get_ ## short_type) shogun::CSGObject::get; - %template(has) shogun::CSGObject::has; - %template(has_ ## short_type) shogun::CSGObject::has; -%enddef - -SUPPORT_TAG(String, string, std::string) -SUPPORT_TAG(Float64, float, float64_t) -SUPPORT_TAG(Int64, int, int64_t) -SUPPORT_TAG(Object, object, CSGObject*) diff --git a/src/shogun/base/SGObject.cpp b/src/shogun/base/SGObject.cpp index 8ea913a01b7..385545a2b48 100644 --- a/src/shogun/base/SGObject.cpp +++ b/src/shogun/base/SGObject.cpp @@ -1012,3 +1012,20 @@ CSGObject* CSGObject::create_empty() const SG_REF(object); return object; } + +namespace shogun +{ +#define SGOBJECT_PUT_DEFINE(T) \ +void CSGObject::put(const std::string& name, T const & value) throw(ShogunException)\ +{ \ + Tag tag(name); \ + put(tag, value); \ +} + +SGOBJECT_PUT_DEFINE(int32_t) +SGOBJECT_PUT_DEFINE(float64_t) +SGOBJECT_PUT_DEFINE(SGVector) +SGOBJECT_PUT_DEFINE(SGVector) +SGOBJECT_PUT_DEFINE(CSGObject*) + +}; diff --git a/src/shogun/base/SGObject.h b/src/shogun/base/SGObject.h index d1fe32f8a86..1d1aab607ef 100644 --- a/src/shogun/base/SGObject.h +++ b/src/shogun/base/SGObject.h @@ -364,18 +364,21 @@ class CSGObject } } - /** Setter for a class parameter, identified by a name. - * Throws an exception if the class does not have such a parameter. - * - * @param name name of the parameter - * @param value value of the parameter along with type information - */ - template - void put(const std::string& name, const T& value) throw(ShogunException) - { - Tag tag(name); - put(tag, value); - } + +#define SGOBJECT_PUT_DECLARE(T) \ + /** Setter for a class parameter, identified by a name. \ + * Throws an exception if the class does not have such a parameter. \ + * \ + * @param name name of the parameter \ + * @param value value of the parameter along with type information \ + */ \ + void put(const std::string& name, T const & value) throw(ShogunException); + + SGOBJECT_PUT_DECLARE(int32_t) + SGOBJECT_PUT_DECLARE(float64_t) + SGOBJECT_PUT_DECLARE(SGVector) + SGOBJECT_PUT_DECLARE(SGVector) + SGOBJECT_PUT_DECLARE(CSGObject*) /** Getter for a class parameter, identified by a Tag. * Throws an exception if the class does not have such a parameter. From 6da65acf6c15869b7cb70ec6306c47ab181b9982 Mon Sep 17 00:00:00 2001 From: Heiko Strathmann Date: Tue, 6 Feb 2018 17:07:15 +0000 Subject: [PATCH 2/4] a "fix" for octave and its ignorance about float and int --- examples/meta/src/meta_api/kwargs.sg | 4 ++-- src/shogun/base/SGObject.cpp | 24 ++++++++++++++++++++++-- src/shogun/base/SGObject.h | 1 + 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/examples/meta/src/meta_api/kwargs.sg b/examples/meta/src/meta_api/kwargs.sg index e6582a91f8f..fc2f4f7c79c 100644 --- a/examples/meta/src/meta_api/kwargs.sg +++ b/examples/meta/src/meta_api/kwargs.sg @@ -30,6 +30,6 @@ # Real example # ------------ -Kernel k = kernel("GaussianKernel") -KernelMachine svm = kernel_machine("LibSVM", kernel=k) +Kernel k = kernel("GaussianKernel", log_width=2.0) +KernelMachine svm = kernel_machine("LibSVM", C1=1.0, kernel=k) diff --git a/src/shogun/base/SGObject.cpp b/src/shogun/base/SGObject.cpp index 385545a2b48..b9daa7c51c3 100644 --- a/src/shogun/base/SGObject.cpp +++ b/src/shogun/base/SGObject.cpp @@ -1022,10 +1022,30 @@ void CSGObject::put(const std::string& name, T const & value) throw(ShogunExcep put(tag, value); \ } -SGOBJECT_PUT_DEFINE(int32_t) -SGOBJECT_PUT_DEFINE(float64_t) SGOBJECT_PUT_DEFINE(SGVector) SGOBJECT_PUT_DEFINE(SGVector) SGOBJECT_PUT_DEFINE(CSGObject*) +#define PUT_DEFINE_CHECK_AND_CAST(T) \ +else if (has(Tag(name))) \ + put(Tag(name), (T)value); + +#define SGOBJECT_PUT_DEFINE_NUMBER(numeric_t) \ +void CSGObject::put(const std::string& name, numeric_t const & value) throw(ShogunException)\ +{ \ + /* use correct type of possible, otherwise cast-convert */ \ + if (has(Tag(name))) \ + put(Tag(name), value); \ + PUT_DEFINE_CHECK_AND_CAST(int32_t) \ + PUT_DEFINE_CHECK_AND_CAST(float32_t) \ + PUT_DEFINE_CHECK_AND_CAST(float64_t) \ + else \ + /* if nothing works, moan about original type */ \ + put(Tag(name), value); \ +} + +SGOBJECT_PUT_DEFINE_NUMBER(int32_t) +SGOBJECT_PUT_DEFINE_NUMBER(float32_t) +SGOBJECT_PUT_DEFINE_NUMBER(float64_t) + }; diff --git a/src/shogun/base/SGObject.h b/src/shogun/base/SGObject.h index 1d1aab607ef..4bbcad6574d 100644 --- a/src/shogun/base/SGObject.h +++ b/src/shogun/base/SGObject.h @@ -375,6 +375,7 @@ class CSGObject void put(const std::string& name, T const & value) throw(ShogunException); SGOBJECT_PUT_DECLARE(int32_t) + SGOBJECT_PUT_DECLARE(float32_t) SGOBJECT_PUT_DECLARE(float64_t) SGOBJECT_PUT_DECLARE(SGVector) SGOBJECT_PUT_DECLARE(SGVector) From ea9ce459b235914f04eb1fb429690e6060f99e83 Mon Sep 17 00:00:00 2001 From: Heiko Strathmann Date: Tue, 6 Feb 2018 19:07:32 +0000 Subject: [PATCH 3/4] add comment on rational of converting scalar int/floats --- examples/meta/src/meta_api/kwargs.sg | 2 +- src/shogun/base/SGObject.cpp | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/examples/meta/src/meta_api/kwargs.sg b/examples/meta/src/meta_api/kwargs.sg index fc2f4f7c79c..e26f9abe0bc 100644 --- a/examples/meta/src/meta_api/kwargs.sg +++ b/examples/meta/src/meta_api/kwargs.sg @@ -31,5 +31,5 @@ # ------------ Kernel k = kernel("GaussianKernel", log_width=2.0) -KernelMachine svm = kernel_machine("LibSVM", C1=1.0, kernel=k) +KernelMachine svm = kernel_machine("LibSVM", C1=1.1, kernel=k) diff --git a/src/shogun/base/SGObject.cpp b/src/shogun/base/SGObject.cpp index b9daa7c51c3..caa140a72d2 100644 --- a/src/shogun/base/SGObject.cpp +++ b/src/shogun/base/SGObject.cpp @@ -1030,7 +1030,14 @@ SGOBJECT_PUT_DEFINE(CSGObject*) else if (has(Tag(name))) \ put(Tag(name), (T)value); -#define SGOBJECT_PUT_DEFINE_NUMBER(numeric_t) \ +/* Some target languages have problems with scalar numeric types, so allow to + * convert all int/float types into each other. + * + * For example, Octave treats a=1.0 as an integer, and b=1.1 as a float. + * Furthermore, if a user wants to set a registered 16bit integer using a + * literal obj.put("16-bit-var", 2), might complain about a wrong type since + * internally the int literal is represented at a different word length. */ +#define SGOBJECT_PUT_DEFINE_WITH_CONVERSION(numeric_t) \ void CSGObject::put(const std::string& name, numeric_t const & value) throw(ShogunException)\ { \ /* use correct type of possible, otherwise cast-convert */ \ @@ -1044,8 +1051,8 @@ void CSGObject::put(const std::string& name, numeric_t const & value) throw(Sho put(Tag(name), value); \ } -SGOBJECT_PUT_DEFINE_NUMBER(int32_t) -SGOBJECT_PUT_DEFINE_NUMBER(float32_t) -SGOBJECT_PUT_DEFINE_NUMBER(float64_t) +SGOBJECT_PUT_DEFINE_WITH_CONVERSION(int32_t) +SGOBJECT_PUT_DEFINE_WITH_CONVERSION(float32_t) +SGOBJECT_PUT_DEFINE_WITH_CONVERSION(float64_t) }; From 73e57f9e8389c59bdca521c1ff86913f2a716489 Mon Sep 17 00:00:00 2001 From: Heiko Strathmann Date: Tue, 6 Feb 2018 19:08:23 +0000 Subject: [PATCH 4/4] apply autoformater --- src/shogun/base/SGObject.cpp | 58 ++++++++++++++++++------------------ src/shogun/base/SGObject.h | 17 +++++------ 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/src/shogun/base/SGObject.cpp b/src/shogun/base/SGObject.cpp index caa140a72d2..0ccc3b46214 100644 --- a/src/shogun/base/SGObject.cpp +++ b/src/shogun/base/SGObject.cpp @@ -1015,20 +1015,20 @@ CSGObject* CSGObject::create_empty() const namespace shogun { -#define SGOBJECT_PUT_DEFINE(T) \ -void CSGObject::put(const std::string& name, T const & value) throw(ShogunException)\ -{ \ - Tag tag(name); \ - put(tag, value); \ -} +#define SGOBJECT_PUT_DEFINE(T) \ + void CSGObject::put(const std::string& name, T const& value) throw( \ + ShogunException) \ + { \ + Tag tag(name); \ + put(tag, value); \ + } -SGOBJECT_PUT_DEFINE(SGVector) -SGOBJECT_PUT_DEFINE(SGVector) -SGOBJECT_PUT_DEFINE(CSGObject*) + SGOBJECT_PUT_DEFINE(SGVector) + SGOBJECT_PUT_DEFINE(SGVector) + SGOBJECT_PUT_DEFINE(CSGObject*) -#define PUT_DEFINE_CHECK_AND_CAST(T) \ -else if (has(Tag(name))) \ - put(Tag(name), (T)value); +#define PUT_DEFINE_CHECK_AND_CAST(T) \ + else if (has(Tag(name))) put(Tag(name), (T)value); /* Some target languages have problems with scalar numeric types, so allow to * convert all int/float types into each other. @@ -1037,22 +1037,22 @@ else if (has(Tag(name))) \ * Furthermore, if a user wants to set a registered 16bit integer using a * literal obj.put("16-bit-var", 2), might complain about a wrong type since * internally the int literal is represented at a different word length. */ -#define SGOBJECT_PUT_DEFINE_WITH_CONVERSION(numeric_t) \ -void CSGObject::put(const std::string& name, numeric_t const & value) throw(ShogunException)\ -{ \ - /* use correct type of possible, otherwise cast-convert */ \ - if (has(Tag(name))) \ - put(Tag(name), value); \ - PUT_DEFINE_CHECK_AND_CAST(int32_t) \ - PUT_DEFINE_CHECK_AND_CAST(float32_t) \ - PUT_DEFINE_CHECK_AND_CAST(float64_t) \ - else \ - /* if nothing works, moan about original type */ \ - put(Tag(name), value); \ -} - -SGOBJECT_PUT_DEFINE_WITH_CONVERSION(int32_t) -SGOBJECT_PUT_DEFINE_WITH_CONVERSION(float32_t) -SGOBJECT_PUT_DEFINE_WITH_CONVERSION(float64_t) +#define SGOBJECT_PUT_DEFINE_WITH_CONVERSION(numeric_t) \ + void CSGObject::put( \ + const std::string& name, \ + numeric_t const& value) throw(ShogunException) \ + { \ + /* use correct type of possible, otherwise cast-convert */ \ + if (has(Tag(name))) \ + put(Tag(name), value); \ + PUT_DEFINE_CHECK_AND_CAST(int32_t) \ + PUT_DEFINE_CHECK_AND_CAST(float32_t) \ + PUT_DEFINE_CHECK_AND_CAST(float64_t) \ + else /* if nothing works, moan about original type */ \ + put(Tag(name), value); \ + } + SGOBJECT_PUT_DEFINE_WITH_CONVERSION(int32_t) + SGOBJECT_PUT_DEFINE_WITH_CONVERSION(float32_t) + SGOBJECT_PUT_DEFINE_WITH_CONVERSION(float64_t) }; diff --git a/src/shogun/base/SGObject.h b/src/shogun/base/SGObject.h index 4bbcad6574d..157da1a0f63 100644 --- a/src/shogun/base/SGObject.h +++ b/src/shogun/base/SGObject.h @@ -364,15 +364,14 @@ class CSGObject } } - -#define SGOBJECT_PUT_DECLARE(T) \ - /** Setter for a class parameter, identified by a name. \ - * Throws an exception if the class does not have such a parameter. \ - * \ - * @param name name of the parameter \ - * @param value value of the parameter along with type information \ - */ \ - void put(const std::string& name, T const & value) throw(ShogunException); +#define SGOBJECT_PUT_DECLARE(T) \ + /** Setter for a class parameter, identified by a name. \ + * Throws an exception if the class does not have such a parameter. \ + * \ + * @param name name of the parameter \ + * @param value value of the parameter along with type information \ + */ \ + void put(const std::string& name, T const& value) throw(ShogunException); SGOBJECT_PUT_DECLARE(int32_t) SGOBJECT_PUT_DECLARE(float32_t)