Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-2023 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : plumed is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "DimensionalityReductionBase.h" 23 : #include "core/ActionRegister.h" 24 : #include "SMACOF.h" 25 : 26 : //+PLUMEDOC DIMRED SMACOF_MDS 27 : /* 28 : Optimize the multidimensional scaling stress function using the SMACOF algorithm. 29 : 30 : \par Examples 31 : 32 : */ 33 : //+ENDPLUMEDOC 34 : 35 : namespace PLMD { 36 : namespace dimred { 37 : 38 : class SmacofMDS : public DimensionalityReductionBase { 39 : private: 40 : unsigned maxloops; 41 : double tol; 42 : public: 43 : static void registerKeywords( Keywords& keys ); 44 : explicit SmacofMDS( const ActionOptions& ); 45 : void calculateProjections( const Matrix<double>&, Matrix<double>& ) override; 46 : }; 47 : 48 10419 : PLUMED_REGISTER_ACTION(SmacofMDS,"SMACOF_MDS") 49 : 50 1 : void SmacofMDS::registerKeywords( Keywords& keys ) { 51 1 : DimensionalityReductionBase::registerKeywords( keys ); 52 1 : keys.remove("NLOW_DIM"); 53 2 : keys.add("compulsory","SMACOF_TOL","1E-4","tolerance for the SMACOF optimization algorithm"); 54 2 : keys.add("compulsory","SMACOF_MAXCYC","1000","maximum number of optimization cycles for SMACOF algorithm"); 55 1 : } 56 : 57 0 : SmacofMDS::SmacofMDS( const ActionOptions& ao): 58 : Action(ao), 59 0 : DimensionalityReductionBase(ao) 60 : { 61 0 : if( !dimredbase ) error("SMACOF must be initialized using output from dimensionality reduction object"); 62 : 63 0 : parse("SMACOF_TOL",tol); parse("SMACOF_MAXCYC",maxloops); 64 0 : log.printf(" running smacof to convergence at %f or for a maximum of %u steps \n",tol,maxloops); 65 0 : } 66 : 67 0 : void SmacofMDS::calculateProjections( const Matrix<double>& targets, Matrix<double>& projections ) { 68 : // Take the square root of all the distances and the weights 69 : Matrix<double> weights( targets.nrows(), targets.ncols() ); 70 : Matrix<double> distances( targets.nrows(), targets.ncols() ); 71 0 : for(unsigned i=1; i<distances.ncols(); ++i) { 72 0 : for(unsigned j=0; j<i; ++j) { 73 0 : distances(i,j)=distances(j,i)=std::sqrt( targets(i,j) ); 74 0 : weights(i,j)=weights(j,i)=getWeight(i)*getWeight(j); 75 : } 76 : } 77 : // And run SMACOF 78 0 : SMACOF::run( weights, targets, tol, maxloops, projections ); 79 0 : } 80 : 81 : } 82 : }