// MAUS WARNING: THIS IS LEGACY CODE. #include "Interface/Differentiator.hh" #include #include #include "gsl/gsl_sf_gamma.h" #include "Maths/Matrix.hh" #include "Maths/PolynomialMap.hh" #include "Maths/Vector.hh" ////////////////////////// DIFFERENTIATOR /////////////////////////// Differentiator::Differentiator(VectorMap* in, std::vector delta, std::vector magnitude) : _inSize(in->PointDimension()), _outSize(MAUS::PolynomialMap::NumberOfPolynomialCoefficients(_inSize, magnitude.size()-1) * in->ValueDimension()), _diffKey(), _factKey(), _delta(delta), _magnitude(magnitude), _diffOrder(magnitude.size()), _y(in) { size_t num_poly_coeff = MAUS::PolynomialMap::NumberOfPolynomialCoefficients( _inSize, magnitude.size()-1); for(size_t i = 0; i < num_poly_coeff; ++i) { _diffKey.push_back(MAUS::PolynomialMap::IndexByVector(i,_inSize)); _factKey.push_back(1); std::vector powerKey = MAUS::PolynomialMap::IndexByPower(i,_inSize); for(size_t j = 0; j < powerKey.size(); ++j) { _factKey[i] *= gsl_sf_fact(powerKey[j]); } } } std::vector< std::vector > Differentiator::SetupInPoints(const MAUS::Vector& inPoint) const { std::vector< std::vector > inVector( _diffKey.size() ); for(unsigned int i=0; i<_diffKey.size(); i++) { inVector[i] = std::vector(_inSize, 0); for(int j=0; j<_inSize; j++) inVector[i][j] = inPoint(j+1); for(unsigned int j=0; j<_diffKey[i].size(); j++) inVector[i][_diffKey[i][j]] += _magnitude[_diffKey[i].size()]*_delta[_diffKey[i][j]]; } return inVector; } MAUS::Matrix Differentiator::SetupMatrixIn(std::vector< std::vector > inVector, const MAUS::Vector& inPoint) const { MAUS::Matrix matrixIn(_diffKey.size(), _diffKey.size(), 0.); for(unsigned int i=0; i<_diffKey.size(); i++) { for(int j=0; j<_inSize; j++) inVector[i][j] -= inPoint(j+1); for(unsigned int j=0; j<_diffKey.size(); j++) { matrixIn(j+1,i+1) = 1; for(unsigned int k=0; k<_diffKey[j].size(); k++) matrixIn(j+1,i+1) *= inVector[i][ _diffKey[j][k] ]; } } return matrixIn; } MAUS::Matrix Differentiator::SetupMatrixOut(std::vector< std::vector > inVector) const { MAUS::Matrix matrixOut(_diffKey.size(), _y->ValueDimension(), 0.); double* out = new double[_y->ValueDimension()]; for(unsigned int i=0; i<_diffKey.size(); i++) { for(unsigned int j=0; j<_y->ValueDimension(); j++) out[j] = 0.; Y(&inVector[i][0], out); for(unsigned int j=0; j<_y->ValueDimension(); j++) matrixOut(i+1,j+1) = out[j]; } delete [] out; return matrixOut; } MAUS::Matrix Differentiator::PolynomialMap(const MAUS::Vector& inPoint) const { MAUS::Vector zero(PointDimension(), 0); std::vector< std::vector > inVec = SetupInPoints (inPoint); MAUS::Matrix in = SetupMatrixIn (inVec, zero); MAUS::Matrix out = SetupMatrixOut(inVec); // for(int i=0; i outMap = transpose(out) * inverse(in); /* std::cout << "InPoints" << std::endl; for(unsigned int i=0; i Differentiator::CentredPolynomialMap(const MAUS::Vector& inPoint) const { MAUS::Vector zero(PointDimension(), 0); std::vector< std::vector > inVec = SetupInPoints (inPoint); MAUS::Matrix in = SetupMatrixIn (inVec, inPoint); MAUS::Matrix out = SetupMatrixOut(inVec); MAUS::Matrix outMap = transpose(out) * inverse(in); return outMap; } void Differentiator::F(const double* point, double* value) const { MAUS::Vector pHep(PointDimension(),0); for(int i=0; i diffs(_y->ValueDimension(), _diffKey.size()); F (pHep, diffs); int index = -1; for(size_t i=0; i& point, MAUS::Matrix& differentials) const { //Fit a polynomial around point MAUS::Matrix map = CentredPolynomialMap(point); //d^p y_j/dx^p = p_1! p_2!... p_n! a_{pj} //where x^p is shorthand for x_1^{p_1} x_2^{p_2}...x_n^{p_n} etc for(unsigned int i=0; iValueDimension()); j++) { differentials(j+1,i+1) = map(j+1,i+1); differentials(j+1,i+1) *= _factKey[i]; } } } MAUS::PolynomialMap* Differentiator::PolynomialFromDifferentials(const MAUS::Vector& point) const { return new MAUS::PolynomialMap(_inSize, PolynomialMap(point) ); } MAUS::PolynomialMap* Differentiator::PolynomialFromDifferentials(double* point) const { MAUS::Vector pointHep(PointDimension()); for(int i=0; i delta, std::vector magnitude) : _mesh(mesh), _func(F), _differentialOrder(differentialOrder), _totalOrder(interpolationOrder+differentialOrder), _inSize(F->PointDimension()), _outSize(F->ValueDimension()), _delta(delta), _magnitude(magnitude), _muIndex(), _alphaIndex(), _taylorCoefficient() { for(unsigned int i=0; i(_alphaIndex.size(), 1)); for(unsigned int j=0; j<_alphaIndex.size(); j++) { for(int k=0; k<_inSize; k++) { _taylorCoefficient[i][j] *= double(gsl_sf_fact(_muIndex[i][k]) );//double(gsl_sf_fact(_alphaIndex[i][k]) ); } } } BuildFixedMeshPolynomials(F); _meshCounter[this] = _mesh; } unsigned int PolynomialInterpolator::NumberOfDiffIndices() const { return MAUS::PolynomialMap::NumberOfPolynomialCoefficients( PointDimension(), DifferentialOrder()); } unsigned int PolynomialInterpolator::NumberOfIndices() const { return MAUS::PolynomialMap::NumberOfPolynomialCoefficients( _inSize, _totalOrder); } PolynomialInterpolator* PolynomialInterpolator::Clone() const { PolynomialInterpolator * clone = new PolynomialInterpolator(*this); clone->_points = new MAUS::PolynomialMap*[_mesh->End().ToInteger()]; for(int i=0; i<_mesh->End().ToInteger(); i++) clone->_points[i] = _points[i]->Clone(); _meshCounter[clone] = _mesh; return clone; } //copy function PolynomialInterpolator::~PolynomialInterpolator() { for(Mesh::Iterator it = _mesh->Begin(); it<_mesh->End(); it++) { delete _points[it.ToInteger()]; } delete [] _points; _meshCounter.erase(this); //can't believe that search by value doesn't exist in std::map //not sure I understand std::map - some stuff makes no sense bool _meshStillExists = false; for(PIMMap::iterator it = _meshCounter.begin(); it != _meshCounter.end(); it++) if(it->second == _mesh) _meshStillExists = true; if (!_meshStillExists) delete _mesh; } void PolynomialInterpolator::BuildFixedMeshPolynomials(VectorMap* F) { Differentiator* diff = new Differentiator(F, _delta, _magnitude); _points = new MAUS::PolynomialMap*[_mesh->End().ToInteger()]; for(Mesh::Iterator it=_mesh->Begin(); it<_mesh->End(); it++) { _points[it.ToInteger()] = PolynomialFromDiffs(it, diff); } delete diff; } void PolynomialInterpolator::F(const double* point, double* value) const { Mesh::Iterator it = _mesh->Nearest(point); std::vector pos = it.Position(); for(unsigned int i=0; iF(&pos[0], value); } bool PolynomialInterpolator::CheckDirection(Mesh::Iterator start, Mesh::Iterator it) { bool direction = true; for(unsigned int i=0; iEnd()[i]/2.) direction &= (start[i] <= it[i]); else direction &= start[i] >= it[i]; return direction; } std::vector< Mesh::Iterator > PolynomialInterpolator::GetFixedMeshPoints(Mesh::Iterator start, int polySize) { std::vector< Mesh::Iterator > points; for(Mesh::Iterator it = _mesh->Begin(); it<_mesh->End(); it++) if(CheckDirection(start, it)) points.push_back(it); PolynomialInterpolator::_itCompCentre = start; std::vector< Mesh::Iterator > closest_points(NumberOfPoints()); std::partial_sort_copy(points.begin(), points.end(), closest_points.begin(), closest_points.end(), M1_LT_M2); return closest_points; } Mesh::Iterator PolynomialInterpolator::_itCompCentre = Mesh::Iterator(); bool PolynomialInterpolator::M1_LT_M2(const Mesh::Iterator& m1, const Mesh::Iterator& m2) { int dist = 0; int size = m1.State().size(); for(int i=0; i points = GetFixedMeshPoints(dualPoint, _muIndex.size()); MAUS::Matrix X = GetX(points); MAUS::Matrix D = GetD(points, diff); MAUS::Matrix A = transpose(D) * inverse(X); return new MAUS::PolynomialMap(_inSize, A ); } MAUS::Matrix PolynomialInterpolator::GetX(std::vector< Mesh::Iterator> points ) { int size( NumberOfIndices() ); // std::cout << size << std::endl; MAUS::Matrix X(size, size, 0.); int gamma = -1; for(int nu=0; nu 0) { X(alpha+1,gamma+1) *= pow(points[nu].Position()[k]-points[0].Position()[k], dpow); } else if(dpow < 0) { X(alpha+1,gamma+1) = 0.; } } X(alpha+1,gamma+1) *=_taylorCoefficient[mu][alpha]; // std::cout << "a: " << alpha << " g: " << gamma << " t: " << _taylorCoefficient[mu][alpha] << " X: " << X[alpha][gamma]<< std::endl; } } } return X; } MAUS::Matrix PolynomialInterpolator::GetD(std::vector< Mesh::Iterator> points, Differentiator* diff) { int size( NumberOfIndices() ); MAUS::Matrix Delta(size, _outSize, 0.); MAUS::Matrix Diffs(_outSize, diff->NumberOfDiffRows(), 0.); MAUS::Vector Pos (_inSize, 0); int gamma = 0; for(unsigned int nu=0; nu posVec = points[nu].Position(); for(int i=0; i<_inSize; i++) Pos(i+1) = posVec[i]; diff->F(Pos, Diffs); // std::cout << "DIFFS" << Diffs << std::endl; for(unsigned int mu=0; mu<_muIndex.size() && gamma < size; mu++) { for(int beta=0; beta<_outSize; beta++) { Delta(gamma+1,beta+1) = Diffs(beta+1,mu+1); } gamma++; } } return Delta; }