1 /**
2  * @file bindings/python/mlpack/io_util.hpp
3  * @author Ryan Curtin
4  *
5  * Simple function to work around Cython's lack of support for lvalue
6  * references.
7  *
8  * mlpack is free software; you may redistribute it and/or modify it under the
9  * terms of the 3-clause BSD license.  You should have received a copy of the
10  * 3-clause BSD license along with mlpack.  If not, see
11  * http://www.opensource.org/licenses/BSD-3-Clause for more information.
12  */
13 #ifndef MLPACK_BINDINGS_PYTHON_CYTHON_IO_UTIL_HPP
14 #define MLPACK_BINDINGS_PYTHON_CYTHON_IO_UTIL_HPP
15 
16 #include <mlpack/core/util/io.hpp>
17 #include <mlpack/core/data/dataset_mapper.hpp>
18 
19 namespace mlpack {
20 namespace util {
21 
22 /**
23  * Set the parameter to the given value.
24  *
25  * This function exists to work around Cython's lack of support for lvalue
26  * references.
27  *
28  * @param identifier Name of parameter.
29  * @param value Value to set parameter to.
30  */
31 template<typename T>
SetParam(const std::string & identifier,T & value)32 inline void SetParam(const std::string& identifier, T& value)
33 {
34   IO::GetParam<T>(identifier) = std::move(value);
35 }
36 
37 /**
38  * Set the parameter to the given value, given that the type is a pointer.
39  *
40  * This function exists to work around both Cython's lack of support for lvalue
41  * references and also its seeming lack of support for template pointer types.
42  *
43  * @param identifier Name of parameter.
44  * @param value Value to set parameter to.
45  * @param copy Whether or not the object should be copied.
46  */
47 template<typename T>
SetParamPtr(const std::string & identifier,T * value,const bool copy)48 inline void SetParamPtr(const std::string& identifier,
49                         T* value,
50                         const bool copy)
51 {
52   IO::GetParam<T*>(identifier) = copy ? new T(*value) : value;
53 }
54 
55 /**
56  * Set the parameter (which is a matrix/DatasetInfo tuple) to the given value.
57  */
58 template<typename T>
SetParamWithInfo(const std::string & identifier,T & matrix,const bool * dims)59 inline void SetParamWithInfo(const std::string& identifier,
60                              T& matrix,
61                              const bool* dims)
62 {
63   typedef typename std::tuple<data::DatasetInfo, T> TupleType;
64   typedef typename T::elem_type eT;
65 
66   // The true type of the parameter is std::tuple<T, DatasetInfo>.
67   const size_t dimensions = matrix.n_rows;
68   std::get<1>(IO::GetParam<TupleType>(identifier)) = std::move(matrix);
69   data::DatasetInfo& di = std::get<0>(IO::GetParam<TupleType>(identifier));
70   di = data::DatasetInfo(dimensions);
71 
72   bool hasCategoricals = false;
73   for (size_t i = 0; i < dimensions; ++i)
74   {
75     if (dims[i])
76     {
77       di.Type(i) = data::Datatype::categorical;
78       hasCategoricals = true;
79     }
80   }
81 
82   // Do we need to find how many categories we have?
83   if (hasCategoricals)
84   {
85     arma::vec maxs = arma::max(
86         std::get<1>(IO::GetParam<TupleType>(identifier)), 1);
87 
88     for (size_t i = 0; i < dimensions; ++i)
89     {
90       if (dims[i])
91       {
92         // Map the right number of objects.
93         for (size_t j = 0; j < (size_t) maxs[i]; ++j)
94         {
95           std::ostringstream oss;
96           oss << j;
97           di.MapString<eT>(oss.str(), i);
98         }
99       }
100     }
101   }
102 }
103 
104 /**
105  * Return a pointer.  This function exists to work around Cython's seeming lack
106  * of support for template pointer types.
107  */
108 template<typename T>
GetParamPtr(const std::string & paramName)109 T* GetParamPtr(const std::string& paramName)
110 {
111   return IO::GetParam<T*>(paramName);
112 }
113 
114 /**
115  * Return the matrix part of a matrix + dataset info parameter.
116  */
117 template<typename T>
GetParamWithInfo(const std::string & paramName)118 T& GetParamWithInfo(const std::string& paramName)
119 {
120   // T will be the Armadillo type.
121   typedef std::tuple<data::DatasetInfo, T> TupleType;
122   return std::get<1>(IO::GetParam<TupleType>(paramName));
123 }
124 
125 /**
126  * Turn verbose output on.
127  */
EnableVerbose()128 inline void EnableVerbose()
129 {
130   Log::Info.ignoreInput = false;
131 }
132 
133 /**
134  * Turn verbose output off.
135  */
DisableVerbose()136 inline void DisableVerbose()
137 {
138   Log::Info.ignoreInput = true;
139 }
140 
141 /**
142  * Disable backtraces.
143  */
DisableBacktrace()144 inline void DisableBacktrace()
145 {
146   Log::Fatal.backtrace = false;
147 }
148 
149 /**
150  * Reset the status of all timers.
151  */
ResetTimers()152 inline void ResetTimers()
153 {
154   // Just get a new object---removes all old timers.
155   IO::GetSingleton().timer.Reset();
156 }
157 
158 /**
159  * Enable timing.
160  */
EnableTimers()161 inline void EnableTimers()
162 {
163   Timer::EnableTiming();
164 }
165 
166 } // namespace util
167 } // namespace mlpack
168 
169 #endif
170