% ------------------------------------------------------
%
% nlse.m
%
% solves the cubic nonlinear Schroedinger equation
%
% PDE:      u_t + d*u_{xx} + c|u|^2*u=0 
%
% Initial conditiion:  u(t=0,x) = a/cosh(a*x)
%
% Analytical solution: u(t,x) = a/cosh(a*x)*exp(i*a^2*t)
%
% Boundary Conditons:  vanishing for |x|->infinity
%
%
% Solution method: standard split-step
%
%-------------------------------------------------------

function [x,u,uStart,uAna]=nlse()

% Set up parameters

xMin =  -50;            % range in x
xMax =   50;

nMin = -512;             % grid
nMax = -nMin-1;
nPoints = nMax-nMin+1;

dx = (xMax-xMin)/(nPoints);
x = linspace(xMin,xMax-dx,nPoints);
dom = 2*pi/(xMax-xMin);

dt= 0.001

tStart = 0.0;

stepNum = 50000; 

tEnd = dt*stepNum;

% PDE parameters

d = 1.0;
c = 2.0;

% Set up vector for FFT

om  = dom*[0:nPoints/2,-nPoints/2+1:-1]; 

% Initial condition

u = nlseSol(x,0.0,1.0);

% Analytical Solutions

uAna = nlseSol(x,tEnd,1.0);

% Create output of initial condition

uStart = u;             

% Prepare coefficients for linear step

cv2 = exp(-i*d*om.^2*dt/2);
cv = cv2.^2;

% Start Integration: first linear step
% of dt/2

u = fft(u);
u = u.*cv2;
u = ifft(u);

% Peform one nonlinear step of dt

u = exp(i*c*(abs(u)).^2*dt).*u;

% Perform stepNum-1 times a linear
% step followed by a nonlinear step

for stepCtr=1:stepNum-1
     
    % linear step
	
    u = fft(u);
    u = u.*cv;
    u = ifft(u);

    % nonlinear step

    u = exp(i*c*(abs(u)).^2*dt).*u;
        
end         

% Perform the final linear step of dt/2

u = fft(u);
u = u.*cv2;
u = ifft(u);

% Analytical soliton solution of the NLSE

function y = nlseSol(x,t,a)

y = a./cosh(a*x)*exp(i*a^2*t);


