% Parameters Nx = 256; Ny = 256; Lx = 10; Ly = 10; x = linspace(-Lx/2, Lx/2, Nx); dx = x(2) - x(1); Kmax = pi*Nx/Lx; kx = linspace(-Kmax,Kmax,Nx+1); kx = kx(1:end-1); dkx = kx(2)-kx(1); kx = fftshift(kx); y = linspace(-Ly/2, Ly/2, Ny); dy = y(2) - y(1); Kmax = pi*Ny/Ly; ky = linspace(-Kmax,Kmax,Ny+1); ky = ky(1:end-1); dky = ky(2)-ky(1); ky = fftshift(ky); [X, Y] = ndgrid(x, y); [KX, KY] = ndgrid(kx,ky); % Operators % Kinetic energy KEop = 0.5 * (KX.^2+KY.^2); HKin = @(w) ifft2(KEop .* fft2(w)); % Trap Potential % Harmonic potential V = 0.5 * (X.^2 + Y.^2); HV = @(w) V.*w; H = @(w) HKin(w) + HV(w); % Initial guess: random Gaussian psi = exp(-0.5 * (X.^2 + Y.^2)) .* (1 + 0.1*randn(size(X))); psi = psi / sqrt(sum(sum(abs(psi).^2)) * dx * dy); % Normalize % Gradient descent parameters (Heavy Ball) alpha = 1e-6; beta = 0.95; epsilon = 1e-8; max_iter = 1000; psi_old = psi; energy = zeros(1, max_iter); % Live plotting setup figure(1); for idx = 1:max_iter J = H(psi); % Compute gradient: -Laplace + V % Chemical potential mu = real(sum(conj(J(:)) .* psi(:))) / sum(abs(psi(:)).^2); % Residual and energy diff = J - mu * psi; res = sum(abs(diff(:)).^2) * dx * dy; energy(idx) = real(sum(conj(psi(:)) .* J(:)) * dx * dy); if res < epsilon fprintf('Converged at iteration %d\n', idx); break; end % Heavy-ball update psi_new = (1 + beta)*psi - alpha * J - beta * psi_old; psi_old = psi; % Normalize psi = psi_new / sqrt(sum(sum(abs(psi_new).^2)) * dx * dy); % Plot the evolution of |psi|^2 every 50 iterations if mod(idx, 10) == 0 imagesc(x, y, abs(psi).^2); title(sprintf('Iteration %d', idx)); axis equal tight; colorbar; drawnow; pause(0.25) end end % Trim unused energy slots energy = energy(1:idx); % Analytical ground state psi_analytic = (1/pi)^(1/2) * exp(-(X.^2 + Y.^2)/2); psi_analytic = psi_analytic / sqrt(sum(sum(abs(psi_analytic).^2)) * dx * dy); % L2 error L2_error = sqrt(sum(sum(abs(psi - psi_analytic).^2)) * dx * dy); fprintf('L2 error compared to analytical solution: %.5e\n', L2_error); % Plot results figure(2); subplot(2,3,1); imagesc(x, y, abs(psi).^2); title('$|\psi|^2$ Numerical', 'Interpreter', 'latex', 'FontSize', 14); axis equal tight; colorbar; subplot(2,3,2); imagesc(x, y, abs(psi_analytic).^2); title('$|\psi|^2$ Analytical', 'Interpreter', 'latex', 'FontSize', 14); axis equal tight; colorbar; subplot(2,3,3); imagesc(x, y, abs(psi).^2 - abs(psi_analytic).^2); title('Difference $|\psi|^2$', 'Interpreter', 'latex', 'FontSize', 14); axis equal tight; colorbar; subplot(2,3,[4 5 6]); plot(1:idx, energy, 'b-', 'LineWidth', 1.5); hold on; yline(1, 'r--', 'Analytical E=1'); xlabel('Iteration'); ylabel('Energy'); title('Energy Convergence'); grid on; legend('Numerical', 'Analytical');