SHOGUN  v2.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>
14 
15 using namespace shogun;
16 
18 {
19  m_name=NULL;
20  m_ctype=(EContainerType) -1;
21  m_stype=(EStructType) -1;
22  m_ptype=(EPrimitiveType) -1;
23  m_param_version=-1;
24 }
25 
27 {
28  /* copy name if existent */
29  m_name=orig.m_name ? strdup(orig.m_name) : NULL;
30 
31  m_ctype=orig.m_ctype;
32  m_stype=orig.m_stype;
33  m_ptype=orig.m_ptype;
35 }
36 
37 SGParamInfo::SGParamInfo(const char* name, EContainerType ctype,
38  EStructType stype, EPrimitiveType ptype, int32_t param_version)
39 {
40  /* copy name if existent */
41  m_name=name ? strdup(name) : NULL;
42 
43  m_ctype=ctype;
44  m_stype=stype;
45  m_ptype=ptype;
46  m_param_version=param_version;
47 }
48 
49 SGParamInfo::SGParamInfo(const TParameter* param, int32_t param_version)
50 {
51  /* copy name if existent */
52  m_name=param->m_name ? strdup(param->m_name) : NULL;
53 
54  TSGDataType type=param->m_datatype;
55  m_ctype=type.m_ctype;
56  m_stype=type.m_stype;
57  m_ptype=type.m_ptype;
58  m_param_version=param_version;
59 }
60 
62 {
63  SG_FREE(m_name);
64 }
65 
67 {
68  char* buffer=SG_MALLOC(char, 200);
69  strcpy(buffer, "SGParamInfo with: ");
70  strcat(buffer, "name=\"");
71  strcat(buffer, m_name ? m_name : "NULL");
72  strcat(buffer, "\", type=");
73 
74  char* b;
75  /* only cat type if it is defined (is not when std constructor was used)*/
76  if (!is_empty())
77  {
79  index_t l=100;
80  b=SG_MALLOC(char, l);
81  t.to_string(b, l);
82  strcat(buffer, b);
83  SG_FREE(b);
84  }
85  else
86  strcat(buffer, "no type");
87 
88  b=SG_MALLOC(char, 10);
89  sprintf(b, "%d", m_param_version);
90  strcat(buffer, ", version=");
91  strcat(buffer, b);
92  SG_FREE(b);
93 
94  return buffer;
95 }
96 
97 void SGParamInfo::print_param_info(const char* prefix) const
98 {
99  char* s=to_string();
100  SG_SPRINT("%s%s\n", prefix, s);
101  SG_FREE(s);
102 }
103 
105 {
107 }
108 
109 bool SGParamInfo::operator==(const SGParamInfo& other) const
110 {
111  bool result=true;
112 
113  /* handle NULL strings */
114  if ((!m_name && other.m_name) || (m_name && !other.m_name))
115  return false;
116 
117  if (m_name && other.m_name)
118  result&=!strcmp(m_name, other.m_name);
119 
120  result&=m_ctype==other.m_ctype;
121  result&=m_stype==other.m_stype;
122  result&=m_ptype==other.m_ptype;
123  result&=m_param_version==other.m_param_version;
124  return result;
125 }
126 
127 bool SGParamInfo::operator!=(const SGParamInfo& other) const
128 {
129  return !operator ==(other);
130 }
131 
132 bool SGParamInfo::operator<(const SGParamInfo& other) const
133 {
134  /* NULL here is always smaller than anything */
135  if (!m_name)
136  {
137  if (!other.m_name)
138  return false;
139  else
140  return true;
141  }
142  else if (!other.m_name)
143  return true;
144 
145  int32_t result=strcmp(m_name, other.m_name);
146 
147  if (result==0)
148  {
149  if (m_param_version==other.m_param_version)
150  {
151  if (m_ctype==other.m_ctype)
152  {
153  if (m_stype==other.m_stype)
154  {
155  if (m_ptype==other.m_ptype)
156  {
157  return false;
158  }
159  else
160  return m_ptype<other.m_ptype;
161  }
162  else
163  return m_stype<other.m_stype;
164  }
165  else
166  return m_ctype<other.m_ctype;
167  }
168  else
169  return m_param_version<other.m_param_version;
170 
171  }
172  else
173  return result<0;
174 }
175 
176 bool SGParamInfo::operator>(const SGParamInfo& other) const
177 {
178  return !(*this<(other)) && !(*this==other);
179 }
180 
182 {
183  /* return true if this info is for empty parameter */
184  return m_ctype<0 && m_stype<0 && m_ptype<0 && !m_name;
185 }
186 
188 {
189  m_key=NULL;
190  m_values=NULL;
191 }
192 
195 {
196  m_key=key;
197  m_values=values;
198 }
199 
201 {
202  delete m_key;
203 
204  if (m_values)
205  {
206  for (index_t i=0; i<m_values->get_num_elements(); ++i)
207  delete m_values->get_element(i);
208 
209  delete m_values;
210  }
211 }
212 
214 {
215  return *m_key==*other.m_key;
216 }
217 
219 {
220  return *m_key<*other.m_key;
221 }
222 
224 {
225  return *m_key>*other.m_key;
226 }
227 
229 {
230  m_finalized=false;
231 }
232 
234 {
235  for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
236  delete m_map_elements[i];
237 
238  for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
239  delete m_multi_map_elements[i];
240 }
241 
242 void ParameterMap::put(const SGParamInfo* key, const SGParamInfo* value)
243 {
244  /* assert that versions do differ exactly one if mapping is non-empty */
245  if(key->m_param_version-value->m_param_version!=1)
246  {
247  if (!key->is_empty() && !value->is_empty())
248  {
249  char* s=key->to_string();
250  char* t=value->to_string();
251  SG_SERROR("Versions of parameter mappings from \"%s\" to \"%s\" have"
252  " to differ exactly one\n", s, t);
253  SG_FREE(s);
254  SG_FREE(t);
255  }
256  }
257 
258  /* always add array of ONE element as values, will be processed later
259  * in finalize map method */
261  values->append_element(value);
263  m_finalized=false;
264 }
265 
267 {
268  return get(&key);
269 }
270 
272 {
274 
275  /* check if maps is finalized */
276  if (!m_finalized && num_elements)
277  SG_SERROR("Call finalize_map() before calling get()\n");
278 
279  /* do binary search in array of pointers */
280  /* dummy element for searching */
281  ParameterMapElement* dummy=new ParameterMapElement(key->duplicate(), NULL);
282  index_t index=CMath::binary_search<ParameterMapElement> (
283  m_multi_map_elements.get_array(), num_elements, dummy);
284  delete dummy;
285 
286  if (index==-1)
287  return NULL;
288 
290  return element->m_values;
291 }
292 
294 {
295  /* only do something if there are elements in map */
297  return;
298 
299  /* sort underlying array */
300  CMath::qsort<ParameterMapElement> (m_map_elements.get_array(),
302 
303 // SG_SPRINT("map elements before finalize\n");
304 // for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
305 // {
306 // ParameterMapElement* current=m_map_elements[i];
307 // SG_SPRINT("element %d:\n", i);
308 // SG_SPRINT("\tkey: ");
309 // current->m_key->print_param_info();
310 // SG_SPRINT("\t%d values:\n", current->m_values->get_num_elements());
311 // for (index_t j=0; j<current->m_values->get_num_elements(); ++j)
312 // current->m_values->get_element(j)->print_param_info("\t\t");
313 // }
314 
315  /* clear old multi elements. These were copies. */
316  for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
317  delete m_multi_map_elements[i];
318 
320 // SG_SPRINT("\nstarting finalization\n");
321 
322  /* iterate over all elements of map elements (have all one value (put)) and
323  * add all values of same key to ONE map element of hidden structure */
325  const SGParamInfo* current_key=m_map_elements[0]->m_key;
326 // char* s=current_key->to_string();
327 // SG_SPRINT("current key: %s\n", s);
328 // SG_FREE(s);
329  for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
330  {
331  const ParameterMapElement* current=m_map_elements[i];
332  if (*current_key != *current->m_key)
333  {
334  /* create new values array to add and update key */
335  values=new DynArray<const SGParamInfo*>();
336  current_key=current->m_key;
337 // s=current_key->to_string();
338 // SG_SPRINT("new current key: %s\n", s);
339 // SG_FREE(s);
340  }
341 
342  /* add to values array */
343  char* t=current->m_values->get_element(0)->to_string();
344 // SG_SPRINT("\tadding %s\n", t);
345  SG_FREE(t);
346  values->append_element(current->m_values->get_element(0)->duplicate());
347 
348  /* if current values array has not been added to multi map elements, do
349  * now */
351  if (last_idx<0 ||
352  m_multi_map_elements.get_element(last_idx)->m_values != values)
353  {
354 // SG_SPRINT("adding values array\n");
356  new ParameterMapElement(current_key->duplicate(), values));
357  }
358  }
359 
360  m_finalized=true;
361 // SG_SPRINT("leaving finalize_map()\n");
362 }
363 
365 {
366  /* check if maps is finalized */
368  SG_SERROR("Call finalize_map() before calling print_map()\n");
369 
370 // SG_SPRINT("map with %d keys:\n", m_multi_map_elements.get_num_elements());
371  for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
372  {
374 // SG_SPRINT("element %d:\n", i);
375 // SG_SPRINT("\tkey: ");
376 // current->m_key->print_param_info();
377 // SG_SPRINT("\t%d values:\n", current->m_values->get_num_elements());
378  for (index_t j=0; j<current->m_values->get_num_elements(); ++j)
379  current->m_values->get_element(j)->print_param_info("\t\t");
380  }
381 }

SHOGUN Machine Learning Toolbox - Documentation