SHOGUN
v3.2.0
|
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation; either version 3 of the License, or 00005 * (at your option) any later version. 00006 * 00007 * Written (W) 2011-2012 Heiko Strathmann 00008 * Written (W) 2012 Jacob Walker 00009 * Written (W) 2013 Roman Votyakov 00010 * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society 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 CParameterCombination::CParameterCombination(CSGObject* obj) 00035 { 00036 init(); 00037 00038 Parameter* gradient_params=obj->m_gradient_parameters; 00039 00040 for (index_t i=0; i<gradient_params->get_num_parameters(); i++) 00041 { 00042 TParameter* param=gradient_params->get_parameter(i); 00043 TSGDataType type=param->m_datatype; 00044 00045 if (type.m_ptype==PT_FLOAT64 || type.m_ptype==PT_FLOAT32 || 00046 type.m_ptype==PT_FLOATMAX) 00047 { 00048 if ((type.m_ctype==CT_SGVECTOR || type.m_ctype==CT_VECTOR)) 00049 { 00050 Parameter* p=new Parameter(); 00051 p->add_vector((float64_t**)param->m_parameter, type.m_length_y, 00052 param->m_name); 00053 00054 m_child_nodes->append_element(new CParameterCombination(p)); 00055 m_parameters_length+=*(type.m_length_y); 00056 } 00057 else if (type.m_ctype==CT_SCALAR) 00058 { 00059 Parameter* p=new Parameter(); 00060 p->add((float64_t*)param->m_parameter, param->m_name); 00061 00062 m_child_nodes->append_element(new CParameterCombination(p)); 00063 m_parameters_length++; 00064 } 00065 } 00066 else 00067 { 00068 SG_WARNING("Parameter %s.%s was not added to parameter combination, " 00069 "since it isn't of floating point type\n", obj->get_name(), 00070 param->m_name); 00071 } 00072 } 00073 00074 Parameter* modsel_params=obj->m_model_selection_parameters; 00075 00076 for (index_t i=0; i<modsel_params->get_num_parameters(); i++) 00077 { 00078 TParameter* param=modsel_params->get_parameter(i); 00079 TSGDataType type=param->m_datatype; 00080 00081 if (type.m_ptype==PT_SGOBJECT) 00082 { 00083 if (type.m_ctype==CT_SCALAR) 00084 { 00085 CSGObject* child=*((CSGObject**)(param->m_parameter)); 00086 00087 if (child->m_gradient_parameters->get_num_parameters()>0) 00088 { 00089 CParameterCombination* comb=new CParameterCombination(child); 00090 00091 comb->m_param=new Parameter(); 00092 comb->m_param->add((CSGObject**)(param->m_parameter), 00093 param->m_name); 00094 00095 m_child_nodes->append_element(comb); 00096 m_parameters_length+=comb->m_parameters_length; 00097 } 00098 } 00099 else 00100 { 00101 SG_NOTIMPLEMENTED 00102 } 00103 } 00104 } 00105 } 00106 00107 void CParameterCombination::init() 00108 { 00109 m_parameters_length=0; 00110 m_param=NULL; 00111 m_child_nodes=new CDynamicObjectArray(); 00112 SG_REF(m_child_nodes); 00113 00114 SG_ADD((CSGObject**)&m_child_nodes, "child_nodes", "Children of this node", 00115 MS_NOT_AVAILABLE); 00116 } 00117 00118 CParameterCombination::~CParameterCombination() 00119 { 00120 delete m_param; 00121 SG_UNREF(m_child_nodes); 00122 } 00123 00124 void CParameterCombination::append_child(CParameterCombination* child) 00125 { 00126 m_child_nodes->append_element(child); 00127 } 00128 00129 bool CParameterCombination::set_parameter_helper( 00130 const char* name, bool value, index_t index) 00131 { 00132 if (m_param) 00133 { 00134 for (index_t i = 0; i < m_param->get_num_parameters(); ++i) 00135 { 00136 void* param = m_param->get_parameter(i)->m_parameter; 00137 00138 if (!strcmp(m_param->get_parameter(i)->m_name, name)) 00139 { 00140 if (m_param->get_parameter(i)->m_datatype.m_ptype 00141 != PT_BOOL) 00142 SG_ERROR("Parameter %s not a boolean parameter", name) 00143 00144 if (index < 0) 00145 *((bool*)(param)) = value; 00146 00147 else 00148 (*((bool**)(param)))[index] = value; 00149 00150 return true; 00151 } 00152 } 00153 00154 } 00155 00156 return false; 00157 } 00158 00159 bool CParameterCombination::set_parameter_helper( 00160 const char* name, int32_t value, index_t index) 00161 { 00162 if (m_param) 00163 { 00164 for (index_t i = 0; i < m_param->get_num_parameters(); ++i) 00165 { 00166 void* param = m_param->get_parameter(i)->m_parameter; 00167 00168 if (!strcmp(m_param->get_parameter(i)->m_name, name)) 00169 { 00170 if (m_param->get_parameter(i)->m_datatype.m_ptype 00171 != PT_INT32) 00172 SG_ERROR("Parameter %s not a integer parameter", name) 00173 00174 if (index < 0) 00175 *((int32_t*)(param)) = value; 00176 00177 else 00178 (*((int32_t**)(param)))[index] = value; 00179 00180 return true; 00181 } 00182 } 00183 } 00184 00185 return false; 00186 } 00187 00188 bool CParameterCombination::set_parameter_helper( 00189 const char* name, float64_t value, index_t index) 00190 { 00191 if (m_param) 00192 { 00193 for (index_t i = 0; i < m_param->get_num_parameters(); ++i) 00194 { 00195 void* param = m_param->get_parameter(i)->m_parameter; 00196 00197 if (!strcmp(m_param->get_parameter(i)->m_name, name)) 00198 { 00199 if (m_param->get_parameter(i)->m_datatype.m_ptype 00200 != PT_FLOAT64) 00201 SG_ERROR("Parameter %s not a double parameter", name) 00202 00203 if (index < 0) 00204 *((float64_t*)(param)) = value; 00205 00206 else 00207 (*((float64_t**)(param)))[index] = value; 00208 00209 return true; 00210 } 00211 } 00212 00213 } 00214 00215 return false; 00216 } 00217 00218 00219 TParameter* CParameterCombination::get_parameter_helper(const char* name) 00220 { 00221 if (m_param) 00222 { 00223 for (index_t i = 0; i < m_param->get_num_parameters(); i++) 00224 { 00225 if (!strcmp(m_param->get_parameter(i)->m_name, name)) 00226 return m_param->get_parameter(i); 00227 } 00228 00229 } 00230 00231 return NULL; 00232 } 00233 00234 00235 TParameter* CParameterCombination::get_parameter(const char* name, 00236 CSGObject* parent) 00237 { 00238 bool match = false; 00239 00240 if (m_param) 00241 { 00242 for (index_t i = 0; i < m_param->get_num_parameters(); i++) 00243 { 00244 if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_SGOBJECT) 00245 { 00246 CSGObject* obj = 00247 (*((CSGObject**)m_param->get_parameter(i)->m_parameter)); 00248 if (parent == obj) 00249 match = true; 00250 } 00251 } 00252 00253 } 00254 00255 for (index_t i = 0; i < m_child_nodes->get_num_elements(); ++i) 00256 { 00257 CParameterCombination* child = (CParameterCombination*) 00258 m_child_nodes->get_element(i); 00259 00260 TParameter* p; 00261 00262 if (!match) 00263 p = child->get_parameter(name, parent); 00264 00265 else 00266 p = child->get_parameter_helper(name); 00267 00268 if (p) 00269 { 00270 SG_UNREF(child); 00271 return p; 00272 } 00273 00274 SG_UNREF(child); 00275 } 00276 00277 return NULL; 00278 } 00279 00280 00281 void CParameterCombination::merge_with(CParameterCombination* node) 00282 { 00283 for (index_t i=0; i<node->m_child_nodes->get_num_elements(); ++i) 00284 { 00285 CParameterCombination* child= 00286 (CParameterCombination*)node->m_child_nodes->get_element(i); 00287 append_child(child->copy_tree()); 00288 SG_UNREF(child); 00289 } 00290 } 00291 00292 void CParameterCombination::print_tree(int prefix_num) const 00293 { 00294 /* prefix is enlarged */ 00295 char* prefix=SG_MALLOC(char, prefix_num+1); 00296 for (index_t i=0; i<prefix_num; ++i) 00297 prefix[i]='\t'; 00298 00299 prefix[prefix_num]='\0'; 00300 00301 /* cases: 00302 * -node with a Parameter instance and a possible children 00303 * -root node with children 00304 */ 00305 00306 if (m_param) 00307 { 00308 SG_SPRINT("%s", prefix) 00309 for (index_t i=0; i<m_param->get_num_parameters(); ++i) 00310 { 00311 /* distinction between sgobject and values */ 00312 if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_SGOBJECT) 00313 { 00314 TParameter* param=m_param->get_parameter(i); 00315 CSGObject* current_sgobject=*((CSGObject**) param->m_parameter); 00316 SG_SPRINT("\"%s\":%s at %p ", param->m_name, 00317 current_sgobject->get_name(), current_sgobject); 00318 } 00319 00320 else if (m_param->get_parameter(i)->m_datatype.m_ctype == CT_SGVECTOR) 00321 { 00322 SG_SPRINT("\"%s\"=", m_param->get_parameter(i)->m_name) 00323 float64_t** param = (float64_t**)(m_param-> 00324 get_parameter(i)->m_parameter); 00325 if (!m_param->get_parameter(i)->m_datatype.m_length_y) 00326 { 00327 SG_ERROR("Parameter vector %s has no length\n", 00328 m_param->get_parameter(i)->m_name); 00329 } 00330 00331 index_t length = *(m_param->get_parameter(i)->m_datatype.m_length_y); 00332 00333 for (index_t j = 0; j < length; j++) 00334 SG_SPRINT("%f ", (*param)[j]) 00335 } 00336 00337 else 00338 { 00339 SG_SPRINT("\"%s\"=", m_param->get_parameter(i)->m_name) 00340 void* param=m_param->get_parameter(i)->m_parameter; 00341 00342 if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_FLOAT64) 00343 SG_SPRINT("%f ", *((float64_t*)param)) 00344 else if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_INT32) 00345 SG_SPRINT("%i ", *((int32_t*)param)) 00346 else if (m_param->get_parameter(i)->m_datatype.m_ptype==PT_BOOL) 00347 SG_SPRINT("%s ", *((bool*)param ? "true" : "false")) 00348 else 00349 SG_NOTIMPLEMENTED 00350 } 00351 00352 } 00353 00354 } 00355 else 00356 SG_SPRINT("%sroot", prefix) 00357 00358 SG_SPRINT("\n") 00359 00360 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i) 00361 { 00362 CParameterCombination* child=(CParameterCombination*) 00363 m_child_nodes->get_element(i); 00364 child->print_tree(prefix_num+1); 00365 SG_UNREF(child); 00366 } 00367 00368 SG_FREE(prefix); 00369 } 00370 00371 DynArray<Parameter*>* CParameterCombination::parameter_set_multiplication( 00372 const DynArray<Parameter*>& set_1, const DynArray<Parameter*>& set_2) 00373 { 00374 SG_SDEBUG("entering CParameterCombination::parameter_set_multiplication()\n") 00375 00376 SG_SDEBUG("set 1:\n") 00377 for (index_t i=0; i<set_1.get_num_elements(); ++i) 00378 { 00379 for (index_t j=0; j<set_1.get_element(i)->get_num_parameters(); ++j) 00380 SG_SDEBUG("\t%s\n", set_1.get_element(i)->get_parameter(j)->m_name) 00381 } 00382 00383 SG_SDEBUG("set 2:\n") 00384 for (index_t i=0; i<set_2.get_num_elements(); ++i) 00385 { 00386 for (index_t j=0; j<set_2.get_element(i)->get_num_parameters(); ++j) 00387 SG_SDEBUG("\t%s\n", set_2.get_element(i)->get_parameter(j)->m_name) 00388 } 00389 00390 DynArray<Parameter*>* result=new DynArray<Parameter*>(); 00391 00392 for (index_t i=0; i<set_1.get_num_elements(); ++i) 00393 { 00394 for (index_t j=0; j<set_2.get_num_elements(); ++j) 00395 { 00396 Parameter* p=new Parameter(); 00397 p->add_parameters(set_1[i]); 00398 p->add_parameters(set_2[j]); 00399 result->append_element(p); 00400 } 00401 } 00402 00403 SG_SDEBUG("leaving CParameterCombination::parameter_set_multiplication()\n") 00404 return result; 00405 } 00406 00407 CDynamicObjectArray* CParameterCombination::leaf_sets_multiplication( 00408 const CDynamicObjectArray& sets, const CParameterCombination* new_root) 00409 { 00410 CDynamicObjectArray* result=new CDynamicObjectArray(); 00411 00412 /* check marginal cases */ 00413 if (sets.get_num_elements()==1) 00414 { 00415 CDynamicObjectArray* current_set= 00416 (CDynamicObjectArray*)sets.get_element(0); 00417 00418 /* just use the only element into result array. 00419 * put root node before all combinations*/ 00420 *result=*current_set; 00421 00422 SG_UNREF(current_set); 00423 00424 for (index_t i=0; i<result->get_num_elements(); ++i) 00425 { 00426 /* put new root as root into the tree and replace tree */ 00427 CParameterCombination* current=(CParameterCombination*) 00428 result->get_element(i); 00429 CParameterCombination* root=new_root->copy_tree(); 00430 root->append_child(current); 00431 result->set_element(root, i); 00432 SG_UNREF(current); 00433 } 00434 } 00435 else if (sets.get_num_elements()>1) 00436 { 00437 /* now the case where at least two sets are given */ 00438 00439 /* first, extract Parameter instances of given sets */ 00440 DynArray<DynArray<Parameter*>*> param_sets; 00441 00442 for (index_t set_nr=0; set_nr<sets.get_num_elements(); ++set_nr) 00443 { 00444 CDynamicObjectArray* current_set=(CDynamicObjectArray*) 00445 sets.get_element(set_nr); 00446 DynArray<Parameter*>* new_param_set=new DynArray<Parameter*> (); 00447 param_sets.append_element(new_param_set); 00448 00449 for (index_t i=0; i<current_set->get_num_elements(); ++i) 00450 { 00451 CParameterCombination* current_node=(CParameterCombination*) 00452 current_set->get_element(i); 00453 00454 if (current_node->m_child_nodes->get_num_elements()) 00455 { 00456 SG_SERROR("leaf sets multiplication only possible if all " 00457 "trees are leafs"); 00458 } 00459 00460 Parameter* current_param=current_node->m_param; 00461 00462 if (current_param) 00463 new_param_set->append_element(current_param); 00464 else 00465 { 00466 SG_SERROR("leaf sets multiplication only possible if all " 00467 "leafs have non-NULL Parameter instances\n"); 00468 } 00469 00470 SG_UNREF(current_node); 00471 } 00472 00473 SG_UNREF(current_set); 00474 } 00475 00476 /* second, build products of all parameter sets */ 00477 DynArray<Parameter*>* param_product=parameter_set_multiplication( 00478 *param_sets[0], *param_sets[1]); 00479 00480 delete param_sets[0]; 00481 delete param_sets[1]; 00482 00483 /* build product of all remaining sets and collect results. delete all 00484 * parameter instances of interim products*/ 00485 for (index_t i=2; i<param_sets.get_num_elements(); ++i) 00486 { 00487 DynArray<Parameter*>* old_temp_result=param_product; 00488 param_product=parameter_set_multiplication(*param_product, 00489 *param_sets[i]); 00490 00491 /* delete interim result parameter instances */ 00492 for (index_t j=0; j<old_temp_result->get_num_elements(); ++j) 00493 delete old_temp_result->get_element(j); 00494 00495 /* and dyn arrays of interim result and of param_sets */ 00496 delete old_temp_result; 00497 delete param_sets[i]; 00498 } 00499 00500 /* at this point there is only one DynArray instance remaining: 00501 * param_product. contains all combinations of parameters of all given 00502 * sets */ 00503 00504 /* third, build tree sets with the given root and the parameter product 00505 * elements */ 00506 for (index_t i=0; i<param_product->get_num_elements(); ++i) 00507 { 00508 /* build parameter node from parameter product to append to root */ 00509 CParameterCombination* param_node=new CParameterCombination( 00510 param_product->get_element(i)); 00511 00512 /* copy new root node, has to be a new one each time */ 00513 CParameterCombination* root=new_root->copy_tree(); 00514 00515 /* append both and add them to result set */ 00516 root->append_child(param_node); 00517 result->append_element(root); 00518 } 00519 00520 /* this is not needed anymore, because the Parameter instances are now 00521 * in the resulting tree sets */ 00522 delete param_product; 00523 } 00524 00525 return result; 00526 } 00527 00528 CDynamicObjectArray* CParameterCombination::non_value_tree_multiplication( 00529 const CDynamicObjectArray* sets, 00530 const CParameterCombination* new_root) 00531 { 00532 SG_SDEBUG("entering CParameterCombination::non_value_tree_multiplication()\n") 00533 CDynamicObjectArray* result=new CDynamicObjectArray(); 00534 00535 /* first step: get all names in the sets */ 00536 set<string> names; 00537 00538 for (index_t j=0; 00539 j<sets->get_num_elements(); ++j) 00540 { 00541 CDynamicObjectArray* current_set= 00542 (CDynamicObjectArray*) 00543 sets->get_element(j); 00544 00545 for (index_t k=0; k 00546 <current_set->get_num_elements(); ++k) 00547 { 00548 CParameterCombination* current_tree=(CParameterCombination*) 00549 current_set->get_element(k); 00550 00551 names.insert(string(current_tree->m_param->get_parameter(0)->m_name)); 00552 00553 SG_UNREF(current_tree); 00554 } 00555 00556 SG_UNREF(current_set); 00557 } 00558 00559 SG_SDEBUG("all names\n") 00560 for (set<string>::iterator it=names.begin(); it!=names.end(); ++it) 00561 SG_SDEBUG("\"%s\"\n", (*it).c_str()) 00562 00563 /* only do stuff if there are names */ 00564 if (!names.empty()) 00565 { 00566 /* next step, build temporary structure where all elements with first 00567 * name are put. Elements of that structure will be extend iteratively 00568 * per name */ 00569 00570 00571 /* extract all trees with first name */ 00572 const char* first_name=(*(names.begin())).c_str(); 00573 CDynamicObjectArray* trees= 00574 CParameterCombination::extract_trees_with_name(sets, first_name); 00575 00576 SG_SDEBUG("adding trees for first name \"%s\":\n", first_name) 00577 for (index_t i=0; i<trees->get_num_elements(); ++i) 00578 { 00579 CParameterCombination* current_tree= 00580 (CParameterCombination*)trees->get_element(i); 00581 00582 CParameterCombination* current_root=new_root->copy_tree(); 00583 current_root->append_child(current_tree); 00584 result->append_element(current_root); 00585 00586 // current_tree->print_tree(1); 00587 SG_UNREF(current_tree); 00588 } 00589 SG_UNREF(trees); 00590 00591 /* now iterate over the remaining names and build products */ 00592 SG_SDEBUG("building products with remaining trees:\n") 00593 set<string>::iterator it=names.begin(); 00594 for (++it; it!=names.end(); ++it) 00595 { 00596 SG_SDEBUG("processing \"%s\"\n", (*it).c_str()) 00597 00598 /* extract all trees with current name */ 00599 const char* current_name=(*it).c_str(); 00600 trees=CParameterCombination::extract_trees_with_name(sets, 00601 current_name); 00602 00603 /* create new set of trees where each element is put once for each 00604 * of the just generated trees */ 00605 CDynamicObjectArray* new_result=new CDynamicObjectArray(); 00606 for (index_t i=0; i<result->get_num_elements(); ++i) 00607 { 00608 for (index_t j=0; j<trees->get_num_elements(); ++j) 00609 { 00610 CParameterCombination* to_copy= 00611 (CParameterCombination*)result->get_element(i); 00612 00613 /* create a copy of current element */ 00614 CParameterCombination* new_element=to_copy->copy_tree(); 00615 SG_UNREF(to_copy); 00616 00617 CParameterCombination* to_add= 00618 (CParameterCombination*)trees->get_element(j); 00619 new_element->append_child(to_add); 00620 SG_UNREF(to_add); 00621 new_result->append_element(new_element); 00622 // SG_SDEBUG("added:\n") 00623 // new_element->print_tree(); 00624 } 00625 } 00626 00627 /* clean up */ 00628 SG_UNREF(trees); 00629 00630 /* replace result by new_result */ 00631 SG_UNREF(result); 00632 result=new_result; 00633 } 00634 } 00635 00636 SG_SDEBUG("leaving CParameterCombination::non_value_tree_multiplication()\n") 00637 return result; 00638 } 00639 00640 CDynamicObjectArray* CParameterCombination::extract_trees_with_name( 00641 const CDynamicObjectArray* sets, const char* desired_name) 00642 { 00643 CDynamicObjectArray* result=new CDynamicObjectArray(); 00644 00645 for (index_t j=0; 00646 j<sets->get_num_elements(); ++j) 00647 { 00648 CDynamicObjectArray* current_set= 00649 (CDynamicObjectArray*) sets->get_element(j); 00650 00651 for (index_t k=0; k<current_set->get_num_elements(); ++k) 00652 { 00653 CParameterCombination* current_tree=(CParameterCombination*) 00654 current_set->get_element(k); 00655 00656 char* current_name=current_tree->m_param->get_parameter(0)->m_name; 00657 00658 if (!strcmp(current_name, desired_name)) 00659 result->append_element(current_tree); 00660 00661 SG_UNREF(current_tree); 00662 } 00663 00664 SG_UNREF(current_set); 00665 } 00666 00667 return result; 00668 } 00669 00670 CParameterCombination* CParameterCombination::copy_tree() const 00671 { 00672 CParameterCombination* copy=new CParameterCombination(); 00673 00674 /* but build new Parameter instance */ 00675 00676 /* only call add_parameters() argument is non-null */ 00677 if (m_param) 00678 { 00679 copy->m_param=new Parameter(); 00680 copy->m_param->add_parameters(m_param); 00681 } else 00682 copy->m_param=NULL; 00683 00684 /* recursively copy all children */ 00685 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i) 00686 { 00687 CParameterCombination* child=(CParameterCombination*) 00688 m_child_nodes->get_element(i); 00689 copy->m_child_nodes->append_element(child->copy_tree()); 00690 SG_UNREF(child); 00691 } 00692 00693 return copy; 00694 } 00695 00696 void CParameterCombination::apply_to_machine(CMachine* machine) const 00697 { 00698 apply_to_modsel_parameter(machine->m_model_selection_parameters); 00699 } 00700 00701 void CParameterCombination::apply_to_modsel_parameter( 00702 Parameter* parameter) const 00703 { 00704 /* case root node */ 00705 if (!m_param) 00706 { 00707 /* iterate over all children and recursively set parameters from 00708 * their values to the current parameter input (its just handed one 00709 * recursion level downwards) */ 00710 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i) 00711 { 00712 CParameterCombination* child=(CParameterCombination*) 00713 m_child_nodes->get_element(i); 00714 child->apply_to_modsel_parameter(parameter); 00715 SG_UNREF(child); 00716 } 00717 } 00718 /* case parameter node */ 00719 else if (m_param) 00720 { 00721 /* set parameters */ 00722 parameter->set_from_parameters(m_param); 00723 00724 /* does this node has sub parameters? */ 00725 if (has_children()) 00726 { 00727 /* if a parameter node has children, it has to have ONE CSGObject as 00728 * parameter */ 00729 if (m_param->get_num_parameters()>1 || 00730 m_param->get_parameter(0)->m_datatype.m_ptype!=PT_SGOBJECT) 00731 { 00732 SG_SERROR("invalid CParameterCombination node type, has children" 00733 " and more than one parameter or is not a " 00734 "CSGObject.\n"); 00735 } 00736 00737 /* cast is now safe */ 00738 CSGObject* current_sgobject= 00739 *((CSGObject**)(m_param->get_parameter(0)->m_parameter)); 00740 00741 /* iterate over all children and recursively set parameters from 00742 * their values */ 00743 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i) 00744 { 00745 CParameterCombination* child=(CParameterCombination*) 00746 m_child_nodes->get_element(i); 00747 child->apply_to_modsel_parameter( 00748 current_sgobject->m_model_selection_parameters); 00749 SG_UNREF(child); 00750 } 00751 } 00752 } 00753 else 00754 SG_SERROR("CParameterCombination node has illegal type.\n") 00755 } 00756 00757 void CParameterCombination::build_parameter_values_map( 00758 CMap<TParameter*, SGVector<float64_t> >* dict) 00759 { 00760 if (m_param) 00761 { 00762 for (index_t i=0; i<m_param->get_num_parameters(); i++) 00763 { 00764 TParameter* param=m_param->get_parameter(i); 00765 TSGDataType type=param->m_datatype; 00766 00767 if (type.m_ptype==PT_FLOAT64 || type.m_ptype==PT_FLOAT32 || 00768 type.m_ptype==PT_FLOATMAX) 00769 { 00770 if ((type.m_ctype==CT_SGVECTOR || type.m_ctype==CT_VECTOR)) 00771 { 00772 SGVector<float64_t> value(*((float64_t **)param->m_parameter), 00773 (*type.m_length_y)); 00774 dict->add(param, value); 00775 } 00776 else if (type.m_ctype==CT_SCALAR) 00777 { 00778 SGVector<float64_t> value(1); 00779 value.set_const(*((float64_t *)param->m_parameter)); 00780 dict->add(param, value); 00781 } 00782 } 00783 } 00784 } 00785 00786 for (index_t i=0; i<m_child_nodes->get_num_elements(); i++) 00787 { 00788 CParameterCombination* child=(CParameterCombination*) 00789 m_child_nodes->get_element(i); 00790 child->build_parameter_values_map(dict); 00791 SG_UNREF(child); 00792 } 00793 } 00794 00795 void CParameterCombination::build_parameter_parent_map( 00796 CMap<TParameter*, CSGObject*>* dict) 00797 { 00798 CSGObject* parent=NULL; 00799 00800 if (m_param) 00801 { 00802 for (index_t i=0; i<m_param->get_num_parameters(); i++) 00803 { 00804 TParameter* param=m_param->get_parameter(i); 00805 TSGDataType type=param->m_datatype; 00806 00807 if (type.m_ptype==PT_SGOBJECT) 00808 { 00809 if (type.m_ctype==CT_SCALAR) 00810 { 00811 parent=(*(CSGObject**)param->m_parameter); 00812 break; 00813 } 00814 else 00815 { 00816 SG_NOTIMPLEMENTED 00817 } 00818 } 00819 } 00820 } 00821 00822 for (index_t i=0; i<m_child_nodes->get_num_elements(); i++) 00823 { 00824 CParameterCombination* child=(CParameterCombination*) 00825 m_child_nodes->get_element(i); 00826 00827 for (index_t j=0; j<child->m_param->get_num_parameters(); j++) 00828 { 00829 TParameter* param=child->m_param->get_parameter(j); 00830 TSGDataType type=param->m_datatype; 00831 00832 if (type.m_ptype==PT_SGOBJECT) 00833 { 00834 if (type.m_ctype==CT_SCALAR) 00835 { 00836 child->build_parameter_parent_map(dict); 00837 } 00838 else 00839 { 00840 SG_NOTIMPLEMENTED 00841 } 00842 } 00843 else 00844 { 00845 dict->add(param, parent); 00846 } 00847 } 00848 SG_UNREF(child); 00849 } 00850 }