/* Copyright 2008-2009, Technische Universitaet Muenchen,
Authors: Christian Hoeppner & Sebastian Neubert
This file is part of GENFIT.
GENFIT is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GENFIT 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with GENFIT. If not, see .
*/
//-----------------------------------------------------------
// File and Version Information:
// $Id$
//
// Description:
// Implementation of class Nystrom
// see Nystrom.hh for details
//
// Environment:
// Software developed for the PANDA Detector at FAIR.
//
// Author List:
// Sebastian Neubert TUM (original author)
//
//
//-----------------------------------------------------------
// Panda Headers ----------------------
// This Class' Header ------------------
#include "Nystrom.h"
#include
// C/C++ Headers ----------------------
#include
#include "assert.h"
#include "TMath.h"
// Collaborating Class Headers --------
#include "AbsNystromEQM.h"
// Class Member definitions -----------
Nystrom::Nystrom(AbsNystromEQM* eqm)
: _eqm(eqm), _acc(1E-2), _adaptive(true)
{}
void
Nystrom::step(const TVectorT& u, const TVectorT& uprime,
const TVectorT& par,
TVectorT& newu, TVectorT& newuprime,
double h)
{
assert(h!=0);
double sign= h > 0 ? 1. : -1.;
double habs=sign*h;
double hh=habs*0.5;
double h2=h*h;
TVectorT k1=_eqm->eval(u,uprime,par);
TVectorT k2=_eqm->eval(u+hh*uprime+h2/8.*k1,uprime+hh*k1,par);
TVectorT k3=_eqm->eval(u+hh*uprime+h2/8.*k2,uprime+hh*k2,par);
TVectorT k4=_eqm->eval(u+habs*uprime+h2/2.*k3,uprime+habs*k3,par);
TVectorT ksum=k1+k2+k3;
newu=u+h*uprime+h2/6.*ksum;
newuprime=uprime+(h/6.)*(ksum+k4+k2+k3);
assert(TMath::Abs(newuprime[2]-1.)<1E-4);
}
// this will return the new h!
double
Nystrom::adaptiveStep(const TVectorT& u,
const TVectorT& uprime,
const TVectorT& par,
TVectorT& newu,
TVectorT& newuprime,
double& stepdone,
double h, double sign, double reststep)
{
//std::cout<<"Starting adaptive step:"<=0);
TVectorT newu1(u);
TVectorT newuprime1(uprime);
TVectorT newu2(u);
TVectorT newuprime2(uprime);
TVectorT utmp(u);
TVectorT uprimetmp(uprime);
TVectorT delta(u);
//newh=0.01;
int n=delta.GetNrows();
while(d>d0){
if(newh>=reststep)newh=reststep;
//std::cout<<"newh="<=maxsteps)std::cerr<<"Nystrom:: too many steps (>"<1E-8){
step(utmp,uprimetmp,par,
newu,newuprime,h);
}
double dx=h*uprimetmp[0];
double dy=h*uprimetmp[1];
length+=sqrt(dx*dx+dy*dy+h*h);
return length;
//double avstep=fabs(z0-z)/(double)steps;
//std::cout<<"z0="<