Untitled

Anonymous
c_cpp
02/20/2026 4:38 AM
11.4 KB
12
Indexable
//#include "/home/lipegal/Documents/OIST/code/Modular/kp_lib.h"
#include "/flash/BuschU/andres/Transfer_protocol/kp_lib.h"
#include <vector>
#include <functional>
#include <iostream>
#include <fstream>
#include <cmath>
#include <boost/numeric/odeint.hpp>
//signature
using namespace boost::numeric::odeint;
using namespace std;

int in_trunc_dim = 100, num_comp = 300;
int evo_trunc_d = 20;
double tol = 1e-8;
double dt = 1e-4;

// Blackman window
double a0 = 0.42, a1 = 0.5, a2 = 0.08, a3 = 0.012604;

double dip_(int n, int m, double L){
  if(n == m) return ((L * L)/ 12.) - (L * L) / (2 * PI * PI * n * n);
  if((n + m) % 2 == 0) return (8 * L * L * m * n) / (PI * PI * pow(n * n - m * m, 2));
  return 0.0;
}

double dip_x(int n, int m, double L)
{
  if (n == m) return 0.0;
  if ((n + m) % 2 == 0) return 0.0;

  double sign = pow(-1.0, (n + m + 1) / 2.0);
  return (-4.0 * L / (M_PI * M_PI)) * sign *
    (1.0 / pow(n - m, 2) + 1.0 / pow(n + m, 2));
}

// Contrasted with S. Iqbal - F.saif paper
double dip_x2(int n, int m, double a)
{
  // ---- Diagonal term ----
  if (n == m) {
    return (a * a) / 3.0
      + (2.0 * a * a * pow(-1.0, n))
      / (n * n * M_PI * M_PI);
  }

  // ---- Selection rule: same parity only ----
  if ( (n + m) % 2 != 0 )
    return 0.0;

  // ---- Off-diagonal term ----
  double sign = pow(-1.0, (m - n) / 2.0);

  return (8.0 * a * a / (M_PI * M_PI)) * sign *
    ( 1.0 / pow(m - n, 2)
      - 1.0 / pow(m + n, 2) );
}

// Nuttall envelope
double nuttall(double t, double t_pi) {
  double n = t / t_pi;
  return a0 - a1 * cos(2 * PI * n) + a2 * cos(4 * PI * n) - a3 * cos(6 * PI * n);
}

// Blackman envelope
double blackman(double t, double t_pi) {
  double n = t / t_pi;
  return a0 - a1 * cos(2. * PI * n) + a2 * cos(4. * PI * n);
}

// Gaussian envelope
double gaussian(double t, double t_pi, double sigma) {
  return exp(- 0.5 * pow( (t - (0.5 * t_pi)) / sigma, 2));
}

struct EvoResult {
  ComplexVector final_state;
  double max_population;
  int steps;
};

EvoResult evolve_state_fixed_dt(ComplexVector psi_init, double t_tot, double omega, int evo_trunc_d,
                                auto& schrodinger_rhs, const vector<ComplexVector>& eigs_in, int target_level,
                                ofstream& fidelFile, int L, ofstream* wfFile=nullptr) {
  ComplexVector psi_t = psi_init;
  double t = 0.0;
  int step_count = 0;

  // ---- FIXED DT FROM OMEGA ----
  const int Npp = 5000; // points per period
  const double dt = 2.0 * M_PI / (omega * Npp);

  runge_kutta4<ComplexVector> stepper;

  double output_interval = 0.1;
  double next_output_time = 0.0;

  cout << "Fixed-step RK4 evolution\n";
  cout << "omega = " << omega << "\n";
  cout << "dt    = " << dt << "\n";
  cout << "steps = " << int(t_tot / dt) << endl;

  while (t < t_tot) {
    stepper.do_step(schrodinger_rhs, psi_t, t, dt);
    t += dt;
    step_count++;

    normalize(psi_t);
    // ---- OUTPUT ----
    while (t >= next_output_time) {
      //wf_data wf_t;
      //build_wf(psi_t, wf_t, L);
      //save_wf_par(wfFile, wf_t, t);

      fidelFile << t;

      // Eigenstates overlaps
      for (int n = 0; n <= target_level + 2; ++n) {
        if (n < 0 || n >= evo_trunc_d) {
          fidelFile << " 0.0";
          continue;
        }
        Complex ovlp = 0.0;
        for (int i = 0; i < evo_trunc_d; ++i)
          ovlp += conj(eigs_in[n](i)) * psi_t(i);
        fidelFile << " " << norm(ovlp);
      }

      fidelFile << "\n";

      next_output_time += output_interval;
    }

    if (step_count % 1000 == 0) {
      cout << "Progress: " << (t / t_tot) * 100.0 << "%\r" << flush;
    }
  }

  cout << "\nEvolution completed: " << step_count << " steps\n";

  return {psi_t, 0.0, step_count};
}


RealMatrix build_H_with(double pref, double L, double trunc_dim) {
  HamKernel kernel = [&](int n, int m) {
    return kin(n , m , L) + pref * dip_x2(n, m , L/2);
  };
  return build_H(trunc_dim, kernel);
}

// ------------------------------------------------------------------
// Main
// ------------------------------------------------------------------
int main(int argc, char* argv[]) {
  if (argc < 2) {
    cerr << "Usage: ./run [target_level] [alpha]" << endl;
    return 1;
  }

  int target_level = atoi(argv[1]);
  cout << "Target level: " << target_level << endl;

  // -------------------- System setup ------------------------------
  double doms_num = 1;
  std::vector<Domain> domains;
  double L_[] = {1};
  int    M_[] = {0};
  double B_[] = {0.0};
  double W_[] = {0.0}; // Empty well
  double D_[] = {0.0};
  double h_[] = {0.0};

  dom_load(domains, L_, M_, B_, W_, D_, h_, doms_num);
  print_syst_info(domains);

  double L = syst_L(domains);
  RealVector offsets = offsets_(domains);

  //--------------------------- EMPTY WELL HAMILTONIAN ----------------------------
  dom_load (domains, L_, M_, B_, W_, D_, h_, doms_num);

  // Generate Hamiltonian function
  auto H_in = [&](int n, int m) {
    return Ham_uni(n, m, domains, offsets, L);
  };

  Ham_data in_data = H_diag (H_in, in_trunc_dim, tol, num_comp);

  cout << "--Initial state succesfully extracted--" << endl;
  cout << "in_dim = " << in_data.dim << endl;

  // Ground state of the empty well
  ComplexVector psi_in = eigen_extract(in_data, 0);
  normalize(psi_in);

  //----------------------------------------------------------------------

  // Initial and final eigenstates
  vector<ComplexVector> eigs_in;
  for (int k = 0; k < evo_trunc_d; ++k) {
    eigs_in.push_back(eigen_extract(in_data, k));
  }
  in_data = truncate_Ham_data(in_data, evo_trunc_d);

  double omega = in_data.eigvals[target_level - 1] - in_data.eigvals[0];
  double dipole_val = dip_x2(target_level, 1, L/2);

  // Adaptive parameter
  double alpha =  atof(argv[2]);

  // Gaussian parameters
  double lambda = alpha * (PI * PI / (L * L * dipole_val));
  double sigma = (L * L) / (sqrt(2 * PI) * alpha * PI);
  double t_pi = 10 * sigma;
  double t_tot = t_pi + 0.5 * t_pi;

  if (fabs(dipole_val) < 1e-6) {
    cerr << "Dipole too small for target level " << target_level << endl;
    return 1;
  }

  cout << "t_pi = " << t_pi << " , sigma = " << sigma << " ,lambda = " << lambda << " ,omega = "<< omega << endl;

  //for (int n = 1; n < 50; ++n) cout << "<1|x|" << n + 1 << "> = " << dip(n + 1, 1,L) << endl;

  // To print the gaussian
  /*
    ofstream gaussFile("gaussian.dat", ios::trunc);
    double t_curr = 0;
    double dtg= 0.01;
    while (t_curr < t_pi) {
    gaussFile << t_curr << " " << gaussian(t_curr, t_pi,sigma) << endl;
    t_curr += dtg;
    }

    // Blackman - Nutall parameters
    double t_pi = (L * L) / (a0 * alpha * PI);
    double lambda = PI / (dipole_val * a0 * t_pi);

    cout << "  omega = " << omega << ", dipole = " << dipole_val << endl;
    cout << "  alpha = " << alpha << ", t_pi = " << t_pi << ", lambda = " << lambda << endl;
  */

  // ----------------- Files definition ---------------------
  std::ostringstream fidel_th_ss;
  //std::ostringstream wf_th_ss;

  fidel_th_ss << "data/fidelity_" << std::fixed << std::setprecision(3) << alpha <<"_" << target_level << ".dat";
  //wf_th_ss << "data/wf_" << std::fixed << std::setprecision(3) << alpha << "_" << target_level << ".dat";

  //fidel_th_ss << "data/fidelity.dat";
  //wf_th_ss << "data/wf_prep.dat";

  ofstream fidel_thFile(fidel_th_ss.str(), ios::trunc);
  //ofstream wf_thFile(wf_th_ss.str(), ios::trunc);

  ofstream summaryFile("data/summary_fidelity.dat", ios::app);

  // --------------------------TIME EVOLUTION------------------------------
  ComplexVector psi_t = psi_in;

  RealMatrix H_kin = build_H_with(0.0, L, evo_trunc_d);
  RealMatrix H_drive = build_H_with(1.0, L, evo_trunc_d);

  auto schrodinger_rhs = [&](const ComplexVector &psi, ComplexVector &dpsi, double t) {
    double pref = 0.0;
    if (t <= t_pi) {
      pref = 1 * gaussian(t, t_pi, sigma) * lambda * cos(omega * t);
    }
    for (int i = 0; i < evo_trunc_d; ++i) {
      Complex sum = 0.;
      for (int j = 0; j < evo_trunc_d; ++j) {
        sum += (H_kin(i,j) + pref * H_drive(i,j) ) * psi(j);
      }
      dpsi(i) = Complex(0.0, -1.0) * sum;
    }
  };

  auto result_theo = evolve_state_fixed_dt(psi_in, t_tot, omega, evo_trunc_d, schrodinger_rhs,
                                           eigs_in, target_level, fidel_thFile, L);
  cout << "\n=== PROTOCOL COMPLETE ===\n";

  // --- Compute final fidelity with target eigenstate
  ComplexVector psi_final = result_theo.final_state;

  Complex overlap = 0.0;
  for (int i = 0; i < evo_trunc_d; ++i) {
    overlap += conj(eigs_in[target_level - 1](i)) * psi_final(i);
  }

  double final_fidelity = norm(overlap);
  summaryFile << alpha << " " << target_level << " " << t_pi << " " << final_fidelity << endl;

  return 0;
}
Editor is loading...
Leave a Comment