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