@*
HermiteGaussEPBasis.tmpl

Hermite-Gauss basis using the definite parity of the basis functions to remove
half the work.

Created by Graham Dennis on 2008-12-28.

Copyright (c) 2008-2012, Graham Dennis

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*@
@extends xpdeint.Features.Transforms.EPBasis

@def description: Hermite-Gauss basis (Harmonic oscillator)

@def transformMatricesForwardDimConstantsAtIndex($forwardDimRep, $backwardDimRep, $forwardIndex)
real hermiteGaussMinusOne = 0.0;
real hermiteGaussMinusTwo = 0.0;
const real _root = _hermite_zeros_${forwardDimRep.parent.name}[${forwardIndex}] / sqrt(${forwardDimRep.fieldCount / 2.0});
const real expFactor = exp(-0.5 * _root * _root / ${backwardDimRep.globalLattice});
const real expFactor2 = exp(-_root * _root / ${backwardDimRep.globalLattice});
const real normalisation = 1.0/sqrt(${forwardDimRep._maximum});
@end def

@def transformMatricesForDimRepsAtIndices($forwardDimRep, $backwardDimRep, $forwardIndex, $backwardIndex)
  @#
real hermiteGauss;
const real correctionFactor = exp( -0.5 * _root * _root * (${backwardDimRep.globalLattice} - ${backwardIndex} - 1) / ${backwardDimRep.globalLattice}) * normalisation;
if (${backwardIndex} == 0)
  hermiteGauss = pow(M_PI, -0.25) * expFactor;
else if (${backwardIndex} == 1)
  hermiteGauss = sqrt(2.0) * _root * hermiteGaussMinusOne * expFactor;
else
  hermiteGauss = sqrt(2.0/${backwardIndex}) * _root * hermiteGaussMinusOne * expFactor \
                 - sqrt((${backwardIndex}-1.0)/${backwardIndex}) * hermiteGaussMinusTwo * expFactor2;

  @super(forwardDimRep, backwardDimRep, forwardIndex, backwardIndex)

hermiteGaussMinusTwo = hermiteGaussMinusOne;
hermiteGaussMinusOne = hermiteGauss;
  @#
@end def

@def forwardMatrixForDimAtIndices($forwardDimRep, $backwardDimRep, $forwardIndex, $backwardIndex)
hermiteGauss * correctionFactor * ${forwardDimRep.stepSizeArrayName}[$forwardIndex]@slurp
@end def

@def backwardMatrixForDimAtIndices($forwardDimRep, $backwardDimRep, $forwardIndex, $backwardIndex)
hermiteGauss * correctionFactor@slurp
@end def

