/*! Type II quasisolitons in Lieb-Liniger: amplitudes_IDeltax Purpose: Produce the .amplitudes file containing the (complex) amplitudes of each basis state for amplitudes optimizing depletion density integral I(Δx) for (multi-)type II hole wavepackets in Lieb-Liniger. This executable requires Abacus version 2. See README for compilation instructions. Copyright © Jean-Sébastien Caux, Anahita Sarvi and Cesare Vianello. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ import std; import abacus; int main(int argc, char* argv[]) { using namespace std::complex_literals; if (argc != 8) { std::cout << "Executable amplitudes_IDeltax\n" << " part of the Type II quasisolitons in Lieb-Liniger software suite\n" << " copyright © Jean-Sébastien Caux, Anahita Sarvi and Cesare Vianello.\n"; std::cout << "\nPurpose:\n" << " Produce the .amplitudes file\n" << " containing the (complex) amplitudes of each basis state\n" << " for amplitudes optimizing depletion density integral I(Δx)\n" << " for (multi-)type II hole wavepackets in Lieb-Liniger.\n"; std::cout << "\nPrerequirements:\n----------------\n" << " - .states and .rho files produced by executable rho\n"; std::cout << "\nUsage:\n------\n"; std::cout << "holeIx2 \n\n"; int warg { 16 }, wtype { 10 }, wcons { 26 }; std::cout << std::left << std::setw(warg) << "Argument" << std::setw(wtype) << "Type" << std::setw(wcons) << "Constraints" << "Description\n"; std::cout << std::left << std::setw(warg) << "--------" << std::setw(wtype) << "----" << std::setw(wcons) << "-----------" << "-----------\n"; std::cout << std::left << std::setw(warg) << "c" << std::setw(wtype) << "Real" << std::setw(wcons) << "> 0" << "Value of the interaction parameter\n"; std::cout << std::left << std::setw(warg) << "L" << std::setw(wtype) << "Real" << std::setw(wcons) << "> 0" << "System size\n"; std::cout << std::left << std::setw(warg) << "N" << std::setw(wtype) << "int" << std::setw(wcons) << "> 0" << "Number of particles\n"; std::cout << std::left << std::setw(warg) << "nr holes" << std::setw(wtype) << "int" << std::setw(wcons) << "1 <= nr holes <= N" << "Number of holes (Type II modes)\n"; std::cout << std::left << std::setw(warg) << "width" << std::setw(wtype) << "int" << std::setw(wcons) << "nr holes < width <= N" << "Width of the hole window\n"; std::cout << std::left << std::setw(warg) << "offset" << std::setw(wtype) << "int" << std::setw(wcons) << "0 <= offset <= N-width" << "Offset of the hole window w/r to the right Fermi edge\n"; std::cout << std::left << std::setw(warg) << "Δx" << std::setw(wtype) << "Real" << std::setw(wcons) << "0 < Δx <= L" << "Spatial width of depletion density to optimize\n"; return 0; } std::cout << std::setprecision(std::numeric_limits::digits10 + 1); Real c { std::stold(argv[1]) }; Real L { std::stold(argv[2]) }; int N { std::stoi(argv[3]) }; int nholes { std::stoi(argv[4]) }; int width { std::stoi(argv[5]) }; int offset { std::stoi(argv[6]) }; Real Δx {std::stold(argv[7]) }; // Define the input files std::stringstream filename_base; filename_base << "c_" << c << "_N_" << N << "_L_" << L << "_nholes_" << nholes; filename_base << "_width_" << width; filename_base << "_offset_" << offset; std::stringstream states_filename; states_filename << filename_base.str() << ".states"; std::ifstream states_file; states_file.open(states_filename.str()); states_file >> std::setprecision(std::numeric_limits::digits10 + 1); std::stringstream rho_ME_filename; rho_ME_filename << filename_base.str() << ".rho"; std::ifstream rho_ME_file; rho_ME_file.open(rho_ME_filename.str()); rho_ME_file >> std::setprecision(std::numeric_limits::digits10 + 1); // Input the states info std::vector label; std::vector iK; std::vector E; std::string tmp_label; int tmp_iK; Real tmp_E; states_file >> tmp_label; do { states_file >> tmp_iK >> tmp_E; label.push_back(tmp_label); iK.push_back(tmp_iK); E.push_back(tmp_E); } while (states_file >> tmp_label); states_file.close(); int nr_states { int(label.size()) }; // Input the density operator matrix elements std::map>> rho_ME; for (int ibra { 0 }; ibra < nr_states; ++ibra) { for (int iket { 0 }; iket <= ibra; ++iket) { rho_ME_file >> rho_ME[label[ibra]][label[iket]]; } } rho_ME_file.close(); // Define the M matrix for the given Δx Matrix M (nr_states); Real K; M.setZero(); for (int ibra { 0 }; ibra < nr_states; ++ibra) { for (int iket { 0 }; iket < ibra; ++iket) { K = pi_r * (iK[ibra] - iK[iket]) * Δx/L; // K_{ab}*Δx/2 // To balance the matrix numerically, it is multiplied by sqrt(N) M(ibra, iket) = std::sqrt(N) * std::real(rho_ME[label[ibra]][label[iket]]) * (K != Real(0) ? std::sin(K)/K : 1); M(iket, ibra) = M(ibra, iket); // matrix is symmetric } } // Householder reduction and QL factorization std::vector d(nr_states); std::vector e(nr_states); tred2(M, d, e); tqli(d, e, M); // std::cout << "Eigenvalues according to QL: " << d << std::endl; // Find minimal eigenvalue; the optimal wavefunction is then the corresponding eigenvector int min_red_ev_index { 0 }; Real min_red_ev { d[0] }; for (int ibra { 0 }; ibra < nr_states; ++ibra) { if (d[ibra] < min_red_ev) { min_red_ev_index = ibra; min_red_ev = d[ibra]; } } // Define the output files std::stringstream amplitudes_filename; amplitudes_filename << filename_base.str() << "_IDeltax_" << Δx << ".amplitudes"; std::ofstream amplitudes_file; amplitudes_file.open(amplitudes_filename.str(), std::ios::out | std::ios::trunc); amplitudes_file << std::setprecision(std::numeric_limits::digits10 + 1); // Output the state amplitudes for (int ibra { 0 }; ibra < nr_states; ++ibra) { amplitudes_file << M(ibra, min_red_ev_index) << "\t"; } amplitudes_file.close(); return 0; }