00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <shogun/modelselection/ParameterCombination.h>
00014 #include <shogun/base/Parameter.h>
00015 #include <shogun/machine/Machine.h>
00016 #include <set>
00017 #include <string>
00018
00019 using namespace shogun;
00020 using namespace std;
00021
00022 CParameterCombination::CParameterCombination()
00023 {
00024 init();
00025 }
00026
00027 CParameterCombination::CParameterCombination(Parameter* param)
00028 {
00029 init();
00030
00031 m_param=param;
00032 }
00033
00034 void CParameterCombination::init()
00035 {
00036 m_param=NULL;
00037 m_child_nodes=new CDynamicObjectArray();
00038 SG_REF(m_child_nodes);
00039
00040 SG_ADD((CSGObject**)&m_child_nodes, "child_nodes",
00041 "children of this node", MS_NOT_AVAILABLE);
00042 }
00043
00044 CParameterCombination::~CParameterCombination()
00045 {
00046 delete m_param;
00047 SG_UNREF(m_child_nodes);
00048 }
00049
00050 void CParameterCombination::append_child(CParameterCombination* child)
00051 {
00052 m_child_nodes->append_element(child);
00053 }
00054
00055
00056
00057 bool CParameterCombination::set_parameter_helper(
00058 const char* name, bool value, index_t index)
00059 {
00060 if (m_param)
00061 {
00062 for (index_t i = 0; i < m_param->get_num_parameters(); ++i)
00063 {
00064 void* param = m_param->get_parameter(i)->m_parameter;
00065
00066 if (!strcmp(m_param->get_parameter(i)->m_name, name))
00067 {
00068 if (m_param->get_parameter(i)->m_datatype.m_ptype
00069 != PT_BOOL)
00070 SG_ERROR("Parameter %s not a boolean parameter", name);
00071
00072 if (index < 0)
00073 *((bool*)(param)) = value;
00074
00075 else
00076 (*((bool**)(param)))[index] = value;
00077
00078 return true;
00079 }
00080 }
00081
00082 }
00083
00084 return false;
00085 }
00086
00087 bool CParameterCombination::set_parameter_helper(
00088 const char* name, int32_t value, index_t index)
00089 {
00090 if (m_param)
00091 {
00092 for (index_t i = 0; i < m_param->get_num_parameters(); ++i)
00093 {
00094 void* param = m_param->get_parameter(i)->m_parameter;
00095
00096 if (!strcmp(m_param->get_parameter(i)->m_name, name))
00097 {
00098 if (m_param->get_parameter(i)->m_datatype.m_ptype
00099 != PT_INT32)
00100 SG_ERROR("Parameter %s not a integer parameter", name);
00101
00102 if (index < 0)
00103 *((int32_t*)(param)) = value;
00104
00105 else
00106 (*((int32_t**)(param)))[index] = value;
00107
00108 return true;
00109 }
00110 }
00111 }
00112
00113 return false;
00114 }
00115
00116 bool CParameterCombination::set_parameter_helper(
00117 const char* name, float64_t value, index_t index)
00118 {
00119 if (m_param)
00120 {
00121 for (index_t i = 0; i < m_param->get_num_parameters(); ++i)
00122 {
00123 void* param = m_param->get_parameter(i)->m_parameter;
00124
00125 if (!strcmp(m_param->get_parameter(i)->m_name, name))
00126 {
00127 if (m_param->get_parameter(i)->m_datatype.m_ptype
00128 != PT_FLOAT64)
00129 SG_ERROR("Parameter %s not a double parameter", name);
00130
00131 if (index < 0)
00132 *((float64_t*)(param)) = value;
00133
00134 else
00135 (*((float64_t**)(param)))[index] = value;
00136
00137 return true;
00138 }
00139 }
00140
00141 }
00142
00143 return false;
00144 }
00145
00146
00147 TParameter* CParameterCombination::get_parameter_helper(const char* name)
00148 {
00149 if (m_param)
00150 {
00151 for (index_t i = 0; i < m_param->get_num_parameters(); i++)
00152 {
00153 if (!strcmp(m_param->get_parameter(i)->m_name, name))
00154 return m_param->get_parameter(i);
00155 }
00156
00157 }
00158
00159 return NULL;
00160 }
00161
00162
00163 TParameter* CParameterCombination::get_parameter(const char* name,
00164 CSGObject* parent)
00165 {
00166 bool match = false;
00167
00168 if (m_param)
00169 {
00170 for (index_t i = 0; i < m_param->get_num_parameters(); i++)
00171 {
00172 if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_SGOBJECT)
00173 {
00174 CSGObject* obj =
00175 (*((CSGObject**)m_param->get_parameter(i)->m_parameter));
00176 if (parent == obj)
00177 match = true;
00178 }
00179 }
00180
00181 }
00182
00183 for (index_t i = 0; i < m_child_nodes->get_num_elements(); ++i)
00184 {
00185 CParameterCombination* child = (CParameterCombination*)
00186 m_child_nodes->get_element(i);
00187
00188 TParameter* p;
00189
00190 if (!match)
00191 p = child->get_parameter(name, parent);
00192
00193 else
00194 p = child->get_parameter_helper(name);
00195
00196 if (p)
00197 {
00198 SG_UNREF(child);
00199 return p;
00200 }
00201
00202 SG_UNREF(child);
00203 }
00204
00205 return NULL;
00206 }
00207
00208
00209 void CParameterCombination::merge_with(CParameterCombination* node)
00210 {
00211 for (index_t i=0; i<node->m_child_nodes->get_num_elements(); ++i)
00212 {
00213 CParameterCombination* child=
00214 (CParameterCombination*)node->m_child_nodes->get_element(i);
00215 append_child(child->copy_tree());
00216 SG_UNREF(child);
00217 }
00218 }
00219
00220 void CParameterCombination::print_tree(int prefix_num) const
00221 {
00222
00223 char* prefix=SG_MALLOC(char, prefix_num+1);
00224 for (index_t i=0; i<prefix_num; ++i)
00225 prefix[i]='\t';
00226
00227 prefix[prefix_num]='\0';
00228
00229
00230
00231
00232
00233
00234 if (m_param)
00235 {
00236 SG_SPRINT("%s", prefix);
00237 for (index_t i=0; i<m_param->get_num_parameters(); ++i)
00238 {
00239
00240 if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_SGOBJECT)
00241 {
00242 TParameter* param=m_param->get_parameter(i);
00243 CSGObject* current_sgobject=*((CSGObject**) param->m_parameter);
00244 SG_SPRINT("\"%s\":%s at %p ", param->m_name,
00245 current_sgobject->get_name(), current_sgobject);
00246 }
00247
00248 else if (m_param->get_parameter(i)->m_datatype.m_ctype == CT_SGVECTOR)
00249 {
00250 SG_SPRINT("\"%s\"=", m_param->get_parameter(i)->m_name);
00251 float64_t** param = (float64_t**)(m_param->
00252 get_parameter(i)->m_parameter);
00253 if (!m_param->get_parameter(i)->m_datatype.m_length_y)
00254 {
00255 SG_ERROR("Parameter vector %s has no length\n",
00256 m_param->get_parameter(i)->m_name);
00257 }
00258
00259 index_t length = *(m_param->get_parameter(i)->m_datatype.m_length_y);
00260
00261 for (index_t j = 0; j < length; j++)
00262 SG_SPRINT("%f ", (*param)[j]);
00263 }
00264
00265 else
00266 {
00267 SG_SPRINT("\"%s\"=", m_param->get_parameter(i)->m_name);
00268 void* param=m_param->get_parameter(i)->m_parameter;
00269
00270 if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_FLOAT64)
00271 SG_SPRINT("%f ", *((float64_t*)param));
00272 else if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_INT32)
00273 SG_SPRINT("%i ", *((int32_t*)param));
00274 else if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_BOOL)
00275 SG_SPRINT("%s ", *((bool*)param ? "true" : "false"));
00276 else
00277 SG_NOTIMPLEMENTED;
00278 }
00279
00280 }
00281
00282 }
00283 else
00284 SG_SPRINT("%sroot", prefix);
00285
00286 SG_SPRINT("\n");
00287
00288 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
00289 {
00290 CParameterCombination* child=(CParameterCombination*)
00291 m_child_nodes->get_element(i);
00292 child->print_tree(prefix_num+1);
00293 SG_UNREF(child);
00294 }
00295
00296 SG_FREE(prefix);
00297 }
00298
00299 DynArray<Parameter*>* CParameterCombination::parameter_set_multiplication(
00300 const DynArray<Parameter*>& set_1, const DynArray<Parameter*>& set_2)
00301 {
00302 SG_SDEBUG("entering CParameterCombination::parameter_set_multiplication()\n");
00303
00304 SG_SDEBUG("set 1:\n");
00305 for (index_t i=0; i<set_1.get_num_elements(); ++i)
00306 {
00307 for (index_t j=0; j<set_1.get_element(i)->get_num_parameters(); ++j)
00308 SG_SDEBUG("\t%s\n", set_1.get_element(i)->get_parameter(j)->m_name);
00309 }
00310
00311 SG_SDEBUG("set 2:\n");
00312 for (index_t i=0; i<set_2.get_num_elements(); ++i)
00313 {
00314 for (index_t j=0; j<set_2.get_element(i)->get_num_parameters(); ++j)
00315 SG_SDEBUG("\t%s\n", set_2.get_element(i)->get_parameter(j)->m_name);
00316 }
00317
00318 DynArray<Parameter*>* result=new DynArray<Parameter*>();
00319
00320 for (index_t i=0; i<set_1.get_num_elements(); ++i)
00321 {
00322 for (index_t j=0; j<set_2.get_num_elements(); ++j)
00323 {
00324 Parameter* p=new Parameter();
00325 p->add_parameters(set_1[i]);
00326 p->add_parameters(set_2[j]);
00327 result->append_element(p);
00328 }
00329 }
00330
00331 SG_SDEBUG("leaving CParameterCombination::parameter_set_multiplication()\n");
00332 return result;
00333 }
00334
00335 CDynamicObjectArray* CParameterCombination::leaf_sets_multiplication(
00336 const CDynamicObjectArray& sets, const CParameterCombination* new_root)
00337 {
00338 CDynamicObjectArray* result=new CDynamicObjectArray();
00339
00340
00341 if (sets.get_num_elements()==1)
00342 {
00343 CDynamicObjectArray* current_set=
00344 (CDynamicObjectArray*)sets.get_element(0);
00345
00346
00347
00348 *result=*current_set;
00349
00350 SG_UNREF(current_set);
00351
00352 for (index_t i=0; i<result->get_num_elements(); ++i)
00353 {
00354
00355 CParameterCombination* current=(CParameterCombination*)
00356 result->get_element(i);
00357 CParameterCombination* root=new_root->copy_tree();
00358 root->append_child(current);
00359 result->set_element(root, i);
00360 SG_UNREF(current);
00361 }
00362 }
00363 else if (sets.get_num_elements()>1)
00364 {
00365
00366
00367
00368 DynArray<DynArray<Parameter*>*> param_sets;
00369
00370 for (index_t set_nr=0; set_nr<sets.get_num_elements(); ++set_nr)
00371 {
00372 CDynamicObjectArray* current_set=(CDynamicObjectArray*)
00373 sets.get_element(set_nr);
00374 DynArray<Parameter*>* new_param_set=new DynArray<Parameter*> ();
00375 param_sets.append_element(new_param_set);
00376
00377 for (index_t i=0; i<current_set->get_num_elements(); ++i)
00378 {
00379 CParameterCombination* current_node=(CParameterCombination*)
00380 current_set->get_element(i);
00381
00382 if (current_node->m_child_nodes->get_num_elements())
00383 {
00384 SG_SERROR("leaf sets multiplication only possible if all "
00385 "trees are leafs");
00386 }
00387
00388 Parameter* current_param=current_node->m_param;
00389
00390 if (current_param)
00391 new_param_set->append_element(current_param);
00392 else
00393 {
00394 SG_SERROR("leaf sets multiplication only possible if all "
00395 "leafs have non-NULL Parameter instances\n");
00396 }
00397
00398 SG_UNREF(current_node);
00399 }
00400
00401 SG_UNREF(current_set);
00402 }
00403
00404
00405 DynArray<Parameter*>* param_product=parameter_set_multiplication(
00406 *param_sets[0], *param_sets[1]);
00407
00408 delete param_sets[0];
00409 delete param_sets[1];
00410
00411
00412
00413 for (index_t i=2; i<param_sets.get_num_elements(); ++i)
00414 {
00415 DynArray<Parameter*>* old_temp_result=param_product;
00416 param_product=parameter_set_multiplication(*param_product,
00417 *param_sets[i]);
00418
00419
00420 for (index_t j=0; j<old_temp_result->get_num_elements(); ++j)
00421 delete old_temp_result->get_element(j);
00422
00423
00424 delete old_temp_result;
00425 delete param_sets[i];
00426 }
00427
00428
00429
00430
00431
00432
00433
00434 for (index_t i=0; i<param_product->get_num_elements(); ++i)
00435 {
00436
00437 CParameterCombination* param_node=new CParameterCombination(
00438 param_product->get_element(i));
00439
00440
00441 CParameterCombination* root=new_root->copy_tree();
00442
00443
00444 root->append_child(param_node);
00445 result->append_element(root);
00446 }
00447
00448
00449
00450 delete param_product;
00451 }
00452
00453 return result;
00454 }
00455
00456 CDynamicObjectArray* CParameterCombination::non_value_tree_multiplication(
00457 const CDynamicObjectArray* sets,
00458 const CParameterCombination* new_root)
00459 {
00460 SG_SDEBUG("entering CParameterCombination::non_value_tree_multiplication()\n");
00461 CDynamicObjectArray* result=new CDynamicObjectArray();
00462
00463
00464 set<string> names;
00465
00466 for (index_t j=0;
00467 j<sets->get_num_elements(); ++j)
00468 {
00469 CDynamicObjectArray* current_set=
00470 (CDynamicObjectArray*)
00471 sets->get_element(j);
00472
00473 for (index_t k=0; k
00474 <current_set->get_num_elements(); ++k)
00475 {
00476 CParameterCombination* current_tree=(CParameterCombination*)
00477 current_set->get_element(k);
00478
00479 names.insert(string(current_tree->m_param->get_parameter(0)->m_name));
00480
00481 SG_UNREF(current_tree);
00482 }
00483
00484 SG_UNREF(current_set);
00485 }
00486
00487 SG_SDEBUG("all names\n");
00488 for (set<string>::iterator it=names.begin(); it!=names.end(); ++it)
00489 SG_SDEBUG("\"%s\"\n", (*it).c_str());
00490
00491
00492 if (!names.empty())
00493 {
00494
00495
00496
00497
00498
00499
00500 const char* first_name=(*(names.begin())).c_str();
00501 CDynamicObjectArray* trees=
00502 CParameterCombination::extract_trees_with_name(sets, first_name);
00503
00504 SG_SDEBUG("adding trees for first name \"%s\":\n", first_name);
00505 for (index_t i=0; i<trees->get_num_elements(); ++i)
00506 {
00507 CParameterCombination* current_tree=
00508 (CParameterCombination*)trees->get_element(i);
00509
00510 CParameterCombination* current_root=new_root->copy_tree();
00511 current_root->append_child(current_tree);
00512 result->append_element(current_root);
00513
00514
00515 SG_UNREF(current_tree);
00516 }
00517 SG_UNREF(trees);
00518
00519
00520 SG_SDEBUG("building products with remaining trees:\n");
00521 set<string>::iterator it=names.begin();
00522 for (++it; it!=names.end(); ++it)
00523 {
00524 SG_SDEBUG("processing \"%s\"\n", (*it).c_str());
00525
00526
00527 const char* current_name=(*it).c_str();
00528 trees=CParameterCombination::extract_trees_with_name(sets,
00529 current_name);
00530
00531
00532
00533 CDynamicObjectArray* new_result=new CDynamicObjectArray();
00534 for (index_t i=0; i<result->get_num_elements(); ++i)
00535 {
00536 for (index_t j=0; j<trees->get_num_elements(); ++j)
00537 {
00538 CParameterCombination* to_copy=
00539 (CParameterCombination*)result->get_element(i);
00540
00541
00542 CParameterCombination* new_element=to_copy->copy_tree();
00543 SG_UNREF(to_copy);
00544
00545 CParameterCombination* to_add=
00546 (CParameterCombination*)trees->get_element(j);
00547 new_element->append_child(to_add);
00548 SG_UNREF(to_add);
00549 new_result->append_element(new_element);
00550
00551
00552 }
00553 }
00554
00555
00556 SG_UNREF(trees);
00557
00558
00559 SG_UNREF(result);
00560 result=new_result;
00561 }
00562 }
00563
00564 SG_SDEBUG("leaving CParameterCombination::non_value_tree_multiplication()\n");
00565 return result;
00566 }
00567
00568 CDynamicObjectArray* CParameterCombination::extract_trees_with_name(
00569 const CDynamicObjectArray* sets, const char* desired_name)
00570 {
00571 CDynamicObjectArray* result=new CDynamicObjectArray();
00572
00573 for (index_t j=0;
00574 j<sets->get_num_elements(); ++j)
00575 {
00576 CDynamicObjectArray* current_set=
00577 (CDynamicObjectArray*) sets->get_element(j);
00578
00579 for (index_t k=0; k<current_set->get_num_elements(); ++k)
00580 {
00581 CParameterCombination* current_tree=(CParameterCombination*)
00582 current_set->get_element(k);
00583
00584 char* current_name=current_tree->m_param->get_parameter(0)->m_name;
00585
00586 if (!strcmp(current_name, desired_name))
00587 result->append_element(current_tree);
00588
00589 SG_UNREF(current_tree);
00590 }
00591
00592 SG_UNREF(current_set);
00593 }
00594
00595 return result;
00596 }
00597
00598 CParameterCombination* CParameterCombination::copy_tree() const
00599 {
00600 CParameterCombination* copy=new CParameterCombination();
00601
00602
00603
00604
00605 if (m_param)
00606 {
00607 copy->m_param=new Parameter();
00608 copy->m_param->add_parameters(m_param);
00609 } else
00610 copy->m_param=NULL;
00611
00612
00613 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
00614 {
00615 CParameterCombination* child=(CParameterCombination*)
00616 m_child_nodes->get_element(i);
00617 copy->m_child_nodes->append_element(child->copy_tree());
00618 SG_UNREF(child);
00619 }
00620
00621 return copy;
00622 }
00623
00624 void CParameterCombination::apply_to_machine(CMachine* machine) const
00625 {
00626 apply_to_modsel_parameter(machine->m_model_selection_parameters);
00627 }
00628
00629 void CParameterCombination::apply_to_modsel_parameter(
00630 Parameter* parameter) const
00631 {
00632
00633 if (!m_param)
00634 {
00635
00636
00637
00638 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
00639 {
00640 CParameterCombination* child=(CParameterCombination*)
00641 m_child_nodes->get_element(i);
00642 child->apply_to_modsel_parameter(parameter);
00643 SG_UNREF(child);
00644 }
00645 }
00646
00647 else if (m_param)
00648 {
00649
00650 parameter->set_from_parameters(m_param);
00651
00652
00653 if (has_children())
00654 {
00655
00656
00657 if (m_param->get_num_parameters()>1 ||
00658 m_param->get_parameter(0)->m_datatype.m_ptype!=PT_SGOBJECT)
00659 {
00660 SG_SERROR("invalid CParameterCombination node type, has children"
00661 " and more than one parameter or is not a "
00662 "CSGObject.\n");
00663 }
00664
00665
00666 CSGObject* current_sgobject=
00667 *((CSGObject**)(m_param->get_parameter(0)->m_parameter));
00668
00669
00670
00671 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
00672 {
00673 CParameterCombination* child=(CParameterCombination*)
00674 m_child_nodes->get_element(i);
00675 child->apply_to_modsel_parameter(
00676 current_sgobject->m_model_selection_parameters);
00677 SG_UNREF(child);
00678 }
00679 }
00680 }
00681 else
00682 SG_SERROR("CParameterCombination node has illegal type.\n");
00683 }