/* DFT++ is a density functional package developed by the research group of Professor Tomas Arias Copyright 1996-2003 Sohrab Ismail-Beigi This file is part of DFT++. DFT++ is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. DFT++ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DFT++; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Please see the file CREDITS for a list of authors. For academic users, we request that publications using results obtained with this software reference "New algebraic formulation of density functional calculation," by Sohrab Ismail-Beigi and T.A. Arias, Computer Physics Communications 128:1-2, 1-45 (June 2000). and, if using the wavelet basis, further reference "Multiresolution analysis of electronic structure: semicardinal and wavelet bases," T.A. Arias, Reviews of Modern Physics 71:1, 267-311 (January 1999). and "Robust ab initio calculation of condensed matter: transparent convergence through semicardinal multiresolution analysis,'' I.P. Daykov, T.A. Arias, and Torkel D. Engeness, Physical Review Letters, 90:21, 216402 (May 2003). For your convenience, preprints of the above articles may be obtained from http://arXiv.org/abs/cond-mat/9909130, 9805262, and 0204411, respectively. */ /* * Gabor Csanyi 8/1/2001 * * * the rArray class holds a simple array of real numbers * */ #include "header.h" RealArray::RealArray(int length): ndata(length) { } void RealArray::init(int length) { ndata = length; if(ndata > 0){ d = (real *)malloc(ndata*sizeof(real)); //dft_log("Allocated RealArray\n"); } else die("Can't initiliaze RealArray.init() with length < 0\n"); } ////////////////////////////////////// // // // Operator functions // // // ////////////////////////////////////// /* Assignment: nonstandard in that it returns void. To make it standard, * replace void -> RealArray and uncomment the return *this; */ void RealArray::operator=(const RealArray &rd) { dft_log("RealArray::operator=\n"); if (ndata != rd.ndata) die("Size mismatch in RealArray::operator=()\n"); for (int i=0; i < ndata; i++) d[i] = rd.d[i]; /* return *this; */ } // Assignment of scalar: all entries set to r inline void RealArray::operator=(real r) { dft_log("RealArray::operator=(real r)\n"); for (int i=0; i < ndata; i++) d[i] = r; } /* Add two RealArray */ RealArray RealArray::operator+(const RealArray &rd) { dft_log("RealArray::operator+\n"); if (ndata != rd.ndata) die("Size mismatch in RealArray::operator+()\n"); RealArray rd2(*this); for(int i = 0; i < ndata; i++) rd2.d[i] += rd.d[i]; return rd2; } /* Accumulate sum of RealArray */ void RealArray::operator+=(const RealArray &rd) { dft_log("RealArray::operator+=\n"); if (ndata != rd.ndata) die("Size mismatch in RealArray::operator+=()\n"); for (int i=0; i < ndata; i++) d[i] += rd.d[i]; } /* Subtract two RealArray */ RealArray RealArray::operator-(const RealArray &rd) { dft_log("RealArray::operator-\n"); if (ndata != rd.ndata) die("Size mismatch in RealArray::operator-()\n"); RealArray rd2(*this); for(int i = 0; i < ndata; i++) rd2.d[i] -= rd.d[i]; return rd2; } /* Accumulate difference of column_bundles */ void RealArray::operator-=(const RealArray &rd) { dft_log("RealArray::operator-=\n"); if (ndata != rd.ndata) die("Size mismatch in RealArray::operator-=()\n"); for (int i=0; i < ndata; i++) d[i] -= rd.d[i]; } /* Scale a RealArray rd by real r */ RealArray operator*(real r,const RealArray &rd) { dft_log("RealArray::operator*\n"); RealArray rd2(rd); for(int i = 0; i < rd.ndata; i++) rd2.d[i] *= r; return rd2; } /* Scale a RealArray by real r */ RealArray RealArray::operator*(real r) { dft_log("RealArray::operator*\n"); RealArray rd2(*this); for(int i = 0; i < ndata; i++) rd2.d[i] *= r; return rd2; } /* Scale a RealArray rd by complex number c */ ComplexArray operator*(complex c,const RealArray &rd) { dft_log("RealArray::operator*\n"); ComplexArray cd(rd.ndata); for(int i =0; i < rd.ndata; i++){ cd.d[i].x = c.x*rd.d[i]; cd.d[i].y = c.y*rd.d[i]; } return cd; } /* Scale a RealArray by a complex number c */ ComplexArray RealArray::operator*(complex c) { ComplexArray cd(ndata); for(int i = 0; i < ndata; i++){ cd.d[i].x = d[i]*c.x; cd.d[i].y = d[i]*c.y; } return cd; } /* Scale a RealArray real r in place */ void RealArray::operator*=(real r) { dft_log("RealArray::operator*=\n"); for (int i=0; i < ndata; i++) d[i] *= r; } ///////////////////////////////////////////// // // // MEMBER FUNCTIONS: // // // ///////////////////////////////////////////// // zeroes out the whole array void RealArray::zero_out(void) { for(int i=0;i < ndata; i++) d[i] = (real)0.0; } /* Negates all the entries in the array */ void RealArray::negate(void) { dft_log("RealArray::negate()\n"); for(int i=0;i < ndata; i++) d[i] = -d[i]; } /* Randomizes w/ uniform distribution in [-.5, .5]*/ void RealArray::randomize(void) { //dft_log("ComplexArray::negate()\n"); for(int i=0;i < ndata; i++) d[i] = rand()/(RAND_MAX+1.) -.5; } // Sum of absolute squares of all elements in rd real abs2(const RealArray &rd) { real rdrd(0); real r; for(int i = 0; i < rd.ndata; i++){ r = rd.d[i]; rdrd += r*r; } return rdrd; } /* Take "dot-product" of two RealArray: sum the diagonals of rd1^rd2 */ real dot(const RealArray &rd1,const RealArray &rd2) { dft_log("RealArray::dot()\n"); int i; real dot12; if (rd1.ndata != rd2.ndata) die("rd1.ndata != rd2.ndata in dot_RealArray()\n"); dot12 = 0.0; for (i=0; i < rd1.ndata; i++) dot12 += rd1.d[i]*rd2.d[i]; return dot12; } /* Does rd2 += r * rd1 */ void scale_accumulate(real r,const RealArray &rd1, RealArray &rd2) { dft_log("RealArray::scale_accumulate()\n"); for (int i=0; i < rd1.ndata; i++) rd2.d[i] += r * rd1.d[i]; } /* Does rd3 = r1*rd1 + r2*rd2 */ void scaled_sum(real r1,RealArray &rd1, real r2,RealArray &rd2, RealArray &rd3) { dft_log("RealArray::scaled_sum()\n"); if (rd1.ndata != rd2.ndata || rd1.ndata != rd3.ndata) die("Incomaptible sizes in scaled_sum(r1,rd1,r2,rd2,rd3)"); for (int i=0; i < rd1.ndata; i++) rd3.d[i] = r1*rd1.d[i] + r2*rd2.d[i]; }