SHOGUN  v3.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ParameterMap.cpp
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2011 Heiko Strathmann
8  * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
9  */
10 
12 #include <shogun/base/Parameter.h>
13 #include <shogun/lib/memory.h>
15 #include <shogun/lib/DataType.h>
16 
17 using namespace shogun;
18 
20 {
21  m_name=NULL;
22  m_ctype=CT_UNDEFINED;
23  m_stype=ST_UNDEFINED;
24  m_ptype=PT_UNDEFINED;
25  m_param_version=-1;
26 }
27 
29 {
30  /* copy name if existent */
31  m_name=get_strdup(orig.m_name);
32 
33  m_ctype=orig.m_ctype;
34  m_stype=orig.m_stype;
35  m_ptype=orig.m_ptype;
37 }
38 
39 SGParamInfo::SGParamInfo(const char* name, EContainerType ctype,
40  EStructType stype, EPrimitiveType ptype, int32_t param_version)
41 {
42  /* copy name if existent */
43  m_name=get_strdup(name);
44 
45  m_ctype=ctype;
46  m_stype=stype;
47  m_ptype=ptype;
48  m_param_version=param_version;
49 }
50 
51 SGParamInfo::SGParamInfo(const TParameter* param, int32_t param_version)
52 {
53  /* copy name if existent */
54  m_name=get_strdup(param->m_name);
55 
56  TSGDataType type=param->m_datatype;
57  m_ctype=type.m_ctype;
58  m_stype=type.m_stype;
59  m_ptype=type.m_ptype;
60  m_param_version=param_version;
61 }
62 
64 {
65  SG_FREE(m_name);
66 }
67 
69 {
70  char* buffer=SG_MALLOC(char, 200);
71  strcpy(buffer, "SGParamInfo with: ");
72  strcat(buffer, "name=\"");
73  strcat(buffer, m_name ? m_name : "NULL");
74  strcat(buffer, "\", type=");
75 
76  char* b;
77  /* only cat type if it is defined (is not when std constructor was used)*/
78  if (!is_empty())
79  {
81  index_t l=100;
82  b=SG_MALLOC(char, l);
83  t.to_string(b, l);
84  strcat(buffer, b);
85  SG_FREE(b);
86  }
87  else
88  strcat(buffer, "no type");
89 
90  b=SG_MALLOC(char, 10);
91  sprintf(b, "%d", m_param_version);
92  strcat(buffer, ", version=");
93  strcat(buffer, b);
94  SG_FREE(b);
95 
96  return buffer;
97 }
98 
99 void SGParamInfo::print_param_info(const char* prefix) const
100 {
101  char* s=to_string();
102  SG_SPRINT("%s%s\n", prefix, s)
103  SG_FREE(s);
104 }
105 
107 {
109 }
110 
111 bool SGParamInfo::operator==(const SGParamInfo& other) const
112 {
113  bool result=true;
114 
115  /* handle NULL strings */
116  if ((!m_name && other.m_name) || (m_name && !other.m_name))
117  return false;
118 
119  if (m_name && other.m_name)
120  result&=!strcmp(m_name, other.m_name);
121 
122  result&=m_ctype==other.m_ctype;
123  result&=m_stype==other.m_stype;
124  result&=m_ptype==other.m_ptype;
125  result&=m_param_version==other.m_param_version;
126  return result;
127 }
128 
129 bool SGParamInfo::operator!=(const SGParamInfo& other) const
130 {
131  return !operator ==(other);
132 }
133 
134 bool SGParamInfo::operator<(const SGParamInfo& other) const
135 {
136  /* NULL here is always smaller than anything */
137  if (!m_name)
138  {
139  if (!other.m_name)
140  return false;
141  else
142  return true;
143  }
144  else if (!other.m_name)
145  return true;
146 
147  int32_t result=strcmp(m_name, other.m_name);
148 
149  if (result==0)
150  {
151  if (m_param_version==other.m_param_version)
152  {
153  if (m_ctype==other.m_ctype)
154  {
155  if (m_stype==other.m_stype)
156  {
157  if (m_ptype==other.m_ptype)
158  {
159  return false;
160  }
161  else
162  return m_ptype<other.m_ptype;
163  }
164  else
165  return m_stype<other.m_stype;
166  }
167  else
168  return m_ctype<other.m_ctype;
169  }
170  else
171  return m_param_version<other.m_param_version;
172 
173  }
174  else
175  return result<0;
176 }
177 
178 bool SGParamInfo::operator>(const SGParamInfo& other) const
179 {
180  return !(*this<(other)) && !(*this==other);
181 }
182 
184 {
185  /* return true if this info is for empty parameter */
186  return m_ctype==CT_UNDEFINED && m_stype==ST_UNDEFINED && m_ptype==PT_UNDEFINED && !m_name;
187 }
188 
190 {
191  m_key=NULL;
192  m_values=NULL;
193 }
194 
197 {
198  m_key=key;
199  m_values=values;
200 }
201 
203 {
204  delete m_key;
205 
206  if (m_values)
207  {
208  for (index_t i=0; i<m_values->get_num_elements(); ++i)
209  delete m_values->get_element(i);
210 
211  delete m_values;
212  }
213 }
214 
216 {
217  return *m_key==*other.m_key;
218 }
219 
221 {
222  return *m_key<*other.m_key;
223 }
224 
226 {
227  return *m_key>*other.m_key;
228 }
229 
231 {
232  m_finalized=false;
233 }
234 
236 {
237  for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
238  delete m_map_elements[i];
239 
240  for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
241  delete m_multi_map_elements[i];
242 }
243 
244 void ParameterMap::put(const SGParamInfo* key, const SGParamInfo* value)
245 {
246  /* assert that versions do differ exactly one if mapping is non-empty */
247  if (key->m_param_version-value->m_param_version!=1)
248  {
249  if (!key->is_empty() && !value->is_empty())
250  {
251  char* s=key->to_string();
252  char* t=value->to_string();
253  SG_SERROR("Versions of parameter mappings from \"%s\" to \"%s\" have"
254  " to differ exactly one\n", s, t);
255  SG_FREE(s);
256  SG_FREE(t);
257  }
258  }
259 
260  /* always add array of ONE element as values, will be processed later
261  * in finalize map method */
263  values->append_element(value);
265  m_finalized=false;
266 }
267 
269 {
270  return get(&key);
271 }
272 
274 {
276 
277  /* check if maps is finalized */
278  if (!m_finalized && num_elements)
279  SG_SERROR("Call finalize_map() before calling get()\n")
280 
281  /* do binary search in array of pointers */
282  /* dummy element for searching */
283  ParameterMapElement* dummy=new ParameterMapElement(key->duplicate(), NULL);
284  index_t index=CMath::binary_search<ParameterMapElement> (
285  m_multi_map_elements.get_array(), num_elements, dummy);
286  delete dummy;
287 
288  if (index==-1)
289  return NULL;
290 
292  return element->m_values;
293 }
294 
296 {
297  /* only do something if there are elements in map */
299  return;
300 
301  /* sort underlying array */
302  CMath::qsort<ParameterMapElement> (m_map_elements.get_array(),
304 
305 // SG_SPRINT("map elements before finalize\n")
306 // for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
307 // {
308 // ParameterMapElement* current=m_map_elements[i];
309 // SG_SPRINT("element %d:\n", i)
310 // SG_SPRINT("\tkey: ")
311 // current->m_key->print_param_info();
312 // SG_SPRINT("\t%d values:\n", current->m_values->get_num_elements())
313 // for (index_t j=0; j<current->m_values->get_num_elements(); ++j)
314 // current->m_values->get_element(j)->print_param_info("\t\t");
315 // }
316 
317  /* clear old multi elements. These were copies. */
318  for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
319  delete m_multi_map_elements[i];
320 
322 // SG_SPRINT("\nstarting finalization\n")
323 
324  /* iterate over all elements of map elements (have all one value (put)) and
325  * add all values of same key to ONE map element of hidden structure */
327  const SGParamInfo* current_key=m_map_elements[0]->m_key;
328 // char* s=current_key->to_string();
329 // SG_SPRINT("current key: %s\n", s)
330 // SG_FREE(s);
331  for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
332  {
333  const ParameterMapElement* current=m_map_elements[i];
334  if (*current_key != *current->m_key)
335  {
336  /* create new values array to add and update key */
337  values=new DynArray<const SGParamInfo*>();
338  current_key=current->m_key;
339 // s=current_key->to_string();
340 // SG_SPRINT("new current key: %s\n", s)
341 // SG_FREE(s);
342  }
343 
344  /* add to values array */
345  char* t=current->m_values->get_element(0)->to_string();
346 // SG_SPRINT("\tadding %s\n", t)
347  SG_FREE(t);
348  values->append_element(current->m_values->get_element(0)->duplicate());
349 
350  /* if current values array has not been added to multi map elements, do
351  * now */
353  if (last_idx<0 ||
354  m_multi_map_elements.get_element(last_idx)->m_values != values)
355  {
356 // SG_SPRINT("adding values array\n")
358  new ParameterMapElement(current_key->duplicate(), values));
359  }
360  }
361 
362  m_finalized=true;
363 // SG_SPRINT("leaving finalize_map()\n")
364 }
365 
367 {
368  /* check if maps is finalized */
370  SG_SERROR("Call finalize_map() before calling print_map()\n")
371 
372 // SG_SPRINT("map with %d keys:\n", m_multi_map_elements.get_num_elements())
373  for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
374  {
376 // SG_SPRINT("element %d:\n", i)
377 // SG_SPRINT("\tkey: ")
378 // current->m_key->print_param_info();
379 // SG_SPRINT("\t%d values:\n", current->m_values->get_num_elements())
380  for (index_t j=0; j<current->m_values->get_num_elements(); ++j)
381  current->m_values->get_element(j)->print_param_info("\t\t");
382  }
383 }

SHOGUN Machine Learning Toolbox - Documentation