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-2013 Sergey Lisitsyn 00008 * Copyright (C) 2011-2013 Berlin Institute of Technology and Max-Planck-Society 00009 */ 00010 00011 #include <shogun/converter/MultidimensionalScaling.h> 00012 #ifdef HAVE_EIGEN3 00013 #include <shogun/converter/EmbeddingConverter.h> 00014 #include <shogun/mathematics/lapack.h> 00015 #include <shogun/distance/CustomDistance.h> 00016 #include <shogun/lib/common.h> 00017 #include <shogun/mathematics/Math.h> 00018 #include <shogun/mathematics/Statistics.h> 00019 #include <shogun/io/SGIO.h> 00020 #include <shogun/distance/EuclideanDistance.h> 00021 #include <shogun/lib/tapkee/tapkee_shogun.hpp> 00022 00023 using namespace shogun; 00024 00025 CMultidimensionalScaling::CMultidimensionalScaling() : CEmbeddingConverter() 00026 { 00027 m_eigenvalues = SGVector<float64_t>(); 00028 m_landmark_number = 3; 00029 m_landmark = false; 00030 00031 init(); 00032 } 00033 00034 void CMultidimensionalScaling::init() 00035 { 00036 SG_ADD(&m_eigenvalues, "eigenvalues", "eigenvalues of last embedding", 00037 MS_NOT_AVAILABLE); 00038 SG_ADD(&m_landmark, "landmark", 00039 "indicates if landmark approximation should be used", MS_NOT_AVAILABLE); 00040 SG_ADD(&m_landmark_number, "landmark_number", 00041 "the number of landmarks for approximation", MS_AVAILABLE); 00042 } 00043 00044 CMultidimensionalScaling::~CMultidimensionalScaling() 00045 { 00046 } 00047 00048 SGVector<float64_t> CMultidimensionalScaling::get_eigenvalues() const 00049 { 00050 return m_eigenvalues; 00051 } 00052 00053 void CMultidimensionalScaling::set_landmark_number(int32_t num) 00054 { 00055 if (num<3) 00056 SG_ERROR("Number of landmarks should be greater than 3 to make triangulation possible while %d given.", 00057 num); 00058 m_landmark_number = num; 00059 } 00060 00061 int32_t CMultidimensionalScaling::get_landmark_number() const 00062 { 00063 return m_landmark_number; 00064 } 00065 00066 void CMultidimensionalScaling::set_landmark(bool landmark) 00067 { 00068 m_landmark = landmark; 00069 } 00070 00071 bool CMultidimensionalScaling::get_landmark() const 00072 { 00073 return m_landmark; 00074 } 00075 00076 const char* CMultidimensionalScaling::get_name() const 00077 { 00078 return "MultidimensionalScaling"; 00079 }; 00080 00081 CDenseFeatures<float64_t>* CMultidimensionalScaling::embed_distance(CDistance* distance) 00082 { 00083 TAPKEE_PARAMETERS_FOR_SHOGUN parameters; 00084 if (m_landmark) 00085 { 00086 parameters.method = SHOGUN_LANDMARK_MULTIDIMENSIONAL_SCALING; 00087 parameters.landmark_ratio = float64_t(m_landmark_number)/distance->get_num_vec_lhs(); 00088 if (parameters.landmark_ratio > 1.0) { 00089 SG_WARNING("Number of landmarks (%d) exceeds number of feature vectors (%d)",m_landmark_number,distance->get_num_vec_lhs()); 00090 parameters.landmark_ratio = 1.0; 00091 } 00092 } 00093 else 00094 { 00095 parameters.method = SHOGUN_MULTIDIMENSIONAL_SCALING; 00096 } 00097 parameters.target_dimension = m_target_dim; 00098 parameters.distance = distance; 00099 CDenseFeatures<float64_t>* embedding = tapkee_embed(parameters); 00100 return embedding; 00101 } 00102 00103 CFeatures* CMultidimensionalScaling::apply(CFeatures* features) 00104 { 00105 SG_REF(features); 00106 ASSERT(m_distance) 00107 00108 m_distance->init(features,features); 00109 CDenseFeatures<float64_t>* embedding = embed_distance(m_distance); 00110 m_distance->remove_lhs_and_rhs(); 00111 00112 SG_UNREF(features); 00113 return (CFeatures*)embedding; 00114 } 00115 00116 #endif /* HAVE_EIGEN3 */