SHOGUN
v2.0.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) 2012 Heiko Strathmann 00008 */ 00009 00010 #include <shogun/features/SubsetStack.h> 00011 #include <shogun/io/SGIO.h> 00012 #include <shogun/base/Parameter.h> 00013 00014 using namespace shogun; 00015 00016 CSubsetStack::CSubsetStack() 00017 { 00018 init(); 00019 } 00020 00021 CSubsetStack::CSubsetStack(const CSubsetStack& other) 00022 { 00023 init(); 00024 00025 for (int32_t i=0; i < other.m_active_subsets_stack->get_num_elements(); ++i) 00026 { 00027 m_active_subset=(CSubset*)other.m_active_subsets_stack->get_element(i); 00028 m_active_subsets_stack->append_element(m_active_subset); 00029 } 00030 } 00031 00032 CSubsetStack::~CSubsetStack() 00033 { 00034 SG_UNREF(m_active_subsets_stack); 00035 SG_UNREF(m_active_subset); 00036 } 00037 00038 void CSubsetStack::remove_all_subsets() 00039 { 00040 /* delete all active subsets, backwards due to DynArray implementation */ 00041 for (index_t i=m_active_subsets_stack->get_num_elements()-1; i>=0; --i) 00042 m_active_subsets_stack->delete_element(i); 00043 00044 SG_UNREF(m_active_subset); 00045 } 00046 00047 void CSubsetStack::init() 00048 { 00049 SG_ADD((CSGObject**)&m_active_subset, "active_subset", 00050 "Currently active subset", MS_NOT_AVAILABLE); 00051 SG_ADD((CSGObject**)&m_active_subsets_stack, "active_subsets_stack", 00052 "Stack of active subsets", MS_NOT_AVAILABLE); 00053 00054 m_active_subset=NULL; 00055 m_active_subsets_stack=new CDynamicObjectArray(); 00056 SG_REF(m_active_subsets_stack); 00057 } 00058 00059 void CSubsetStack::add_subset(SGVector<index_t> subset) 00060 { 00061 /* if there are already subsets on stack, do some legality checks */ 00062 if (m_active_subsets_stack->get_num_elements()) 00063 { 00064 /* check that subsets may only be smaller or equal than existing */ 00065 CSubset* latest=(CSubset*)m_active_subsets_stack->get_last_element(); 00066 if (subset.vlen>latest->m_subset_idx.vlen) 00067 { 00068 subset.display_vector("subset"); 00069 latest->m_subset_idx.display_vector("last on stack"); 00070 SG_ERROR("%s::add_subset(): Provided index vector is " 00071 "larger than the subsets on the stubset stack!\n", get_name()); 00072 } 00073 00074 /* check for range of indices */ 00075 index_t max_index=SGVector<index_t>::max(subset.vector, subset.vlen); 00076 if (max_index>=latest->m_subset_idx.vlen) 00077 { 00078 subset.display_vector("subset"); 00079 latest->m_subset_idx.display_vector("last on stack"); 00080 SG_ERROR("%s::add_subset(): Provided index vector contains" 00081 " indices larger than possible range!\n", get_name()); 00082 } 00083 00084 /* clean up */ 00085 SG_UNREF(latest); 00086 } 00087 00088 /* active subset will be changed anyway, no setting to NULL */ 00089 SG_UNREF(m_active_subset); 00090 00091 /* two cases: stack is empty/stack is not empty */ 00092 if (m_active_subsets_stack->get_num_elements()) 00093 { 00094 /* if there are alreay subsets, we need to map given one through 00095 * existing ones */ 00096 00097 /* get latest current subset */ 00098 CSubset* latest=(CSubset*)m_active_subsets_stack->get_last_element(); 00099 00100 /* create new index vector */ 00101 SGVector<index_t> new_active_subset=SGVector<index_t>(subset.vlen); 00102 00103 /* using the latest current subset, transform all indices by the latest 00104 * added subset (dynamic programming greets you) */ 00105 for (index_t i=0; i<subset.vlen; ++i) 00106 { 00107 new_active_subset.vector[i]= 00108 latest->m_subset_idx.vector[subset.vector[i]]; 00109 } 00110 00111 /* replace active subset */ 00112 m_active_subset=new CSubset(new_active_subset); 00113 SG_REF(m_active_subset); 00114 SG_UNREF(latest); 00115 } 00116 else 00117 { 00118 /* just use plain given subset since there is nothing to map */ 00119 m_active_subset=new CSubset(subset); 00120 SG_REF(m_active_subset); 00121 } 00122 00123 /* add current active subset on stack of active subsets in any case */ 00124 m_active_subsets_stack->append_element(m_active_subset); 00125 } 00126 00127 void CSubsetStack::remove_subset() 00128 { 00129 index_t num_subsets=m_active_subsets_stack->get_num_elements(); 00130 if (num_subsets) 00131 { 00132 /* unref current subset */ 00133 SG_UNREF(m_active_subset); 00134 m_active_subset=NULL; 00135 00136 /* delete last element on stack */ 00137 if (num_subsets>=1) 00138 { 00139 index_t last_idx=m_active_subsets_stack->get_num_elements()-1; 00140 m_active_subsets_stack->delete_element(last_idx); 00141 } 00142 00143 /* if there are subsets left on stack, set the next one as active */ 00144 if (num_subsets>1) 00145 { 00146 /* use new last element on stack as active subset */ 00147 index_t last_idx=m_active_subsets_stack->get_num_elements()-1; 00148 m_active_subset=(CSubset*) 00149 m_active_subsets_stack->get_element(last_idx); 00150 } 00151 00152 /* otherwise, active subset is just empty */ 00153 } 00154 else 00155 { 00156 SG_WARNING("%s::remove_subset() was called but there is no subset set." 00157 "\n", get_name()); 00158 } 00159 }