/*
    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.
*/

#ifndef DFT_PW_COLUMN_H
#define DFT_PW_COLUMN_H

#define IDENTITY 0
#define SPHERE 1
#define BOX 2

class PW_ComplexColumn
{
 public:
  int fat;

  int length;
  ComplexArray data;
  
  PW_BasisSpec *basis_spec;
  PW_Basis *basis;

  int representation;
  int embedding; // either SPHERE or BOX

  //constructors
  PW_ComplexColumn();
  PW_ComplexColumn(PW_Basis *, char s[10]="fat");
  PW_ComplexColumn(PW_Basis *, int space, char s[10]="fat");
  PW_ComplexColumn(const PW_ComplexColumn &col, char s[10]="fat");
//  PW_ComplexColumn(const PW_ComplexColumn &col);
  
  ~PW_ComplexColumn();
  
  // expansion maps to help perform I, J, L, O  on a column
  // map() is not a real function, but pointer to one of the others
  // see if possible to have map public and the other protected/private

  void map(PW_ComplexColumn &) const;

  char *getrepresentation();
  char *getembedding();
  
  void init_wavefunction(PW_Basis &);
  void init_scalarfield(PW_Basis &, int space);
  
  // a smart randomization should depend on the basis, so it's here
  void randomize();
  void zero_out(){data.zero_out();};
  // Sets the column to e(i*theta) on every point.
  void setmodones();

  void print();

  // Reads and writes files in DFT++ format.
  void read(char *filename);
  void write(char *filename);
  
  //PW specific
  void IdentityMap(PW_ComplexColumn &) const; 
  void SphereToBoxMap(PW_ComplexColumn &) const;
  void BoxToSphereMap(PW_ComplexColumn &) const;

  void operator=(const PW_ComplexColumn &col);
  void operator+=(const PW_ComplexColumn &col);
  void operator-=(const PW_ComplexColumn &col);
  void operator*=(const real);
  void operator*=(const complex c);
  void operator*=(const PW_ComplexColumn &col);
  complex operator^(const PW_ComplexColumn &);

  friend PW_ComplexColumn operator*(const real &r,
                                    const PW_ComplexColumn &in){
    PW_ComplexColumn out(in);
    out*=r;
    return out;
  }

  friend PW_ComplexColumn operator*(const complex &c,
                                    const PW_ComplexColumn &in){
    PW_ComplexColumn out(in);
    out*=c;
    return out;
  }


};

void add_scale_abs2(const complex &, const  PW_ComplexColumn &,
                    PW_ComplexColumn &);

PW_ComplexColumn abs2(PW_ComplexColumn &);
PW_ComplexColumn pointwise_mult(const PW_ComplexColumn &a,
                                const PW_ComplexColumn &b);

#endif // DFT_PW_COLUMN_H
