LCOV - code coverage report
Current view: top level - function - Highest.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 24 28 85.7 %
Date: 2025-04-08 21:11:17 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-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 "core/ActionRegister.h"
      23             : #include "FunctionShortcut.h"
      24             : #include "FunctionOfScalar.h"
      25             : #include "FunctionOfVector.h"
      26             : #include "FunctionTemplateBase.h"
      27             : 
      28             : namespace PLMD {
      29             : namespace function {
      30             : 
      31             : //+PLUMEDOC FUNCTION HIGHEST
      32             : /*
      33             : This function can be used to find the highest colvar by magnitude in a set.
      34             : 
      35             : This action allows you to find the highest of the input arguments.  As a first example of how it might be used consider the following input:
      36             : 
      37             : ```plumed
      38             : d1: DISTANCE ATOMS=1,2
      39             : d2: DISTANCE ATOMS=3,4
      40             : h1: HIGHEST ARG=d1,d2
      41             : PRINT ARG=h1 FILE=colvar
      42             : ```
      43             : 
      44             : The value, `h1`, that is output to the file `colvar` here will be equal to `d1` if `d1>d2` and will be equal to `d2` if `d2>d1`.  In other words, if
      45             : all the arguments input to a HIGHEST action are scalars then the output value will be a scalar that is equal to the largest of the input arguments.
      46             : Notice that you can also use this command with more than two arguments as illustrated below:
      47             : 
      48             : ```plumed
      49             : d1: DISTANCE ATOMS=1,2
      50             : d2: DISTANCE ATOMS=3,4
      51             : d3: DISTANCE ATOMS=5,6
      52             : d4: DISTANCE ATOMS=7,8
      53             : h1: HIGHEST ARG=d1,d2,d3,d4
      54             : PRINT ARG=h1 FILE=colvar
      55             : ```
      56             : 
      57             : ## Using a single vector as input
      58             : 
      59             : Instead of inputting multiple scalars you can input a single vector to this action instead as is illustrated below:
      60             : 
      61             : ```plumed
      62             : d: DISTANCE ATOMS1=1,2 ATOMS2=3,4
      63             : h1: HIGHEST ARG=d
      64             : PRINT ARG=h1 FILE=colvar
      65             : ```
      66             : 
      67             : The output from this action is a single scalar once again.  This single scalar is equal to the largest element of the input vector.
      68             : 
      69             : ## Using multiple vectors in input
      70             : 
      71             : If you input multiple vectors with the same numbers of elements to this action, as shown below, the output will be a vector.
      72             : 
      73             : 
      74             : ```plumed
      75             : d1: DISTANCE ATOMS1=1,2 ATOMS2=3,4
      76             : d2: DISTANCE ATOMS1=5,6 ATOMS2=7,8
      77             : d3: DISTANCE ATOMS1=9,10 ATOMS2=11,12
      78             : h2: HIGHEST ARG=d1,d2,d3
      79             : PRINT ARG=h2 FILE=colvar
      80             : ```
      81             : 
      82             : The elements of the output vector here are determined by doing an elementwise comparison of the elements in the input vectors.  In the above
      83             : input the first element of `h2` is equal to the distance between atoms 1 and 2 if this distance is larger than the distances between atoms 5 and 6 and the distance between atoms 9 and 10.
      84             : By the same token the second element of `h2` is equal to the distance between atoms 3 and 4 if this is larger than the distance between atoms 7 and 8 and the distance between atoms 11 and 12.
      85             : In other words, if the elements of the $j$th input vector are given by $v_i^{(j)}$ then the elements of the output vector, $h_i$ are given by:
      86             : 
      87             : $$
      88             : h_i = \max_j v_i^{(j)}
      89             : $$
      90             : 
      91             : Notice that you can also use a combination of scalars and vectors in the input to this action as shown below:
      92             : 
      93             : ```plumed
      94             : c: CONSTANT VALUE=0.05
      95             : d: DISTANCE ATOMS1=1,2 ATOMS2=3,4
      96             : h: HIGHEST ARG=d,c
      97             : PRINT ARG=h FILE=colvar
      98             : ```
      99             : 
     100             : For the input above the HIGHEST action outputs a vector with two elements.  The elements of this vector are equal to the distances between the pairs
     101             : of atoms that are specified in the DISTANCE command as long as those distances are greater than 0.05 nm.  If either of the two input distances is less
     102             : than 0.05 nm then the corresponding value in the vector `h` is set equal to 0.05 nm.
     103             : 
     104             : */
     105             : //+ENDPLUMEDOC
     106             : 
     107             : //+PLUMEDOC COLVAR HIGHEST_SCALAR
     108             : /*
     109             : Calculate the highest of a set of sclalar arguments
     110             : 
     111             : \par Examples
     112             : 
     113             : */
     114             : //+ENDPLUMEDOC
     115             : 
     116             : //+PLUMEDOC COLVAR HIGHEST_VECTOR
     117             : /*
     118             : Calculate the largest element in a vector of inputs
     119             : 
     120             : \par Examples
     121             : 
     122             : */
     123             : //+ENDPLUMEDOC
     124             : 
     125             : //+PLUMEDOC FUNCTION LOWEST
     126             : /*
     127             : This function can be used to find the lowest colvar by magnitude in a set.
     128             : 
     129             : This action allows you to find the lowest of the input arguments.  As a first example of how it might be used consider the following input:
     130             : 
     131             : ```plumed
     132             : d1: DISTANCE ATOMS=1,2
     133             : d2: DISTANCE ATOMS=3,4
     134             : l1: LOWEST ARG=d1,d2
     135             : PRINT ARG=l1 FILE=colvar
     136             : ```
     137             : 
     138             : The value, `l1`, that is output to the file `colvar` here will be equal to `d1` if `d1<d2` and will be equal to `d2` if `d2<d1`.  In other words, if
     139             : all the arguments input to a LOWEST action are scalars then the output value will be a scalar that is equal to the smallest of the input arguments.
     140             : Notice that you can also use this command with more than two arguments as illustrated below:
     141             : 
     142             : ```plumed
     143             : d1: DISTANCE ATOMS=1,2
     144             : d2: DISTANCE ATOMS=3,4
     145             : d3: DISTANCE ATOMS=5,6
     146             : d4: DISTANCE ATOMS=7,8
     147             : l1: LOWEST ARG=d1,d2,d3,d4
     148             : PRINT ARG=l1 FILE=colvar
     149             : ```
     150             : 
     151             : ## Using a single vector as input
     152             : 
     153             : Instead of inputting multiple scalars you can input a single vector to this action instead as is illustrated below:
     154             : 
     155             : ```plumed
     156             : d: DISTANCE ATOMS1=1,2 ATOMS2=3,4
     157             : l1: LOWEST ARG=d
     158             : PRINT ARG=l1 FILE=colvar
     159             : ```
     160             : 
     161             : The output from this action is a single scalar once again.  This single scalar is equal to the smallest element of the input vector.
     162             : 
     163             : ## Using multiple vectors in input
     164             : 
     165             : If you input multiple vectors with the same numbers of elements to this action, as shown below, the output will be a vector.
     166             : 
     167             : 
     168             : ```plumed
     169             : d1: DISTANCE ATOMS1=1,2 ATOMS2=3,4
     170             : d2: DISTANCE ATOMS1=5,6 ATOMS2=7,8
     171             : d3: DISTANCE ATOMS1=9,10 ATOMS2=11,12
     172             : l2: LOWEST ARG=d1,d2,d3
     173             : PRINT ARG=l2 FILE=colvar
     174             : ```
     175             : 
     176             : The elements of the output vector here are determined by doing an elementwise comparison of the elements in the input vectors.  In the above
     177             : input the first element of `h2` is equal to the distance between atoms 1 and 2 if this distance is smaller than the distances between atoms 5 and 6 and the distance between atoms 9 and 10.
     178             : By the same token the second element of `h2` is equal to the distance between atoms 3 and 4 if this is smaller than the distance between atoms 7 and 8 and the distance between atoms 11 and 12.
     179             : In other words, if the elements of the $j$th input vector are given by $v_i^{(j)}$ then the elements of the output vector, $h_i$ are given by:
     180             : 
     181             : $$
     182             : h_i = \min_j v_i^{(j)}
     183             : $$
     184             : 
     185             : Notice that you can also use a combination of scalars and vectors in the input to this action as shown below:
     186             : 
     187             : ```plumed
     188             : c: CONSTANT VALUE=0.5
     189             : d: DISTANCE ATOMS1=1,2 ATOMS2=3,4
     190             : h: LOWEST ARG=d,c
     191             : PRINT ARG=h FILE=colvar
     192             : ```
     193             : 
     194             : For the input above the LOWEST action outputs a vector with two elements.  The elements of this vector are equal to the distances between the pairs
     195             : of atoms that are specified in the DISTANCE command as long as those distances are less than 0.5 nm.  If either of the two input distances is more
     196             : han 0.5 nm then the corresponding value in the vector `h` is set equal to 0.5 nm.
     197             : 
     198             : */
     199             : //+ENDPLUMEDOC
     200             : 
     201             : //+PLUMEDOC COLVAR LOWEST_SCALAR
     202             : /*
     203             : Calculate the lowest of a set of sclalar arguments
     204             : 
     205             : \par Examples
     206             : 
     207             : */
     208             : //+ENDPLUMEDOC
     209             : 
     210             : //+PLUMEDOC COLVAR LOWEST_VECTOR
     211             : /*
     212             : Calculate the lowest element in a vector of inputs
     213             : 
     214             : \par Examples
     215             : 
     216             : */
     217             : //+ENDPLUMEDOC
     218             : 
     219         334 : class Highest : public FunctionTemplateBase {
     220             : private:
     221             :   bool min, scalar_out;
     222             : public:
     223             :   void registerKeywords( Keywords& keys ) override ;
     224             :   void read( ActionWithArguments* action ) override;
     225           0 :   bool zeroRank() const override {
     226          51 :     return scalar_out;
     227             :   }
     228           0 :   bool doWithTasks() const override {
     229        5341 :     return !scalar_out;
     230             :   }
     231             :   void calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const override;
     232             : };
     233             : 
     234             : typedef FunctionShortcut<Highest> HighestShortcut;
     235             : PLUMED_REGISTER_ACTION(HighestShortcut,"HIGHEST")
     236             : PLUMED_REGISTER_ACTION(HighestShortcut,"LOWEST")
     237             : typedef FunctionOfScalar<Highest> ScalarHighest;
     238             : PLUMED_REGISTER_ACTION(ScalarHighest,"HIGHEST_SCALAR")
     239             : PLUMED_REGISTER_ACTION(ScalarHighest,"LOWEST_SCALAR")
     240             : typedef FunctionOfVector<Highest> VectorHighest;
     241             : PLUMED_REGISTER_ACTION(VectorHighest,"HIGHEST_VECTOR")
     242             : PLUMED_REGISTER_ACTION(VectorHighest,"LOWEST_VECTOR")
     243             : 
     244         228 : void Highest::registerKeywords( Keywords& keys ) {
     245         456 :   if( keys.getDisplayName().find("LOWEST") ) {
     246         176 :     keys.setValueDescription("scalar","the lowest of the input values");
     247             :   } else {
     248         280 :     keys.setValueDescription("scalar","the highest of the input values");
     249             :   }
     250         228 : }
     251             : 
     252          53 : void Highest::read( ActionWithArguments* action ) {
     253          53 :   min=action->getName().find("LOWEST")!=std::string::npos;
     254          53 :   if( !min ) {
     255          21 :     plumed_assert( action->getName().find("HIGHEST")!=std::string::npos );
     256             :   }
     257         130 :   for(unsigned i=0; i<action->getNumberOfArguments(); ++i) {
     258          77 :     if( action->getPntrToArgument(i)->isPeriodic() ) {
     259           0 :       action->error("Cannot sort periodic values (check argument "+ action->getPntrToArgument(i)->getName() +")");
     260             :     }
     261             :   }
     262          53 :   scalar_out = action->getNumberOfArguments()==1;
     263          53 :   if( scalar_out && action->getPntrToArgument(0)->getRank()==0 ) {
     264           0 :     action->error("sorting a single scalar is trivial");
     265             :   }
     266          53 : }
     267             : 
     268       41979 : void Highest::calc( const ActionWithArguments* action, const std::vector<double>& args, std::vector<double>& vals, Matrix<double>& derivatives ) const {
     269       41979 :   if( min ) {
     270       41845 :     vals[0] = *std::min_element(args.begin(), args.end());
     271       41845 :     derivatives(0,std::min_element(args.begin(), args.end()) - args.begin()) = 1;
     272             :   } else {
     273         134 :     vals[0] = *std::max_element(args.begin(), args.end());
     274         134 :     derivatives(0,std::max_element(args.begin(), args.end()) - args.begin()) = 1;
     275             :   }
     276       41979 : }
     277             : 
     278             : }
     279             : }
     280             : 
     281             : 

Generated by: LCOV version 1.16