ParameterMap.cpp

Go to the documentation of this file.
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 Heiko Strathmann
00008  * Copyright (C) 2011 Berlin Institute of Technology and Max-Planck-Society
00009  */
00010 
00011 #include <shogun/base/ParameterMap.h>
00012 #include <shogun/base/Parameter.h>
00013 #include <shogun/mathematics/Math.h>
00014 
00015 using namespace shogun;
00016 
00017 SGParamInfo::SGParamInfo()
00018 {
00019     m_name=NULL;
00020     m_ctype=(EContainerType) -1;
00021     m_stype=(EStructType) -1;
00022     m_ptype=(EPrimitiveType) -1;
00023     m_param_version=-1;
00024 }
00025 
00026 SGParamInfo::SGParamInfo(const SGParamInfo& orig)
00027 {
00028     /* copy name if existent */
00029     m_name=orig.m_name ? strdup(orig.m_name) : NULL;
00030 
00031     m_ctype=orig.m_ctype;
00032     m_stype=orig.m_stype;
00033     m_ptype=orig.m_ptype;
00034     m_param_version=orig.m_param_version;
00035 }
00036 
00037 SGParamInfo::SGParamInfo(const char* name, EContainerType ctype,
00038         EStructType stype, EPrimitiveType ptype, int32_t param_version)
00039 {
00040     /* copy name if existent */
00041     m_name=name ? strdup(name) : NULL;
00042 
00043     m_ctype=ctype;
00044     m_stype=stype;
00045     m_ptype=ptype;
00046     m_param_version=param_version;
00047 }
00048 
00049 SGParamInfo::SGParamInfo(const TParameter* param, int32_t param_version)
00050 {
00051     /* copy name if existent */
00052     m_name=param->m_name ? strdup(param->m_name) : NULL;
00053 
00054     TSGDataType type=param->m_datatype;
00055     m_ctype=type.m_ctype;
00056     m_stype=type.m_stype;
00057     m_ptype=type.m_ptype;
00058     m_param_version=param_version;
00059 }
00060 
00061 SGParamInfo::~SGParamInfo()
00062 {
00063     SG_FREE(m_name);
00064 }
00065 
00066 char* SGParamInfo::to_string() const
00067 {
00068     char* buffer=SG_MALLOC(char, 200);
00069     strcpy(buffer, "SGParamInfo with: ");
00070     strcat(buffer, "name=\"");
00071     strcat(buffer, m_name ? m_name : "NULL");
00072     strcat(buffer, "\", type=");
00073 
00074     char* b;
00075     /* only cat type if it is defined (is not when std constructor was used)*/
00076     if (!is_empty())
00077     {
00078         TSGDataType t(m_ctype, m_stype, m_ptype);
00079         index_t l=100;
00080         b=SG_MALLOC(char, l);
00081         t.to_string(b, l);
00082         strcat(buffer, b);
00083         SG_FREE(b);
00084     }
00085     else
00086         strcat(buffer, "no type");
00087 
00088     b=SG_MALLOC(char, 10);
00089     sprintf(b, "%d", m_param_version);
00090     strcat(buffer, ", version=");
00091     strcat(buffer, b);
00092     SG_FREE(b);
00093 
00094     return buffer;
00095 }
00096 
00097 void SGParamInfo::print_param_info(const char* prefix) const
00098 {
00099     char* s=to_string();
00100     SG_SPRINT("%s%s\n", prefix, s);
00101     SG_FREE(s);
00102 }
00103 
00104 SGParamInfo* SGParamInfo::duplicate() const
00105 {
00106     return new SGParamInfo(m_name, m_ctype, m_stype, m_ptype, m_param_version);
00107 }
00108 
00109 bool SGParamInfo::operator==(const SGParamInfo& other) const
00110 {
00111     bool result=true;
00112 
00113     /* handle NULL strings */
00114     if ((!m_name && other.m_name) || (m_name && !other.m_name))
00115         return false;
00116 
00117     if (m_name && other.m_name)
00118         result&=!strcmp(m_name, other.m_name);
00119 
00120     result&=m_ctype==other.m_ctype;
00121     result&=m_stype==other.m_stype;
00122     result&=m_ptype==other.m_ptype;
00123     result&=m_param_version==other.m_param_version;
00124     return result;
00125 }
00126 
00127 bool SGParamInfo::operator!=(const SGParamInfo& other) const
00128 {
00129     return !operator ==(other);
00130 }
00131 
00132 bool SGParamInfo::operator<(const SGParamInfo& other) const
00133 {
00134     /* NULL here is always smaller than anything */
00135     if (!m_name)
00136     {
00137         if (!other.m_name)
00138             return false;
00139         else
00140             return true;
00141     }
00142     else if (!other.m_name)
00143         return true;
00144 
00145     int32_t result=strcmp(m_name, other.m_name);
00146 
00147     if (result==0)
00148     {
00149         if (m_param_version==other.m_param_version)
00150         {
00151             if (m_ctype==other.m_ctype)
00152             {
00153                 if (m_stype==other.m_stype)
00154                 {
00155                     if (m_ptype==other.m_ptype)
00156                     {
00157                         return false;
00158                     }
00159                     else
00160                         return m_ptype<other.m_ptype;
00161                 }
00162                 else
00163                     return m_stype<other.m_stype;
00164             }
00165             else
00166                 return m_ctype<other.m_ctype;
00167         }
00168         else
00169             return m_param_version<other.m_param_version;
00170 
00171     }
00172     else
00173         return result<0;
00174 }
00175 
00176 bool SGParamInfo::operator>(const SGParamInfo& other) const
00177 {
00178     return !(*this<(other)) && !(*this==other);
00179 }
00180 
00181 bool SGParamInfo::is_empty() const
00182 {
00183     /* return true if this info is for empty parameter */
00184     return m_ctype<0 && m_stype<0 && m_ptype<0 && !m_name;
00185 }
00186 
00187 ParameterMapElement::ParameterMapElement()
00188 {
00189     m_key=NULL;
00190     m_values=NULL;
00191 }
00192 
00193 ParameterMapElement::ParameterMapElement(const SGParamInfo* key,
00194         DynArray<const SGParamInfo*>* values)
00195 {
00196     m_key=key;
00197     m_values=values;
00198 }
00199 
00200 ParameterMapElement::~ParameterMapElement()
00201 {
00202     delete m_key;
00203 
00204     if (m_values)
00205     {
00206         for (index_t i=0; i<m_values->get_num_elements(); ++i)
00207             delete m_values->get_element(i);
00208 
00209         delete m_values;
00210     }
00211 }
00212 
00213 bool ParameterMapElement::operator==(const ParameterMapElement& other) const
00214 {
00215     return *m_key==*other.m_key;
00216 }
00217 
00218 bool ParameterMapElement::operator<(const ParameterMapElement& other) const
00219 {
00220     return *m_key<*other.m_key;
00221 }
00222 
00223 bool ParameterMapElement::operator>(const ParameterMapElement& other) const
00224 {
00225     return *m_key>*other.m_key;
00226 }
00227 
00228 ParameterMap::ParameterMap()
00229 {
00230     m_finalized=false;
00231 }
00232 
00233 ParameterMap::~ParameterMap()
00234 {
00235     for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
00236         delete m_map_elements[i];
00237 
00238     for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
00239         delete m_multi_map_elements[i];
00240 }
00241 
00242 void ParameterMap::put(const SGParamInfo* key, const SGParamInfo* value)
00243 {
00244     /* assert that versions do differ exactly one if mapping is non-empty */
00245     if(key->m_param_version-value->m_param_version!=1)
00246     {
00247         if (!key->is_empty() && !value->is_empty())
00248         {
00249             char* s=key->to_string();
00250             char* t=value->to_string();
00251             SG_SERROR("Versions of parameter mappings from \"%s\" to \"%s\" have"
00252                     " to differ exactly one\n", s, t);
00253             SG_FREE(s);
00254             SG_FREE(t);
00255         }
00256     }
00257 
00258     /* always add array of ONE element as values, will be processed later
00259      * in finalize map method */
00260     DynArray<const SGParamInfo*>* values=new DynArray<const SGParamInfo*>();
00261     values->append_element(value);
00262     m_map_elements.append_element(new ParameterMapElement(key, values));
00263     m_finalized=false;
00264 }
00265 
00266 DynArray<const SGParamInfo*>* ParameterMap::get(const SGParamInfo key) const
00267 {
00268     return get(&key);
00269 }
00270 
00271 DynArray<const SGParamInfo*>* ParameterMap::get(const SGParamInfo* key) const
00272 {
00273     index_t num_elements=m_multi_map_elements.get_num_elements();
00274 
00275     /* check if maps is finalized */
00276     if (!m_finalized && num_elements)
00277         SG_SERROR("Call finalize_map() before calling get()\n");
00278 
00279     /* do binary search in array of pointers */
00280     /* dummy element for searching */
00281     ParameterMapElement* dummy=new ParameterMapElement(key->duplicate(), NULL);
00282     index_t index=CMath::binary_search<ParameterMapElement> (
00283             m_multi_map_elements.get_array(), num_elements, dummy);
00284     delete dummy;
00285 
00286     if (index==-1)
00287         return NULL;
00288 
00289     ParameterMapElement* element=m_multi_map_elements.get_element(index);
00290     return element->m_values;
00291 }
00292 
00293 void ParameterMap::finalize_map()
00294 {
00295     /* only do something if there are elements in map */
00296     if (!m_map_elements.get_num_elements())
00297         return;
00298 
00299     /* sort underlying array */
00300     CMath::qsort<ParameterMapElement> (m_map_elements.get_array(),
00301             m_map_elements.get_num_elements());
00302 
00303 //  SG_SPRINT("map elements before finalize\n");
00304 //  for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
00305 //  {
00306 //      ParameterMapElement* current=m_map_elements[i];
00307 //      SG_SPRINT("element %d:\n", i);
00308 //      SG_SPRINT("\tkey: ");
00309 //      current->m_key->print_param_info();
00310 //      SG_SPRINT("\t%d values:\n", current->m_values->get_num_elements());
00311 //      for (index_t j=0; j<current->m_values->get_num_elements(); ++j)
00312 //          current->m_values->get_element(j)->print_param_info("\t\t");
00313 //  }
00314 
00315     /* clear old multi elements. These were copies. */
00316     for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
00317         delete m_multi_map_elements[i];
00318 
00319     m_multi_map_elements.reset();
00320 //  SG_SPRINT("\nstarting finalization\n");
00321 
00322     /* iterate over all elements of map elements (have all one value (put)) and
00323      * add all values of same key to ONE map element of hidden structure */
00324     DynArray<const SGParamInfo*>* values=new DynArray<const SGParamInfo*>();
00325     const SGParamInfo* current_key=m_map_elements[0]->m_key;
00326 //  char* s=current_key->to_string();
00327 //  SG_SPRINT("current key: %s\n", s);
00328 //  SG_FREE(s);
00329     for (index_t i=0; i<m_map_elements.get_num_elements(); ++i)
00330     {
00331         const ParameterMapElement* current=m_map_elements[i];
00332         if (*current_key != *current->m_key)
00333         {
00334             /* create new values array to add and update key */
00335             values=new DynArray<const SGParamInfo*>();
00336             current_key=current->m_key;
00337 //          s=current_key->to_string();
00338 //          SG_SPRINT("new current key: %s\n", s);
00339 //          SG_FREE(s);
00340         }
00341 
00342         /* add to values array */
00343         char* t=current->m_values->get_element(0)->to_string();
00344 //      SG_SPRINT("\tadding %s\n", t);
00345         SG_FREE(t);
00346         values->append_element(current->m_values->get_element(0)->duplicate());
00347 
00348         /* if current values array has not been added to multi map elements, do
00349          * now */
00350         index_t last_idx=m_multi_map_elements.get_num_elements()-1;
00351         if (last_idx<0 ||
00352                 m_multi_map_elements.get_element(last_idx)->m_values != values)
00353         {
00354 //          SG_SPRINT("adding values array\n");
00355             m_multi_map_elements.append_element(
00356                 new ParameterMapElement(current_key->duplicate(), values));
00357         }
00358     }
00359 
00360     m_finalized=true;
00361 //  SG_SPRINT("leaving finalize_map()\n");
00362 }
00363 
00364 void ParameterMap::print_map()
00365 {
00366     /* check if maps is finalized */
00367     if (!m_finalized && m_map_elements.get_num_elements())
00368         SG_SERROR("Call finalize_map() before calling print_map()\n");
00369 
00370 //  SG_SPRINT("map with %d keys:\n", m_multi_map_elements.get_num_elements());
00371     for (index_t i=0; i<m_multi_map_elements.get_num_elements(); ++i)
00372     {
00373         ParameterMapElement* current=m_multi_map_elements[i];
00374 //      SG_SPRINT("element %d:\n", i);
00375 //      SG_SPRINT("\tkey: ");
00376 //      current->m_key->print_param_info();
00377 //      SG_SPRINT("\t%d values:\n", current->m_values->get_num_elements());
00378         for (index_t j=0; j<current->m_values->get_num_elements(); ++j)
00379             current->m_values->get_element(j)->print_param_info("\t\t");
00380     }
00381 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

SHOGUN Machine Learning Toolbox - Documentation