#!/usr/bin/env ruby
# This example is taken from frei2.cpp
# in "Numerische Physik" p205-206 (Springer).
#
# Reference:
# "Numerische Physik", by Harald Wiedemann, Springer (2004)
# ISBN: 3-540-40774-X
# http://www.springeronline.com/sgw/cda/frontpage/0,10735,1-102-22-22345455-0,00.html
require("rbgsl")
#NMAX = 8192
NMAX = 256
psi = GSL::Vector[2*NMAX]
dx = 0.1
dt = 0.1
n_out = 20
alpha = 1
p_0 = -0.5
dp = 2*Math::PI/dx/NMAX
sum = 0.0
for n in 0...NMAX
x = (n-NMAX/2) * dx
psi[2*n] = Math::exp(-GSL::pow_2(x/alpha)/2)
sum += GSL::pow_2(psi[2*n]);
end
sum = 1.0/Math::sqrt(sum)
for n in 0...NMAX
x = (n-NMAX/2) * dx
psi[2*n+1] = -psi[2*n] * sum * Math::sin(p_0*x) # Imaginaerteil
psi[2*n] = psi[2*n] * sum * Math::cos(p_0*x)
end
IO.popen("graph -T X -C -g 3", "w") do |io|
psi_p = psi.duplicate
for n1 in 0...NMAX do
x = (n1-NMAX/2) * dx
io.printf("%e %e\n", x, Math::sqrt(GSL::pow_2(psi[2*n1]) + GSL::pow_2(psi[2*n1+1])))
end
io.printf("\n")
GSL::FFT::Complex::Radix2::forward(psi_p)
t = 0.0
for n in 1..n_out do
t1 = n*dt
STDOUT.printf("t = %2.1f (%2d/%2d)\n", t1, n, n_out)
for n1 in 0...(NMAX/2) do
pp = n1*dp
arg = GSL::pow_2(pp)*t1/2
psi[2*n1] = psi_p[2*n1] * Math::cos(arg) - psi_p[2*n1+1] * Math::sin(arg)
psi[2*n1+1] = psi_p[2*n1] * Math::sin(arg) + psi_p[2*n1+1] * Math::cos(arg)
end
for n1 in (NMAX/2)...NMAX do
pp = (n1-NMAX)*dp
arg = GSL::pow_2(pp)*t1/2
psi[2*n1] = psi_p[2*n1] * Math::cos(arg) - psi_p[2*n1+1] * Math::sin(arg)
psi[2*n1+1] = psi_p[2*n1] * Math::sin(arg) + psi_p[2*n1+1] * Math::cos(arg)
end
GSL::FFT::Complex::Radix2::inverse(psi)
if n%10 == 0
for n1 in 0...NMAX do
x = (n1-NMAX/2) * dx
io.printf("%e %e\n", x, Math::sqrt(GSL::pow_2(psi[2*n1]) + GSL::pow_2(psi[2*n1+1])))
end
io.printf("\n")
end
end
end
syntax highlighted by Code2HTML, v. 0.9.1