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 Chiyuan Zhang 00008 * Written (W) 2012 Heiko Strathmann 00009 * Copyright (C) 2012 Chiyuan Zhang 00010 */ 00011 00012 #include <shogun/lib/Set.h> 00013 #include <shogun/machine/KernelMulticlassMachine.h> 00014 00015 using namespace shogun; 00016 00017 void CKernelMulticlassMachine::store_model_features() 00018 { 00019 CKernel *kernel= m_kernel; 00020 if (!kernel) 00021 SG_ERROR("%s::store_model_features(): kernel is needed to store SV " 00022 "features.\n", get_name()); 00023 00024 CFeatures* lhs=kernel->get_lhs(); 00025 CFeatures* rhs=kernel->get_rhs(); 00026 if (!lhs) 00027 { 00028 SG_ERROR("%s::store_model_features(): kernel lhs is needed to store " 00029 "SV features.\n", get_name()); 00030 } 00031 00032 /* this map will be abused as a map */ 00033 CSet<index_t> all_sv; 00034 for (index_t i=0; i<m_machines->get_num_elements(); ++i) 00035 { 00036 CKernelMachine *machine=(CKernelMachine *)get_machine(i); 00037 for (index_t j=0; j<machine->get_num_support_vectors(); ++j) 00038 all_sv.add(machine->get_support_vector(j)); 00039 00040 SG_UNREF(machine); 00041 } 00042 00043 /* convert map to vector of SV */ 00044 SGVector<index_t> sv_idx(all_sv.get_num_elements()); 00045 for (index_t i=0; i<sv_idx.vlen; ++i) 00046 sv_idx[i]=*all_sv.get_element_ptr(i); 00047 00048 CFeatures* sv_features=lhs->copy_subset(sv_idx); 00049 00050 /* now, features are replaced by concatenated SV features */ 00051 kernel->init(sv_features, rhs); 00052 00053 /* was SG_REF'ed by copy_subset */ 00054 SG_UNREF(sv_features); 00055 00056 /* now the old SV indices have to be mapped to the new features */ 00057 00058 /* update SV of all machines */ 00059 for (int32_t i=0; i<m_machines->get_num_elements(); ++i) 00060 { 00061 CKernelMachine *machine=(CKernelMachine *)get_machine(i); 00062 00063 /* for each machine, replace SV by index in sv_idx array */ 00064 for (int32_t j=0; j<machine->get_num_support_vectors(); ++j) 00065 { 00066 /* get index of SV in old features */ 00067 index_t current_sv_idx=machine->get_support_vector(j); 00068 00069 /* the position of this old index in the map is the position of 00070 * the SV in the new features */ 00071 index_t new_sv_idx=all_sv.index_of(current_sv_idx); 00072 00073 machine->set_support_vector(j, new_sv_idx); 00074 } 00075 00076 SG_UNREF(machine); 00077 } 00078 00079 SG_UNREF(lhs); 00080 SG_UNREF(rhs); 00081 }