00001 /* Ergo, version 3.2, a program for linear scaling electronic structure 00002 * calculations. 00003 * Copyright (C) 2012 Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek. 00004 * 00005 * This program is free software: you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation, either version 3 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * Primary academic reference: 00019 * KohnâSham Density Functional Theory Electronic Structure Calculations 00020 * with Linearly Scaling Computational Time and Memory Usage, 00021 * Elias Rudberg, Emanuel H. Rubensson, and Pawel Salek, 00022 * J. Chem. Theory Comput. 7, 340 (2011), 00023 * <http://dx.doi.org/10.1021/ct100611z> 00024 * 00025 * For further information about Ergo, see <http://www.ergoscf.org>. 00026 */ 00027 00028 /* This file belongs to the template_lapack part of the Ergo source 00029 * code. The source files in the template_lapack directory are modified 00030 * versions of files originally distributed as CLAPACK, see the 00031 * Copyright/license notice in the file template_lapack/COPYING. 00032 */ 00033 00034 00035 #ifndef TEMPLATE_LAPACK_LARNV_HEADER 00036 #define TEMPLATE_LAPACK_LARNV_HEADER 00037 00038 00039 template<class Treal> 00040 int template_lapack_larnv(const integer *idist, integer *iseed, const integer *n, 00041 Treal *x) 00042 { 00043 /* -- LAPACK auxiliary routine (version 3.0) -- 00044 Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., 00045 Courant Institute, Argonne National Lab, and Rice University 00046 September 30, 1994 00047 00048 00049 Purpose 00050 ======= 00051 00052 DLARNV returns a vector of n random real numbers from a uniform or 00053 normal distribution. 00054 00055 Arguments 00056 ========= 00057 00058 IDIST (input) INTEGER 00059 Specifies the distribution of the random numbers: 00060 = 1: uniform (0,1) 00061 = 2: uniform (-1,1) 00062 = 3: normal (0,1) 00063 00064 ISEED (input/output) INTEGER array, dimension (4) 00065 On entry, the seed of the random number generator; the array 00066 elements must be between 0 and 4095, and ISEED(4) must be 00067 odd. 00068 On exit, the seed is updated. 00069 00070 N (input) INTEGER 00071 The number of random numbers to be generated. 00072 00073 X (output) DOUBLE PRECISION array, dimension (N) 00074 The generated random numbers. 00075 00076 Further Details 00077 =============== 00078 00079 This routine calls the auxiliary routine DLARUV to generate random 00080 real numbers from a uniform (0,1) distribution, in batches of up to 00081 128 using vectorisable code. The Box-Muller method is used to 00082 transform numbers from a uniform to a normal distribution. 00083 00084 ===================================================================== 00085 00086 00087 Parameter adjustments */ 00088 /* System generated locals */ 00089 integer i__1, i__2, i__3; 00090 /* Local variables */ 00091 integer i__; 00092 Treal u[128]; 00093 integer il, iv; 00094 integer il2; 00095 00096 --x; 00097 --iseed; 00098 00099 /* Function Body */ 00100 i__1 = *n; 00101 for (iv = 1; iv <= i__1; iv += 64) { 00102 /* Computing MIN */ 00103 i__2 = 64, i__3 = *n - iv + 1; 00104 il = minMACRO(i__2,i__3); 00105 if (*idist == 3) { 00106 il2 = il << 1; 00107 } else { 00108 il2 = il; 00109 } 00110 00111 /* Call DLARUV to generate IL2 numbers from a uniform (0,1) 00112 distribution (IL2 <= LV) */ 00113 00114 dlaruv_(&iseed[1], &il2, u); 00115 00116 if (*idist == 1) { 00117 00118 /* Copy generated numbers */ 00119 00120 i__2 = il; 00121 for (i__ = 1; i__ <= i__2; ++i__) { 00122 x[iv + i__ - 1] = u[i__ - 1]; 00123 /* L10: */ 00124 } 00125 } else if (*idist == 2) { 00126 00127 /* Convert generated numbers to uniform (-1,1) distribution */ 00128 00129 i__2 = il; 00130 for (i__ = 1; i__ <= i__2; ++i__) { 00131 x[iv + i__ - 1] = u[i__ - 1] * 2. - 1.; 00132 /* L20: */ 00133 } 00134 } else if (*idist == 3) { 00135 00136 /* Convert generated numbers to normal (0,1) distribution */ 00137 00138 i__2 = il; 00139 for (i__ = 1; i__ <= i__2; ++i__) { 00140 x[iv + i__ - 1] = template_blas_sqrt(template_blas_log(u[(i__ << 1) - 2]) * -2.) * cos(u[( 00141 i__ << 1) - 1] * 6.2831853071795864769252867663); 00142 /* L30: */ 00143 } 00144 } 00145 /* L40: */ 00146 } 00147 return 0; 00148 00149 /* End of DLARNV */ 00150 00151 } /* dlarnv_ */ 00152 00153 #endif