/**********************************************************

This software is part of J.-S. Caux's ABACUS library.

Copyright (c) J.-S. Caux.

-----------------------------------------------------------

File:  ABACUS_Bethe.h

Purpose:  Declares Bethe state-related classes and functions.

Status: IN DEVELOPMENT

***********************************************************/

#ifndef ABACUS_BETHE_H
#define ABACUS_BETHE_H

#include "ABACUS.h"

namespace ABACUS {


  class Base {

  public:
    int charge;        // charge of the base:  number of particles (LiebLin gas), number of down spins (Heis), ...
    Vect<int> Nrap;    // Nrap[i] contains the number of rapidities of type i, i = 0, ..., Nstrings - 1.
    int Nraptot;       // total number of strings in this state
    Vect<DP> Ix2_infty;  // Ix2_infty[i] contains the max of BAE function for the (half-)integer I[i], i = 0, Nstrings - 1.
    Vect<int> Ix2_min;
    Vect<int> Ix2_max;    // Ix2_max[i] contains the integer part of 2*I_infty, with correct parity for base.
    string baselabel;

  public:
    Base ();
    Base (const Base& RefBase);   // copy constructor

  public:   // LiebLin constructors
    Base (int N);       // Constructor for repulsive LiebLin gas case:  one type of particle

  public:   // HEIS constructors
    Base (const Heis_Chain& RefChain, const Vect<int>& Nrapidities);  // sets to Nrapidities vector, and checks consistency
    Base (const Heis_Chain& RefChain, string baselabel_ref);

  public:    // operators
    Base& operator= (const Base& RefBase);
    bool operator== (const Base& RefBase);
    bool operator!= (const Base& RefBase);

  public:    // member functions
    void Compute_Ix2_limits(const Heis_Chain& RefChain);  // computes the Ix2_infty and Ix2_max
  };


  //****************************************************************************

  // Class Bethe_State is a wrapper class for all types of eigenstates

  class Bethe_State {

  public:   // configuration
    Base base;
    Vect<Vect<int> > Ix2;
    Vect<Vect<DP> > lambda;

  public:   // properties
    DP E;
    int iK;
    DP K;
    DP lnnorm;

  public:   // identification
    string label;  // this is the relative label by default
    Vect<Vect<int> > OriginIx2; // to define the relative label

  public:   // convergence
    DP diffsq;
    int conv;
    int iter;
    int iter_Newton;

  public:   // constructors
    Bethe_State();
    Bethe_State (const Bethe_State& RefState);  // copy constructor
    Bethe_State (const Bethe_State& OriginState, string label_ref);

    LiebLin_Bethe_State& operator= (const LiebLin_Bethe_State& RefState);


} // namespace ABACUS

#endif