From 8e4e5db00d4744b18898bac0c67d775b10af04cf Mon Sep 17 00:00:00 2001 From: cnoelle <19640096+cnoelle@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:40:26 +0100 Subject: [PATCH] initial commit --- .gitattributes | 2 + .gitignore | 33 + Examples.md | 437 +++++++++++++ Project.toml | 9 + README.md | 385 +++++++++++ examples/freeParticle/gaussian.json | 17 + .../coherentStateClassical.json | 9 + .../harmonicOscillator/coherentStateQm.json | 18 + .../coherentStateQmResidual.json | 21 + .../harmonicOscillator/groundStateQm.json | 18 + src/ClassicalSystem.jl | 88 +++ src/CrankNicolson.jl | 42 ++ src/DifferentiationUtils.jl | 102 +++ src/ExactQuantumPropagation.jl | 31 + src/ExactTrajectory.jl | 41 ++ src/ExactWaveFunction.jl | 113 ++++ src/ForwardEulerQm.jl | 31 + src/IoSystemUtils.jl | 144 +++++ src/IoUtils.jl | 290 +++++++++ src/MatrixExponential.jl | 60 ++ src/NumericsScheme.jl | 47 ++ src/PhaseSpace.jl | 54 ++ src/PhaseSpaceFunctions.jl | 611 ++++++++++++++++++ src/QmSystem.jl | 145 +++++ src/QmSystemConcat.jl | 56 ++ src/QmSystemResidual.jl | 136 ++++ src/QmSystemSum.jl | 34 + src/Representation.jl | 242 +++++++ src/ResidualScheme.jl | 177 +++++ src/SchroedingerConfig.jl | 42 ++ src/SchroedingerNumerics.jl | 34 + src/SymplecticEuler.jl | 53 ++ src/WaveFunction.jl | 338 ++++++++++ src/WeylTransformedScheme.jl | 45 ++ viz/assets/icons/east_black_24dp.svg | 1 + viz/assets/icons/license.txt | 3 + viz/assets/icons/pause_black_24dp.svg | 1 + viz/assets/icons/play_arrow_black_24dp.svg | 1 + viz/assets/icons/stop_black_24dp.svg | 1 + viz/assets/icons/west_black_24dp.svg | 1 + viz/assets/style.css | 153 +++++ viz/index.html | 70 ++ viz/package.json | 30 + viz/src/JsUtils.ts | 98 +++ viz/src/PlotsController.ts | 34 + viz/src/SimulationController.ts | 353 ++++++++++ viz/src/SimulationControls.ts | 146 +++++ viz/src/SimulationUtils.ts | 408 ++++++++++++ viz/src/colorPalette.ts | 21 + viz/src/datasetsGrid.ts | 44 ++ viz/src/differencePlot.ts | 202 ++++++ viz/src/index.ts | 112 ++++ viz/src/phaseSpace.ts | 318 +++++++++ viz/src/psiPlot.ts | 253 ++++++++ viz/src/types.ts | 160 +++++ viz/tsconfig.json | 13 + viz/webpack.config.js | 53 ++ 57 files changed, 6381 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Examples.md create mode 100644 Project.toml create mode 100644 README.md create mode 100644 examples/freeParticle/gaussian.json create mode 100644 examples/harmonicOscillator/coherentStateClassical.json create mode 100644 examples/harmonicOscillator/coherentStateQm.json create mode 100644 examples/harmonicOscillator/coherentStateQmResidual.json create mode 100644 examples/harmonicOscillator/groundStateQm.json create mode 100644 src/ClassicalSystem.jl create mode 100644 src/CrankNicolson.jl create mode 100644 src/DifferentiationUtils.jl create mode 100644 src/ExactQuantumPropagation.jl create mode 100644 src/ExactTrajectory.jl create mode 100644 src/ExactWaveFunction.jl create mode 100644 src/ForwardEulerQm.jl create mode 100644 src/IoSystemUtils.jl create mode 100644 src/IoUtils.jl create mode 100644 src/MatrixExponential.jl create mode 100644 src/NumericsScheme.jl create mode 100644 src/PhaseSpace.jl create mode 100644 src/PhaseSpaceFunctions.jl create mode 100644 src/QmSystem.jl create mode 100644 src/QmSystemConcat.jl create mode 100644 src/QmSystemResidual.jl create mode 100644 src/QmSystemSum.jl create mode 100644 src/Representation.jl create mode 100644 src/ResidualScheme.jl create mode 100644 src/SchroedingerConfig.jl create mode 100644 src/SchroedingerNumerics.jl create mode 100644 src/SymplecticEuler.jl create mode 100644 src/WaveFunction.jl create mode 100644 src/WeylTransformedScheme.jl create mode 100644 viz/assets/icons/east_black_24dp.svg create mode 100644 viz/assets/icons/license.txt create mode 100644 viz/assets/icons/pause_black_24dp.svg create mode 100644 viz/assets/icons/play_arrow_black_24dp.svg create mode 100644 viz/assets/icons/stop_black_24dp.svg create mode 100644 viz/assets/icons/west_black_24dp.svg create mode 100644 viz/assets/style.css create mode 100644 viz/index.html create mode 100644 viz/package.json create mode 100644 viz/src/JsUtils.ts create mode 100644 viz/src/PlotsController.ts create mode 100644 viz/src/SimulationController.ts create mode 100644 viz/src/SimulationControls.ts create mode 100644 viz/src/SimulationUtils.ts create mode 100644 viz/src/colorPalette.ts create mode 100644 viz/src/datasetsGrid.ts create mode 100644 viz/src/differencePlot.ts create mode 100644 viz/src/index.ts create mode 100644 viz/src/phaseSpace.ts create mode 100644 viz/src/psiPlot.ts create mode 100644 viz/src/types.ts create mode 100644 viz/tsconfig.json create mode 100644 viz/webpack.config.js diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..032c1bd --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..360e0d5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Files generated by invoking Julia with --code-coverage +*.jl.cov +*.jl.*.cov + +# Files generated by invoking Julia with --track-allocation +*.jl.mem + +# System-specific files and directories generated by the BinaryProvider and BinDeps packages +# They contain absolute paths specific to the host computer, and so should not be committed +deps/deps.jl +deps/build.log +deps/downloads/ +deps/usr/ +deps/src/ + +# Build artifacts for creating documentation generated by the Documenter package +docs/build/ +docs/site/ + +# File generated by Pkg, the package manager, based on a corresponding Project.toml +# It records a fixed state of all packages used by the project. As such, it should not be +# committed for packages, but should be committed for applications that require a static +# environment. +Manifest.toml + +.env +results/ +package-lock.json +dist/ +node_modules/ + +.vscode/ + diff --git a/Examples.md b/Examples.md new file mode 100644 index 0000000..8571bd9 --- /dev/null +++ b/Examples.md @@ -0,0 +1,437 @@ +# SchroedingerNumerics examples + +## Content + +* [Free particle](#free-particle) + * [Free Gaussian wave packet](#free-gaussian-wave-packet) + * [Plane wave](#plane-wave) +* [Harmonic Oscillator](#harmonic-oscillator) + * [Ground state (QM)](#ground-state-qm) + * [Coherent state (Classical)](#coherent-state-classical) + * [Coherent state (QM)](#coherent-state-qm) + * [Coherent state (QMResidual)](#coherent-state-qmresidual) +* [Morse potential](#morse-potential) + * [Schrödinger equation](#schrödinger-equation) + * [Residual representation](#residual-representation) +* [Tunneling](#tunneling) + * [Residual representation](#residual-representation-1) + * [Combining different approaches](#combining-different-approaches) +* [Scattering](#scattering) +* [Quartic oscillator](#quartic-oscillator) + +## Free particle + +### Free Gaussian wave packet + +The Schrödinger equation for a free Gaussian wave packet. + +```julia +config = SchroedingerConfig(hbar=0.001) +# free particle Hamiltonian (mass=1) +H = PMonomial(2)/2 +# Gaussian wave packet of width ~ 0.03 +psi0 = PositionWaveFunction(x -> exp(-x^2/2/config.hbar)) +rep = PositionRepresentation(range(-0.8, 0.8, step=0.001), config) +steps = 1000 +T = 4 * pi +deltaT=T/steps +systemFree0 = QmSystem(psi0, H, rep, deltaT) +# solve the Schrödinger equation and store results in the specified subfolder +# => can be used for visualization later on +trace(systemFree0, steps, folder="results/freeParticle/gaussian") +# store example scenario +#store(systemFree0, "examples/freeParticle/gaussian.json") +``` + +### Plane wave + +We consider different ways to integrate the time-dependent Schrödinger equation for a plane wave $\psi(t=0, x) = e^{\frac i\hbar p_0 x}$ for some $p_0 \neq 0$. The known exact solution is + +$$ \psi(t,x) =\exp\Big\{ \frac i\hbar \Big( p_0 x - \frac{p_0^2}{2m}t\Big) \Big\} $$ + +The original Schrödinger equation suffers from boundary reflections, if we use Neumann boundary conditions $\frac\partial{\partial x} \psi |_{\partial \Omega} = 0$: + +```julia +p = 1. +mass = 1. +hbar = 1. +T = 4 * pi * mass * hbar / p^2 +H = PMonomial(2)/(2*mass) + +steps = 1000 +deltaT = T / steps +xPeriod = 2*pi*hbar / p +config = SchroedingerConfig(hbar=hbar, includeIntegralFactor=true, firstDerivativeMethod=0) +xmin = -1 - 8 * xPeriod +xmax = -xmin + +point0 = Point(0., p) +Phi0 = PositionWaveFunction(x -> 1.) +rep = PositionRepresentation(range(xmin, xmax, length=1001), config) +psi = weylTranslate(Phi0, -point0, hbar) + +# For solving in the original Schrödinger equation +systemQm = QmSystem(psi, H, rep, deltaT) +trace(systemQm, steps, folder="results/freeParticle/planeWaveQm") +``` + +The appropriate residual representation is perfectly adapted to Neumann boundary conditions, on the other hand, since $\Phi$ is constant in this representation anyway: + +```julia +# For solving in the residual scheme +# a trajectory at constant speed but staying at the same position all the time +classicalScheme = ExactTrajectory((t::Real) -> point0) +scheme = ResidualCrankNicolson(classicalScheme=classicalScheme, isTrajectoryHamiltonian=false,) +systemRes = QmSystemResidual(point0, Phi0, H, rep, deltaT, scheme=scheme, classicalResolutionFactor=1) +trace(systemRes, steps, folder="results/freeParticle/planeWaveQmResidual") +``` + +Also prone to boundary problems, the Weyl transformed wave function (without phase integral factor): + +```julia +# For solving directly in the Weyl representation over (0, p0) +systemWeyl = QmSystem(psi, H, rep, deltaT, scheme=WeylTransformedScheme(point0)) +trace(systemWeyl, steps, folder="results/freeParticle/planeWaveQmWeyl") +``` + + +## Harmonic Oscillator + +### Ground state (QM) + +Using the default Crank-Nicolson method: + +```julia +config = SchroedingerConfig(hbar=0.001) +# using again the harmonic oscillator example from above +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +# the harmonic oscillator ground state, see e.g. https://en.wikipedia.org/wiki/Quantum_harmonic_oscillator; this a Gaussian with variance \sqrt{\hbar} +psi0 = PositionWaveFunction(x -> exp(-x^2 / 2/config.hbar)) +# introducing a grid with 401 points +rep = PositionRepresentation(range(-0.2, 0.2, step=0.001), config) +steps = 1000 +T = 4 * pi # the oscillation period of the ground state +deltaT=T/steps # 1000th part of an oscillation period +systemQm0 = QmSystem(psi0, H, rep, deltaT) +# solve the Schrödinger equation and store results in the specified subfolder +# => can be used for visualization later on +trace(systemQm0, steps, folder="results/harmonicOscillator/groundStateQm") +# store example scenario +#store(systemQm0, "examples/harmonicOscillator/groundStateQm.json") +``` + +### Coherent state (Classical) + +Hamilton's equation for a harmonic oscillator. Leading to a circular solution in phase space for our parameters. + +```julia +# the initial condition for Hamilton's equations, q=0.6, p=0 +q0 = 0.6 +startingPoint = Point(q0, 0.) +# the Hamiltonian, a harmonic oscillator with m=1 and \omega=1 +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +T = 2 * pi # the oscillation period of the oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +system0 = ClassicalSystem(startingPoint, H, deltaT) +# solve the Hamiltonian equations and store results in the specified subfolder +# => can be used for visualization later on +trace(system0, steps, folder="results/harmonicOscillator/coherentState" * string(q0) * "Classical") +# store example scenario +#store(system0, "examples/harmonicOscillator/coherentState" * string(q0) * "Classical.json") +``` + +### Coherent state (QM) + +This is an example that does not work well... we are trying to directly integrate the Schrödinger equation in the semiclassical regime, and the chosen grid resolution is too small. + +```julia +config = SchroedingerConfig(hbar=0.001) +# using again the harmonic oscillator example from above +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +q0 = 0.6 +psi0 = PositionWaveFunction((x::Real) -> exp(-1/2/config.hbar * (x-q0)^2)) +point0 = Point(q0, 0) +Phi0 = weylTranslate(psi0, point0, config.hbar) +T = 2 * pi # the oscillation period of the classical oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +# here we need to enlarge the grid, because the wave function now oscillates between -1 and 1. The width of the initial wave function remains roughly 0.03, so we keep the step size as before +rep = PositionRepresentation(range(-0.2, 0.2, step=0.001), config) +psiRep = PositionRepresentation(range(-q0 - 0.2, q0 + 0.2, step=0.001), config) +systemCoherent0 = QmSystem(psi0, H, psiRep, deltaT) +trace(systemCoherent0, steps + 5, folder="results/harmonicOscillator/coherentState" * string(q0) * "Qm") +# store example scenario +#store(systemCoherent0, "examples/harmonicOscillator/coherentState" * string(q0) * "Qm.json") +``` + +### Coherent state (QMResidual) + +This is a better way to solve the Schrödinger equation in the semi-classical regime, by resorting to the *residual Schrödinger equation*. It is based on a solution of Hamilton's equation and a modified form of Schrödinger's equation. + +```julia +config = SchroedingerConfig(hbar=0.001) +# using again the harmonic oscillator example from above +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +q0 = 0.6 +psi0 = PositionWaveFunction((x::Real) -> exp(-1/2/config.hbar * (x-q0)^2)) +point0 = Point(q0, 0) +Phi0 = weylTranslate(psi0, point0, config.hbar) +T = 2 * pi # the oscillation period of the classical oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +# here we need to enlarge the grid, because the wave function now oscillates between -1 and 1. The width of the initial wave function remains roughly 0.03, so we keep the step size as before +rep = PositionRepresentation(range(-0.2, 0.2, step=0.001), config) +psiRep = PositionRepresentation(range(-q0 - 0.2, q0 + 0.2, step=0.001), config) +systemResidual0 = QmSystemResidual(point0, Phi0, H, rep, deltaT, psiRepresentation=psiRep, classicalResolutionFactor=100) +trace(systemResidual0, steps + 5, folder="results/harmonicOscillator/coherentState" * string(q0) * "QmResidual") +# store example scenario +#store(systemResidual0, "examples/harmonicOscillator/coherentStateQm" * string(q0) * "Residual.json") +``` + +## Morse potential + + +The Morse potential is + +$$ V(x) = D(1-\exp(-ax))^2 $$ + +for $a>0$ and $D>0$. It has a minimum in x = 0. The Schrödinger equation for the Morse potential can be solved exactly +(see [Wikipedia](https://en.wikipedia.org/wiki/Morse_potential)) and it has a finite number of bound states, given by + +$$ N = \Big[\sqrt{\frac{2mD}{a}}\hbar - 1\Big] $$ + +(the closest integer smaller or equal to the expression in square brackets). Note that the $n$-th derivative of the potential can be determined as + +$$ V^{(n)}(x) = (-1)^n 2a^nDe^{-ax}\big[ne^{-ax}-1\big] $$ + +In the Taylor expansion around 0, the harmonic approximation corresponds to a frequency + +$$ \omega = \sqrt{\frac {2a^2D}{m}}. $$ + +### Schrödinger equation + +```julia +# fraction of energy of the dissociation energy assigned to the particle +energyFraction = 0.5 +a = 1. +mass = 1. +config = SchroedingerConfig(hbar=0.001) +D = 5000 * a * config.hbar^2/2/mass # roughly 100 bound states +V_func = (x::Real, p::Union{Real, Nothing}=nothing) -> D * (1. - exp(-a * x))^2 +function derivatives(n::Int, x::Real, p::Union{Real, Nothing}=nothing)::Real + e::Real = exp(-a*x) + return (-a)^n * 2 * D * e * (n*e - 1) +end # deriv +potential = XFunction(V_func, derivatives) +p0 = -sqrt(2*mass*D*energyFraction) # momentum such that the kinetic energy equals the dissociation energy times energyFraction +H = PMonomial(2) / (2*mass) + potential +omega = sqrt(2*a^2*D/mass) +deltaT = 2 * pi / omega / 1000 +# harmonic ground state at 0 +Phi0 = PositionWaveFunction((x::Real) -> exp(-sqrt(mass*D/2)*a/config.hbar * x^2)) +point0 = Point(0., p0) +psi0 = weylTranslate(Phi0, -point0, config.hbar) +# a good range depends on the energy fraction +rep = PositionRepresentation(range(-1, 4, step=0.005), config) +systemQmMorse = QmSystem(psi0, H, rep, deltaT) +# store results in a folder, to be used with visualization component +trace(systemQmMorse, 2000, folder="results/morse/energy0.5/qm") +``` + + +### Residual representation + +```julia +# fraction of energy of the dissociation energy assigned to the particle +energyFraction = 0.5 +a = 1. +mass = 1. +config = SchroedingerConfig(hbar=0.001) +D = 5000 * a * config.hbar^2/2/mass # roughly 100 bound states +V_func = (x::Real, p::Union{Real, Nothing}=nothing) -> D * (1. - exp(-a * x))^2 +function derivatives(n::Int, x::Real, p::Union{Real, Nothing}=nothing)::Real + e::Real = exp(-a*x) + return (-a)^n * 2 * D * e * (n*e - 1) +end # deriv +potential = XFunction(V_func, derivatives) +p0 = -sqrt(2*mass*D*energyFraction) # momentum such that the kinetic energy equals the dissociation energy times energyFraction +H = PMonomial(2) / (2*mass) + potential +omega = sqrt(2*a^2*D/mass) +deltaT = 2 * pi / omega / 1000 +# harmonic ground state at 0 +Phi0 = PositionWaveFunction((x::Real) -> exp(-sqrt(mass*D/2)*a/config.hbar * x^2)) +point0 = Point(0., p0) +# a good range depends on the energy fraction +rep = PositionRepresentation(range(-1.5, 4, step=0.005), config) +psiRep = PositionRepresentation(range(-1, 3, step=0.005), config) +systemResidualMorse = QmSystemResidual(point0, Phi0, H, rep, deltaT, psiRepresentation=psiRep) +# store results in a folder, to be used with visualization component +trace(systemResidualMorse, 2000, folder="results/morse/energy0.5/residual") +``` + + +## Tunneling + +We consider a harmonic oscillator potential with a spike added in the origin: + +$$ V(x) = \big(1+x^2/2\big) * \big(1 + \tfrac 14 e^{-x^2/2\hbar}\big) - 1 $$ + +Our initial wave function is a coherent state traveling in the harmonic potential away from the spike. The energy of the wave packet is carefully chosen to almost exactly match the height of the spike at the origin (slightly surpassing it). When the wave packet hits the spike for the first time it splits into two, a reflected wave packet and a transmitted one. + +### Residual representation + +Here we start with the residual representation, which cannot successfully trace the splitting of the wave function. Although initially, after hitting the potential spike, the wave function behaves somewhat as expected, splitting into two parts, one traversing the obstacle and the other being reflected, after some time the classical trajectory *drags* the reflected part of the wave function over to the transmitted side. This is unphysical, the residual representation is prone to such problems when a splitting of the wave function into multiple wave packets takes place. + +```julia +config = SchroedingerConfig(hbar=0.001) +V_func = (x::Real, p::Union{Real, Nothing}=nothing) -> (1+x^2/2) * (1 + 0.25*exp(-x^2/(2*config.hbar))) - 1 +V = XFunction(V_func) +H = PMonomial(2)/2 + V +point0 = Point(-0.5, -0.5) +Phi0 = PositionWaveFunction((x::Real) -> exp(-1/2/config.hbar * x^2)) +T = 2 * pi # the oscillation period of the classical oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +# here we need to enlarge the grid, because the wave function now oscillates between -1 and 1. The width of the initial wave function remains roughly 0.03, so we keep the step size as before +rep = PositionRepresentation(range(-0.5, 0.5, step=0.001), config) +# The original wave function must be considered on a larger grid; but we do not need a fine resolution for it +psiRep = PositionRepresentation(range(-1.2, 1.2, step=0.005), config) +systemTunnel0 = QmSystemResidual(point0, Phi0, H, rep, deltaT, psiRepresentation=psiRep) +trace(systemTunnel0, 600, folder="results/tunneling/residual") +``` + +### Combining different approaches + +To overcome the problems of the residual scheme we combine different approaches to solving the Schrödinger equation, starting with the residual equation for a semi-classical wave packet, then turning to the ordinary Schrödinger equation when the wave function splits (*quantum tunneling*), and finally setting up two residual equations for the resulting wave packets and summing them up to the final solution. + +```julia +config = SchroedingerConfig(hbar=0.001) +V_func = (x::Real, p::Union{Real, Nothing}=nothing) -> (1+x^2/2) * (1 + 0.25*exp(-x^2/(2*config.hbar))) - 1 +V = XFunction(V_func) +# using again the harmonic oscillator example from above +H = PMonomial(2)/2 + V +point0 = Point(-0.5, -0.5) +Phi0 = PositionWaveFunction((x::Real) -> exp(-1/2/config.hbar * x^2)) +T = 2 * pi # the oscillation period of the classical oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +# here we need to enlarge the grid, because the wave function now oscillates between -1 and 1. The width of the initial wave function remains roughly 0.03, so we keep the step size as before +rep = PositionRepresentation(range(-0.4, 0.4, step=0.001), config) +# The original wave function must be considered on a larger grid; but we do not need a fine resolution for it +psiRep = PositionRepresentation(range(-1.2, 1.2, step=0.005), config) +systemTunnel0 = QmSystemResidual(point0, Phi0, H, rep, deltaT, psiRepresentation=psiRep) +function transition1(system::QmSystemResidual)::AbstractQmSystem + psi1 = getPsi(system.currentState) + # for simulating the quantum effects we use a slightly higher resolution here + psiRep2 = PositionRepresentation(range(-0.5, 0.5, step=0.0004), config) + systemTunnel2 = QmSystem(psi1, H, psiRep2, deltaT) + return systemTunnel2 +end # transition1 +function transition2(system::QmSystem)::AbstractQmSystem + psiRep2 = representation(system) + # the wave function after splitting into two wave packets + psi3 = getPsi(system) + valuesPsi = values(psi3, psiRep2) + half = Int((length(psiRep2.points)-1)/2) + valuesPsiLeft = [idx <= half ? valuesPsi[idx] : idx == half+1 ? valuesPsi[idx]/2 : 0. + 0*im for idx in 1:length(psiRep2.points)] + valuesPsiRight = [idx > half+1 ? valuesPsi[idx] : idx == half+1 ? valuesPsi[idx]/2 : 0. + 0*im for idx in 1:length(psiRep2.points)] + psi3Left = asWavefunction(valuesPsiLeft, psiRep2) + psi3Right = asWavefunction(valuesPsiRight, psiRep2) + qHat = XPolynomial([0., 1.]) + pHat = PMonomial(1.) + centerLeftQ = expectationValue(psi3Left, qHat, psiRep2) + centerRightQ = expectationValue(psi3Right, qHat, psiRep2) + centerLeftP = expectationValue(psi3Left, pHat, psiRep2) + centerRightP = expectationValue(psi3Right, pHat, psiRep2) + centerLeft = Point(centerLeftQ, centerLeftP) + centerRight = Point(centerRightQ, centerRightP) + PhiLeft = weylTranslate(psi3Left, centerLeft, config.hbar) + # TODO add t0? + systemTunnel3Left = QmSystemResidual(centerLeft, PhiLeft, H, rep, deltaT, psiRepresentation=psiRep) + PhiRight = weylTranslate(psi3Right, centerRight, config.hbar) + systemTunnel3Right = QmSystemResidual(centerRight, PhiRight, H, rep, deltaT, psiRepresentation=psiRep) + return QmSystemSum([systemTunnel3Left, systemTunnel3Right]) +end # transition2 +systemConcat = QmSystemConcat(systemTunnel0, psiRep, [transition1, transition2], [358, 558]) +trace(systemConcat, 900, folder="results/tunneling/concat") + +``` + + +## Scattering + +This example is similar to the [plane wave](#plane-wave) example above, except that now we place a potential spike at the origin. Again, the ordinary Schrödinger equation with Neumann boundary conditions leads to significant artifacts due to boundary reflections: + +```julia +Vfunc = (x::Real, p::Union{Real, Nothing}=nothing) -> x >-1 && x < 1 ? exp(-1/(1-x^2)) : 0. +# only the first derivative is required, therefore we can set all others to 0 +VDiff = (order::Int, x::Real, p::Union{Real, Nothing}=nothing) -> + order > 1 ? 0 : x >-1 && x < 1 ? -2*x/(1-x^2)^2*V(x) : 0. +p = 1. +mass = 1. +hbar = 1. +T = 4 * pi * mass * hbar / p^2 +#V = XFunction(Vfunc, VDiff) +V = XFunction(Vfunc, VDiff) +H = PMonomial(2)/(2*mass) + V + +steps = 1000 +deltaT = T / steps +xPeriod = 2*pi*hbar / p +# Using the midpoint rule for calculating first derivatives, otherwise the method becomes unstable +config = SchroedingerConfig(hbar=hbar, includeIntegralFactor=true, firstDerivativeMethod=0) +xmin = -1 - 8 * xPeriod +xmax = -xmin + +point0 = Point(0., p) +Phi0 = PositionWaveFunction(x -> 1.) +rep = PositionRepresentation(range(xmin, xmax, length=1001), config) + +# For solving the system in the original Schrödinger representation +psi = weylTranslate(Phi0, -point0, hbar) +systemQm = QmSystem(psi, H, rep, deltaT) +trace(systemQm, steps, folder="results/scattering/qm") +``` + +The residual representation does not suffer from the boundary effects, as long as the disturbances from the potential spike do not reach the boundary: + +```julia +# a trajectory at constant speed but staying at the same position all the time +classicalScheme = ExactTrajectory((t::Real) -> point0) +# For solving in the residual scheme over constant trajectory (0, p0) +scheme = ResidualCrankNicolson(classicalScheme=classicalScheme, isTrajectoryHamiltonian=false,) +systemScattering = QmSystemResidual(point0, Phi0, H, rep, deltaT, scheme=scheme, classicalResolutionFactor=1) +trace(systemScattering, steps, folder="results/scattering/qmResidual") +``` + +## Quartic oscillator + +Here we consider a quartic oscillator, with potential + +$$ V(x) = \frac 12 x^2 + \frac{\alpha}{24} x^4. $$ + +```julia +q0 = 0.6 +alpha = 4 +config = SchroedingerConfig(hbar=0.001) +# V(x) = 1/2 x^2 + 1/24 x^4 +H = PMonomial(2)/2 + XPolynomial([0, 0, 1, 0, alpha]) +# starting with a coherent state +point0 = Point(0, q0) +Phi0 = PositionWaveFunction((x::Real) -> exp(-1/2/config.hbar * x^2)) +T = 2 * pi # the oscillation period of the classical oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +# here we need to enlarge the grid, because the wave function now oscillates between -1 and 1. The width of the initial wave function remains roughly 0.03, so we keep the step size as before +#xbound = alpha < 3 ? 0.2 : 0.3 +xbound = 0.2 # ok for one period +rep = PositionRepresentation(range(-xbound, xbound, step=0.001), config) +# The original wave function must be considered on a larger grid; but we do not need a fine resolution for it +psiRep = PositionRepresentation(range(- q0- 0.2, q0 + 0.2, step=0.001), config) +systemResidual0 = QmSystemResidual(point0, Phi0, H, rep, deltaT, psiRepresentation=psiRep, classicalResolutionFactor=100) +# solve both Hamilton's equations and the residual Schrödinger equation and store results in the specified subfolder +# => can be used for visualization later on +trace(systemResidual0, steps, folder="results/quarticOscillator/coherentState " * string(q0) * "QmResidual_" * string(alpha)) +``` + diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..055a7d6 --- /dev/null +++ b/Project.toml @@ -0,0 +1,9 @@ +name = "SchroedingerNumerics" +uuid = "537d3920-04f8-45d5-b939-67e14d5b2f3b" +authors = ["cnoelle <19640096+cnoelle@users.noreply.github.com>"] +version = "0.1.0" + +[deps] +JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" diff --git a/README.md b/README.md new file mode 100644 index 0000000..1fdce72 --- /dev/null +++ b/README.md @@ -0,0 +1,385 @@ +# SchroedingerNumerics + +This package can be used to solve the one-dimensional time-dependent *residual Schrödinger equation*, which is particularly interesting for semi-classical problems. Furthermore, it can be used to solve the original Schrödinger equation, as well as Hamilton's equations for the trajectory of a classical point particle in one dimension. + +The quantum solvers use the Crank-Nicolson method for integrating the Schrödinger equation. + +## Content + +* [Installation](#installation) + * [Install dependencies](#install-dependencies) +* [Usage](#usage) + * [Preparation](#preparation) + * [Basic concepts](#basic-concepts) + * [Systems as simulation containers](#systems-as-simulation-containers) + * [Visualization](#visualization) + * [Classical mechanics](#classical-mechanics) + * [Schrödinger equation](#schrödinger-equation) + * [Residual Schrödinger equation](#residual-schrödinger-equation) + * [Storing to and reading from file](#storing-to-and-reading-from-file) + * [Loading examples](#loading-examples) + +See also [Examples.md](./Examples.md). + +## Installation + +Clone the git repository: + +```shell +git clone git@github.com:cnoelle/schroedinger-numerics.git +``` + +### Install dependencies + +The Julia programming environment is needed: https://julialang.org. Once Julia is installed, the following step needs to be executed once. In a shell, go to this directory and run + +``` +julia +add Pkg +Pkg.instantiate() +``` + +## Usage + +### Preparation + +In a shell, go to the base directory (this dir). Then: + +* type `julia` to enter the Julia shell +* type `]` to activate the Julia package mode +* type `activate .` to activate the present environment +* Hit *Backspace* to leave the package mode +* type `using SchroedingerNumerics` to import the library and make it available in the current shell session + +### Basic concepts + +**Observables** + +The generic type for observables, i.e. real functions of two variables `x` (position) and `p` (momentum) is called `AbstractObservable`. Several sub-interfaces and implementations are provided: + +* `AbstractXFunction`: interface for observables that depend only on `x`. Note that these functions by convention must accept either a single argument, `x`, or two arguments, `x` and `p`. + * `XPolynomial <: AbstractXFunction`: A polynomial in `x`, defined by its set of coefficients `[V_0, ..., V_k]` in the expansion `V(x) = V_0 + V_1 x + ... + 1/k! V_k x^k`. + * `XFunction <: AbstractXFunction`: A generic function `(x,p=nothing) -> f(x)`. The simplest constructor takes only the function itself, but it is also possible to pass a second function for the derivatives of `f`, which is often beneficial if a closed form of the derivatives is known. The signature of the second argument is `(diffOrder::Int, x::Real, p::Union{Real, Nothing}=nothing) -> Real`. + * `SampledXFunction <: AbstractXFunction`: A function defined by a vector of values at specific points. +* `PMonomial`: a monomial in `p`, defined by its power. Note that while no type for general polynomials in `p` is provided, they can be constructed by adding multiple monomials, e.g. `2 * PMonomial(1) + 3 * PMonomial(3)` for the expression `2p + 3p^3`. + +Points in phase space implement the interface `AbstractPoint`, a concrete version is + +```julia +struct Point <: AbstractPoint + q::Real + p::Real +end +``` + +The `function pin(p::AbstractPoint)::Point` creates a concrete point from an abstract one. Observables can be added and multiplied, and they can be evaluated on points: + +```julia +# a harmonic oscillator: +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +point = Point(2, 3) +# alternatively, we can call H(point.q, point.p) +H(point) +``` + +**Configuration** + +Some configuration parameters for the quantum simulation are defined in the class `SchroedingerConfig`. All parameters have a default value. + +* `hbar`: Planck's constant. Default value: `0.001`. +* TODO + +Create an instance: + +```julia +config = SchroedingerConfig(hbar=0.01) +``` + +**Wave functions** + +The generic type for a wave function is called `AbstractWaveFunction`. Note that wave functions are not time-dependent here, they should be thought of as snapshots at a specific instant of time. +Typical implementations include `PointsWaveFunction` and `PositionWaveFunction`, both defined in position space, the first one by means of sampled values at specific grid points, the second one by a function of a single variable `x`. + +```julia +"A wave function defined in position space by its values at a set of fixed points" +struct PointsWaveFunction <: AbstractWaveFunction + "base points in x coordinates" + points::AbstractArray{<:Real, 1} + "values of the wave function at the base points" + values::AbstractArray{<:Complex, 1} +end # PointsWaveFunction + +"A wave function defined in position space by an arbitrary function of one real variable" +struct PositionWaveFunction <: AbstractWaveFunction + func::Function +end # PositionWaveFunction + +``` + +**Representations** + +The generic type of a quantum representation is called `QmRepresentation`. + +Only the position space representation is implemented, in a type `PositionRepresentation`. It contains the grid of points for which the simulation is calculated. Example: `rep = PositionRepresentation(range(-100, 100), config)`, for a grid with step size 1 ranging from `-100` to `100`. + +Representations can be used to map observables to matrix operators and wave functions to an array of values. + +```julia +function asOperator(V::AbstractObservable, representation::QmRepresentation)::Operator + +function values(psi::AbstractWaveFunction, representation::QmRepresentation)::AbstractArray{<:Complex, 1} + +"The inverse function of values(psi, representation)" +function asWavefunction(values::AbstractArray{<:Number, 1}, representation::QmRepresentation; cacheNorm::Bool = true)::AbstractWaveFunction +``` + +Here the `Operator` type is a union including `AbstractArray{<:Number, 2}`, it can act on the values obtained from the wave function. + + +Once a representation is given, we can also calculate the inner product and the norm squared of wave functions, and the expectation value of an observable on a wave function: + +```julia +function innerProduct(psi::AbstractWaveFunction, phi::AbstractWaveFunction, representation::QmRepresentation)::Number + +function norm_sqr(psi::AbstractWaveFunction, representation::QmRepresentation)::Real + +function expectationValue(psi::AbstractWaveFunction, f::AbstractObservable, representation::QmRepresentation)::Real +``` + +### Systems as simulation containers + +The three types `ClassicalSystem, QmSystem, QmSystemResidual` are the main entry points to a simulation. See examples below ([Classical system](#classical-mechanics), [Quantum system](#schrödinger-equation), [Residual quantum system](#residual-schrödinger-equation)). + +In order to record the results at every simulation step the `trace`-function can be used. For example: + +```julia +system0::Union{ClassicalSystem, QmSystem, QmSystemResidual} = + loadSystem("./examples/harmonicOscillator/coherentStateClassical.json") + +# solve the equations of motion for 1000 timesteps and store results +system1 = trace(system0, 1000, folder="./results/mySystem") +``` + +A set of files containing the simulation results will be created in the specified folder. The exact filenames depend on the type of system that was used (classical, quantum, or residual quantum). For a classical system, two files *settings.json* and *points.csv* are created, with the latter containing the classical trajectory and the observables. + +Instead of `trace` there is also a `propagate` method with similar effect, which will also solve the underlying equations of motion (Hamilton, Schrödinger, or both in the residual scheme), but does not record results in files: + +```julia +system1 = propagate(system0, 1000) +``` + +### Visualization + +A simple web app for visualizing the results of the simulations is provided in the *viz* folder. It can be run locally and is also available via Github pages: https://cnoelle.github.io/physics/schroedingerviz/ (sometimes causes issues with Firefox, Chrome/Chromium seems to be better supported). In order to view the results of a simulation run recorded with the `trace` function, upload all the files created in the respective folder and click *Upload*. + +To run the visualization locally in NodeJS, navigate to the *viz* folder in a shell and install the dependencies once: + +```shell +npm install +``` + +To start the app, run + +```shell +npm run start +``` + +This will spin up a development server, and the app can be accessed in the browser at http://localhost:8080. + +You can then upload the files created by a trace operation, see [Systems as simulation containers](#systems-as-simulation-containers) and start the animation. + +TODO: how to run in Docker + +### Classical mechanics + +Here is an example how to integrate Hamilton's equations for the harmonic oscillator. It uses the default symplectic Euler method. + +```julia +# the initial condition for Hamilton's equations, q=1, p=0 +startingPoint = Point(1., 0.) +# the Hamiltonian, a harmonic oscillator with m=1 and \omega=1 +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +T = 2 * pi # the oscillation period of the oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +system0 = ClassicalSystem(startingPoint, H, deltaT) +# here we solve the Hamilton's equations for one full oscillation cycle +system1 = propagate(system0, steps) +# Alternatively, we could have recorded the results using trace, for later visualization: +#system1 = trace(system1, steps, folder="results/harmonicOscillator/classical") +endPoint = system1.currentState +# validate the norm preservation (harmonics oscillator trajectories form a circle for our params) +using LinearAlgebra +E0 = H(startingPoint) +E1 = H(endPoint) +# this one should be pretty small +difference = abs(2*(E1-E0)/(E0+E1)) +pointsDiff = LinearAlgebra.norm_sqr(endPoint - startingPoint) / LinearAlgebra.norm_sqr(startingPoint) +println("Energy deviation after one oscillation cycle: ", difference, ". E0 = ", E0, ", E1 = ", E1) +println("Points deviation after one oscillation cycle: ", pointsDiff) +``` + +In this particular example we can even determine the solutions of Hamilton's equations analytically: `q(t) = cos(t), p(t)=-sin(t)`, hence it is possible to compare the above numerical solution to the known exact one: + +```julia +c = (t::Real) -> Point(cos(t), -sin(t)) +exactScheme = ExactTrajectory(c) +system0Exact = ClassicalSystem(startingPoint, H, deltaT, scheme=exactScheme) +system1Exact = propagate(system0Exact, steps) +endPointExact = system1Exact.currentState +println("Exact propagation end point: ", pin(endPointExact), ", simulated end point: ", endPoint, ", and expected end point=starting point: ", startingPoint) +``` + +### Schrödinger equation + +#### Harmonic oscillator ground state + +**Numerical solution** + +Below is an example how to solve the standard Schrödinger equation in the position representation, again for the harmonic oscillator. This uses the default CrankNicolson integration scheme. + +```julia +config = SchroedingerConfig(hbar=0.001) +# using again the harmonic oscillator example from above +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +# the harmonic oscillator ground state, see e.g. https://en.wikipedia.org/wiki/Quantum_harmonic_oscillator; this is a Gaussian with variance \sqrt{\hbar} +psi0 = PositionWaveFunction(x -> exp(-x^2 / 2/config.hbar)) +# introducing a grid with 401 points +rep = PositionRepresentation(range(-0.2, 0.2, step=0.001), config) +steps = 1000 +T = 4 * pi # the oscillation period of the ground state +deltaT=T/steps # 1000th part of an oscillation period +systemQm0 = QmSystem(psi0, H, rep, deltaT) +# here we solve the Schrödinger equation for one full oscillation cycle and store the results for visualization +systemQm1 = trace(systemQm0, steps, folder="results/harmonicOscillator/groundStateQm") +psi1 = systemQm1.currentState +``` + +**Exact solution** + +Since we also know the exact solution in this case, we can compare it as follows: + +```julia +# the ground state energy is \hbar\omega/2 +psi0Exact = ExactWaveFunction((t::Real, x::Real) -> exp(-x^2 / 2/config.hbar)*exp(-im/2*t)) +systemQm0Exact = QmSystem(psi0Exact, H, rep, deltaT, scheme=ExactPropagation()) +# instead of propagate we could also use trace here, recording the results +systemQm1Exact = propagate(systemQm0Exact, steps) +psi1Exact = systemQm1Exact.currentState +psiDiffEx=norm_sqr(psi1-psi1Exact, rep)/norm_sqr(psi1Exact, rep) +println("The deviation from the exact solution is ", psiDiffEx) +``` + +#### Harmonic oscillator coherent state + +The following example using a coherent state solution for the harmonic oscillator demonstrates the difficulties in integrating the Schrödinger equation for semi-classical wave functions directly. In the example we select our wave function to be concentrated at `(q_0, p_0) = (1, 0)` initially, so in perfect analogy to the classical example above. Furthermore, it is the initial condition of a so-called coherent state, which is known to reproduce exactly the classical trajectory in the time evolution of its expectation values `` and `

`. + +```julia +config = SchroedingerConfig(hbar=0.001) +# using again the harmonic oscillator example from above +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +psi0Coherent = PositionWaveFunction((x::Real) -> exp(-1/2/config.hbar * (x-1)^2)) +T = 2 * pi # the oscillation period of the classical oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +# here we need to enlarge the grid, because the wave function now oscillates between -1 and 1. The width of the initial wave function remains roughly 0.03, so we keep the step size as before +repCoh = PositionRepresentation(range(-1.2, 1.2, step=0.001), config) +systemCoherent0 = QmSystem(psi0Coherent, H, repCoh, deltaT) +systemCoherent1 = trace(systemCoherent0, steps, folder="results/harmonicOscillator/coherentStateQm") +psi1Coherent = systemCoherent1.currentState +# the observables \hat q and \hat p +q = XPolynomial([0, 1]) +p = PMonomial(1) +q0 = expectationValue(psi0Coherent, q, repCoh) +p0 = expectationValue(psi0Coherent, p, repCoh) +q1 = expectationValue(psi1Coherent, q, repCoh) +p1 = expectationValue(psi1Coherent, p, repCoh) +print("After one oscillation period the initial point ($(q0), $(p0)) moved to ($(q1), $(p1))" ) +``` + +We would have expected the points to be equal, but they are not, due to insufficient resolution of our grid. This is an indication of the problems one encounters in the semi-classical value range. + +**Exact solution** + +```julia +psi0Exact = ExactWaveFunction((t::Real, x::Real) -> + exp(-(x-cos(t))^2 / 2/config.hbar)*exp(-im/2*t +im/2/config.hbar*sin(t)*(cos(t)-2x))) +repCohEx = PositionRepresentation(range(-1.2, 1.2, step=0.01), config) +systemQm0Exact = QmSystem(psi0Exact, H, repCohEx, deltaT, scheme=ExactPropagation()) +systemCoherent1 = propagate(systemQm0Exact, steps) +psi1CoherentExact = systemCoherent1.currentState +q1Ex = expectationValue(psi1CoherentExact, q, repCoh) +p1Ex = expectationValue(psi1CoherentExact, p, repCoh) +print("After one oscillation period the initial point ($(q0), $(p0)) moved along the exact trajectory to ($(q1Ex), $(p1Ex))" ) +``` + +### Residual Schrödinger equation + +Finally, again the harmonic oscillator coherent state example, but this time solved in the residual representation. + +#### Harmonic oscillator coherent state + +```julia +config = SchroedingerConfig(hbar=0.001) +# using again the harmonic oscillator example from above +H = PMonomial(2)/2 + XPolynomial([0, 0, 1]) +# the same wave function as in the coherent state example above +psi0 = PositionWaveFunction((x::Real) -> exp(-1/2/config.hbar * (x-1)^2)) +point0 = Point(1, 0) +Phi0 = weylTranslate(psi0, point0, config.hbar) +T = 2 * pi # the oscillation period of the classical oscillator +steps = 1000 +deltaT=T/steps # deltaT = 1000th part of an oscillation period +# here we need to enlarge the grid, because the wave function now oscillates between -1 and 1. The width of the initial wave function remains roughly 0.03, so we keep the step size as before +rep = PositionRepresentation(range(-0.2, 0.2, step=0.001), config) +# The original wave function must be considered on a larger grid; but we do not need a fine resolution for it +psiRep = PositionRepresentation(range(-1.2, 1.2, step=0.01), config) +systemResidual0 = QmSystemResidual(point0, Phi0, H, rep, deltaT, psiRepresentation=psiRep, classicalResolutionFactor=100) +systemResidual1 = trace(systemResidual0, steps, folder="results/harmonicOscillator/coherentStateQmResidual") +point1 = pin(systemResidual1.currentState.point) +Phi1 = systemResidual1.currentState.Phi +psi1 = getPsi(systemResidual1.currentState) +# the observables \hat q and \hat p +q = XPolynomial([0, 1]) +p = PMonomial(1) +q1 = expectationValue(psi1, q, psiRep) +p1 = expectationValue(psi1, p, psiRep) +print("In one classical oscillation period the initial point $(point0) moved along the residual Schrödinger equation to ($(q1), $(p1))" ) + +``` + + +### Storing to and reading from file + +Note: this is about storing a system at one specific timestamp. In order to record the evolution of a system over time see the [`trace` function](#systems-as-simulation-containers) . + +**Store system data** + +```julia +system::ClassicalSystem = ... +store(system, "./someFolder/classicalSystem.json") +``` + +Depending on the type of Hamiltonian it may be necessary to provide a set of base points on which the potential is sampled: `store(system, systemFile, range(-100, 100, step=0.2))`. This is not required for polynomials or sampled `x` functions. If the process involves sampling then it is not lossless. For instance, if the potential is defined by a Julia function: `V = XFunction(x -> tanh(x^2))`, then persisting the potential requires selecting some grid points for sampling and only the corresponding values will be stored and recovered. + +**Load system data** + +```julia +system0::Union{ClassicalSystem, QmSystem, QmSystemResidual} = + loadSystem("./someFolder/classicalSystem.json") +# solve the equations of motion for a single timestep +system1 = propagate(system0, 1) +... +``` + +### Loading examples + +A few examples are provided in the subfolder `./examples`, they can be loaded using the `loadSystem` method. For example: + +```julia +freeGaussianWavePacket = loadSystem("examples/freeParticle/gaussian.json") +trace(freeGaussianWavePacket, 1000, folder="results/freeParticle/wavePacket") +``` + +For a more extensive set of examples developed from scratch see [Examples.md](./Examples.md). + diff --git a/examples/freeParticle/gaussian.json b/examples/freeParticle/gaussian.json new file mode 100644 index 0000000..65b8e79 --- /dev/null +++ b/examples/freeParticle/gaussian.json @@ -0,0 +1,17 @@ +{ + "type": "qm", + "scheme": {"id": "CrankNicolson" }, + "V": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], + "points": [-0.8,-0.799,-0.798,-0.797,-0.796,-0.795,-0.794,-0.793,-0.792,-0.791,-0.79,-0.789,-0.788,-0.787,-0.786,-0.785,-0.784,-0.783,-0.782,-0.781,-0.78,-0.779,-0.778,-0.777,-0.776,-0.775,-0.774,-0.773,-0.772,-0.771,-0.77,-0.769,-0.768,-0.767,-0.766,-0.765,-0.764,-0.763,-0.762,-0.761,-0.76,-0.759,-0.758,-0.757,-0.756,-0.755,-0.754,-0.753,-0.752,-0.751,-0.75,-0.749,-0.748,-0.747,-0.746,-0.745,-0.744,-0.743,-0.742,-0.741,-0.74,-0.739,-0.738,-0.737,-0.736,-0.735,-0.734,-0.733,-0.732,-0.731,-0.73,-0.729,-0.728,-0.727,-0.726,-0.725,-0.724,-0.723,-0.722,-0.721,-0.72,-0.719,-0.718,-0.717,-0.716,-0.715,-0.714,-0.713,-0.712,-0.711,-0.71,-0.709,-0.708,-0.707,-0.706,-0.705,-0.704,-0.703,-0.702,-0.701,-0.7,-0.699,-0.698,-0.697,-0.696,-0.695,-0.694,-0.693,-0.692,-0.691,-0.69,-0.689,-0.688,-0.687,-0.686,-0.685,-0.684,-0.683,-0.682,-0.681,-0.68,-0.679,-0.678,-0.677,-0.676,-0.675,-0.674,-0.673,-0.672,-0.671,-0.67,-0.669,-0.668,-0.667,-0.666,-0.665,-0.664,-0.663,-0.662,-0.661,-0.66,-0.659,-0.658,-0.657,-0.656,-0.655,-0.654,-0.653,-0.652,-0.651,-0.65,-0.649,-0.648,-0.647,-0.646,-0.645,-0.644,-0.643,-0.642,-0.641,-0.64,-0.639,-0.638,-0.637,-0.636,-0.635,-0.634,-0.633,-0.632,-0.631,-0.63,-0.629,-0.628,-0.627,-0.626,-0.625,-0.624,-0.623,-0.622,-0.621,-0.62,-0.619,-0.618,-0.617,-0.616,-0.615,-0.614,-0.613,-0.612,-0.611,-0.61,-0.609,-0.608,-0.607,-0.606,-0.605,-0.604,-0.603,-0.602,-0.601,-0.6,-0.599,-0.598,-0.597,-0.596,-0.595,-0.594,-0.593,-0.592,-0.591,-0.59,-0.589,-0.588,-0.587,-0.586,-0.585,-0.584,-0.583,-0.582,-0.581,-0.58,-0.579,-0.578,-0.577,-0.576,-0.575,-0.574,-0.573,-0.572,-0.571,-0.57,-0.569,-0.568,-0.567,-0.566,-0.565,-0.564,-0.563,-0.562,-0.561,-0.56,-0.559,-0.558,-0.557,-0.556,-0.555,-0.554,-0.553,-0.552,-0.551,-0.55,-0.549,-0.548,-0.547,-0.546,-0.545,-0.544,-0.543,-0.542,-0.541,-0.54,-0.539,-0.538,-0.537,-0.536,-0.535,-0.534,-0.533,-0.532,-0.531,-0.53,-0.529,-0.528,-0.527,-0.526,-0.525,-0.524,-0.523,-0.522,-0.521,-0.52,-0.519,-0.518,-0.517,-0.516,-0.515,-0.514,-0.513,-0.512,-0.511,-0.51,-0.509,-0.508,-0.507,-0.506,-0.505,-0.504,-0.503,-0.502,-0.501,-0.5,-0.499,-0.498,-0.497,-0.496,-0.495,-0.494,-0.493,-0.492,-0.491,-0.49,-0.489,-0.488,-0.487,-0.486,-0.485,-0.484,-0.483,-0.482,-0.481,-0.48,-0.479,-0.478,-0.477,-0.476,-0.475,-0.474,-0.473,-0.472,-0.471,-0.47,-0.469,-0.468,-0.467,-0.466,-0.465,-0.464,-0.463,-0.462,-0.461,-0.46,-0.459,-0.458,-0.457,-0.456,-0.455,-0.454,-0.453,-0.452,-0.451,-0.45,-0.449,-0.448,-0.447,-0.446,-0.445,-0.444,-0.443,-0.442,-0.441,-0.44,-0.439,-0.438,-0.437,-0.436,-0.435,-0.434,-0.433,-0.432,-0.431,-0.43,-0.429,-0.428,-0.427,-0.426,-0.425,-0.424,-0.423,-0.422,-0.421,-0.42,-0.419,-0.418,-0.417,-0.416,-0.415,-0.414,-0.413,-0.412,-0.411,-0.41,-0.409,-0.408,-0.407,-0.406,-0.405,-0.404,-0.403,-0.402,-0.401,-0.4,-0.399,-0.398,-0.397,-0.396,-0.395,-0.394,-0.393,-0.392,-0.391,-0.39,-0.389,-0.388,-0.387,-0.386,-0.385,-0.384,-0.383,-0.382,-0.381,-0.38,-0.379,-0.378,-0.377,-0.376,-0.375,-0.374,-0.373,-0.372,-0.371,-0.37,-0.369,-0.368,-0.367,-0.366,-0.365,-0.364,-0.363,-0.362,-0.361,-0.36,-0.359,-0.358,-0.357,-0.356,-0.355,-0.354,-0.353,-0.352,-0.351,-0.35,-0.349,-0.348,-0.347,-0.346,-0.345,-0.344,-0.343,-0.342,-0.341,-0.34,-0.339,-0.338,-0.337,-0.336,-0.335,-0.334,-0.333,-0.332,-0.331,-0.33,-0.329,-0.328,-0.327,-0.326,-0.325,-0.324,-0.323,-0.322,-0.321,-0.32,-0.319,-0.318,-0.317,-0.316,-0.315,-0.314,-0.313,-0.312,-0.311,-0.31,-0.309,-0.308,-0.307,-0.306,-0.305,-0.304,-0.303,-0.302,-0.301,-0.3,-0.299,-0.298,-0.297,-0.296,-0.295,-0.294,-0.293,-0.292,-0.291,-0.29,-0.289,-0.288,-0.287,-0.286,-0.285,-0.284,-0.283,-0.282,-0.281,-0.28,-0.279,-0.278,-0.277,-0.276,-0.275,-0.274,-0.273,-0.272,-0.271,-0.27,-0.269,-0.268,-0.267,-0.266,-0.265,-0.264,-0.263,-0.262,-0.261,-0.26,-0.259,-0.258,-0.257,-0.256,-0.255,-0.254,-0.253,-0.252,-0.251,-0.25,-0.249,-0.248,-0.247,-0.246,-0.245,-0.244,-0.243,-0.242,-0.241,-0.24,-0.239,-0.238,-0.237,-0.236,-0.235,-0.234,-0.233,-0.232,-0.231,-0.23,-0.229,-0.228,-0.227,-0.226,-0.225,-0.224,-0.223,-0.222,-0.221,-0.22,-0.219,-0.218,-0.217,-0.216,-0.215,-0.214,-0.213,-0.212,-0.211,-0.21,-0.209,-0.208,-0.207,-0.206,-0.205,-0.204,-0.203,-0.202,-0.201,-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2,0.201,0.202,0.203,0.204,0.205,0.206,0.207,0.208,0.209,0.21,0.211,0.212,0.213,0.214,0.215,0.216,0.217,0.218,0.219,0.22,0.221,0.222,0.223,0.224,0.225,0.226,0.227,0.228,0.229,0.23,0.231,0.232,0.233,0.234,0.235,0.236,0.237,0.238,0.239,0.24,0.241,0.242,0.243,0.244,0.245,0.246,0.247,0.248,0.249,0.25,0.251,0.252,0.253,0.254,0.255,0.256,0.257,0.258,0.259,0.26,0.261,0.262,0.263,0.264,0.265,0.266,0.267,0.268,0.269,0.27,0.271,0.272,0.273,0.274,0.275,0.276,0.277,0.278,0.279,0.28,0.281,0.282,0.283,0.284,0.285,0.286,0.287,0.288,0.289,0.29,0.291,0.292,0.293,0.294,0.295,0.296,0.297,0.298,0.299,0.3,0.301,0.302,0.303,0.304,0.305,0.306,0.307,0.308,0.309,0.31,0.311,0.312,0.313,0.314,0.315,0.316,0.317,0.318,0.319,0.32,0.321,0.322,0.323,0.324,0.325,0.326,0.327,0.328,0.329,0.33,0.331,0.332,0.333,0.334,0.335,0.336,0.337,0.338,0.339,0.34,0.341,0.342,0.343,0.344,0.345,0.346,0.347,0.348,0.349,0.35,0.351,0.352,0.353,0.354,0.355,0.356,0.357,0.358,0.359,0.36,0.361,0.362,0.363,0.364,0.365,0.366,0.367,0.368,0.369,0.37,0.371,0.372,0.373,0.374,0.375,0.376,0.377,0.378,0.379,0.38,0.381,0.382,0.383,0.384,0.385,0.386,0.387,0.388,0.389,0.39,0.391,0.392,0.393,0.394,0.395,0.396,0.397,0.398,0.399,0.4,0.401,0.402,0.403,0.404,0.405,0.406,0.407,0.408,0.409,0.41,0.411,0.412,0.413,0.414,0.415,0.416,0.417,0.418,0.419,0.42,0.421,0.422,0.423,0.424,0.425,0.426,0.427,0.428,0.429,0.43,0.431,0.432,0.433,0.434,0.435,0.436,0.437,0.438,0.439,0.44,0.441,0.442,0.443,0.444,0.445,0.446,0.447,0.448,0.449,0.45,0.451,0.452,0.453,0.454,0.455,0.456,0.457,0.458,0.459,0.46,0.461,0.462,0.463,0.464,0.465,0.466,0.467,0.468,0.469,0.47,0.471,0.472,0.473,0.474,0.475,0.476,0.477,0.478,0.479,0.48,0.481,0.482,0.483,0.484,0.485,0.486,0.487,0.488,0.489,0.49,0.491,0.492,0.493,0.494,0.495,0.496,0.497,0.498,0.499,0.5,0.501,0.502,0.503,0.504,0.505,0.506,0.507,0.508,0.509,0.51,0.511,0.512,0.513,0.514,0.515,0.516,0.517,0.518,0.519,0.52,0.521,0.522,0.523,0.524,0.525,0.526,0.527,0.528,0.529,0.53,0.531,0.532,0.533,0.534,0.535,0.536,0.537,0.538,0.539,0.54,0.541,0.542,0.543,0.544,0.545,0.546,0.547,0.548,0.549,0.55,0.551,0.552,0.553,0.554,0.555,0.556,0.557,0.558,0.559,0.56,0.561,0.562,0.563,0.564,0.565,0.566,0.567,0.568,0.569,0.57,0.571,0.572,0.573,0.574,0.575,0.576,0.577,0.578,0.579,0.58,0.581,0.582,0.583,0.584,0.585,0.586,0.587,0.588,0.589,0.59,0.591,0.592,0.593,0.594,0.595,0.596,0.597,0.598,0.599,0.6,0.601,0.602,0.603,0.604,0.605,0.606,0.607,0.608,0.609,0.61,0.611,0.612,0.613,0.614,0.615,0.616,0.617,0.618,0.619,0.62,0.621,0.622,0.623,0.624,0.625,0.626,0.627,0.628,0.629,0.63,0.631,0.632,0.633,0.634,0.635,0.636,0.637,0.638,0.639,0.64,0.641,0.642,0.643,0.644,0.645,0.646,0.647,0.648,0.649,0.65,0.651,0.652,0.653,0.654,0.655,0.656,0.657,0.658,0.659,0.66,0.661,0.662,0.663,0.664,0.665,0.666,0.667,0.668,0.669,0.67,0.671,0.672,0.673,0.674,0.675,0.676,0.677,0.678,0.679,0.68,0.681,0.682,0.683,0.684,0.685,0.686,0.687,0.688,0.689,0.69,0.691,0.692,0.693,0.694,0.695,0.696,0.697,0.698,0.699,0.7,0.701,0.702,0.703,0.704,0.705,0.706,0.707,0.708,0.709,0.71,0.711,0.712,0.713,0.714,0.715,0.716,0.717,0.718,0.719,0.72,0.721,0.722,0.723,0.724,0.725,0.726,0.727,0.728,0.729,0.73,0.731,0.732,0.733,0.734,0.735,0.736,0.737,0.738,0.739,0.74,0.741,0.742,0.743,0.744,0.745,0.746,0.747,0.748,0.749,0.75,0.751,0.752,0.753,0.754,0.755,0.756,0.757,0.758,0.759,0.76,0.761,0.762,0.763,0.764,0.765,0.766,0.767,0.768,0.769,0.77,0.771,0.772,0.773,0.774,0.775,0.776,0.777,0.778,0.779,0.78,0.781,0.782,0.783,0.784,0.785,0.786,0.787,0.788,0.789,0.79,0.791,0.792,0.793,0.794,0.795,0.796,0.797,0.798,0.799,0.8], + "mass": 1.0, + "deltaT": 0.012566370614359173, + "t": 0.0, + "config": {"hbar": 0.001, "includeIntegralFactor": true, "firstDerivativeMethod": 1, "limitDiffOrder":10}, + "representation": {"type": "PositionRepresentation", "points": {"first": -0.8, "step": 0.001, "last": 0.8}}, + "psi": { + "points": [-0.8,-0.799,-0.798,-0.797,-0.796,-0.795,-0.794,-0.793,-0.792,-0.791,-0.79,-0.789,-0.788,-0.787,-0.786,-0.785,-0.784,-0.783,-0.782,-0.781,-0.78,-0.779,-0.778,-0.777,-0.776,-0.775,-0.774,-0.773,-0.772,-0.771,-0.77,-0.769,-0.768,-0.767,-0.766,-0.765,-0.764,-0.763,-0.762,-0.761,-0.76,-0.759,-0.758,-0.757,-0.756,-0.755,-0.754,-0.753,-0.752,-0.751,-0.75,-0.749,-0.748,-0.747,-0.746,-0.745,-0.744,-0.743,-0.742,-0.741,-0.74,-0.739,-0.738,-0.737,-0.736,-0.735,-0.734,-0.733,-0.732,-0.731,-0.73,-0.729,-0.728,-0.727,-0.726,-0.725,-0.724,-0.723,-0.722,-0.721,-0.72,-0.719,-0.718,-0.717,-0.716,-0.715,-0.714,-0.713,-0.712,-0.711,-0.71,-0.709,-0.708,-0.707,-0.706,-0.705,-0.704,-0.703,-0.702,-0.701,-0.7,-0.699,-0.698,-0.697,-0.696,-0.695,-0.694,-0.693,-0.692,-0.691,-0.69,-0.689,-0.688,-0.687,-0.686,-0.685,-0.684,-0.683,-0.682,-0.681,-0.68,-0.679,-0.678,-0.677,-0.676,-0.675,-0.674,-0.673,-0.672,-0.671,-0.67,-0.669,-0.668,-0.667,-0.666,-0.665,-0.664,-0.663,-0.662,-0.661,-0.66,-0.659,-0.658,-0.657,-0.656,-0.655,-0.654,-0.653,-0.652,-0.651,-0.65,-0.649,-0.648,-0.647,-0.646,-0.645,-0.644,-0.643,-0.642,-0.641,-0.64,-0.639,-0.638,-0.637,-0.636,-0.635,-0.634,-0.633,-0.632,-0.631,-0.63,-0.629,-0.628,-0.627,-0.626,-0.625,-0.624,-0.623,-0.622,-0.621,-0.62,-0.619,-0.618,-0.617,-0.616,-0.615,-0.614,-0.613,-0.612,-0.611,-0.61,-0.609,-0.608,-0.607,-0.606,-0.605,-0.604,-0.603,-0.602,-0.601,-0.6,-0.599,-0.598,-0.597,-0.596,-0.595,-0.594,-0.593,-0.592,-0.591,-0.59,-0.589,-0.588,-0.587,-0.586,-0.585,-0.584,-0.583,-0.582,-0.581,-0.58,-0.579,-0.578,-0.577,-0.576,-0.575,-0.574,-0.573,-0.572,-0.571,-0.57,-0.569,-0.568,-0.567,-0.566,-0.565,-0.564,-0.563,-0.562,-0.561,-0.56,-0.559,-0.558,-0.557,-0.556,-0.555,-0.554,-0.553,-0.552,-0.551,-0.55,-0.549,-0.548,-0.547,-0.546,-0.545,-0.544,-0.543,-0.542,-0.541,-0.54,-0.539,-0.538,-0.537,-0.536,-0.535,-0.534,-0.533,-0.532,-0.531,-0.53,-0.529,-0.528,-0.527,-0.526,-0.525,-0.524,-0.523,-0.522,-0.521,-0.52,-0.519,-0.518,-0.517,-0.516,-0.515,-0.514,-0.513,-0.512,-0.511,-0.51,-0.509,-0.508,-0.507,-0.506,-0.505,-0.504,-0.503,-0.502,-0.501,-0.5,-0.499,-0.498,-0.497,-0.496,-0.495,-0.494,-0.493,-0.492,-0.491,-0.49,-0.489,-0.488,-0.487,-0.486,-0.485,-0.484,-0.483,-0.482,-0.481,-0.48,-0.479,-0.478,-0.477,-0.476,-0.475,-0.474,-0.473,-0.472,-0.471,-0.47,-0.469,-0.468,-0.467,-0.466,-0.465,-0.464,-0.463,-0.462,-0.461,-0.46,-0.459,-0.458,-0.457,-0.456,-0.455,-0.454,-0.453,-0.452,-0.451,-0.45,-0.449,-0.448,-0.447,-0.446,-0.445,-0.444,-0.443,-0.442,-0.441,-0.44,-0.439,-0.438,-0.437,-0.436,-0.435,-0.434,-0.433,-0.432,-0.431,-0.43,-0.429,-0.428,-0.427,-0.426,-0.425,-0.424,-0.423,-0.422,-0.421,-0.42,-0.419,-0.418,-0.417,-0.416,-0.415,-0.414,-0.413,-0.412,-0.411,-0.41,-0.409,-0.408,-0.407,-0.406,-0.405,-0.404,-0.403,-0.402,-0.401,-0.4,-0.399,-0.398,-0.397,-0.396,-0.395,-0.394,-0.393,-0.392,-0.391,-0.39,-0.389,-0.388,-0.387,-0.386,-0.385,-0.384,-0.383,-0.382,-0.381,-0.38,-0.379,-0.378,-0.377,-0.376,-0.375,-0.374,-0.373,-0.372,-0.371,-0.37,-0.369,-0.368,-0.367,-0.366,-0.365,-0.364,-0.363,-0.362,-0.361,-0.36,-0.359,-0.358,-0.357,-0.356,-0.355,-0.354,-0.353,-0.352,-0.351,-0.35,-0.349,-0.348,-0.347,-0.346,-0.345,-0.344,-0.343,-0.342,-0.341,-0.34,-0.339,-0.338,-0.337,-0.336,-0.335,-0.334,-0.333,-0.332,-0.331,-0.33,-0.329,-0.328,-0.327,-0.326,-0.325,-0.324,-0.323,-0.322,-0.321,-0.32,-0.319,-0.318,-0.317,-0.316,-0.315,-0.314,-0.313,-0.312,-0.311,-0.31,-0.309,-0.308,-0.307,-0.306,-0.305,-0.304,-0.303,-0.302,-0.301,-0.3,-0.299,-0.298,-0.297,-0.296,-0.295,-0.294,-0.293,-0.292,-0.291,-0.29,-0.289,-0.288,-0.287,-0.286,-0.285,-0.284,-0.283,-0.282,-0.281,-0.28,-0.279,-0.278,-0.277,-0.276,-0.275,-0.274,-0.273,-0.272,-0.271,-0.27,-0.269,-0.268,-0.267,-0.266,-0.265,-0.264,-0.263,-0.262,-0.261,-0.26,-0.259,-0.258,-0.257,-0.256,-0.255,-0.254,-0.253,-0.252,-0.251,-0.25,-0.249,-0.248,-0.247,-0.246,-0.245,-0.244,-0.243,-0.242,-0.241,-0.24,-0.239,-0.238,-0.237,-0.236,-0.235,-0.234,-0.233,-0.232,-0.231,-0.23,-0.229,-0.228,-0.227,-0.226,-0.225,-0.224,-0.223,-0.222,-0.221,-0.22,-0.219,-0.218,-0.217,-0.216,-0.215,-0.214,-0.213,-0.212,-0.211,-0.21,-0.209,-0.208,-0.207,-0.206,-0.205,-0.204,-0.203,-0.202,-0.201,-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2,0.201,0.202,0.203,0.204,0.205,0.206,0.207,0.208,0.209,0.21,0.211,0.212,0.213,0.214,0.215,0.216,0.217,0.218,0.219,0.22,0.221,0.222,0.223,0.224,0.225,0.226,0.227,0.228,0.229,0.23,0.231,0.232,0.233,0.234,0.235,0.236,0.237,0.238,0.239,0.24,0.241,0.242,0.243,0.244,0.245,0.246,0.247,0.248,0.249,0.25,0.251,0.252,0.253,0.254,0.255,0.256,0.257,0.258,0.259,0.26,0.261,0.262,0.263,0.264,0.265,0.266,0.267,0.268,0.269,0.27,0.271,0.272,0.273,0.274,0.275,0.276,0.277,0.278,0.279,0.28,0.281,0.282,0.283,0.284,0.285,0.286,0.287,0.288,0.289,0.29,0.291,0.292,0.293,0.294,0.295,0.296,0.297,0.298,0.299,0.3,0.301,0.302,0.303,0.304,0.305,0.306,0.307,0.308,0.309,0.31,0.311,0.312,0.313,0.314,0.315,0.316,0.317,0.318,0.319,0.32,0.321,0.322,0.323,0.324,0.325,0.326,0.327,0.328,0.329,0.33,0.331,0.332,0.333,0.334,0.335,0.336,0.337,0.338,0.339,0.34,0.341,0.342,0.343,0.344,0.345,0.346,0.347,0.348,0.349,0.35,0.351,0.352,0.353,0.354,0.355,0.356,0.357,0.358,0.359,0.36,0.361,0.362,0.363,0.364,0.365,0.366,0.367,0.368,0.369,0.37,0.371,0.372,0.373,0.374,0.375,0.376,0.377,0.378,0.379,0.38,0.381,0.382,0.383,0.384,0.385,0.386,0.387,0.388,0.389,0.39,0.391,0.392,0.393,0.394,0.395,0.396,0.397,0.398,0.399,0.4,0.401,0.402,0.403,0.404,0.405,0.406,0.407,0.408,0.409,0.41,0.411,0.412,0.413,0.414,0.415,0.416,0.417,0.418,0.419,0.42,0.421,0.422,0.423,0.424,0.425,0.426,0.427,0.428,0.429,0.43,0.431,0.432,0.433,0.434,0.435,0.436,0.437,0.438,0.439,0.44,0.441,0.442,0.443,0.444,0.445,0.446,0.447,0.448,0.449,0.45,0.451,0.452,0.453,0.454,0.455,0.456,0.457,0.458,0.459,0.46,0.461,0.462,0.463,0.464,0.465,0.466,0.467,0.468,0.469,0.47,0.471,0.472,0.473,0.474,0.475,0.476,0.477,0.478,0.479,0.48,0.481,0.482,0.483,0.484,0.485,0.486,0.487,0.488,0.489,0.49,0.491,0.492,0.493,0.494,0.495,0.496,0.497,0.498,0.499,0.5,0.501,0.502,0.503,0.504,0.505,0.506,0.507,0.508,0.509,0.51,0.511,0.512,0.513,0.514,0.515,0.516,0.517,0.518,0.519,0.52,0.521,0.522,0.523,0.524,0.525,0.526,0.527,0.528,0.529,0.53,0.531,0.532,0.533,0.534,0.535,0.536,0.537,0.538,0.539,0.54,0.541,0.542,0.543,0.544,0.545,0.546,0.547,0.548,0.549,0.55,0.551,0.552,0.553,0.554,0.555,0.556,0.557,0.558,0.559,0.56,0.561,0.562,0.563,0.564,0.565,0.566,0.567,0.568,0.569,0.57,0.571,0.572,0.573,0.574,0.575,0.576,0.577,0.578,0.579,0.58,0.581,0.582,0.583,0.584,0.585,0.586,0.587,0.588,0.589,0.59,0.591,0.592,0.593,0.594,0.595,0.596,0.597,0.598,0.599,0.6,0.601,0.602,0.603,0.604,0.605,0.606,0.607,0.608,0.609,0.61,0.611,0.612,0.613,0.614,0.615,0.616,0.617,0.618,0.619,0.62,0.621,0.622,0.623,0.624,0.625,0.626,0.627,0.628,0.629,0.63,0.631,0.632,0.633,0.634,0.635,0.636,0.637,0.638,0.639,0.64,0.641,0.642,0.643,0.644,0.645,0.646,0.647,0.648,0.649,0.65,0.651,0.652,0.653,0.654,0.655,0.656,0.657,0.658,0.659,0.66,0.661,0.662,0.663,0.664,0.665,0.666,0.667,0.668,0.669,0.67,0.671,0.672,0.673,0.674,0.675,0.676,0.677,0.678,0.679,0.68,0.681,0.682,0.683,0.684,0.685,0.686,0.687,0.688,0.689,0.69,0.691,0.692,0.693,0.694,0.695,0.696,0.697,0.698,0.699,0.7,0.701,0.702,0.703,0.704,0.705,0.706,0.707,0.708,0.709,0.71,0.711,0.712,0.713,0.714,0.715,0.716,0.717,0.718,0.719,0.72,0.721,0.722,0.723,0.724,0.725,0.726,0.727,0.728,0.729,0.73,0.731,0.732,0.733,0.734,0.735,0.736,0.737,0.738,0.739,0.74,0.741,0.742,0.743,0.744,0.745,0.746,0.747,0.748,0.749,0.75,0.751,0.752,0.753,0.754,0.755,0.756,0.757,0.758,0.759,0.76,0.761,0.762,0.763,0.764,0.765,0.766,0.767,0.768,0.769,0.77,0.771,0.772,0.773,0.774,0.775,0.776,0.777,0.778,0.779,0.78,0.781,0.782,0.783,0.784,0.785,0.786,0.787,0.788,0.789,0.79,0.791,0.792,0.793,0.794,0.795,0.796,0.797,0.798,0.799,0.8], + "real": [1.0611231537462908e-139,2.3603925174764465e-139,5.245276336559158e-139,1.164442967489197e-138,2.5824610333817212e-138,5.721567653719609e-138,1.266374052489056e-137,2.8001073064647562e-137,6.185190094812883e-137,1.364888372889789e-136,3.0088942341314604e-136,6.62647273765158e-136,1.4578861646930437e-135,3.204280442340767e-135,7.035632219041899e-135,1.5432683322371144e-134,3.381780889772396e-134,7.403126871785171e-134,1.6190140748580427e-133,3.537136028507449e-133,7.720023192237626e-133,1.683259807940478e-132,3.666480738687979e-132,7.97835520227533e-132,1.7343751114636022e-131,3.7665037436629926e-131,8.171456623088348e-131,1.771031400861482e-130,3.834588351744406e-130,8.294246562734797e-130,1.792259288325748e-129,3.868926182171023e-129,8.34345163810283e-129,1.7974911790146005e-128,3.868596977664953e-128,8.317750978754201e-128,1.7865864897071797e-127,3.833609586867529e-127,8.217835146786753e-127,1.759837925894444e-126,3.764901569118742e-126,8.04637530414115e-126,1.7179584260947477e-125,3.6642974462270196e-125,7.807904548914741e-125,1.6620495862245283e-124,3.5344281960640372e-124,7.508618778827979e-124,1.5935535160343384e-123,3.378616946293087e-123,7.156109291711506e-123,1.5141910641060698e-122,3.200737798538324e-122,6.75904322499322e-122,1.425890102824819e-121,3.0050561468230967e-121,6.326810585835376e-121,1.3307080370769246e-120,2.796059653055709e-120,5.8691578647788316e-120,1.2307528635097376e-119,2.578289169271099e-119,5.395828021136882e-119,1.1281069622809019e-118,2.3561783736410964e-118,4.916225067466307e-118,1.024757378125161e-117,2.133909792229038e-117,4.439118764598805e-117,9.225356925630352e-117,1.9152933328195318e-116,3.9724013556304896e-116,8.230697708237948e-116,1.7036716127542782e-115,3.5229041579341887e-115,7.2774876113593695e-115,1.5018543851238501e-114,3.0962775551987292e-114,6.3770180723675784e-114,1.3120824195491827e-113,2.696933827677159e-113,5.53790077974594e-113,1.1360194201247952e-112,2.328048621867829e-112,4.766109793969954e-112,9.74769079415443e-112,1.991613914468042e-111,4.065128372041242e-111,8.289132523350869e-111,1.6885332105914376e-110,3.4361794505522245e-110,6.985665259581456e-110,1.4187484877600835e-109,2.8785167276375615e-109,5.8344216086921955e-109,1.1813880294849498e-108,2.389753071775236e-108,4.829244529683176e-108,9.749246922969946e-108,1.966204334320149e-107,3.9614295213417946e-107,7.973351751344742e-107,1.6032292193245195e-106,3.2204459938403463e-106,6.462523378357862e-106,1.2955492861036534e-105,2.5946062328075976e-105,5.191043643670399e-105,1.0375370376038381e-104,2.0716588670349632e-104,4.132364128393191e-104,8.234640202191164e-104,1.6392922247143835e-103,3.260121870884224e-103,6.477046234195058e-103,1.2855407994207314e-102,2.5489448402334042e-102,5.048945882663486e-102,9.990948023373804e-102,1.9750513389070897e-101,3.9004596002045173e-101,7.695181797351578e-101,1.5166581052740366e-100,2.986222764767726e-100,5.873844145041218e-100,1.1542193250659967e-99,2.265791636841681e-99,4.443419361045004e-99,8.705231845009533e-99,1.7037626237913177e-98,3.331221699433918e-98,6.506743583076161e-98,1.2696661862173374e-97,2.4750337206240986e-97,4.81990404612984e-97,9.376945032045818e-97,1.8224266322334955e-96,3.5383797599017644e-96,6.863166522433561e-96,1.329873512641931e-95,2.5743159142051835e-95,4.978276936276906e-95,9.617494987264396e-95,1.856139403968579e-94,3.5786969060948957e-94,6.892947182843259e-94,1.326327239733728e-93,2.5495417788283806e-93,4.895976025503147e-93,9.392520193711107e-93,1.800075404569458e-92,3.4463943047331014e-92,6.591813863302463e-92,1.2595360797099625e-91,2.4042631220661123e-91,4.5847861456848984e-91,8.734174746333978e-91,1.6622271661006572e-90,3.160272852073358e-90,6.002393878844099e-90,1.1389118357060604e-89,2.15884482731646e-89,4.0880712281692506e-89,7.733590752953963e-89,1.4615363595131158e-88,2.759330791485219e-88,5.204315490748091e-88,9.805938617053889e-88,1.8457821006861264e-87,3.4708623900815556e-87,6.520187221510919e-87,1.223625284968177e-86,2.2940481258278325e-86,4.296574157013102e-86,8.039106920553505e-86,1.5026540397883717e-85,2.8059240224436676e-85,5.234298871952674e-85,9.75454084704156e-85,1.8160209409991771e-84,3.3775405999812994e-84,6.275466416007976e-84,1.1648155152923516e-83,2.159901715345179e-83,4.001073573587828e-83,7.404313372006404e-83,1.3688591086827e-82,2.5281242522996897e-82,4.6644859043355185e-82,8.597552979570069e-82,1.5831120037748048e-81,2.912152599155926e-81,5.351583682463348e-81,9.824630338994893e-81,1.8018383324206884e-80,3.3012706490349188e-80,6.042437194147352e-80,1.1048641061305512e-79,2.0182329402824727e-79,3.6829805135442004e-79,6.714184288211594e-79,1.22279259291269e-78,2.22473376779541e-78,4.0436075584570405e-78,7.34219066291586e-78,1.3318276349331359e-77,2.4134376949094467e-77,4.369078688898636e-77,7.901496410148077e-77,1.4275605344202143e-76,2.5765906396728972e-76,4.645816176280437e-76,8.368436488145923e-76,1.505886821087695e-75,2.7071108916061756e-75,4.861669874890641e-75,8.722291364435312e-75,1.5632967326411662e-74,2.7990970458842988e-74,5.006799464711466e-74,8.946808545141198e-74,1.5971356219323755e-73,2.848269989001125e-73,5.074417746363769e-73,9.03143968761754e-73,1.6058074201023938e-72,2.8523028785724646e-72,5.061316845418397e-72,8.972162205477011e-72,1.588899443352958e-71,2.811003684247604e-71,4.968120514937853e-71,8.771796246540036e-71,1.5472149520062127e-70,2.7263303466327176e-70,4.7992349009963084e-70,8.439782259040792e-70,1.482709884522689e-69,2.602236887752464e-69,4.5625031831684467e-69,7.991443578311751e-69,1.398340705847158e-68,2.444367317506248e-68,4.268601788406172e-68,7.446814250801847e-68,1.2978398526705579e-67,2.259630333372411e-67,3.930242900055228e-67,6.829156936471596e-67,1.1854425177833202e-66,2.055699414243779e-66,3.561266135266247e-66,6.163323354140786e-66,1.0655925661967488e-65,1.8404885351489542e-65,3.175709413194699e-65,5.474117330943129e-65,9.426558187592811e-65,1.6216529225308025e-64,2.7869448266390432e-64,4.7848082531684535e-64,8.206659440951944e-64,1.4061575725514113e-63,2.4069511379721528e-63,4.1159137322320165e-63,7.031224400813443e-63,1.199945051862329e-62,2.0457731072970513e-62,3.4843299735607634e-62,5.928526890046399e-62,1.0077203218182182e-61,1.7111928024524956e-61,2.902843206220607e-61,4.919420173461512e-61,8.328560837430633e-61,1.4086130666758972e-60,2.3800121188941e-60,4.0172821007799504e-60,6.774093652871721e-60,1.1411316969919425e-59,1.9203750137882758e-59,3.2285092127455378e-59,5.422302206694305e-59,9.097689558799636e-59,1.5249100026385019e-58,2.5534244853097604e-58,4.271373309381595e-58,7.138019762199148e-58,1.1916635840467523e-57,1.9874458078034284e-57,3.311331255947733e-57,5.511574307863163e-57,9.164618921438996e-57,1.5223652450197602e-56,2.5263238128761693e-56,4.188175542267686e-56,6.936277224894154e-56,1.147608388467308e-55,1.896822494101458e-55,3.1320261101645413e-55,5.166420632837861e-55,8.513729661519419e-55,1.4015727818629223e-54,2.3050330659919683e-54,3.787079045962578e-54,6.215803631041029e-54,1.0191917678005994e-53,1.6694762069277811e-53,2.7319343972057713e-53,4.4660749189684045e-53,7.293692464440711e-53,1.189966119476966e-52,1.9394895806315456e-52,3.157955535221233e-52,5.136771841129314e-52,8.347189001773146e-52,1.3550518817273488e-51,2.1975426145950051e-51,3.5602819554483226e-51,5.762317529716718e-51,9.31699118824694e-51,1.5049424371105486e-50,2.428453535707831e-50,3.9147624460235043e-50,6.304443168789515e-50,1.014270420713244e-49,1.6301459598146663e-49,2.6173688480711924e-49,4.198257493527248e-49,6.727270953307621e-49,1.0768977604396345e-48,1.7221688636533958e-48,2.751330089656034e-48,4.391120631800023e-48,7.001220308967917e-48,1.1151616485924562e-47,1.7744657127603565e-47,2.820740307027492e-47,4.479445967094649e-47,7.106425471137004e-47,1.126273367436048e-46,1.783208514152264e-46,2.820500292001311e-46,4.456725384886305e-46,7.0351166916366e-46,1.1094109344035213e-45,1.7477498922024384e-45,2.7506278225520885e-45,4.324641231687153e-45,6.792568756843043e-45,1.065819611814323e-44,1.6707023247078499e-44,2.616255486177179e-44,4.092860407454631e-44,6.396456030373832e-44,9.986598974843636e-44,1.5576199742735253e-43,2.4270074557542443e-43,3.777864862090005e-43,5.874723521448935e-43,9.126287621727244e-43,1.416336921314365e-42,2.1958602995411638e-42,3.401014963497178e-42,5.262330059470764e-42,8.13417161509699e-42,1.2560712733777698e-41,1.9376750232689842e-41,2.986161587697738e-41,4.59739028316497e-41,7.070907371452675e-41,1.0864372010800405e-40,1.6676304385425774e-40,2.5571764990599964e-40,3.917304225924761e-40,5.9948676994976285e-40,9.165108500221327e-40,1.3997849627215599e-39,2.1357516097542594e-39,3.255411298837604e-39,4.9570887694092454e-39,7.540727228467494e-39,1.1459494802550252e-38,1.7397362717407126e-38,2.638560580418412e-38,3.9977573195524367e-38,6.051060426395873e-38,9.149813840443645e-38,1.3821613101436096e-37,2.085791586055619e-37,3.1444797047653166e-37,4.735789457265777e-37,7.1252758470426834e-37,1.0709684662829915e-36,1.6081160648509705e-36,2.4122582640624812e-36,3.614896945681192e-36,5.411700386319788e-36,8.093516813403859e-36,1.209223302558629e-35,1.8048513878453896e-35,2.69117595153109e-35,4.008745120417611e-35,5.965412787758881e-35,8.86825684793637e-35,1.3170483861997544e-34,1.954028544586258e-34,2.8961815480360437e-34,4.288311912012338e-34,6.343262092756452e-34,9.37356189101052e-34,1.3837650328134295e-33,2.0407309832662094e-33,3.0065945778781195e-33,4.425167225430208e-33,6.506541586875531e-33,9.557326840839284e-33,1.4024531816775815e-32,2.0559190532067264e-32,3.01085164057414e-32,4.4049238664938293e-32,6.438032466483551e-32,9.40012489424457e-32,1.3711336546588905e-31,1.9979824228502428e-31,2.908501158882566e-31,4.229728822365796e-31,6.144994714057436e-31,8.91859018253701e-31,1.2931133881823633e-30,1.8730212893122038e-30,2.7102822745595387e-30,3.9178882222261096e-30,5.6578999501424246e-30,8.162518734745172e-30,1.1764103160493386e-29,1.693788433624625e-29,2.4362688200739486e-29,3.5007166225158424e-29,5.0252122749665084e-29,7.206386860901402e-29,1.0323962988226507e-28,1.4775460005142883e-28,2.1125222311883924e-28,3.0173609865056806e-28,4.305454054873446e-28,6.137285870734339e-28,8.739758903134928e-28,1.2433352802103817e-27,1.7670252992065744e-27,2.5087823372704526e-27,3.5583519804461035e-27,5.041973187085947e-27,7.13703561978753e-27,1.0092549827747071e-26,1.4257705691451965e-26,2.0121673361609085e-26,2.8369014500581107e-26,3.9956745672595413e-26,5.622140244567847e-26,7.902762784127537e-26,1.1097417436229193e-25,1.5567920485110108e-25,2.1817500388130056e-25,3.054534857369281e-25,4.272193197849987e-25,5.969286015454393e-25,8.332198316061588e-25,1.1618833101820788e-24,1.6185686865073693e-24,2.2525034268586583e-24,3.1315942873576345e-24,4.349418821218209e-24,6.034797090462571e-24,8.364882032735935e-24,1.1583043157259795e-23,1.602327306359053e-23,2.214346085379256e-23,3.0570706051477833e-23,4.216296511689076e-23,5.809282904332702e-23,7.996125715898559e-23,1.0995181582344653e-22,1.510396268500848e-22,2.0727413314766979e-22,2.8416135602989754e-22,3.891801052059091e-22,5.32478345940941e-22,7.278116060855443e-22,9.938062139416303e-22,1.355658010244742e-21,1.84741423925725e-21,2.5150355857997425e-21,3.4205007308105835e-21,4.6473025424301114e-21,6.30779993722011e-21,8.553041518726105e-21,1.1585878118244407e-20,1.5678446784031995e-20,2.1195458835817854e-20,2.8625185805493937e-20,3.862064402764662e-20,5.2054276489889177e-20,7.0090478181035e-20,9.428168525186911e-20,1.2669554854311538e-19,1.7008306797855945e-19,2.281006440605616e-19,3.0560302410500396e-19,4.090293659585318e-19,5.469114754618021e-19,7.305421669072776e-19,9.748532558742922e-19,1.2995677041456882e-18,1.7307099047275522e-18,2.3025833168839055e-18,3.0603573001197283e-18,4.063447185740342e-18,5.3899260980653026e-18,7.142277291537083e-18,9.454886273886542e-18,1.2503788443783228e-17,1.6519337657093817e-17,2.1802653310787557e-17,2.874694997796842e-17,3.7865169307176476e-17,4.9825737803796317e-17,6.549879030815129e-17,8.601585793886041e-17,1.1284685949921312e-16,1.478993054892707e-16,1.9364598527666014e-16,2.532891379399189e-16,3.3097130305276804e-16,4.3204583143122605e-16,5.634235610076765e-16,7.340166218224748e-16,9.553059674117186e-16,1.2420663387296556e-15,1.6132913272786093e-15,2.0933724855193764e-15,2.7136006195020253e-15,3.5140752184873113e-15,4.5461303333259e-15,5.875413231954853e-15,7.585787228155214e-15,9.78427392184295e-15,1.2607304836678604e-14,1.622862072583604e-14,2.086924188642608e-14,2.6810038677818034e-14,3.440756300153675e-14,4.411396481999411e-14,5.650202029296272e-14,7.229654889580203e-14,9.241380709418244e-14,1.1801082940941501e-13,1.5054716065120718e-13,1.9186200600672365e-13,2.4427054326289204e-13,3.1068402375434566e-13,3.947593721769117e-13,5.010853244716474e-13,6.35413771221259e-13,8.049469663281766e-13,1.0186936956057596e-12,1.287910471973002e-12,1.6266474472769461e-12,2.0524231426703886e-12,2.5870574649569044e-12,3.2576989934351024e-12,4.0980904279240085e-12,5.15012566798567e-12,6.465763585541305e-12,8.109377563554935e-12,1.0160636785541307e-11,1.2718035649663771e-11,1.590321223100274e-11,1.986622623798576e-11,2.479200236622546e-11,3.0908187484083317e-11,3.8494721035388447e-11,4.7895479004777865e-11,5.953242463265209e-11,7.39227859934513e-11,9.169988415235747e-11,1.1363835893008249e-10,1.4068468589288598e-10,1.739940522098978e-10,2.1497486534649347e-10,2.653424128642819e-10,3.2718348048165496e-10,4.0303407669533237e-10,4.959728145900305e-10,6.097329753058061e-10,7.488368349509218e-10,9.187564913605652e-10,1.1261061949471507e-9,1.3788720873212995e-9,1.6866863034858534e-9,2.0611536224385504e-9,2.5162402847134513e-9,3.068736265489405e-9,3.738804234642494e-9,4.550630691832344e-9,5.5331973823979935e-9,6.721194131889258e-9,8.156097743999838e-9,9.88744565699232e-9,1.1974337724766124e-8,1.4487204867720514e-8,1.750988952360636e-8,2.114208992980118e-8,2.550222840930488e-8,3.073081315126569e-8,3.6994373627009155e-8,4.449006193583845e-8,5.345102622180933e-8,6.415267805440613e-8,7.691999355609144e-8,9.213600834566135e-8,1.1025168933173763e-7,1.3179739234671758e-7,1.5739614389882933e-7,1.877790183105108e-7,2.2380291861018086e-7,2.664711111911448e-7,3.1695691092168007e-7,3.7663096559740727e-7,4.470926469226304e-7,5.302061201824272e-7,6.281417370526491e-7,7.434234762611724e-7,8.789832457702981e-7,1.0382229585448621e-6,1.2250854025871314e-6,1.4441350455752758e-6,1.7006500459841898e-6,2.0007268868677913e-6,2.351399206432659e-6,2.7607725720371986e-6,3.2381771322159517e-6,3.7943402856560886e-6,4.441581727623776e-6,5.194033474002857e-6,6.067887721667202e-6,7.081675682098689e-6,8.256580823632166e-6,9.616790277000506e-6,1.1189888499372052e-5,1.300729765406762e-5,1.51047695466708e-5,1.7522934363135297e-5,2.0307911881324526e-5,2.3511991273467765e-5,2.719438608223449e-5,3.1422071436077375e-5,3.6270711068331634e-5,4.182568221696112e-5,4.818320700499157e-5,5.5451599432176945e-5,6.37526376423301e-5,7.32230716633574e-5,8.401627734305137e-5,9.630406771703447e-5,0.00011027867353903842,0.00012615490517032247,0.00014417250845590252,0.0001645987276010445,0.00018773108839185998,0.0002139004153676611,0.000243474096737915,0.00027685961093021247,0.0003145083286438566,0.0003569196041517842,0.0004046451693262645,0.0004582938434450188,0.0005185365712474733,0.0005861118009386389,0.0006618312128631535,0.0007465858083766799,0.0008413523670084695,0.0009472002783201115,0.0010652987529042183,0.0011969244147168809,0.0013434692743837268,0.0015064490802475016,0.0016875120407226383,0.0018884479079789745,0.0021111974090845076,0.002357862006490233,0.0026307139651365738,0.0029322066985015887,0.0032649853606012925,0.00363189764530118,0.004036004748319562,0.004480592441016624,0.004969182198492809,0.005505542317696355,0.006093698954199193,0.006737946999085461,0.007442860710056644,0.00821330400344857,0.009054440306439577,0.009971741861376466,0.010970998366931477,0.012058324833811458,0.013240168526058691,0.014523314852706914,0.015914892068784183,0.017422374639493515,0.019053585116958024,0.020816694375305894,0.02272022004720072,0.024773023003314215,0.026984301715802465,0.029363584347699333,0.031920718412389276,0.034665857851076426,0.0376094473815209,0.04076220397836621,0.04413509535420925,0.047739315321240997,0.051586255925869705,0.05568747626326995,0.060054667895307945,0.0646996168137855,0.06963416191140502,0.07487014994525978,0.0804193870019325,0.0862935864993705,0.0925043137884824,0.09906292744674727,0.10598051738688176,0.11326783993558943,0.12093525007041664,0.1289926310365194,0.13744932159945192,0.14631404122463545,0.15559481350864937,0.16529888822158656,0.17543266235308227,0.18600160058690876,0.19701015565985838,0.20846168908963153,0.22035839278323385,0.2327012120615711,0.24548977065714736,0.2587222982596401,0.2723955611982928,0.28650479686019004,0.30104365244924836,0.31600412869186256,0.33137652909136334,0.34714941532451044,0.36330956935901126,0.3798419628513787,0.3967297343592199,0.4139541748712741,0.4314947221221877,0.44932896411722156,0.46743265224496583,0.485779724303885,0.5043423377113949,0.5230909131025009,0.5419941884591871,0.5610192838421705,0.5801317767238207,0.5992957878455384,0.618474077445272,0.6376281516217733,0.656718378522315,0.675704113960626,0.6945438359924635,0.7131952878982822,0.7316156289466418,0.7497615922390413,0.7675896488675729,0.7850561775518295,0.8021176388616299,0.8187307530779818,0.8348526806969435,0.850441204540233,0.8654549124031068,0.8798533791446438,0.8935973471085157,0.9066489037539209,0.9189716553768317,0.9305308958112057,0.9412937690184057,0.951229424500714,0.960309164511413,0.9685065820791976,0.9757976889184073,0.9821610323583008,0.9875778004938814,0.9920319148370607,0.9955101098295706,0.9980019986673331,0.9995001249791693,1.0,0.9995001249791693,0.9980019986673331,0.9955101098295706,0.9920319148370607,0.9875778004938814,0.9821610323583008,0.9757976889184073,0.9685065820791976,0.960309164511413,0.951229424500714,0.9412937690184057,0.9305308958112057,0.9189716553768317,0.9066489037539209,0.8935973471085157,0.8798533791446438,0.8654549124031068,0.850441204540233,0.8348526806969435,0.8187307530779818,0.8021176388616299,0.7850561775518295,0.7675896488675729,0.7497615922390413,0.7316156289466418,0.7131952878982822,0.6945438359924635,0.675704113960626,0.656718378522315,0.6376281516217733,0.618474077445272,0.5992957878455384,0.5801317767238207,0.5610192838421705,0.5419941884591871,0.5230909131025009,0.5043423377113949,0.485779724303885,0.46743265224496583,0.44932896411722156,0.4314947221221877,0.4139541748712741,0.3967297343592199,0.3798419628513787,0.36330956935901126,0.34714941532451044,0.33137652909136334,0.31600412869186256,0.30104365244924836,0.28650479686019004,0.2723955611982928,0.2587222982596401,0.24548977065714736,0.2327012120615711,0.22035839278323385,0.20846168908963153,0.19701015565985838,0.18600160058690876,0.17543266235308227,0.16529888822158656,0.15559481350864937,0.14631404122463545,0.13744932159945192,0.1289926310365194,0.12093525007041664,0.11326783993558943,0.10598051738688176,0.09906292744674727,0.0925043137884824,0.0862935864993705,0.0804193870019325,0.07487014994525978,0.06963416191140502,0.0646996168137855,0.060054667895307945,0.05568747626326995,0.051586255925869705,0.047739315321240997,0.04413509535420925,0.04076220397836621,0.0376094473815209,0.034665857851076426,0.031920718412389276,0.029363584347699333,0.026984301715802465,0.024773023003314215,0.02272022004720072,0.020816694375305894,0.019053585116958024,0.017422374639493515,0.015914892068784183,0.014523314852706914,0.013240168526058691,0.012058324833811458,0.010970998366931477,0.009971741861376466,0.009054440306439577,0.00821330400344857,0.007442860710056644,0.006737946999085461,0.006093698954199193,0.005505542317696355,0.004969182198492809,0.004480592441016624,0.004036004748319562,0.00363189764530118,0.0032649853606012925,0.0029322066985015887,0.0026307139651365738,0.002357862006490233,0.0021111974090845076,0.0018884479079789745,0.0016875120407226383,0.0015064490802475016,0.0013434692743837268,0.0011969244147168809,0.0010652987529042183,0.0009472002783201115,0.0008413523670084695,0.0007465858083766799,0.0006618312128631535,0.0005861118009386389,0.0005185365712474733,0.0004582938434450188,0.0004046451693262645,0.0003569196041517842,0.0003145083286438566,0.00027685961093021247,0.000243474096737915,0.0002139004153676611,0.00018773108839185998,0.0001645987276010445,0.00014417250845590252,0.00012615490517032247,0.00011027867353903842,9.630406771703447e-5,8.401627734305137e-5,7.32230716633574e-5,6.37526376423301e-5,5.5451599432176945e-5,4.818320700499157e-5,4.182568221696112e-5,3.6270711068331634e-5,3.1422071436077375e-5,2.719438608223449e-5,2.3511991273467765e-5,2.0307911881324526e-5,1.7522934363135297e-5,1.51047695466708e-5,1.300729765406762e-5,1.1189888499372052e-5,9.616790277000506e-6,8.256580823632166e-6,7.081675682098689e-6,6.067887721667202e-6,5.194033474002857e-6,4.441581727623776e-6,3.7943402856560886e-6,3.2381771322159517e-6,2.7607725720371986e-6,2.351399206432659e-6,2.0007268868677913e-6,1.7006500459841898e-6,1.4441350455752758e-6,1.2250854025871314e-6,1.0382229585448621e-6,8.789832457702981e-7,7.434234762611724e-7,6.281417370526491e-7,5.302061201824272e-7,4.470926469226304e-7,3.7663096559740727e-7,3.1695691092168007e-7,2.664711111911448e-7,2.2380291861018086e-7,1.877790183105108e-7,1.5739614389882933e-7,1.3179739234671758e-7,1.1025168933173763e-7,9.213600834566135e-8,7.691999355609144e-8,6.415267805440613e-8,5.345102622180933e-8,4.449006193583845e-8,3.6994373627009155e-8,3.073081315126569e-8,2.550222840930488e-8,2.114208992980118e-8,1.750988952360636e-8,1.4487204867720514e-8,1.1974337724766124e-8,9.88744565699232e-9,8.156097743999838e-9,6.721194131889258e-9,5.5331973823979935e-9,4.550630691832344e-9,3.738804234642494e-9,3.068736265489405e-9,2.5162402847134513e-9,2.0611536224385504e-9,1.6866863034858534e-9,1.3788720873212995e-9,1.1261061949471507e-9,9.187564913605652e-10,7.488368349509218e-10,6.097329753058061e-10,4.959728145900305e-10,4.0303407669533237e-10,3.2718348048165496e-10,2.653424128642819e-10,2.1497486534649347e-10,1.739940522098978e-10,1.4068468589288598e-10,1.1363835893008249e-10,9.169988415235747e-11,7.39227859934513e-11,5.953242463265209e-11,4.7895479004777865e-11,3.8494721035388447e-11,3.0908187484083317e-11,2.479200236622546e-11,1.986622623798576e-11,1.590321223100274e-11,1.2718035649663771e-11,1.0160636785541307e-11,8.109377563554935e-12,6.465763585541305e-12,5.15012566798567e-12,4.0980904279240085e-12,3.2576989934351024e-12,2.5870574649569044e-12,2.0524231426703886e-12,1.6266474472769461e-12,1.287910471973002e-12,1.0186936956057596e-12,8.049469663281766e-13,6.35413771221259e-13,5.010853244716474e-13,3.947593721769117e-13,3.1068402375434566e-13,2.4427054326289204e-13,1.9186200600672365e-13,1.5054716065120718e-13,1.1801082940941501e-13,9.241380709418244e-14,7.229654889580203e-14,5.650202029296272e-14,4.411396481999411e-14,3.440756300153675e-14,2.6810038677818034e-14,2.086924188642608e-14,1.622862072583604e-14,1.2607304836678604e-14,9.78427392184295e-15,7.585787228155214e-15,5.875413231954853e-15,4.5461303333259e-15,3.5140752184873113e-15,2.7136006195020253e-15,2.0933724855193764e-15,1.6132913272786093e-15,1.2420663387296556e-15,9.553059674117186e-16,7.340166218224748e-16,5.634235610076765e-16,4.3204583143122605e-16,3.3097130305276804e-16,2.532891379399189e-16,1.9364598527666014e-16,1.478993054892707e-16,1.1284685949921312e-16,8.601585793886041e-17,6.549879030815129e-17,4.9825737803796317e-17,3.7865169307176476e-17,2.874694997796842e-17,2.1802653310787557e-17,1.6519337657093817e-17,1.2503788443783228e-17,9.454886273886542e-18,7.142277291537083e-18,5.3899260980653026e-18,4.063447185740342e-18,3.0603573001197283e-18,2.3025833168839055e-18,1.7307099047275522e-18,1.2995677041456882e-18,9.748532558742922e-19,7.305421669072776e-19,5.469114754618021e-19,4.090293659585318e-19,3.0560302410500396e-19,2.281006440605616e-19,1.7008306797855945e-19,1.2669554854311538e-19,9.428168525186911e-20,7.0090478181035e-20,5.2054276489889177e-20,3.862064402764662e-20,2.8625185805493937e-20,2.1195458835817854e-20,1.5678446784031995e-20,1.1585878118244407e-20,8.553041518726105e-21,6.30779993722011e-21,4.6473025424301114e-21,3.4205007308105835e-21,2.5150355857997425e-21,1.84741423925725e-21,1.355658010244742e-21,9.938062139416303e-22,7.278116060855443e-22,5.32478345940941e-22,3.891801052059091e-22,2.8416135602989754e-22,2.0727413314766979e-22,1.510396268500848e-22,1.0995181582344653e-22,7.996125715898559e-23,5.809282904332702e-23,4.216296511689076e-23,3.0570706051477833e-23,2.214346085379256e-23,1.602327306359053e-23,1.1583043157259795e-23,8.364882032735935e-24,6.034797090462571e-24,4.349418821218209e-24,3.1315942873576345e-24,2.2525034268586583e-24,1.6185686865073693e-24,1.1618833101820788e-24,8.332198316061588e-25,5.969286015454393e-25,4.272193197849987e-25,3.054534857369281e-25,2.1817500388130056e-25,1.5567920485110108e-25,1.1097417436229193e-25,7.902762784127537e-26,5.622140244567847e-26,3.9956745672595413e-26,2.8369014500581107e-26,2.0121673361609085e-26,1.4257705691451965e-26,1.0092549827747071e-26,7.13703561978753e-27,5.041973187085947e-27,3.5583519804461035e-27,2.5087823372704526e-27,1.7670252992065744e-27,1.2433352802103817e-27,8.739758903134928e-28,6.137285870734339e-28,4.305454054873446e-28,3.0173609865056806e-28,2.1125222311883924e-28,1.4775460005142883e-28,1.0323962988226507e-28,7.206386860901402e-29,5.0252122749665084e-29,3.5007166225158424e-29,2.4362688200739486e-29,1.693788433624625e-29,1.1764103160493386e-29,8.162518734745172e-30,5.6578999501424246e-30,3.9178882222261096e-30,2.7102822745595387e-30,1.8730212893122038e-30,1.2931133881823633e-30,8.91859018253701e-31,6.144994714057436e-31,4.229728822365796e-31,2.908501158882566e-31,1.9979824228502428e-31,1.3711336546588905e-31,9.40012489424457e-32,6.438032466483551e-32,4.4049238664938293e-32,3.01085164057414e-32,2.0559190532067264e-32,1.4024531816775815e-32,9.557326840839284e-33,6.506541586875531e-33,4.425167225430208e-33,3.0065945778781195e-33,2.0407309832662094e-33,1.3837650328134295e-33,9.37356189101052e-34,6.343262092756452e-34,4.288311912012338e-34,2.8961815480360437e-34,1.954028544586258e-34,1.3170483861997544e-34,8.86825684793637e-35,5.965412787758881e-35,4.008745120417611e-35,2.69117595153109e-35,1.8048513878453896e-35,1.209223302558629e-35,8.093516813403859e-36,5.411700386319788e-36,3.614896945681192e-36,2.4122582640624812e-36,1.6081160648509705e-36,1.0709684662829915e-36,7.1252758470426834e-37,4.735789457265777e-37,3.1444797047653166e-37,2.085791586055619e-37,1.3821613101436096e-37,9.149813840443645e-38,6.051060426395873e-38,3.9977573195524367e-38,2.638560580418412e-38,1.7397362717407126e-38,1.1459494802550252e-38,7.540727228467494e-39,4.9570887694092454e-39,3.255411298837604e-39,2.1357516097542594e-39,1.3997849627215599e-39,9.165108500221327e-40,5.9948676994976285e-40,3.917304225924761e-40,2.5571764990599964e-40,1.6676304385425774e-40,1.0864372010800405e-40,7.070907371452675e-41,4.59739028316497e-41,2.986161587697738e-41,1.9376750232689842e-41,1.2560712733777698e-41,8.13417161509699e-42,5.262330059470764e-42,3.401014963497178e-42,2.1958602995411638e-42,1.416336921314365e-42,9.126287621727244e-43,5.874723521448935e-43,3.777864862090005e-43,2.4270074557542443e-43,1.5576199742735253e-43,9.986598974843636e-44,6.396456030373832e-44,4.092860407454631e-44,2.616255486177179e-44,1.6707023247078499e-44,1.065819611814323e-44,6.792568756843043e-45,4.324641231687153e-45,2.7506278225520885e-45,1.7477498922024384e-45,1.1094109344035213e-45,7.0351166916366e-46,4.456725384886305e-46,2.820500292001311e-46,1.783208514152264e-46,1.126273367436048e-46,7.106425471137004e-47,4.479445967094649e-47,2.820740307027492e-47,1.7744657127603565e-47,1.1151616485924562e-47,7.001220308967917e-48,4.391120631800023e-48,2.751330089656034e-48,1.7221688636533958e-48,1.0768977604396345e-48,6.727270953307621e-49,4.198257493527248e-49,2.6173688480711924e-49,1.6301459598146663e-49,1.014270420713244e-49,6.304443168789515e-50,3.9147624460235043e-50,2.428453535707831e-50,1.5049424371105486e-50,9.31699118824694e-51,5.762317529716718e-51,3.5602819554483226e-51,2.1975426145950051e-51,1.3550518817273488e-51,8.347189001773146e-52,5.136771841129314e-52,3.157955535221233e-52,1.9394895806315456e-52,1.189966119476966e-52,7.293692464440711e-53,4.4660749189684045e-53,2.7319343972057713e-53,1.6694762069277811e-53,1.0191917678005994e-53,6.215803631041029e-54,3.787079045962578e-54,2.3050330659919683e-54,1.4015727818629223e-54,8.513729661519419e-55,5.166420632837861e-55,3.1320261101645413e-55,1.896822494101458e-55,1.147608388467308e-55,6.936277224894154e-56,4.188175542267686e-56,2.5263238128761693e-56,1.5223652450197602e-56,9.164618921438996e-57,5.511574307863163e-57,3.311331255947733e-57,1.9874458078034284e-57,1.1916635840467523e-57,7.138019762199148e-58,4.271373309381595e-58,2.5534244853097604e-58,1.5249100026385019e-58,9.097689558799636e-59,5.422302206694305e-59,3.2285092127455378e-59,1.9203750137882758e-59,1.1411316969919425e-59,6.774093652871721e-60,4.0172821007799504e-60,2.3800121188941e-60,1.4086130666758972e-60,8.328560837430633e-61,4.919420173461512e-61,2.902843206220607e-61,1.7111928024524956e-61,1.0077203218182182e-61,5.928526890046399e-62,3.4843299735607634e-62,2.0457731072970513e-62,1.199945051862329e-62,7.031224400813443e-63,4.1159137322320165e-63,2.4069511379721528e-63,1.4061575725514113e-63,8.206659440951944e-64,4.7848082531684535e-64,2.7869448266390432e-64,1.6216529225308025e-64,9.426558187592811e-65,5.474117330943129e-65,3.175709413194699e-65,1.8404885351489542e-65,1.0655925661967488e-65,6.163323354140786e-66,3.561266135266247e-66,2.055699414243779e-66,1.1854425177833202e-66,6.829156936471596e-67,3.930242900055228e-67,2.259630333372411e-67,1.2978398526705579e-67,7.446814250801847e-68,4.268601788406172e-68,2.444367317506248e-68,1.398340705847158e-68,7.991443578311751e-69,4.5625031831684467e-69,2.602236887752464e-69,1.482709884522689e-69,8.439782259040792e-70,4.7992349009963084e-70,2.7263303466327176e-70,1.5472149520062127e-70,8.771796246540036e-71,4.968120514937853e-71,2.811003684247604e-71,1.588899443352958e-71,8.972162205477011e-72,5.061316845418397e-72,2.8523028785724646e-72,1.6058074201023938e-72,9.03143968761754e-73,5.074417746363769e-73,2.848269989001125e-73,1.5971356219323755e-73,8.946808545141198e-74,5.006799464711466e-74,2.7990970458842988e-74,1.5632967326411662e-74,8.722291364435312e-75,4.861669874890641e-75,2.7071108916061756e-75,1.505886821087695e-75,8.368436488145923e-76,4.645816176280437e-76,2.5765906396728972e-76,1.4275605344202143e-76,7.901496410148077e-77,4.369078688898636e-77,2.4134376949094467e-77,1.3318276349331359e-77,7.34219066291586e-78,4.0436075584570405e-78,2.22473376779541e-78,1.22279259291269e-78,6.714184288211594e-79,3.6829805135442004e-79,2.0182329402824727e-79,1.1048641061305512e-79,6.042437194147352e-80,3.3012706490349188e-80,1.8018383324206884e-80,9.824630338994893e-81,5.351583682463348e-81,2.912152599155926e-81,1.5831120037748048e-81,8.597552979570069e-82,4.6644859043355185e-82,2.5281242522996897e-82,1.3688591086827e-82,7.404313372006404e-83,4.001073573587828e-83,2.159901715345179e-83,1.1648155152923516e-83,6.275466416007976e-84,3.3775405999812994e-84,1.8160209409991771e-84,9.75454084704156e-85,5.234298871952674e-85,2.8059240224436676e-85,1.5026540397883717e-85,8.039106920553505e-86,4.296574157013102e-86,2.2940481258278325e-86,1.223625284968177e-86,6.520187221510919e-87,3.4708623900815556e-87,1.8457821006861264e-87,9.805938617053889e-88,5.204315490748091e-88,2.759330791485219e-88,1.4615363595131158e-88,7.733590752953963e-89,4.0880712281692506e-89,2.15884482731646e-89,1.1389118357060604e-89,6.002393878844099e-90,3.160272852073358e-90,1.6622271661006572e-90,8.734174746333978e-91,4.5847861456848984e-91,2.4042631220661123e-91,1.2595360797099625e-91,6.591813863302463e-92,3.4463943047331014e-92,1.800075404569458e-92,9.392520193711107e-93,4.895976025503147e-93,2.5495417788283806e-93,1.326327239733728e-93,6.892947182843259e-94,3.5786969060948957e-94,1.856139403968579e-94,9.617494987264396e-95,4.978276936276906e-95,2.5743159142051835e-95,1.329873512641931e-95,6.863166522433561e-96,3.5383797599017644e-96,1.8224266322334955e-96,9.376945032045818e-97,4.81990404612984e-97,2.4750337206240986e-97,1.2696661862173374e-97,6.506743583076161e-98,3.331221699433918e-98,1.7037626237913177e-98,8.705231845009533e-99,4.443419361045004e-99,2.265791636841681e-99,1.1542193250659967e-99,5.873844145041218e-100,2.986222764767726e-100,1.5166581052740366e-100,7.695181797351578e-101,3.9004596002045173e-101,1.9750513389070897e-101,9.990948023373804e-102,5.048945882663486e-102,2.5489448402334042e-102,1.2855407994207314e-102,6.477046234195058e-103,3.260121870884224e-103,1.6392922247143835e-103,8.234640202191164e-104,4.132364128393191e-104,2.0716588670349632e-104,1.0375370376038381e-104,5.191043643670399e-105,2.5946062328075976e-105,1.2955492861036534e-105,6.462523378357862e-106,3.2204459938403463e-106,1.6032292193245195e-106,7.973351751344742e-107,3.9614295213417946e-107,1.966204334320149e-107,9.749246922969946e-108,4.829244529683176e-108,2.389753071775236e-108,1.1813880294849498e-108,5.8344216086921955e-109,2.8785167276375615e-109,1.4187484877600835e-109,6.985665259581456e-110,3.4361794505522245e-110,1.6885332105914376e-110,8.289132523350869e-111,4.065128372041242e-111,1.991613914468042e-111,9.74769079415443e-112,4.766109793969954e-112,2.328048621867829e-112,1.1360194201247952e-112,5.53790077974594e-113,2.696933827677159e-113,1.3120824195491827e-113,6.3770180723675784e-114,3.0962775551987292e-114,1.5018543851238501e-114,7.2774876113593695e-115,3.5229041579341887e-115,1.7036716127542782e-115,8.230697708237948e-116,3.9724013556304896e-116,1.9152933328195318e-116,9.225356925630352e-117,4.439118764598805e-117,2.133909792229038e-117,1.024757378125161e-117,4.916225067466307e-118,2.3561783736410964e-118,1.1281069622809019e-118,5.395828021136882e-119,2.578289169271099e-119,1.2307528635097376e-119,5.8691578647788316e-120,2.796059653055709e-120,1.3307080370769246e-120,6.326810585835376e-121,3.0050561468230967e-121,1.425890102824819e-121,6.75904322499322e-122,3.200737798538324e-122,1.5141910641060698e-122,7.156109291711506e-123,3.378616946293087e-123,1.5935535160343384e-123,7.508618778827979e-124,3.5344281960640372e-124,1.6620495862245283e-124,7.807904548914741e-125,3.6642974462270196e-125,1.7179584260947477e-125,8.04637530414115e-126,3.764901569118742e-126,1.759837925894444e-126,8.217835146786753e-127,3.833609586867529e-127,1.7865864897071797e-127,8.317750978754201e-128,3.868596977664953e-128,1.7974911790146005e-128,8.34345163810283e-129,3.868926182171023e-129,1.792259288325748e-129,8.294246562734797e-130,3.834588351744406e-130,1.771031400861482e-130,8.171456623088348e-131,3.7665037436629926e-131,1.7343751114636022e-131,7.97835520227533e-132,3.666480738687979e-132,1.683259807940478e-132,7.720023192237626e-133,3.537136028507449e-133,1.6190140748580427e-133,7.403126871785171e-134,3.381780889772396e-134,1.5432683322371144e-134,7.035632219041899e-135,3.204280442340767e-135,1.4578861646930437e-135,6.62647273765158e-136,3.0088942341314604e-136,1.364888372889789e-136,6.185190094812883e-137,2.8001073064647562e-137,1.266374052489056e-137,5.721567653719609e-138,2.5824610333817212e-138,1.164442967489197e-138,5.245276336559158e-139,2.3603925174764465e-139,1.0611231537462908e-139], + "imaginary": [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] + }, + "doNormalize": false +} \ No newline at end of file diff --git a/examples/harmonicOscillator/coherentStateClassical.json b/examples/harmonicOscillator/coherentStateClassical.json new file mode 100644 index 0000000..8ae0789 --- /dev/null +++ b/examples/harmonicOscillator/coherentStateClassical.json @@ -0,0 +1,9 @@ +{ + "type": "classical", + "scheme": {"id": "SymplecticEuler" , "mass": 1, "deltaX": 0.001}, + "V_coefficients": [0,0,1], + "mass": 1.0, + "deltaT": 0.006283185307179587, + "t": 0.0, + "point": [1.0,0.0] +} \ No newline at end of file diff --git a/examples/harmonicOscillator/coherentStateQm.json b/examples/harmonicOscillator/coherentStateQm.json new file mode 100644 index 0000000..43b2c97 --- /dev/null +++ b/examples/harmonicOscillator/coherentStateQm.json @@ -0,0 +1,18 @@ +{ + "type": "qm", + "scheme": {"id": "CrankNicolson" }, + "V_coefficients": [0,0,1], + "V": [0.72,0.7188005000000001,0.717602,0.7164045000000001,0.715208,0.7140125,0.712818,0.7116245000000001,0.710432,0.7092405,0.70805,0.7068605000000001,0.705672,0.7044845000000001,0.703298,0.7021125,0.7009279999999999,0.6997445000000001,0.6985619999999999,0.6973805000000001,0.6961999999999999,0.6950205,0.693842,0.6926645,0.6914879999999999,0.6903125000000001,0.6891379999999999,0.6879645000000001,0.686792,0.6856205000000001,0.6844499999999999,0.6832805000000001,0.6821119999999999,0.6809445000000001,0.6797779999999999,0.6786125000000001,0.6774479999999999,0.6762845000000001,0.6751219999999999,0.6739605000000001,0.6728,0.6716405000000001,0.6704819999999999,0.6693245,0.6681679999999999,0.6670125,0.665858,0.6647045,0.6635519999999999,0.6624005000000001,0.6612499999999999,0.6601005,0.6589519999999999,0.6578045,0.6566579999999999,0.6555125,0.6543679999999998,0.6532245,0.6520819999999999,0.6509405,0.6497999999999999,0.6486605,0.6475219999999999,0.6463845,0.6452479999999999,0.6441125,0.6429779999999999,0.6418445,0.6407119999999998,0.6395805,0.6384499999999999,0.6373205,0.6361919999999999,0.6350645,0.6339379999999999,0.6328125,0.6316880000000001,0.6305645,0.6294420000000002,0.6283205,0.6272000000000001,0.6260805,0.6249620000000001,0.6238445,0.6227280000000002,0.6216125,0.6204980000000001,0.6193845,0.6182720000000002,0.6171605,0.6160500000000001,0.6149405,0.6138320000000002,0.6127245,0.6116180000000001,0.6105125,0.6094080000000001,0.6083045,0.6072020000000001,0.6061004999999999,0.6050000000000001,0.6039005,0.6028020000000001,0.6017045,0.6006080000000001,0.5995125,0.5984180000000001,0.5973244999999999,0.5962320000000001,0.5951405,0.5940500000000001,0.5929605,0.5918720000000001,0.5907844999999999,0.589698,0.5886125,0.587528,0.5864444999999999,0.585362,0.5842805,0.5832,0.5821204999999999,0.5810420000000001,0.5799645,0.5788880000000001,0.5778125,0.5767380000000001,0.5756644999999999,0.5745920000000001,0.5735205,0.57245,0.5713805,0.570312,0.5692444999999999,0.5681780000000001,0.5671124999999999,0.5660480000000001,0.5649844999999999,0.563922,0.5628605,0.5618000000000001,0.5607405,0.559682,0.5586245,0.5575680000000001,0.5565125,0.555458,0.5544045,0.5533520000000001,0.5523005,0.55125,0.5502005,0.5491520000000001,0.5481044999999999,0.547058,0.5460124999999999,0.544968,0.5439244999999999,0.5428820000000001,0.5418405,0.5408000000000001,0.5397604999999999,0.538722,0.5376844999999999,0.536648,0.5356124999999999,0.534578,0.5335444999999999,0.532512,0.5314804999999999,0.53045,0.5294205,0.528392,0.5273644999999999,0.526338,0.5253125,0.524288,0.5232644999999999,0.522242,0.5212204999999999,0.5202,0.5191804999999999,0.518162,0.5171444999999999,0.516128,0.5151124999999999,0.514098,0.5130844999999999,0.512072,0.5110604999999999,0.51005,0.5090404999999999,0.508032,0.5070244999999999,0.506018,0.5050124999999999,0.504008,0.5030044999999999,0.502002,0.5010004999999998,0.5,0.4990005,0.498002,0.4970045,0.496008,0.4950125,0.494018,0.4930245,0.49203199999999997,0.4910405,0.49005,0.4890605,0.488072,0.4870845,0.486098,0.4851125,0.484128,0.4831445,0.482162,0.4811805,0.48019999999999996,0.4792205,0.478242,0.4772645,0.476288,0.47531249999999997,0.474338,0.47336449999999997,0.472392,0.47142049999999996,0.47045,0.46948049999999997,0.468512,0.4675445,0.466578,0.4656125,0.46464799999999995,0.46368449999999994,0.46272199999999997,0.46176049999999996,0.4608,0.4598405,0.45888199999999996,0.45792449999999996,0.456968,0.4560125,0.45505799999999996,0.45410449999999997,0.45315199999999994,0.45220049999999995,0.45125,0.45030049999999994,0.449352,0.44840449999999993,0.44745799999999997,0.4465125,0.44556799999999996,0.4446245,0.44368199999999997,0.4427404999999999,0.44179999999999997,0.44086049999999993,0.4399219999999999,0.43898450000000006,0.43804800000000005,0.43711250000000007,0.43617800000000007,0.43524450000000003,0.43431200000000003,0.43338050000000006,0.43245000000000006,0.43152050000000003,0.43059200000000003,0.42966450000000006,0.42873800000000006,0.42781250000000004,0.42688800000000005,0.4259645,0.42504200000000003,0.4241205,0.4232,0.42228050000000006,0.421362,0.42044450000000005,0.419528,0.41861250000000005,0.417698,0.41678450000000006,0.415872,0.4149605,0.41405000000000003,0.4131405,0.41223200000000004,0.41132450000000004,0.410418,0.4095125,0.408608,0.4077045,0.406802,0.4059005,0.405,0.40410050000000003,0.403202,0.4023045,0.40140800000000004,0.4005125,0.39961800000000003,0.39872450000000004,0.397832,0.39694050000000003,0.39605,0.3951605,0.394272,0.3933845,0.392498,0.39161250000000003,0.390728,0.3898445,0.38896200000000003,0.3880805,0.3872,0.3863205,0.385442,0.3845645,0.383688,0.3828125,0.381938,0.3810645,0.380192,0.3793205,0.37845,0.3775805,0.376712,0.37584449999999997,0.374978,0.3741125,0.37324799999999997,0.3723845,0.37152199999999996,0.3706605,0.36979999999999996,0.3689405,0.36808199999999996,0.3672245,0.36636799999999997,0.36551249999999996,0.364658,0.3638045,0.362952,0.3621005,0.36124999999999996,0.36040049999999996,0.359552,0.3587045,0.35785799999999995,0.35701249999999995,0.356168,0.3553245,0.35448199999999996,0.35364049999999997,0.35279999999999995,0.35196049999999995,0.351122,0.3502845,0.349448,0.3486125,0.347778,0.3469445,0.346112,0.3452805,0.34445,0.34362049999999994,0.342792,0.34196449999999995,0.34113799999999994,0.34031249999999996,0.33948799999999996,0.3386645,0.337842,0.33702049999999995,0.33619999999999994,0.33538049999999997,0.33456199999999997,0.33374449999999994,0.33292799999999995,0.3321125,0.331298,0.33048449999999996,0.329672,0.32886050000000006,0.32805000000000006,0.32724050000000005,0.32643200000000006,0.32562450000000004,0.32481800000000005,0.32401250000000004,0.32320800000000005,0.32240450000000004,0.32160200000000005,0.32080050000000004,0.32000000000000006,0.31920050000000005,0.318402,0.3176045,0.31680800000000003,0.31601250000000003,0.31521800000000005,0.31442450000000005,0.313632,0.3128405,0.31205000000000005,0.31126050000000005,0.310472,0.30968450000000003,0.308898,0.3081125,0.30732800000000005,0.3065445,0.30576200000000003,0.30498050000000004,0.3042,0.30342050000000004,0.302642,0.30186450000000004,0.301088,0.30031250000000004,0.299538,0.2987645,0.29799200000000003,0.2972205,0.29645,0.2956805,0.294912,0.29414450000000003,0.293378,0.2926125,0.291848,0.2910845,0.290322,0.2895605,0.2888,0.28804050000000003,0.287282,0.2865245,0.285768,0.2850125,0.284258,0.2835045,0.282752,0.2820005,0.28125,0.2805005,0.279752,0.2790045,0.278258,0.2775125,0.276768,0.2760245,0.27528199999999997,0.2745405,0.2738,0.2730605,0.272322,0.2715845,0.270848,0.2701125,0.269378,0.2686445,0.267912,0.2671805,0.26644999999999996,0.26572049999999997,0.264992,0.26426449999999996,0.263538,0.2628125,0.262088,0.2613645,0.260642,0.2599205,0.2592,0.2584805,0.257762,0.25704449999999995,0.256328,0.25561249999999996,0.25489799999999996,0.2541845,0.253472,0.2527605,0.25205,0.25134049999999997,0.25063199999999997,0.24992449999999997,0.24921799999999997,0.24851249999999997,0.24780799999999997,0.24710449999999998,0.24640199999999998,0.24570049999999996,0.24499999999999997,0.24430049999999998,0.24360199999999996,0.24290449999999997,0.24220799999999998,0.24151249999999996,0.24081799999999998,0.24012449999999996,0.23943199999999998,0.23874049999999997,0.23804999999999996,0.23736049999999997,0.23667199999999997,0.23598450000000004,0.23529800000000003,0.23461250000000003,0.23392800000000002,0.23324450000000005,0.23256200000000005,0.23188050000000004,0.23120000000000004,0.23052050000000004,0.22984200000000002,0.22916450000000002,0.22848800000000002,0.22781250000000003,0.22713800000000003,0.22646450000000004,0.22579200000000002,0.22512050000000003,0.22445000000000004,0.22378050000000002,0.22311200000000003,0.22244450000000002,0.22177800000000003,0.22111250000000002,0.22044800000000003,0.21978450000000002,0.219122,0.21846050000000003,0.21780000000000002,0.21714050000000001,0.216482,0.21582450000000003,0.21516800000000003,0.21451250000000002,0.21385800000000002,0.21320450000000002,0.21255200000000002,0.21190050000000002,0.21125000000000002,0.21060050000000002,0.209952,0.2093045,0.208658,0.20801250000000002,0.20736800000000002,0.2067245,0.20608200000000002,0.2054405,0.2048,0.2041605,0.203522,0.2028845,0.202248,0.2016125,0.20097800000000002,0.2003445,0.199712,0.1990805,0.19845000000000002,0.1978205,0.197192,0.1965645,0.195938,0.1953125,0.194688,0.1940645,0.193442,0.1928205,0.1922,0.1915805,0.190962,0.1903445,0.189728,0.1891125,0.188498,0.18788449999999998,0.187272,0.18666049999999998,0.18605,0.18544049999999998,0.184832,0.18422449999999999,0.183618,0.1830125,0.182408,0.18180449999999998,0.18120199999999997,0.1806005,0.18,0.1794005,0.178802,0.1782045,0.177608,0.1770125,0.176418,0.1758245,0.17523199999999997,0.17464049999999998,0.17404999999999998,0.1734605,0.17287199999999997,0.17228449999999998,0.171698,0.17111249999999997,0.17052799999999999,0.16994449999999997,0.16936199999999998,0.16878049999999997,0.1682,0.16762049999999998,0.16704199999999997,0.1664645,0.16588799999999998,0.16531249999999997,0.16473799999999997,0.16416449999999996,0.16359199999999996,0.16302049999999998,0.16244999999999998,0.16188049999999998,0.16131199999999998,0.16074449999999998,0.16017799999999996,0.15961249999999996,0.15904799999999997,0.15848449999999997,0.15792200000000003,0.15736050000000004,0.15680000000000002,0.15624050000000003,0.15568200000000004,0.15512450000000003,0.15456800000000004,0.15401250000000002,0.15345800000000004,0.15290450000000003,0.15235200000000002,0.15180050000000003,0.15125000000000002,0.15070050000000001,0.15015200000000004,0.14960450000000003,0.14905800000000002,0.14851250000000002,0.14796800000000002,0.1474245,0.146882,0.1463405,0.1458,0.14526050000000001,0.14472200000000002,0.14418450000000002,0.14364800000000003,0.1431125,0.142578,0.14204450000000002,0.14151200000000003,0.1409805,0.14045000000000002,0.1399205,0.13939200000000002,0.1388645,0.13833800000000002,0.1378125,0.13728800000000002,0.1367645,0.136242,0.13572050000000002,0.13520000000000001,0.1346805,0.134162,0.1336445,0.133128,0.1326125,0.132098,0.1315845,0.131072,0.1305605,0.13005,0.1295405,0.129032,0.1285245,0.128018,0.1275125,0.127008,0.1265045,0.126002,0.1255005,0.125,0.1245005,0.124002,0.1235045,0.12300799999999999,0.1225125,0.122018,0.1215245,0.121032,0.1205405,0.12004999999999999,0.1195605,0.119072,0.1185845,0.118098,0.1176125,0.117128,0.1166445,0.11616199999999999,0.11568049999999999,0.1152,0.11472049999999999,0.114242,0.11376449999999999,0.11328799999999999,0.1128125,0.112338,0.11186449999999999,0.11139199999999999,0.11092049999999999,0.11044999999999999,0.10998049999999998,0.10951200000000001,0.10904450000000002,0.10857800000000001,0.10811250000000001,0.10764800000000001,0.10718450000000002,0.10672200000000001,0.10626050000000001,0.1058,0.1053405,0.104882,0.1044245,0.103968,0.10351250000000001,0.10305800000000001,0.1026045,0.102152,0.1017005,0.10125,0.1008005,0.10035200000000001,0.09990450000000001,0.099458,0.0990125,0.098568,0.0981245,0.097682,0.09724050000000001,0.0968,0.0963605,0.095922,0.0954845,0.095048,0.0946125,0.094178,0.0937445,0.09331199999999999,0.09288049999999999,0.09244999999999999,0.09202049999999999,0.09159199999999999,0.0911645,0.090738,0.09031249999999999,0.089888,0.08946449999999999,0.089042,0.08862049999999999,0.08819999999999999,0.0877805,0.087362,0.0869445,0.086528,0.0861125,0.085698,0.08528449999999999,0.08487199999999999,0.0844605,0.08404999999999999,0.08364049999999999,0.08323199999999999,0.0828245,0.082418,0.08201250000000002,0.08160800000000001,0.08120450000000001,0.08080200000000001,0.08040050000000001,0.08000000000000002,0.0796005,0.07920200000000001,0.07880450000000001,0.078408,0.07801250000000001,0.077618,0.0772245,0.07683200000000001,0.07644050000000001,0.07605,0.0756605,0.075272,0.0748845,0.07449800000000001,0.0741125,0.073728,0.0733445,0.072962,0.0725805,0.0722,0.0718205,0.071442,0.0710645,0.070688,0.0703125,0.069938,0.0695645,0.069192,0.06882049999999999,0.06845,0.0680805,0.067712,0.0673445,0.066978,0.06661249999999999,0.066248,0.0658845,0.065522,0.0651605,0.0648,0.0644405,0.064082,0.06372449999999999,0.063368,0.0630125,0.06265799999999999,0.06230449999999999,0.06195199999999999,0.061600499999999996,0.06124999999999999,0.06090049999999999,0.060551999999999995,0.060204499999999994,0.059857999999999995,0.05951249999999999,0.05916799999999999,0.05882450000000001,0.058482000000000006,0.05814050000000001,0.05780000000000001,0.057460500000000005,0.057122000000000006,0.05678450000000001,0.056448000000000005,0.05611250000000001,0.05577800000000001,0.05544450000000001,0.05511200000000001,0.0547805,0.054450000000000005,0.0541205,0.053792000000000006,0.053464500000000005,0.053138000000000005,0.052812500000000005,0.052488,0.0521645,0.051842000000000006,0.051520500000000004,0.0512,0.0508805,0.050562,0.050244500000000004,0.049928,0.049612500000000004,0.049298,0.0489845,0.048672,0.0483605,0.04805,0.0477405,0.047432,0.0471245,0.046818,0.0465125,0.046208,0.0459045,0.045602,0.045300499999999994,0.045,0.0447005,0.044402,0.0441045,0.04380799999999999,0.043512499999999996,0.04321799999999999,0.0429245,0.042631999999999996,0.042340499999999996,0.04205,0.04176049999999999,0.041471999999999995,0.04118449999999999,0.04089799999999999,0.040612499999999996,0.040327999999999996,0.04004449999999999,0.03976199999999999,0.03948050000000001,0.039200000000000006,0.03892050000000001,0.03864200000000001,0.03836450000000001,0.038088000000000004,0.037812500000000006,0.03753800000000001,0.037264500000000006,0.036992000000000004,0.0367205,0.03645,0.036180500000000004,0.035912000000000006,0.0356445,0.03537800000000001,0.035112500000000005,0.034848000000000004,0.034584500000000004,0.034322000000000005,0.0340605,0.033800000000000004,0.0335405,0.033282,0.0330245,0.032768,0.0325125,0.032258,0.0320045,0.031752,0.0315005,0.03125,0.0310005,0.030751999999999998,0.0305045,0.030258,0.030012499999999998,0.029768,0.0295245,0.029282,0.029040499999999997,0.0288,0.0285605,0.028321999999999996,0.0280845,0.027847999999999998,0.027612499999999998,0.027378000000000003,0.027144500000000002,0.026912000000000002,0.026680500000000003,0.02645,0.0262205,0.025992,0.025764500000000003,0.025538,0.0253125,0.025088000000000003,0.0248645,0.024642,0.0244205,0.0242,0.0239805,0.023762,0.0235445,0.023327999999999998,0.023112499999999998,0.022897999999999998,0.0226845,0.022472,0.0222605,0.022049999999999997,0.0218405,0.021632,0.0214245,0.021217999999999997,0.021012499999999996,0.020807999999999997,0.0206045,0.020402000000000003,0.020200500000000003,0.020000000000000004,0.019800500000000002,0.019602,0.0194045,0.019208000000000003,0.0190125,0.018818,0.018624500000000002,0.018432,0.0182405,0.01805,0.0178605,0.017672,0.0174845,0.017298,0.0171125,0.016928,0.0167445,0.016562,0.0163805,0.0162,0.0160205,0.015842,0.015664499999999998,0.015487999999999998,0.015312499999999998,0.015137999999999999,0.014964499999999999,0.014791999999999998,0.014620500000000002,0.014450000000000003,0.014280500000000002,0.014112000000000001,0.013944500000000002,0.013778000000000002,0.013612500000000001,0.013448000000000002,0.013284500000000001,0.013122,0.012960500000000002,0.0128,0.0126405,0.012482,0.0123245,0.012168,0.0120125,0.011858,0.0117045,0.011552,0.0114005,0.01125,0.0111005,0.010951999999999998,0.010804499999999998,0.010657999999999999,0.0105125,0.010367999999999999,0.010224499999999997,0.010081999999999999,0.009940499999999998,0.009800000000000001,0.009660500000000002,0.009522000000000001,0.009384500000000002,0.009248000000000001,0.0091125,0.008978000000000002,0.008844500000000002,0.008712000000000001,0.008580500000000001,0.008450000000000001,0.0083205,0.008192,0.0080645,0.007938,0.0078125,0.0076879999999999995,0.0075645,0.007442,0.0073205,0.0072,0.007080499999999999,0.0069619999999999994,0.006844500000000001,0.0067280000000000005,0.0066125,0.006498,0.0063845,0.006272000000000001,0.0061605,0.00605,0.0059405,0.0058319999999999995,0.0057244999999999996,0.005618,0.005512499999999999,0.005408,0.005304499999999999,0.005201999999999999,0.005100500000000001,0.005000000000000001,0.0049005,0.004802000000000001,0.0047045,0.004608,0.0045125,0.004418,0.0043245,0.004232,0.0041405,0.00405,0.0039605,0.0038719999999999996,0.0037844999999999997,0.0036979999999999995,0.0036125000000000007,0.0035280000000000003,0.0034445000000000005,0.0033620000000000004,0.0032805,0.0032,0.0031205,0.003042,0.0029645,0.002888,0.0028125,0.0027379999999999995,0.0026644999999999998,0.0025919999999999997,0.0025204999999999997,0.0024500000000000004,0.0023805000000000002,0.0023120000000000003,0.0022445000000000004,0.0021780000000000002,0.0021125000000000002,0.002048,0.0019845,0.0019219999999999999,0.0018605,0.0018,0.0017404999999999999,0.0016820000000000001,0.0016245,0.0015680000000000002,0.0015125,0.0014579999999999999,0.0014045,0.001352,0.0013004999999999998,0.0012500000000000002,0.0012005000000000002,0.001152,0.0011045,0.001058,0.0010125,0.0009679999999999999,0.0009244999999999999,0.0008820000000000001,0.0008405000000000001,0.0008,0.0007605,0.000722,0.0006844999999999999,0.0006479999999999999,0.0006125000000000001,0.0005780000000000001,0.0005445000000000001,0.000512,0.00048049999999999997,0.00045,0.00042050000000000003,0.00039200000000000004,0.00036449999999999997,0.000338,0.00031250000000000006,0.000288,0.0002645,0.00024199999999999997,0.00022050000000000002,0.0002,0.0001805,0.00016199999999999998,0.00014450000000000002,0.000128,0.0001125,9.800000000000001e-5,8.45e-5,7.2e-5,6.049999999999999e-5,5.0e-5,4.0499999999999995e-5,3.2e-5,2.4500000000000003e-5,1.8e-5,1.25e-5,8.0e-6,4.5e-6,2.0e-6,5.0e-7,0.0,5.0e-7,2.0e-6,4.5e-6,8.0e-6,1.25e-5,1.8e-5,2.4500000000000003e-5,3.2e-5,4.0499999999999995e-5,5.0e-5,6.049999999999999e-5,7.2e-5,8.45e-5,9.800000000000001e-5,0.0001125,0.000128,0.00014450000000000002,0.00016199999999999998,0.0001805,0.0002,0.00022050000000000002,0.00024199999999999997,0.0002645,0.000288,0.00031250000000000006,0.000338,0.00036449999999999997,0.00039200000000000004,0.00042050000000000003,0.00045,0.00048049999999999997,0.000512,0.0005445000000000001,0.0005780000000000001,0.0006125000000000001,0.0006479999999999999,0.0006844999999999999,0.000722,0.0007605,0.0008,0.0008405000000000001,0.0008820000000000001,0.0009244999999999999,0.0009679999999999999,0.0010125,0.001058,0.0011045,0.001152,0.0012005000000000002,0.0012500000000000002,0.0013004999999999998,0.001352,0.0014045,0.0014579999999999999,0.0015125,0.0015680000000000002,0.0016245,0.0016820000000000001,0.0017404999999999999,0.0018,0.0018605,0.0019219999999999999,0.0019845,0.002048,0.0021125000000000002,0.0021780000000000002,0.0022445000000000004,0.0023120000000000003,0.0023805000000000002,0.0024500000000000004,0.0025204999999999997,0.0025919999999999997,0.0026644999999999998,0.0027379999999999995,0.0028125,0.002888,0.0029645,0.003042,0.0031205,0.0032,0.0032805,0.0033620000000000004,0.0034445000000000005,0.0035280000000000003,0.0036125000000000007,0.0036979999999999995,0.0037844999999999997,0.0038719999999999996,0.0039605,0.00405,0.0041405,0.004232,0.0043245,0.004418,0.0045125,0.004608,0.0047045,0.004802000000000001,0.0049005,0.005000000000000001,0.005100500000000001,0.005201999999999999,0.005304499999999999,0.005408,0.005512499999999999,0.005618,0.0057244999999999996,0.0058319999999999995,0.0059405,0.00605,0.0061605,0.006272000000000001,0.0063845,0.006498,0.0066125,0.0067280000000000005,0.006844500000000001,0.0069619999999999994,0.007080499999999999,0.0072,0.0073205,0.007442,0.0075645,0.0076879999999999995,0.0078125,0.007938,0.0080645,0.008192,0.0083205,0.008450000000000001,0.008580500000000001,0.008712000000000001,0.008844500000000002,0.008978000000000002,0.0091125,0.009248000000000001,0.009384500000000002,0.009522000000000001,0.009660500000000002,0.009800000000000001,0.009940499999999998,0.010081999999999999,0.010224499999999997,0.010367999999999999,0.0105125,0.010657999999999999,0.010804499999999998,0.010951999999999998,0.0111005,0.01125,0.0114005,0.011552,0.0117045,0.011858,0.0120125,0.012168,0.0123245,0.012482,0.0126405,0.0128,0.012960500000000002,0.013122,0.013284500000000001,0.013448000000000002,0.013612500000000001,0.013778000000000002,0.013944500000000002,0.014112000000000001,0.014280500000000002,0.014450000000000003,0.014620500000000002,0.014791999999999998,0.014964499999999999,0.015137999999999999,0.015312499999999998,0.015487999999999998,0.015664499999999998,0.015842,0.0160205,0.0162,0.0163805,0.016562,0.0167445,0.016928,0.0171125,0.017298,0.0174845,0.017672,0.0178605,0.01805,0.0182405,0.018432,0.018624500000000002,0.018818,0.0190125,0.019208000000000003,0.0194045,0.019602,0.019800500000000002,0.020000000000000004,0.020200500000000003,0.020402000000000003,0.0206045,0.020807999999999997,0.021012499999999996,0.021217999999999997,0.0214245,0.021632,0.0218405,0.022049999999999997,0.0222605,0.022472,0.0226845,0.022897999999999998,0.023112499999999998,0.023327999999999998,0.0235445,0.023762,0.0239805,0.0242,0.0244205,0.024642,0.0248645,0.025088000000000003,0.0253125,0.025538,0.025764500000000003,0.025992,0.0262205,0.02645,0.026680500000000003,0.026912000000000002,0.027144500000000002,0.027378000000000003,0.027612499999999998,0.027847999999999998,0.0280845,0.028321999999999996,0.0285605,0.0288,0.029040499999999997,0.029282,0.0295245,0.029768,0.030012499999999998,0.030258,0.0305045,0.030751999999999998,0.0310005,0.03125,0.0315005,0.031752,0.0320045,0.032258,0.0325125,0.032768,0.0330245,0.033282,0.0335405,0.033800000000000004,0.0340605,0.034322000000000005,0.034584500000000004,0.034848000000000004,0.035112500000000005,0.03537800000000001,0.0356445,0.035912000000000006,0.036180500000000004,0.03645,0.0367205,0.036992000000000004,0.037264500000000006,0.03753800000000001,0.037812500000000006,0.038088000000000004,0.03836450000000001,0.03864200000000001,0.03892050000000001,0.039200000000000006,0.03948050000000001,0.03976199999999999,0.04004449999999999,0.040327999999999996,0.040612499999999996,0.04089799999999999,0.04118449999999999,0.041471999999999995,0.04176049999999999,0.04205,0.042340499999999996,0.042631999999999996,0.0429245,0.04321799999999999,0.043512499999999996,0.04380799999999999,0.0441045,0.044402,0.0447005,0.045,0.045300499999999994,0.045602,0.0459045,0.046208,0.0465125,0.046818,0.0471245,0.047432,0.0477405,0.04805,0.0483605,0.048672,0.0489845,0.049298,0.049612500000000004,0.049928,0.050244500000000004,0.050562,0.0508805,0.0512,0.051520500000000004,0.051842000000000006,0.0521645,0.052488,0.052812500000000005,0.053138000000000005,0.053464500000000005,0.053792000000000006,0.0541205,0.054450000000000005,0.0547805,0.05511200000000001,0.05544450000000001,0.05577800000000001,0.05611250000000001,0.056448000000000005,0.05678450000000001,0.057122000000000006,0.057460500000000005,0.05780000000000001,0.05814050000000001,0.058482000000000006,0.05882450000000001,0.05916799999999999,0.05951249999999999,0.059857999999999995,0.060204499999999994,0.060551999999999995,0.06090049999999999,0.06124999999999999,0.061600499999999996,0.06195199999999999,0.06230449999999999,0.06265799999999999,0.0630125,0.063368,0.06372449999999999,0.064082,0.0644405,0.0648,0.0651605,0.065522,0.0658845,0.066248,0.06661249999999999,0.066978,0.0673445,0.067712,0.0680805,0.06845,0.06882049999999999,0.069192,0.0695645,0.069938,0.0703125,0.070688,0.0710645,0.071442,0.0718205,0.0722,0.0725805,0.072962,0.0733445,0.073728,0.0741125,0.07449800000000001,0.0748845,0.075272,0.0756605,0.07605,0.07644050000000001,0.07683200000000001,0.0772245,0.077618,0.07801250000000001,0.078408,0.07880450000000001,0.07920200000000001,0.0796005,0.08000000000000002,0.08040050000000001,0.08080200000000001,0.08120450000000001,0.08160800000000001,0.08201250000000002,0.082418,0.0828245,0.08323199999999999,0.08364049999999999,0.08404999999999999,0.0844605,0.08487199999999999,0.08528449999999999,0.085698,0.0861125,0.086528,0.0869445,0.087362,0.0877805,0.08819999999999999,0.08862049999999999,0.089042,0.08946449999999999,0.089888,0.09031249999999999,0.090738,0.0911645,0.09159199999999999,0.09202049999999999,0.09244999999999999,0.09288049999999999,0.09331199999999999,0.0937445,0.094178,0.0946125,0.095048,0.0954845,0.095922,0.0963605,0.0968,0.09724050000000001,0.097682,0.0981245,0.098568,0.0990125,0.099458,0.09990450000000001,0.10035200000000001,0.1008005,0.10125,0.1017005,0.102152,0.1026045,0.10305800000000001,0.10351250000000001,0.103968,0.1044245,0.104882,0.1053405,0.1058,0.10626050000000001,0.10672200000000001,0.10718450000000002,0.10764800000000001,0.10811250000000001,0.10857800000000001,0.10904450000000002,0.10951200000000001,0.10998049999999998,0.11044999999999999,0.11092049999999999,0.11139199999999999,0.11186449999999999,0.112338,0.1128125,0.11328799999999999,0.11376449999999999,0.114242,0.11472049999999999,0.1152,0.11568049999999999,0.11616199999999999,0.1166445,0.117128,0.1176125,0.118098,0.1185845,0.119072,0.1195605,0.12004999999999999,0.1205405,0.121032,0.1215245,0.122018,0.1225125,0.12300799999999999,0.1235045,0.124002,0.1245005,0.125,0.1255005,0.126002,0.1265045,0.127008,0.1275125,0.128018,0.1285245,0.129032,0.1295405,0.13005,0.1305605,0.131072,0.1315845,0.132098,0.1326125,0.133128,0.1336445,0.134162,0.1346805,0.13520000000000001,0.13572050000000002,0.136242,0.1367645,0.13728800000000002,0.1378125,0.13833800000000002,0.1388645,0.13939200000000002,0.1399205,0.14045000000000002,0.1409805,0.14151200000000003,0.14204450000000002,0.142578,0.1431125,0.14364800000000003,0.14418450000000002,0.14472200000000002,0.14526050000000001,0.1458,0.1463405,0.146882,0.1474245,0.14796800000000002,0.14851250000000002,0.14905800000000002,0.14960450000000003,0.15015200000000004,0.15070050000000001,0.15125000000000002,0.15180050000000003,0.15235200000000002,0.15290450000000003,0.15345800000000004,0.15401250000000002,0.15456800000000004,0.15512450000000003,0.15568200000000004,0.15624050000000003,0.15680000000000002,0.15736050000000004,0.15792200000000003,0.15848449999999997,0.15904799999999997,0.15961249999999996,0.16017799999999996,0.16074449999999998,0.16131199999999998,0.16188049999999998,0.16244999999999998,0.16302049999999998,0.16359199999999996,0.16416449999999996,0.16473799999999997,0.16531249999999997,0.16588799999999998,0.1664645,0.16704199999999997,0.16762049999999998,0.1682,0.16878049999999997,0.16936199999999998,0.16994449999999997,0.17052799999999999,0.17111249999999997,0.171698,0.17228449999999998,0.17287199999999997,0.1734605,0.17404999999999998,0.17464049999999998,0.17523199999999997,0.1758245,0.176418,0.1770125,0.177608,0.1782045,0.178802,0.1794005,0.18,0.1806005,0.18120199999999997,0.18180449999999998,0.182408,0.1830125,0.183618,0.18422449999999999,0.184832,0.18544049999999998,0.18605,0.18666049999999998,0.187272,0.18788449999999998,0.188498,0.1891125,0.189728,0.1903445,0.190962,0.1915805,0.1922,0.1928205,0.193442,0.1940645,0.194688,0.1953125,0.195938,0.1965645,0.197192,0.1978205,0.19845000000000002,0.1990805,0.199712,0.2003445,0.20097800000000002,0.2016125,0.202248,0.2028845,0.203522,0.2041605,0.2048,0.2054405,0.20608200000000002,0.2067245,0.20736800000000002,0.20801250000000002,0.208658,0.2093045,0.209952,0.21060050000000002,0.21125000000000002,0.21190050000000002,0.21255200000000002,0.21320450000000002,0.21385800000000002,0.21451250000000002,0.21516800000000003,0.21582450000000003,0.216482,0.21714050000000001,0.21780000000000002,0.21846050000000003,0.219122,0.21978450000000002,0.22044800000000003,0.22111250000000002,0.22177800000000003,0.22244450000000002,0.22311200000000003,0.22378050000000002,0.22445000000000004,0.22512050000000003,0.22579200000000002,0.22646450000000004,0.22713800000000003,0.22781250000000003,0.22848800000000002,0.22916450000000002,0.22984200000000002,0.23052050000000004,0.23120000000000004,0.23188050000000004,0.23256200000000005,0.23324450000000005,0.23392800000000002,0.23461250000000003,0.23529800000000003,0.23598450000000004,0.23667199999999997,0.23736049999999997,0.23804999999999996,0.23874049999999997,0.23943199999999998,0.24012449999999996,0.24081799999999998,0.24151249999999996,0.24220799999999998,0.24290449999999997,0.24360199999999996,0.24430049999999998,0.24499999999999997,0.24570049999999996,0.24640199999999998,0.24710449999999998,0.24780799999999997,0.24851249999999997,0.24921799999999997,0.24992449999999997,0.25063199999999997,0.25134049999999997,0.25205,0.2527605,0.253472,0.2541845,0.25489799999999996,0.25561249999999996,0.256328,0.25704449999999995,0.257762,0.2584805,0.2592,0.2599205,0.260642,0.2613645,0.262088,0.2628125,0.263538,0.26426449999999996,0.264992,0.26572049999999997,0.26644999999999996,0.2671805,0.267912,0.2686445,0.269378,0.2701125,0.270848,0.2715845,0.272322,0.2730605,0.2738,0.2745405,0.27528199999999997,0.2760245,0.276768,0.2775125,0.278258,0.2790045,0.279752,0.2805005,0.28125,0.2820005,0.282752,0.2835045,0.284258,0.2850125,0.285768,0.2865245,0.287282,0.28804050000000003,0.2888,0.2895605,0.290322,0.2910845,0.291848,0.2926125,0.293378,0.29414450000000003,0.294912,0.2956805,0.29645,0.2972205,0.29799200000000003,0.2987645,0.299538,0.30031250000000004,0.301088,0.30186450000000004,0.302642,0.30342050000000004,0.3042,0.30498050000000004,0.30576200000000003,0.3065445,0.30732800000000005,0.3081125,0.308898,0.30968450000000003,0.310472,0.31126050000000005,0.31205000000000005,0.3128405,0.313632,0.31442450000000005,0.31521800000000005,0.31601250000000003,0.31680800000000003,0.3176045,0.318402,0.31920050000000005,0.32000000000000006,0.32080050000000004,0.32160200000000005,0.32240450000000004,0.32320800000000005,0.32401250000000004,0.32481800000000005,0.32562450000000004,0.32643200000000006,0.32724050000000005,0.32805000000000006,0.32886050000000006,0.329672,0.33048449999999996,0.331298,0.3321125,0.33292799999999995,0.33374449999999994,0.33456199999999997,0.33538049999999997,0.33619999999999994,0.33702049999999995,0.337842,0.3386645,0.33948799999999996,0.34031249999999996,0.34113799999999994,0.34196449999999995,0.342792,0.34362049999999994,0.34445,0.3452805,0.346112,0.3469445,0.347778,0.3486125,0.349448,0.3502845,0.351122,0.35196049999999995,0.35279999999999995,0.35364049999999997,0.35448199999999996,0.3553245,0.356168,0.35701249999999995,0.35785799999999995,0.3587045,0.359552,0.36040049999999996,0.36124999999999996,0.3621005,0.362952,0.3638045,0.364658,0.36551249999999996,0.36636799999999997,0.3672245,0.36808199999999996,0.3689405,0.36979999999999996,0.3706605,0.37152199999999996,0.3723845,0.37324799999999997,0.3741125,0.374978,0.37584449999999997,0.376712,0.3775805,0.37845,0.3793205,0.380192,0.3810645,0.381938,0.3828125,0.383688,0.3845645,0.385442,0.3863205,0.3872,0.3880805,0.38896200000000003,0.3898445,0.390728,0.39161250000000003,0.392498,0.3933845,0.394272,0.3951605,0.39605,0.39694050000000003,0.397832,0.39872450000000004,0.39961800000000003,0.4005125,0.40140800000000004,0.4023045,0.403202,0.40410050000000003,0.405,0.4059005,0.406802,0.4077045,0.408608,0.4095125,0.410418,0.41132450000000004,0.41223200000000004,0.4131405,0.41405000000000003,0.4149605,0.415872,0.41678450000000006,0.417698,0.41861250000000005,0.419528,0.42044450000000005,0.421362,0.42228050000000006,0.4232,0.4241205,0.42504200000000003,0.4259645,0.42688800000000005,0.42781250000000004,0.42873800000000006,0.42966450000000006,0.43059200000000003,0.43152050000000003,0.43245000000000006,0.43338050000000006,0.43431200000000003,0.43524450000000003,0.43617800000000007,0.43711250000000007,0.43804800000000005,0.43898450000000006,0.4399219999999999,0.44086049999999993,0.44179999999999997,0.4427404999999999,0.44368199999999997,0.4446245,0.44556799999999996,0.4465125,0.44745799999999997,0.44840449999999993,0.449352,0.45030049999999994,0.45125,0.45220049999999995,0.45315199999999994,0.45410449999999997,0.45505799999999996,0.4560125,0.456968,0.45792449999999996,0.45888199999999996,0.4598405,0.4608,0.46176049999999996,0.46272199999999997,0.46368449999999994,0.46464799999999995,0.4656125,0.466578,0.4675445,0.468512,0.46948049999999997,0.47045,0.47142049999999996,0.472392,0.47336449999999997,0.474338,0.47531249999999997,0.476288,0.4772645,0.478242,0.4792205,0.48019999999999996,0.4811805,0.482162,0.4831445,0.484128,0.4851125,0.486098,0.4870845,0.488072,0.4890605,0.49005,0.4910405,0.49203199999999997,0.4930245,0.494018,0.4950125,0.496008,0.4970045,0.498002,0.4990005,0.5,0.5010004999999998,0.502002,0.5030044999999999,0.504008,0.5050124999999999,0.506018,0.5070244999999999,0.508032,0.5090404999999999,0.51005,0.5110604999999999,0.512072,0.5130844999999999,0.514098,0.5151124999999999,0.516128,0.5171444999999999,0.518162,0.5191804999999999,0.5202,0.5212204999999999,0.522242,0.5232644999999999,0.524288,0.5253125,0.526338,0.5273644999999999,0.528392,0.5294205,0.53045,0.5314804999999999,0.532512,0.5335444999999999,0.534578,0.5356124999999999,0.536648,0.5376844999999999,0.538722,0.5397604999999999,0.5408000000000001,0.5418405,0.5428820000000001,0.5439244999999999,0.544968,0.5460124999999999,0.547058,0.5481044999999999,0.5491520000000001,0.5502005,0.55125,0.5523005,0.5533520000000001,0.5544045,0.555458,0.5565125,0.5575680000000001,0.5586245,0.559682,0.5607405,0.5618000000000001,0.5628605,0.563922,0.5649844999999999,0.5660480000000001,0.5671124999999999,0.5681780000000001,0.5692444999999999,0.570312,0.5713805,0.57245,0.5735205,0.5745920000000001,0.5756644999999999,0.5767380000000001,0.5778125,0.5788880000000001,0.5799645,0.5810420000000001,0.5821204999999999,0.5832,0.5842805,0.585362,0.5864444999999999,0.587528,0.5886125,0.589698,0.5907844999999999,0.5918720000000001,0.5929605,0.5940500000000001,0.5951405,0.5962320000000001,0.5973244999999999,0.5984180000000001,0.5995125,0.6006080000000001,0.6017045,0.6028020000000001,0.6039005,0.6050000000000001,0.6061004999999999,0.6072020000000001,0.6083045,0.6094080000000001,0.6105125,0.6116180000000001,0.6127245,0.6138320000000002,0.6149405,0.6160500000000001,0.6171605,0.6182720000000002,0.6193845,0.6204980000000001,0.6216125,0.6227280000000002,0.6238445,0.6249620000000001,0.6260805,0.6272000000000001,0.6283205,0.6294420000000002,0.6305645,0.6316880000000001,0.6328125,0.6339379999999999,0.6350645,0.6361919999999999,0.6373205,0.6384499999999999,0.6395805,0.6407119999999998,0.6418445,0.6429779999999999,0.6441125,0.6452479999999999,0.6463845,0.6475219999999999,0.6486605,0.6497999999999999,0.6509405,0.6520819999999999,0.6532245,0.6543679999999998,0.6555125,0.6566579999999999,0.6578045,0.6589519999999999,0.6601005,0.6612499999999999,0.6624005000000001,0.6635519999999999,0.6647045,0.665858,0.6670125,0.6681679999999999,0.6693245,0.6704819999999999,0.6716405000000001,0.6728,0.6739605000000001,0.6751219999999999,0.6762845000000001,0.6774479999999999,0.6786125000000001,0.6797779999999999,0.6809445000000001,0.6821119999999999,0.6832805000000001,0.6844499999999999,0.6856205000000001,0.686792,0.6879645000000001,0.6891379999999999,0.6903125000000001,0.6914879999999999,0.6926645,0.693842,0.6950205,0.6961999999999999,0.6973805000000001,0.6985619999999999,0.6997445000000001,0.7009279999999999,0.7021125,0.703298,0.7044845000000001,0.705672,0.7068605000000001,0.70805,0.7092405,0.710432,0.7116245000000001,0.712818,0.7140125,0.715208,0.7164045000000001,0.717602,0.7188005000000001,0.72], + "points": [-1.2,-1.199,-1.198,-1.197,-1.196,-1.195,-1.194,-1.193,-1.192,-1.191,-1.19,-1.189,-1.188,-1.187,-1.186,-1.185,-1.184,-1.183,-1.182,-1.181,-1.18,-1.179,-1.178,-1.177,-1.176,-1.175,-1.174,-1.173,-1.172,-1.171,-1.17,-1.169,-1.168,-1.167,-1.166,-1.165,-1.164,-1.163,-1.162,-1.161,-1.16,-1.159,-1.158,-1.157,-1.156,-1.155,-1.154,-1.153,-1.152,-1.151,-1.15,-1.149,-1.148,-1.147,-1.146,-1.145,-1.144,-1.143,-1.142,-1.141,-1.14,-1.139,-1.138,-1.137,-1.136,-1.135,-1.134,-1.133,-1.132,-1.131,-1.13,-1.129,-1.128,-1.127,-1.126,-1.125,-1.124,-1.123,-1.122,-1.121,-1.12,-1.119,-1.118,-1.117,-1.116,-1.115,-1.114,-1.113,-1.112,-1.111,-1.11,-1.109,-1.108,-1.107,-1.106,-1.105,-1.104,-1.103,-1.102,-1.101,-1.1,-1.099,-1.098,-1.097,-1.096,-1.095,-1.094,-1.093,-1.092,-1.091,-1.09,-1.089,-1.088,-1.087,-1.086,-1.085,-1.084,-1.083,-1.082,-1.081,-1.08,-1.079,-1.078,-1.077,-1.076,-1.075,-1.074,-1.073,-1.072,-1.071,-1.07,-1.069,-1.068,-1.067,-1.066,-1.065,-1.064,-1.063,-1.062,-1.061,-1.06,-1.059,-1.058,-1.057,-1.056,-1.055,-1.054,-1.053,-1.052,-1.051,-1.05,-1.049,-1.048,-1.047,-1.046,-1.045,-1.044,-1.043,-1.042,-1.041,-1.04,-1.039,-1.038,-1.037,-1.036,-1.035,-1.034,-1.033,-1.032,-1.031,-1.03,-1.029,-1.028,-1.027,-1.026,-1.025,-1.024,-1.023,-1.022,-1.021,-1.02,-1.019,-1.018,-1.017,-1.016,-1.015,-1.014,-1.013,-1.012,-1.011,-1.01,-1.009,-1.008,-1.007,-1.006,-1.005,-1.004,-1.003,-1.002,-1.001,-1.0,-0.999,-0.998,-0.997,-0.996,-0.995,-0.994,-0.993,-0.992,-0.991,-0.99,-0.989,-0.988,-0.987,-0.986,-0.985,-0.984,-0.983,-0.982,-0.981,-0.98,-0.979,-0.978,-0.977,-0.976,-0.975,-0.974,-0.973,-0.972,-0.971,-0.97,-0.969,-0.968,-0.967,-0.966,-0.965,-0.964,-0.963,-0.962,-0.961,-0.96,-0.959,-0.958,-0.957,-0.956,-0.955,-0.954,-0.953,-0.952,-0.951,-0.95,-0.949,-0.948,-0.947,-0.946,-0.945,-0.944,-0.943,-0.942,-0.941,-0.94,-0.939,-0.938,-0.937,-0.936,-0.935,-0.934,-0.933,-0.932,-0.931,-0.93,-0.929,-0.928,-0.927,-0.926,-0.925,-0.924,-0.923,-0.922,-0.921,-0.92,-0.919,-0.918,-0.917,-0.916,-0.915,-0.914,-0.913,-0.912,-0.911,-0.91,-0.909,-0.908,-0.907,-0.906,-0.905,-0.904,-0.903,-0.902,-0.901,-0.9,-0.899,-0.898,-0.897,-0.896,-0.895,-0.894,-0.893,-0.892,-0.891,-0.89,-0.889,-0.888,-0.887,-0.886,-0.885,-0.884,-0.883,-0.882,-0.881,-0.88,-0.879,-0.878,-0.877,-0.876,-0.875,-0.874,-0.873,-0.872,-0.871,-0.87,-0.869,-0.868,-0.867,-0.866,-0.865,-0.864,-0.863,-0.862,-0.861,-0.86,-0.859,-0.858,-0.857,-0.856,-0.855,-0.854,-0.853,-0.852,-0.851,-0.85,-0.849,-0.848,-0.847,-0.846,-0.845,-0.844,-0.843,-0.842,-0.841,-0.84,-0.839,-0.838,-0.837,-0.836,-0.835,-0.834,-0.833,-0.832,-0.831,-0.83,-0.829,-0.828,-0.827,-0.826,-0.825,-0.824,-0.823,-0.822,-0.821,-0.82,-0.819,-0.818,-0.817,-0.816,-0.815,-0.814,-0.813,-0.812,-0.811,-0.81,-0.809,-0.808,-0.807,-0.806,-0.805,-0.804,-0.803,-0.802,-0.801,-0.8,-0.799,-0.798,-0.797,-0.796,-0.795,-0.794,-0.793,-0.792,-0.791,-0.79,-0.789,-0.788,-0.787,-0.786,-0.785,-0.784,-0.783,-0.782,-0.781,-0.78,-0.779,-0.778,-0.777,-0.776,-0.775,-0.774,-0.773,-0.772,-0.771,-0.77,-0.769,-0.768,-0.767,-0.766,-0.765,-0.764,-0.763,-0.762,-0.761,-0.76,-0.759,-0.758,-0.757,-0.756,-0.755,-0.754,-0.753,-0.752,-0.751,-0.75,-0.749,-0.748,-0.747,-0.746,-0.745,-0.744,-0.743,-0.742,-0.741,-0.74,-0.739,-0.738,-0.737,-0.736,-0.735,-0.734,-0.733,-0.732,-0.731,-0.73,-0.729,-0.728,-0.727,-0.726,-0.725,-0.724,-0.723,-0.722,-0.721,-0.72,-0.719,-0.718,-0.717,-0.716,-0.715,-0.714,-0.713,-0.712,-0.711,-0.71,-0.709,-0.708,-0.707,-0.706,-0.705,-0.704,-0.703,-0.702,-0.701,-0.7,-0.699,-0.698,-0.697,-0.696,-0.695,-0.694,-0.693,-0.692,-0.691,-0.69,-0.689,-0.688,-0.687,-0.686,-0.685,-0.684,-0.683,-0.682,-0.681,-0.68,-0.679,-0.678,-0.677,-0.676,-0.675,-0.674,-0.673,-0.672,-0.671,-0.67,-0.669,-0.668,-0.667,-0.666,-0.665,-0.664,-0.663,-0.662,-0.661,-0.66,-0.659,-0.658,-0.657,-0.656,-0.655,-0.654,-0.653,-0.652,-0.651,-0.65,-0.649,-0.648,-0.647,-0.646,-0.645,-0.644,-0.643,-0.642,-0.641,-0.64,-0.639,-0.638,-0.637,-0.636,-0.635,-0.634,-0.633,-0.632,-0.631,-0.63,-0.629,-0.628,-0.627,-0.626,-0.625,-0.624,-0.623,-0.622,-0.621,-0.62,-0.619,-0.618,-0.617,-0.616,-0.615,-0.614,-0.613,-0.612,-0.611,-0.61,-0.609,-0.608,-0.607,-0.606,-0.605,-0.604,-0.603,-0.602,-0.601,-0.6,-0.599,-0.598,-0.597,-0.596,-0.595,-0.594,-0.593,-0.592,-0.591,-0.59,-0.589,-0.588,-0.587,-0.586,-0.585,-0.584,-0.583,-0.582,-0.581,-0.58,-0.579,-0.578,-0.577,-0.576,-0.575,-0.574,-0.573,-0.572,-0.571,-0.57,-0.569,-0.568,-0.567,-0.566,-0.565,-0.564,-0.563,-0.562,-0.561,-0.56,-0.559,-0.558,-0.557,-0.556,-0.555,-0.554,-0.553,-0.552,-0.551,-0.55,-0.549,-0.548,-0.547,-0.546,-0.545,-0.544,-0.543,-0.542,-0.541,-0.54,-0.539,-0.538,-0.537,-0.536,-0.535,-0.534,-0.533,-0.532,-0.531,-0.53,-0.529,-0.528,-0.527,-0.526,-0.525,-0.524,-0.523,-0.522,-0.521,-0.52,-0.519,-0.518,-0.517,-0.516,-0.515,-0.514,-0.513,-0.512,-0.511,-0.51,-0.509,-0.508,-0.507,-0.506,-0.505,-0.504,-0.503,-0.502,-0.501,-0.5,-0.499,-0.498,-0.497,-0.496,-0.495,-0.494,-0.493,-0.492,-0.491,-0.49,-0.489,-0.488,-0.487,-0.486,-0.485,-0.484,-0.483,-0.482,-0.481,-0.48,-0.479,-0.478,-0.477,-0.476,-0.475,-0.474,-0.473,-0.472,-0.471,-0.47,-0.469,-0.468,-0.467,-0.466,-0.465,-0.464,-0.463,-0.462,-0.461,-0.46,-0.459,-0.458,-0.457,-0.456,-0.455,-0.454,-0.453,-0.452,-0.451,-0.45,-0.449,-0.448,-0.447,-0.446,-0.445,-0.444,-0.443,-0.442,-0.441,-0.44,-0.439,-0.438,-0.437,-0.436,-0.435,-0.434,-0.433,-0.432,-0.431,-0.43,-0.429,-0.428,-0.427,-0.426,-0.425,-0.424,-0.423,-0.422,-0.421,-0.42,-0.419,-0.418,-0.417,-0.416,-0.415,-0.414,-0.413,-0.412,-0.411,-0.41,-0.409,-0.408,-0.407,-0.406,-0.405,-0.404,-0.403,-0.402,-0.401,-0.4,-0.399,-0.398,-0.397,-0.396,-0.395,-0.394,-0.393,-0.392,-0.391,-0.39,-0.389,-0.388,-0.387,-0.386,-0.385,-0.384,-0.383,-0.382,-0.381,-0.38,-0.379,-0.378,-0.377,-0.376,-0.375,-0.374,-0.373,-0.372,-0.371,-0.37,-0.369,-0.368,-0.367,-0.366,-0.365,-0.364,-0.363,-0.362,-0.361,-0.36,-0.359,-0.358,-0.357,-0.356,-0.355,-0.354,-0.353,-0.352,-0.351,-0.35,-0.349,-0.348,-0.347,-0.346,-0.345,-0.344,-0.343,-0.342,-0.341,-0.34,-0.339,-0.338,-0.337,-0.336,-0.335,-0.334,-0.333,-0.332,-0.331,-0.33,-0.329,-0.328,-0.327,-0.326,-0.325,-0.324,-0.323,-0.322,-0.321,-0.32,-0.319,-0.318,-0.317,-0.316,-0.315,-0.314,-0.313,-0.312,-0.311,-0.31,-0.309,-0.308,-0.307,-0.306,-0.305,-0.304,-0.303,-0.302,-0.301,-0.3,-0.299,-0.298,-0.297,-0.296,-0.295,-0.294,-0.293,-0.292,-0.291,-0.29,-0.289,-0.288,-0.287,-0.286,-0.285,-0.284,-0.283,-0.282,-0.281,-0.28,-0.279,-0.278,-0.277,-0.276,-0.275,-0.274,-0.273,-0.272,-0.271,-0.27,-0.269,-0.268,-0.267,-0.266,-0.265,-0.264,-0.263,-0.262,-0.261,-0.26,-0.259,-0.258,-0.257,-0.256,-0.255,-0.254,-0.253,-0.252,-0.251,-0.25,-0.249,-0.248,-0.247,-0.246,-0.245,-0.244,-0.243,-0.242,-0.241,-0.24,-0.239,-0.238,-0.237,-0.236,-0.235,-0.234,-0.233,-0.232,-0.231,-0.23,-0.229,-0.228,-0.227,-0.226,-0.225,-0.224,-0.223,-0.222,-0.221,-0.22,-0.219,-0.218,-0.217,-0.216,-0.215,-0.214,-0.213,-0.212,-0.211,-0.21,-0.209,-0.208,-0.207,-0.206,-0.205,-0.204,-0.203,-0.202,-0.201,-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2,0.201,0.202,0.203,0.204,0.205,0.206,0.207,0.208,0.209,0.21,0.211,0.212,0.213,0.214,0.215,0.216,0.217,0.218,0.219,0.22,0.221,0.222,0.223,0.224,0.225,0.226,0.227,0.228,0.229,0.23,0.231,0.232,0.233,0.234,0.235,0.236,0.237,0.238,0.239,0.24,0.241,0.242,0.243,0.244,0.245,0.246,0.247,0.248,0.249,0.25,0.251,0.252,0.253,0.254,0.255,0.256,0.257,0.258,0.259,0.26,0.261,0.262,0.263,0.264,0.265,0.266,0.267,0.268,0.269,0.27,0.271,0.272,0.273,0.274,0.275,0.276,0.277,0.278,0.279,0.28,0.281,0.282,0.283,0.284,0.285,0.286,0.287,0.288,0.289,0.29,0.291,0.292,0.293,0.294,0.295,0.296,0.297,0.298,0.299,0.3,0.301,0.302,0.303,0.304,0.305,0.306,0.307,0.308,0.309,0.31,0.311,0.312,0.313,0.314,0.315,0.316,0.317,0.318,0.319,0.32,0.321,0.322,0.323,0.324,0.325,0.326,0.327,0.328,0.329,0.33,0.331,0.332,0.333,0.334,0.335,0.336,0.337,0.338,0.339,0.34,0.341,0.342,0.343,0.344,0.345,0.346,0.347,0.348,0.349,0.35,0.351,0.352,0.353,0.354,0.355,0.356,0.357,0.358,0.359,0.36,0.361,0.362,0.363,0.364,0.365,0.366,0.367,0.368,0.369,0.37,0.371,0.372,0.373,0.374,0.375,0.376,0.377,0.378,0.379,0.38,0.381,0.382,0.383,0.384,0.385,0.386,0.387,0.388,0.389,0.39,0.391,0.392,0.393,0.394,0.395,0.396,0.397,0.398,0.399,0.4,0.401,0.402,0.403,0.404,0.405,0.406,0.407,0.408,0.409,0.41,0.411,0.412,0.413,0.414,0.415,0.416,0.417,0.418,0.419,0.42,0.421,0.422,0.423,0.424,0.425,0.426,0.427,0.428,0.429,0.43,0.431,0.432,0.433,0.434,0.435,0.436,0.437,0.438,0.439,0.44,0.441,0.442,0.443,0.444,0.445,0.446,0.447,0.448,0.449,0.45,0.451,0.452,0.453,0.454,0.455,0.456,0.457,0.458,0.459,0.46,0.461,0.462,0.463,0.464,0.465,0.466,0.467,0.468,0.469,0.47,0.471,0.472,0.473,0.474,0.475,0.476,0.477,0.478,0.479,0.48,0.481,0.482,0.483,0.484,0.485,0.486,0.487,0.488,0.489,0.49,0.491,0.492,0.493,0.494,0.495,0.496,0.497,0.498,0.499,0.5,0.501,0.502,0.503,0.504,0.505,0.506,0.507,0.508,0.509,0.51,0.511,0.512,0.513,0.514,0.515,0.516,0.517,0.518,0.519,0.52,0.521,0.522,0.523,0.524,0.525,0.526,0.527,0.528,0.529,0.53,0.531,0.532,0.533,0.534,0.535,0.536,0.537,0.538,0.539,0.54,0.541,0.542,0.543,0.544,0.545,0.546,0.547,0.548,0.549,0.55,0.551,0.552,0.553,0.554,0.555,0.556,0.557,0.558,0.559,0.56,0.561,0.562,0.563,0.564,0.565,0.566,0.567,0.568,0.569,0.57,0.571,0.572,0.573,0.574,0.575,0.576,0.577,0.578,0.579,0.58,0.581,0.582,0.583,0.584,0.585,0.586,0.587,0.588,0.589,0.59,0.591,0.592,0.593,0.594,0.595,0.596,0.597,0.598,0.599,0.6,0.601,0.602,0.603,0.604,0.605,0.606,0.607,0.608,0.609,0.61,0.611,0.612,0.613,0.614,0.615,0.616,0.617,0.618,0.619,0.62,0.621,0.622,0.623,0.624,0.625,0.626,0.627,0.628,0.629,0.63,0.631,0.632,0.633,0.634,0.635,0.636,0.637,0.638,0.639,0.64,0.641,0.642,0.643,0.644,0.645,0.646,0.647,0.648,0.649,0.65,0.651,0.652,0.653,0.654,0.655,0.656,0.657,0.658,0.659,0.66,0.661,0.662,0.663,0.664,0.665,0.666,0.667,0.668,0.669,0.67,0.671,0.672,0.673,0.674,0.675,0.676,0.677,0.678,0.679,0.68,0.681,0.682,0.683,0.684,0.685,0.686,0.687,0.688,0.689,0.69,0.691,0.692,0.693,0.694,0.695,0.696,0.697,0.698,0.699,0.7,0.701,0.702,0.703,0.704,0.705,0.706,0.707,0.708,0.709,0.71,0.711,0.712,0.713,0.714,0.715,0.716,0.717,0.718,0.719,0.72,0.721,0.722,0.723,0.724,0.725,0.726,0.727,0.728,0.729,0.73,0.731,0.732,0.733,0.734,0.735,0.736,0.737,0.738,0.739,0.74,0.741,0.742,0.743,0.744,0.745,0.746,0.747,0.748,0.749,0.75,0.751,0.752,0.753,0.754,0.755,0.756,0.757,0.758,0.759,0.76,0.761,0.762,0.763,0.764,0.765,0.766,0.767,0.768,0.769,0.77,0.771,0.772,0.773,0.774,0.775,0.776,0.777,0.778,0.779,0.78,0.781,0.782,0.783,0.784,0.785,0.786,0.787,0.788,0.789,0.79,0.791,0.792,0.793,0.794,0.795,0.796,0.797,0.798,0.799,0.8,0.801,0.802,0.803,0.804,0.805,0.806,0.807,0.808,0.809,0.81,0.811,0.812,0.813,0.814,0.815,0.816,0.817,0.818,0.819,0.82,0.821,0.822,0.823,0.824,0.825,0.826,0.827,0.828,0.829,0.83,0.831,0.832,0.833,0.834,0.835,0.836,0.837,0.838,0.839,0.84,0.841,0.842,0.843,0.844,0.845,0.846,0.847,0.848,0.849,0.85,0.851,0.852,0.853,0.854,0.855,0.856,0.857,0.858,0.859,0.86,0.861,0.862,0.863,0.864,0.865,0.866,0.867,0.868,0.869,0.87,0.871,0.872,0.873,0.874,0.875,0.876,0.877,0.878,0.879,0.88,0.881,0.882,0.883,0.884,0.885,0.886,0.887,0.888,0.889,0.89,0.891,0.892,0.893,0.894,0.895,0.896,0.897,0.898,0.899,0.9,0.901,0.902,0.903,0.904,0.905,0.906,0.907,0.908,0.909,0.91,0.911,0.912,0.913,0.914,0.915,0.916,0.917,0.918,0.919,0.92,0.921,0.922,0.923,0.924,0.925,0.926,0.927,0.928,0.929,0.93,0.931,0.932,0.933,0.934,0.935,0.936,0.937,0.938,0.939,0.94,0.941,0.942,0.943,0.944,0.945,0.946,0.947,0.948,0.949,0.95,0.951,0.952,0.953,0.954,0.955,0.956,0.957,0.958,0.959,0.96,0.961,0.962,0.963,0.964,0.965,0.966,0.967,0.968,0.969,0.97,0.971,0.972,0.973,0.974,0.975,0.976,0.977,0.978,0.979,0.98,0.981,0.982,0.983,0.984,0.985,0.986,0.987,0.988,0.989,0.99,0.991,0.992,0.993,0.994,0.995,0.996,0.997,0.998,0.999,1.0,1.001,1.002,1.003,1.004,1.005,1.006,1.007,1.008,1.009,1.01,1.011,1.012,1.013,1.014,1.015,1.016,1.017,1.018,1.019,1.02,1.021,1.022,1.023,1.024,1.025,1.026,1.027,1.028,1.029,1.03,1.031,1.032,1.033,1.034,1.035,1.036,1.037,1.038,1.039,1.04,1.041,1.042,1.043,1.044,1.045,1.046,1.047,1.048,1.049,1.05,1.051,1.052,1.053,1.054,1.055,1.056,1.057,1.058,1.059,1.06,1.061,1.062,1.063,1.064,1.065,1.066,1.067,1.068,1.069,1.07,1.071,1.072,1.073,1.074,1.075,1.076,1.077,1.078,1.079,1.08,1.081,1.082,1.083,1.084,1.085,1.086,1.087,1.088,1.089,1.09,1.091,1.092,1.093,1.094,1.095,1.096,1.097,1.098,1.099,1.1,1.101,1.102,1.103,1.104,1.105,1.106,1.107,1.108,1.109,1.11,1.111,1.112,1.113,1.114,1.115,1.116,1.117,1.118,1.119,1.12,1.121,1.122,1.123,1.124,1.125,1.126,1.127,1.128,1.129,1.13,1.131,1.132,1.133,1.134,1.135,1.136,1.137,1.138,1.139,1.14,1.141,1.142,1.143,1.144,1.145,1.146,1.147,1.148,1.149,1.15,1.151,1.152,1.153,1.154,1.155,1.156,1.157,1.158,1.159,1.16,1.161,1.162,1.163,1.164,1.165,1.166,1.167,1.168,1.169,1.17,1.171,1.172,1.173,1.174,1.175,1.176,1.177,1.178,1.179,1.18,1.181,1.182,1.183,1.184,1.185,1.186,1.187,1.188,1.189,1.19,1.191,1.192,1.193,1.194,1.195,1.196,1.197,1.198,1.199,1.2], + "mass": 1.0, + "deltaT": 0.006283185307179587, + "t": 0.0, + "config": {"hbar": 0.001, "includeIntegralFactor": true, "firstDerivativeMethod": 1, "limitDiffOrder":10}, + "representation": {"type": "PositionRepresentation", "points": {"first": -1.2, "step": 0.001, "last": 1.2}}, + "psi": { + "points": [-1.2,-1.199,-1.198,-1.197,-1.196,-1.195,-1.194,-1.193,-1.192,-1.191,-1.19,-1.189,-1.188,-1.187,-1.186,-1.185,-1.184,-1.183,-1.182,-1.181,-1.18,-1.179,-1.178,-1.177,-1.176,-1.175,-1.174,-1.173,-1.172,-1.171,-1.17,-1.169,-1.168,-1.167,-1.166,-1.165,-1.164,-1.163,-1.162,-1.161,-1.16,-1.159,-1.158,-1.157,-1.156,-1.155,-1.154,-1.153,-1.152,-1.151,-1.15,-1.149,-1.148,-1.147,-1.146,-1.145,-1.144,-1.143,-1.142,-1.141,-1.14,-1.139,-1.138,-1.137,-1.136,-1.135,-1.134,-1.133,-1.132,-1.131,-1.13,-1.129,-1.128,-1.127,-1.126,-1.125,-1.124,-1.123,-1.122,-1.121,-1.12,-1.119,-1.118,-1.117,-1.116,-1.115,-1.114,-1.113,-1.112,-1.111,-1.11,-1.109,-1.108,-1.107,-1.106,-1.105,-1.104,-1.103,-1.102,-1.101,-1.1,-1.099,-1.098,-1.097,-1.096,-1.095,-1.094,-1.093,-1.092,-1.091,-1.09,-1.089,-1.088,-1.087,-1.086,-1.085,-1.084,-1.083,-1.082,-1.081,-1.08,-1.079,-1.078,-1.077,-1.076,-1.075,-1.074,-1.073,-1.072,-1.071,-1.07,-1.069,-1.068,-1.067,-1.066,-1.065,-1.064,-1.063,-1.062,-1.061,-1.06,-1.059,-1.058,-1.057,-1.056,-1.055,-1.054,-1.053,-1.052,-1.051,-1.05,-1.049,-1.048,-1.047,-1.046,-1.045,-1.044,-1.043,-1.042,-1.041,-1.04,-1.039,-1.038,-1.037,-1.036,-1.035,-1.034,-1.033,-1.032,-1.031,-1.03,-1.029,-1.028,-1.027,-1.026,-1.025,-1.024,-1.023,-1.022,-1.021,-1.02,-1.019,-1.018,-1.017,-1.016,-1.015,-1.014,-1.013,-1.012,-1.011,-1.01,-1.009,-1.008,-1.007,-1.006,-1.005,-1.004,-1.003,-1.002,-1.001,-1.0,-0.999,-0.998,-0.997,-0.996,-0.995,-0.994,-0.993,-0.992,-0.991,-0.99,-0.989,-0.988,-0.987,-0.986,-0.985,-0.984,-0.983,-0.982,-0.981,-0.98,-0.979,-0.978,-0.977,-0.976,-0.975,-0.974,-0.973,-0.972,-0.971,-0.97,-0.969,-0.968,-0.967,-0.966,-0.965,-0.964,-0.963,-0.962,-0.961,-0.96,-0.959,-0.958,-0.957,-0.956,-0.955,-0.954,-0.953,-0.952,-0.951,-0.95,-0.949,-0.948,-0.947,-0.946,-0.945,-0.944,-0.943,-0.942,-0.941,-0.94,-0.939,-0.938,-0.937,-0.936,-0.935,-0.934,-0.933,-0.932,-0.931,-0.93,-0.929,-0.928,-0.927,-0.926,-0.925,-0.924,-0.923,-0.922,-0.921,-0.92,-0.919,-0.918,-0.917,-0.916,-0.915,-0.914,-0.913,-0.912,-0.911,-0.91,-0.909,-0.908,-0.907,-0.906,-0.905,-0.904,-0.903,-0.902,-0.901,-0.9,-0.899,-0.898,-0.897,-0.896,-0.895,-0.894,-0.893,-0.892,-0.891,-0.89,-0.889,-0.888,-0.887,-0.886,-0.885,-0.884,-0.883,-0.882,-0.881,-0.88,-0.879,-0.878,-0.877,-0.876,-0.875,-0.874,-0.873,-0.872,-0.871,-0.87,-0.869,-0.868,-0.867,-0.866,-0.865,-0.864,-0.863,-0.862,-0.861,-0.86,-0.859,-0.858,-0.857,-0.856,-0.855,-0.854,-0.853,-0.852,-0.851,-0.85,-0.849,-0.848,-0.847,-0.846,-0.845,-0.844,-0.843,-0.842,-0.841,-0.84,-0.839,-0.838,-0.837,-0.836,-0.835,-0.834,-0.833,-0.832,-0.831,-0.83,-0.829,-0.828,-0.827,-0.826,-0.825,-0.824,-0.823,-0.822,-0.821,-0.82,-0.819,-0.818,-0.817,-0.816,-0.815,-0.814,-0.813,-0.812,-0.811,-0.81,-0.809,-0.808,-0.807,-0.806,-0.805,-0.804,-0.803,-0.802,-0.801,-0.8,-0.799,-0.798,-0.797,-0.796,-0.795,-0.794,-0.793,-0.792,-0.791,-0.79,-0.789,-0.788,-0.787,-0.786,-0.785,-0.784,-0.783,-0.782,-0.781,-0.78,-0.779,-0.778,-0.777,-0.776,-0.775,-0.774,-0.773,-0.772,-0.771,-0.77,-0.769,-0.768,-0.767,-0.766,-0.765,-0.764,-0.763,-0.762,-0.761,-0.76,-0.759,-0.758,-0.757,-0.756,-0.755,-0.754,-0.753,-0.752,-0.751,-0.75,-0.749,-0.748,-0.747,-0.746,-0.745,-0.744,-0.743,-0.742,-0.741,-0.74,-0.739,-0.738,-0.737,-0.736,-0.735,-0.734,-0.733,-0.732,-0.731,-0.73,-0.729,-0.728,-0.727,-0.726,-0.725,-0.724,-0.723,-0.722,-0.721,-0.72,-0.719,-0.718,-0.717,-0.716,-0.715,-0.714,-0.713,-0.712,-0.711,-0.71,-0.709,-0.708,-0.707,-0.706,-0.705,-0.704,-0.703,-0.702,-0.701,-0.7,-0.699,-0.698,-0.697,-0.696,-0.695,-0.694,-0.693,-0.692,-0.691,-0.69,-0.689,-0.688,-0.687,-0.686,-0.685,-0.684,-0.683,-0.682,-0.681,-0.68,-0.679,-0.678,-0.677,-0.676,-0.675,-0.674,-0.673,-0.672,-0.671,-0.67,-0.669,-0.668,-0.667,-0.666,-0.665,-0.664,-0.663,-0.662,-0.661,-0.66,-0.659,-0.658,-0.657,-0.656,-0.655,-0.654,-0.653,-0.652,-0.651,-0.65,-0.649,-0.648,-0.647,-0.646,-0.645,-0.644,-0.643,-0.642,-0.641,-0.64,-0.639,-0.638,-0.637,-0.636,-0.635,-0.634,-0.633,-0.632,-0.631,-0.63,-0.629,-0.628,-0.627,-0.626,-0.625,-0.624,-0.623,-0.622,-0.621,-0.62,-0.619,-0.618,-0.617,-0.616,-0.615,-0.614,-0.613,-0.612,-0.611,-0.61,-0.609,-0.608,-0.607,-0.606,-0.605,-0.604,-0.603,-0.602,-0.601,-0.6,-0.599,-0.598,-0.597,-0.596,-0.595,-0.594,-0.593,-0.592,-0.591,-0.59,-0.589,-0.588,-0.587,-0.586,-0.585,-0.584,-0.583,-0.582,-0.581,-0.58,-0.579,-0.578,-0.577,-0.576,-0.575,-0.574,-0.573,-0.572,-0.571,-0.57,-0.569,-0.568,-0.567,-0.566,-0.565,-0.564,-0.563,-0.562,-0.561,-0.56,-0.559,-0.558,-0.557,-0.556,-0.555,-0.554,-0.553,-0.552,-0.551,-0.55,-0.549,-0.548,-0.547,-0.546,-0.545,-0.544,-0.543,-0.542,-0.541,-0.54,-0.539,-0.538,-0.537,-0.536,-0.535,-0.534,-0.533,-0.532,-0.531,-0.53,-0.529,-0.528,-0.527,-0.526,-0.525,-0.524,-0.523,-0.522,-0.521,-0.52,-0.519,-0.518,-0.517,-0.516,-0.515,-0.514,-0.513,-0.512,-0.511,-0.51,-0.509,-0.508,-0.507,-0.506,-0.505,-0.504,-0.503,-0.502,-0.501,-0.5,-0.499,-0.498,-0.497,-0.496,-0.495,-0.494,-0.493,-0.492,-0.491,-0.49,-0.489,-0.488,-0.487,-0.486,-0.485,-0.484,-0.483,-0.482,-0.481,-0.48,-0.479,-0.478,-0.477,-0.476,-0.475,-0.474,-0.473,-0.472,-0.471,-0.47,-0.469,-0.468,-0.467,-0.466,-0.465,-0.464,-0.463,-0.462,-0.461,-0.46,-0.459,-0.458,-0.457,-0.456,-0.455,-0.454,-0.453,-0.452,-0.451,-0.45,-0.449,-0.448,-0.447,-0.446,-0.445,-0.444,-0.443,-0.442,-0.441,-0.44,-0.439,-0.438,-0.437,-0.436,-0.435,-0.434,-0.433,-0.432,-0.431,-0.43,-0.429,-0.428,-0.427,-0.426,-0.425,-0.424,-0.423,-0.422,-0.421,-0.42,-0.419,-0.418,-0.417,-0.416,-0.415,-0.414,-0.413,-0.412,-0.411,-0.41,-0.409,-0.408,-0.407,-0.406,-0.405,-0.404,-0.403,-0.402,-0.401,-0.4,-0.399,-0.398,-0.397,-0.396,-0.395,-0.394,-0.393,-0.392,-0.391,-0.39,-0.389,-0.388,-0.387,-0.386,-0.385,-0.384,-0.383,-0.382,-0.381,-0.38,-0.379,-0.378,-0.377,-0.376,-0.375,-0.374,-0.373,-0.372,-0.371,-0.37,-0.369,-0.368,-0.367,-0.366,-0.365,-0.364,-0.363,-0.362,-0.361,-0.36,-0.359,-0.358,-0.357,-0.356,-0.355,-0.354,-0.353,-0.352,-0.351,-0.35,-0.349,-0.348,-0.347,-0.346,-0.345,-0.344,-0.343,-0.342,-0.341,-0.34,-0.339,-0.338,-0.337,-0.336,-0.335,-0.334,-0.333,-0.332,-0.331,-0.33,-0.329,-0.328,-0.327,-0.326,-0.325,-0.324,-0.323,-0.322,-0.321,-0.32,-0.319,-0.318,-0.317,-0.316,-0.315,-0.314,-0.313,-0.312,-0.311,-0.31,-0.309,-0.308,-0.307,-0.306,-0.305,-0.304,-0.303,-0.302,-0.301,-0.3,-0.299,-0.298,-0.297,-0.296,-0.295,-0.294,-0.293,-0.292,-0.291,-0.29,-0.289,-0.288,-0.287,-0.286,-0.285,-0.284,-0.283,-0.282,-0.281,-0.28,-0.279,-0.278,-0.277,-0.276,-0.275,-0.274,-0.273,-0.272,-0.271,-0.27,-0.269,-0.268,-0.267,-0.266,-0.265,-0.264,-0.263,-0.262,-0.261,-0.26,-0.259,-0.258,-0.257,-0.256,-0.255,-0.254,-0.253,-0.252,-0.251,-0.25,-0.249,-0.248,-0.247,-0.246,-0.245,-0.244,-0.243,-0.242,-0.241,-0.24,-0.239,-0.238,-0.237,-0.236,-0.235,-0.234,-0.233,-0.232,-0.231,-0.23,-0.229,-0.228,-0.227,-0.226,-0.225,-0.224,-0.223,-0.222,-0.221,-0.22,-0.219,-0.218,-0.217,-0.216,-0.215,-0.214,-0.213,-0.212,-0.211,-0.21,-0.209,-0.208,-0.207,-0.206,-0.205,-0.204,-0.203,-0.202,-0.201,-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2,0.201,0.202,0.203,0.204,0.205,0.206,0.207,0.208,0.209,0.21,0.211,0.212,0.213,0.214,0.215,0.216,0.217,0.218,0.219,0.22,0.221,0.222,0.223,0.224,0.225,0.226,0.227,0.228,0.229,0.23,0.231,0.232,0.233,0.234,0.235,0.236,0.237,0.238,0.239,0.24,0.241,0.242,0.243,0.244,0.245,0.246,0.247,0.248,0.249,0.25,0.251,0.252,0.253,0.254,0.255,0.256,0.257,0.258,0.259,0.26,0.261,0.262,0.263,0.264,0.265,0.266,0.267,0.268,0.269,0.27,0.271,0.272,0.273,0.274,0.275,0.276,0.277,0.278,0.279,0.28,0.281,0.282,0.283,0.284,0.285,0.286,0.287,0.288,0.289,0.29,0.291,0.292,0.293,0.294,0.295,0.296,0.297,0.298,0.299,0.3,0.301,0.302,0.303,0.304,0.305,0.306,0.307,0.308,0.309,0.31,0.311,0.312,0.313,0.314,0.315,0.316,0.317,0.318,0.319,0.32,0.321,0.322,0.323,0.324,0.325,0.326,0.327,0.328,0.329,0.33,0.331,0.332,0.333,0.334,0.335,0.336,0.337,0.338,0.339,0.34,0.341,0.342,0.343,0.344,0.345,0.346,0.347,0.348,0.349,0.35,0.351,0.352,0.353,0.354,0.355,0.356,0.357,0.358,0.359,0.36,0.361,0.362,0.363,0.364,0.365,0.366,0.367,0.368,0.369,0.37,0.371,0.372,0.373,0.374,0.375,0.376,0.377,0.378,0.379,0.38,0.381,0.382,0.383,0.384,0.385,0.386,0.387,0.388,0.389,0.39,0.391,0.392,0.393,0.394,0.395,0.396,0.397,0.398,0.399,0.4,0.401,0.402,0.403,0.404,0.405,0.406,0.407,0.408,0.409,0.41,0.411,0.412,0.413,0.414,0.415,0.416,0.417,0.418,0.419,0.42,0.421,0.422,0.423,0.424,0.425,0.426,0.427,0.428,0.429,0.43,0.431,0.432,0.433,0.434,0.435,0.436,0.437,0.438,0.439,0.44,0.441,0.442,0.443,0.444,0.445,0.446,0.447,0.448,0.449,0.45,0.451,0.452,0.453,0.454,0.455,0.456,0.457,0.458,0.459,0.46,0.461,0.462,0.463,0.464,0.465,0.466,0.467,0.468,0.469,0.47,0.471,0.472,0.473,0.474,0.475,0.476,0.477,0.478,0.479,0.48,0.481,0.482,0.483,0.484,0.485,0.486,0.487,0.488,0.489,0.49,0.491,0.492,0.493,0.494,0.495,0.496,0.497,0.498,0.499,0.5,0.501,0.502,0.503,0.504,0.505,0.506,0.507,0.508,0.509,0.51,0.511,0.512,0.513,0.514,0.515,0.516,0.517,0.518,0.519,0.52,0.521,0.522,0.523,0.524,0.525,0.526,0.527,0.528,0.529,0.53,0.531,0.532,0.533,0.534,0.535,0.536,0.537,0.538,0.539,0.54,0.541,0.542,0.543,0.544,0.545,0.546,0.547,0.548,0.549,0.55,0.551,0.552,0.553,0.554,0.555,0.556,0.557,0.558,0.559,0.56,0.561,0.562,0.563,0.564,0.565,0.566,0.567,0.568,0.569,0.57,0.571,0.572,0.573,0.574,0.575,0.576,0.577,0.578,0.579,0.58,0.581,0.582,0.583,0.584,0.585,0.586,0.587,0.588,0.589,0.59,0.591,0.592,0.593,0.594,0.595,0.596,0.597,0.598,0.599,0.6,0.601,0.602,0.603,0.604,0.605,0.606,0.607,0.608,0.609,0.61,0.611,0.612,0.613,0.614,0.615,0.616,0.617,0.618,0.619,0.62,0.621,0.622,0.623,0.624,0.625,0.626,0.627,0.628,0.629,0.63,0.631,0.632,0.633,0.634,0.635,0.636,0.637,0.638,0.639,0.64,0.641,0.642,0.643,0.644,0.645,0.646,0.647,0.648,0.649,0.65,0.651,0.652,0.653,0.654,0.655,0.656,0.657,0.658,0.659,0.66,0.661,0.662,0.663,0.664,0.665,0.666,0.667,0.668,0.669,0.67,0.671,0.672,0.673,0.674,0.675,0.676,0.677,0.678,0.679,0.68,0.681,0.682,0.683,0.684,0.685,0.686,0.687,0.688,0.689,0.69,0.691,0.692,0.693,0.694,0.695,0.696,0.697,0.698,0.699,0.7,0.701,0.702,0.703,0.704,0.705,0.706,0.707,0.708,0.709,0.71,0.711,0.712,0.713,0.714,0.715,0.716,0.717,0.718,0.719,0.72,0.721,0.722,0.723,0.724,0.725,0.726,0.727,0.728,0.729,0.73,0.731,0.732,0.733,0.734,0.735,0.736,0.737,0.738,0.739,0.74,0.741,0.742,0.743,0.744,0.745,0.746,0.747,0.748,0.749,0.75,0.751,0.752,0.753,0.754,0.755,0.756,0.757,0.758,0.759,0.76,0.761,0.762,0.763,0.764,0.765,0.766,0.767,0.768,0.769,0.77,0.771,0.772,0.773,0.774,0.775,0.776,0.777,0.778,0.779,0.78,0.781,0.782,0.783,0.784,0.785,0.786,0.787,0.788,0.789,0.79,0.791,0.792,0.793,0.794,0.795,0.796,0.797,0.798,0.799,0.8,0.801,0.802,0.803,0.804,0.805,0.806,0.807,0.808,0.809,0.81,0.811,0.812,0.813,0.814,0.815,0.816,0.817,0.818,0.819,0.82,0.821,0.822,0.823,0.824,0.825,0.826,0.827,0.828,0.829,0.83,0.831,0.832,0.833,0.834,0.835,0.836,0.837,0.838,0.839,0.84,0.841,0.842,0.843,0.844,0.845,0.846,0.847,0.848,0.849,0.85,0.851,0.852,0.853,0.854,0.855,0.856,0.857,0.858,0.859,0.86,0.861,0.862,0.863,0.864,0.865,0.866,0.867,0.868,0.869,0.87,0.871,0.872,0.873,0.874,0.875,0.876,0.877,0.878,0.879,0.88,0.881,0.882,0.883,0.884,0.885,0.886,0.887,0.888,0.889,0.89,0.891,0.892,0.893,0.894,0.895,0.896,0.897,0.898,0.899,0.9,0.901,0.902,0.903,0.904,0.905,0.906,0.907,0.908,0.909,0.91,0.911,0.912,0.913,0.914,0.915,0.916,0.917,0.918,0.919,0.92,0.921,0.922,0.923,0.924,0.925,0.926,0.927,0.928,0.929,0.93,0.931,0.932,0.933,0.934,0.935,0.936,0.937,0.938,0.939,0.94,0.941,0.942,0.943,0.944,0.945,0.946,0.947,0.948,0.949,0.95,0.951,0.952,0.953,0.954,0.955,0.956,0.957,0.958,0.959,0.96,0.961,0.962,0.963,0.964,0.965,0.966,0.967,0.968,0.969,0.97,0.971,0.972,0.973,0.974,0.975,0.976,0.977,0.978,0.979,0.98,0.981,0.982,0.983,0.984,0.985,0.986,0.987,0.988,0.989,0.99,0.991,0.992,0.993,0.994,0.995,0.996,0.997,0.998,0.999,1.0,1.001,1.002,1.003,1.004,1.005,1.006,1.007,1.008,1.009,1.01,1.011,1.012,1.013,1.014,1.015,1.016,1.017,1.018,1.019,1.02,1.021,1.022,1.023,1.024,1.025,1.026,1.027,1.028,1.029,1.03,1.031,1.032,1.033,1.034,1.035,1.036,1.037,1.038,1.039,1.04,1.041,1.042,1.043,1.044,1.045,1.046,1.047,1.048,1.049,1.05,1.051,1.052,1.053,1.054,1.055,1.056,1.057,1.058,1.059,1.06,1.061,1.062,1.063,1.064,1.065,1.066,1.067,1.068,1.069,1.07,1.071,1.072,1.073,1.074,1.075,1.076,1.077,1.078,1.079,1.08,1.081,1.082,1.083,1.084,1.085,1.086,1.087,1.088,1.089,1.09,1.091,1.092,1.093,1.094,1.095,1.096,1.097,1.098,1.099,1.1,1.101,1.102,1.103,1.104,1.105,1.106,1.107,1.108,1.109,1.11,1.111,1.112,1.113,1.114,1.115,1.116,1.117,1.118,1.119,1.12,1.121,1.122,1.123,1.124,1.125,1.126,1.127,1.128,1.129,1.13,1.131,1.132,1.133,1.134,1.135,1.136,1.137,1.138,1.139,1.14,1.141,1.142,1.143,1.144,1.145,1.146,1.147,1.148,1.149,1.15,1.151,1.152,1.153,1.154,1.155,1.156,1.157,1.158,1.159,1.16,1.161,1.162,1.163,1.164,1.165,1.166,1.167,1.168,1.169,1.17,1.171,1.172,1.173,1.174,1.175,1.176,1.177,1.178,1.179,1.18,1.181,1.182,1.183,1.184,1.185,1.186,1.187,1.188,1.189,1.19,1.191,1.192,1.193,1.194,1.195,1.196,1.197,1.198,1.199,1.2], + "real": [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.0e-324,2.0e-323,7.4e-323,2.4e-322,8.2e-322,2.767e-321,9.32e-321,3.1353e-320,1.05404e-319,3.5401e-319,1.18775e-318,3.981107e-318,1.333057e-317,4.4592226e-317,1.4901688e-316,4.974821e-316,1.659148125e-315,5.527879526e-315,1.8399146784e-314,6.117901834e-314,2.0322308024e-313,6.74387109934e-313,2.235688007756e-312,7.4042119013e-312,2.4496959655157e-311,8.096759510074e-311,2.6734742081949e-310,8.8187384609823e-310,2.906046990435146e-309,9.56675182054503e-309,3.146241740156714e-308,1.0336782414431435e-307,3.39269146604321e-307,1.1124207050717218e-306,3.643841404838599e-306,1.1923824484329282e-305,3.8979600928649413e-305,1.2729897531734842e-304,4.153154932803231e-304,1.3536209367342868e-303,4.4073922022690616e-303,1.4336133625950965e-302,4.6585213187119075e-302,1.512271751154994e-301,4.904303040145672e-301,1.5888776686463365e-300,5.142441147863618e-300,1.6627000301870156e-299,5.370617030720186e-299,1.7330064146975746e-298,5.586526475717649e-298,1.799074955570786e-297,5.787917871538849e-297,1.8602065430998796e-296,5.972630954588839e-296,1.9157370541237091e-295,6.138635174970509e-295,1.9650493121524818e-294,6.284066735530802e-294,2.0075844782137136e-293,6.407263362575556e-293,2.0428525792229626e-292,6.506795903003267e-292,2.070441896920103e-291,6.581495908836067e-291,2.0900269659736113e-290,6.630478465084551e-290,2.101374964083434e-289,6.653159637453737e-289,2.1043503186708436e-288,6.649268058940415e-288,2.0989174027271926e-287,6.618850333886366e-287,2.0851412448656003e-286,6.562270109016706e-286,2.0631862337936552e-285,6.4802008373570524e-285,2.033312853291967e-284,6.373612436339547e-284,1.9958725383634547e-283,6.243752209663641e-283,1.95130079457364e-282,6.092120557535567e-282,1.9001087689066523e-281,5.920442136499819e-281,1.8428735001675592e-280,5.730633243571949e-280,1.7802271087288642e-279,5.524766286032615e-279,1.7128452083277396e-278,5.305032255977816e-278,1.6414348360271552e-277,5.073702155674141e-277,1.5667222002010916e-276,4.833088316602398e-276,1.4894405406318467e-275,4.585506522170385e-275,1.4103183800696013e-274,4.3332397845028016e-274,1.3300684237973977e-273,4.078504541885092e-273,1.2493773339694496e-272,3.823419940106787e-272,1.1688965701657635e-271,3.5699807420248555e-271,1.0892344482100076e-270,3.32003428071672e-270,1.0109495274488338e-269,3.075261737118018e-269,9.345453939641441e-269,2.83716388851385e-268,8.604668651413409e-268,2.607051343959492e-267,7.89097601038062e-267,2.386039161119906e-266,7.207590713341937e-266,2.175045629545766e-265,6.557107943144061e-265,1.9747949109970735e-264,5.941517371071417e-264,1.785823150069983e-263,5.362227448103821e-263,1.6084876093588466e-262,4.8200985043461846e-262,1.4429783431192612e-261,4.315483077957788e-261,1.2893319015666198e-260,3.848271854057869e-260,1.1474465535694091e-259,3.417943606078149e-259,1.0170985270513959e-258,3.0236175914402634e-258,8.979587918598723e-258,2.6641069531997702e-257,7.896099469211063e-257,2.3379718118995962e-256,6.915628196529845e-256,2.043570889140047e-255,6.032724382796394e-255,1.7791106782419285e-254,5.241530943690541e-254,1.542691360067931e-253,4.535922712063252e-253,1.3323488463647298e-252,3.9096327138152287e-252,1.1460925125359094e-251,3.35636432330773e-251,9.819383511299291e-251,2.8698886999413984e-250,8.379374322425015e-250,2.4441273704431814e-249,7.121996942254037e-249,2.073220224558355e-248,6.029132054730613e-248,1.7515795301934608e-247,5.08359134519642e-247,1.473930845622278e-246,4.269227410391193e-246,1.2353419119453461e-245,3.5710075524190147e-245,1.0312407516680553e-244,2.9750554888774056e-244,8.574242839450792e-244,2.4686651946746845e-243,7.100588000237557e-243,2.040291122044701e-242,5.856736308869154e-242,1.6795189473774188e-241,4.8114929066542514e-241,1.3770207912383028e-240,3.937013018142588e-240,1.1244985754389304e-239,3.2086080877422314e-239,9.14618841266073e-239,2.6045297289217816e-238,7.409419769885602e-238,2.105740190124373e-237,5.978484092496298e-237,1.6956767888471244e-236,4.804639178097715e-236,1.3600165293401287e-235,3.845858494549511e-235,1.086445936988154e-234,3.066116449373418e-234,8.644400416313715e-234,2.434707601032553e-233,6.85053442591541e-233,1.9256076391245632e-232,5.407255022944915e-232,1.5168813468093003e-231,4.251009489296704e-231,1.190140525290031e-230,3.3286652194301547e-230,9.300530007885952e-230,2.5960376339517034e-229,7.239023311973521e-229,2.0165763608786535e-228,5.611966554837463e-228,1.5602032631247868e-227,4.333242511323626e-227,1.2022935408476215e-226,3.332527471855779e-226,9.227895505882828e-226,2.5526854525077058e-225,7.054360411091291e-225,1.9475279115823243e-224,5.371250937600623e-224,1.4799018051040761e-223,4.073390656114489e-223,1.1200693966456137e-222,3.076801688627538e-222,8.443447060165621e-222,2.314758938049479e-221,6.339535822703434e-221,1.7345022050060532e-220,4.7408690305945296e-220,1.2945140395584217e-219,3.531191557531794e-219,9.62280079943537e-219,2.6196750220705593e-218,7.124576406741286e-218,1.935692569904455e-217,5.253871217866028e-217,1.424584349646541e-216,3.8588919655595483e-216,1.0442458954003107e-215,2.822985445915465e-215,7.623952939998356e-215,2.0569203751842274e-214,5.543964733830957e-214,1.492757092500152e-213,4.015351168593494e-213,1.0790054257237993e-212,2.896606023060378e-212,7.768209612587994e-212,2.081220752393038e-211,5.5703318025531235e-211,1.4893943022444613e-210,3.9783594218446845e-210,1.061607677221385e-209,2.8300218592887513e-209,7.536700115475691e-209,2.0051108434797134e-208,5.329190458915739e-208,1.4149783770864401e-207,3.7532204187161946e-207,9.945440945830308e-207,2.6327506042027074e-206,6.962434215268871e-206,1.8394085206594017e-205,4.854684250953158e-205,1.279998582853705e-204,3.371504118602707e-204,8.871633777939913e-204,2.3321110275376713e-203,6.12435765201777e-203,1.606710280872557e-202,4.2109521448571315e-202,1.1025257585203361e-201,2.883785070354561e-201,7.535338025607518e-201,1.967017819924948e-200,5.129553399724874e-200,1.336338626323437e-199,3.477916841607377e-199,9.042480296151613e-199,2.3486681265282674e-198,6.094266510205044e-198,1.579744807616159e-197,4.0908931480745495e-197,1.0583152181622371e-196,2.7351279762670904e-196,7.061646409758073e-196,1.8213775927056605e-195,4.693099009390503e-195,1.2080506661918555e-194,3.106535259979337e-194,7.980555661822829e-194,2.04812132849328e-193,5.251023173738293e-193,1.3449244693459069e-192,3.4412605900572147e-192,8.796358727232364e-192,2.2462288915196558e-191,5.73021333838143e-191,1.4603376394318252e-190,3.7179322570565084e-190,9.45617217835326e-190,2.402674701766409e-189,6.098742338307926e-189,1.546504902007075e-188,3.917671541806086e-188,9.91449158084638e-188,2.506562743907102e-187,6.330709972925755e-187,1.597320115051209e-186,4.026217287774424e-186,1.0138370620041504e-185,2.550379582305333e-185,6.40924964423311e-185,1.6090711883914085e-184,4.0356085609381966e-184,1.0111335395472102e-183,2.530892526776914e-183,6.3285555433363885e-183,1.5808883326789317e-182,3.9451497969336726e-182,9.83538822535731e-182,2.44954387051106e-181,6.094592069139777e-181,1.5148504768289146e-180,3.7614959560513366e-180,9.330762516720798e-180,2.3122744394136506e-179,5.7243651126336606e-179,1.4157317750661397e-178,3.497843210364292e-178,8.633470370480867e-178,2.128806427420445e-177,5.243878833769773e-177,1.2904311236918859e-176,3.172361829040439e-176,7.791055671594379e-176,1.9115057341332694e-175,4.6851188049900144e-175,1.1471793392296205e-174,2.806129638184433e-174,6.857247903282343e-174,1.6740085640429026e-173,4.082547120925306e-173,9.946503555625693e-173,2.420891824922044e-172,5.886349316003755e-172,1.4298233454376698e-171,3.469640207494117e-171,8.411088559897842e-171,2.036974887495469e-170,4.928160570440254e-170,1.1911041284657108e-169,2.8759432747235336e-169,6.937078468947572e-169,1.67162402341826e-168,4.0240772221147233e-168,9.677422769310288e-168,2.324977891601812e-167,5.580121386477538e-167,1.337932399666595e-166,3.2047222880104995e-166,7.66853380207816e-166,1.8331583325061583e-165,4.377773859886786e-165,1.0444132568420411e-164,2.4891847594481456e-164,5.926627015063379e-164,1.4096904736105185e-163,3.349697884468515e-163,7.951576079645034e-163,1.8856735254946275e-162,4.46730386758129e-162,1.057280422458485e-161,2.4997731107144866e-161,5.904412613941382e-161,1.3932161884339238e-160,3.2841730301673135e-160,7.733912496953336e-160,1.8194418642342106e-159,4.2760504266971427e-159,1.0039524836013197e-158,2.3547738498256986e-158,5.517609434686178e-158,1.2915713786719718e-157,3.0203103773571167e-157,7.055867922517387e-157,1.6467020119875616e-156,3.8392402945706865e-156,8.942136181074575e-156,2.0806688698786853e-155,4.836490788587965e-155,1.1231130303898445e-154,2.6054471758883393e-154,6.038190138396637e-154,1.397967265203066e-153,3.233351541085652e-153,7.470928047857809e-153,1.724494794949861e-152,3.9766276464257356e-152,9.160805716139337e-152,2.1082306518948527e-151,4.846947096435813e-151,1.1132280512537537e-150,2.554263564680686e-150,5.854812362301835e-150,1.3406825582599096e-149,3.0669355046761376e-149,7.008886585447056e-149,1.6001442206964193e-148,3.649513106141344e-148,8.3152714931226e-148,1.8927081179249387e-147,4.3038444014423623e-147,9.776765174934378e-147,2.2187047443717286e-146,5.03001807291809e-146,1.1392139239127662e-145,2.577547805922451e-145,5.826045592120653e-145,1.3155481082467346e-144,2.96759954242394e-144,6.687588803369968e-144,1.5055650829807864e-143,3.3860643834975525e-143,7.607756341766922e-143,1.7075903166594414e-142,3.828921631354747e-142,8.576991449988895e-142,1.919372120839007e-141,4.2909069127037714e-141,9.583071075447326e-141,2.1380902395371213e-140,4.765550303791767e-140,1.0611231537462908e-139,2.3603925174767147e-139,5.2452763365588594e-139,1.1644429674892633e-138,2.5824610333817212e-138,5.721567653719609e-138,1.266374052489056e-137,2.8001073064647562e-137,6.185190094812883e-137,1.364888372889789e-136,3.0088942341314604e-136,6.62647273765158e-136,1.4578861646930437e-135,3.204280442340767e-135,7.035632219041899e-135,1.5432683322371144e-134,3.381780889772396e-134,7.403126871785171e-134,1.6190140748579506e-133,3.537136028507449e-133,7.720023192237626e-133,1.683259807940382e-132,3.666480738687979e-132,7.97835520227533e-132,1.7343751114636022e-131,3.7665037436629926e-131,8.171456623088348e-131,1.771031400861482e-130,3.834588351744406e-130,8.294246562734797e-130,1.792259288325748e-129,3.868926182171023e-129,8.343451638102356e-129,1.7974911790146005e-128,3.868596977664953e-128,8.317750978754201e-128,1.7865864897071797e-127,3.833609586867311e-127,8.217835146786753e-127,1.759837925894444e-126,3.764901569118742e-126,8.04637530414115e-126,1.7179584260947477e-125,3.6642974462270196e-125,7.807904548914741e-125,1.6620495862245283e-124,3.5344281960638365e-124,7.508618778827979e-124,1.5935535160343384e-123,3.378616946293087e-123,7.156109291711506e-123,1.5141910641060698e-122,3.200737798538324e-122,6.75904322499322e-122,1.425890102824819e-121,3.0050561468230967e-121,6.326810585835376e-121,1.3307080370769246e-120,2.796059653055709e-120,5.8691578647788316e-120,1.2307528635096678e-119,2.578289169271099e-119,5.395828021136882e-119,1.1281069622809019e-118,2.3561783736410964e-118,4.916225067466307e-118,1.024757378125161e-117,2.133909792229038e-117,4.439118764598805e-117,9.225356925630352e-117,1.915293332819423e-116,3.9724013556304896e-116,8.230697708237948e-116,1.7036716127542782e-115,3.5229041579341887e-115,7.2774876113593695e-115,1.5018543851238501e-114,3.0962775551987292e-114,6.3770180723675784e-114,1.3120824195491827e-113,2.696933827677159e-113,5.53790077974594e-113,1.1360194201247952e-112,2.3280486218675644e-112,4.766109793969954e-112,9.747690794153321e-112,1.991613914467985e-111,4.065128372041011e-111,8.289132523350869e-111,1.6885332105913416e-110,3.4361794505522245e-110,6.985665259580662e-110,1.4187484877600434e-109,2.878516727637316e-109,5.8344216086921955e-109,1.181388029484849e-108,2.389753071775236e-108,4.829244529682765e-108,9.749246922969946e-108,1.9662043343199815e-107,3.9614295213417946e-107,7.973351751344062e-107,1.6032292193245195e-106,3.220445993840072e-106,6.462523378357862e-106,1.295549286103543e-105,2.5946062328075976e-105,5.191043643669956e-105,1.0375370376038087e-104,2.0716588670347866e-104,4.132364128393191e-104,8.234640202190696e-104,1.6392922247143835e-103,3.260121870884131e-103,6.47704623419561e-103,1.2855407994206947e-102,2.548944840233549e-102,5.048945882663486e-102,9.990948023374656e-102,1.9750513389070897e-101,3.90045960020485e-101,7.695181797351359e-101,1.516658105274123e-100,2.9862227647676414e-100,5.873844145041552e-100,1.1542193250659967e-99,2.265791636841874e-99,4.443419361045004e-99,8.70523184500978e-99,1.7037626237913177e-98,3.331221699434202e-98,6.506743583076161e-98,1.2696661862174458e-97,2.4750337206240986e-97,4.819904046130251e-97,9.376945032045818e-97,1.8224266322336508e-96,3.5383797599017644e-96,6.863166522433951e-96,1.329873512641931e-95,2.5743159142054028e-95,4.978276936276906e-95,9.617494987264943e-95,1.856139403968579e-94,3.5786969060948957e-94,6.892947182843259e-94,1.3263272397336903e-93,2.5495417788283806e-93,4.895976025503147e-93,9.392520193711107e-93,1.800075404569458e-92,3.4463943047331014e-92,6.591813863302463e-92,1.2595360797099265e-91,2.4042631220661123e-91,4.5847861456848984e-91,8.734174746333978e-91,1.6622271661006572e-90,3.160272852073358e-90,6.002393878844099e-90,1.1389118357060604e-89,2.15884482731646e-89,4.088071228169134e-89,7.733590752953963e-89,1.4615363595131158e-88,2.7593307914851405e-88,5.204315490748091e-88,9.805938617053889e-88,1.8457821006861264e-87,3.4708623900815556e-87,6.520187221510919e-87,1.223625284968177e-86,2.2940481258278325e-86,4.296574157013102e-86,8.039106920553505e-86,1.5026540397883717e-85,2.8059240224436676e-85,5.234298871952674e-85,9.75454084704156e-85,1.8160209409991771e-84,3.3775405999812994e-84,6.275466416007798e-84,1.1648155152923516e-83,2.1599017153451176e-83,4.001073573587828e-83,7.404313372006404e-83,1.3688591086827e-82,2.5281242522996897e-82,4.6644859043355185e-82,8.597552979570069e-82,1.5831120037748048e-81,2.912152599155926e-81,5.351583682463348e-81,9.824630338994893e-81,1.8018383324206884e-80,3.3012706490349188e-80,6.042437194147352e-80,1.1048641061305512e-79,2.0182329402824727e-79,3.682980513544096e-79,6.714184288211594e-79,1.22279259291269e-78,2.22473376779541e-78,4.0436075584570405e-78,7.34219066291586e-78,1.3318276349331359e-77,2.4134376949094467e-77,4.369078688898636e-77,7.901496410147404e-77,1.4275605344202143e-76,2.5765906396727508e-76,4.645816176280437e-76,8.36843648814521e-76,1.505886821087695e-75,2.7071108916060214e-75,4.861669874890641e-75,8.722291364434816e-75,1.5632967326411662e-74,2.7990970458841397e-74,5.006799464711466e-74,8.94680854514069e-74,1.5971356219323755e-73,2.848269989000882e-73,5.074417746363769e-73,9.031439687617026e-73,1.6058074201023938e-72,2.852302878572221e-72,5.061316845418253e-72,8.972162205476246e-72,1.5888994433529127e-71,2.8110036842474443e-71,4.968120514937853e-71,8.771796246539538e-71,1.5472149520062127e-70,2.7263303466324853e-70,4.7992349009963084e-70,8.439782259040312e-70,1.482709884522689e-69,2.602236887752464e-69,4.562503183168836e-69,7.991443578311751e-69,1.3983407058472374e-68,2.444367317506248e-68,4.268601788406294e-68,7.446814250801847e-68,1.2978398526706317e-67,2.259630333372411e-67,3.93024290005534e-67,6.829156936471596e-67,1.1854425177833876e-66,2.055699414243779e-66,3.561266135266449e-66,6.163323354140786e-66,1.0655925661968096e-65,1.8404885351489542e-65,3.1757094131948795e-65,5.474117330943129e-65,9.426558187593346e-65,1.6216529225308025e-64,2.7869448266392014e-64,4.7848082531684535e-64,8.206659440952411e-64,1.4061575725514113e-63,2.4069511379722896e-63,4.1159137322320165e-63,7.031224400813842e-63,1.199945051862329e-62,2.0457731072971674e-62,3.4843299735607634e-62,5.928526890046399e-62,1.0077203218182182e-61,1.7111928024524956e-61,2.902843206220607e-61,4.919420173461512e-61,8.328560837430633e-61,1.4086130666758972e-60,2.3800121188941e-60,4.0172821007799504e-60,6.774093652871721e-60,1.1411316969919425e-59,1.9203750137882758e-59,3.2285092127455378e-59,5.422302206694305e-59,9.097689558799636e-59,1.5249100026385019e-58,2.5534244853097604e-58,4.271373309381595e-58,7.138019762199148e-58,1.1916635840467523e-57,1.9874458078034284e-57,3.311331255947639e-57,5.511574307863163e-57,9.164618921438996e-57,1.5223652450197602e-56,2.5263238128761693e-56,4.188175542267686e-56,6.936277224894154e-56,1.147608388467308e-55,1.8968224941014307e-55,3.1320261101645413e-55,5.166420632837861e-55,8.513729661519419e-55,1.4015727818629223e-54,2.3050330659919683e-54,3.787079045962578e-54,6.21580363104094e-54,1.0191917678005994e-53,1.6694762069277811e-53,2.7319343972057713e-53,4.4660749189684045e-53,7.293692464440711e-53,1.189966119476966e-52,1.939489580631518e-52,3.157955535221233e-52,5.136771841129314e-52,8.347189001773146e-52,1.3550518817273488e-51,2.1975426145950051e-51,3.5602819554483226e-51,5.762317529716718e-51,9.316991188246808e-51,1.5049424371105486e-50,2.428453535707831e-50,3.9147624460235043e-50,6.304443168789515e-50,1.014270420713244e-49,1.6301459598146663e-49,2.6173688480711924e-49,4.198257493527188e-49,6.727270953307621e-49,1.0768977604396345e-48,1.7221688636533958e-48,2.7513300896561116e-48,4.3911206318001473e-48,7.001220308968115e-48,1.1151616485924878e-47,1.774465712760407e-47,2.820740307027572e-47,4.479445967094777e-47,7.106425471137206e-47,1.1262733674360639e-46,1.7832085141522895e-46,2.820500292001351e-46,4.456725384886368e-46,7.035116691636799e-46,1.1094109344035529e-45,1.7477498922024882e-45,2.7506278225521277e-45,4.324641231687276e-45,6.792568756843043e-45,1.0658196118143382e-44,1.6707023247078974e-44,2.616255486177216e-44,4.0928604074546895e-44,6.396456030374013e-44,9.986598974843921e-44,1.5576199742735697e-43,2.4270074557543136e-43,3.777864862090113e-43,5.874723521449101e-43,9.126287621727375e-43,1.4163369213144053e-42,2.195860299541195e-42,3.401014963497081e-42,5.262330059470614e-42,8.134171615096759e-42,1.256071273377734e-41,1.9376750232689292e-41,2.986161587697611e-41,4.597390283164839e-41,7.070907371452474e-41,1.0864372010800097e-40,1.6676304385425064e-40,2.557176499059924e-40,3.9173042259247056e-40,5.994867699497459e-40,9.165108500221066e-40,1.3997849627215201e-39,2.1357516097541683e-39,3.2554112988375115e-39,4.9570887694091045e-39,7.540727228467279e-39,1.1459494802550088e-38,1.7397362717406633e-38,2.638560580418337e-38,3.99775731955238e-38,6.051060426395788e-38,9.149813840443385e-38,1.3821613101435703e-37,2.0857915860555893e-37,3.1444797047652272e-37,4.73578945726571e-37,7.125275847042481e-37,1.0709684662829761e-36,1.6081160648509705e-36,2.4122582640624812e-36,3.614896945681192e-36,5.411700386319788e-36,8.093516813403859e-36,1.209223302558629e-35,1.8048513878453896e-35,2.691175951531052e-35,4.008745120417611e-35,5.965412787758881e-35,8.86825684793637e-35,1.3170483861997544e-34,1.954028544586258e-34,2.8961815480360437e-34,4.288311912012338e-34,6.343262092756363e-34,9.37356189101052e-34,1.3837650328134295e-33,2.0407309832662094e-33,3.0065945778781195e-33,4.425167225430208e-33,6.506541586875531e-33,9.557326840839149e-33,1.4024531816775815e-32,2.0559190532067264e-32,3.01085164057414e-32,4.4049238664938293e-32,6.438032466483551e-32,9.40012489424457e-32,1.371133654658871e-31,1.9979824228502428e-31,2.908501158882566e-31,4.229728822365796e-31,6.144994714057436e-31,8.91859018253701e-31,1.2931133881823633e-30,1.8730212893121775e-30,2.7102822745595387e-30,3.9178882222261096e-30,5.6578999501424246e-30,8.162518734745172e-30,1.176410316049322e-29,1.693788433624625e-29,2.4362688200739486e-29,3.5007166225158424e-29,5.0252122749665084e-29,7.206386860901402e-29,1.0323962988226507e-28,1.4775460005142883e-28,2.112522231188377e-28,3.0173609865056806e-28,4.305454054873446e-28,6.137285870734296e-28,8.739758903134928e-28,1.2433352802103817e-27,1.7670252992065744e-27,2.5087823372704526e-27,3.5583519804461035e-27,5.041973187085947e-27,7.13703561978753e-27,1.0092549827747e-26,1.4257705691451965e-26,2.0121673361609085e-26,2.8369014500581715e-26,3.995674567259598e-26,5.622140244567967e-26,7.902762784127705e-26,1.109741743622935e-25,1.556792048511033e-25,2.181750038813052e-25,3.0545348573693027e-25,4.272193197850078e-25,5.96928601545452e-25,8.332198316061767e-25,1.1618833101821036e-24,1.6185686865073923e-24,2.2525034268587065e-24,3.131594287357679e-24,4.3494188212183016e-24,6.034797090462657e-24,8.364882032736114e-24,1.1583043157260042e-23,1.6023273063590758e-23,2.2143460853793033e-23,3.0570706051478486e-23,4.216296511689166e-23,5.809282904332826e-23,7.996125715898672e-23,1.0995181582344888e-22,1.5103962685008802e-22,2.0727413314767275e-22,2.841613560299036e-22,3.8918010520591737e-22,5.324783459409485e-22,7.27811606085534e-22,9.938062139416161e-22,1.3556580102447225e-21,1.8474142392572105e-21,2.5150355857997067e-21,3.4205007308105354e-21,4.647302542430045e-21,6.3077999372200205e-21,8.553041518725983e-21,1.1585878118244242e-20,1.5678446784031772e-20,2.1195458835817402e-20,2.862518580549353e-20,3.8620644027646074e-20,5.2054276489888436e-20,7.009047818103402e-20,9.42816852518671e-20,1.2669554854311358e-19,1.700830679785558e-19,2.2810064406055835e-19,3.056030241049996e-19,4.0902936595852597e-19,5.469114754617943e-19,7.30542166907262e-19,9.748532558742784e-19,1.2995677041456606e-18,1.7307099047275152e-18,2.3025833168838727e-18,3.0603573001196848e-18,4.063447185740255e-18,5.389926098065226e-18,7.142277291537083e-18,9.454886273886542e-18,1.2503788443783228e-17,1.6519337657093817e-17,2.1802653310787557e-17,2.874694997796842e-17,3.7865169307176476e-17,4.9825737803796317e-17,6.549879030815129e-17,8.601585793886041e-17,1.1284685949921312e-16,1.478993054892707e-16,1.9364598527666014e-16,2.532891379399189e-16,3.3097130305276804e-16,4.3204583143122605e-16,5.634235610076765e-16,7.340166218224748e-16,9.553059674117186e-16,1.2420663387296556e-15,1.6132913272786093e-15,2.0933724855193764e-15,2.7136006195020253e-15,3.5140752184873113e-15,4.5461303333259e-15,5.875413231954853e-15,7.58578722815516e-15,9.78427392184295e-15,1.2607304836678604e-14,1.622862072583604e-14,2.0869241886426005e-14,2.6810038677818034e-14,3.440756300153675e-14,4.411396481999411e-14,5.650202029296272e-14,7.229654889580203e-14,9.241380709418244e-14,1.180108294094146e-13,1.5054716065120718e-13,1.9186200600672365e-13,2.4427054326289204e-13,3.1068402375434455e-13,3.947593721769117e-13,5.010853244716474e-13,6.35413771221259e-13,8.049469663281738e-13,1.0186936956057596e-12,1.287910471973011e-12,1.6266474472769579e-12,2.052423142670403e-12,2.5870574649569225e-12,3.2576989934351138e-12,4.098090427924023e-12,5.150125667985707e-12,6.465763585541351e-12,8.109377563554992e-12,1.0160636785541343e-11,1.2718035649663817e-11,1.5903212231002853e-11,1.9866226237985902e-11,2.479200236622564e-11,3.0908187484083427e-11,3.849472103538858e-11,4.789547900477803e-11,5.953242463265251e-11,7.39227859934513e-11,9.169988415235779e-11,1.1363835893008249e-10,1.40684685892887e-10,1.7399405220989904e-10,2.1497486534649424e-10,2.653424128642829e-10,3.271834804816573e-10,4.030340766953352e-10,4.95972814590034e-10,6.097329753058105e-10,7.488368349509243e-10,9.187564913605684e-10,1.1261061949471627e-9,1.3788720873213142e-9,1.6866863034858714e-9,2.0611536224385798e-9,2.516240284713478e-9,3.0687362654894375e-9,3.738804234642533e-9,4.550630691832408e-9,5.533197382398052e-9,6.72119413188933e-9,8.156097743999924e-9,9.88744565699239e-9,1.1974337724766251e-8,1.448720486772067e-8,1.7509889523606546e-8,2.1142089929801404e-8,2.550222840930461e-8,3.0730813151265356e-8,3.699437362700863e-8,4.449006193583798e-8,5.345102622180876e-8,6.415267805440544e-8,7.691999355609062e-8,9.213600834566037e-8,1.1025168933173685e-7,1.3179739234671617e-7,1.5739614389882767e-7,1.8777901831050882e-7,2.2380291861017848e-7,2.664711111911425e-7,3.169569109216767e-7,3.766309655974039e-7,4.47092646922628e-7,5.302061201824254e-7,6.281417370526457e-7,7.434234762611671e-7,8.789832457702949e-7,1.0382229585448585e-6,1.2250854025871248e-6,1.4441350455752707e-6,1.7006500459841837e-6,2.0007268868677803e-6,2.3513992064326504e-6,2.7607725720371842e-6,3.2381771322159403e-6,3.7943402856560683e-6,4.4415817276237596e-6,5.194033474002839e-6,6.0678877216671805e-6,7.081675682098663e-6,8.256580823632136e-6,9.616790277000472e-6,1.1189888499372013e-5,1.3007297654067575e-5,1.5104769546670746e-5,1.7522934363135202e-5,2.030791188132442e-5,2.351199127346768e-5,2.7194386082234394e-5,3.142207143607726e-5,3.627071106833144e-5,4.182568221696097e-5,4.81832070049914e-5,5.5451599432176945e-5,6.37526376423301e-5,7.32230716633574e-5,8.401627734305137e-5,9.630406771703447e-5,0.00011027867353903842,0.00012615490517032247,0.00014417250845590252,0.0001645987276010445,0.00018773108839185998,0.0002139004153676611,0.000243474096737915,0.00027685961093021247,0.0003145083286438566,0.0003569196041517842,0.0004046451693262645,0.0004582938434450188,0.0005185365712474733,0.0005861118009386385,0.0006618312128631535,0.0007465858083766792,0.0008413523670084695,0.0009472002783201107,0.0010652987529042202,0.001196924414716883,0.0013434692743837279,0.0015064490802475042,0.0016875120407226411,0.0018884479079789762,0.002111197409084511,0.0023578620064902346,0.0026307139651365764,0.0029322066985015887,0.0032649853606012925,0.0036318976453011864,0.004036004748319565,0.0044805924410166315,0.004969182198492818,0.005505542317696359,0.006093698954199208,0.006737946999085485,0.007442860710056664,0.0082133040034486,0.009054440306439602,0.009971741861376485,0.010970998366931507,0.01205832483381149,0.013240168526058726,0.014523314852706953,0.015914892068784228,0.01742237463949356,0.019053585116958073,0.02081669437530595,0.022720220047200777,0.02477302300331428,0.026984301715802572,0.029363584347699426,0.03192071841238939,0.034665857851076544,0.03760944738152102,0.04076220397836635,0.04413509535420937,0.04773931532124114,0.05158625592586989,0.05568747626327012,0.06005466789530813,0.06469961681378571,0.06963416191140524,0.07487014994526,0.08041938700193275,0.0862935864993708,0.09250431378848267,0.09906292744674766,0.10598051738688218,0.11326783993558988,0.12093525007041712,0.12899263103651984,0.13744932159945242,0.14631404122463498,0.15559481350864884,0.165298888221586,0.1754326623530817,0.18600160058690823,0.1970101556598578,0.20846168908963097,0.22035839278323321,0.23270121206157043,0.2454897706571467,0.25872229825963944,0.272395561198292,0.2865047968601895,0.30104365244924775,0.3160041286918619,0.33137652909136267,0.3471494153245097,0.36330956935901054,0.37984196285137806,0.3967297343592192,0.41395417487127345,0.4314947221221871,0.4493289641172209,0.4674326522449652,0.48577972430388433,0.5043423377113943,0.5230909131025002,0.5419941884591866,0.5610192838421699,0.5801317767238202,0.5992957878455379,0.6184740774452715,0.6376281516217728,0.6567183785223145,0.6757041139606256,0.6945438359924629,0.7131952878982818,0.7316156289466413,0.7497615922390409,0.7675896488675725,0.7850561775518291,0.8021176388616297,0.8187307530779816,0.8348526806969433,0.8504412045402328,0.8654549124031066,0.8798533791446437,0.8935973471085155,0.9066489037539208,0.9189716553768316,0.9305308958112056,0.9412937690184056,0.9512294245007139,0.9603091645114129,0.9685065820791975,0.9757976889184073,0.9821610323583007,0.9875778004938814,0.9920319148370607,0.9955101098295706,0.9980019986673331,0.9995001249791693,1.0,0.9995001249791694,0.9980019986673331,0.9955101098295709,0.9920319148370607,0.987577800493882,0.9821610323583007,0.975797688918408,0.9685065820791975,0.9603091645114139,0.9512294245007139,0.9412937690184067,0.9305308958112056,0.9189716553768329,0.9066489037539208,0.893597347108517,0.8798533791446437,0.8654549124031082,0.8504412045402328,0.834852680696945,0.8187307530779816,0.8021176388616315,0.7850561775518291,0.7675896488675744,0.7497615922390409,0.7316156289466434,0.7131952878982818,0.694543835992465,0.6757041139606256,0.6567183785223166,0.6376281516217728,0.6184740774452736,0.5992957878455379,0.5801317767238223,0.5610192838421699,0.5419941884591887,0.5230909131025002,0.5043423377113962,0.48577972430388433,0.4674326522449672,0.4493289641172209,0.4314947221221891,0.41395417487127345,0.3967297343592211,0.37984196285137806,0.3633095693590124,0.3471494153245097,0.33137652909136445,0.3160041286918619,0.30104365244924935,0.2865047968601895,0.2723955611982936,0.25872229825963944,0.2454897706571481,0.23270121206157043,0.22035839278323463,0.20846168908963097,0.19701015565985908,0.18600160058690823,0.17543266235308283,0.165298888221586,0.15559481350864987,0.14631404122463498,0.13744932159945242,0.12899263103651892,0.12093525007041712,0.11326783993558903,0.10598051738688218,0.09906292744674687,0.09250431378848267,0.08629358649937015,0.08041938700193275,0.07487014994525941,0.06963416191140524,0.06469961681378515,0.06005466789530813,0.05568747626326965,0.05158625592586989,0.04773931532124074,0.04413509535420937,0.040762203978365975,0.03760944738152102,0.03466585785107624,0.03192071841238939,0.029363584347699152,0.026984301715802572,0.024773023003314038,0.022720220047200777,0.020816694375305735,0.019053585116958073,0.017422374639493376,0.015914892068784228,0.014523314852706798,0.013240168526058726,0.012058324833811362,0.010970998366931507,0.009971741861376386,0.009054440306439602,0.008213304003448505,0.007442860710056664,0.006737946999085407,0.006093698954199208,0.005505542317696296,0.004969182198492818,0.004480592441016576,0.004036004748319565,0.0036318976453011413,0.0032649853606012925,0.002932206698501555,0.0026307139651365764,0.0023578620064902056,0.002111197409084511,0.0018884479079789543,0.0016875120407226411,0.0015064490802474842,0.0013434692743837279,0.0011969244147168672,0.0010652987529042202,0.0009472002783200989,0.0008413523670084695,0.00074658580837667,0.0006618312128631535,0.0005861118009386311,0.0005185365712474733,0.0004582938434450127,0.0004046451693262645,0.00035691960415178923,0.0003145083286438566,0.0002768596109302164,0.000243474096737915,0.00021390041536766452,0.00018773108839185998,0.00016459872760104713,0.00014417250845590252,0.00012615490517032448,0.00011027867353903842,9.6304067717036e-5,8.401627734305137e-5,7.322307166335831e-5,6.37526376423301e-5,5.545159943217773e-5,4.81832070049914e-5,4.182568221696164e-5,3.627071106833144e-5,3.142207143607776e-5,2.7194386082234394e-5,2.3511991273468056e-5,2.030791188132442e-5,1.7522934363135514e-5,1.5104769546670746e-5,1.3007297654067783e-5,1.1189888499372013e-5,9.616790277000626e-6,8.256580823632136e-6,7.0816756820987894e-6,6.0678877216671805e-6,5.194033474002922e-6,4.4415817276237596e-6,3.794340285656129e-6,3.2381771322159403e-6,2.760772572037238e-6,2.3513992064326504e-6,2.000726886867816e-6,1.7006500459841837e-6,1.4441350455752963e-6,1.2250854025871248e-6,1.038222958544877e-6,8.789832457702949e-7,7.434234762611816e-7,6.281417370526457e-7,5.302061201824356e-7,4.47092646922628e-7,3.7663096559741124e-7,3.169569109216767e-7,2.664711111911477e-7,2.2380291861017848e-7,1.8777901831051282e-7,1.5739614389882767e-7,1.3179739234671898e-7,1.1025168933173685e-7,9.213600834566233e-8,7.691999355609062e-8,6.415267805440682e-8,5.345102622180876e-8,4.4490061935838925e-8,3.699437362700863e-8,3.073081315126601e-8,2.550222840930461e-8,2.1142089929801404e-8,1.7509889523606172e-8,1.448720486772067e-8,1.1974337724765995e-8,9.88744565699239e-9,8.15609774399975e-9,6.72119413188933e-9,5.533197382397935e-9,4.550630691832408e-9,3.738804234642454e-9,3.0687362654894375e-9,2.516240284713425e-9,2.0611536224385798e-9], + "imaginary": [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] + }, + "doNormalize": false +} \ No newline at end of file diff --git a/examples/harmonicOscillator/coherentStateQmResidual.json b/examples/harmonicOscillator/coherentStateQmResidual.json new file mode 100644 index 0000000..075621f --- /dev/null +++ b/examples/harmonicOscillator/coherentStateQmResidual.json @@ -0,0 +1,21 @@ +{ + "type": "qmResidual", + "scheme": {"id": "ResidualCrankNicolson" , "isTrajectoryHamiltonian": true, "classicalScheme": {"id": "SymplecticEuler" , "mass": 1, "deltaX": 0.001}}, + "V_coefficients": [0,0,1], + "V": [0.020000000000000004,0.019800500000000002,0.019602,0.0194045,0.019208000000000003,0.0190125,0.018818,0.018624500000000002,0.018432,0.0182405,0.01805,0.0178605,0.017672,0.0174845,0.017298,0.0171125,0.016928,0.0167445,0.016562,0.0163805,0.0162,0.0160205,0.015842,0.015664499999999998,0.015487999999999998,0.015312499999999998,0.015137999999999999,0.014964499999999999,0.014791999999999998,0.014620500000000002,0.014450000000000003,0.014280500000000002,0.014112000000000001,0.013944500000000002,0.013778000000000002,0.013612500000000001,0.013448000000000002,0.013284500000000001,0.013122,0.012960500000000002,0.0128,0.0126405,0.012482,0.0123245,0.012168,0.0120125,0.011858,0.0117045,0.011552,0.0114005,0.01125,0.0111005,0.010951999999999998,0.010804499999999998,0.010657999999999999,0.0105125,0.010367999999999999,0.010224499999999997,0.010081999999999999,0.009940499999999998,0.009800000000000001,0.009660500000000002,0.009522000000000001,0.009384500000000002,0.009248000000000001,0.0091125,0.008978000000000002,0.008844500000000002,0.008712000000000001,0.008580500000000001,0.008450000000000001,0.0083205,0.008192,0.0080645,0.007938,0.0078125,0.0076879999999999995,0.0075645,0.007442,0.0073205,0.0072,0.007080499999999999,0.0069619999999999994,0.006844500000000001,0.0067280000000000005,0.0066125,0.006498,0.0063845,0.006272000000000001,0.0061605,0.00605,0.0059405,0.0058319999999999995,0.0057244999999999996,0.005618,0.005512499999999999,0.005408,0.005304499999999999,0.005201999999999999,0.005100500000000001,0.005000000000000001,0.0049005,0.004802000000000001,0.0047045,0.004608,0.0045125,0.004418,0.0043245,0.004232,0.0041405,0.00405,0.0039605,0.0038719999999999996,0.0037844999999999997,0.0036979999999999995,0.0036125000000000007,0.0035280000000000003,0.0034445000000000005,0.0033620000000000004,0.0032805,0.0032,0.0031205,0.003042,0.0029645,0.002888,0.0028125,0.0027379999999999995,0.0026644999999999998,0.0025919999999999997,0.0025204999999999997,0.0024500000000000004,0.0023805000000000002,0.0023120000000000003,0.0022445000000000004,0.0021780000000000002,0.0021125000000000002,0.002048,0.0019845,0.0019219999999999999,0.0018605,0.0018,0.0017404999999999999,0.0016820000000000001,0.0016245,0.0015680000000000002,0.0015125,0.0014579999999999999,0.0014045,0.001352,0.0013004999999999998,0.0012500000000000002,0.0012005000000000002,0.001152,0.0011045,0.001058,0.0010125,0.0009679999999999999,0.0009244999999999999,0.0008820000000000001,0.0008405000000000001,0.0008,0.0007605,0.000722,0.0006844999999999999,0.0006479999999999999,0.0006125000000000001,0.0005780000000000001,0.0005445000000000001,0.000512,0.00048049999999999997,0.00045,0.00042050000000000003,0.00039200000000000004,0.00036449999999999997,0.000338,0.00031250000000000006,0.000288,0.0002645,0.00024199999999999997,0.00022050000000000002,0.0002,0.0001805,0.00016199999999999998,0.00014450000000000002,0.000128,0.0001125,9.800000000000001e-5,8.45e-5,7.2e-5,6.049999999999999e-5,5.0e-5,4.0499999999999995e-5,3.2e-5,2.4500000000000003e-5,1.8e-5,1.25e-5,8.0e-6,4.5e-6,2.0e-6,5.0e-7,0.0,5.0e-7,2.0e-6,4.5e-6,8.0e-6,1.25e-5,1.8e-5,2.4500000000000003e-5,3.2e-5,4.0499999999999995e-5,5.0e-5,6.049999999999999e-5,7.2e-5,8.45e-5,9.800000000000001e-5,0.0001125,0.000128,0.00014450000000000002,0.00016199999999999998,0.0001805,0.0002,0.00022050000000000002,0.00024199999999999997,0.0002645,0.000288,0.00031250000000000006,0.000338,0.00036449999999999997,0.00039200000000000004,0.00042050000000000003,0.00045,0.00048049999999999997,0.000512,0.0005445000000000001,0.0005780000000000001,0.0006125000000000001,0.0006479999999999999,0.0006844999999999999,0.000722,0.0007605,0.0008,0.0008405000000000001,0.0008820000000000001,0.0009244999999999999,0.0009679999999999999,0.0010125,0.001058,0.0011045,0.001152,0.0012005000000000002,0.0012500000000000002,0.0013004999999999998,0.001352,0.0014045,0.0014579999999999999,0.0015125,0.0015680000000000002,0.0016245,0.0016820000000000001,0.0017404999999999999,0.0018,0.0018605,0.0019219999999999999,0.0019845,0.002048,0.0021125000000000002,0.0021780000000000002,0.0022445000000000004,0.0023120000000000003,0.0023805000000000002,0.0024500000000000004,0.0025204999999999997,0.0025919999999999997,0.0026644999999999998,0.0027379999999999995,0.0028125,0.002888,0.0029645,0.003042,0.0031205,0.0032,0.0032805,0.0033620000000000004,0.0034445000000000005,0.0035280000000000003,0.0036125000000000007,0.0036979999999999995,0.0037844999999999997,0.0038719999999999996,0.0039605,0.00405,0.0041405,0.004232,0.0043245,0.004418,0.0045125,0.004608,0.0047045,0.004802000000000001,0.0049005,0.005000000000000001,0.005100500000000001,0.005201999999999999,0.005304499999999999,0.005408,0.005512499999999999,0.005618,0.0057244999999999996,0.0058319999999999995,0.0059405,0.00605,0.0061605,0.006272000000000001,0.0063845,0.006498,0.0066125,0.0067280000000000005,0.006844500000000001,0.0069619999999999994,0.007080499999999999,0.0072,0.0073205,0.007442,0.0075645,0.0076879999999999995,0.0078125,0.007938,0.0080645,0.008192,0.0083205,0.008450000000000001,0.008580500000000001,0.008712000000000001,0.008844500000000002,0.008978000000000002,0.0091125,0.009248000000000001,0.009384500000000002,0.009522000000000001,0.009660500000000002,0.009800000000000001,0.009940499999999998,0.010081999999999999,0.010224499999999997,0.010367999999999999,0.0105125,0.010657999999999999,0.010804499999999998,0.010951999999999998,0.0111005,0.01125,0.0114005,0.011552,0.0117045,0.011858,0.0120125,0.012168,0.0123245,0.012482,0.0126405,0.0128,0.012960500000000002,0.013122,0.013284500000000001,0.013448000000000002,0.013612500000000001,0.013778000000000002,0.013944500000000002,0.014112000000000001,0.014280500000000002,0.014450000000000003,0.014620500000000002,0.014791999999999998,0.014964499999999999,0.015137999999999999,0.015312499999999998,0.015487999999999998,0.015664499999999998,0.015842,0.0160205,0.0162,0.0163805,0.016562,0.0167445,0.016928,0.0171125,0.017298,0.0174845,0.017672,0.0178605,0.01805,0.0182405,0.018432,0.018624500000000002,0.018818,0.0190125,0.019208000000000003,0.0194045,0.019602,0.019800500000000002,0.020000000000000004], + "points": [-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2], + "mass": 1.0, + "deltaT": 0.006283185307179587, + "config": {"hbar": 0.001, "includeIntegralFactor": true, "firstDerivativeMethod": 1, "limitDiffOrder":10}, + "representation": {"type": "PositionRepresentation", "points": {"first": -0.2, "step": 0.001, "last": 0.2}}, + "psiRepresentation": {"type": "PositionRepresentation", "points": {"first": -1.2, "step": 0.01, "last": 1.2}}, + "t": 0.0, + "point": [1,0], + "Phi": { + "points": [-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2], + "real": [2.0611536224385798e-9,2.516240284713425e-9,3.0687362654894375e-9,3.738804234642454e-9,4.550630691832408e-9,5.533197382397935e-9,6.72119413188933e-9,8.15609774399975e-9,9.88744565699239e-9,1.1974337724765995e-8,1.448720486772067e-8,1.7509889523606172e-8,2.1142089929801404e-8,2.550222840930461e-8,3.073081315126601e-8,3.699437362700863e-8,4.4490061935838925e-8,5.345102622180876e-8,6.415267805440682e-8,7.691999355609062e-8,9.213600834566233e-8,1.1025168933173685e-7,1.3179739234671898e-7,1.5739614389882767e-7,1.8777901831051282e-7,2.2380291861017848e-7,2.664711111911477e-7,3.169569109216767e-7,3.7663096559741124e-7,4.47092646922628e-7,5.302061201824254e-7,6.281417370526457e-7,7.434234762611671e-7,8.789832457702949e-7,1.0382229585448585e-6,1.2250854025871248e-6,1.4441350455752707e-6,1.7006500459841837e-6,2.0007268868677803e-6,2.3513992064326504e-6,2.7607725720371842e-6,3.2381771322159403e-6,3.7943402856560683e-6,4.4415817276237596e-6,5.194033474002839e-6,6.0678877216671805e-6,7.081675682098663e-6,8.256580823632136e-6,9.616790277000472e-6,1.1189888499372013e-5,1.3007297654067575e-5,1.5104769546670746e-5,1.7522934363135202e-5,2.030791188132442e-5,2.351199127346768e-5,2.7194386082234394e-5,3.142207143607726e-5,3.627071106833144e-5,4.182568221696097e-5,4.81832070049914e-5,5.5451599432176945e-5,6.37526376423301e-5,7.32230716633574e-5,8.401627734305137e-5,9.630406771703447e-5,0.00011027867353903842,0.00012615490517032247,0.00014417250845590252,0.0001645987276010445,0.00018773108839185998,0.0002139004153676611,0.000243474096737915,0.00027685961093021247,0.0003145083286438566,0.0003569196041517842,0.0004046451693262645,0.0004582938434450188,0.0005185365712474733,0.0005861118009386385,0.0006618312128631535,0.0007465858083766792,0.0008413523670084695,0.0009472002783201107,0.0010652987529042202,0.001196924414716883,0.0013434692743837279,0.0015064490802475042,0.0016875120407226411,0.0018884479079789762,0.002111197409084511,0.0023578620064902346,0.0026307139651365764,0.0029322066985015887,0.0032649853606012925,0.0036318976453011864,0.004036004748319565,0.0044805924410166315,0.004969182198492818,0.005505542317696359,0.006093698954199208,0.006737946999085485,0.007442860710056664,0.0082133040034486,0.009054440306439602,0.009971741861376485,0.010970998366931507,0.01205832483381149,0.013240168526058726,0.014523314852706953,0.015914892068784228,0.01742237463949356,0.019053585116958073,0.02081669437530595,0.022720220047200777,0.02477302300331428,0.026984301715802572,0.029363584347699426,0.03192071841238939,0.034665857851076544,0.03760944738152102,0.04076220397836635,0.04413509535420937,0.04773931532124114,0.05158625592586989,0.05568747626327012,0.06005466789530813,0.06469961681378571,0.06963416191140524,0.07487014994526,0.08041938700193275,0.08629358649937015,0.09250431378848267,0.09906292744674687,0.10598051738688218,0.11326783993558903,0.12093525007041712,0.12899263103651892,0.13744932159945242,0.14631404122463498,0.15559481350864987,0.165298888221586,0.17543266235308283,0.18600160058690823,0.1970101556598578,0.20846168908963097,0.22035839278323321,0.23270121206157043,0.2454897706571467,0.25872229825963944,0.272395561198292,0.2865047968601895,0.30104365244924775,0.3160041286918619,0.33137652909136267,0.3471494153245097,0.36330956935901054,0.37984196285137806,0.3967297343592192,0.41395417487127345,0.4314947221221871,0.4493289641172209,0.4674326522449652,0.48577972430388433,0.5043423377113943,0.5230909131025002,0.5419941884591866,0.5610192838421699,0.5801317767238202,0.5992957878455379,0.6184740774452715,0.6376281516217728,0.6567183785223145,0.6757041139606256,0.6945438359924629,0.7131952878982818,0.7316156289466413,0.7497615922390409,0.7675896488675725,0.7850561775518291,0.8021176388616297,0.8187307530779816,0.8348526806969433,0.8504412045402328,0.8654549124031066,0.8798533791446437,0.8935973471085155,0.9066489037539208,0.9189716553768316,0.9305308958112056,0.9412937690184056,0.9512294245007139,0.9603091645114129,0.9685065820791975,0.9757976889184073,0.9821610323583007,0.9875778004938814,0.9920319148370607,0.9955101098295706,0.9980019986673331,0.9995001249791693,1.0,0.9995001249791694,0.9980019986673331,0.9955101098295709,0.9920319148370607,0.987577800493882,0.9821610323583007,0.975797688918408,0.9685065820791975,0.9603091645114139,0.9512294245007139,0.9412937690184067,0.9305308958112056,0.9189716553768329,0.9066489037539208,0.893597347108517,0.8798533791446437,0.8654549124031082,0.8504412045402328,0.834852680696945,0.8187307530779816,0.8021176388616315,0.7850561775518291,0.7675896488675744,0.7497615922390409,0.7316156289466434,0.7131952878982818,0.694543835992465,0.6757041139606256,0.6567183785223166,0.6376281516217728,0.6184740774452736,0.5992957878455379,0.5801317767238223,0.5610192838421699,0.5419941884591887,0.5230909131025002,0.5043423377113962,0.48577972430388433,0.4674326522449672,0.4493289641172209,0.4314947221221891,0.41395417487127345,0.3967297343592211,0.37984196285137806,0.3633095693590124,0.3471494153245097,0.33137652909136445,0.3160041286918619,0.30104365244924935,0.2865047968601895,0.2723955611982936,0.25872229825963944,0.2454897706571481,0.23270121206157043,0.22035839278323463,0.20846168908963097,0.19701015565985908,0.18600160058690823,0.17543266235308283,0.165298888221586,0.15559481350864987,0.14631404122463498,0.13744932159945242,0.12899263103651892,0.12093525007041712,0.11326783993558903,0.10598051738688218,0.09906292744674687,0.09250431378848267,0.08629358649937015,0.08041938700193275,0.07487014994525941,0.06963416191140524,0.06469961681378515,0.06005466789530813,0.05568747626326965,0.05158625592586989,0.04773931532124074,0.04413509535420937,0.040762203978365975,0.03760944738152102,0.03466585785107624,0.03192071841238939,0.029363584347699152,0.026984301715802572,0.024773023003314038,0.022720220047200777,0.020816694375305735,0.019053585116958073,0.017422374639493376,0.015914892068784228,0.014523314852706798,0.013240168526058726,0.012058324833811362,0.010970998366931507,0.009971741861376386,0.009054440306439602,0.008213304003448505,0.007442860710056664,0.006737946999085407,0.006093698954199208,0.005505542317696296,0.004969182198492818,0.004480592441016576,0.004036004748319565,0.0036318976453011413,0.0032649853606012925,0.002932206698501555,0.0026307139651365764,0.0023578620064902056,0.002111197409084511,0.0018884479079789543,0.0016875120407226411,0.0015064490802474842,0.0013434692743837279,0.0011969244147168672,0.0010652987529042202,0.0009472002783201233,0.0008413523670084695,0.00074658580837667,0.0006618312128631535,0.0005861118009386467,0.0005185365712474733,0.0004582938434450127,0.0004046451693262645,0.00035691960415178923,0.0003145083286438566,0.00027685961093020856,0.000243474096737915,0.00021390041536766452,0.00018773108839185998,0.00016459872760104217,0.00014417250845590252,0.00012615490517032448,0.00011027867353903842,9.630406771703293e-5,8.401627734305137e-5,7.322307166335831e-5,6.37526376423301e-5,5.545159943217606e-5,4.81832070049914e-5,4.182568221696164e-5,3.627071106833144e-5,3.142207143607776e-5,2.7194386082234394e-5,2.3511991273468056e-5,2.030791188132442e-5,1.7522934363135514e-5,1.5104769546670746e-5,1.3007297654067783e-5,1.1189888499372013e-5,9.616790277000626e-6,8.256580823632136e-6,7.0816756820987894e-6,6.0678877216671805e-6,5.194033474002922e-6,4.4415817276237596e-6,3.794340285656129e-6,3.2381771322159403e-6,2.760772572037238e-6,2.3513992064326504e-6,2.000726886867816e-6,1.7006500459841837e-6,1.4441350455752963e-6,1.2250854025871248e-6,1.038222958544877e-6,8.789832457702949e-7,7.434234762611816e-7,6.281417370526457e-7,5.302061201824356e-7,4.47092646922628e-7,3.7663096559741124e-7,3.169569109216767e-7,2.664711111911477e-7,2.2380291861017848e-7,1.8777901831051282e-7,1.5739614389882767e-7,1.3179739234671898e-7,1.1025168933173685e-7,9.213600834566233e-8,7.691999355609062e-8,6.415267805440682e-8,5.345102622180876e-8,4.4490061935838925e-8,3.699437362700863e-8,3.073081315126601e-8,2.550222840930461e-8,2.1142089929801404e-8,1.7509889523606172e-8,1.448720486772067e-8,1.1974337724765995e-8,9.88744565699239e-9,8.15609774399975e-9,6.72119413188933e-9,5.533197382397935e-9,4.550630691832408e-9,3.738804234642454e-9,3.0687362654894375e-9,2.516240284713425e-9,2.0611536224385798e-9], + "imaginary": [-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0,-0.0] + }, + "V_t": [0.020000000000000004,0.019800500000000002,0.019602,0.0194045,0.019208000000000003,0.0190125,0.018818,0.018624500000000002,0.018432,0.0182405,0.01805,0.0178605,0.017672,0.0174845,0.017298,0.0171125,0.016928,0.0167445,0.016562,0.0163805,0.0162,0.0160205,0.015842,0.015664499999999998,0.015487999999999998,0.015312499999999998,0.015137999999999999,0.014964499999999999,0.014791999999999998,0.014620500000000002,0.014450000000000003,0.014280500000000002,0.014112000000000001,0.013944500000000002,0.013778000000000002,0.013612500000000001,0.013448000000000002,0.013284500000000001,0.013122,0.012960500000000002,0.0128,0.0126405,0.012482,0.0123245,0.012168,0.0120125,0.011858,0.0117045,0.011552,0.0114005,0.01125,0.0111005,0.010951999999999998,0.010804499999999998,0.010657999999999999,0.0105125,0.010367999999999999,0.010224499999999997,0.010081999999999999,0.009940499999999998,0.009800000000000001,0.009660500000000002,0.009522000000000001,0.009384500000000002,0.009248000000000001,0.0091125,0.008978000000000002,0.008844500000000002,0.008712000000000001,0.008580500000000001,0.008450000000000001,0.0083205,0.008192,0.0080645,0.007938,0.0078125,0.0076879999999999995,0.0075645,0.007442,0.0073205,0.0072,0.007080499999999999,0.0069619999999999994,0.006844500000000001,0.0067280000000000005,0.0066125,0.006498,0.0063845,0.006272000000000001,0.0061605,0.00605,0.0059405,0.0058319999999999995,0.0057244999999999996,0.005618,0.005512499999999999,0.005408,0.005304499999999999,0.005201999999999999,0.005100500000000001,0.005000000000000001,0.0049005,0.004802000000000001,0.0047045,0.004608,0.0045125,0.004418,0.0043245,0.004232,0.0041405,0.00405,0.0039605,0.0038719999999999996,0.0037844999999999997,0.0036979999999999995,0.0036125000000000007,0.0035280000000000003,0.0034445000000000005,0.0033620000000000004,0.0032805,0.0032,0.0031205,0.003042,0.0029645,0.002888,0.0028125,0.0027379999999999995,0.0026644999999999998,0.0025919999999999997,0.0025204999999999997,0.0024500000000000004,0.0023805000000000002,0.0023120000000000003,0.0022445000000000004,0.0021780000000000002,0.0021125000000000002,0.002048,0.0019845,0.0019219999999999999,0.0018605,0.0018,0.0017404999999999999,0.0016820000000000001,0.0016245,0.0015680000000000002,0.0015125,0.0014579999999999999,0.0014045,0.001352,0.0013004999999999998,0.0012500000000000002,0.0012005000000000002,0.001152,0.0011045,0.001058,0.0010125,0.0009679999999999999,0.0009244999999999999,0.0008820000000000001,0.0008405000000000001,0.0008,0.0007605,0.000722,0.0006844999999999999,0.0006479999999999999,0.0006125000000000001,0.0005780000000000001,0.0005445000000000001,0.000512,0.00048049999999999997,0.00045,0.00042050000000000003,0.00039200000000000004,0.00036449999999999997,0.000338,0.00031250000000000006,0.000288,0.0002645,0.00024199999999999997,0.00022050000000000002,0.0002,0.0001805,0.00016199999999999998,0.00014450000000000002,0.000128,0.0001125,9.800000000000001e-5,8.45e-5,7.2e-5,6.049999999999999e-5,5.0e-5,4.0499999999999995e-5,3.2e-5,2.4500000000000003e-5,1.8e-5,1.25e-5,8.0e-6,4.5e-6,2.0e-6,5.0e-7,0.0,5.0e-7,2.0e-6,4.5e-6,8.0e-6,1.25e-5,1.8e-5,2.4500000000000003e-5,3.2e-5,4.0499999999999995e-5,5.0e-5,6.049999999999999e-5,7.2e-5,8.45e-5,9.800000000000001e-5,0.0001125,0.000128,0.00014450000000000002,0.00016199999999999998,0.0001805,0.0002,0.00022050000000000002,0.00024199999999999997,0.0002645,0.000288,0.00031250000000000006,0.000338,0.00036449999999999997,0.00039200000000000004,0.00042050000000000003,0.00045,0.00048049999999999997,0.000512,0.0005445000000000001,0.0005780000000000001,0.0006125000000000001,0.0006479999999999999,0.0006844999999999999,0.000722,0.0007605,0.0008,0.0008405000000000001,0.0008820000000000001,0.0009244999999999999,0.0009679999999999999,0.0010125,0.001058,0.0011045,0.001152,0.0012005000000000002,0.0012500000000000002,0.0013004999999999998,0.001352,0.0014045,0.0014579999999999999,0.0015125,0.0015680000000000002,0.0016245,0.0016820000000000001,0.0017404999999999999,0.0018,0.0018605,0.0019219999999999999,0.0019845,0.002048,0.0021125000000000002,0.0021780000000000002,0.0022445000000000004,0.0023120000000000003,0.0023805000000000002,0.0024500000000000004,0.0025204999999999997,0.0025919999999999997,0.0026644999999999998,0.0027379999999999995,0.0028125,0.002888,0.0029645,0.003042,0.0031205,0.0032,0.0032805,0.0033620000000000004,0.0034445000000000005,0.0035280000000000003,0.0036125000000000007,0.0036979999999999995,0.0037844999999999997,0.0038719999999999996,0.0039605,0.00405,0.0041405,0.004232,0.0043245,0.004418,0.0045125,0.004608,0.0047045,0.004802000000000001,0.0049005,0.005000000000000001,0.005100500000000001,0.005201999999999999,0.005304499999999999,0.005408,0.005512499999999999,0.005618,0.0057244999999999996,0.0058319999999999995,0.0059405,0.00605,0.0061605,0.006272000000000001,0.0063845,0.006498,0.0066125,0.0067280000000000005,0.006844500000000001,0.0069619999999999994,0.007080499999999999,0.0072,0.0073205,0.007442,0.0075645,0.0076879999999999995,0.0078125,0.007938,0.0080645,0.008192,0.0083205,0.008450000000000001,0.008580500000000001,0.008712000000000001,0.008844500000000002,0.008978000000000002,0.0091125,0.009248000000000001,0.009384500000000002,0.009522000000000001,0.009660500000000002,0.009800000000000001,0.009940499999999998,0.010081999999999999,0.010224499999999997,0.010367999999999999,0.0105125,0.010657999999999999,0.010804499999999998,0.010951999999999998,0.0111005,0.01125,0.0114005,0.011552,0.0117045,0.011858,0.0120125,0.012168,0.0123245,0.012482,0.0126405,0.0128,0.012960500000000002,0.013122,0.013284500000000001,0.013448000000000002,0.013612500000000001,0.013778000000000002,0.013944500000000002,0.014112000000000001,0.014280500000000002,0.014450000000000003,0.014620500000000002,0.014791999999999998,0.014964499999999999,0.015137999999999999,0.015312499999999998,0.015487999999999998,0.015664499999999998,0.015842,0.0160205,0.0162,0.0163805,0.016562,0.0167445,0.016928,0.0171125,0.017298,0.0174845,0.017672,0.0178605,0.01805,0.0182405,0.018432,0.018624500000000002,0.018818,0.0190125,0.019208000000000003,0.0194045,0.019602,0.019800500000000002,0.020000000000000004], + "points": [-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2] +} \ No newline at end of file diff --git a/examples/harmonicOscillator/groundStateQm.json b/examples/harmonicOscillator/groundStateQm.json new file mode 100644 index 0000000..3078483 --- /dev/null +++ b/examples/harmonicOscillator/groundStateQm.json @@ -0,0 +1,18 @@ +{ + "type": "qm", + "scheme": {"id": "CrankNicolson" }, + "V_coefficients": [0,0,1], + "V": [0.020000000000000004,0.019800500000000002,0.019602,0.0194045,0.019208000000000003,0.0190125,0.018818,0.018624500000000002,0.018432,0.0182405,0.01805,0.0178605,0.017672,0.0174845,0.017298,0.0171125,0.016928,0.0167445,0.016562,0.0163805,0.0162,0.0160205,0.015842,0.015664499999999998,0.015487999999999998,0.015312499999999998,0.015137999999999999,0.014964499999999999,0.014791999999999998,0.014620500000000002,0.014450000000000003,0.014280500000000002,0.014112000000000001,0.013944500000000002,0.013778000000000002,0.013612500000000001,0.013448000000000002,0.013284500000000001,0.013122,0.012960500000000002,0.0128,0.0126405,0.012482,0.0123245,0.012168,0.0120125,0.011858,0.0117045,0.011552,0.0114005,0.01125,0.0111005,0.010951999999999998,0.010804499999999998,0.010657999999999999,0.0105125,0.010367999999999999,0.010224499999999997,0.010081999999999999,0.009940499999999998,0.009800000000000001,0.009660500000000002,0.009522000000000001,0.009384500000000002,0.009248000000000001,0.0091125,0.008978000000000002,0.008844500000000002,0.008712000000000001,0.008580500000000001,0.008450000000000001,0.0083205,0.008192,0.0080645,0.007938,0.0078125,0.0076879999999999995,0.0075645,0.007442,0.0073205,0.0072,0.007080499999999999,0.0069619999999999994,0.006844500000000001,0.0067280000000000005,0.0066125,0.006498,0.0063845,0.006272000000000001,0.0061605,0.00605,0.0059405,0.0058319999999999995,0.0057244999999999996,0.005618,0.005512499999999999,0.005408,0.005304499999999999,0.005201999999999999,0.005100500000000001,0.005000000000000001,0.0049005,0.004802000000000001,0.0047045,0.004608,0.0045125,0.004418,0.0043245,0.004232,0.0041405,0.00405,0.0039605,0.0038719999999999996,0.0037844999999999997,0.0036979999999999995,0.0036125000000000007,0.0035280000000000003,0.0034445000000000005,0.0033620000000000004,0.0032805,0.0032,0.0031205,0.003042,0.0029645,0.002888,0.0028125,0.0027379999999999995,0.0026644999999999998,0.0025919999999999997,0.0025204999999999997,0.0024500000000000004,0.0023805000000000002,0.0023120000000000003,0.0022445000000000004,0.0021780000000000002,0.0021125000000000002,0.002048,0.0019845,0.0019219999999999999,0.0018605,0.0018,0.0017404999999999999,0.0016820000000000001,0.0016245,0.0015680000000000002,0.0015125,0.0014579999999999999,0.0014045,0.001352,0.0013004999999999998,0.0012500000000000002,0.0012005000000000002,0.001152,0.0011045,0.001058,0.0010125,0.0009679999999999999,0.0009244999999999999,0.0008820000000000001,0.0008405000000000001,0.0008,0.0007605,0.000722,0.0006844999999999999,0.0006479999999999999,0.0006125000000000001,0.0005780000000000001,0.0005445000000000001,0.000512,0.00048049999999999997,0.00045,0.00042050000000000003,0.00039200000000000004,0.00036449999999999997,0.000338,0.00031250000000000006,0.000288,0.0002645,0.00024199999999999997,0.00022050000000000002,0.0002,0.0001805,0.00016199999999999998,0.00014450000000000002,0.000128,0.0001125,9.800000000000001e-5,8.45e-5,7.2e-5,6.049999999999999e-5,5.0e-5,4.0499999999999995e-5,3.2e-5,2.4500000000000003e-5,1.8e-5,1.25e-5,8.0e-6,4.5e-6,2.0e-6,5.0e-7,0.0,5.0e-7,2.0e-6,4.5e-6,8.0e-6,1.25e-5,1.8e-5,2.4500000000000003e-5,3.2e-5,4.0499999999999995e-5,5.0e-5,6.049999999999999e-5,7.2e-5,8.45e-5,9.800000000000001e-5,0.0001125,0.000128,0.00014450000000000002,0.00016199999999999998,0.0001805,0.0002,0.00022050000000000002,0.00024199999999999997,0.0002645,0.000288,0.00031250000000000006,0.000338,0.00036449999999999997,0.00039200000000000004,0.00042050000000000003,0.00045,0.00048049999999999997,0.000512,0.0005445000000000001,0.0005780000000000001,0.0006125000000000001,0.0006479999999999999,0.0006844999999999999,0.000722,0.0007605,0.0008,0.0008405000000000001,0.0008820000000000001,0.0009244999999999999,0.0009679999999999999,0.0010125,0.001058,0.0011045,0.001152,0.0012005000000000002,0.0012500000000000002,0.0013004999999999998,0.001352,0.0014045,0.0014579999999999999,0.0015125,0.0015680000000000002,0.0016245,0.0016820000000000001,0.0017404999999999999,0.0018,0.0018605,0.0019219999999999999,0.0019845,0.002048,0.0021125000000000002,0.0021780000000000002,0.0022445000000000004,0.0023120000000000003,0.0023805000000000002,0.0024500000000000004,0.0025204999999999997,0.0025919999999999997,0.0026644999999999998,0.0027379999999999995,0.0028125,0.002888,0.0029645,0.003042,0.0031205,0.0032,0.0032805,0.0033620000000000004,0.0034445000000000005,0.0035280000000000003,0.0036125000000000007,0.0036979999999999995,0.0037844999999999997,0.0038719999999999996,0.0039605,0.00405,0.0041405,0.004232,0.0043245,0.004418,0.0045125,0.004608,0.0047045,0.004802000000000001,0.0049005,0.005000000000000001,0.005100500000000001,0.005201999999999999,0.005304499999999999,0.005408,0.005512499999999999,0.005618,0.0057244999999999996,0.0058319999999999995,0.0059405,0.00605,0.0061605,0.006272000000000001,0.0063845,0.006498,0.0066125,0.0067280000000000005,0.006844500000000001,0.0069619999999999994,0.007080499999999999,0.0072,0.0073205,0.007442,0.0075645,0.0076879999999999995,0.0078125,0.007938,0.0080645,0.008192,0.0083205,0.008450000000000001,0.008580500000000001,0.008712000000000001,0.008844500000000002,0.008978000000000002,0.0091125,0.009248000000000001,0.009384500000000002,0.009522000000000001,0.009660500000000002,0.009800000000000001,0.009940499999999998,0.010081999999999999,0.010224499999999997,0.010367999999999999,0.0105125,0.010657999999999999,0.010804499999999998,0.010951999999999998,0.0111005,0.01125,0.0114005,0.011552,0.0117045,0.011858,0.0120125,0.012168,0.0123245,0.012482,0.0126405,0.0128,0.012960500000000002,0.013122,0.013284500000000001,0.013448000000000002,0.013612500000000001,0.013778000000000002,0.013944500000000002,0.014112000000000001,0.014280500000000002,0.014450000000000003,0.014620500000000002,0.014791999999999998,0.014964499999999999,0.015137999999999999,0.015312499999999998,0.015487999999999998,0.015664499999999998,0.015842,0.0160205,0.0162,0.0163805,0.016562,0.0167445,0.016928,0.0171125,0.017298,0.0174845,0.017672,0.0178605,0.01805,0.0182405,0.018432,0.018624500000000002,0.018818,0.0190125,0.019208000000000003,0.0194045,0.019602,0.019800500000000002,0.020000000000000004], + "points": [-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2], + "mass": 1.0, + "deltaT": 0.012566370614359173, + "t": 0.0, + "config": {"hbar": 0.001, "includeIntegralFactor": true, "firstDerivativeMethod": 1, "limitDiffOrder":10}, + "representation": {"type": "PositionRepresentation", "points": {"first": -0.2, "step": 0.001, "last": 0.2}}, + "psi": { + "points": [-0.2,-0.199,-0.198,-0.197,-0.196,-0.195,-0.194,-0.193,-0.192,-0.191,-0.19,-0.189,-0.188,-0.187,-0.186,-0.185,-0.184,-0.183,-0.182,-0.181,-0.18,-0.179,-0.178,-0.177,-0.176,-0.175,-0.174,-0.173,-0.172,-0.171,-0.17,-0.169,-0.168,-0.167,-0.166,-0.165,-0.164,-0.163,-0.162,-0.161,-0.16,-0.159,-0.158,-0.157,-0.156,-0.155,-0.154,-0.153,-0.152,-0.151,-0.15,-0.149,-0.148,-0.147,-0.146,-0.145,-0.144,-0.143,-0.142,-0.141,-0.14,-0.139,-0.138,-0.137,-0.136,-0.135,-0.134,-0.133,-0.132,-0.131,-0.13,-0.129,-0.128,-0.127,-0.126,-0.125,-0.124,-0.123,-0.122,-0.121,-0.12,-0.119,-0.118,-0.117,-0.116,-0.115,-0.114,-0.113,-0.112,-0.111,-0.11,-0.109,-0.108,-0.107,-0.106,-0.105,-0.104,-0.103,-0.102,-0.101,-0.1,-0.099,-0.098,-0.097,-0.096,-0.095,-0.094,-0.093,-0.092,-0.091,-0.09,-0.089,-0.088,-0.087,-0.086,-0.085,-0.084,-0.083,-0.082,-0.081,-0.08,-0.079,-0.078,-0.077,-0.076,-0.075,-0.074,-0.073,-0.072,-0.071,-0.07,-0.069,-0.068,-0.067,-0.066,-0.065,-0.064,-0.063,-0.062,-0.061,-0.06,-0.059,-0.058,-0.057,-0.056,-0.055,-0.054,-0.053,-0.052,-0.051,-0.05,-0.049,-0.048,-0.047,-0.046,-0.045,-0.044,-0.043,-0.042,-0.041,-0.04,-0.039,-0.038,-0.037,-0.036,-0.035,-0.034,-0.033,-0.032,-0.031,-0.03,-0.029,-0.028,-0.027,-0.026,-0.025,-0.024,-0.023,-0.022,-0.021,-0.02,-0.019,-0.018,-0.017,-0.016,-0.015,-0.014,-0.013,-0.012,-0.011,-0.01,-0.009,-0.008,-0.007,-0.006,-0.005,-0.004,-0.003,-0.002,-0.001,0.0,0.001,0.002,0.003,0.004,0.005,0.006,0.007,0.008,0.009,0.01,0.011,0.012,0.013,0.014,0.015,0.016,0.017,0.018,0.019,0.02,0.021,0.022,0.023,0.024,0.025,0.026,0.027,0.028,0.029,0.03,0.031,0.032,0.033,0.034,0.035,0.036,0.037,0.038,0.039,0.04,0.041,0.042,0.043,0.044,0.045,0.046,0.047,0.048,0.049,0.05,0.051,0.052,0.053,0.054,0.055,0.056,0.057,0.058,0.059,0.06,0.061,0.062,0.063,0.064,0.065,0.066,0.067,0.068,0.069,0.07,0.071,0.072,0.073,0.074,0.075,0.076,0.077,0.078,0.079,0.08,0.081,0.082,0.083,0.084,0.085,0.086,0.087,0.088,0.089,0.09,0.091,0.092,0.093,0.094,0.095,0.096,0.097,0.098,0.099,0.1,0.101,0.102,0.103,0.104,0.105,0.106,0.107,0.108,0.109,0.11,0.111,0.112,0.113,0.114,0.115,0.116,0.117,0.118,0.119,0.12,0.121,0.122,0.123,0.124,0.125,0.126,0.127,0.128,0.129,0.13,0.131,0.132,0.133,0.134,0.135,0.136,0.137,0.138,0.139,0.14,0.141,0.142,0.143,0.144,0.145,0.146,0.147,0.148,0.149,0.15,0.151,0.152,0.153,0.154,0.155,0.156,0.157,0.158,0.159,0.16,0.161,0.162,0.163,0.164,0.165,0.166,0.167,0.168,0.169,0.17,0.171,0.172,0.173,0.174,0.175,0.176,0.177,0.178,0.179,0.18,0.181,0.182,0.183,0.184,0.185,0.186,0.187,0.188,0.189,0.19,0.191,0.192,0.193,0.194,0.195,0.196,0.197,0.198,0.199,0.2], + "real": [2.0611536224385504e-9,2.5162402847134513e-9,3.068736265489405e-9,3.738804234642494e-9,4.550630691832344e-9,5.5331973823979935e-9,6.721194131889258e-9,8.156097743999838e-9,9.88744565699232e-9,1.1974337724766124e-8,1.4487204867720514e-8,1.750988952360636e-8,2.114208992980118e-8,2.550222840930488e-8,3.073081315126569e-8,3.6994373627009155e-8,4.449006193583845e-8,5.345102622180933e-8,6.415267805440613e-8,7.691999355609144e-8,9.213600834566135e-8,1.1025168933173763e-7,1.3179739234671758e-7,1.5739614389882933e-7,1.877790183105108e-7,2.2380291861018086e-7,2.664711111911448e-7,3.1695691092168007e-7,3.7663096559740727e-7,4.470926469226304e-7,5.302061201824272e-7,6.281417370526491e-7,7.434234762611724e-7,8.789832457702981e-7,1.0382229585448621e-6,1.2250854025871314e-6,1.4441350455752758e-6,1.7006500459841898e-6,2.0007268868677913e-6,2.351399206432659e-6,2.7607725720371986e-6,3.2381771322159517e-6,3.7943402856560886e-6,4.441581727623776e-6,5.194033474002857e-6,6.067887721667202e-6,7.081675682098689e-6,8.256580823632166e-6,9.616790277000506e-6,1.1189888499372052e-5,1.300729765406762e-5,1.51047695466708e-5,1.7522934363135297e-5,2.0307911881324526e-5,2.3511991273467765e-5,2.719438608223449e-5,3.1422071436077375e-5,3.6270711068331634e-5,4.182568221696112e-5,4.818320700499157e-5,5.5451599432176945e-5,6.37526376423301e-5,7.32230716633574e-5,8.401627734305137e-5,9.630406771703447e-5,0.00011027867353903842,0.00012615490517032247,0.00014417250845590252,0.0001645987276010445,0.00018773108839185998,0.0002139004153676611,0.000243474096737915,0.00027685961093021247,0.0003145083286438566,0.0003569196041517842,0.0004046451693262645,0.0004582938434450188,0.0005185365712474733,0.0005861118009386389,0.0006618312128631535,0.0007465858083766799,0.0008413523670084695,0.0009472002783201115,0.0010652987529042183,0.0011969244147168809,0.0013434692743837268,0.0015064490802475016,0.0016875120407226383,0.0018884479079789745,0.0021111974090845076,0.002357862006490233,0.0026307139651365738,0.0029322066985015887,0.0032649853606012925,0.00363189764530118,0.004036004748319562,0.004480592441016624,0.004969182198492809,0.005505542317696355,0.006093698954199193,0.006737946999085461,0.007442860710056644,0.00821330400344857,0.009054440306439577,0.009971741861376466,0.010970998366931477,0.012058324833811458,0.013240168526058691,0.014523314852706914,0.015914892068784183,0.017422374639493515,0.019053585116958024,0.020816694375305894,0.02272022004720072,0.024773023003314215,0.026984301715802465,0.029363584347699333,0.031920718412389276,0.034665857851076426,0.0376094473815209,0.04076220397836621,0.04413509535420925,0.047739315321240997,0.051586255925869705,0.05568747626326995,0.060054667895307945,0.0646996168137855,0.06963416191140502,0.07487014994525978,0.0804193870019325,0.0862935864993705,0.0925043137884824,0.09906292744674727,0.10598051738688176,0.11326783993558943,0.12093525007041664,0.1289926310365194,0.13744932159945192,0.14631404122463545,0.15559481350864937,0.16529888822158656,0.17543266235308227,0.18600160058690876,0.19701015565985838,0.20846168908963153,0.22035839278323385,0.2327012120615711,0.24548977065714736,0.2587222982596401,0.2723955611982928,0.28650479686019004,0.30104365244924836,0.31600412869186256,0.33137652909136334,0.34714941532451044,0.36330956935901126,0.3798419628513787,0.3967297343592199,0.4139541748712741,0.4314947221221877,0.44932896411722156,0.46743265224496583,0.485779724303885,0.5043423377113949,0.5230909131025009,0.5419941884591871,0.5610192838421705,0.5801317767238207,0.5992957878455384,0.618474077445272,0.6376281516217733,0.656718378522315,0.675704113960626,0.6945438359924635,0.7131952878982822,0.7316156289466418,0.7497615922390413,0.7675896488675729,0.7850561775518295,0.8021176388616299,0.8187307530779818,0.8348526806969435,0.850441204540233,0.8654549124031068,0.8798533791446438,0.8935973471085157,0.9066489037539209,0.9189716553768317,0.9305308958112057,0.9412937690184057,0.951229424500714,0.960309164511413,0.9685065820791976,0.9757976889184073,0.9821610323583008,0.9875778004938814,0.9920319148370607,0.9955101098295706,0.9980019986673331,0.9995001249791693,1.0,0.9995001249791693,0.9980019986673331,0.9955101098295706,0.9920319148370607,0.9875778004938814,0.9821610323583008,0.9757976889184073,0.9685065820791976,0.960309164511413,0.951229424500714,0.9412937690184057,0.9305308958112057,0.9189716553768317,0.9066489037539209,0.8935973471085157,0.8798533791446438,0.8654549124031068,0.850441204540233,0.8348526806969435,0.8187307530779818,0.8021176388616299,0.7850561775518295,0.7675896488675729,0.7497615922390413,0.7316156289466418,0.7131952878982822,0.6945438359924635,0.675704113960626,0.656718378522315,0.6376281516217733,0.618474077445272,0.5992957878455384,0.5801317767238207,0.5610192838421705,0.5419941884591871,0.5230909131025009,0.5043423377113949,0.485779724303885,0.46743265224496583,0.44932896411722156,0.4314947221221877,0.4139541748712741,0.3967297343592199,0.3798419628513787,0.36330956935901126,0.34714941532451044,0.33137652909136334,0.31600412869186256,0.30104365244924836,0.28650479686019004,0.2723955611982928,0.2587222982596401,0.24548977065714736,0.2327012120615711,0.22035839278323385,0.20846168908963153,0.19701015565985838,0.18600160058690876,0.17543266235308227,0.16529888822158656,0.15559481350864937,0.14631404122463545,0.13744932159945192,0.1289926310365194,0.12093525007041664,0.11326783993558943,0.10598051738688176,0.09906292744674727,0.0925043137884824,0.0862935864993705,0.0804193870019325,0.07487014994525978,0.06963416191140502,0.0646996168137855,0.060054667895307945,0.05568747626326995,0.051586255925869705,0.047739315321240997,0.04413509535420925,0.04076220397836621,0.0376094473815209,0.034665857851076426,0.031920718412389276,0.029363584347699333,0.026984301715802465,0.024773023003314215,0.02272022004720072,0.020816694375305894,0.019053585116958024,0.017422374639493515,0.015914892068784183,0.014523314852706914,0.013240168526058691,0.012058324833811458,0.010970998366931477,0.009971741861376466,0.009054440306439577,0.00821330400344857,0.007442860710056644,0.006737946999085461,0.006093698954199193,0.005505542317696355,0.004969182198492809,0.004480592441016624,0.004036004748319562,0.00363189764530118,0.0032649853606012925,0.0029322066985015887,0.0026307139651365738,0.002357862006490233,0.0021111974090845076,0.0018884479079789745,0.0016875120407226383,0.0015064490802475016,0.0013434692743837268,0.0011969244147168809,0.0010652987529042183,0.0009472002783201115,0.0008413523670084695,0.0007465858083766799,0.0006618312128631535,0.0005861118009386389,0.0005185365712474733,0.0004582938434450188,0.0004046451693262645,0.0003569196041517842,0.0003145083286438566,0.00027685961093021247,0.000243474096737915,0.0002139004153676611,0.00018773108839185998,0.0001645987276010445,0.00014417250845590252,0.00012615490517032247,0.00011027867353903842,9.630406771703447e-5,8.401627734305137e-5,7.32230716633574e-5,6.37526376423301e-5,5.5451599432176945e-5,4.818320700499157e-5,4.182568221696112e-5,3.6270711068331634e-5,3.1422071436077375e-5,2.719438608223449e-5,2.3511991273467765e-5,2.0307911881324526e-5,1.7522934363135297e-5,1.51047695466708e-5,1.300729765406762e-5,1.1189888499372052e-5,9.616790277000506e-6,8.256580823632166e-6,7.081675682098689e-6,6.067887721667202e-6,5.194033474002857e-6,4.441581727623776e-6,3.7943402856560886e-6,3.2381771322159517e-6,2.7607725720371986e-6,2.351399206432659e-6,2.0007268868677913e-6,1.7006500459841898e-6,1.4441350455752758e-6,1.2250854025871314e-6,1.0382229585448621e-6,8.789832457702981e-7,7.434234762611724e-7,6.281417370526491e-7,5.302061201824272e-7,4.470926469226304e-7,3.7663096559740727e-7,3.1695691092168007e-7,2.664711111911448e-7,2.2380291861018086e-7,1.877790183105108e-7,1.5739614389882933e-7,1.3179739234671758e-7,1.1025168933173763e-7,9.213600834566135e-8,7.691999355609144e-8,6.415267805440613e-8,5.345102622180933e-8,4.449006193583845e-8,3.6994373627009155e-8,3.073081315126569e-8,2.550222840930488e-8,2.114208992980118e-8,1.750988952360636e-8,1.4487204867720514e-8,1.1974337724766124e-8,9.88744565699232e-9,8.156097743999838e-9,6.721194131889258e-9,5.5331973823979935e-9,4.550630691832344e-9,3.738804234642494e-9,3.068736265489405e-9,2.5162402847134513e-9,2.0611536224385504e-9], + "imaginary": [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] + }, + "doNormalize": false +} \ No newline at end of file diff --git a/src/ClassicalSystem.jl b/src/ClassicalSystem.jl new file mode 100644 index 0000000..79ac0b9 --- /dev/null +++ b/src/ClassicalSystem.jl @@ -0,0 +1,88 @@ +struct ClassicalSystem + initialState::AbstractPoint + hamiltonian::AbstractObservable + propagator::ClassicalPropagator + scheme::ClassicalNumericsScheme + deltaT::Real + # state + currentTime::Real + currentState::AbstractPoint + function ClassicalSystem(point::AbstractPoint, hamiltonian::AbstractObservable, deltaT::Real; + scheme::ClassicalNumericsScheme=SymplecticEuler(), t0::Real=0.) + propagator::ClassicalPropagator = incarnate(hamiltonian, scheme, deltaT) + return new(point, hamiltonian, propagator, scheme, deltaT, t0, point) + end # ClassicalSystem + function ClassicalSystem(other::ClassicalSystem, t::Real, point::AbstractPoint) + return new(other.initialState, other.hamiltonian, other.propagator, + other.scheme, other.deltaT, t, point) + end # ClassicalSystem +end # ClassicalSystem + +function scheme(system::ClassicalSystem)::NumericsScheme + return system.scheme +end + +function hamiltonian(system::ClassicalSystem)::AbstractObservable + return system.hamiltonian +end + +function deltaT(system::ClassicalSystem)::Real + return system.deltaT +end + +function propagate(system::ClassicalSystem, timeSteps::Int=1)::ClassicalSystem + for _ in 1:timeSteps + point::AbstractPoint = propagateSingleTimestep(system.currentState, system.propagator) + system = ClassicalSystem(system, system.currentTime + system.deltaT, point) + end # for k + return system +end # p + +function _writeSettings(system::ClassicalSystem, file::IO) + indent::String = " " + write(file, "{\n") + write(file, indent, "\"type\": \"classical\",\n") + write(file, indent, "\"deltaT\": $(system.deltaT),\n") + write(file, indent, "\"scheme\": $(_schemeToJson(system.scheme))") + try + _writePotentialJson(file, projectX(system.hamiltonian), + indent=length(indent), startWithComma=true) + catch + end + write(file, "\n}\n") +end # _writeSettings + + +function trace(system::ClassicalSystem, timeSteps::Int=1000; + folder::String = "./results") # io::IO + Base.Filesystem.mkpath(folder) + settingsFile::String = joinpath(folder, "settings.json") + pointsFile::String = joinpath(folder, "points.csv") + open(settingsFile, "w") do settingsFile1 + _writeSettings(system, settingsFile1) + end # settingsFile + V::Any = nothing + try + V = projectX(system.hamiltonian) # we expect this to be a function of x + catch + end + open(pointsFile, "w") do fileObservables + write(fileObservables, "x, p, E\n") + for _ in 1:timeSteps + # write expectation values + point::Point = pin(system.currentState) + xVal::Real = point.q + pVal::Real = point.p + energy::Real = system.hamiltonian(point) + write(fileObservables, "$(xVal), $(pVal), $(energy)\n") + system = propagate(system, 1) + end # for k + end # open fileObservables + return system + +end # trace + +export ClassicalSystem +export propagate +export trace + diff --git a/src/CrankNicolson.jl b/src/CrankNicolson.jl new file mode 100644 index 0000000..fde16a2 --- /dev/null +++ b/src/CrankNicolson.jl @@ -0,0 +1,42 @@ +raw"Implements the Crank-Nicolson integration scheme for the Schrödinger equation, i.e. +(1+i/(2\hbar) \hat H) \psi(t+1) = (1-i/(2\hbar) \hat H)\psi(t) " +struct CrankNicolson <: QmNumericsScheme +end # CrankNicolson + +function schemeId(::CrankNicolson)::String + return "CrankNicolson" +end + +struct CNMatrix <: QuantumPropagator + representation::QmRepresentation + config::SchroedingerConfig + raw"(1+i*deltaT/(2\hbar) \hat H)" + A::AbstractArray{<:Complex, 2} + raw"(1-i*deltaT/(2\hbar) \hat H)" + B::AbstractArray{<:Complex, 2} + raw"The time evolution matrix (1+i/(2\hbar) \hat H)^(-1) * (1-i/(2\hbar) \hat H)" + AinvB::Union{AbstractArray{<:Complex, 2}, Nothing} +end # CNMatrix + +""" +Find the concrete matrix representation of the Hamiltonian for the selected grid +""" +function incarnate(hamiltonian::AbstractObservable, representation::QmRepresentation, + scheme::CrankNicolson, deltaT::Real, invertMatrix::Bool=false)::QuantumPropagator + cfg = qmConfig(representation) + H = asOperator(hamiltonian, representation) + hbar = cfg.hbar + A = (LinearAlgebra.I + (im*deltaT/2/hbar) * H) + B = (LinearAlgebra.I - (im*deltaT/2/hbar) * H) + AinvB = invertMatrix ? LinearAlgebra.inv(A) * B : nothing + return CNMatrix(representation, cfg, A, B, AinvB) +end # incarnate + + +function propagateSingleTimestep(psi::AbstractWaveFunction, propagator::CNMatrix)::AbstractWaveFunction + valuesOld::AbstractArray{<:Complex, 1} = values(psi, propagator.representation) + valuesNew::AbstractArray{<:Complex, 1} = isnothing(propagator.AinvB) ? propagator.A\(propagator.B * valuesOld) : propagator.AinvB * valuesOld + return asWavefunction(valuesNew, propagator.representation) +end # propagateSingleTimestep + +export CrankNicolson diff --git a/src/DifferentiationUtils.jl b/src/DifferentiationUtils.jl new file mode 100644 index 0000000..41ea596 --- /dev/null +++ b/src/DifferentiationUtils.jl @@ -0,0 +1,102 @@ +# below: different types of operators associated to V, and helpers +" +Differentiation as a matrix operator + +* 1: forward/Newton (default) +* 0: symmetric/midpoint +* -1: backward +" +function _diffOperator(gridPoints::AbstractRange{<:Real}, order::Int; + diffMethod::Int=1)::AbstractArray{<:Real, 2} + if order == 0 + return LinearAlgebra.I + end # if + # In principle we can give a formula that works for all orders, see + # https://en.wikipedia.org/wiki/Numerical_differentiation#Higher_derivatives + # It is rather tricky, however, to take into account the boundary conditions, so we do it case by case + numPoints::Int = length(gridPoints) + deltaX::Real = step(gridPoints) + if (order === 1) # the first derivative may be calculated in different ways + # FIXME use ints? + if (diffMethod === 1) + diag1 = fill(-1., numPoints) + diag1[numPoints] = 0. + M1::AbstractArray{<:Real, 2} = LinearAlgebra.Bidiagonal(diag1, ones(numPoints-1), :U) + return M1/deltaX + elseif (diffMethod === 0) + upper = fill(1., numPoints-1) + lower = fill(-1., numPoints-1) + upper[1] = 2. + lower[numPoints-1] = -2. + diag2 = fill(0., numPoints) + diag2[1] = -2. + diag2[numPoints] = 2. + M2::AbstractArray{<:Real, 2} = LinearAlgebra.Tridiagonal(lower, diag2, upper) + return M2/deltaX/2 + elseif (diffMethod === -1) + diag3 = fill(1., numPoints) + diag3[0] = 0. + M3::AbstractArray{<:Real, 2} = LinearAlgebra.Bidiagonal(-ones(numPoints), diag3, :L) + return M3/deltaX + end + elseif (order === 2) + diagonal::AbstractArray{Float64, 1} = fill(-2., numPoints) + diagonal[1] = -1. + diagonal[numPoints] = -1. + Msquared::AbstractArray{Float64, 2} = LinearAlgebra.Tridiagonal(ones(numPoints-1), diagonal, ones(numPoints-1)) + return Msquared/(deltaX^2) + end # if + squares::Int = convert(Int, floor(order / 2)) + M::AbstractArray{<:Real, 2} = _diffOperator(gridPoints, 2, diffMethod=diffMethod)^squares + return order % 2 === 0 ? M : M * _diffOperator(gridPoints, 1, diffMethod=diffMethod) +end # _diffOperator + +"Differentiation as a matrix operator", +function _diffOperator(gridPoints::AbstractArray{<:Real, 1}, order::Int; diffMethod::Int=1)::AbstractArray{<:Real, 2} + if order == 0 + return LinearAlgebra.I + end # if + # this is the case that gridPoints is not equally spaced (is not a range) + # In principle we can give a formula that works for all orders, see + # https://en.wikipedia.org/wiki/Numerical_differentiation#Higher_derivatives + # It is rather tricky, however, to take into account the boundary conditions, so we do it case by case + numPoints::Int = length(gridPoints) + if (order === 1) # the first derivative may be calculated in different ways + if (diffMethod === 1) + upper1 = map(idx -> 1/(gridPoints[idx+1] - gridPoints[idx]), 1:(numPoints-1)) + diag1 = -copy(upper1) + push!(diag1, 0.) + return LinearAlgebra.Bidiagonal(diag1, upper1, :U) + elseif (diffMethod === 0) + upper2 = map(idx -> 1/(gridPoints[idx+1] - gridPoints[idx-1]), 2:(numPoints-1)) + lower2 = -copy(upper2) + diag2 = fill(0., numPoints-2) + firstUpper::Float64 = 1/(gridPoints[2] - gridPoints[1]) + prepend!(upper2, firstUpper) + prepend!(diag2, -firstUpper) + lastLower::Float64 = 1/(gridPoints[numPoints] - gridPoints[numPoints-1]) + push!(lower2, -lastLower) + push!(diag2, lastLower) + return LinearAlgebra.Tridiagonal(lower2, diag2, upper2) + elseif (diffMethod === -1) + diag3 = map(idx -> 1/(gridPoints[idx] - gridPoints[idx-1]), 2:numPoints) + lower3 = -copy(diag3) + prepend!(diag3, 0.) + return LinearAlgebra.Bidiagonal(diag3, lower3, :L) + end + elseif (order === 2) + upperSquare = map(idx -> 1/(gridPoints[idx+1] - gridPoints[idx])/(gridPoints[idx] - gridPoints[idx-1]), 2:(numPoints-1)) + lowerSquare = copy(upperSquare) + diagSquare = -2 * copy(upperSquare) + firstUpperSquare::Real = 1/(gridPoints[2] - gridPoints[1])^2 + prepend!(upperSquare, firstUpperSquare) + prepend!(diagSquare, -firstUpperSquare) + lastLowerSquare::Real = 1/(gridPoints[numPoints] - gridPoints[numPoints-1])^2 + push!(lowerSquare, lastLowerSquare) + push!(diagSquare, -lastLowerSquare) + return LinearAlgebra.Tridiagonal(lowerSquare, diagSquare, upperSquare) + end # if + squares::Int = convert(Int, floor(order / 2)) + M::AbstractArray{<:Real, 2} = _diffOperator(gridPoints, 2, diffMethod=diffMethod)^squares + return order % 2 === 0 ? M : M * _diffOperator(gridPoints, 1, diffMethod=diffMethod) +end # _diffOperator diff --git a/src/ExactQuantumPropagation.jl b/src/ExactQuantumPropagation.jl new file mode 100644 index 0000000..387bfaa --- /dev/null +++ b/src/ExactQuantumPropagation.jl @@ -0,0 +1,31 @@ +"Get the next value of an exactly known wave function" +struct ExactPropagation <: QmNumericsScheme +end # ExactPropagation + +function schemeId(::ExactPropagation)::String + return "ExactQmPropagation" +end + +struct ExactPropagator <: QuantumPropagator + deltaT::Real +end # ExactPropagator + +function incarnate(hamiltonian::AbstractObservable, representation::QmRepresentation, + scheme::ExactPropagation, deltaT::Real)::QuantumPropagator + return ExactPropagator(deltaT) +end #specialize + +# propagate time step (qm) +function propagateSingleTimestep(psi::ExactWaveFunction, propagator::ExactPropagator)::ExactWaveFunction + return ExactWaveFunction(psi.f, psi.timestamp + propagator.deltaT) +end # propagateSingleTimestep + +function propagateSingleTimestep(psi::ExactSampledWaveFunction, propagator::ExactPropagator)::ExactSampledWaveFunction + return ExactSampledWaveFunction(psi.psi0, psi.f, psi.timestamp + propagator.deltaT) +end # propagateSingleTimestep + +function propagateSingleTimestep(psi::TranslatedExactWaveFunction, propagator::ExactPropagator)::TranslatedExactWaveFunction + return TranslatedExactWaveFunction(psi.trajectory, propagateSingleTimestep(psi.psi, propagator), psi.hbar) +end # propagateSingleTimestep + +export ExactPropagation diff --git a/src/ExactTrajectory.jl b/src/ExactTrajectory.jl new file mode 100644 index 0000000..0bf1d0d --- /dev/null +++ b/src/ExactTrajectory.jl @@ -0,0 +1,41 @@ +struct ExactTrajectory <: ClassicalNumericsScheme + # A function Real -> Point (time -> phase space) + f::Any +end # struct + +function schemeId(scheme::ExactTrajectory)::String + return "ExactTrajectory" +end + +struct ExactTrajectoryPropagator <: ClassicalPropagator + scheme::ExactTrajectory + deltaT::Real +end # ExactTrajectoryPropagator + +function incarnate(hamiltonian::AbstractObservable, + scheme::ExactTrajectory, deltaT::Real)::ExactTrajectoryPropagator + return ExactTrajectoryPropagator(scheme, deltaT) +end #specialize + +struct TimedPoint <: AbstractPoint + q::Real + p::Real + t::Real +end # TimedPoint + +function pin(point::TimedPoint)::Point + return Point(point.q, point.p) +end # pin + +# propagate time step (classical) +function propagateSingleTimestep(point::AbstractPoint, propagator::ExactTrajectoryPropagator)::TimedPoint + if !(point isa TimedPoint) + p = pin(point) + point = TimedPoint(p.q, p.p, 0.) + end # if + newT::Real = point.t + propagator.deltaT + newPoint::Point = propagator.scheme.f(newT) + return TimedPoint(newPoint.q, newPoint.p, newT) +end # propagateSingleTimestep + +export ExactTrajectory diff --git a/src/ExactWaveFunction.jl b/src/ExactWaveFunction.jl new file mode 100644 index 0000000..df2d4f0 --- /dev/null +++ b/src/ExactWaveFunction.jl @@ -0,0 +1,113 @@ +""" +This is used to model a wave function whose dependence on time t and space x +is known in an analytical form, given by the function f(t, x). +""" +struct ExactWaveFunction <: AbstractWaveFunction + "A function of two arguments, t and x (both Real), with Complex values" + f::Any + timestamp::Real + function ExactWaveFunction(f::Any, timestamp::Union{Nothing, Real}=nothing) + if isnothing(timestamp) + timestamp = 0. + end # if + return new(f, timestamp) + end # constructor +end # ExactWaveFunction + +function Base.:values(psi::ExactWaveFunction, representation::PositionRepresentation)::AbstractArray{<:Complex, 1} + t::Real = psi.timestamp + f::Any = psi.f + return map(x -> f(t, x), representation.points) +end # values + +function weylTranslate(psi::ExactWaveFunction, point0::AbstractPoint, hbar::Real)::ExactWaveFunction + point::Point = pin(point0) + if point.q == 0 && point.p == 0 + return psi + end # if + f = psi.f + newFunc = (t::Real, x::Real) -> exp(-im/hbar*point.p * (x+point.q/2)) * f(t, x + point.q) + return ExactWaveFunction(newFunc, psi.timestamp) +end # weylTranslate + +Base.:*(c::Number, psi::ExactWaveFunction) = ExactWaveFunction((t,x) -> c * psi.f(t, x), psi.timestamp) +# Here we need to pin the exact method invocation we want, +# there seems to be some ambiguity with another implementation in Base +Base.:*(psi::ExactWaveFunction, c::Number) = Core.invoke(Base.:*, Tuple{Number, ExactWaveFunction}, c, psi) +Base.:-(psi::ExactWaveFunction) = Core.invoke(Base.:*, Tuple{Number, ExactWaveFunction}, -1, psi) +function Base.:+(psi1::ExactWaveFunction, psi2::ExactWaveFunction) + if psi1.timestamp != psi2.timestamp + throw(ErrorException("Cannot add wave functions at different timesteps")) + end #if + return ExactWaveFunction((t,x) -> psi1.f(t, x) + psi2.f(t, x), psi1.timestamp) +end # Base.:+ +Base.:-(psi1::ExactWaveFunction, psi2::ExactWaveFunction) = psi1 + (-psi2) + +"TODO document what exactly this is good for" +struct ExactSampledWaveFunction <: AbstractWaveFunction + psi0::AbstractArray{<:AbstractWaveFunction, 1} + "Function of one argument t (Float64)" + f::AbstractArray{<:Any, 1} + length::Int + timestamp::Real + function ExactSampledWaveFunction(psi0::AbstractWaveFunction, f::Any, timestamp::Union{Nothing, Real}=nothing) + if isnothing(timestamp) + timestamp = 0. + end # if + return new([psi0], [f], 1, timestamp) + end # constructor + function ExactSampledWaveFunction(psi0::AbstractArray{<:AbstractWaveFunction, 1}, + f::AbstractArray{<:Any, 1}, timestamp::Union{Nothing, Real}=nothing) + if isnothing(timestamp) + timestamp = 0. + end # if + if length(psi0) !== length(f) + throw(ErrorException("Invalid arguments: length of psi0 must equal length(f), got " * string(length(psi0)) * " - " * string(length(f)))) + end + return new(psi0, f, length(psi0), timestamp) + end # constructor +end # ExactWaveFunction + +function Base.:values(psi::ExactSampledWaveFunction, representation::QmRepresentation)::AbstractArray{ComplexF64, 1} + return sum(idx -> psi.f[idx](psi.timestamp) * values(psi.psi0[idx], representation), 1:psi.length) +end # values + +Base.:*(c::Number, psi::ExactSampledWaveFunction) = ExactSampledWaveFunction(psi.psi0, map(f -> (t -> c * f(t)), psi.f), psi.timestamp) +Base.:*(psi::ExactSampledWaveFunction, c::Number) = Core.invoke(Base.:*, Tuple{Number, ExactSampledWaveFunction}, c, psi) +Base.:-(psi::ExactSampledWaveFunction) = Core.invoke(Base.:*, Tuple{Number, ExactSampledWaveFunction}, -1, psi) +function Base.:+(psi1::ExactSampledWaveFunction, psi2::ExactSampledWaveFunction) + if psi1.timestamp != psi2.timestamp + throw(ErrorException("Cannot add wave functions at different timesteps")) + end #if + return ExactSampledWaveFunction([psi1.psi0; psi2.psi0], [psi1.f; psi2.f], psi1.timestamp) +end # Base.:+ +Base.:-(psi1::ExactSampledWaveFunction, psi2::ExactSampledWaveFunction) = psi1 + (-psi2) + +function weylTranslate(psi::ExactSampledWaveFunction, point0::AbstractPoint, hbar::Real)::ExactSampledWaveFunction + point::Point = pin(point0) + if point.q == 0 && point.p == 0 + return psi + end # if + return ExactSampledWaveFunction(map(phi -> weylTranslate(phi, point0, hbar), psi.psi0), psi.f, psi.timestamp) +end # weylTranslate + +struct TranslatedExactWaveFunction <: AbstractWaveFunction + trajectory::ExactTrajectory + psi::ExactSampledWaveFunction + hbar::Real +end + +function Base.:values(psi::TranslatedExactWaveFunction, representation::QmRepresentation)::AbstractArray{<:Complex, 1} + wavef::ExactSampledWaveFunction=psi.psi + t::Real = wavef.timestamp + point::Point = psi.trajectory.f(t) + hbar::Real = qmConfig(representation).hbar + return values(ExactSampledWaveFunction(map(phi -> weylTranslate(phi, point, hbar), wavef.psi0), wavef.f, t), representation) +end # values + +Base.:*(c::Number, psi::TranslatedExactWaveFunction) = TranslatedExactWaveFunction(psi.trajectory, c*psi.psi, psi.hbar) +Base.:*(psi::TranslatedExactWaveFunction, c::Number) = Core.invoke(Base.:*, Tuple{Number, TranslatedExactWaveFunction}, c, psi) +Base.:-(psi::TranslatedExactWaveFunction) = Core.invoke(Base.:*, Tuple{Number, TranslatedExactWaveFunction}, -1, psi) + +export ExactWaveFunction, ExactSampledWaveFunction, TranslatedExactWaveFunction + diff --git a/src/ForwardEulerQm.jl b/src/ForwardEulerQm.jl new file mode 100644 index 0000000..de63bc2 --- /dev/null +++ b/src/ForwardEulerQm.jl @@ -0,0 +1,31 @@ +"Implements the naive Euler integration scheme for the time-dependent Schrödinger equation. +Note that this integration scheme is not stable and leads to extremely unreliable results. +For testing only, do not use." +struct ForwardEulerQm <: QmNumericsScheme +end # ForwardEulerQm + +function schemeId(scheme::ForwardEulerQm)::String + return "ForwardEulerQm" +end + +struct HamiltonianMatrix <: QuantumPropagator + scheme::ForwardEulerQm + config::SchroedingerConfig + representation::QmRepresentation + propagationMatrix::Operator +end # struct + +"Find the concrete matrix representation of the Hamiltonian for the selected grid" +function incarnate(hamiltonian::AbstractObservable, representation::QmRepresentation, + scheme::ForwardEulerQm, deltaT::Real)::QuantumPropagator + config = qmConfig(representation) + propagator::AbstractArray{<:Complex, 2} = + LinearAlgebra.I - (im/config.hbar) * deltaT * asOperator(hamiltonian, representation) + return HamiltonianMatrix(scheme, config, representation, propagator) +end # specialize + +function propagateSingleTimestep(psi::AbstractWaveFunction, propagator::HamiltonianMatrix)::AbstractWaveFunction + return asWavefunction(propagator.propagationMatrix * values(psi, propagator.representation), propagator.representation) +end # propagateSingleTimestep + +export ForwardEulerQm diff --git a/src/IoSystemUtils.jl b/src/IoSystemUtils.jl new file mode 100644 index 0000000..1745fcc --- /dev/null +++ b/src/IoSystemUtils.jl @@ -0,0 +1,144 @@ +# TODO need to write more scheme parameters? +function _writeCommon(system::Union{ClassicalSystem, AbstractQmSystem}, + file::IO; points::Union{AbstractArray{<:Real, 1}, Nothing}=nothing, + indent::Int=4) + indentation = repeat(" ", indent) + write(file, "{\n") + type = system isa QmSystemResidual ? "qmResidual" : + system isa AbstractQmSystem ? "qm" : "classical" + write(file, indentation, "\"type\": \"$(type)\",\n") + write(file, indentation, "\"scheme\": $(_schemeToJson(scheme(system))),") + _writePotentialJson(file, projectX(hamiltonian(system)), + points=points, indent=indent) + mass::Real = 1/2/hamiltonian(system)(Point(0, 1)) + write(file, ",\n", indentation, "\"mass\": $(mass),\n") + write(file, indentation, "\"deltaT\": $(deltaT(system)),\n") + if hasproperty(system, :currentTime) + write(file, indentation, "\"t\": $(system.currentTime),\n") + end +end # _writeCommon + +"points may only be nothing for polynomial potentials or sampled x functions" +function store(system::ClassicalSystem, file::IO; + points::Union{AbstractArray{<:Real, 1}, Nothing}=nothing, indent::Int=4) + indentation = repeat(" ", indent) + _writeCommon(system, file, points=points, indent=indent) + p::Point = pin(system.currentState) + write(file, indentation, "\"point\": [$(p.q),$(p.p)]\n") + write(file, "}") +end + +function store(system::AbstractQmSystem, file::IO; + points::Union{AbstractArray{<:Real, 1}, Nothing}=nothing, indent::Int=4) + indentation = repeat(" ", indent) + rep = representation(system) + if isnothing(points) + points = rep isa PositionRepresentation ? rep.points : nothing + end + _writeCommon(system, file, points=points, indent=indent) + write(file, indentation, "\"config\": ", _configToJson(system.config),",\n") + write(file, indentation, "\"representation\": ") + _writeRepresentationJson(rep, file) + write(file, ",\n", indentation, "\"psi\": ") + _writeWaveFunctionJson(getPsi(system), rep, file, indent=indent) + if hasproperty(system, :doNormalize) + write(file, ",\n") + write(file, indentation, "\"doNormalize\": $(system.doNormalize)\n") + else + write(file, "\n") + end + write(file, "}") +end + + +function store(system::QmSystemResidual, file::IO; + points::Union{AbstractArray{<:Real, 1}, Nothing}=nothing, indent::Int=4) + indentation = repeat(" ", indent) + rep::QmRepresentation = system.propagator.representation + if isnothing(points) + points = rep isa PositionRepresentation ? rep.points : nothing + end + _writeCommon(system, file, points=points, indent=indent) + write(file, indentation, "\"config\": ", _configToJson(system.config),",\n") + write(file, indentation, "\"representation\": ") + _writeRepresentationJson(rep, file) + if !isnothing(system.psiRepresentation) + write(file, ",\n", indentation, "\"psiRepresentation\": ") + _writeRepresentationJson(system.psiRepresentation, file) + end # if + state::CombinedState = system.currentState + write(file, ",\n", indentation, "\"t\": $(state.t),\n") + p::Point = pin(state.point) + write(file, indentation, "\"point\": [$(p.q),$(p.p)],\n") + if !isnothing(state.cDot) + write(file, indentation, "\"cDot\": [$(state.cDot.q),$(state.cDot.p)],\n") + end # if + write(file, indentation, "\"Phi\": ") + _writeWaveFunctionJson(state.Phi, rep, file, indent=indent) + write(file, ",") + _writePotentialJson(file, state.V, points=points, indent=indent, id="V_t") + write(file, "\n}") +end + +function store(system::Union{ClassicalSystem, AbstractQmSystem}, file::String; + points::Union{AbstractArray{<:Real, 1}, Nothing}=nothing, indent::Int=4) + Base.Filesystem.mkpath(Base.Filesystem.dirname(file)) + open(file, "w") do systemFile + store(system, systemFile, points=points, indent=indent) + end # systemFile +end + +function loadSystem(file::IO)::Union{ClassicalSystem, AbstractQmSystem} + dict::Dict{String, Any} = JSON.parse(file) + type::String = dict["type"] + schemeDict::Dict{String, Any} = dict["scheme"] + schemeId = Symbol(schemeDict["id"]) + mass::Real = dict["mass"] + local V::AbstractXFunction + if haskey(dict, "V_coefficients") + coeff::AbstractArray{Float64, 1} = convert(AbstractArray{Float64, 1}, dict["V_coefficients"]) + V = XPolynomial(coeff) + else + values::AbstractArray{Float64, 1} = convert(AbstractArray{Float64, 1}, dict["V"]) + points::AbstractArray{Float64, 1} = convert(AbstractArray{Float64, 1}, dict["points"]) + V = SampledXFunction(points, values) + end #if + hamiltonian = PMonomial(2)/(2*mass) + V + deltaT = dict["deltaT"] + config::Union{Nothing, SchroedingerConfig} = haskey(dict, "config") ? _configFromJson(dict["config"]) : nothing + scheme::NumericsScheme = loadScheme(NumericsSchemeId{schemeId}(), schemeDict) + t0::Real = dict["t"] + if type == "classical" + # lists parsed by JSON are of type Any + point0::AbstractArray{Any, 1} = dict["point"] + point::Point = Point(Real(point0[1]), Real(point0[2])) + system = ClassicalSystem(point, hamiltonian, deltaT, scheme=scheme, t0=t0) + return system + elseif type == "qm" + rep::QmRepresentation = _parseRepresentationJson(dict["representation"], config) + psi0::AbstractWaveFunction = _parseWavefunctionJson(dict["psi"], rep) + doNormalize::Bool = haskey(dict, "doNormalize") && dict["doNormalize"] + system = QmSystem(psi0, hamiltonian, rep, deltaT, scheme=scheme, t0=t0, doNormalize=doNormalize) + return system + elseif type == "qmResidual" + rep2::QmRepresentation = _parseRepresentationJson(dict["representation"], config) + Phi::AbstractWaveFunction = _parseWavefunctionJson(dict["Phi"], rep2) + point2::AbstractArray{Any, 1} = dict["point"] + startingPoint::Point = Point(Real(point2[1]), Real(point2[2])) + psiRepresentation::Union{Nothing, QmRepresentation} = + haskey(dict, "psiRepresentation") ? _parseRepresentationJson(dict["psiRepresentation"], config) : nothing + system = QmSystemResidual(startingPoint, Phi, hamiltonian, rep2, deltaT, + scheme=scheme, psiRepresentation=psiRepresentation, t0=t0) + return system + else + throw(error("Unsupported system type $(type)")) + end +end + +function loadSystem(file::String)::Union{ClassicalSystem, AbstractQmSystem} + open(file, "r") do systemFile + return loadSystem(systemFile) + end # systemFile +end # loadSystem + +export loadSystem, store diff --git a/src/IoUtils.jl b/src/IoUtils.jl new file mode 100644 index 0000000..b061f2e --- /dev/null +++ b/src/IoUtils.jl @@ -0,0 +1,290 @@ +function _schemeToJson(scheme::NumericsScheme)::String + return "{\"id\": \"$(schemeId(scheme))\" $(_serializeScheme(scheme))}" +end + +function _serializeScheme(::NumericsScheme)::String + return "" +end + +function _serializeScheme(scheme::SymplecticEuler)::String + return ", \"mass\": $(scheme.mass), \"deltaX\": $(scheme.deltaX)" +end +function _serializeScheme(scheme::ResidualCrankNicolson)::String + return ", \"isTrajectoryHamiltonian\": $(scheme.isTrajectoryHamiltonian), " * + "\"classicalScheme\": $(_schemeToJson(scheme.classicalScheme))" +end + +struct NumericsSchemeId{T} end + +function loadScheme(::NumericsSchemeId{:SymplecticEuler}, dict::Dict{String, Any}) + return SymplecticEuler(mass=dict["mass"], deltaX=dict["deltaX"]) +end + +function loadScheme(::NumericsSchemeId{:CrankNicolson}, dict::Dict{String, Any}) + return CrankNicolson() +end + +# With the current conventions this is not possible since we cannot +# serialize/deserialize arbitrary Julia functions... +#function loadScheme(::NumericsSchemeId{:ExactTrajectory}, dict::Dict{String, Any}) +# return ExactTrajectory(func=...) +#end + +function loadScheme(::NumericsSchemeId{:ResidualCrankNicolson}, dict::Dict{String, Any}) + isTrajectoryHamiltonian::Bool=dict["isTrajectoryHamiltonian"] + classicalDict::Dict{String, Any} = dict["classicalScheme"] + classicalScheme::ClassicalNumericsScheme = loadScheme(NumericsSchemeId{Symbol(classicalDict["id"])}(), classicalDict) + return ResidualCrankNicolson(isTrajectoryHamiltonian=isTrajectoryHamiltonian, + classicalScheme=classicalScheme) +end + +"points may only be nothing for polynomial potentials or sampled x functions" +function _writePotentialJson(file::IO, V::Union{AbstractXFunction, Operator}; + points::Union{AbstractArray{<:Real, 1}, Nothing}=nothing, + indent::Int=4, id::String="V", startWithComma::Bool=false) + indentation = repeat(" ", indent) + writeCoefficients::Bool = V isa XPolynomial + if writeCoefficients + valuesCoefficients::String = join(V.coefficients, ",") + if startWithComma + write(file, ",") + end + write(file, "\n", indentation, "\"", id, "_coefficients\": [$(valuesCoefficients)]") + end #if + local V_Values::AbstractArray{<:Real, 1} + if isnothing(points) + if V isa SampledXFunction + V_Values = V.values + points = V.points + else + #throw(ErrorException("Must specify points to store non-polynomial potential")) + return + end # if + else + if V isa LinearAlgebra.Diagonal + V_Values = V.diag + elseif V isa LinearAlgebra.UniformScaling + V_Values = fill(V.λ, length(points)) + elseif V isa AbstractArray{<:Real, 2} + V_Values = [V[idx, idx] for idx in 1:length(points)] + else + V_Values = map(x -> V(x), points) + end # if + end # if + if writeCoefficients || startWithComma + write(file, ",") + end # if + valuesString::String = join(V_Values, ",") + write(file, "\n", indentation, "\"", id,"\": [$(valuesString)],\n") + pointsString::String = join(points, ",") + write(file, indentation, "\"points\": [$(pointsString)]") +end + +function _loadPotential(dict::Dict{String, Any})::AbstractXFunction + if haskey(dict, "V_coefficients") + coeff::AbstractArray{<:Real, 1} = dict["V_coefficients"] + return XPolynomial(coeff) + else + points::AbstractArray{<:Real, 1} = dict["points"] + values::AbstractArray{<:Real, 1} = dict["V"] + return SampledXFunction(points, values) + end #if +end #_loadPotential + +function _writeComplex(val::Complex, file::IO) + r::Real = real(val) + i::Real = imag(val) + if r == 0. + write(file, "0.0") + else + write(file, "$(Printf.@sprintf("%.4g", r))") + end # if + if i == 0. + write(file, " + 0.0i") + else + sgn::String = i >= 0. ? "+" : "-" + v::Real = abs(i) + write(file, " $(sgn) $(Printf.@sprintf("%.4gi", v))") + end # if +end # writeValue + +function _writePointsHeader(file::IO, points0::AbstractArray{<:Real, 1}, symbol::Union{String, Nothing} = nothing) + start::Bool = true + symbol = isnothing(symbol) ? "Psi" : symbol + for point in points0 + if !start + write(file, ",") + else + start=false + end # + write(file, "$(symbol)($(Printf.@sprintf("%.4g", point)))") + end # for point + write(file, "\n") +end # _writePointsHeader + +function _writeObservablesHeader(file::IO) + write(file, "x, x^2, p, p^2, E\n") +end # _writeObservablesHeader + +function _writePointsLine(file::IO, waveFunction::AbstractWaveFunction, representation::QmRepresentation) + start::Bool = true + # TODO normalize? + for value in values(waveFunction, representation) + if !start + write(file, ",") + else + start=false + end # + #write(file, replace("$(Printf.@sprintf("%.2f", value))", "im" => "i")) + _writeComplex(value, file) + end # for real + write(file, "\n") +end # _writePointsLine + +function _writePotentialLine(file::IO, values0::AbstractArray{<:Real, 1}) + start::Bool = true + # TODO normalize? + for value in values0 + if !start + write(file, ",") + else + start=false + end # + write(file, "$(Printf.@sprintf("%.4g", value))") + end # for real + write(file, "\n") +end # _writePotentialLine + +function _writeObservablesLine(file::IO, + xVal::Real, x2Val::Real, pVal::Real, p2Val::Real, energy::Real) + write(file, "$(xVal), $(x2Val), $(pVal), $(p2Val), $(energy)\n") +end # _writeObservablesLine + +"write csv file" +function writeWavefunction(psi::AbstractWaveFunction, rep::QmRepresentation; + fileOrFolder::String="results", hamiltonian::Union{AbstractObservable, Nothing}=nothing) + local points::AbstractArray{<:Real, 1} + local delX::Real + if rep isa PositionRepresentation + points = rep.points + delX = deltaX(rep) + else + points = 1:length(values(psi, rep)) + delX = 1. + end # if + isFile::Bool = endswith(lowercase(fileOrFolder), ".csv") + psiFile::String = isFile ? fileOrFolder : fileOrFolder * "/psi.csv" + open(psiFile, "w") do file + _writePointsHeader(points, file) + _writePointsLine(psi, rep, file) + end # open + if isFile + return + end # if + open(fileOrFolder * "/settings.json", "w") do file + indent::String = " " + write(file, "{\n") + write(file, indent, "\"type\": \"quantum\",\n") + write(file, indent, "\"hbar\": $(config.hbar),\n") + write(file, indent, "\"deltaX\": $(delX)\n") + write(file, "}\n") + end # open + open(fileOrFolder * "/observables.csv", "w") do file + write(file, "x, x^2, p, p^2") + if !isnothing(hamiltonian) + write(file, ", E") + end # if + xVal::Real = expectationValue(psi, XPolynomial([0., 1.]), rep) + x2Val::Real = expectationValue(psi, XPolynomial([0., 0., 1.]), rep) + pVal::Real = expectationValue(psi, PMonomial(1), rep) + p2Val::Real = expectationValue(psi, PMonomial(2), rep) + write(file, "\n$(xVal), $(x2Val), $(pVal), $(p2Val)") + if !isnothing(hamiltonian) + energy::Real = expectationValue(psi, hamiltonian, rep) + write(file, ", $(energy)") + end # if + write(file, "\n") + end # open +end # writeWavefunction + +"write csv file" +function _writeWaveFunctionJson(psi::AbstractWaveFunction, rep::QmRepresentation, + file::IO; indent::Int=4) + indentation = repeat(" ", 2*indent) + local points::AbstractArray{<:Real, 1} + local vals::AbstractArray{<:Complex, 1} + if psi isa PointsWaveFunction + points = psi.points + vals = psi.values + else + vals = values(psi, rep) + points = rep.points # XXX + end # if + pointsStr = join(points, ",") + valuesRealStr = join(map(v->real(v), vals), ",") + valuesImgStr = join(map(v->imag(v), vals), ",") + # TODO information about the representation? + write(file, "{\n", indentation, "\"points\": [$(pointsStr)],\n", + indentation, "\"real\": [$(valuesRealStr)],\n", indentation, + "\"imaginary\": [$(valuesImgStr)]\n", repeat(" ", indent), "}") +end # writeWavefunction + +function _configToJson(config::SchroedingerConfig)::String + return "{\"hbar\": $(config.hbar), \"includeIntegralFactor\": $(config.includeIntegralFactor), " * + "\"firstDerivativeMethod\": $(config.firstDerivativeMethod), \"limitDiffOrder\":$(config.limitDiffOrder)}" +end # _configToJson + +function _configFromJson(config::Dict{String, Any})::SchroedingerConfig + return SchroedingerConfig(hbar=config["hbar"], includeIntegralFactor=config["includeIntegralFactor"], + firstDerivativeMethod=config["firstDerivativeMethod"], limitDiffOrder=config["limitDiffOrder"]) +end # _configFromJson + +function _writeRepresentationJson(rep::PositionRepresentation, file::IO) + write(file, "{\"type\": \"PositionRepresentation\", \"points\": ") + points = rep.points + if points isa AbstractRange + write(file, "{\"first\": $(first(points)), \"step\": $(step(points)), \"last\": $(last(points))}") + else + write(file, "[", join(points, ","), "]") + end + write(file, "}") +end + +struct RepresentationId{T} end + +# Note: the reason for using the symbol approach is that other modules can thus implement +# their own version for other types of representations +function loadRepresentationJson(::RepresentationId{:PositionRepresentation}, + rep::Dict{String, Any}, config::SchroedingerConfig)::QmRepresentation + points::Union{Dict{String, Any}, AbstractArray{Any, 1}} = rep["points"] + local pointsArr::AbstractArray{<:Real, 1} + if points isa Dict + step::Real = points["step"] + first::Real = points["first"] + last::Real = points["last"] + pointsArr = first:step:last + else + # TODO allow for other number types, e.g. Float32 or Int? + pointsArr = convert(AbstractArray{Float64, 1}, points) + end # if + return PositionRepresentation(pointsArr, config) +end # _parseRepresentationJson + +function _parseRepresentationJson(rep::Dict{String, Any}, config::SchroedingerConfig)::QmRepresentation + type::String = rep["type"] + return loadRepresentationJson(RepresentationId{Symbol(type)}(), rep, config) +end # _parseRepresentationJson + +function _parseWavefunctionJson(psi::Dict{String,Any}, ::PositionRepresentation)::AbstractWaveFunction + # TODO other number types + pointsArr = convert(AbstractArray{Float64, 1}, psi["points"]) + realArr = convert(AbstractArray{Float64, 1}, psi["real"]) + imagArr = convert(AbstractArray{Float64, 1}, psi["imaginary"]) + if length(pointsArr) != length(realArr) || length(realArr) != length(imagArr) + raise(error("The base points (domain), real and imaginary values of a wave function " * + "must be arrays of the same length, got $(length(pointsArr)), $(length(realArr)), $(length(imagArr))")) + end # if + return PointsWaveFunction(pointsArr, realArr + im * imagArr) +end # _parseWavefunctionJson + +export writeWavefunction \ No newline at end of file diff --git a/src/MatrixExponential.jl b/src/MatrixExponential.jl new file mode 100644 index 0000000..476ed26 --- /dev/null +++ b/src/MatrixExponential.jl @@ -0,0 +1,60 @@ +" +Integrate the Schrödinger equation by calculating the matrix exponential. +Usage not recommended. +" +struct MatrixExponential <: QmNumericsScheme +end # MatrixExponential + +function schemeId(scheme::MatrixExponential)::String + return "MatrixExponential" +end + +struct ExponentialMatrix <: QuantumPropagator + representation::QmRepresentation + config::SchroedingerConfig + deltaT::Real + raw"-i/2\hbar times the Hamiltonian" + H::Operator +end # ExponentialMatrix + +""" +Find the concrete matrix representation of the Hamiltonian for the selected grid +""" +function incarnate(hamiltonian::AbstractObservable, representation::QmRepresentation, + scheme::MatrixExponential, deltaT::Real)::ExponentialMatrix + config = qmConfig(representation) + return ExponentialMatrix(representation, config, deltaT, + (-im/2/config.hbar * asOperator(hamiltonian, representation))) +end # specialize + +struct MemoryWaveFunction <: AbstractWaveFunction + psi0::AbstractWaveFunction + t0::Real + psi1::AbstractWaveFunction + t1::Real +end # MemoryWaveFunction + +# apply exponential matrix +# Note: for this scheme it may be advantageous to advance by larger timesteps +function propagateSingleTimestep(psi::AbstractWaveFunction, propagator::MatrixExponential)::MemoryWaveFunction + if psi isa MemoryWaveFunction + t1::Real = psi.t1 + propagator.deltaT + U::Operator = exp(propagator.H * (t1 - psi.t0)) + psi1 = asWavefunction(U * values(psi.psi0, propagator.representation), propagator.representation) + return MemoryWaveFunction(psi.psi0, psi.t0, psi1, t1) + end # if + psi1 = asWavefunction(exp(propagator.H * propagator.deltaT) * values(psi, propagator.representation), propagator.representation) + return MemoryWaveFunction(psi, 0., psi1, propagator.deltaT) +end # propagateSingleTimestep + + +function Base.:values(psi::MemoryWaveFunction, repr::QmRepresentation)::AbstractArray{<:Complex, 1} + return values(psi.psi1, repr) +end # values + +function innerProduct(psi::MemoryWaveFunction, phi::MemoryWaveFunction, repr::QmRepresentation)::Number + return innerProduct(psi.psi1, phi.psi1, repr) +end # innerProduct + +export MatrixExponential + diff --git a/src/NumericsScheme.jl b/src/NumericsScheme.jl new file mode 100644 index 0000000..a1309da --- /dev/null +++ b/src/NumericsScheme.jl @@ -0,0 +1,47 @@ +abstract type NumericsScheme +end # + +abstract type QmNumericsScheme <: NumericsScheme +end # + +# concrete representation of the time evolution operator in some integration scheme +abstract type QuantumPropagator +end # QuantumPropagator + +function incarnate(hamiltonian::AbstractObservable, representation::QmRepresentation, + scheme::QmNumericsScheme, deltaT::Real)::QuantumPropagator + throw(ErrorException("Not implemented")) +end # incarnate + + +function propagateSingleTimestep(psi::AbstractWaveFunction, + propagator::QuantumPropagator)::AbstractWaveFunction + throw(ErrorException("Not implemented")) +end # propagateSingleTimestep + +### Classical schem below ### + +abstract type ClassicalNumericsScheme <: NumericsScheme +end # + +abstract type ClassicalPropagator +end # + +function incarnate(hamiltonian::AbstractObservable, + scheme::ClassicalNumericsScheme, deltaT::Real)::ClassicalPropagator + throw(ErrorException("Not implemented")) +end # incarnate + + +function propagateSingleTimestep(p::AbstractPoint, + propagator::ClassicalPropagator)::AbstractPoint + throw(ErrorException("Not implemented")) +end # propagateSingleTimestep + +function schemeId(scheme::NumericsScheme)::String + throw(ErrorException("Not implemented")) +end + + +export QmNumericsScheme, QuantumPropagator, incarnate, propagateSingleTimestep, schemeId, + ClassicalNumericsScheme, ClassicalPropagator diff --git a/src/PhaseSpace.jl b/src/PhaseSpace.jl new file mode 100644 index 0000000..ee9ea7e --- /dev/null +++ b/src/PhaseSpace.jl @@ -0,0 +1,54 @@ +##### abstract types and functions ######## + +"A point in phase space (x,p)" +abstract type AbstractPoint +end # AbstractPoint + +struct Point <: AbstractPoint + q::Real + p::Real +end # Point + +function pin(p::AbstractPoint)::Point + throw(ErrorException("Not implemented")) +end # pin + +function pin(p::Point)::Point + return p +end # pin + +Base.:convert(::Type{A}, point::Point) where {T<:Real, A<:AbstractArray{T, 1}} = convert(A, [convert(T, point.q), convert(T, point.p)]) +Base.:convert(type::Type{A}, point::AbstractPoint) where {T<:Real, A<:AbstractArray{T, 1}} = convert(type, pin(point)) +Base.:length(::AbstractPoint)::Integer = 2 +# https://itnext.io/generators-and-iterators-in-julia-and-python-6c9ace18fa93 +function Base.:iterate(point::Point, coords=[:q, :p]) + if isempty(coords) + return nothing + else + return getfield(point, coords[1]), coords[2:end] + end +end +Base.:iterate(point::AbstractPoint, coords=[:q, :p]) = Base.:iterate(pin(point), coords) + +Base.:*(scalar::Real, point::Point) = Point(scalar * point.q, scalar * point.p) +Base.:+(point1::Point, point2::Point) = Point(point1.q + point2.q, point1.p + point2.p) +Base.:-(point1::Point, point2::Point) = Point(point1.q - point2.q, point1.p - point2.p) +struct SumPoint <: AbstractPoint + points::AbstractArray{<:AbstractPoint, 1} +end # SumPoint +struct ScaledPoint <: AbstractPoint + scalar::Real + point::AbstractPoint +end # SumPoint +pin(point::SumPoint) = sum(p -> pin(p), point.points) +pin(point::ScaledPoint) = point.scalar * pin(point.point) +Base.:*(scalar::Real, point::AbstractPoint) = ScaledPoint(scalar, point) +Base.:*(point::AbstractPoint, scalar::Real) = Base.:*(scalar, point) +Base.:-(point::AbstractPoint) = -1 * point +Base.:/(point::AbstractPoint, scalar::Real) = Base.:*(1/scalar, point) +Base.:+(point1::AbstractPoint, point2::AbstractPoint) = SumPoint([point1, point2]) +Base.:-(point1::AbstractPoint, point2::AbstractPoint) = SumPoint([point1, -point2]) + +###### export #### + +export Point, AbstractPoint, pin diff --git a/src/PhaseSpaceFunctions.jl b/src/PhaseSpaceFunctions.jl new file mode 100644 index 0000000..bd0aa76 --- /dev/null +++ b/src/PhaseSpaceFunctions.jl @@ -0,0 +1,611 @@ +# This file contains definitions of phase space concepts, such as +# AbstractObservable, and useful implementations + +##### abstract types and functions ######## + +"A function on phase space, i.e. a real function of two variables x and p." +abstract type AbstractObservable +end # AbstractObservable + +" +A function on configuration space, e.g. the potential V(x) appearing in the Hamiltonian. +May be evaluated on two variables (x,p) like AbstractObservable, or on a single variable (x) +" +abstract type AbstractXFunction <: AbstractObservable +end # AbstractXFunction + +"A function of the momentum only. Requires two arguments (x,p) nevertheless" +abstract type AbstractPFunction <: AbstractObservable +end # AbstractXFunction + +function (f::AbstractObservable)(point::Point)::Real + return f(point.q, point.p) +end # function + +function (f::AbstractObservable)(point::AbstractPoint)::Real + return f(pin(point)) +end # function + +"calculate higher order derivatives, up to order limitOrder" +function differentiateX(f::AbstractObservable; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + throw(ErrorException("not implemented")) +end #differentiateX + +"first derivative w.r.t. p" +function differentiateP1(f::AbstractObservable)::AbstractObservable + throw(ErrorException("not implemented")) +end # differentiateP1 + +##### concrete types and implementations below #### + +"Create a polynomial function of x; internal helper method" +function _coefficientsToFunction(coeff::AbstractArray{<:Real, 1})::Any + if isempty(coeff) + return (x::Real, p::Union{Real, Nothing} = nothing) -> 0 + end + function result(x::Real, p::Union{Real, Nothing} = nothing)::Real + return sum(k -> coeff[k] * x^(k-1) / factorial(k-1), 1:length(coeff)) + end # result + return result +end # potential + +struct XFunction <: AbstractXFunction + "a function f: (Real, Real) -> Real, (x, p) |-> f(x,p) on phase space that only depends on x. + The p argument must be optional, i.e. the function must also accept a single argument x." + func::Any + "Optional function of three arguments, (diffOrder::Int, x::Real, p::Union{Real, Nothing}=nothing) -> Real" + derivatives::Union{Nothing, Any} + function XFunction(func::Any, derivatives::Union{Nothing, Any}=nothing) + if !(func isa Function) + throw(ErrorException(string("Argument passed is not a function ", func))) + end # if + return new(func, derivatives) + end # constructor +end + +struct XPolynomial <: AbstractXFunction + # Note: the convention for the polynomial coefficients implies that the derivative is equivalent to dropping the first entry + "Coefficients [V_0, V_1, ... ] of the polynomial: V(x) = V_0 + V_1 * x + 1/2 V_2 x^2 + ... + 1/k! V_k x^k" + coefficients::AbstractArray{<:Real, 1} + "A function Real -> Real" + func::Any + function XPolynomial(coefficients::AbstractArray{<:Real, 1}) + return new(coefficients, _coefficientsToFunction(coefficients)) + end # constructor +end # XPolynomial + +struct SampledXFunction <: AbstractXFunction + points::AbstractArray{<:Real, 1} + values::AbstractArray{<:Real, 1} + function SampledXFunction(points::AbstractArray{<:Real, 1}, values::AbstractArray{<:Real, 1}) + if length(values) !== length(points) + throw(error("Length of values does not match number of grid points " + length(values) + " - " + length(points))) + end # if + return new(points, values) + end # constructor +end # SampledXFunction + +struct ConstantFunction <: AbstractXFunction + value::Real + function ConstantFunction(value::Real=0) + return new(value) + end +end + +struct XDerivative <: AbstractXFunction + baseFunction::AbstractXFunction + diffOrder::Int +end # XDerivative + +struct PMonomial <: AbstractPFunction + power::Int +end # PMonomial + +"Represents the multiplication of a function of x with a monomial in P. +In the position representation this is represented by a symmetrized operator of p and V(q)" +struct PMonomialXFunction <: AbstractObservable + P::PMonomial + V::AbstractXFunction +end + +function (f::XFunction)(x::Real, p::Union{Real, Nothing} = nothing)::Real + return f.func(x, p) +end # + +function (f::XPolynomial)(x::Real, p::Union{Real, Nothing} = nothing)::Real + return f.func(x, p) +end # + +function (f::SampledXFunction)(x::Real, p::Union{Real, Nothing} = nothing)::Real + points = f.points + values = f.values + l::Int = length(points) + startIdx = 1 + endIdx = l + endPoint = points[endIdx] + startPoint = points[startIdx] + # some special cases first + if startPoint > x # linear extrapolation + return values[1] - + (startPoint - x)/(points[2] - points[1]) * (values[2] - values[1]) + elseif startPoint == x + return values[1] + elseif endPoint < x # linear extrapolation + return values[l] + + (x - endPoint) / (points[l] - points[l-1]) * (values[l] - values[l-1]) + elseif endPoint == x + return values[l] + end + while startIdx < endIdx - 1 + centerIdx = Int(floor((endIdx + startIdx)/2)) + centerValue = points[centerIdx] + if centerValue == x + return values[centerIdx] + elseif centerValue < x + startIdx = centerIdx + startPoint = centerValue + else + endIdx = centerIdx + endPoint = centerValue + end # if + end + fraction = (x - startPoint) / (endPoint - startPoint) + value = values[startIdx] + fraction * (values[endIdx] - values[startIdx]) + return value +end # + +function (f::ConstantFunction)(::Real, p::Union{Real, Nothing} = nothing)::Real + return f.value +end + +function (f::PMonomial)(::Real, p::Real)::Real + return p^f.power +end # + +"Calculate all derivatives up to a certain order; for convenient usage with polynomials, the order need not be specified. + The returned array starts with the first derivative" +function differentiateX(V::XPolynomial; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + order::Int = length(V.coefficients) + if order == 0 + return V + elseif order == 1 # constant + return AbstractObservable[] + elseif order == 2 + return ConstantFunction(V[2]) + end + vl::Int = isnothing(limitOrder) ? order : min(limitOrder+1, order) + V0 = copy(V.coefficients) + function shift()::AbstractArray{<:Real, 1} + popfirst!(V0) # remove first element + return copy(V0) + end + # outer index: order of derivative; inner index: polynomial coefficient + V_diff_k::AbstractArray{<:AbstractObservable, 1} = map(k -> XPolynomial(shift()), 1:vl-1) + return V_diff_k +end #differentiate + +function differentiateX(f::XFunction; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + limitOrder = isnothing(limitOrder) ? 10 : limitOrder # default order + result::AbstractArray{<:AbstractObservable, 1} = AbstractXFunction[] + for order in 1:limitOrder + if !isnothing(f.derivatives) + push!(result, XFunction( + (x::Real, p::Union{Nothing, Real}=nothing) -> f.derivatives(order, x, p), + (newOrder::Int, x::Real, p::Union{Nothing, Real}=nothing) -> f.derivatives(order + newOrder, x, p) + )) + else + push!(result, XDerivative(f, order)) + end # if + end # for i + return result +end # differentiateX + +function differentiateX(P::AbstractPFunction; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + return AbstractXFunction[] +end # differentiateX + +function differentiateX(P::ConstantFunction; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + return AbstractXFunction[] +end # differentiateX + +function differentiateX(PV::PMonomialXFunction; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + derivatives::AbstractArray{<:AbstractObservable, 1} = differentiateX(PV.V, limitOrder=limitOrder) + return map(derivative -> PMonomialXFunction(PV.P, derivative), derivatives) +end # differentiateX + +function Base.:convert(::Type{XFunction}, f::XPolynomial) + derivatives = differentiateX(f) + max_order::Int = length(derivatives) + function diff(order::Int, x::Real, p::Union{Real,Nothing}=nothing)::Real + if order > max_order + return 0 + end + return derivatives[order](x, p) + end # diff + return XFunction(f.func, diff) +end # convert + +function differentiateX(f::SampledXFunction; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + limitOrder = isnothing(limitOrder) ? 10 : limitOrder # default order + result::AbstractArray{<:AbstractObservable, 1} = SampledXFunction[] + for order in 1:limitOrder + operator = _diffOperator(f.points, order, diffMethod=0) + newValues = operator * f.values + push!(result, SampledXFunction(f.points, newValues)) + end # for i + return result +end # differentiateX + +function differentiateP1(::AbstractXFunction)::AbstractXFunction + return ConstantFunction(0) +end # differentiateP1 + +function differentiateP1(f::PMonomial)::AbstractObservable + return f.power * PMonomial(f.power-1) +end # differentiateP1 + +function differentiateP1(f::PMonomialXFunction)::AbstractObservable + power::Int = f.P.power + if power == 0 + return ConstantFunction(0) + elseif power == 1 + return f.V + end + return PMonomialXFunction(differentiateP1(f.P), f.V) +end # differentiateP1 + +###### basic operations on functions and observables ############### + +# utility types, not exported +struct XSumFunction <: AbstractXFunction + functions::AbstractArray{AbstractXFunction, 1} +end # XSumFunction + +struct PSumFunction <: AbstractPFunction + functions::AbstractArray{AbstractPFunction, 1} +end # PSumFunction + +struct SumFunction <: AbstractObservable + functions::AbstractArray{AbstractObservable, 1} +end # XSumFunction + +Base.:convert(::Type{SumFunction}, f::XSumFunction) = SumFunction(f.functions) + +struct XProdFunction <: AbstractXFunction + functions::AbstractArray{AbstractXFunction, 1} +end # XProdFunction + +struct PProdFunction <: AbstractPFunction + functions::AbstractArray{AbstractPFunction, 1} +end # PProdFunction + +struct ProdFunction <: AbstractObservable + functions::AbstractArray{AbstractObservable, 1} +end # ProdFunction + +Base.:convert(::Type{ProdFunction}, f::XProdFunction) = ProdFunction(f.functions) +Base.:convert(::Type{ProdFunction}, f::PProdFunction) = ProdFunction(f.functions) + +struct ScalarXProdFunction <: AbstractXFunction + func::AbstractXFunction + scalar::Real +end # ScalarProdFunction + +struct ScalarPProdFunction <: AbstractPFunction + func::AbstractPFunction + scalar::Real +end # ScalarProdFunction + +struct ScalarProdFunction <: AbstractObservable + func::AbstractObservable + scalar::Real +end # ScalarProdFunction + +Base.:convert(::Type{ScalarProdFunction}, f::ScalarXProdFunction) = ScalarProdFunction(f.func, f.scalar) +Base.:convert(::Type{ScalarProdFunction}, f::ScalarPProdFunction) = ScalarProdFunction(f.func, f.scalar) + +struct ScalarXSumFunction <: AbstractXFunction + func::AbstractXFunction + scalar::Real +end # ScalarXSumFunction + +struct ScalarSumFunction <: AbstractObservable + func::AbstractObservable + scalar::Real +end # ScalarSumFunction + +Base.:convert(::Type{ScalarSumFunction}, f::ScalarXSumFunction) = ScalarSumFunction(f.func, f.scalar) + +function (f::Union{SumFunction, PSumFunction})(x::Real, p::Real)::Real + return sum(func -> func(x, p), f.functions) +end + +function (f::XSumFunction)(x::Real, p::Union{Real, Nothing} = nothing)::Real + return sum(func -> func(x, p), f.functions) +end + +function (f::Union{ProdFunction, PProdFunction})(x::Real, p::Real)::Real + return prod(func -> func(x, p), f.functions) +end + +function (f::XProdFunction)(x::Real, p::Union{Real, Nothing} = nothing)::Real + return prod(func -> func(x, p), f.functions) +end + +function (f::ScalarProdFunction)(x::Real, p::Real)::Real + return f.scalar * f.func(x, p) +end + +function (f::ScalarXProdFunction)(x::Real, p::Union{Real, Nothing} = nothing)::Real + return f.scalar * f.func(x, p) +end + +function (f::ScalarPProdFunction)(x::Real, p::Real)::Real + return f.scalar * f.func(x, p) +end + +function (f::ScalarSumFunction)(x::Real, p::Real)::Real + return f.scalar + f.func(x, p) +end + +function (f::ScalarXSumFunction)(x::Real, p::Union{Real, Nothing} = nothing)::Real + return f.scalar + f.func(x, p) +end + +function differentiateX(V::Union{SumFunction, XSumFunction}; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + total_num::Int = length(V.functions) + if total_num == 0 + return AbstractObservable[] + elseif total_num == 1 + return differentiateX(V.functions[1]) + end + total_ps::Int = sum(f->f isa AbstractPFunction, V.functions) + if total_ps == total_num + return AbstractObservable[] + elseif total_num - total_ps == 1 + f = V.functions[findfirst(fu->!(fu isa AbstractPFunction), V.functions)] + return differentiateX(f) + end + derivatives::AbstractArray{AbstractArray{<:AbstractObservable, 1}, 1} = map(f-> differentiateX(f, limitOrder=limitOrder), V.functions) + result::AbstractArray{<:AbstractObservable, 1} = AbstractObservable[] + for derivativeArr in derivatives + for idx in 1:length(derivativeArr) + if idx > length(result) + push!(result, derivativeArr[idx]) + else + result[idx] = result[idx] + derivativeArr[idx] + end # if + end # for idx + end # derivativeArr + return result +end # + +function differentiateX(V::Union{ProdFunction, XProdFunction}; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + if isnothing(limitOrder) + limitOrder = 10 + end # if + l = length(V.functions) + firstDerivative::AbstractObservable = + sum(idx -> differentiateX(V.functions[idx], limitOrder=1)[1] * prod(V.functions[1:l .!= idx]), 1:l) + higherOrder::AbstractArray{<:AbstractObservable, 1} = differentiateX(firstDerivative, limitOrder=limitOrder-1) + prepend!(higherOrder, firstDerivative) + return higherOrder +end # + +function differentiateX(V::ScalarProdFunction; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + return map(f -> ScalarProdFunction(f, V.scalar), differentiateX(V.func, limitOrder=limitOrder)) +end # differentiateX + +function differentiateX(V::ScalarXProdFunction; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractXFunction, 1} + return map(f -> ScalarXProdFunction(f, V.scalar), differentiateX(V.func, limitOrder=limitOrder)) +end # differentiateX + +function differentiateX(V::Union{ScalarSumFunction, ScalarXSumFunction}; limitOrder::Union{Nothing, Int} = nothing)::AbstractArray{<:AbstractObservable, 1} + return differentiateX(V.func, limitOrder=limitOrder) +end # differentiateX + +function differentiateP1(f::ScalarSumFunction)::AbstractObservable + return differentiateP1(f.func) +end # differentiateP1 + +function differentiateP1(f::Union{ScalarProdFunction, ScalarPProdFunction})::AbstractObservable + return f.scalar * differentiateP1(f.func) +end # differentiateP1 + +function differentiateP1(f::Union{ProdFunction, PProdFunction})::AbstractObservable + l = length(f.functions) + return sum(idx -> differentiateP1(f.functions[idx]) * prod(f.functions[1:l .!= idx]), 1:l) +end # differentiateP1 + +function differentiateP1(f::Union{SumFunction, PSumFunction})::AbstractObservable + numXs = sum(func -> func isa AbstractXFunction, f.functions) + numPs = length(f.functions) - numXs + if numPs == 0 + return ConstantFunction(0) + elseif numPs == 1 + pFunc = f.functions[findfirst(func -> !(func isa AbstractXFunction), f.functions)] + return differentiateP1(pFunc) + end + return sum(func -> differentiateP1(func), f.functions) +end # differentiateP1 + +function _addPolynomialCoefficients(coeff1::AbstractArray{<:Real, 1}, coeff2::AbstractArray{<:Real, 1})::AbstractArray{<:Real, 1} + l1::Int = length(coeff1) + l2::Int = length(coeff2) + if l1 === l2 + return coeff1 + coeff2 + end + diff::Int = l1 > l2 ? l1 - l2 : l2 - l1 + longer = l1 > l2 ? coeff1 : coeff2 + shorter = l1 < l2 ? coeff1 : coeff2 + shorter = cat(dims=1, shorter, zeros(diff)) + return longer + shorter +end # _addPolynomialCoefficients + +function _multiplyPolynomialCoefficients(coeff1::AbstractArray{<:Real, 1}, coeff2::AbstractArray{<:Real, 1})::AbstractArray{<:Real, 1} + l1::Int = length(coeff1) + l2::Int = length(coeff2) + mx::Int = l1 + l2 - 1 + return map(n -> sum(a -> coeff1[a] * coeff2[n-a+1] * binomial(n-1, a-1), max(1, n-l2+1):min(n, l1)), 1:mx) +end # _multiplyPolynomialCoefficients + +#### some utilities #### + +# retain only the p-dependent part of an observable (kinetic part) +# only possible for monomials in p OR x and sums thereof +function projectP(::AbstractObservable)::AbstractObservable + throw(ErrorException("Cannot project to a pure p function")) +end # projectP + +function projectX(::AbstractObservable)::AbstractXFunction + throw(ErrorException("Cannot project to a pure x function")) +end # projectP + +function projectP(::AbstractXFunction)::AbstractObservable + return ConstantFunction() +end # projectP + +function projectP(m::AbstractPFunction)::AbstractPFunction + return m +end # projectP + +function projectP(sumF::SumFunction)::AbstractObservable + return sum(f -> projectP(f), sumF.functions) +end # projectP + +function projectP(sumF::ScalarSumFunction)::AbstractObservable + return projectP(sumF.func) +end # projectP + +function projectP(prod::ScalarProdFunction)::AbstractObservable + return prod.scalar * projectP(prod.func) +end # projectP + +function projectX(f::AbstractXFunction)::AbstractXFunction + return f +end # projectP + +function projectX(::AbstractPFunction)::AbstractXFunction + return ConstantFunction() +end # projectP + +function projectX(sumF::SumFunction)::AbstractObservable + return sum(f -> projectX(f), sumF.functions) +end # projectP + +function projectX(sumF::ScalarSumFunction)::AbstractObservable + return projectX(sumF.func) +end # projectP + +function projectX(prod::ScalarProdFunction)::AbstractObservable + return prod.scalar * projectX(prod.func) +end # projectP + +####### + +"Create a Hamiltonian observable of the form p^2/2m + V(q)" +function hamiltonian(V::AbstractXFunction; mass::Real = 1)::AbstractObservable + return SumFunction([PMonomial(2) / (2 * mass), V]) +end # hamiltonian + +Base.:+(xFunc1::XPolynomial, xFunc2::XPolynomial) = XPolynomial(_addPolynomialCoefficients(xFunc1.coefficients, xFunc2.coefficients)) +Base.:+(xFunc1::AbstractXFunction, xFunc2::AbstractXFunction) = XSumFunction([xFunc1, xFunc2]) +Base.:+(xFunc1::ConstantFunction, xFunc2::AbstractXFunction) = xFunc1.value == 0 ? xFunc2 : XSumFunction([xFunc1, xFunc2]) +Base.:+(xFunc1::AbstractXFunction, xFunc2::ConstantFunction) = Base.:+(xFunc2, xFunc1) +Base.:+(xFunc1::XFunction, xFunc2::XFunction) = #=XSumFunction([xFunc1, xFunc2])=# + XFunction((x::Real, p::Union{Real, Nothing}=nothing) -> xFunc1.func(x, p) + xFunc2.func(x, p)) +Base.:+(func1::AbstractObservable, func2::AbstractObservable) = SumFunction([func1, func2]) +Base.:-(func1::AbstractObservable, func2::AbstractObservable) = func1 + (-func2) +Base.:+(xFunc1::ConstantFunction, xFunc2::AbstractObservable) = xFunc1.value == 0 ? xFunc2 : SumFunction([xFunc1, xFunc2]) +Base.:+(xFunc1::AbstractObservable, xFunc2::ConstantFunction) = Base.:+(xFunc2, xFunc1) + +function Base.:+(xFunc1::SampledXFunction, xFunc2::SampledXFunction) + if xFunc1.points == xFunc2.points + return SampledXFunction(xFunc1.points, xFunc1.values + xFunc2.values) + end + throw(error("+ not implemented for SampledXFunctions with different domains")) +end # + + +function Base.:+(xFunc1::SampledXFunction, xFunc2::AbstractXFunction) + values2 = xFunc2.(xFunc1.points) + return SampledXFunction(xFunc1.points, xFunc1.values + values2) +end # + +Base.:+(xFunc1::AbstractObservable, xFunc2::SampledXFunction)=xFunc2 + xFunc1 + +Base.:+(func1::ConstantFunction, func2::ConstantFunction) = ConstantFunction(func1.value+func2.value) +function Base.:+(func1::ConstantFunction, func2::XPolynomial) + if func1.value == 0 + return func2 + end + order = length(func2.coefficients) + if order == 0 + return func1 + elseif order == 1 + return ConstantFunction(func1.value + func2.coefficients[1]) + end + coeff = copy(func2.coefficients) + coeff[1] = coeff[1] + func1.value + return XPolynomial(coeff) +end +Base.:+(func1::XPolynomial, func2::ConstantFunction) = Base.:+(func2, func1) +Base.:+(func1::AbstractPFunction, func2::AbstractPFunction) = PSumFunction([func1, func2]) + +Base.:*(xFunc1::AbstractXFunction, xFunc2::AbstractXFunction) = XProdFunction([xFunc1, xFunc2]) +Base.:*(xFunc1::XFunction, xFunc2::XFunction) = #=XProdFunction([xFunc1, xFunc2])=# + XFunction((x::Real, p::Union{Real, Nothing}=nothing) -> xFunc1.func(x, p) * xFunc2.func(x, p)) +Base.:*(xFunc1::XPolynomial, xFunc2::XPolynomial) = XPolynomial(_multiplyPolynomialCoefficients(xFunc1.coefficients, xFunc2.coefficients)) +Base.:*(func1::PMonomial, func2::PMonomial) = PMonomial(func1.power + func2.power) +Base.:*(pFunc1::AbstractPFunction, pFunc2::AbstractPFunction) = PProdFunction([pFunc1, pFunc2]) +Base.:*(pFunc1::ScalarPProdFunction, pFunc2::ScalarPProdFunction) = ScalarPProdFunction(pFunc1.func*pFunc2.func, pFunc1.scalar*pFunc2.scalar) +Base.:*(func1::Union{SumFunction, XSumFunction, PSumFunction}, func2::Union{SumFunction, XSumFunction, PSumFunction}) = sum(f -> sum(g -> f * g, func2.functions), func1.functions) +Base.:*(func1::Union{SumFunction, XSumFunction}, func2::AbstractObservable) = sum(f -> f * func2, func1.functions) +Base.:*(func1::AbstractObservable, func2::Union{SumFunction, XSumFunction, PSumFunction}) = Base.:*(func2, func1) +Base.:*(func1::ScalarProdFunction, func2::AbstractObservable) = ScalarProdFunction(func1.func * func2, func1.scalar) +Base.:*(func1::ScalarPProdFunction, func2::AbstractPFunction) = ScalarPProdFunction(func1.func * func2, func1.scalar) +Base.:*(func1::ScalarXProdFunction, func2::AbstractXFunction) = ScalarXProdFunction(func1.func * func2, func1.scalar) +Base.:*(func1::AbstractObservable, func2::ScalarProdFunction) = Base.:*(func2, func1) +Base.:*(func1::AbstractObservable, func2::ScalarPProdFunction) = Base.:*(func2, func1) +Base.:*(func1::AbstractObservable, func2::ScalarXProdFunction) = Base.:*(func2, func1) + +# the tricky case: x*p +Base.:*(func1::PMonomial, func2::AbstractXFunction) = PMonomialXFunction(func1, func2) +Base.:*(func1::AbstractXFunction, func2::PMonomial) = PMonomialXFunction(func2, func1) +Base.:*(func1::PMonomialXFunction, func2::AbstractXFunction) = PMonomialXFunction(func1.P, func1.V * func2) +Base.:*(func1::AbstractXFunction, func2::PMonomialXFunction) = Base.:*(func2, func1) +Base.:*(func1::PMonomialXFunction, func2::PMonomial) = PMonomialXFunction(func1.P * func2, func1.V) +Base.:*(func1::PMonomial, func2::PMonomialXFunction) = Base.:*(func2, func1) +Base.:*(func1::PMonomialXFunction, func2::PMonomialXFunction) = PMonomialXFunction(func1.P * func2.P, func1.V * func2.V) +# Note that a matrix representation for a generic ProdFunction is not defined here, which is why we define all those specific multiplications above +Base.:*(func1::AbstractObservable, func2::AbstractObservable) = ProdFunction([func1, func2]) +function Base.:*(func1::ConstantFunction, func2::AbstractObservable) + if func1.value == 0 + return ConstantFunction() + end + return Base.:*(func1.value, func2) +end # * +Base.:*(func1::AbstractObservable, func2::ConstantFunction) = Base.:*(func2, func1) +Base.:*(func1::ConstantFunction, func2::ConstantFunction) = ConstantFunction(func1.value*func2.value) + +Base.:-(func::AbstractObservable) = -1 * func + +Base.:*(scalar::Real, func::AbstractObservable) = ScalarProdFunction(func, scalar) +Base.:*(scalar::Real, func::AbstractXFunction) = ScalarXProdFunction(func, scalar) +Base.:*(scalar::Real, func::AbstractPFunction) = ScalarPProdFunction(func, scalar) +Base.:*(func::AbstractObservable, scalar::Real) = Base.:*(scalar, func) +Base.:/(func::AbstractObservable, scalar::Real) = Base.:*(1/scalar, func) +Base.:*(scalar::Real, func::XFunction) = #=ScalarXProdFunction(func, scalar)=# + XFunction((x::Real, p::Union{Real, Nothing}=nothing) -> func.func(x, p) * scalar) +Base.:*(scalar::Real, func::XPolynomial) = XPolynomial(scalar * func.coefficients) +Base.:*(scalar::Real, func::SampledXFunction) = SampledXFunction(func.points, scalar*func.values) +Base.:*(scalar::Real, func::XDerivative) = XDerivative(scalar * func.baseFunction, func.diffOrder) +Base.:*(scalar::Real, func::ConstantFunction) = ConstantFunction(scalar * func.value) +Base.:*(scalar::Real, func::SumFunction) = SumFunction((f-> scalar * f, func.functions)) +Base.:*(scalar::Real, func::XSumFunction) = XSumFunction((f-> scalar * f, func.functions)) +Base.:*(scalar::Real, func::PSumFunction) = PSumFunction((f-> scalar * f, func.functions)) + +###### export #### + +export AbstractObservable, AbstractXFunction, XPolynomial, XFunction, SampledXFunction, ConstantFunction, + PMonomial, + #PMonomialXFunction, SumFunction, XSumFunction, ProdFunction, XProdFunction, XDerivative, # mainly used internally + differentiateX, differentiateP1, hamiltonian diff --git a/src/QmSystem.jl b/src/QmSystem.jl new file mode 100644 index 0000000..3ddaee0 --- /dev/null +++ b/src/QmSystem.jl @@ -0,0 +1,145 @@ +abstract type AbstractQmSystem +end + +struct QmSystem <: AbstractQmSystem + config::SchroedingerConfig + initialState::AbstractWaveFunction + hamiltonian::AbstractObservable + representation::QmRepresentation + scheme::QmNumericsScheme + propagator::QuantumPropagator + deltaT::Real + "Whether to normalize the wave function in every step. Usually not required nor recommended." + doNormalize::Bool + # state + currentTime::Real + currentState::AbstractWaveFunction + function QmSystem(psi0::AbstractWaveFunction, + hamiltonian::AbstractObservable, representation::QmRepresentation, + deltaT::Real; + scheme::QmNumericsScheme=CrankNicolson(), + doNormalize::Bool = false, t0::Real=0.) + propagator::QuantumPropagator = incarnate(hamiltonian, representation, scheme, deltaT) + return new(qmConfig(representation), psi0, hamiltonian, representation, scheme, propagator, deltaT, doNormalize, t0, psi0) + end # QmSystem + function QmSystem(other::QmSystem, t::Real, psi::AbstractWaveFunction) + return new(other.config, other.initialState, other.hamiltonian, other.representation, + other.scheme, other.propagator, other.deltaT, other.doNormalize, t, psi) + end # QmSystem +end # QmSystem + +function propagate(system::AbstractQmSystem, timeSteps::Int=1)::AbstractQmSystem + for _ in 1:timeSteps + newPsi::AbstractWaveFunction = propagateSingleTimestep(getPsi(system), system.propagator) + if system isa QmSystem && system.doNormalize + newPsi = normalize(newPsi, system.representation) + end # if + system = QmSystem(system, system.currentTime + system.deltaT, newPsi) + end # for k + return system +end # p + +function getPsi(system::QmSystem)::AbstractWaveFunction + return system.currentState +end # getPsi + +function representation(system::QmSystem)::QmRepresentation + return system.representation +end + +function hamiltonian(system::AbstractQmSystem)::AbstractObservable + return system.hamiltonian +end + +function hbar(system::AbstractQmSystem)::Real + return system.config.hbar +end + +function deltaT(system::AbstractQmSystem)::Real + return system.deltaT +end + +function scheme(system::AbstractQmSystem)::NumericsScheme + return system.scheme +end + +function _writeSettingsQm(system::AbstractQmSystem, file::IO; + points::Union{AbstractArray{<:Real, 1}, Nothing}=nothing, + parameters::Union{Dict{String, Any}, Nothing}=nothing) + indent::String = " " + write(file, "{\n") + write(file, indent, "\"type\": \"quantum\",\n") + write(file, indent, "\"hbar\": $(hbar(system)),\n") + write(file, indent, "\"deltaT\": $(deltaT(system)),\n") + write(file, indent, "\"scheme\": $(_schemeToJson(scheme(system)))") + if isnothing(points) + try + points = representation(system).points + catch + end + end + try + _writePotentialJson(file, projectX(hamiltonian(system)), + indent=length(indent), startWithComma=true, points=points) + catch + end + if !isnothing(parameters) + for (key, value) in parameters + write(file, ",\n", indent, "\"$(key)\": ") + isStr::Bool = value isa String + if isStr + write(file, "\"") + end + write(file, "$(value)") + if isStr + write(file, "\"") + end + end # for + end # if + write(file, "\n}\n") +end # _writeSettingsQm + +function trace(system::AbstractQmSystem, timeSteps::Int=1000; + folder::String = "./results", + parameters::Union{Dict{String, Any}, Nothing}=nothing) # io::IO + rep::QmRepresentation = representation(system) + if !(rep isa PositionRepresentation) + throw(ErrorException("Can only handle position representation, currently")) # XXX + end # if + Base.Filesystem.mkpath(folder) + settingsFile::String = joinpath(folder, "settings.json") + psiFile::String = joinpath(folder, "psi.csv") + observablesFile::String = joinpath(folder, "observables.csv") + points0::AbstractArray{<:Real, 1} = rep.points + x = XPolynomial([0., 1.]) + x2 = XPolynomial([0., 0., 1.]) + p = PMonomial(1) + p2 = PMonomial(2) + open(settingsFile, "w") do settingsFile1 + _writeSettingsQm(system, settingsFile1, parameters=parameters) + end # settingsFile + open(psiFile, "w") do file + open(observablesFile, "w") do fileObservables + _writePointsHeader(file, points0) + _writeObservablesHeader(fileObservables) + for _ in 1:timeSteps + psi = getPsi(system) + # write wave function values + _writePointsLine(file, psi, rep) + # write expectation values + xVal::Real = expectationValue(psi, x, rep) + x2Val::Real = expectationValue(psi, x2, rep) + pVal::Real = expectationValue(psi, p, rep) + p2Val::Real = expectationValue(psi, p2, rep) + energy::Real = expectationValue(psi, hamiltonian(system), rep) + # Note: var(X) = x2Val - xVal^2 + _writeObservablesLine(fileObservables, xVal, x2Val, pVal, p2Val, energy) + system = propagate(system, 1) + end # for k + end # open fileObservables + end # open file + return system + +end # trace + +export AbstractQmSystem, QmSystem, propagate, trace, representation, getPsi diff --git a/src/QmSystemConcat.jl b/src/QmSystemConcat.jl new file mode 100644 index 0000000..b6d815f --- /dev/null +++ b/src/QmSystemConcat.jl @@ -0,0 +1,56 @@ +struct QmSystemConcat <: AbstractQmSystem + system::AbstractQmSystem + mainRepresentation::QmRepresentation + transitions::AbstractArray{<:Function, 1} # system -> system + transitionSteps::AbstractArray{Int, 1} + currentStep::Int + function QmSystemConcat( + system::AbstractQmSystem, + mainRepresentation::QmRepresentation, + transitions::AbstractArray{<:Function, 1}, + transitionSteps::AbstractArray{Int, 1}, + currentStep::Int=0) + return new(system, mainRepresentation, transitions, transitionSteps, currentStep) + end +end # QmSystemConcat + +function propagate(system::QmSystemConcat, timeSteps::Int=1)::QmSystemConcat + for _ in 1:timeSteps + step::Int = system.currentStep+1 + local sys::AbstractQmSystem + if step in system.transitionSteps + idx::Int = findfirst((tr == step for tr in system.transitionSteps)) + sys = system.transitions[idx](system.system) + else + sys = propagate(system.system, 1) + end # if + system = QmSystemConcat(sys, system.mainRepresentation, system.transitions, system.transitionSteps, step) + end # if + return system +end # p + +function getPsi(system::QmSystemConcat) + return getPsi(system.system) +end # getPsi + +function representation(system::QmSystemConcat)::QmRepresentation + return system.mainRepresentation +end + +function hamiltonian(system::QmSystemConcat)::AbstractObservable + return hamiltonian(system.system) +end + +function hbar(system::QmSystemConcat)::Real + return hbar(system.system) +end + +function deltaT(system::QmSystemConcat)::Real + return deltaT(system.system) +end + +function scheme(system::QmSystemConcat)::NumericsScheme + return scheme(system.system) +end + +export QmSystemConcat diff --git a/src/QmSystemResidual.jl b/src/QmSystemResidual.jl new file mode 100644 index 0000000..590ab15 --- /dev/null +++ b/src/QmSystemResidual.jl @@ -0,0 +1,136 @@ +struct QmSystemResidual <: AbstractQmSystem + config::SchroedingerConfig + initialPoint::AbstractPoint + initialPhi::AbstractWaveFunction + hamiltonian::AbstractObservable + propagator::ResidualCrankNicolsonPropagator + scheme::ResidualCrankNicolson + deltaT::Real + # state + currentState::CombinedState + psiRepresentation::Union{QmRepresentation,Nothing} + classicalResolutionFactor::Int + raw"Note that the initial wave function to be passed is Phi" + function QmSystemResidual( + initialPoint::Point, initialPhi::AbstractWaveFunction, + hamiltonian::AbstractObservable, representation::QmRepresentation, + deltaT::Real; + scheme::ResidualCrankNicolson=ResidualCrankNicolson(), + psiRepresentation::Union{QmRepresentation,Nothing}=nothing, + # use a higher resolution for the classical propagation than for the quantum propagation + classicalResolutionFactor::Int=100, + t0::Real=0.) + propagator::ResidualCrankNicolsonPropagator = incarnate(hamiltonian, representation, + scheme, deltaT, initialPoint, initialPhi, t0=t0, classicalResolutionFactor=classicalResolutionFactor) + return new(qmConfig(representation), initialPoint, initialPhi, hamiltonian, + propagator, scheme, deltaT, propagator.initialState, psiRepresentation, classicalResolutionFactor) + end # QmSystem + function QmSystemResidual(other::QmSystemResidual, state::CombinedState) + return new(other.config, other.initialPoint, other.initialPhi, + other.hamiltonian, other.propagator, other.scheme, other.deltaT, state, other.psiRepresentation, + other.classicalResolutionFactor) + end # QmSystem +end # QmSystemHamiltonianGauge + +function propagate(system::QmSystemResidual, timeSteps::Int=1)::QmSystemResidual + for _ in 1:timeSteps + newState::CombinedState = propagateSingleTimestep(system.propagator, system.currentState) + system = QmSystemResidual(system, newState) + end # for k + return system +end # p + +function representation(system::QmSystemResidual)::QmRepresentation + return system.propagator.representation +end + +function getPsi(system::QmSystemResidual)::AbstractWaveFunction + return getPsi(system.currentState) +end + +function trace(system::QmSystemResidual, timeSteps::Int=1000; + folder::String = "./results") # io::IO + representation::PositionRepresentation = system.propagator.representation + if !(representation isa PositionRepresentation) + throw(ErrorException("Can only handle position space, currently")) # XXX why? + end # if + psiRepresentation = isnothing(system.psiRepresentation) ? representation : system.psiRepresentation + config::SchroedingerConfig = system.config + points0::AbstractArray{<:Real, 1} = representation.points + x = XPolynomial([0, 1]) + x2 = XPolynomial([0, 0, 1]) + p = PMonomial(1) + p2 = PMonomial(2) + mass::Real = 1/2/system.hamiltonian(Point(0, 1)) + V::Union{Nothing, AbstractObservable} = nothing + try + V = projectX(system.hamiltonian) + catch + end + Base.Filesystem.mkpath(folder) + settingsFile0 = joinpath(folder, "settings.json") + pointsFile0 = joinpath(folder, "points.csv") + psiFile0 = joinpath(folder, "psi.csv") + psiTildeFile0 = joinpath(folder, "psiTilde.csv") + observablesFile0 = joinpath(folder, "observables.csv") + observablesQmFile0 = joinpath(folder, "observablesQm.csv") + VtFile0 = joinpath(folder, "V_t.csv") + open(settingsFile0, "w") do settingsFile + _writeSettingsQm(system, settingsFile, points=psiRepresentation.points) + end # settingsFile + open(pointsFile0, "w") do filePoints + open(psiFile0, "w") do filePsi + open(psiTildeFile0, "w") do filePsiTilde + open(observablesFile0, "w") do fileObservables + open(observablesQmFile0, "w") do fileObservablesQm + open(VtFile0, "w") do filePotential + _writePointsHeader(filePsiTilde, points0) + _writePointsHeader(filePsi, psiRepresentation.points) # assume a PositionRepresentation as well + _writePointsHeader(filePotential, points0, "V") + write(fileObservables, "x, x^2, p, p^2, E\n") + write(fileObservablesQm, "x, x^2, p, p^2, E\n") + write(filePoints, "x, p, E\n") + for _ in 1:timeSteps + pnt::Point = pin(system.currentState.point) + classicalEnergy::Real = pnt.p^2 / 2 / mass + V(pnt.q) + Phi::AbstractWaveFunction = system.currentState.Phi + psi::AbstractWaveFunction = getPsi(system.currentState) + _writePointsLine(filePsiTilde, Phi, representation) + _writePointsLine(filePsi, psi, psiRepresentation) + if !isnothing(V) + _writePotentialLine(filePotential, LinearAlgebra.diag(asCircleOperator(V, pnt, representation))) + end + ## The below values would become extremely unreliable in case of high classical contributions (strong oscillations) + #xVal::Real = expectationValue(psi, x, psiRepresentation) + #x2Val::Real = expectationValue(psi, x2, psiRepresentation) + #pVal::Real = expectationValue(psi, p, psiRepresentation) + #p2Val::Real = expectationValue(psi, p2, psiRepresentation) + #energy::Real = expectationValue(psi, system.hamiltonian, psiRepresentation) + xValQm::Real = expectationValue(Phi, x, representation) + x2ValQm::Real = expectationValue(Phi, x2, representation) + pValQm::Real = expectationValue(Phi, p, representation) + p2ValQm::Real = expectationValue(Phi, p2, representation) + tildeHamiltonian::Operator = asTildeOperator(system.hamiltonian, pnt, representation) + energyQm::Real = expectationValue(Phi, tildeHamiltonian, representation) + xVal::Real = pnt.q + xValQm + x2Val::Real = pnt.q^2 + x2ValQm + pVal::Real = pnt.p + pValQm + p2Val::Real = pnt.p^2 + p2ValQm + energy::Real = energyQm + # Note: var(X) = x2Val - xVal^2 + write(fileObservablesQm, "$(xValQm), $(x2ValQm), $(pValQm), $(p2ValQm), $(energyQm)\n") + write(fileObservables, "$(xVal), $(x2Val), $(pVal), $(p2Val), $(energy)\n") + write(filePoints, "$(pnt.q), $(pnt.p), $(classicalEnergy)\n") + system = propagate(system, 1) + end # for timeSteps + end # open filePotential + end # open fileObserservablesQm + end # open fileObservables + end # filePhi + end # open filePsi + end # open filePpoints + return system + +end # trace + +export QmSystemResidual, propagate, trace diff --git a/src/QmSystemSum.jl b/src/QmSystemSum.jl new file mode 100644 index 0000000..23c275b --- /dev/null +++ b/src/QmSystemSum.jl @@ -0,0 +1,34 @@ +struct QmSystemSum <: AbstractQmSystem + systems::AbstractArray{Union{QmSystem, QmSystemResidual}, 1} +end # QmSystemConcat + +function propagate(system::QmSystemSum, timeSteps::Int=1)::QmSystemSum + return QmSystemSum([propagate(sys, timeSteps) for sys in system.systems]) +end # p + +function getPsi(system::QmSystemSum) + return sum(sys.currentState isa AbstractWaveFunction ? sys.currentState : + getPsi(sys.currentState) for sys in system.systems) +end # getPsi + +function representation(system::QmSystemSum)::QmRepresentation + return representation(system.systems[1]) +end + +function hamiltonian(system::QmSystemSum)::AbstractObservable + return hamiltonian(system.systems[1]) +end + +function hbar(system::QmSystemSum)::Real + return hbar(system.systems[1]) +end + +function deltaT(system::QmSystemSum)::Real + return deltaT(system.systems[1]) +end + +function scheme(system::QmSystemSum)::NumericsScheme + return scheme(system.systems[1]) +end + +export QmSystemSum diff --git a/src/Representation.jl b/src/Representation.jl new file mode 100644 index 0000000..ee68cfe --- /dev/null +++ b/src/Representation.jl @@ -0,0 +1,242 @@ +" +This module defines both generic QM representations and the position representation. +A representation assigns an operator to every observable (see function `asOperator`), +but also assigns a \"tilde\" operator and \"circle\" operator (functions +`asTildeOperator` and `asCircleOperator`) +" + +##### Abstract types and functions below ##### + +"A concrete representation of quantum mechanics" +abstract type QmRepresentation +end # QmRepresentation + +function qmConfig(rep::QmRepresentation)::SchroedingerConfig + throw(ErrorException("not implemented")) +end + +"An operator acting on wave functions in a concrete representation" +Operator = Union{AbstractArray{<:Number, 2}, LinearAlgebra.UniformScaling{<:Number}} + +"Create a matrix representation of the observable in a specific representation of QM" +function asOperator(V::AbstractObservable, representation::QmRepresentation)::Operator + throw(ErrorException("not implemented")) +end # asObservable + +" +The matrix representation of an observable translated by means of a Weyl operator to +some point in phase space +" +function asTildeOperator(V::AbstractObservable, point::AbstractPoint, representation::QmRepresentation)::Operator + throw(ErrorException("not implemented")) +end # asTildeObservable + +" +The circle operator, i.e. the operator appearing in the residual Schrödinger equation. +Note that we assume here that the system is \"on-shell\", i.e. the trajectory satisfies +Hamilton's equations. Otherwise the 'circle operators' would depend on the derivative of the +trajectory, so this case cannot be covered in our formalism. +" +function asCircleOperator(V::AbstractObservable, point::AbstractPoint, + representation::QmRepresentation)::Operator + throw(ErrorException("not implemented")) +end # asCircleOperator + +#### Concrete types and function implementations below ######### + +struct PositionRepresentation <: QmRepresentation + points::AbstractArray{<:Real, 1} + config::SchroedingerConfig +end # PositionRepresentation + +function qmConfig(rep::PositionRepresentation)::SchroedingerConfig + return rep.config +end + +# see DifferentiationUtils for _diffOperator +function _values(V::XDerivative, representation::PositionRepresentation)::AbstractArray{<:Real, 1} + values0::AbstractArray{<:Real, 1} = _values(V.baseFunction, representation) + return _diffOperator(representation.points, V.diffOrder, diffMethod=qmConfig(representation).firstDerivativeMethod) * values0 +end # _values + +function _values(V::AbstractXFunction, representation::PositionRepresentation)::AbstractArray{<:Real, 1} + return V.(representation.points) +end # _values + +function deltaX(rep::PositionRepresentation)::Real + pnts::AbstractArray{<:Real, 1} = rep.points + return pnts isa AbstractRange ? step(pnts) : sum(pnts[2:lPoints] - pnts[1:lPoints-1])/(lPoints - 1) +end # deltaX + +function asOperator(V::XDerivative, representation::PositionRepresentation)::AbstractArray{<:Real, 2} + return LinearAlgebra.Diagonal(_values(V, representation)) +end # asOperator + +function asOperator(V::Union{XFunction, XPolynomial}, representation::PositionRepresentation)::AbstractArray{<:Real, 2} + return LinearAlgebra.Diagonal(map(x -> V.func(x), representation.points)) +end # asOperator + +function asOperator(V::SampledXFunction, representation::PositionRepresentation)::AbstractArray{<:Real, 2} + if V.points == representation.points + return LinearAlgebra.Diagonal(V.values) + end + return LinearAlgebra.Diagonal(V.(representation.points)) +end # asOperator + +function asOperator(P::PMonomial, representation::PositionRepresentation)::Operator + config = qmConfig(representation) + M::AbstractArray{<:Real, 2} = _diffOperator(representation.points, P.power, diffMethod=config.firstDerivativeMethod) + hbar = config.hbar + if P.power % 2 === 0 + return (-1)^(convert(Int, P.power/2)) * hbar^P.power * M # this is real + else + return (-im * hbar)^P.power * M # this is imaginary + end +end # asOperator + +function asOperator(PV::PMonomialXFunction, representation::QmRepresentation)::Operator + p::Int = PV.P.power + if p === 0 + return asOperator(PV.V, representation) + end # if + # McCoy's formula, https://en.wikipedia.org/wiki/Wigner%E2%80%93Weyl_transform + return 2^(-p) * sum(k -> binomial(p, k) * asOperator(PMonomial(k), representation) * asOperator(PV.V, representation) + * asOperator(PMonomial(p-k), representation), 0:p) +end # asOperator + +function asTildeOperator(V::AbstractXFunction, point::AbstractPoint, representation::PositionRepresentation)::Operator + q::Real = pin(point).q + shiftedRepresentation = PositionRepresentation(map(x -> x+q, representation.points), representation.config) + return LinearAlgebra.Diagonal(_values(V, shiftedRepresentation)) +end # asTildeOperator + +function asTildeOperator(P::PMonomial, point::AbstractPoint, representation::PositionRepresentation)::Operator + d::Int = P.power + p::Real = pin(point).p + return p^d * LinearAlgebra.I + sum(k -> binomial(d, k) * p^(d-k) * asOperator(PMonomial(k), representation), 1:d) +end # asTildeOperator + +# TODO same for asTildeOperator for generic representations? +function _circleOperatorViaDerivatives( + V::AbstractXFunction, point::AbstractPoint, representation::QmRepresentation)::AbstractArray{<:Real, 2} + config::SchroedingerConfig=qmConfig(representation) + derivatives::AbstractArray{AbstractXFunction, 1} = differentiateX(V, limitOrder=config.limitDiffOrder) + newCoefficients::AbstractArray{<:Real, 1} = map(k -> k(pin(point).q), derivatives) + empty::Bool = isempty(newCoefficients) + q = pin(point).q + if !empty + newCoefficients[1] = 0. # remove first derivative term + zerothOrder::Real = config.includeIntegralFactor ? 0. : V(q) - q * derivatives[1](q) / 2 + pushfirst!(newCoefficients, zerothOrder) + end # if + polynomial::XPolynomial = XPolynomial(newCoefficients) + return asOperator(polynomial, representation) +end # _circleOperatorViaDerivatives + +function asCircleOperator(V::XPolynomial, point::AbstractPoint, representation::PositionRepresentation)::AbstractArray{<:Real, 2} + return _circleOperatorViaDerivatives(V, point, representation) +end # asCircleOperator + +# for a general representation; position representation below +# This is in general not exact, since we cannot calculate the infinite series of derivatives. +function asCircleOperator(V::AbstractXFunction, point::AbstractPoint, representation::QmRepresentation)::AbstractArray{<:Real, 2} + return _circleOperatorViaDerivatives(V, point, representation) +end # asCircleOperator + +raw""" +Represent a generic potential (not a polynomial) as an operator on \Phi as + \circ V\cdot \Phi(t,x) = [ V(q(t) + x) - V'(q(t)) * (x + 1/2 q(t)) ]\Phi(t, x) +if config.includeIntegralFactor is false, or + \circ V\cdot \Phi(t,x) = [ V(q(t) + x) - V(q) - V'(q(t)) * x ]\Phi(t, x) +if it is true. +Note that this way we do not need to approximate the operator by truncating the Taylor expansion after +a finite number of terms, as in the more generic case above (generic representation) +""" +function asCircleOperator(V::AbstractXFunction, point::AbstractPoint, representation::PositionRepresentation)::Operator + dff = differentiateX(V, limitOrder=1) + firstDerivative::AbstractXFunction = length(dff) > 0 ? dff[1] : ConstantFunction(0) + includeIntegralFactor::Bool = qmConfig(representation).includeIntegralFactor + function diffX(x::Real)::Real + try # not implemented for generic functions + return firstDerivative(x) + catch + d::XDerivative = firstDerivative + step::Real = deltaX(representation) + return (d.baseFunction(x + step) - d.baseFunction(x - step))/2/step + end + end # diffX + q = pin(point).q + diag::AbstractArray{<:Real, 1} = includeIntegralFactor ? + map(x -> V(q + x) - diffX(q) * x - V(q), representation.points) : + map(x -> V(q + x) - diffX(q) * (x + q / 2), representation.points) + return LinearAlgebra.Diagonal(diag) +end # asCircleOperator + +function asCircleOperator(P::PMonomial, point::AbstractPoint, representation::QmRepresentation)::Operator + d::Int = P.power + p::Real = pin(point).p + includeIntegralFactor::Bool = qmConfig(representation).includeIntegralFactor + if d === 0 + return LinearAlgebra.UniformScaling(includeIntegralFactor ? 0 : 1) # or 0? + elseif d === 1 + return LinearAlgebra.UniformScaling(includeIntegralFactor ? 0 : p/2) + elseif d === 2 + return asOperator(PMonomial(2), representation) # independent of includeIntegralFactor + end # if + #return (1-d/2)*p^d * LinearAlgebra.I + sum(k -> binomial(d, k) * p^(d-k) * asOperator(PMonomial(k), representation), 2:d) + return includeIntegralFactor ? + sum(k -> binomial(d, k) * p^(d-k) * asOperator(PMonomial(k), representation), 2:d) : + LinearAlgebra.UniformScaling((1-d/2)*p^d) + sum(k -> binomial(d, k) * p^(d-k) * asOperator(PMonomial(k), representation), 2:d) +end # asCircleObservable + + +################### + +function asOperator(f::Union{XProdFunction, PProdFunction},representation::QmRepresentation)::Operator + return prod(func -> asOperator(func, representation), f.functions) +end # asOperator + +function asOperator(f::Union{SumFunction, XSumFunction, PSumFunction}, representation::QmRepresentation)::Operator + return sum(func -> asOperator(func, representation), f.functions) +end # asOperator + +function asOperator(f::Union{ScalarProdFunction, ScalarXProdFunction, ScalarPProdFunction}, + representation::QmRepresentation)::Operator + return f.scalar * asOperator(f.func, representation) +end # asOperator + +function asOperator(f::Union{ScalarSumFunction, ScalarXSumFunction}, representation::QmRepresentation)::Operator + return f.scalar * LinearAlgebra.I + asOperator(f.func, representation) +end # asOperator + +function asTildeOperator(f::Union{SumFunction, XSumFunction, PSumFunction}, point::AbstractPoint, representation::QmRepresentation)::Operator + return sum(func -> asTildeOperator(func, point, representation), f.functions) +end # asTildeOperator + +function asTildeOperator(f::Union{ScalarProdFunction, ScalarXProdFunction, ScalarPProdFunction}, + point::AbstractPoint, representation::QmRepresentation)::Operator + return f.scalar * asTildeOperator(f.func, point, representation) +end # asTildeOperator + +function asTildeOperator(f::Union{ScalarSumFunction, ScalarXSumFunction}, representation::QmRepresentation)::Operator + return LinearAlgebra.UniformScaling(f.scalar) + asTildeOperator(f.func, representation) +end # asTildeOperator + +function asCircleOperator(f::Union{SumFunction, XSumFunction, PSumFunction}, point::AbstractPoint, representation::QmRepresentation)::Operator + return sum(func -> asCircleOperator(func, point, representation), f.functions) +end # asCircleOperator + +function asCircleOperator(f::Union{ScalarProdFunction, ScalarXProdFunction, ScalarPProdFunction}, + point::AbstractPoint, representation::QmRepresentation)::Operator + return f.scalar * asCircleOperator(f.func, point, representation) +end # asCircleOperator + +function asCircleOperator(f::Union{ScalarSumFunction, ScalarXSumFunction}, point::AbstractPoint, representation::QmRepresentation)::Operator + includeIntegralFactor::Bool = config(representation).includeIntegralFactor + circ = asCircleOperator(f.func, point, representation) + return includeIntegralFactor ? circ : circ + LinearAlgebra.UniformScaling(f.scalar) +end # asCircleOperator + + +export QmRepresentation, PositionRepresentation, qmConfig, + Operator, asOperator, asTildeOperator, asCircleOperator, deltaX diff --git a/src/ResidualScheme.jl b/src/ResidualScheme.jl new file mode 100644 index 0000000..86d2ea9 --- /dev/null +++ b/src/ResidualScheme.jl @@ -0,0 +1,177 @@ +struct CombinedState + t::Real + point::AbstractPoint + # All calculations are based on Phi, the original wave function psi is then obtained by performing the respective transformations + Phi::AbstractWaveFunction + raw"\circ V, the potential part of the Hamiltonian propagator in the residual scheme, changes with time; will be reused in the next iteration" + V::Operator + "Time derivative of the trajectory. Only nothing in the initial state." + cDot::Union{Point, Nothing} + hbar::Real + includeIntegralFactor::Bool + raw""" + Only relevant if includeIntegralFactor is true. + If the trajectory is hamiltonian, then it is given by + \int_0^t (H(c(\tau)) - 1/2 c^\alpha \partial_\alpha H(c(\tau))) d\tau + In the more general case, it is + \int_0^t (H(c(\tau)) + 1/2 \omega_{\alpha\beta} \dot c^\alpha(\tau) c^\beta(\tau)) d\tau + """ + phaseIntegral::Real +end # CombinedState + +raw""" +Implements the Crank Nicolson integration scheme for the Schrödinger equation in the residual version. +I.e. it includes a numerical solution c(t) of Hamilton's equations, plus a solution of +(1+i\Delta T/2\hbar(T + V_{t+1}) ) \Phi(t+1) = (1-i\Delta T/2\hbar(T + V_t) ) \Phi(t), +where $V_t = \circ V(q(t)) +""" +struct ResidualCrankNicolson <: NumericsScheme + classicalScheme::ClassicalNumericsScheme + #config::Config + "is the classical trajectory Hamiltonian?" + isTrajectoryHamiltonian::Bool + function ResidualCrankNicolson(; + # FIXME here we don't know the mass yet, only in the incarnate method + classicalScheme::ClassicalNumericsScheme=SymplecticEuler(mass=1), + isTrajectoryHamiltonian::Bool=true) + return new(classicalScheme, isTrajectoryHamiltonian) + end # constructor +end # ResidualCrankNicolson + +function schemeId(scheme::ResidualCrankNicolson)::String + return "ResidualCrankNicolson" +end + +struct ResidualCrankNicolsonPropagator + scheme::ResidualCrankNicolson + config::SchroedingerConfig + deltaT::Real + hamiltonian::AbstractObservable + representation::QmRepresentation + classicalPropagator::ClassicalPropagator + "The (time-independent) kinetic energy operator" + T::Operator + V::AbstractObservable + "first x derivative" + VDiff1::Function # as a function of x + "first p derivative" + TDiff1::AbstractObservable + initialState::CombinedState + mass::Real + classicalResolutionFactor::Int +end # ResidualCrankNicolsonPropagator + +function incarnate( + hamiltonian::AbstractObservable, + representation::QmRepresentation, + scheme::ResidualCrankNicolson, + deltaT::Real, + initialPoint::Point, + initialWaveFunction::AbstractWaveFunction; # initial \Phi + t0::Real=0., + classicalResolutionFactor::Int=1 # use a higher resolution for the classical propagation than for the quantum one + )::ResidualCrankNicolsonPropagator + config::SchroedingerConfig = qmConfig(representation) + classicalPropagator::ClassicalPropagator = incarnate(hamiltonian, scheme.classicalScheme, deltaT / classicalResolutionFactor) + VDiff::AbstractArray{<:AbstractXFunction, 1} = differentiateX(hamiltonian, limitOrder=1) # should project to the potential part of H + VDiff1 = length(VDiff) > 0 ? VDiff[1] : ConstantFunction(0) + function VdiffX(x::Real)::Real + try + return VDiff1(x) + catch + d::XDerivative = VDiff1 + step::Real = deltaX(representation) + return (d.baseFunction(x + step) - d.baseFunction(x - step))/2/step + end + end # diffX + + TDiff1 = differentiateP1(hamiltonian) + # assuming a quadratic (in p) kinetic term; at this point we could as well use the more general circle operator, + # but then we'd also have to determine it anew in every step + # TODO it makes a difference though when we set includeIntegralFactor = false => check if this is considered + T::Operator = asOperator(projectP(hamiltonian), representation) + V::AbstractObservable = projectX(hamiltonian) + mass::Real = 1/2/projectP(hamiltonian)(Point(0, 1)) + VInitial::Operator = scheme.isTrajectoryHamiltonian ? asCircleOperator(V, initialPoint, representation) : + # TODO does this depend on the integral factor? + LinearAlgebra.Diagonal(map(x-> V(x + initialPoint.q), (representation::PositionRepresentation).points)) # XXX assuming PositionRepresentation here + initialState::CombinedState = CombinedState(t0, initialPoint, initialWaveFunction, + VInitial, nothing, config.hbar, config.includeIntegralFactor, 0.) + return ResidualCrankNicolsonPropagator(scheme, config, deltaT, hamiltonian, representation, classicalPropagator, + T, V, VdiffX, TDiff1, initialState, mass, classicalResolutionFactor) +end # incarnate + +function propagateSingleTimestep( + propagator::ResidualCrankNicolsonPropagator, + state::Union{CombinedState, Nothing} = nothing + )::CombinedState + if isnothing(state) + state = propagator.initialState + end # if + config = propagator.config + hbar = config.hbar + # step 1: propagate classical state + oldPoint::Point = pin(state.point) + pt::AbstractPoint = oldPoint + for _ in 1:propagator.classicalResolutionFactor + pt = propagateSingleTimestep(pt, propagator.classicalPropagator) + end + newPoint0::AbstractPoint = pt + newPoint::Point = pin(newPoint0) + isTrajectoryHamiltonian::Bool = propagator.scheme.isTrajectoryHamiltonian + Vnew::Operator = asCircleOperator(propagator.V, newPoint, propagator.representation) + Vold::Operator = state.V + deltaT::Real = propagator.deltaT + factor::Complex = im*deltaT/2/hbar + # we need to solve A\tilde\psi_{t+1} = B\tilde\psi_t + A::Operator = LinearAlgebra.I + factor * (propagator.T + Vnew) + B::Operator = LinearAlgebra.I - factor * (propagator.T + Vold) + qDot::Real = (newPoint.q - oldPoint.q) / deltaT + pDot::Real = (newPoint.p - oldPoint.p) / deltaT + oldCdot::Point = isnothing(state.cDot) ? Point(qDot, pDot) : state.cDot + if !isTrajectoryHamiltonian + hamiltonian1New = newPoint.p / propagator.mass - qDot + hamiltonian2New = propagator.VDiff1(newPoint.q) + pDot + hamiltonian1Old = oldPoint.p / propagator.mass - oldCdot.q + hamiltonian2Old = propagator.VDiff1(oldPoint.q) + oldCdot.p + corrA = hamiltonian1New * asOperator(PMonomial(1), propagator.representation) + + hamiltonian2New * asOperator(XPolynomial([0.,1.]), propagator.representation) + corrB = hamiltonian1Old * asOperator(PMonomial(1), propagator.representation) + + hamiltonian2Old * asOperator(XPolynomial([0.,1.]), propagator.representation) + if !config.includeIntegralFactor + corrA = corrA + (0.5 * newPoint.p * hamiltonian1New + 0.5 * newPoint.q * hamiltonian2New) * LinearAlgebra.I + corrB = corrB + (0.5 * oldPoint.p * hamiltonian1Old + 0.5 * oldPoint.q * hamiltonian2Old) * LinearAlgebra.I + end # if + A = A + factor * corrA + B = B - factor * corrB + end + values0::AbstractArray{<:Complex, 1} = values(state.Phi, propagator.representation) + newValues::AbstractArray{<:Complex, 1} = A \ (B * values0) + PhiNew::AbstractWaveFunction = asWavefunction(newValues, propagator.representation) + # calculate phase integral summand if required + local deltaIntegral::Real + if !config.includeIntegralFactor + deltaIntegral = 0 + elseif isTrajectoryHamiltonian + deltaIntegral = deltaT * (propagator.hamiltonian(newPoint) - + 0.5*(newPoint.q * propagator.VDiff1(newPoint.q) + newPoint.p * propagator.TDiff1(newPoint))) + else # non-Hamiltonian case + deltaIntegral = deltaT * (propagator.hamiltonian(newPoint) + + 0.5*(newPoint.q * pDot - newPoint.p * qDot)) + end # if + newIntegral = state.phaseIntegral + deltaIntegral + newState::CombinedState = CombinedState(state.t + deltaT, newPoint0, PhiNew, Vnew, + Point(qDot, pDot), state.hbar, state.includeIntegralFactor, newIntegral) + return newState +end # propagateSingleTimestep + +function getPsi(state::CombinedState)::AbstractWaveFunction + weylTranslated::AbstractWaveFunction = weylTranslate(state.Phi, -state.point, state.hbar) + if !state.includeIntegralFactor + return weylTranslated + end + return exp(-im/state.hbar*state.phaseIntegral) * weylTranslated +end # getPsi + +export CombinedState, ResidualCrankNicolson, ResidualCrankNicolsonPropagator, getPsi + \ No newline at end of file diff --git a/src/SchroedingerConfig.jl b/src/SchroedingerConfig.jl new file mode 100644 index 0000000..126515c --- /dev/null +++ b/src/SchroedingerConfig.jl @@ -0,0 +1,42 @@ +"Global configuration options for the numerical simulation" +struct SchroedingerConfig + " + Value of Planck's constant, or maybe rather the dimensionless parameter + \"hbar / characteristic action of the system\" + " + hbar::Real + " + Defines the convention used for the residual Schrödinger equation: + include an integral factor in the unitary transformation to eliminate + the zeroth order contributions from the Hamiltonian or not? + If this is true (the default), then the conversion from the residual + wave function Phi to the original wave function psi needs to include + a phase consisting of a time-integral, otherwise we get some nasty zeroth-order + terms in the Hamiltonian. + Default: true. + " + includeIntegralFactor::Bool + " + Derivative method used in the definition of derivative operators, such as + the momentum operator in position space representation. + * 1: forward/Newton (default) + * 0: symmetric/midpoint + * -1: backward + " + firstDerivativeMethod::Int + " + Number of derivatives to include in expressions summing over the + Tayler series of some function. TODO is it still relevant? + Default: 10 + " + limitDiffOrder::Int + function SchroedingerConfig(; + hbar::Real=0.001, + includeIntegralFactor::Bool=true, + firstDerivativeMethod::Int=1, + limitDiffOrder::Int=10) + return new(hbar, includeIntegralFactor, firstDerivativeMethod, limitDiffOrder) + end # constructor +end # SchroedingerConfig + +export SchroedingerConfig diff --git a/src/SchroedingerNumerics.jl b/src/SchroedingerNumerics.jl new file mode 100644 index 0000000..c75784f --- /dev/null +++ b/src/SchroedingerNumerics.jl @@ -0,0 +1,34 @@ +module SchroedingerNumerics +import LinearAlgebra +import Printf +import JSON +import Base.values + +# imports are listed in order of dependencies; lower files may depend on upper files +include("./SchroedingerConfig.jl") +include("./PhaseSpace.jl") +include("./DifferentiationUtils.jl") +include("./PhaseSpaceFunctions.jl") +include("./Representation.jl") +include("./WaveFunction.jl") +include("./NumericsScheme.jl") +include("./ExactTrajectory.jl") +include("./SymplecticEuler.jl") +include("./ExactWaveFunction.jl") +include("./ForwardEulerQm.jl") +include("./MatrixExponential.jl") +include("./CrankNicolson.jl") +include("./WeylTransformedScheme.jl") +include("./ExactQuantumPropagation.jl") +include("./ResidualScheme.jl") +include("./IoUtils.jl") +include("./ClassicalSystem.jl") +include("./QmSystem.jl") +include("./QmSystemResidual.jl") +include("./QmSystemSum.jl") +include("./QmSystemConcat.jl") +include("./IoSystemUtils.jl") + + + +end # module diff --git a/src/SymplecticEuler.jl b/src/SymplecticEuler.jl new file mode 100644 index 0000000..5a8cb8e --- /dev/null +++ b/src/SymplecticEuler.jl @@ -0,0 +1,53 @@ + +raw""" +Implements the scheme +p_{n+1} = p_n - \Delta t V'(q_n) +q_{n+1} = q_n + \Delta t / m p_{n+1} +""" +struct SymplecticEuler <: ClassicalNumericsScheme + mass::Real + "delta for calculating derivatives of the potential; only needed if they cannot be determined otherwise" + deltaX::Real # may be needed for derivatives calculation; depends on the potential + function SymplecticEuler(;mass::Real=1, deltaX=0.001) + return new(mass, deltaX) + end #constructor +end # SymplecticEuler + +function schemeId(scheme::SymplecticEuler)::String + return "SymplecticEuler" +end + +struct SymplecticEulerPropagation <: ClassicalPropagator + deltaT::Real + mass::Real + deltaX::Real + "A function Float64 -> Float64" + V_diff::AbstractXFunction +end # + +function incarnate(hamiltonian::AbstractObservable, scheme::SymplecticEuler, deltaT::Real)::SymplecticEulerPropagation + diffs = differentiateX(hamiltonian, limitOrder=1) + # the empty case seems strange? + V_diff::AbstractXFunction = isempty(diffs) ? projectX(hamiltonian) : diffs[1] + return SymplecticEulerPropagation(deltaT, scheme.mass, scheme.deltaX, V_diff) +end # specialize + + +function propagateSingleTimestep(point::Point, propagator::SymplecticEulerPropagation)::Point + deltaT::Real = propagator.deltaT + local V1::Real + try + V1 = propagator.V_diff(point.q) + catch + diff::XDerivative = propagator.V_diff + if diff.diffOrder > 1 + throw(ErrorException("higher order differentiation not implemented")) + end + V1 = (diff.baseFunction(point.q + propagator.deltaX) - diff.baseFunction(point.q - propagator.deltaX)) / 2 / propagator.deltaX + end + p::Real = point.p - deltaT * V1 + q::Real = point.q + deltaT / propagator.mass * p + return Point(q, p) +end # propagateSingleTimestep + +export SymplecticEuler diff --git a/src/WaveFunction.jl b/src/WaveFunction.jl new file mode 100644 index 0000000..3ded0b4 --- /dev/null +++ b/src/WaveFunction.jl @@ -0,0 +1,338 @@ +##### Abstract types and functions below ##### + +abstract type AbstractWaveFunction +end # AbstractWaveFunction + +function Base.:values(psi::AbstractWaveFunction, representation::QmRepresentation)::AbstractArray{<:Complex, 1} + throw(ErrorException("Not implemented")) +end # values + +# called "dot" in LinearAlgebra +function innerProduct(psi::AbstractWaveFunction, phi::AbstractWaveFunction, representation::QmRepresentation)::Number + throw(ErrorException("Not implemented")) +end # innerProduct + +# Named like the corresponding Base function +function norm_sqr(psi::AbstractWaveFunction, representation::QmRepresentation)::Real + return real(innerProduct(psi, psi, representation)) +end # norm_sqr + +function normalize(psi::AbstractWaveFunction, representation::QmRepresentation)::AbstractWaveFunction + return 1/sqrt(norm_sqr(psi, representation)) * psi +end # normalize + +"The inverse function of values(psi, representation)" +function asWavefunction(values::AbstractArray{<:Number, 1}, representation::QmRepresentation; cacheNorm::Bool = true)::AbstractWaveFunction + throw(ErrorException("Not implemented")) +end + +function expectationValue(psi::AbstractWaveFunction, f::AbstractObservable, representation::QmRepresentation; normalize::Bool=true)::Real + config::SchroedingerConfig = qmConfig(representation) + result::Real = real(innerProduct(psi, asWavefunction( + asOperator(f, representation) * values(psi, representation), representation, cacheNorm=false + ), representation)) + return normalize ? (result / norm_sqr(psi, representation)) : result +end # expectationValue + +function expectationValue(psi::AbstractWaveFunction, fHat::Operator, representation::QmRepresentation; normalize::Bool=true)::Real + result::Real = real(innerProduct(psi, asWavefunction(fHat * values(psi, representation), representation, cacheNorm=false), representation)) + return normalize ? (result / norm_sqr(psi, representation)) : result +end # expectationValue + + +#### Concrete types and function implementations below ######### + +function _norm_sqr(points::AbstractArray{<:Real, 1}, values::AbstractArray{<:Number, 1}) + l::Int = length(values) + if length(points) !== l + throw(ErrorException("Length of points and values not equal: " + length(points) + ": " + l)) + end # if + if points isa AbstractRange + deltaX::Float64 = convert(Float64, step(points)) + return (sum(abs2.(values)) - (abs2(values[1]) + abs2(values[l]))/2) * deltaX + end # if + result::Float64 = 0. + previousPoint::Real = points[1] + previousValue::Complex = complex(values[1]) + for idx in 2:length(points) + nextPoint::Real = points[idx] + nextValue::Complex = complex(values[idx]) + result += abs2((nextValue + previousValue) / 2) * (nextPoint - previousPoint) + previousPoint = nextPoint + previousValue = nextValue + end # for idx + return result +end # _norm_sqr + +function _innerProduct( + points::AbstractArray{<:Real, 1}, + vPsi0::Union{AbstractArray{<:Number, 1}}, + vPhi0::Union{AbstractArray{<:Number, 1}})::ComplexF64 + vPsi::AbstractArray{<:Complex, 1} = complex(vPsi0) + vPhi::AbstractArray{<:Complex, 1} = complex(vPhi0) + l::Int = length(points) + if points isa AbstractRange + deltaX::Real = step(points) + return (LinearAlgebra.dot(vPsi, vPhi) - (conj(vPsi[1]) * vPhi[1] + conj(vPsi[l]) * vPhi[l])/2) * deltaX + end # if + result::ComplexF64 = 0. + previousPoint::Real = points[1] + previousValue::Complex = conj(vPsi[1]) * vPhi[1] + for idx in 2:l + nextPoint::Real = points[idx] + nextValue::Complex = conj(vPsi[idx]) * vPhi[idx] + result += (nextValue + previousValue) / 2 * (nextPoint - previousPoint) + previousPoint = nextPoint + previousValue = nextValue + end # for idx + return result +end # _innerProduct + +function innerProduct(psi::AbstractWaveFunction, phi::AbstractWaveFunction, representation::PositionRepresentation)::Number + return _innerProduct(representation.points, values(psi, representation), values(phi, representation)) +end # innerProduct + +"A wave function defined in position space by its values at a set of fixed points" +struct PointsWaveFunction <: AbstractWaveFunction + "base points in x coordinates" + points::AbstractArray{<:Real, 1} + "values of the wave function at the base points" + values::AbstractArray{<:Complex, 1} + "used internally" + normSquared::Union{<:Real, Nothing} + function PointsWaveFunction(points::AbstractArray{<:Real, 1}, + values::AbstractArray{<:Number, 1}, + normSquared::Union{Nothing, Real}=nothing; cacheNorm::Bool = true) + if length(values) !== length(points) + throw(error("Length of wave function array does not match number of grid points " + length(values) + " - " + length(points))) + end # if + normSquared::Union{<:Real, Nothing} = isnothing(normSquared) ? (cacheNorm ? _norm_sqr(points, values) : nothing) : normSquared + return new(points, complex(values), normSquared) + end # constructor +end # PointsWaveFunction + +"A wave function defined in position space by an arbitrary function" +struct PositionWaveFunction <: AbstractWaveFunction + func::Any + "Pass a complex function of a single argument" + function PositionWaveFunction(func::Any) + if !(func isa Function) + throw(ErrorException(string("Argument passed is not a function ", func))) + end # if + return new(func) + end # constructor +end # PositionWaveFunction + +function asWavefunction(values::AbstractArray{<:Number, 1}, representation::PositionRepresentation; cacheNorm::Bool = true)::AbstractWaveFunction + return PointsWaveFunction(representation.points, values; cacheNorm=cacheNorm) +end + +"A wave function translated by a Weyl-Operator U(q,p)" +struct TranslatedWaveFunction <: AbstractWaveFunction + psi0::AbstractWaveFunction + point::Point + hbar::Real +end # TranslatedWaveFunction + +struct ScaledWaveFunction <: AbstractWaveFunction + psi0::AbstractWaveFunction + factor::Number +end # ScaledWaveFunction + +struct SumWaveFunction <: AbstractWaveFunction + psis::AbstractArray{AbstractWaveFunction, 1} +end # SumWaveFunction + +function Base.:values(psi::PointsWaveFunction, representation::PositionRepresentation)::AbstractArray{<:Complex, 1} + if psi.points == representation.points + return psi.values + end + pnts1::AbstractArray{<:Real, 1} = psi.points + l1::Int = length(pnts1) + pnts2::AbstractArray{<:Real, 1} = representation.points + l2::Int = length(pnts2) + if pnts2[1] >= pnts1[l1] || pnts2[l2] <= pnts1[1] + throw(ErrorException("No overlap between wave function grid and representation grid")) + end #if + idx1::Int = 1 + v::AbstractArray{ComplexF64} = fill(complex(0.), l2) + for idx2 in 1:l2 + pnt2::Real = pnts2[idx2] + idxNext::Union{Int, Nothing} = findnext(pnt -> pnt >= pnt2, pnts1, idx1) + if isnothing(idxNext) + break + end # if + pntNext::Real = pnts1[idxNext] + if pntNext === pnt2 + v[idx2] = psi.values[idxNext] + else + idxPrev::Union{Int, Nothing} = findprev(pnt -> pnt <= pnt2, pnts1, idxNext) + if !isnothing(idxPrev) + pntPrev::Real = pnts1[idxPrev] + v[idx2] = psi.values[idxPrev] + (psi.values[idxNext] - psi.values[idxPrev]) * (pnt2 - pntPrev) / (pntNext - pntPrev) + end # if + end # if + idx1 = idxNext + end # for idx2 + return v +end # values + +function Base.:values(psi::PositionWaveFunction, representation::PositionRepresentation)::AbstractArray{<:Complex, 1} + return map(pt -> complex(psi.func(pt)), representation.points) +end # values + +function norm_sqr(psi::PointsWaveFunction, representation::PositionRepresentation)::Real + if !isnothing(psi.normSquared) && psi.points == representation.points + return psi.normSquared + end + return _norm_sqr(representation.points, values(psi, representation)) +end # norm + +function norm_sqr(psi::AbstractWaveFunction, representation::PositionRepresentation)::Real + return _norm_sqr(representation.points, values(psi, representation)) +end # norm_sqr + +"Apply the Weyl operator U(q,p) to psi.psi0" +function Base.:values(psi::TranslatedWaveFunction, representation::PositionRepresentation)::AbstractArray{<:Complex, 1} + p::Real = psi.point.p + q::Real = psi.point.q + if p == 0 && q == 0 + return values(psi.psi0, representation) + end + # Note that psi0 should not be a PositionWaveFunction, because the weylTranslate operation on a such + # returns a new PositionWaveFunction, not TranslatedWaveFunction + psi0::AbstractWaveFunction = psi.psi0 + hbar::Real = qmConfig(representation).hbar + if psi0 isa PointsWaveFunction + # whether they are the same or not is not really important + oldPoints::AbstractArray{<:Real, 1} = psi0.points + oldValues::AbstractArray{<:Complex, 1} = psi0.values + oldLength::Int = length(oldPoints) + newPoints::AbstractArray{<:Real, 1} = representation.points + newLength::Int = length(newPoints) + newValues::AbstractArray{<:Complex, 1} = Array{ComplexF64, 1}(undef, newLength) + idx::Int=1 # in oldPoints + for newIdx in 1:newLength + x = newPoints[newIdx] + x1::Real = x + q + while oldPoints[idx] < x1 && idx= l + return 0. + #newIndex = l + #frac = 0. + elseif newIndex < 1 + return 0. + #newIndex = 1 + #frac = 0. + end # if + vLower::Complex = v[newIndex] + if frac === 0. + return vLower + end # if + return vLower + frac * (v[newIndex + 1] - vLower) + end # vShifted + # FIXME a loop for creating the shifted values would be more efficient + shiftedPsis::AbstractArray{<:Complex, 1} = map(idx -> vShifted(idx) * exp(-im/hbar * p * (pnts[idx] + q/2)), 1:l) + return shiftedPsis +end # values + +function Base.:values(psi::ScaledWaveFunction, representation::QmRepresentation)::AbstractArray{<:Complex, 1} + return psi.factor .* values(psi.psi0, representation) +end # values + +function norm_sqr(psi::ScaledWaveFunction, representation::QmRepresentation)::Real + return abs2(psi.factor) * norm_sqr(psi.psi0, representation) +end # norm_sqr + +function norm_sqr(psi::ScaledWaveFunction, representation::PositionRepresentation)::Real + return abs2(psi.factor) * norm_sqr(psi.psi0, representation) +end # norm_sqr + +function Base.:values(psi::SumWaveFunction, representation::QmRepresentation)::AbstractArray{<:Complex, 1} + return sum(wf -> values(wf, representation), psi.psis) +end # values + + +"Apply the Weyl operator U(q,p) to the wave function psi" +function weylTranslate(psi::AbstractWaveFunction, point0::AbstractPoint, hbar::Real)::AbstractWaveFunction + point::Point = pin(point0) + if point.q == 0 && point.p == 0 + return psi + end # if + return TranslatedWaveFunction(psi, point, hbar) +end # weylTranslate + +"Apply the Weyl operator U(q,p) to the wave function psi" +function weylTranslate(psi::PositionWaveFunction, point0::AbstractPoint, hbar::Real)::PositionWaveFunction + point::Point = pin(point0) + if point.q == 0 && point.p == 0 + return psi + end # if + newFunc = x -> exp(-im / hbar * point.p * (x + point.q/2)) * psi.func(x + point.q) + return PositionWaveFunction(newFunc) +end # weylTranslate + + +# scalar multiplication +Base.:*(c::Number, psi::PointsWaveFunction) = PointsWaveFunction(psi.points, c * psi.values, isnothing(psi.normSquared) ? nothing : abs2(c) * psi.normSquared) +Base.:*(psi::PointsWaveFunction, c::Number) = Base.:*(c, psi) +Base.:*(c::Number, psi::PositionWaveFunction) = PositionWaveFunction(x -> c * psi.func(x)) +Base.:*(psi::PositionWaveFunction, c::Number) = Base.:*(c, psi) +Base.:*(c::Number, psi::AbstractWaveFunction) = ScaledWaveFunction(psi, c) +Base.:*(psi::AbstractWaveFunction, c::Number) = Base.:*(c, psi) +Base.:/(psi::AbstractWaveFunction, c::Number) = Base.:*(1/c, psi) +Base.:-(psi::AbstractWaveFunction) = -1 * psi +# addition +function Base.:+(psi1::PointsWaveFunction, psi2::PointsWaveFunction) + if psi1.points == psi2.points + return PointsWaveFunction(psi1.points, psi1.values .+ psi2.values) + end # if + return SumWaveFunction([psi1, psi2]) +end # + +Base.:+(psi1::PositionWaveFunction, psi2::PositionWaveFunction) = PositionWaveFunction(x -> psi1.func(x) + psi2.func(x)) +Base.:+(psi1::AbstractWaveFunction, psi2::AbstractWaveFunction) = SumWaveFunction([psi1, psi2]) +Base.:-(psi1::AbstractWaveFunction, psi2::AbstractWaveFunction) = psi1 + (-psi2) +LinearAlgebra.:normalize(psi::AbstractWaveFunction, representation::QmRepresentation) = normalize(psi, representation) + +##### Utitlity functions below + + +export AbstractWaveFunction, norm_sqr, expectationValue, asWavefunction +export PointsWaveFunction, PositionWaveFunction +export weylTranslate diff --git a/src/WeylTransformedScheme.jl b/src/WeylTransformedScheme.jl new file mode 100644 index 0000000..a695c5f --- /dev/null +++ b/src/WeylTransformedScheme.jl @@ -0,0 +1,45 @@ +""" +Solve the Schrödinger equation over a fixed point (q0, p0) in phase space. +For (q0,p0) = (0,0) this is the standard Schrödinger equation +""" +struct WeylTransformedScheme <: QmNumericsScheme + point::Point +end # WeylTransformedScheme + +function schemeId(::WeylTransformedScheme)::String + return "WeylTransformedScheme" +end + +struct CNMatrixWeyl <: QuantumPropagator + point::Point + hbar::Real + representation::QmRepresentation + config::SchroedingerConfig + raw"(1+i*deltaT/(2\hbar) \tilde H)" + A::AbstractArray{<:Complex, 2} + raw"(1-i*deltaT/(2\hbar) \tilde H)" + B::AbstractArray{<:Complex, 2} +end # CNMatrixWeyl + +function incarnate( + hamiltonian::AbstractObservable, + representation::QmRepresentation, + scheme::WeylTransformedScheme, + deltaT::Real)::QuantumPropagator + cfg = qmConfig(representation) + H = asTildeOperator(hamiltonian, scheme.point, representation) + hbar = cfg.hbar + A = (LinearAlgebra.I + (im*deltaT/2/hbar) * H) + B = (LinearAlgebra.I - (im*deltaT/2/hbar) * H) + return CNMatrixWeyl(scheme.point, cfg.hbar, representation, cfg, A, B) +end # incarnate + + +function propagateSingleTimestep(psi::AbstractWaveFunction, propagator::CNMatrixWeyl)::AbstractWaveFunction + translated::AbstractWaveFunction = weylTranslate(psi, propagator.point, propagator.hbar) + valuesOld::AbstractArray{<:Complex, 1} = values(translated, propagator.representation) + valuesNew::AbstractArray{<:Complex, 1} = propagator.A\(propagator.B * valuesOld) + return weylTranslate(asWavefunction(valuesNew, propagator.representation), -propagator.point, propagator.hbar) +end # propagateSingleTimestep + +export WeylTransformedScheme, propagateSingleTimestep diff --git a/viz/assets/icons/east_black_24dp.svg b/viz/assets/icons/east_black_24dp.svg new file mode 100644 index 0000000..e3e703e --- /dev/null +++ b/viz/assets/icons/east_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/viz/assets/icons/license.txt b/viz/assets/icons/license.txt new file mode 100644 index 0000000..5215d52 --- /dev/null +++ b/viz/assets/icons/license.txt @@ -0,0 +1,3 @@ +Material Icons, ©Google +Retrieved 2022-01-04 from https://fonts.google.com/icons?selected=Material+Icons +License: Apache 2.0 diff --git a/viz/assets/icons/pause_black_24dp.svg b/viz/assets/icons/pause_black_24dp.svg new file mode 100644 index 0000000..4104cb0 --- /dev/null +++ b/viz/assets/icons/pause_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/viz/assets/icons/play_arrow_black_24dp.svg b/viz/assets/icons/play_arrow_black_24dp.svg new file mode 100644 index 0000000..178bd3a --- /dev/null +++ b/viz/assets/icons/play_arrow_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/viz/assets/icons/stop_black_24dp.svg b/viz/assets/icons/stop_black_24dp.svg new file mode 100644 index 0000000..9373136 --- /dev/null +++ b/viz/assets/icons/stop_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/viz/assets/icons/west_black_24dp.svg b/viz/assets/icons/west_black_24dp.svg new file mode 100644 index 0000000..b7f7641 --- /dev/null +++ b/viz/assets/icons/west_black_24dp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/viz/assets/style.css b/viz/assets/style.css new file mode 100644 index 0000000..5e6b2e0 --- /dev/null +++ b/viz/assets/style.css @@ -0,0 +1,153 @@ +.main-menu { + position: absolute; + border-right: 1px solid black; + height: 100%; + max-width: 300px; + padding-right: 2em; +} + +.menu-margin { + margin-left: 350px; +} + +.upload-dataset { + display: flex; + column-gap: 1em; + margin-bottom: 1em; +} + +.datasets-grid { + display: flex; + flex-direction: column; + row-gap: 0.5em; +} + +.dataset-container { + padding-left: 0.2em; + +} + +.controls { + display: flex; + column-gap: 0.5em; + /*margin-bottom: 1em;*/ +} + +.aligned-row { + display: flex; + column-gap: 0.5em; + align-items: baseline; + flex-wrap: nowrap; +} + +.left-margin { + margin-left: 1em; +} + +.menu-close { + position: absolute; + top: 0px; + right: 2.5em; + opacity: 0.6; +} + +.menu-open { + opacity: 0.6; +} + +.control-icon { + cursor: pointer; +} + +.control-icon-disabled { + opacity: 0.5; +} + +.control-icon-disabled:hover { + cursor: auto; +} + +.sim-duration-control { + max-width: 8em; +} + +.observables-canvas { + width: 600px; + height: 600px; +} + +.position-absolute { + position: absolute; +} + +.position-relative { + position: relative; +} + +/* // TODO delete +.phase-space-container { + display: flex; + align-items: flex-end; + column-gap: 1em; +} +*/ + +.legend-grid { + display: grid; + grid-template-columns: auto auto 1fr; + align-items: center; + column-gap: 1em; + + /*border: 1px solid black;*/ +} + +.phase-space-legend { + margin-bottom: 4em; +} + +.current-point { + width: 0px; + height: 0px; + border: red 5px solid; + border-radius: 5px; +} + +.phase-space-plots { + display: flex; + flex-wrap: wrap; + column-gap: 1em; + align-items: flex-end; +} + +.phase-space-plots>div[data-plot="phase-space"] { + min-width: 600px; + margin-left: 2em; +} + +.overlay { + position: fixed; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 10; + background-color: rgb(0,0,0, 0.2); + display: flex; + justify-items: center; + justify-content: space-around; + align-items: center; +} + +/* https://stackoverflow.com/questions/23772673/hidden-property-does-not-work-with-flex-box */ +.overlay[hidden]{ + display:none; +} + +.overlay>div>div { + font-size: 1.8em; + margin-bottom: 1em; +} + +.overlay>div>progress { + transform: scale(2); +} \ No newline at end of file diff --git a/viz/index.html b/viz/index.html new file mode 100644 index 0000000..d768a19 --- /dev/null +++ b/viz/index.html @@ -0,0 +1,70 @@ + + + + + + Schroedinger numerics + + + +

Wave function visualization

+ + + +

+ + + + \ No newline at end of file diff --git a/viz/package.json b/viz/package.json new file mode 100644 index 0000000..d698247 --- /dev/null +++ b/viz/package.json @@ -0,0 +1,30 @@ +{ + "name": "schroedinger-numerics-viz", + "version": "1.0.0", + "description": "", + "main": "src/index.js", + "type": "module", + "private": true, + "scripts": { + "start": "webpack serve --mode development --hot --progress", + "build": "webpack build --mode production" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "uplot": "^1.6.27" + }, + "devDependencies": { + "copy-webpack-plugin": "^11.0.0", + "css-loader": "^6.8.1", + "html-webpack-plugin": "^5.5.3", + "resolve-typescript-plugin": "^1.1.1", + "style-loader": "^3.3.3", + "ts-loader": "^9.5.1", + "typescript": "^5.3.2", + "webpack": "^5.89.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1" + } +} diff --git a/viz/src/JsUtils.ts b/viz/src/JsUtils.ts new file mode 100644 index 0000000..1ec21b1 --- /dev/null +++ b/viz/src/JsUtils.ts @@ -0,0 +1,98 @@ +export class JsUtils { + + private constructor() {} + + public static createElement(tag: T, options?: { + parent?: HTMLElement|DocumentFragment; + classes?: Array; + id?: string; + title?: string; + text?: string; + html?: string; + dataset?: Map; + }): HTMLElementTagNameMap[T] { + const el: HTMLElementTagNameMap[T] = document.createElement(tag); + if (options?.classes?.length > 0) + options.classes.forEach(c => el.classList.add(c)); + if (options?.id) + el.id = options.id; + if (options?.title) + el.title = options.title; + if (options?.text) + el.innerText = options.text; + else if (options?.html) + el.innerHTML = options.html; + if (options?.dataset) + options.dataset.forEach((val, key) => el.dataset[key] = val); + if (options?.parent) + options.parent.appendChild(el); + return el; + } + + /** + * Merge arrays into one, removing duplicates. Assume equal spacing + * @param arrays + * @returns [merged values, are all arrays equal?] + */ + public static mergeArrays(arrays: Array|undefined>): [Array, boolean] { + arrays = arrays.filter(arr => arr); + if (JsUtils.arraysEqual(arrays)) + return [arrays.length > 0 ? arrays[0] : [], true]; + const result: Array = []; + const iterators: Array> = arrays.map(arr => arr[Symbol.iterator]()) + const next: Array> = iterators.map(it => it.next()); + while (next.findIndex(result => !result.done) >= 0) { + const nextValue: number|undefined = next + .filter(r => !r.done) + .map(r => r.value) + .reduce((min, current) => min === undefined || current < min ? current : min, undefined); + if (nextValue === undefined) // TODO or throw error? + break; + const indicesToAdvance: Array = next + .map((val, idx) => [val, idx] as [IteratorResult, number]) + .filter(arr => !arr[0].done && arr[0].value === nextValue) + .map(arr => arr[1]); + indicesToAdvance.forEach(idx => next[idx] = iterators[idx].next()); + result.push(nextValue); + } + return [result, false]; + } + + private static arraysEqual(xs: Array>): boolean { + const l: number = xs.length; + if (l <= 1) + return true; + const l0: number = xs[0].length; + const x0: number = xs[0][0]; + const xn: number = xs[0][l0-1]; + for (let idx=1; idx= Math.exp(Math.log(10) * numDigits) || (abs < 0.01 && abs !== 0)) + return n.toExponential(numDigits-1); + return Intl.NumberFormat("en-US", { maximumSignificantDigits: numDigits }).format(n) + } + + public static createMathElement(tag: K, options?: { + parent?: HTMLElement|MathMLElement|DocumentFragment; + text?: string; + }): MathMLElementTagNameMap[K]{ + const element: MathMLElementTagNameMap[K] = document.createElementNS("http://www.w3.org/1998/Math/MathML", tag); + if (options.text) + element.textContent = options.text; + if (options?.parent) + options.parent.appendChild(element); + return element; + } + +} \ No newline at end of file diff --git a/viz/src/PlotsController.ts b/viz/src/PlotsController.ts new file mode 100644 index 0000000..9966b9d --- /dev/null +++ b/viz/src/PlotsController.ts @@ -0,0 +1,34 @@ +import { DifferencePlot } from "./differencePlot.js"; +import { PhaseSpace } from "./phaseSpace.js"; +import { PsiPlot } from "./psiPlot.js"; +import { SimulationListener } from "./types.js"; + +export class PlotsController { + + #psiPlot: PsiPlot; + #psiTildePlot: PsiPlot; + #differencePlot: DifferencePlot; + #observablesPlot: PhaseSpace; + #energyPlot: PhaseSpace; + + constructor( + simulationListeners: Array // to be filled by the controller + ) { + this.#psiPlot = new PsiPlot(); + this.#psiTildePlot = new PsiPlot(true); + this.#differencePlot = new DifferencePlot(); + this.#observablesPlot = new PhaseSpace(); + this.#energyPlot = new PhaseSpace(true); + simulationListeners.push(this.#psiPlot, this.#psiTildePlot, this.#differencePlot, this.#observablesPlot, this.#energyPlot); + } + + setMargin(margin: number): void { + const width: number = document.body.clientWidth; + this.#psiPlot.setWidth(width - margin); + this.#differencePlot.setWidth(width - margin); + // TODO this.#observablesPlot + } + + + +} \ No newline at end of file diff --git a/viz/src/SimulationController.ts b/viz/src/SimulationController.ts new file mode 100644 index 0000000..48f05e7 --- /dev/null +++ b/viz/src/SimulationController.ts @@ -0,0 +1,353 @@ +import { DatasetsGrid } from "./datasetsGrid.js"; +import { JsUtils } from "./JsUtils.js"; +import { SimulationListener, QuantumSimulationResult, SimulationState, SimulationStateListener, Timeslice, ClassicalSimulationResult, Point } from "./types.js"; + +export class SimulationController { + + #qmResultSet: Array = []; + #classicalResultSet: Array = []; + + #activeSimulation: SimulationRun|null = null; + #duration: number = 10_000; + #scales: Array = []; + + #state: SimulationState = SimulationState.UNSET; + + readonly #datasetsViz: DatasetsGrid; + + readonly #listener: SimulationListener&any = { + + _errorsReported: {}, + + initialize: (qm: Array, classical: Array) => { + this.#listener._errorsReported = {}; + this.listeners.forEach((l, idx) => { + try { + l.initialize(qm, classical); + } catch (e) { + console.log("Failed to initialize listener ", l, e); + this.#listener._errorsReported[idx] = e; + } + }) + }, + scale: (scale: number) => this.listeners.forEach(l => l.scale(scale)), + next: (slice: Array<[Timeslice, Timeslice|undefined]>, points: Array, potential?: Array>) => + this.listeners.forEach((l, idx) => { + try { + l.next(slice, points, potential); + } catch (e) { + if (!(idx in this.#listener._errorsReported)) { + console.log("Error in listener ", l, e); + this.#listener._errorsReported[idx] = e; + } + } + }), + clear: () => { + this.listeners.forEach(l => l.clear()); + this.#listener._errorsReported = {}; + } + }; + + readonly #stateListener: SimulationStateListener + + constructor( + private readonly listeners: Array, + // TODO report done state? + private readonly stateListeners: Array + ) { + this.#datasetsViz = new DatasetsGrid(); + const obj = this; + this.#stateListener = { + stateChanged(simulationState: SimulationState): void { + obj._setState(simulationState); + }, + onProgress(fraction: number): void { + obj.stateListeners.forEach((l: SimulationStateListener) => l.onProgress ? l.onProgress(fraction) : {}) + } + } + } + + addResultSet(results: QuantumSimulationResult|ClassicalSimulationResult) { + const id: string = results.id; + const isClassical: boolean = (results as ClassicalSimulationResult).points !== undefined; + const targetArray: Array = isClassical ? this.#classicalResultSet : this.#qmResultSet; + if (targetArray.find(r => r.id === id)) + throw new Error("Result set " + id + " already exists"); + targetArray.push(results); + this.#listener.initialize(this.#qmResultSet, this.#classicalResultSet); + if (!isClassical) { + const scale0: number = Math.max(...(results as QuantumSimulationResult).waveFunction.map(arr => + Math.max(...arr.waveFunction.map(values => values[0]*values[0] + values[1]*values[1])))); + const scale: number = Math.sqrt(scale0); + this.#scales.push(scale) + if (Math.max(...this.#scales) <= scale) + this.#listener.scale(scale); + } + this._restart(); + this.#datasetsViz.addResultDataset(results); + } + + removeResultSet(id: string): boolean { + const idx: number = this.#qmResultSet.findIndex(r => r.id === id); + if (idx < 0) + return false; + this.#qmResultSet.splice(idx, 1); + this.#scales.splice(idx, 1); + this.#datasetsViz.removeResultDataset(id); + return true; + } + + getResultSets(): Array { + return [...this.#qmResultSet, ...this.#classicalResultSet]; + } + + getDuration(): number { + return this.#duration; + } + + setDuration(millis: number) { + if (!(millis > 0)) + return; + this.#duration = millis; + this._restart(); + } + + start() { + if (this.#activeSimulation) { + this.#activeSimulation.start(); + this._setState(SimulationState.RUNNING); + } + } + + pause() { + if (this.#activeSimulation) { + this.#activeSimulation.pause(); + this._setState(SimulationState.PAUSED); + } + } + + reset(fraction?: number) { + if (this.#activeSimulation) { + this.#activeSimulation.reset(fraction); + // FIXME only if fraction is not set + if (fraction === undefined) + this._setState(SimulationState.INITIALIZED); + } + } + + steps(): number { + return this.#activeSimulation?.steps() || 0; + } + + advance(frames: number) { + this.#activeSimulation?.advance(frames); + } + + getFrameIndices(): {passedTime: number, frameIndices: Record}|undefined { + return this.#activeSimulation?.getFrameIndices(); + } + + private _setState(state: SimulationState) { + if (state !== this.#state) { + this.#state = state; + this.stateListeners.forEach(l => l.stateChanged(state)); + } + } + + private _restart() { + this.#activeSimulation?.pause(); + if (this.#qmResultSet.length === 0 && this.#classicalResultSet.length === 0) { + this._setState(SimulationState.UNSET); + return; + } + this.#activeSimulation = new SimulationRun(this.#qmResultSet, this.#classicalResultSet, this.#duration, this.#listener, this.#stateListener); + this.#activeSimulation.start(1); + this._setState(SimulationState.INITIALIZED); + } + +} + +// TODO report new fraction to stateListeners +class SimulationRun { + + readonly #numQmStates: number; + readonly #deltaT: number; + readonly #hasTildePotentials: boolean; + readonly #steps: number; + + //readonly #count: number; + //#currentIdx: number; + readonly #timeDuration: number; // simulation time + #passedTime: number; // simulation time + // first indices belong to quantum states, last ones to classical + #indices: Array|undefined; + + #timer: number; + #startTime: number; // "real" time + #previousTime: number; + + + + readonly #callback = (timestamp: number, frames?: number) => { + if (this.#startTime === undefined) { + this.#startTime = timestamp; + /* + if (this.#currentIdx !== undefined) { + const fraction: number = this.#currentIdx / this.#count; + if (fraction >= 1) // TODO? + return; + const passedTime: number = fraction * this._durationMillis; + this.#startTime = this.#startTime - passedTime; + }*/ + if (this.#passedTime !== undefined && this.#indices !== undefined) { + const fraction: number = this.#passedTime / this.#timeDuration; + if (fraction >= 1) {// TODO? + this.pause(); + return; + } + const passedTime: number = fraction * this._durationMillis; + this.#startTime = this.#startTime - passedTime; + } + } else if (this.#previousTime === timestamp) { + this.start(frames); + return; + } + this.#previousTime = timestamp; + const passed: number = timestamp - this.#startTime; + if (passed > this._durationMillis) { + this.pause(); + //this.#currentIdx = undefined; + this.#passedTime = undefined; + this.#indices = undefined; + this._stateListener.stateChanged(SimulationState.DONE); + return + } + const fraction: number = passed / this._durationMillis; + //const idx: number = Math.min(Math.floor(fraction * this.#count), this.#count - 1); + const time: number = fraction * this.#timeDuration; + const indices: Array = this._getIndices(time); + if (frames === 1 || !this.#indices || indices.findIndex((v, idx) => v !== this.#indices[idx]) >= 0) { + /* if (idx !== this.#currentIdx || frames === 1) { + this.#currentIdx = idx; + const slice: Timeslice = this._result.waveFunction[idx]; + this._listener.next(slice); + this._stateListener.onProgress(fraction); + */ + this.#indices = indices; + this.#passedTime = time; + const slices: Array<[Timeslice, Timeslice|undefined]> = this._qmResults.map((r, idx) => [r.waveFunction[indices[idx]], r.waveFunctionTilde ? r.waveFunctionTilde[indices[idx]] : undefined]); + const points: Array = this._classicalResults.map((r, idx) => r.points[indices[idx + this.#numQmStates]]); + this._listener.next(slices, points, this.#hasTildePotentials ? this._qmResults.map((r, idx) => r.potential ? r.potential[indices[idx]] : undefined) : undefined); + this._stateListener.onProgress(fraction); + } + const newFrames: number|undefined = frames ? frames - 1 : undefined; + if (!(newFrames <= 0)) + this.start(newFrames); + else + this.#startTime = undefined; + // TODO else we need to reinitialized the start time somehow, resp. rememeber the fraction passed already + // also applies to the pause function + } + + + constructor( + private readonly _qmResults: Array, + private readonly _classicalResults: Array, + private readonly _durationMillis: number, + private readonly _listener: SimulationListener, + private readonly _stateListener: SimulationStateListener + ) { + //this.#count = this._result.timesteps.length; + const deltaTTimestamps: Array<[number, number]> = [..._qmResults, ..._classicalResults].map(r => [r.settings.deltaT || 1, Math.max(1, r.timesteps.length-1)]); + this.#deltaT = Math.min(...deltaTTimestamps.map(arr => arr[0])); + this.#steps = Math.max(...deltaTTimestamps.map(a => a[1])); + //this.#count = Math.round(Math.max(..._results.map(r => r.settings.deltaT / deltaT * r.timesteps.length))); + this.#timeDuration = Math.max(...deltaTTimestamps.map(arr => arr[0] * arr[1])); + this.#numQmStates = _qmResults.length; + this.#hasTildePotentials = this._qmResults.findIndex(r => r.potential) >= 0; + } + + + start(frames?: number) { + window.cancelAnimationFrame(this.#timer); // avoid multiple concurrent runs + this.#timer = window.requestAnimationFrame(timestamp => this.#callback(timestamp, frames)); + } + + // note: frames parameter may be positive or negative + advance(frames?: number) { + if (frames === 0) + return; + frames = frames || 1; + const passedTime: number = this.#passedTime !== undefined ? this.#passedTime : 0; + let newPassedTime: number = passedTime + frames * this.#deltaT; + if (newPassedTime < 0) + newPassedTime = 0; + else if (newPassedTime > this.#timeDuration) { + newPassedTime = this.#timeDuration; + this.#startTime = undefined; // stop simulation if it is running + this.#previousTime = undefined; + } + const actualDeltaFraction: number = (newPassedTime - passedTime) / this.#timeDuration; + if (this.#startTime !== undefined) { // case already running + const realTimeDelta: number = actualDeltaFraction * this._durationMillis; + this.#startTime = this.#startTime - realTimeDelta; + } else if (newPassedTime > 0) { // case not running + this.#passedTime = newPassedTime; + this.#indices = this._getIndices(this.#passedTime); + this.start(1); + } + } + + pause() { + window.cancelAnimationFrame(this.#timer); + this.#startTime = undefined; + this.#previousTime = undefined; + // keep passedTime and indices! + } + + reset(fraction?: number) { + if (isFinite(fraction) && fraction >= 0 && fraction <= 1) { + // must not set to max index, otherwise we might not get any further callbacks // XXX ? + //this.#currentIdx = Math.min(Math.floor(fraction * this.#count), this.#count - 2); + const time: number = fraction * this.#timeDuration; + const indices: Array = this._getIndices(time); + this.#indices = indices; + this.#passedTime = time; + if (this.#startTime !== undefined) { // case: is running; just change the parameters + this.#startTime = undefined; + this.#previousTime = undefined; + } else { // case: not running + this.start(1); + } + return; + } + this.pause(); + this.#timer = undefined; + this.#indices = undefined; + this.#passedTime = undefined; + this.start(1); + } + + steps(): number { + return this.#steps; + } + + getFrameIndices(): {passedTime: number, frameIndices: Record} { + return { + passedTime: this.#passedTime, + frameIndices: this.#indices !== undefined ? + Object.fromEntries([...this._qmResults, ...this._classicalResults].map((run, idx) => [ + run.id, this.#indices[idx] + ])) : undefined + }; + } + + private _getIndices(time: number): Array { + return [...this._qmResults, ...this._classicalResults].map(r => { + const larger: number = r.timesteps.findIndex(step => step > time); + const previous: number = larger > 0 ? larger-1 : larger === 0 ? larger : r.timesteps.length-1; + return previous; + }); + } + +} \ No newline at end of file diff --git a/viz/src/SimulationControls.ts b/viz/src/SimulationControls.ts new file mode 100644 index 0000000..7146bde --- /dev/null +++ b/viz/src/SimulationControls.ts @@ -0,0 +1,146 @@ +import { SimulationController } from "./SimulationController"; +import { SimulationState, SimulationStateListener } from "./types"; + +export class SimulationControls implements SimulationStateListener { + + private static readonly PLAY_SOURCE: string = "assets/icons/play_arrow_black_24dp.svg"; + private static readonly PAUSE_SOURCE: string = "assets/icons/pause_black_24dp.svg"; + private static readonly CLASS_DISABLED: string = "control-icon-disabled"; + + readonly #play: HTMLImageElement; + readonly #stop: HTMLImageElement; + readonly #progress: HTMLProgressElement; + readonly #duration: HTMLInputElement; + readonly #titles: Map; + + #state: SimulationState = SimulationState.UNSET; + + constructor(controller: SimulationController) { + this.#play = document.querySelector("#simPlay>img"); + this.#stop = document.querySelector("#simStop>img"); + this.#progress = document.querySelector("#simProgress>progress"); + this.#duration = document.querySelector("#simDuration"); + this.#titles = new Map([ + [this.#play as HTMLElement, "Run simulation"], + [this.#stop as HTMLElement, "Stop simulation"], + [this.#progress as HTMLElement, "Jump to position"] + ]); + this.#duration.valueAsNumber = Math.max(1, Math.round(controller.getDuration()/1000)); + this.#duration.addEventListener("change", event => { + const durationSeconds: number = (event.currentTarget as HTMLInputElement).valueAsNumber; + if (!durationSeconds) + return; + controller.setDuration(durationSeconds * 1000); + }); + this.#progress.addEventListener("click", event => { + switch (this.#state) { + case SimulationState.UNSET: + return; + case SimulationState.INITIALIZED: + case SimulationState.PAUSED: + case SimulationState.DONE: + case SimulationState.RUNNING: + const el: HTMLElement = event.currentTarget as HTMLElement; + const fraction: number = (event.clientX - el.offsetLeft) / el.clientWidth; // TODO validate + controller.reset(fraction); + break; + } + }); + this.#play.addEventListener("click", () => { + switch (this.#state) { + case SimulationState.UNSET: + return; + case SimulationState.INITIALIZED: + case SimulationState.PAUSED: + case SimulationState.DONE: + controller.start(); + break; + case SimulationState.RUNNING: + controller.pause(); + break; + } + }); + this.#stop.addEventListener("click", () => { + switch (this.#state) { + case SimulationState.UNSET: + return; + case SimulationState.INITIALIZED: + case SimulationState.PAUSED: + case SimulationState.RUNNING: + case SimulationState.DONE: + controller.reset(); + break; + } + }); + document.addEventListener("keydown", event => { + let leftOrRight: boolean; + switch (event.key) { + case "ArrowRight": + leftOrRight = false; + break; + case "ArrowLeft": + leftOrRight = true; + break; + default: + return; + } + event.preventDefault(); + const frames: number = controller.steps() > 1000 ? 10 : 1; + switch (this.#state) { + case SimulationState.UNSET: + return; + default: + controller.advance(leftOrRight ? -frames : frames); + } + }); + } + + stateChanged(simulationState: SimulationState): void { + this.#state = simulationState; + switch(simulationState) { + case SimulationState.INITIALIZED: // fallthrough + case SimulationState.PAUSED: + case SimulationState.DONE: + this.#play.src = SimulationControls.PLAY_SOURCE; + this._enable(this.#play); + this._enable(this.#progress); + if (simulationState === SimulationState.PAUSED || simulationState == SimulationState.DONE) + this._enable(this.#stop); + else + this._disable(this.#stop); + break; + case SimulationState.RUNNING: + this.#play.src = SimulationControls.PAUSE_SOURCE; + this._enable(this.#play, "Pause simulation"); + this._enable(this.#stop); + this._enable(this.#progress); + break; + case SimulationState.UNSET: + this.#play.src = SimulationControls.PLAY_SOURCE; + this._disable(this.#play); + this._disable(this.#stop); + this._disable(this.#progress); + break; + default: + console.log("Unexpected simulation state", simulationState); + } + } + + onProgress(fraction: number): void { + this.#progress.value = fraction * 100; + } + + private _enable(element: HTMLElement, title?: string) { + if (title === undefined) + title = this.#titles.get(element) || ""; + element.classList.remove(SimulationControls.CLASS_DISABLED); + element.title = title; + } + + private _disable(element: HTMLElement) { + element.classList.add(SimulationControls.CLASS_DISABLED); + element.title = ""; + } + + +} diff --git a/viz/src/SimulationUtils.ts b/viz/src/SimulationUtils.ts new file mode 100644 index 0000000..f4f8131 --- /dev/null +++ b/viz/src/SimulationUtils.ts @@ -0,0 +1,408 @@ +import { ClassicalSettings, ClassicalSimulationResult, ExpectationValues, Point, QuantumSettings, QuantumSimulationResult, Timeslice } from "./types.js"; + +export class SimulationUtils { + + private static nextRow(str: string, start: number, minExpectedEntries?: number): [Array, number]|null { + minExpectedEntries = minExpectedEntries||1; + const l: number = str.length; + if (start >= l) + return null; + const nextLineBreak: number = str.indexOf("\n", start); + if (nextLineBreak < 0) { + const arr: Array = str.substring(start).split(","); + if (arr.length < minExpectedEntries || arr.length === 1 && arr[0].trim() === "") + return null; + return [arr.map(e => e.trim()), l]; + } else if (nextLineBreak === start) { + return SimulationUtils.nextRow(str, start + 1, minExpectedEntries); + } + const arr: Array = str.substring(start, nextLineBreak).split(",").map(e => e.trim()); + if (arr.length < minExpectedEntries) + return SimulationUtils.nextRow(str, nextLineBreak + 1, minExpectedEntries) + return [arr, nextLineBreak+1]; + } + + // TODO progress bar + static async parseClassicalFiles(id: string, points: File, settings: File): Promise { + const pointsPromise: Promise> = new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = (event: ProgressEvent) => { + const result: string = event.target.result as string; + const header: [Array, number]|null = SimulationUtils.nextRow(result, 0, 2); + if (!header) { + reject(new Error("Wave function file does not contain any data")); + return; + } + const x: number = header[0].indexOf("x"); + const p: number = header[0].indexOf("p"); + const E: number = header[0].indexOf("E"); + if (x < 0 || p<0 ) { + reject(new Error("Points file does not provide all required observables; header: " + JSON.stringify(header[1]))); + return; + } + const points0: Array = []; + let start: number = header[1]; + while (true) { + const line0: [Array, number]|null = SimulationUtils.nextRow(result, start, 2); + if (!line0) + break; + start = line0[1]; + const line: Array = line0[0]; + const point: Point = { + x: parseFloat(line[x]), + p: parseFloat(line[p]) + } + if (E >= 0) + point.E = parseFloat(line[E]); + points0.push(point); + } + resolve(points0); + }; + reader.onerror = reject; + reader.readAsText(points, "UTF-8"); + }); + const settingsPromise: Promise = new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = (event: ProgressEvent) => { + const result: string = event.target.result as string; + try { + resolve(JSON.parse(result)); + } catch (e) { + reject(e); + } + }; + reader.onerror = reject; + reader.readAsText(settings, "UTF-8"); + }); + const result = await Promise.all([pointsPromise, settingsPromise]); + const pointsResult: Array = result[0]; + const settings2: ClassicalSettings = result[1]; + return { + id: id, + points: pointsResult, + settings: settings2, + timesteps: pointsResult.map((_, idx) => idx * settings2.deltaT), + }; + } + + private static _parseWaveFunctionFile(file: File, progressReporter: ProgressReporter, options?: {headerPrefix?: string}): Promise<[Array, Array>]|undefined> { + if (!file) + return Promise.resolve(undefined); + const headerPrefix: string = (options?.headerPrefix || "Psi") + "("; + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = (event: ProgressEvent) => { + const result: string = event.target.result as string; + // expect entries of the form Psi(x0), Psi(x1), ..., Psi(xk) + const header: [Array, number]|null = SimulationUtils.nextRow(result, 0, 2); + if (!header) { + reject(new Error("Wave function file does not contain any data")); + return; + } + const xs: Array = header[0] + .filter(head => head.startsWith(headerPrefix)) + .map(head => parseFloat(head.substring(headerPrefix.length, head.length-1))); + if (xs.findIndex(x => !isFinite(x)) >= 0) { + reject(new Error("Invalid x value " + xs.find(x => !isFinite(x)))); + return; + } + const unsorted: number|undefined = xs.find((x, idx) => idx > 0 && x <= xs[idx-1]); + if (unsorted !== undefined) { + reject(new Error(headerPrefix + " not sorted")); + return; + } + const psindices: Array = header[0] + .map((head, idx) => [idx, head.startsWith(headerPrefix)]) + .filter(arr => arr[1]) + .map(arr => arr[0] as number) + const maxIdx: number = Math.max(...psindices); + let start: number = header[1]; + const psi: Array> = []; // outer array: timesteps, middle array: x values; inner array: real + imaginary part + const lastPlusMinusSeparator = (s: string, separator: "+"|"-"): number => { + let start: number|undefined = undefined; + while (start === undefined || start >= 0) { + const idx: number = s.lastIndexOf(separator, start); + if (idx <= /* sic */ 0) + return -1; + if (s.charAt(idx - 1) !== "e") + return idx; + start = idx - 1; + } + }; + const parseRealImaginary = (entry: string): [number, number]|null => { + entry = entry.replace(/\s/g, ""); + const l: number = entry.length; + if (l === 0) + return null; + const idxPlus: number = lastPlusMinusSeparator(entry, "+"); + const idx: number = idxPlus > /* sic! */ 0 ? idxPlus : lastPlusMinusSeparator(entry, "-"); + if (idx <= 0) { // only a single entry present + const isReal: boolean = entry.indexOf("i") < 0; + const num: number = parseFloat(entry); + if (!isFinite(num)) + return null + return isReal ? [num, 0] : [0, num]; + } + const iIdx: number = entry.lastIndexOf("i"); + if (iIdx < 0) + return null; + const secondIsImaginary: boolean = iIdx > idx; + const realPart = secondIsImaginary ? entry.substring(0, idx) : entry.substring(idx); + const imagPart = secondIsImaginary ? entry.substring(idx) : entry.substring(0, idx); + const real: number = parseFloat(realPart); + let imag: number = parseFloat(imagPart); + if (!isFinite(imag)) { + if (imagPart === "+i" || imagPart === "i") + imag = 1; + else if (imagPart === "-i") + imag = -1; + } + if (!isFinite(real) || !isFinite(imag)) + return null; + return [real, imag]; + }; + while (true) { + const line0: [Array, number]|null = SimulationUtils.nextRow(result, start, maxIdx + 1); + if (!line0) + break; + start = line0[1]; + const line: Array = line0[0]; + const values: Array<[number, number]|null> = psindices.map(idx => parseRealImaginary(line[idx])); + const invalidIdx: number = values.findIndex(v => !v); + if (invalidIdx >= 0) { + reject("Wave function contains invalid value " + line[invalidIdx] + " at index " + invalidIdx + ": " + line); + return; + } + psi.push(values); + } + resolve([xs, psi]); + }; + const task: StatusSink = progressReporter.add(); + reader.onerror = (event: ProgressEvent) => { + reject(event.target?.error || event); + task.errored(); + }; + reader.onprogress = (event: ProgressEvent) => { + if (event.lengthComputable) + task.progress(event.loaded, event.total); + }; + reader.readAsText(file, "UTF-8"); + }); + } + + private static _parseObservablesFile(file: File, progressReporter: ProgressReporter): Promise|undefined> { + if (!file) + return Promise.resolve(undefined); + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = (event: ProgressEvent) => { + const result: string = event.target.result as string; + const header: [Array, number]|null = SimulationUtils.nextRow(result, 0, 2); + if (!header) { + reject(new Error("Wave function file does not contain any data")); + return; + } + const x: number = header[0].indexOf("x"); + const p: number = header[0].indexOf("p"); + const x2: number = header[0].indexOf("x^2"); + const p2: number = header[0].indexOf("p^2"); + const E: number = header[0].indexOf("E"); + if (x < 0 || p<0 || x2 < 0 || p2< 0) { + reject(new Error("Observables file does not provide all required observables; header: " + JSON.stringify(header[1]))); + return; + } + const exp: Array = []; + let start: number = header[1]; + while (true) { + const line0: [Array, number]|null = SimulationUtils.nextRow(result, start, 4); + if (!line0) + break; + start = line0[1]; + const line: Array = line0[0]; + const e: ExpectationValues = { + x: parseFloat(line[x]), + p: parseFloat(line[p]), + x2: parseFloat(line[x2]), + p2: parseFloat(line[p2]), + E: E >= 0 ? parseFloat(line[E]) || 1 : 1 // FIXME no default value + } + exp.push(e); + } + resolve(exp); + }; + const task: StatusSink = progressReporter.add(); + reader.onerror = e => { + reject(e); + task.errored(); + }; + reader.onprogress = (event: ProgressEvent) => { + if (event.lengthComputable) + task.progress(event.loaded, event.total); + }; + reader.readAsText(file, "UTF-8"); + }); + } + + static async parseQmFiles(id: string, waveFunction: File, observables: File, settings: File, + psiTilde?: File, observablesQm?: File, potential?: File): Promise { + const reporter: ProgressReporter = new ProgressReporter(); + reporter.start(); + try { + return await SimulationUtils.parseQmFiles0(id, reporter, waveFunction, observables, settings, psiTilde, observablesQm, potential); + } finally { + reporter.end(); + } + } + + private static async parseQmFiles0(id: string, reporter: ProgressReporter, waveFunction: File, observables: File, settings: File, + psiTilde?: File, observablesQm?: File, potential?: File): Promise { + const waveFunctionPromise: Promise<[Array, Array>]> = SimulationUtils._parseWaveFunctionFile(waveFunction, reporter); + const observablesPromise: Promise> = SimulationUtils._parseObservablesFile(observables, reporter); + const settingsPromise: Promise = new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = (event: ProgressEvent) => { + const result: string = event.target.result as string; + try { + resolve(JSON.parse(result)); + } catch (e) { + reject(e); + } + }; + reader.onerror = reject; + reader.readAsText(settings, "UTF-8"); + }); + const psiTildePromise: Promise<[Array, Array>]|undefined> = SimulationUtils._parseWaveFunctionFile(psiTilde, reporter); + const observablesQmPromise: Promise|undefined> = SimulationUtils._parseObservablesFile(observablesQm, reporter); + const potentialPromise: Promise<[Array, Array>]> = SimulationUtils._parseWaveFunctionFile(potential, reporter, {headerPrefix: "V"}); + const result = await Promise.all([waveFunctionPromise, observablesPromise, settingsPromise, psiTildePromise, observablesQmPromise, potentialPromise]); + const x = result[0][0]; + const psi = result[0][1]; + const observables2 = result[1]; + const settings2: QuantumSettings = result[2]; + const waveFct: Array = psi.map((values: Array<[number, number]>, idx: number) => { + const slice: Timeslice = { + x: x, + waveFunction: values, + observables: observables2[idx], // TODO + settings: settings2 + }; + return slice; + }); + let waveFctTilde: Array|undefined = undefined; + let obsQm: Array|undefined = undefined; + // outer index: time, inner index: x + let potential2: Array>|undefined = undefined; + if (result[3] && result[4]) { + const x2 = result[3][0]; + const psiTilde = result[3][1]; + obsQm = result[4]; + waveFctTilde = psiTilde.map((values: Array<[number, number]>, idx: number) => { + const slice: Timeslice = { + x: x2, + waveFunction: values, + observables: obsQm[idx], + settings: settings2 + }; + return slice; + }); + if (result[5]) { + // keep only real part + potential2 = result[5][1].map(timeslice => timeslice.map(complex => complex[0])); + } + } + /* + if (psi.length !== observables2.length) + throw new Error("Length of observables file does not match length of wave function (incompatible number of timesteps)"); + */ // TODO for now ignore observables + return { + id: id, + x: x, + timesteps: psi.map((_, idx) => idx * (settings2.deltaT || 1)), + waveFunction: waveFct, + observables: observables2, + settings: settings2, + waveFunctionTilde: waveFctTilde, + observablesTilde: obsQm, + potential: potential2 + }; + } + +} + +interface StatusSink { + progress(done: number, total: number): void; + errored(): void; +} +interface StatusSource { + isValid(): boolean; + status(): [number, number]|undefined; +} + +class ProgressReporter { + + readonly #element: HTMLElement; + readonly #progress: HTMLProgressElement; + readonly #allTasks: Array = []; + #timer: number|undefined; + #done: boolean = false; + + readonly #callback = () => { + if (this.#done) + return; + // [bytes done, bytes total] + const total: [number, number] = this.#allTasks + .filter(t => t.isValid()) + .map(t => t.status() as [number, number]) + .reduce((val, next) => { + val[0] = val[0] + next[0]; + val[1] = val[1] + next[1]; + return val; + }, [0, 0]); + const progress: number = total[1] > 0 ? total[0] / total[1] : 0; + this.#progress.value = progress * 100; + if (!(progress >= 1)) + this.start(); + }; + + constructor() { + this.#element = document.querySelector("#uploadProgress"); + this.#progress = this.#element.querySelector("progress"); + } + + add(): StatusSink { + const sink: StatusSinkImpl = new StatusSinkImpl(); + this.#allTasks.push(sink); + return sink; + } + + start() { + this.#element.hidden = false; + this.#timer = window.requestAnimationFrame(this.#callback.bind(this)); + } + + end() { + this.#done = true; + this.#element.hidden = true; /// ? + window.cancelAnimationFrame(this.#timer); + } + +} + +class StatusSinkImpl implements StatusSink, StatusSource { + #done: number; + #total: number; + progress(done: number, total: number): void { + this.#done = done; + this.#total = total; + } + errored() { + this.#total = undefined; + this.#done = undefined; + } + status(): [number, number]|undefined { + return this.#total !== undefined ? [this.#done, this.#total] : undefined; + } + isValid(): boolean { + return this.#total !== undefined; + } +} \ No newline at end of file diff --git a/viz/src/colorPalette.ts b/viz/src/colorPalette.ts new file mode 100644 index 0000000..fb28a5a --- /dev/null +++ b/viz/src/colorPalette.ts @@ -0,0 +1,21 @@ +export class ColorPalette { + + + + private static readonly COLORS: Array<[string, string, string]> = [ + ["#DA1E37", "#BB3E03", "#EE9B00"], // red, brownish + ["#1E88E5", "#003459", "#007EA7"], // blueish + ["#FF9E00", "#FF7700", "#FF5500"] // orange + + ]; + private static readonly NUM_COLORS: number = ColorPalette.COLORS.length; + + public static getColor(primaryIndex: number, secondaryIndex?: number): string { + if (secondaryIndex === undefined) + secondaryIndex = 0; + primaryIndex = primaryIndex % ColorPalette.NUM_COLORS; + secondaryIndex = secondaryIndex % 3; + return ColorPalette.COLORS[primaryIndex][secondaryIndex]; + } + +} \ No newline at end of file diff --git a/viz/src/datasetsGrid.ts b/viz/src/datasetsGrid.ts new file mode 100644 index 0000000..a8b42d7 --- /dev/null +++ b/viz/src/datasetsGrid.ts @@ -0,0 +1,44 @@ +import { JsUtils } from "./JsUtils.js"; +import { ClassicalSimulationResult, QuantumSimulationResult, TypesUtils } from "./types.js"; + +/** + * List of datasets shown in menu + */ +export class DatasetsGrid { + + readonly #element: HTMLElement + + constructor() { + this.#element = document.querySelector("#datasetsGrid"); + } + + addResultDataset(result: QuantumSimulationResult|ClassicalSimulationResult) { + const isQuantum: boolean = !!(result as QuantumSimulationResult).waveFunction; + const frag: DocumentFragment = document.createDocumentFragment(); + JsUtils.createElement("div", {text: result.id, parent: frag, dataset: new Map([["id", result.id]])}); + const container: HTMLElement = JsUtils.createElement("div", {parent: frag, dataset: new Map([["id", result.id]]), classes: ["dataset-container"]}); + const list = JsUtils.createElement("ul", {parent: container}); + JsUtils.createElement("li", {text: "Potential: " + TypesUtils.printPotential(result.settings), parent: list}); + JsUtils.createElement("li", {text: "Type: " + (result.settings.type ? result.settings.type : isQuantum ? "qm" : "classical"), parent: list}); + //@ts-ignore + JsUtils.createElement("li", {text: "Scheme: " + result.settings.scheme.id, parent: list}); + if (isQuantum) + JsUtils.createElement("li", {html: "ℏ = " + (result as QuantumSimulationResult).settings.hbar, parent: list}); + JsUtils.createElement("li", {html: "Δt = " + result.settings.deltaT?.toPrecision(2), parent: list}); + const timesteps: number = isQuantum ? (result as QuantumSimulationResult).waveFunction.length : (result as ClassicalSimulationResult).points.length; + JsUtils.createElement("li", {text: "time steps = " + timesteps, parent: list}); + JsUtils.createElement("li", {text: "T = " + (result.settings.deltaT * timesteps).toPrecision(4), parent: list}); + if (isQuantum) { + const r = result as QuantumSimulationResult; + JsUtils.createElement("li", {html: "Δx = " + r.settings.deltaX?.toPrecision(2) || "?", parent: list}); + JsUtils.createElement("li", {text: "grid points = " + r.x.length, parent: list}); + JsUtils.createElement("li", {text: "x_range = [" + r.x[0].toPrecision(2) + " - " + r.x[r.x.length-1].toPrecision(2) + "]", parent: list}); + } + this.#element.appendChild(frag); + } + + removeResultDataset(id: string) { + this.#element.querySelectorAll("[data-id='"+ id + "']").forEach(el => el.remove()); + } + +} \ No newline at end of file diff --git a/viz/src/differencePlot.ts b/viz/src/differencePlot.ts new file mode 100644 index 0000000..200aab0 --- /dev/null +++ b/viz/src/differencePlot.ts @@ -0,0 +1,202 @@ +import uPlot, { AlignedData, Options, Series } from "uplot"; +import "../node_modules/uplot/dist/uPlot.min.css"; +import { ColorPalette } from "./colorPalette"; +import { JsUtils } from "./JsUtils.js"; +import { SimulationListener, QuantumSimulationResult, Timeslice } from "./types.js"; + +export class DifferencePlot implements SimulationListener { + + + #element: HTMLElement; + #chart: uPlot; + #activeIds: Array = []; + #yRange: number = 2; + + constructor() { + this.#element = document.querySelector("#waveFunctionDifferences"); + } + + build() { + if (this.#chart) + return; + const width: number = this.#element.getBoundingClientRect().width || 800; // FIXME? + const height: number = /*this.#element.getBoundingClientRect().height ||*/ 600; + const options: Options = { + width: width, + height: height, + title: "Difference", + cursor: {drag: { x: true, y: true, uni: 50 } }, // FIXME?= + scales: { + x: { time: false }, + 1: { range: (self, min, max) => [0, this.#yRange]} + }, + series: [{label: "t"}, {label: "Test"}], + axes: [{}, { + scale: "1", + //values: (self, ticks) => ticks.map(rawValue => rawValue.toFixed(1) + "%"), + }, + /* + { + scale: "E", + //values: (self, ticks) => ticks.map(rawValue => rawValue.toFixed(2) + "MB"), + side: 1, + grid: {show: false}, + }*/] + }; + const data: AlignedData = [ + [], [] + ] as any; + this.#chart = new uPlot(options, data, this.#element); + // for debugging + (window as any).sch = (window as any).sch || {}; + (window as any).sch.diffChart = this.#chart; + } + + initialize(results: Array): void { + const ids: Array = results.map(r => r.id); + if (ids.length === 0) { + this.clear(); + return; + } + if (ids.length <= 1) { + this.clear(); + return; + } + this.build(); // TODO + if (this.#activeIds.length === ids.length && !ids.find(id => this.#activeIds.indexOf(id) < 0)) + return; + // remove old series + const s: number = this.#chart.series.length; + for (let idx=s-1; idx > 0; idx--) { + this.#chart.delSeries(idx); + } + const l: number = ids.length; + // TODO timestamps + const timestampsMerged: [Array, boolean] = JsUtils.mergeArrays(results.map(r => r.timesteps)); + const timestamps: Array = timestampsMerged[0]; + const timestampsEqual: boolean = timestampsMerged[1]; + const data: AlignedData = [timestamps]; + for (let idx=0; idx < l/2 + 1; idx++) { + const id: string = ids[idx]; + for (let idx2=idx+1; idx2 < l; idx2++) { + const id2: string = ids[idx2]; + const series: Series = { + label: "||Psi_" + id + " - Psi_" + id2 + "||_2", + //fill // TODO color + show: true, + spanGaps: false, + //value: (self, rawValue) => "$" + rawValue.toFixed(2), + + // series style + points: { show: true, size: 2, fill: "blue"}, + stroke: ColorPalette.getColor(idx + idx2 - 1, 0), + width: 1, + scale: "1" + //fill: "rgba(0, 255, 0, 0.1)", // TODO configurable + //dash: [10, 5], + }; + this.#chart.addSeries(series); + data.push(DifferencePlot.getDifference(results[idx], results[idx2], timestamps, timestampsEqual)); + } + } + this.#activeIds = ids; + this.#yRange = Math.max(1, ...data.filter((_, idx) => idx > 0).map(arr => Math.max(0, ...arr.filter(v => v)))); + this.#chart.setData(data); + } + + scale(scale: number): void { + // void + } + + // TODO + next(slices: Array<[Timeslice, Timeslice|undefined]>): void { + if (!(slices?.length > 0)) + return; + } + + setWidth(width: number): void { + this.#chart?.setSize({width: width, height: this.#chart?.height}); + } + + clear(): void { + if (!this.#chart) + return; + // remove old series + const s: number = this.#chart.series.length; + for (let idx=s-1; idx > 0; idx--) { + this.#chart.delSeries(idx); + } + this.#chart.addSeries({label: "Test"}); + this.#chart?.setData([[], []]); + this.#activeIds = []; + } + + /** + * Get the norm difference between two wave functions for all common timestamps + * @param r1 + * @param r2 + * @param timestamps + * @param timestampsEqual + */ + private static getDifference(r1: QuantumSimulationResult, r2: QuantumSimulationResult, timestamps: Array, timestampsEqual: boolean): Array { + return timestamps.map((t, idx) => { + const idx1: number = timestampsEqual ? idx : r1.timesteps.indexOf(t); + const idx2: number = timestampsEqual ? idx : r2.timesteps.indexOf(t); + if (idx1 < 0 || idx2 < 0) + return NaN; + const psi1: Timeslice = r1.waveFunction[idx1]; + const psi2: Timeslice = r2.waveFunction[idx2]; + return DifferencePlot.normDiff(psi1, psi2); + }); + } + + private static normDiff(psi1: Timeslice, psi2: Timeslice): number { + const l1: number = psi1.x.length; + const l2: number = psi2.x.length; + const xsEqual: boolean = l1 === l2 && psi1.x[0] === psi2.x[0] && + psi1.x[l1-1] === psi2.x[l2-1]; + const square = (v1: [number, number], v2: [number, number]): number => (v1[0] - v2[0]) * (v1[0] - v2[0]) + (v1[1] - v2[1]) * (v1[1] - v2[1]); + if (xsEqual) { + let diff: number = 0; + for (let idx=0; idx= l1) { + diff += square([0, 0], psi2.waveFunction[idx2]); + idx2++; + continue; + } else if (idx2 >= l2) { + diff += square([0, 0], psi1.waveFunction[idx1]); + idx1++; + continue; + } + const nextX1: number = psi1.x[idx1]; + const nextX2: number = psi2.x[idx2]; + if (nextX1 === nextX2) { + diff += square(psi1.waveFunction[idx1], psi2.waveFunction[idx2]); + idx1++; + idx2++; + } else if (nextX1 < nextX2) { + const v2: [number, number] = idx2 === 0 ? [0, 0] : psi2.waveFunction[idx2]; + diff += square(psi1.waveFunction[idx1], v2); + idx1++; + } else { + const v1: [number, number] = idx1 === 0 ? [0, 0] : psi1.waveFunction[idx1]; + diff += square(v1, psi2.waveFunction[idx2]); + idx2++; + } + } + return Math.sqrt(diff); + } + + +} \ No newline at end of file diff --git a/viz/src/index.ts b/viz/src/index.ts new file mode 100644 index 0000000..728b7ab --- /dev/null +++ b/viz/src/index.ts @@ -0,0 +1,112 @@ +import { PlotsController } from "./PlotsController.js"; +import { SimulationController } from "./SimulationController.js"; +import { SimulationControls } from "./SimulationControls.js"; +import { SimulationUtils } from "./SimulationUtils.js"; +import { SimulationListener, QuantumSimulationResult, SimulationStateListener } from "./types.js"; + + +export class Main { + + readonly #simulationListeners: Array = []; + readonly #simulationStateListeners: Array = []; + readonly #simulationController: SimulationController; + readonly #plotsController: PlotsController; + readonly #simulationControls: SimulationControls; + + //#activeResults: SimulationResult|null = null; + #uploadRunning: boolean = false; + + constructor() { + this.#simulationController = new SimulationController(this.#simulationListeners, this.#simulationStateListeners); + this.#simulationControls = new SimulationControls(this.#simulationController); + this.#simulationStateListeners.push(this.#simulationControls); + this.#plotsController = new PlotsController(this.#simulationListeners); + const fileSelector: HTMLInputElement = document.querySelector("#fileSelector"); + const fileUpload: HTMLInputElement = document.querySelector("#fileUpload"); + const enableFileUpload = (enable: boolean) => { + fileUpload.disabled = !enable; + fileUpload.title = enable ? "Start upload" : "Select files first"; + }; + const hideShowMenu = (show?: boolean) => { + const menu: HTMLElement = document.querySelector("#menu"); + const viz: HTMLElement = document.querySelector("#viz"); + const hideMenu: HTMLElement = document.querySelector("#menuClose"); + const showMenu: HTMLElement = document.querySelector("#menuShow"); + if (show === undefined) + show = menu.hidden; + menu.hidden = !show; + hideMenu.hidden = !show; + showMenu.hidden = show; + const margin: number = show ? 350 : 0; + //viz.style.marginLeft = margin + "px"; + if (show) + viz.classList.add("menu-margin"); + else + viz.classList.remove("menu-margin"); + this.#plotsController.setMargin(margin); + }; + document.querySelector("#menuClose").addEventListener("click", () => hideShowMenu(false)); + document.querySelector("#menuShow").addEventListener("click", () => hideShowMenu(true)); + fileSelector.addEventListener("change", () => enableFileUpload(fileSelector.files.length > 0)); + fileUpload.addEventListener("click", async () => { + if (this.#uploadRunning) + return; + const files: Array = Array.from(fileSelector.files) + .filter(fl => fl.name.toLowerCase().endsWith(".csv") || fl.name.toLowerCase().endsWith(".json")); + if (files.length === 0) + return; + const psi: File|undefined = files.find(fl => fl.name.toLowerCase() === "psi.csv"); + const observables: File|undefined = files.find(fl => fl.name.toLowerCase() === "observables.csv"); + const settings: File|undefined = files.find(fl => fl.name.toLowerCase() === "settings.json"); + const points: File|undefined = files.find(fl => fl.name.toLowerCase() === "points.csv"); + // the three below are present for calculations in the Hamiltonian gauge only, besides all the other files + const psiTilde: File|undefined = files.find(fl => fl.name.toLowerCase() === "psitilde.csv"); + const potential: File|undefined = files.find(fl => fl.name.toLowerCase() === "v_t.csv"); + const observablesQm: File|undefined = files.find(fl => fl.name.toLowerCase() === "observables.csv"); + const isQuantum: boolean = !!psi && !!observables; + const isClassical: boolean = !!points; + if ((!isQuantum && !isClassical) || !settings) { + console.log("Files missing"); + return; + } + const id: string = (document.querySelector("#uploadDataset") as HTMLInputElement).value; + if (!id) { + console.log("Id not set"); + return; + } + this.#uploadRunning = true; + try { + const resultsQm = isQuantum ? await SimulationUtils.parseQmFiles(id, psi, observables, settings, psiTilde, observablesQm, potential) : undefined; + const resultsClassical = isClassical ? await SimulationUtils.parseClassicalFiles(id, points, settings) : undefined; + const results = isQuantum && isClassical ? {...resultsQm, classicalTrajectory: resultsClassical} : isQuantum ? resultsQm : resultsClassical; + this.#simulationController.addResultSet(results); + hideShowMenu(false); + } catch(e) { + //this.#activeResults = null; + //this.#simulationController.addResultSet(null); + console.log("Failed to upload results", e); + } finally { + this.#uploadRunning = false; + } + + }); + fileSelector.dispatchEvent(new Event("change")); + + // for debugging + (window as any).sch = (window as any).sch || {}; + Object.assign((window as any).sch, { + results: () => this.#simulationController.getResultSets(), + menu: () => hideShowMenu(), + start: () => this.#simulationController.start(), + pause: () => this.#simulationController.pause(), + reset: (fraction?: number) => this.#simulationController.reset(fraction), + advance: (frames: number) => this.#simulationController.advance(frames), + getFrameIndices: () => this.#simulationController.getFrameIndices() + }); + } + + run() {} + +} + +new Main().run(); diff --git a/viz/src/phaseSpace.ts b/viz/src/phaseSpace.ts new file mode 100644 index 0000000..4ebd9d3 --- /dev/null +++ b/viz/src/phaseSpace.ts @@ -0,0 +1,318 @@ +import { ColorPalette } from "./colorPalette.js"; +import { JsUtils } from "./JsUtils.js"; +import { SimulationListener, QuantumSimulationResult, Timeslice, ClassicalSimulationResult, Point } from "./types"; + +/** + * Plots p over x, or E over x + */ +export class PhaseSpace implements SimulationListener { + + private static readonly WIDTH: number = 500; + private static readonly HEIGHT: number = 500; + private static readonly WIDTH_OFFSET: number = 50; + private static readonly HEIGHT_OFFSET: number = 50; + private static readonly TICKS: number = 5; + + #element: HTMLElement; // div + #container: HTMLElement; + #canvas: HTMLCanvasElement; + #legendGrid: HTMLElement; + readonly #currentPoints: Array = []; // one point per dataset + #xRange: [number, number] = [0, 1]; + #pRange: [number, number] = [0, 1]; + #currentData: [Array, Array]|undefined; + #currentSlices: Array<[Timeslice, Timeslice|undefined]>|undefined; + #currentClassicalPoints: Array|undefined = undefined; + + #width: number = PhaseSpace.WIDTH; + #height: number = PhaseSpace.HEIGHT; + #ticks: number = PhaseSpace.TICKS; + #numDigitsX: number = 2; + #numDigitsY: number = 2; + + #activeIds: Array = []; + + constructor(private readonly energyOrMomentum?: boolean) { + this.#element = document.querySelector(energyOrMomentum ? "#energy" : "#observables"); + JsUtils.createElement("h3", {text: energyOrMomentum ? "Energy" : "Phase space", parent: this.#element}); + const container: HTMLElement = JsUtils.createElement("div", {parent: this.#element, classes: ["position-relative"]}); + //const flexContainer: HTMLElement = JsUtils.createElement("div", {parent: container, classes: ["phase-space-container", "position-absolute"]}); + const canvas = JsUtils.createElement("canvas", {parent: container /*, classes: ["position-absolute"] */}); + canvas.width = PhaseSpace.WIDTH + 2 * PhaseSpace.WIDTH_OFFSET; + canvas.height = PhaseSpace.HEIGHT + 2 * PhaseSpace.HEIGHT_OFFSET; + canvas.classList.add("observables-canvas"); + + const legend: HTMLElement = JsUtils.createElement("fieldset", { classes: ["phase-space-legend"]}); + this.#element.parentElement.insertBefore(legend, this.#element.nextElementSibling); + const legendTitle: HTMLElement = JsUtils.createElement("legend", {parent: legend, text: "Datasets"}); + const legendGrid: HTMLElement = JsUtils.createElement("div", {parent: legend, classes: ["legend-grid"]}); + this.#legendGrid = legendGrid; + + this.#canvas = canvas; + this.#container = container; + const coordinate: string = energyOrMomentum ? "E": "P"; + const setCoordinateRange = (range: [number, number]|undefined, xOrY: boolean) => { + if (!this.#currentData) + return; + if (range !== undefined && !Array.isArray(range)) { + console.log("Need an array of two values (min, max), got ", range); + return; + } + if (Array.isArray(range) && range.length !== 2) { + console.log("Need an array of two values (min, max), got ", range); + return; + } + const coordinate: "x"|"p" = xOrY ? "x" : "p"; + const otherCoordinate: "x"|"p" = xOrY ? "p" : "x"; + const otherRange: [number, number] = xOrY ? this.#pRange : this.#xRange; + this.initialize(this.#currentData[0], this.#currentData[1], true, {[coordinate]: range, [otherCoordinate]: otherRange}); + if (this.#currentSlices && this.#currentClassicalPoints) + this.next(this.#currentSlices, this.#currentClassicalPoints); + }; + // TODO need to reset points + const debug = { + setX: (xRange: [number, number]) => setCoordinateRange(xRange, true), + ["set" + coordinate]: (pRange: [number, number]) => setCoordinateRange(pRange, false), + reset: () => { + this.initialize(this.#currentData[0], this.#currentData[1], true); + if (this.#currentSlices && this.#currentClassicalPoints) + this.next(this.#currentSlices, this.#currentClassicalPoints); + }, + setSize: (size: {width?: number, height?: number, ticks?: number, numDigitsX?: number, numDigitsY?: number}) => { + this.#width = size.width || this.#width; + this.#height = size.height || this.#height; + this.#ticks = size.ticks || this.#ticks; + this.#numDigitsX = size.numDigitsX || this.#numDigitsX; + this.#numDigitsY = size.numDigitsY || this.#numDigitsY; + this.initialize(this.#currentData[0], this.#currentData[1], true); + if (this.#currentSlices && this.#currentClassicalPoints) + this.next(this.#currentSlices, this.#currentClassicalPoints); + } + }; + (window as any).sch = (window as any).sch || {}; + (window as any).sch[coordinate] = debug; + } + + private _drawAxes(ctx: CanvasRenderingContext2D) { + const startX: number = 0; + const endX: number = this.#width + 2 * PhaseSpace.WIDTH_OFFSET; + const usedStartX: number = PhaseSpace.WIDTH_OFFSET; + const usedEndX: number = this.#width + PhaseSpace.WIDTH_OFFSET; + const startY: number = this.#height + 2 * PhaseSpace.HEIGHT_OFFSET; + const endY: number = 0; + const usedStartY: number = this.#height + PhaseSpace.HEIGHT_OFFSET; + const usedEndY: number = PhaseSpace.HEIGHT_OFFSET; + ctx.strokeStyle = "black"; + // x axis + ctx.beginPath(); + ctx.moveTo(startX, this.#height + PhaseSpace.HEIGHT_OFFSET); + ctx.lineTo(endX, this.#height + PhaseSpace.HEIGHT_OFFSET); + // arrow + ctx.moveTo(endX, this.#height + PhaseSpace.HEIGHT_OFFSET); + ctx.lineTo(endX - PhaseSpace.WIDTH_OFFSET/4, this.#height + PhaseSpace.HEIGHT_OFFSET + PhaseSpace.HEIGHT_OFFSET / 8); + ctx.moveTo(endX, this.#height + PhaseSpace.HEIGHT_OFFSET); + ctx.lineTo(endX - PhaseSpace.WIDTH_OFFSET/4, this.#height + PhaseSpace.HEIGHT_OFFSET - PhaseSpace.HEIGHT_OFFSET / 8); + ctx.stroke(); + // y axis + ctx.beginPath(); + ctx.moveTo(PhaseSpace.WIDTH_OFFSET, startY); + ctx.lineTo(PhaseSpace.WIDTH_OFFSET, endY); + // arrow + ctx.moveTo(PhaseSpace.WIDTH_OFFSET, endY); + ctx.lineTo(PhaseSpace.WIDTH_OFFSET - PhaseSpace.WIDTH_OFFSET/8, endY + PhaseSpace.HEIGHT_OFFSET / 4); + ctx.moveTo(PhaseSpace.WIDTH_OFFSET, endY); + ctx.lineTo(PhaseSpace.WIDTH_OFFSET + PhaseSpace.WIDTH_OFFSET/8, endY + PhaseSpace.HEIGHT_OFFSET / 4); + + ctx.stroke(); + // x, p ticks + ctx.beginPath(); + const ticks: number = this.#ticks; + const tickSpacingX: number = (usedEndX - usedStartX)/ticks; + const tickLengthX: number = PhaseSpace.HEIGHT_OFFSET/5; + const tickSpacingY: number = (usedEndY - usedStartY)/ticks; + const tickLengthY: number = PhaseSpace.WIDTH_OFFSET/5; + for (let idx=1; idx<=ticks; idx++) { + const x: number = usedStartX + idx * tickSpacingX; + ctx.moveTo(x, this.#height + PhaseSpace.HEIGHT_OFFSET); + ctx.lineTo(x, this.#height + PhaseSpace.HEIGHT_OFFSET + tickLengthX); + const y: number = usedStartY + idx * tickSpacingY; + ctx.moveTo(PhaseSpace.WIDTH_OFFSET, y); + ctx.lineTo(PhaseSpace.WIDTH_OFFSET-tickLengthY, y); + } + ctx.stroke(); + ctx.font = "16px serif"; + for (let idx=0; idx<=ticks; idx++) { + const x: number = usedStartX + idx * tickSpacingX; + const value: number = this.#xRange[0] + idx / ticks * (this.#xRange[1] - this.#xRange[0]); + ctx.fillText(JsUtils.formatNumber(value, this.#numDigitsX), x - tickLengthY, this.#height + PhaseSpace.HEIGHT_OFFSET + 2.5 * tickLengthX); + const y: number = usedStartY + idx * tickSpacingY; + const valueY: number = this.#pRange[0] + idx/ticks * (this.#pRange[1] - this.#pRange[0]); + const yPositionOffset: number = idx === 0 ? -tickLengthY/2 : tickLengthY/2; // avoid overlap with x-axis + ctx.fillText(JsUtils.formatNumber(valueY, this.#numDigitsY), PhaseSpace.WIDTH_OFFSET - 4.5 * tickLengthY, y + yPositionOffset); + } + // axis labels + ctx.font = "bold 20px serif"; + ctx.fillText("x", this.#width + 2 * PhaseSpace.WIDTH_OFFSET - 1.2 * tickLengthY, this.#height + PhaseSpace.HEIGHT_OFFSET + 2 * tickLengthX); + ctx.fillText(this.energyOrMomentum ? "E" : "p", PhaseSpace.WIDTH_OFFSET - 2.2 * tickLengthY, 1.4 * tickLengthX); + } + + initialize(qmResults: QuantumSimulationResult[], classicalResults: Array, + keepSlices?: boolean, + ranges?: {x?: [number, number], p?: [number, number]}): void { + this.clear(keepSlices); + this.#currentData = [qmResults, classicalResults]; + let xMin: number|undefined; + let xMax: number|undefined; + let pMin: number|undefined; + let pMax: number|undefined; + const points: Array> = qmResults.map(r => r.observables); + points.push(...classicalResults.map(r => r.points)); + const eOrP: boolean = this.energyOrMomentum; + if (ranges?.x) + [xMin, xMax] = ranges.x; + if (ranges?.p) + [pMin, pMax] = ranges.p; + for (const arr of points) { + for (const p of arr) { + if (!ranges?.x && isFinite(p.x)) { + if (!(xMin <= p.x)) + xMin = p.x; + if (!(xMax >= p.x)) + xMax = p.x; + } + const val: number|undefined = eOrP ? p.E : p.p; + if (!ranges?.p && isFinite(val)) { + if (!(pMin <= val)) + pMin = val; + if (!(pMax >= val)) + pMax = val; + } + } + } + // TODO round numbers + xMin = isFinite(xMin) ? xMin : 0; + xMax = isFinite(xMax) ? xMax : 1; + pMin = (isFinite(pMin) && (ranges?.p || !eOrP)) ? pMin : 0; + pMax = isFinite(pMax) ? pMax : 1; + let potentialDrawn: boolean = false; + const ctx: CanvasRenderingContext2D = this.#canvas.getContext("2d"); + if (this.energyOrMomentum && qmResults?.length > 0) { // plot a slightly larger domain than the actually occurring xs + const minMaxX: Array<[number,number]> = qmResults.map(r => [r.x[0], r.x[r.x.length - 1]]); + const min: number = minMaxX.map(mm => mm[0]).reduce((val, x) => x < val ? x : val, xMin || 0); + const max: number = minMaxX.map(mm => mm[1]).reduce((val, x) => x > val ? x : val, xMax || 1); + if (min < xMin) + xMin = Math.max(xMin - 0.3 * Math.abs(xMin), min); + if (max > xMax) + xMax = Math.min(xMax + 0.3 * Math.abs(xMax), max); + // TODO adapt also pMin and pMax + // XXX simply select the first? + const firstResult: QuantumSimulationResult = qmResults.find(r => r.settings.V?.length === r.x.length); + if (firstResult) { + const containedIndices: Array + = firstResult.x.map((val, idx) => val >= xMin && val <= xMax ? idx : -1).filter(idx => idx >= 0); + const maxV: number = Math.max(...firstResult.settings.V.filter((_, idx) => containedIndices.indexOf(idx) >= 0)); + if (maxV > pMax) + pMax = maxV; + ctx.beginPath(); + ctx.strokeStyle = "black"; // ? + let initialized: boolean = false; + + for (let idx=0; idx xMax) + break; + const val: number = firstResult.settings.V[idx]; + const xPx: number = PhaseSpace.WIDTH_OFFSET + (x - xMin) / (xMax - xMin) * this.#width + const yPx: number = PhaseSpace.HEIGHT_OFFSET + (1-((val - pMin) / (pMax - pMin))) * this.#height; + if (!initialized) { + ctx.moveTo(xPx, yPx); + initialized = true; + } else { + ctx.lineTo(xPx, yPx); + } + } + ctx.stroke(); + potentialDrawn = true; + } + } + this.#xRange = [xMin, xMax]; + this.#pRange = [pMin, pMax]; + this._drawAxes(ctx); + let idx: number = -1; + for (const arr of points) { + idx++; + ctx.beginPath(); + ctx.strokeStyle = ColorPalette.getColor(idx, 1); + let initialized: boolean = false; + let lastXP: [number, number] = [NaN, NaN]; + for (const point of arr) { + if (!isFinite(point.x) || !isFinite(eOrP ? point.E : point.p) || (point.x === lastXP[0] && (eOrP ? point.E ===lastXP[1] : point.p === lastXP[1] ))) + continue; + lastXP = [point.x, eOrP ? point.E : point.p]; + const x: number = PhaseSpace.WIDTH_OFFSET + (point.x - xMin) / (xMax - xMin) * this.#width; + const p: number = PhaseSpace.HEIGHT_OFFSET + (1-((eOrP ? point.E : point.p) - pMin) / (pMax - pMin)) * this.#height; + if (!initialized) { + ctx.moveTo(x, p); + initialized = true; + } else { + ctx.lineTo(x, p); + } + } + ctx.stroke(); + } + idx = -1; + for (const result of points) { + idx++; + const point = JsUtils.createElement("div", {parent: this.#container, classes: ["current-point", "position-absolute"]}); + point.style.borderColor = ColorPalette.getColor(idx, 0); + this.#currentPoints.push(point); + } + // clear legend + for (const c of Array.from(this.#legendGrid.children)) { + c.remove(); + } + idx = 0; + for (const result of [...qmResults, ...classicalResults].map(r => r.id)) { + const colorEl: HTMLElement = JsUtils.createElement("div", {parent: this.#legendGrid, html: "—"}); + colorEl.style.color = ColorPalette.getColor(idx++, 0); + colorEl.style.fontSize = "24px"; + const text: HTMLElement = JsUtils.createElement("div", {parent: this.#legendGrid, text: result}); + JsUtils.createElement("div", {parent: this.#legendGrid}); + } + } + + scale(scale: number): void { + } + + next(slices: [Timeslice, Timeslice|undefined][], points: Array): void { + this.#currentSlices = slices; + this.#currentClassicalPoints = points; + // list of quantum expectation values ,

and classical points + const allPoints: Array = [...slices.map(s => s[0].observables), ...points]; + const eOrP: boolean = this.energyOrMomentum; + allPoints.forEach((slice, idx) => { + if (this.#currentPoints.length <= idx) + return; + const x: number = slice.x; + const p: number = eOrP ? slice.E : slice.p; + // TODO what if p (E) is undefined? + const style: CSSStyleDeclaration = this.#currentPoints[idx].style; + // 5 is the border radius of the point div + style.top = (PhaseSpace.HEIGHT_OFFSET + (1-(p - this.#pRange[0]) / (this.#pRange[1]-this.#pRange[0])) * this.#height - 5) + "px"; + style.left = (PhaseSpace.WIDTH_OFFSET + (x - this.#xRange[0]) / (this.#xRange[1]-this.#xRange[0]) * this.#width - 5) + "px"; + }); + } + + clear(keepSlices?: boolean): void { + this.#canvas.getContext("2d").clearRect(0, 0, this.#canvas.width, this.#canvas.height); + this.#currentPoints.splice(0, this.#currentPoints.length).forEach(p => p.remove()); + this.#currentData = undefined; + if (!keepSlices) { + this.#currentSlices = undefined; + this.#currentClassicalPoints = undefined; + } + } + +} diff --git a/viz/src/psiPlot.ts b/viz/src/psiPlot.ts new file mode 100644 index 0000000..5d532ee --- /dev/null +++ b/viz/src/psiPlot.ts @@ -0,0 +1,253 @@ +import uPlot, { AlignedData, Options, Series } from "uplot"; +import "../node_modules/uplot/dist/uPlot.min.css"; +import { ColorPalette } from "./colorPalette.js"; +import { JsUtils } from "./JsUtils.js"; +import { SimulationListener, QuantumSimulationResult, Timeslice } from "./types.js"; + +export class PsiPlot implements SimulationListener { + + #element: HTMLElement; + #chart: uPlot; + #yRange: number = 1; + #ERange: number = 1; + #activeIds: Array = []; + + constructor(private readonly secondary?: boolean) { + this.#element = document.querySelector(secondary ? "#waveFunctionTilde" : "#waveFunction"); + } + + build() { + if (this.#chart) + return; + const width: number = this.#element.getBoundingClientRect().width || 800; // FIXME? + const height: number = /*this.#element.getBoundingClientRect().height ||*/ 600; + const options: Options = { + width: width, + height: height, + title: this.secondary ? /*"ψ̃ "*/ "Φ" : "ψ", + cursor: {drag: { x: true, y: true, uni: 50 } }, // FIXME?= + scales: { + x: { time: false }, + 1: { range: (self, min, max) => [0, this.#yRange] }, + E: { range: (self, min, max) => [0, this.#ERange] } + }, + series: [{label: "x"}, {label: "Test"}], + axes: [{}, { + scale: "1", + values: (self, ticks) => ticks.map(rawValue => JsUtils.formatNumber(rawValue)), + }, + { + scale: "E", + values: (self, ticks) => ticks.map(rawValue => JsUtils.formatNumber(rawValue, 5)), + side: 1, + grid: {show: false}, + },] + }; + const data: AlignedData = [ + [], [] + ] as any; + this.#chart = new uPlot(options, data, this.#element); + // for debugging + (window as any).sch = (window as any).sch || {}; + const debugId: string = this.secondary ? "Phi" : "psi"; + (window as any).sch[debugId] = this.#chart; + // on this object we can use the uPlot API, see https://github.com/leeoniya/uPlot/blob/master/dist/uPlot.d.ts + // e.g. window.sch.psi.setSize({width: 640, height: 480}) + } + + initialize(results: Array): void { + if (this.secondary) + results = results.filter(r => r.waveFunctionTilde); + const ids: Array = results.map(r => r.id); + if (ids.length === 0) { + this.clear(); + return; + } + this.build(); + const multiIds: boolean = ids.length > 1; + if (this.#activeIds.length === 1 && !multiIds) + return; + if (this.#activeIds.length === ids.length && !ids.find(id => this.#activeIds.indexOf(id) < 0)) + return; + // remove old series + const s: number = this.#chart.series.length; + for (let idx=s-1; idx > 0; idx--) { + this.#chart.delSeries(idx); + } + // TODO the coloring should be aligned between primary (psi) and secondary (Phi) results + let idx: number = -1; + // psi tilde => in Libre Office, copy the psi (from somewhere), then enter "0303" followed by Alt+C. + const psi: string = this.secondary ? /*"ψ̃"*/ "Φ" : "ψ"; + for (const id of ids) { + idx++; + const colors: [string, string, string] = [ColorPalette.getColor(idx, 0), ColorPalette.getColor(idx, 1), ColorPalette.getColor(idx, 2)] + const psiSquared: Series = { + label: multiIds ? "|" + psi +"_" + id +"|" : "|" + psi +"|", + //fill // TODO color + show: true, + spanGaps: false, + //value: (self, rawValue) => "$" + rawValue.toFixed(2), + + // series style + points: { show: true, size: 2, fill: colors[0]}, + stroke: /*"blue"*/ colors[0], + width: 1, + scale: "1" + //fill: "rgba(0, 255, 0, 0.1)", // TODO configurable + //dash: [10, 5], + }; + const psiReal: Series = { + label: multiIds ? "|Re(" + psi + "_" + id +")|" : "|Re(" + psi + ")|", + //fill // TODO color + show: false, + spanGaps: false, + //value: (self, rawValue) => "$" + rawValue.toFixed(2), + + // series style + points: { show: true, size: 2, fill: colors[1]}, + stroke: /*"red"*/ colors[1], + width: 1, + scale: "1", + //fill: "rgba(0, 255, 0, 0.1)", // TODO configurable + dash: [10, 5], + }; + const psiImg: Series = { + label: multiIds ? "|Im(" + psi + "_" + id +")|" : "|Im(" + psi + ")|", + //fill // TODO color + show: false, + spanGaps: false, + //value: (self, rawValue) => "$" + rawValue.toFixed(2), + + // series style + points: { show: true, size: 2, fill: colors[2]}, + stroke: colors[2], + width: 1, + scale: "1" + //fill: "rgba(0, 255, 0, 0.1)", // TODO configurable + //dash: [10, 5], + }; + this.#chart.addSeries(psiSquared); + this.#chart.addSeries(psiReal); + this.#chart.addSeries(psiImg); + // FIXME single V only? + if (!this.secondary || results[idx].potential) { + const V: Series = { + label: multiIds ? "|V_" + id +"|" : "V", + //fill // TODO color + show: true, + spanGaps: false, + //value: (self, rawValue) => "$" + rawValue.toFixed(2), + + // series style + points: { show: true, size: 2, fill: "black"}, + stroke: "black", + width: 1, + scale: "E" + //fill: "rgba(0, 255, 0, 0.1)", // TODO configurable + //dash: [10, 5], + }; + this.#chart.addSeries(V); // ? + } + + } + this.#activeIds = ids; + let maxPotential: number; + if (this.secondary) + maxPotential =results.map(r => r.potential).find(V => V)?.flatMap(v => v)?.reduce((max, val) => val > max ? val : max, 0) || 0; + else + maxPotential =results.map(r => r.settings).find(s => s)?.V?.reduce((max, val) => val > max ? val : max, 0) || 0; + this.#ERange = maxPotential; + this.#chart.setData(this.#chart.series.map(() => []) as any); + } + + scale(scale: number): void { + this.#yRange = scale; + } + + // ||psi||, psi_R, psi_I + // potential: outer index: dataset idx, inner index: spatial + next(slices: Array<[Timeslice, Timeslice|undefined]>, _: any, potential?: Array|undefined>): void { + if (!(slices?.length > 0) || !this.#chart) + return; + const domain: [Array, boolean] = JsUtils.mergeArrays(slices.map(slice => slice[this.secondary ? 1: 0]?.x)); + const allDomainsEqual: boolean = domain[1]; + const data: AlignedData = [domain[0]]; //[slices[0].x]; + let idx: number = -1; + for (const sliceArr of slices) { + idx++; + const slice: Timeslice|undefined = sliceArr[this.secondary ? 1 : 0]; + if (!slice) // TODO ok? + continue; + const psi: Array<[number, number]> = slice.waveFunction; + //const x: Array = slice.x; + if (allDomainsEqual) { + const abs: Array = psi.map(xy => Math.sqrt(xy[0]*xy[0] + xy[1]*xy[1])); + const real: Array = psi.map(xy => Math.abs(xy[0])); + const img: Array = psi.map(xy => Math.abs(xy[1])); + //const data: AlignedData = [x, abs, real, img, slice.settings.V]; + data.push(...[abs, real, img]); + if (!this.secondary || potential) { + const V = this.secondary ? potential[idx] : slice.settings.V; + if (V) + data.push(V); + } + } else { + const localX: Array = slice.x; + const ev = (f: ((xy: [number, number]) => number)): Array => { + return domain[0].map(x => { + const idx: number = localX.indexOf(x); + if (idx < 0) + return NaN; + const xy: [number, number] = psi[idx]; + return f(xy); + }); + }; + const abs: Array = ev(xy => Math.sqrt(xy[0]*xy[0] + xy[1]*xy[1])); + const real: Array = ev(xy => Math.abs(xy[0])); + const img: Array = ev(xy => Math.abs(xy[1])); + data.push(...[abs, real, img]); + if (!this.secondary || (potential && potential[idx])) { + const V: Array = domain[0].map(x => { + const idxX: number = localX.indexOf(x); + if (idxX < 0) + return NaN; + return this.secondary ? potential[idx][idxX] : slice.settings.V[idxX]; + }); + if (V) + data.push(V); + } + } + } + // allow the potential to be specified for a single timestep only (for relax representation) + const dataLength: number = data.length; + const seriesLength: number = this.#chart.series.length; + if (dataLength < seriesLength) { + const oldDataLength: number = this.#chart.data.length; + if (oldDataLength > dataLength) { + for (let idx=dataLength; idx 0; idx--) { + this.#chart.delSeries(idx); + } + this.#chart.addSeries({label: "Test"}); + this.#chart?.setData([[], []]); + this.#activeIds = []; + } + +} \ No newline at end of file diff --git a/viz/src/types.ts b/viz/src/types.ts new file mode 100644 index 0000000..090ae99 --- /dev/null +++ b/viz/src/types.ts @@ -0,0 +1,160 @@ +export interface QuantumSimulationResult { + readonly id: string; + readonly x: Array; // x values + readonly timesteps: Array; + readonly waveFunction: Array; + // array: timesteps + readonly observables: Array; + readonly settings: QuantumSettings; + + // possibly the transformed wave function and classical trajectory + readonly waveFunctionTilde?: Array; + readonly classicalTrajectory?: ClassicalSimulationResult; + readonly observablesTilde?: Array; + // outer index: time, inner: x; the effective, time-dependent potential for \tilde \psi + readonly potential?: Array>; + +} + +export interface Timeslice { + readonly x: Array; + readonly waveFunction: Array<[number, number]>; + readonly observables: ExpectationValues; + readonly settings: QuantumSettings; +} + +export interface ClassicalSimulationResult { + readonly id: string; + readonly timesteps: Array; + readonly points: Array; + readonly settings: ClassicalSettings; +} + +export interface Point { + x: number; + p: number; + E?: number; // for classical trajectories the energy may be specified as well +} + +export interface ExpectationValues extends Point { + readonly x2: number; + readonly p2: number; + readonly E: number; // the energy +} + +export interface Scheme { + id: string; +} + +export type QuantumSettings = { + readonly type: "qm"; + readonly hbar: number; + readonly deltaT: number; + readonly scheme: Scheme; + readonly deltaX?: number; +} & Potential; + +/** + * Either the coefficients of a polynomial, V0 + V1*x + 1/2 V2*x^2 + 1/6 V3*x^3 + ..., + * or the sampled values at specified base points + */ +export interface Potential { + V_coefficients?: Array; + points?: Array; // points and V should always appear together + V?: Array; +} + +export type ClassicalSettings = { + readonly type: "classical"; + readonly deltaT: number; + readonly scheme: Scheme; +} & Potential; + +export interface SimulationListener { + initialize(qmResults: Array, classicalResults: Array): void; + scale(scale: number): void; + // slices: first value: psi, second value: psiTilde, if present + // potential: outer index: dataset idx, inner index: spatial + next(slices: Array<[Timeslice, Timeslice|undefined]>, poins: Array, potential?: Array|undefined>): void; + clear(): void; +} + +export enum SimulationState { + UNSET = "UNSET", + INITIALIZED = "INITIALIZED", + RUNNING = "RUNNING", + PAUSED = "PAUSED", + DONE = "DONE" + +} + +export interface SimulationStateListener { + stateChanged: (simulationState: SimulationState) => void; + onProgress?: (fraction: number) => void; +} + +export class TypesUtils { + + private constructor() {} + + private static factorialize(num: number): number { + if (num === 0) + return 1; + let result = num; + for (let lower = num - 1; lower >= 1; lower--) { + result = result * lower; + } + return result; + } + + /* + * TODO we could use MathML here for nicer presentation + * + + 1 + + 2 + + + + */ + public static printPotential(V: Potential): string { + if (!!V.V_coefficients) { // polynomial + let result = "V(x) = "; + let idx = 0; + for (let c of V.V_coefficients) { + if (c != 0) { + let hasPrefix = false; + if (idx >= 2) { + result += c + "/" + TypesUtils.factorialize(idx) + hasPrefix = true; + } else if (c != 1) { + result += c + hasPrefix = true; + } + if (idx === 0) + continue; + if (hasPrefix) + result += "*" + result += "x"; + if (idx >= 2) + result += "^" + idx; + } + idx++; + } + return result; + } + if (!!V.points && !!V.V) { // sampled values + const values: Array = V.V; + const points: Array = V.points; + const l: number = values.length; + if (l < 10) + return "{" + values.map((v, idx) => points[idx] + " => " + v).join(", ") + "}" + const delta = Math.floor(l / 10); + const indices = [...Array(9).keys()].map(idx => idx * delta); + indices.push(l-1); + return "{" + indices.map(idx => points[idx] + " => " + values[idx]).join(", ") + "}" + } + } + +} diff --git a/viz/tsconfig.json b/viz/tsconfig.json new file mode 100644 index 0000000..a01a468 --- /dev/null +++ b/viz/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "allowSyntheticDefaultImports": true, + "rootDir": "./src", + "outDir": "./dist", + "lib": ["ES2022", "DOM"], + "module": "ES2022", + "target": "ES2022", + "moduleResolution": "node", + "noImplicitAny": true, + "sourceMap": true, + } +} \ No newline at end of file diff --git a/viz/webpack.config.js b/viz/webpack.config.js new file mode 100644 index 0000000..1607013 --- /dev/null +++ b/viz/webpack.config.js @@ -0,0 +1,53 @@ +import CopyPlugin from "copy-webpack-plugin"; +import HtmlWebpackPlugin from "html-webpack-plugin"; +import path from "path"; +import pkg from "resolve-typescript-plugin"; // required for importing .ts files as .js files with webpack https://www.npmjs.com/package/resolve-typescript-plugin +const ResolveTypeScriptPlugin = pkg.default; + +export default { + entry: "./src/index.ts", + devtool: "inline-source-map", + module: { + rules: [{ + test: /\.tsx?$/, + use: "ts-loader", + exclude: /node_modules/ + },{ + test: /\.css$/i, + use: ["style-loader", "css-loader"], + }] + }, + + resolve: { + extensions: [".ts", ".js", ".tsx", ".css"], + //modules: ["src", "node_modules"], + plugins: [new ResolveTypeScriptPlugin()] + }, + output: { + filename: "bundle.js", + path: path.resolve("./dist"), + clean: true + }, + plugins: [ + new CopyPlugin({ + patterns: [ + { from: "./assets", to: "./assets" } + ] + }), + new HtmlWebpackPlugin({ + title: "Schrödinger vis", + template: "index.html", + inject: "body", + scriptLoading: "module" + }) + ], + devServer: { + //contentBase: path.resolve("./src"), + static: [ + { directory: path.resolve("./dist") }, + { directory: path.resolve("./assets"), publicPath: "/assets"} + ], + compress: false, + port: 8080, + }, +} \ No newline at end of file