dcomplex  dot(const Array1 <dcomplex> & a,  const Array1 <dcomplex> & b){
  int dim=a.GetSize();
  assert(a.GetSize()==b.GetSize());
  dcomplex sum(0.0,0.0);
  for(int i=0;i<dim;i++)
    sum+=a(i)*b(i);
  return sum;
}
//----------------------------------------------------------------------
doublevar dot(const Array1 <doublevar> & a,  const Array1 <doublevar> & b){
  int dim=a.GetSize();
  assert(a.GetSize()==b.GetSize());
  doublevar sum=0;
  for(int i=0;i<dim;i++)
    sum+=a(i)*b(i);
  return sum;
}
void normalize(Array1 <doublevar> & a)
{
  int m=a.GetSize();
  double norm;
  norm=norm_i(a);
  for (int k=0;k<m;k++)
    a(k)=a(k)/sqrt(norm);
}
doublevar norm_i(Array1 <doublevar> & a)
{
  int m=a.GetSize();
  double norm=0.0;
  for (int k=0;k<m;k++)
    norm+=a(k)*a(k);
  return norm;
}
doublevar Minimization_function::func(Array1 <doublevar>  &a){
  // \begin{equation}
  //   {\cal F}=1-\frac{\sum_{i,j}^{N}a_i a_j S_{ij}}{\sum_{i}^{N}a_{i}^2}
  //  \end{equation}
  int m=a.GetSize();
  double tmp=0.0;
  double norm=norm_i(a);
  for (int k=0;k<m;k++)
    for (int l=0;l<m;l++){
      tmp+=a(k)*a(l)*_overlap_ma_R(k,l);
    }
  //   cout << 1.0 -tmp/norm<<endl;
  return 1.0 -tmp/norm;
}
void Minimization_function::dfunc(Array1 <doublevar> &a, Array1 <doublevar> &xi){
  // \begin{equation}
  //    \frac{\partial {\cal F}}{\partial a_k}=
  //         -2\frac{\sum_{i}^{N}a_iS_{ik}+2a_k({\cal F}-1)}{\sum_{i}^{N}a_{i}^2}
  //  \end{equation} 
  int m=a.GetSize();
  double fa_i=func(a);
  double norm=norm_i(a);
  double temp=0.0;
  for (int j=0;j<m;j++){
    temp=0.0;
    for (int k=0;k<m;k++)
      temp+=a(k)*_overlap_ma_R(j,k);
    xi(j)=-2.0*(temp+a(j)*(fa_i-1.0))/norm;
    //    cout <<xi(j)<<"  ";
  }
  //  cout <<endl;
} 
void sort_abs_values_descending(const Array1 <doublevar> & vals, Array1 <doublevar> & newvals, Array1 <int> & list){
  int n=vals.GetSize();
  list.Resize(n); 
  for (int i=0; i < n; i++) {
    list(i) = i;
    newvals(i)=vals(i);
  }
  
  for (int i=1; i < n; i++) {
    const double temp = newvals[i];
    const double abstemp =  fabs(newvals[i]);
    int j;
    for (j=i-1; j>=0 && fabs(newvals[j])<abstemp; j--) {
      newvals[j+1] = newvals[j];
      list[j+1] = list[j];
    }
    newvals[j+1] = temp;
    list[j+1] = i;
  }
  //for (int i=0; i < n; i++) 
  //cout << list[i]<<endl;
}
void sort_according_list(const Array1 <doublevar> & vals, Array1 <doublevar> & newvals, const Array1 <int> & list){
  int n=vals.GetSize();
  for (int i=0; i < n; i++) {
    newvals(i)=vals(list(i));
  }
}