00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <shogun/modelselection/ModelSelectionParameters.h>
00014 #include <shogun/modelselection/ParameterCombination.h>
00015 #include <shogun/lib/DataType.h>
00016 #include <shogun/base/Parameter.h>
00017 #include <shogun/base/DynArray.h>
00018 #include <shogun/lib/Set.h>
00019
00020 using namespace shogun;
00021
00022 CModelSelectionParameters::CModelSelectionParameters()
00023 {
00024 init();
00025 }
00026
00027 CModelSelectionParameters::CModelSelectionParameters(const char* node_name)
00028 {
00029 init();
00030
00031 m_node_name=node_name;
00032 }
00033
00034 CModelSelectionParameters::CModelSelectionParameters(const char* node_name,
00035 CSGObject* sgobject)
00036 {
00037 init();
00038
00039 m_node_name=node_name;
00040 m_sgobject=sgobject;
00041 SG_REF(sgobject);
00042 }
00043
00044 void CModelSelectionParameters::init()
00045 {
00046 m_node_name=NULL;
00047 m_sgobject=NULL;
00048 m_child_nodes=new CDynamicObjectArray();
00049 SG_REF(m_child_nodes);
00050 m_value_type=MSPT_NONE;
00051 m_values=NULL;
00052 m_values_length=0;
00053
00054
00055 }
00056
00057 CModelSelectionParameters::~CModelSelectionParameters()
00058 {
00059 SG_UNREF(m_child_nodes);
00060 SG_UNREF(m_sgobject);
00061
00062 delete_values();
00063 }
00064
00065 void CModelSelectionParameters::append_child(CModelSelectionParameters* child)
00066 {
00067
00068 if (m_values)
00069 SG_ERROR("not possible to append child: there already is a range\n");
00070
00071
00072 if (m_sgobject)
00073 {
00074
00075
00076
00077 if (child->m_node_name)
00078 {
00079 if (!m_sgobject->m_parameters->contains_parameter(child->m_node_name))
00080 {
00081 SG_ERROR("Not possible to add child, node with CSGObject \"%s\""
00082 " does not contain a parameter called \"%s\"\n",
00083 m_sgobject->get_name(), child->m_node_name);
00084 }
00085 }
00086 else
00087 {
00088 SG_ERROR("Not possible to add child which has no name.\n");
00089 }
00090 }
00091
00092 m_child_nodes->append_element(child);
00093 }
00094
00095 template <class T>
00096 void CModelSelectionParameters::set_values(const SGVector<T>& values,
00097 EMSParamType value_type)
00098 {
00099
00100 delete_values();
00101 m_values=values.vector;
00102 m_values_length=values.vlen;
00103 m_value_type=value_type;
00104 }
00105
00106 void CModelSelectionParameters::build_values(float64_t min, float64_t max,
00107 ERangeType type, float64_t step, float64_t type_base)
00108 {
00109 build_values(MSPT_FLOAT64, (void*)&min, (void*)&max, type, (void*)&step,
00110 (void*)&type_base);
00111 }
00112
00113 void CModelSelectionParameters::build_values_vector(float64_t min, float64_t max,
00114 ERangeType type, void* vector, index_t* size, float64_t step, float64_t type_base)
00115 {
00116 build_values(MSPT_FLOAT64_VECTOR, (void*)&min, (void*)&max, type, (void*)&step,
00117 (void*)&type_base);
00118 m_vector_length = size;
00119 m_vector = vector;
00120 }
00121
00122 void CModelSelectionParameters::build_values_sgvector(float64_t min, float64_t max,
00123 ERangeType type, void* vector, float64_t step, float64_t type_base)
00124 {
00125 build_values(MSPT_FLOAT64_SGVECTOR, (void*)&min, (void*)&max, type, (void*)&step,
00126 (void*)&type_base);
00127 m_vector = vector;
00128 }
00129
00130 void CModelSelectionParameters::build_values(int32_t min, int32_t max,
00131 ERangeType type, int32_t step, int32_t type_base)
00132 {
00133 build_values(MSPT_INT32, (void*)&min, (void*)&max, type, (void*)&step,
00134 (void*)&type_base);
00135 }
00136
00137 void CModelSelectionParameters::build_values_vector(int32_t min, int32_t max,
00138 ERangeType type, void* vector, index_t* size, int32_t step, int32_t type_base)
00139 {
00140 build_values(MSPT_INT32_VECTOR, (void*)&min, (void*)&max, type, (void*)&step,
00141 (void*)&type_base);
00142 m_vector_length = size;
00143 m_vector = vector;
00144 }
00145
00146 void CModelSelectionParameters::build_values_sgvector(int32_t min, int32_t max,
00147 ERangeType type, void* vector, int32_t step, int32_t type_base)
00148 {
00149 build_values(MSPT_INT32_SGVECTOR, (void*)&min, (void*)&max, type, (void*)&step,
00150 (void*)&type_base);
00151 m_vector = vector;
00152 }
00153
00154 void CModelSelectionParameters::build_values(EMSParamType value_type, void* min,
00155 void* max, ERangeType type, void* step, void* type_base)
00156 {
00157 if (m_sgobject || has_children())
00158 {
00159 SG_ERROR("unable to set range for an CSGObject model selection "
00160 "parameter\n");
00161 }
00162
00163
00164 delete_values();
00165
00166
00167 m_value_type=value_type;
00168
00169 if (value_type==MSPT_FLOAT64 ||
00170 value_type==MSPT_FLOAT64_VECTOR
00171 || value_type==MSPT_FLOAT64_SGVECTOR)
00172 {
00173 SGVector<float64_t> values=create_range_array<float64_t>(
00174 *((float64_t*)min),
00175 *((float64_t*)max),
00176 type,
00177 *((float64_t*)step),
00178 *((float64_t*)type_base));
00179
00180 m_values=values.vector;
00181 m_values_length=values.vlen;
00182 }
00183 else if (value_type==MSPT_INT32 ||
00184 value_type==MSPT_INT32_VECTOR
00185 || value_type==MSPT_INT32_SGVECTOR)
00186 {
00187 SGVector<int32_t> values=create_range_array<int32_t>(
00188 *((int32_t*)min),
00189 *((int32_t*)max),
00190 type,
00191 *((int32_t*)step),
00192 *((int32_t*)type_base));
00193
00194 m_values=values.vector;
00195 m_values_length=values.vlen;
00196 }
00197 else if (value_type==MSPT_NONE)
00198 {
00199 SG_ERROR("Value node has no type!\n");
00200 }
00201 else
00202 {
00203 SG_ERROR("Unknown type for model selection parameter!\n");
00204 }
00205 }
00206
00207 CParameterCombination* CModelSelectionParameters::get_single_combination(
00208 bool is_rand)
00209 {
00210
00211
00212 if (m_values)
00213 {
00214
00215 index_t i = 0;
00216
00217 if (is_rand)
00218 i = CMath::random(0, m_values_length-1);
00219
00220 Parameter* p=new Parameter();
00221
00222 switch (m_value_type)
00223 {
00224 case MSPT_FLOAT64_SGVECTOR:
00225 {
00226 SGVector<float64_t>* param_vect = (SGVector<float64_t>*)m_vector;
00227
00228 for (index_t j = 0; j < param_vect->vlen; j++)
00229 {
00230 if (is_rand)
00231 i = CMath::random(0, m_values_length-1);
00232 (*param_vect)[j] = ((float64_t*)m_values)[i];
00233 }
00234 p->add(param_vect, m_node_name);
00235 break;
00236 }
00237 case MSPT_FLOAT64_VECTOR:
00238 {
00239 float64_t* param_vect = (float64_t*)m_vector;
00240
00241 for (index_t j = 0; j < *m_vector_length; j++)
00242 {
00243 if (is_rand)
00244 i = CMath::random(0, m_values_length-1);
00245 (param_vect)[j] = ((float64_t*)m_values)[i];
00246 }
00247 p->add_vector(¶m_vect, m_vector_length, m_node_name);
00248 break;
00249 }
00250 case MSPT_INT32_SGVECTOR:
00251 {
00252 SGVector<int32_t>* param_vect = (SGVector<int32_t>*)m_vector;
00253
00254 for (index_t j = 0; j < param_vect->vlen; j++)
00255 {
00256 if (is_rand)
00257 i = CMath::random(0, m_values_length-1);
00258 (*param_vect)[j] = ((int32_t*)m_values)[i];
00259 }
00260 p->add(param_vect, m_node_name);
00261 break;
00262 }
00263 case MSPT_INT32_VECTOR:
00264 {
00265 int32_t* param_vect = (int32_t*)m_vector;
00266
00267 for (index_t j = 0; j < *m_vector_length; j++)
00268 {
00269 if (is_rand)
00270 i = CMath::random(0, m_values_length-1);
00271 (param_vect)[j] = ((int32_t*)m_values)[i];
00272 }
00273 p->add_vector(¶m_vect, m_vector_length, m_node_name);
00274 break;
00275 }
00276 case MSPT_FLOAT64:
00277 p->add(&((float64_t*)m_values)[i], m_node_name);
00278 break;
00279 case MSPT_INT32:
00280 p->add(&((int32_t*)m_values)[i], m_node_name);;
00281 break;
00282 case MSPT_NONE:
00283 SG_ERROR("Value node has no type!\n");
00284 break;
00285 default:
00286 SG_ERROR("Unknown type for model selection parameter!\n");
00287 break;
00288 }
00289
00290 return new CParameterCombination(p);
00291 }
00292
00293 CParameterCombination* new_root=NULL;
00294
00295
00296 if (!((m_sgobject && m_node_name) || (!m_node_name && !m_sgobject)))
00297 SG_ERROR("Illegal CModelSelectionParameters node type.\n");
00298
00299
00300 if (m_child_nodes->get_num_elements())
00301 {
00302
00303 if (m_sgobject)
00304 {
00305 Parameter* p=new Parameter();
00306 p->add(&m_sgobject, m_node_name);
00307 new_root = new CParameterCombination(p);
00308 }
00309
00310 else
00311 new_root = new CParameterCombination();
00312
00313 for (index_t i = 0; i < m_child_nodes->get_num_elements(); ++i)
00314 {
00315 CModelSelectionParameters* current =
00316 (CModelSelectionParameters*)m_child_nodes->get_element(i);
00317
00318 CParameterCombination* c = current->get_single_combination(is_rand);
00319
00320 new_root->append_child(c);
00321
00322 SG_UNREF(current);
00323 }
00324
00325 return new_root;
00326 }
00327
00328
00329 else
00330 {
00331
00332 if (m_sgobject)
00333 {
00334 Parameter* p = new Parameter();
00335 p->add(&m_sgobject, m_node_name);
00336 return new CParameterCombination(p);
00337 }
00338
00339 else
00340 {
00341 new_root = new CParameterCombination();
00342 return new_root;
00343 }
00344 }
00345
00346 }
00347
00348
00349
00350 CDynamicObjectArray* CModelSelectionParameters::get_combinations(
00351 index_t num_prefix)
00352 {
00353 char* prefix=SG_MALLOC(char, num_prefix+1);
00354 prefix[num_prefix]='\0';
00355 for (index_t i=0; i<num_prefix; ++i)
00356 prefix[i]='\t';
00357
00358 SG_DEBUG("%s------>entering CModelSelectionParameters::get_combinations() "
00359 "for \"%s\"\n", prefix, m_node_name ? m_node_name : "root");
00360 CDynamicObjectArray* result=new CDynamicObjectArray();
00361
00362
00363
00364
00365
00366 if (m_values)
00367 {
00368 for (index_t i=0; i<m_values_length; ++i)
00369 {
00370
00371 Parameter* p=new Parameter();
00372
00373 switch (m_value_type)
00374 {
00375 case MSPT_FLOAT64:
00376 p->add(&((float64_t*)m_values)[i], m_node_name);
00377 break;
00378 case MSPT_INT32:
00379 p->add(&((int32_t*)m_values)[i], m_node_name);;
00380 break;
00381 case MSPT_NONE:
00382 SG_ERROR("%sValue node has no type!\n", prefix);
00383 break;
00384 default:
00385 SG_ERROR("%sUnknown type for model selection parameter!\n",
00386 prefix);
00387 break;
00388 }
00389
00390 result->append_element(new CParameterCombination(p));
00391 }
00392
00393 SG_DEBUG("%s------>leaving CModelSelectionParameters::get_combinations()"
00394 "for \"%s\"\n", prefix, m_node_name ? m_node_name : "root");
00395
00396 SG_FREE(prefix);
00397 return result;
00398 }
00399
00400
00401
00402
00403
00404
00405
00406
00407 if (!((m_sgobject && m_node_name) || (!m_node_name && !m_sgobject)))
00408 SG_ERROR("%sIllegal CModelSelectionParameters node type.\n", prefix);
00409
00410
00411 if (m_child_nodes->get_num_elements())
00412 {
00413
00414 CDynamicObjectArray value_children;
00415 CDynamicObjectArray non_value_children;
00416
00417 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
00418 {
00419 CModelSelectionParameters* current=
00420 (CModelSelectionParameters*)m_child_nodes->get_element(i);
00421
00422
00423 if (current->m_values)
00424 value_children.append_element(current);
00425 else
00426 non_value_children.append_element(current);
00427
00428 SG_UNREF(current);
00429 }
00430
00431
00432 CDynamicObjectArray value_node_sets;
00433 for (index_t i=0; i<value_children.get_num_elements(); ++i)
00434 {
00435
00436 CModelSelectionParameters* value_child=
00437 (CModelSelectionParameters*)value_children.get_element(i);
00438 value_node_sets.append_element(value_child->get_combinations(
00439 num_prefix+1));
00440 SG_UNREF(value_child);
00441 }
00442
00443
00444
00445
00446 CParameterCombination* new_root=NULL;
00447 if (m_sgobject)
00448 {
00449 Parameter* p=new Parameter();
00450 p->add(&m_sgobject, m_node_name);
00451 new_root=new CParameterCombination(p);
00452 }
00453 else
00454 new_root=new CParameterCombination();
00455
00456 SG_REF(new_root);
00457
00458 CDynamicObjectArray* value_combinations=
00459 CParameterCombination::leaf_sets_multiplication(value_node_sets,
00460 new_root);
00461
00462 SG_UNREF(new_root);
00463
00464 if (!non_value_children.get_num_elements())
00465 *result=*value_combinations;
00466
00467
00468 else
00469 {
00470
00471
00472 CDynamicObjectArray* non_value_combinations=
00473 new CDynamicObjectArray();
00474 for (index_t i=0; i<non_value_children.get_num_elements(); ++i)
00475 {
00476
00477 CModelSelectionParameters* non_value_child=
00478 (CModelSelectionParameters*)
00479 non_value_children.get_element(i);
00480
00481
00482
00483
00484 CDynamicObjectArray* current_combination=
00485 non_value_child->get_combinations(num_prefix+2);
00486 non_value_combinations->append_element(current_combination);
00487 SG_UNREF(non_value_child);
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 }
00498
00499
00500
00501
00502
00503
00504 if (!value_combinations->get_num_elements())
00505 {
00506
00507
00508
00509
00510 if (m_sgobject)
00511 {
00512 Parameter* p=new Parameter();
00513 p->add(&m_sgobject, m_node_name);
00514 new_root=new CParameterCombination(p);
00515 }
00516 else
00517 new_root=new CParameterCombination();
00518
00519 CDynamicObjectArray* non_value_products=
00520 CParameterCombination::non_value_tree_multiplication(
00521 non_value_combinations, new_root);
00522
00523 SG_UNREF(new_root);
00524
00525 SG_UNREF(non_value_combinations);
00526 non_value_combinations=non_value_products;
00527
00528
00529 for (index_t i=0; i<non_value_combinations->get_num_elements(); ++i)
00530 {
00531 CParameterCombination* current=(CParameterCombination*)
00532 non_value_combinations->get_element(i);
00533 result->append_element(current);
00534 SG_UNREF(current);
00535 }
00536 }
00537 else
00538 {
00539
00540
00541
00542 if (m_sgobject)
00543 {
00544 Parameter* p=new Parameter();
00545 p->add(&m_sgobject, m_node_name);
00546 new_root=new CParameterCombination(p);
00547 }
00548 else
00549 new_root=new CParameterCombination();
00550
00551 CDynamicObjectArray* non_value_products=
00552 CParameterCombination::non_value_tree_multiplication(
00553 non_value_combinations, new_root);
00554
00555 SG_UNREF(new_root);
00556
00557 SG_UNREF(non_value_combinations);
00558 non_value_combinations=non_value_products;
00559
00560 for (index_t i=0; i<value_combinations->get_num_elements(); ++i)
00561 {
00562 CParameterCombination* current_value_tree=
00563 (CParameterCombination*)
00564 value_combinations->get_element(i);
00565
00566 for (index_t j=0; j
00567 <non_value_combinations->get_num_elements(); ++j)
00568 {
00569 CParameterCombination* current_non_value_tree=
00570 (CParameterCombination*)
00571 non_value_combinations->get_element(j);
00572
00573
00574
00575 CParameterCombination* value_copy=
00576 current_value_tree->copy_tree();
00577
00578 value_copy->merge_with(current_non_value_tree);
00579 result->append_element(value_copy);
00580
00581 SG_UNREF(current_non_value_tree);
00582 }
00583
00584 SG_UNREF(current_value_tree);
00585 }
00586 }
00587
00588
00589 SG_UNREF(non_value_combinations);
00590 }
00591
00592 SG_UNREF(value_combinations);
00593 }
00594 else
00595 {
00596
00597
00598
00599 if (m_sgobject)
00600 {
00601 Parameter* p=new Parameter();
00602 p->add(&m_sgobject, m_node_name);
00603 result->append_element(new CParameterCombination(p));
00604 }
00605 }
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 SG_DEBUG("%s------>leaving CModelSelectionParameters::get_combinations()"
00618 "for \"%s\"\n", prefix, m_node_name ? m_node_name : "root");
00619 SG_FREE(prefix);
00620 return result;
00621 }
00622
00623 void CModelSelectionParameters::print_tree(int prefix_num)
00624 {
00625
00626 char* prefix=SG_MALLOC(char, prefix_num+1);
00627 for (index_t i=0; i<prefix_num; ++i)
00628 prefix[i]='\t';
00629
00630 prefix[prefix_num]='\0';
00631
00632 if (has_children())
00633 {
00634 if (m_sgobject)
00635 SG_PRINT("%s%s:\"%s\"\n", prefix, m_node_name, m_sgobject->get_name());
00636 else
00637 SG_PRINT("%s%s with\n", prefix, m_node_name ? m_node_name : "root");
00638
00639
00640
00641
00642 for (index_t i=0; i<m_child_nodes->get_num_elements(); ++i)
00643 {
00644 CModelSelectionParameters* child=
00645 (CModelSelectionParameters*)m_child_nodes->get_element(i);
00646 child->print_tree(prefix_num+1);
00647 SG_UNREF(child);
00648 }
00649 }
00650 else
00651 {
00652
00653
00654 if (m_sgobject)
00655 {
00656 SG_PRINT("%s%s:\"%s\"\n", prefix, m_node_name, m_sgobject->get_name());
00657 }
00658 else
00659 {
00660 if (m_values)
00661 {
00662
00663 SG_PRINT("%s%s with values: ", prefix, m_node_name);
00664
00665 switch (m_value_type)
00666 {
00667 case MSPT_FLOAT64: case MSPT_FLOAT64_VECTOR:
00668 case MSPT_FLOAT64_SGVECTOR:
00669
00670 SGVector<float64_t>::display_vector((float64_t*)m_values,
00671 m_values_length);
00672 break;
00673 case MSPT_INT32: case MSPT_INT32_VECTOR:
00674 case MSPT_INT32_SGVECTOR:
00675
00676 SGVector<int32_t>::display_vector((int32_t*)m_values,
00677 m_values_length);;
00678 break;
00679 case MSPT_NONE:
00680 SG_ERROR("Value node has no type!\n");
00681 break;
00682 default:
00683 SG_ERROR("Unknown type for model selection parameter!\n");
00684 break;
00685 }
00686 }
00687 else
00688 SG_PRINT("root\n");
00689 }
00690 }
00691
00692 SG_FREE(prefix);
00693 }
00694
00695 void CModelSelectionParameters::delete_values()
00696 {
00697 if (m_values)
00698 {
00699 switch (m_value_type)
00700 {
00701 case MSPT_FLOAT64: case MSPT_FLOAT64_VECTOR:
00702 case MSPT_FLOAT64_SGVECTOR:
00703
00704 SG_FREE((float64_t*)m_values);
00705 break;
00706 case MSPT_INT32: case MSPT_INT32_VECTOR:
00707 case MSPT_INT32_SGVECTOR:
00708
00709 SG_FREE((int32_t*)m_values);
00710 break;
00711 case MSPT_NONE:
00712 SG_ERROR("Value node has no type!\n");
00713 break;
00714 default:
00715 SG_ERROR("Unknown type for model selection parameter!\n");
00716 break;
00717 }
00718 }
00719 }