SHOGUN  v1.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ParameterCombination.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/machine/Machine.h>
14 
15 using namespace shogun;
16 
18 {
19  init();
20 }
21 
23 {
24  init();
25 
26  m_param=param;
27 }
28 
29 void CParameterCombination::init()
30 {
31  m_param=NULL;
32  m_child_nodes=new CDynamicObjectArray<CParameterCombination> ();
33  SG_REF(m_child_nodes);
34 
35  m_parameters->add((CSGObject**)m_child_nodes, "child nodes",
36  "children of this node");
37 }
38 
40 {
41  delete m_param;
42  SG_UNREF(m_child_nodes);
43 }
44 
46 {
47  m_child_nodes->append_element(child);
48 }
49 
50 void CParameterCombination::print_tree(int prefix_num) const
51 {
52  /* prefix is enlarged */
53  char* prefix=SG_MALLOC(char, prefix_num+1);
54  for (index_t i=0; i<prefix_num; ++i)
55  prefix[i]='\t';
56 
57  prefix[prefix_num]='\0';
58 
59  /* cases:
60  * -node with a Parameter instance and a possible children
61  * -root node with children
62  */
63 
64  if (m_param)
65  {
66  SG_SPRINT("%s", prefix);
67  for (index_t i=0; i<m_param->get_num_parameters(); ++i)
68  {
69  /* distinction between sgobject and values */
70  if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_SGOBJECT)
71  {
72  TParameter* param=m_param->get_parameter(i);
73  CSGObject* current_sgobject=*((CSGObject**) param->m_parameter);
74  SG_SPRINT("\"%s\":%s at %p ", param->m_name,
75  current_sgobject->get_name(), current_sgobject);
76  }
77  else
78  {
79  SG_SPRINT("\"%s\"=", m_param->get_parameter(i)->m_name);
80  void* param=m_param->get_parameter(i)->m_parameter;
81 
82  if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_FLOAT64)
83  SG_SPRINT("%f ", *((float64_t*)param));
84  else if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_INT32)
85  SG_SPRINT("%i ", *((int32_t*)param));
86  else if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_BOOL)
87  SG_SPRINT("%s ", *((bool*)param ? "true" : "false"));
88  else
90  }
91 
92  }
93 
94  }
95  else
96  SG_SPRINT("%sroot", prefix);
97 
98  SG_SPRINT("\n");
99 
100  for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
101  {
102  CParameterCombination* child=m_child_nodes->get_element(i);
103  child->print_tree(prefix_num+1);
104  SG_UNREF(child);
105  }
106 
107  SG_FREE(prefix);
108 }
109 
111  const DynArray<Parameter*>& set_1, const DynArray<Parameter*>& set_2)
112 {
114 
115  for (index_t i=0; i<set_1.get_num_elements(); ++i)
116  {
117  for (index_t j=0; j<set_2.get_num_elements(); ++j)
118  {
119  Parameter* p=new Parameter();
120  p->add_parameters(set_1[i]);
121  p->add_parameters(set_2[j]);
122  result->append_element(p);
123  }
124  }
125 
126  return result;
127 }
128 
131  const CParameterCombination* new_root)
132 {
135 
136  /* check marginal cases */
137  if (sets.get_num_elements()==1)
138  {
140  sets.get_element(0);
141 
142  /* just use the only element into result array.
143  * put root node before all combinations*/
144  *result=*current_set;
145 
146  SG_UNREF(current_set);
147 
148  for (index_t i=0; i<result->get_num_elements(); ++i)
149  {
150  /* put new root as root into the tree and replace tree */
151  CParameterCombination* current=result->get_element(i);
152  CParameterCombination* root=new_root->copy_tree();
153  root->append_child(current);
154  result->set_element(root, i);
155  SG_UNREF(current);
156  }
157  }
158  else if (sets.get_num_elements()>1)
159  {
160  /* now the case where at least two sets are given */
161 
162  /* first, extract Parameter instances of given sets */
163  DynArray<DynArray<Parameter*>*> param_sets;
164 
165  for (index_t set_nr=0; set_nr<sets.get_num_elements(); ++set_nr)
166  {
168  sets.get_element(set_nr);
169  DynArray<Parameter*>* new_param_set=new DynArray<Parameter*> ();
170  param_sets.append_element(new_param_set);
171 
172  for (index_t i=0; i<current_set->get_num_elements(); ++i)
173  {
174  CParameterCombination* current_node=current_set->get_element(i);
175 
176  if (current_node->m_child_nodes->get_num_elements())
177  {
178  SG_SERROR("leaf sets multiplication only possible if all "
179  "trees are leafs");
180  }
181 
182  Parameter* current_param=current_node->m_param;
183 
184  if (current_param)
185  new_param_set->append_element(current_param);
186  else
187  {
188  SG_SERROR("leaf sets multiplication only possible if all "
189  "leafs have non-NULL Parameter instances\n");
190  }
191 
192  SG_UNREF(current_node);
193  }
194 
195  SG_UNREF(current_set);
196  }
197 
198  /* second, build products of all parameter sets */
200  *param_sets[0], *param_sets[1]);
201 
202  delete param_sets[0];
203  delete param_sets[1];
204 
205  /* build product of all remaining sets and collect results. delete all
206  * parameter instances of interim products*/
207  for (index_t i=2; i<param_sets.get_num_elements(); ++i)
208  {
209  DynArray<Parameter*>* old_temp_result=param_product;
210  param_product=parameter_set_multiplication(*param_product,
211  *param_sets[i]);
212 
213  /* delete interim result parameter instances */
214  for (index_t j=0; j<old_temp_result->get_num_elements(); ++j)
215  delete old_temp_result->get_element(j);
216 
217  /* and dyn arrays of interim result and of param_sets */
218  delete old_temp_result;
219  delete param_sets[i];
220  }
221 
222  /* at this point there is only one DynArray instance remaining:
223  * param_product. contains all combinations of parameters of all given
224  * sets */
225 
226  /* third, build tree sets with the given root and the parameter product
227  * elements */
228  for (index_t i=0; i<param_product->get_num_elements(); ++i)
229  {
230  /* build parameter node from parameter product to append to root */
232  param_product->get_element(i));
233 
234  /* copy new root node, has to be a new one each time */
235  CParameterCombination* root=new_root->copy_tree();
236 
237  /* append both and add them to result set */
238  root->append_child(param_node);
239  result->append_element(root);
240  }
241 
242  /* this is not needed anymore, because the Parameter instances are now
243  * in the resulting tree sets */
244  delete param_product;
245  }
246 
247  return result;
248 }
249 
251 {
253 
254  /* but build new Parameter instance */
255 
256  /* only call add_parameters() argument is non-null */
257  if (m_param)
258  {
259  copy->m_param=new Parameter();
260  copy->m_param->add_parameters(m_param);
261  } else
262  copy->m_param=NULL;
263 
264  /* recursively copy all children */
265  for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
266  {
267  CParameterCombination* child=m_child_nodes->get_element(i);
268  copy->m_child_nodes->append_element(child->copy_tree());
269  SG_UNREF(child);
270  }
271 
272  return copy;
273 }
274 
276 {
278 }
279 
281  Parameter* parameter) const
282 {
283  /* case root node */
284  if (!m_param)
285  {
286  /* iterate over all children and recursively set parameters from
287  * their values to the current parameter input (its just handed one
288  * recursion level downwards) */
289  for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
290  {
291  CParameterCombination* child=m_child_nodes->get_element(i);
292  child->apply_to_modsel_parameter(parameter);
293  SG_UNREF(child);
294  }
295  }
296  /* case parameter node */
297  else if (m_param)
298  {
299  /* set parameters */
300  parameter->set_from_parameters(m_param);
301 
302  /* does this node has sub parameters? */
303  if (has_children())
304  {
305  /* if a parameter node has children, it has to have ONE CSGObject as
306  * parameter */
307  if (m_param->get_num_parameters()>1 ||
308  m_param->get_parameter(0)->m_datatype.m_ptype!=PT_SGOBJECT)
309  {
310  SG_SERROR("invalid CParameterCombination node type, has children"
311  " and more than one parameter or is not a "
312  "CSGObject.\n");
313  }
314 
315  /* cast is now safe */
316  CSGObject* current_sgobject=
317  *((CSGObject**)(m_param->get_parameter(0)->m_parameter));
318 
319  /* iterate over all children and recursively set parameters from
320  * their values */
321  for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
322  {
323  CParameterCombination* child=m_child_nodes->get_element(i);
325  current_sgobject->m_model_selection_parameters);
326  SG_UNREF(child);
327  }
328  }
329  }
330  else
331  SG_SERROR("CParameterCombination node has illegal type.\n");
332 }

SHOGUN Machine Learning Toolbox - Documentation