1 /* 2 CheMPS2: a spin-adapted implementation of DMRG for ab initio quantum chemistry 3 Copyright (C) 2013-2018 Sebastian Wouters 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License along 16 with this program; if not, write to the Free Software Foundation, Inc., 17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef SPECIAL_CHEMPS2_H 21 #define SPECIAL_CHEMPS2_H 22 23 namespace CheMPS2{ 24 /** Special class. 25 \author Sebastian Wouters <sebastianwouters@gmail.com> 26 \date April 7, 2016 27 28 The special class contains static special functions used at various places throughout the code. */ 29 class Special{ 30 31 public: 32 33 //! Phase function 34 /** \param power_times_two Two times the power of the phase (-1)^{ power } 35 \return The phase (-1)^{ power_times_two / 2 } */ phase(const int power_times_two)36 static int phase( const int power_times_two ){ return (((( power_times_two / 2 ) % 2 ) != 0 ) ? -1 : 1 ); } 37 38 //! Triangle function for two variables 39 /** \param global The triangle counter global = i + ( j * ( j + 1 ) ) / 2 with i <= j 40 \param result Integer array of size 2 where to store i <= j */ invert_triangle_two(const int global,int * result)41 static void invert_triangle_two( const int global, int * result ){ 42 43 int j = 0; 44 while ((( j + 1 ) * ( j + 2 )) <= ( 2 * global )){ j++; } 45 result[ 1 ] = j; 46 result[ 0 ] = global - ( j * ( j + 1 ) ) / 2; 47 48 } 49 50 //! LOWER triangle function for two variables 51 /** \param global The lower triangle counter global = i + ( j * ( j - 1 ) ) / 2 with i < j 52 \param result Integer array of size 2 where to store i < j */ invert_lower_triangle_two(const int global,int * result)53 static void invert_lower_triangle_two( const int global, int * result ){ 54 55 int j = 1; 56 while (( j * ( j + 1 )) <= ( 2 * global )){ j++; } 57 result[ 1 ] = j; 58 result[ 0 ] = global - ( j * ( j - 1 ) ) / 2; 59 60 } 61 62 //! Triangle function for three variables 63 /** \param global The triangle counter global = i + ( j * ( j + 1 ) ) / 2 + ( k * ( k + 1 ) * ( k + 2 ) ) / 6 with i <= j <= k 64 \param result Integer array of size 3 where to store i <= j <= k */ invert_triangle_three(const int global,int * result)65 static void invert_triangle_three( const int global, int * result ){ 66 67 int k = 0; 68 while ((( k + 1 ) * ( k + 2 ) * ( k + 3 )) <= ( 6 * global )){ k++; } 69 const int remainder = global - ( k * ( k + 1 ) * ( k + 2 ) ) / 6; 70 int j = 0; 71 while ((( j + 1 ) * ( j + 2 )) <= ( 2 * remainder )){ j++; } 72 result[ 2 ] = k; 73 result[ 1 ] = j; 74 result[ 0 ] = remainder - ( j * ( j + 1 ) ) / 2; 75 76 } 77 78 }; 79 } 80 81 #endif 82