// // AttractorKernel.hpp // AwesomeAttractorND // // Created by Joshua Moerman on 11/4/11. // Copyright 2011 Vadovas. All rights reserved. // #ifndef AwesomeAttractorND_AttractorKernel_hpp #define AwesomeAttractorND_AttractorKernel_hpp #include "Vectors.hpp" class AttractorKernel { public: virtual void iterate(VectorIterator begin, VectorIterator end, VectorIterator begin2) = 0; }; template class StaticAttractorKernel : public AttractorKernel, public T { public: virtual void iterate(VectorIterator begin, VectorIterator end, VectorIterator begin2){ while (begin != end) { T::calculate(*begin2, *begin); ++begin; ++begin2; } } }; struct Unravel { Unravel() : parameters() { parameters[0] = 0.761090; parameters[1] = 1.426758; parameters[2] = 1.516635; parameters[3] = -0.02366; parameters[4] = 2.398894; parameters[5] = -0.32422; parameters[6] = -2.12839; } void calculate(VectorConstRef vectorOld, VectorRef vectorNew){ vectorNew[0] = parameters[0]*(vectorOld[2] + parameters[1]); vectorNew[1] = parameters[2]*(vectorOld[0] + parameters[3]); vectorNew[2] = parameters[4]*(vectorOld[1] + parameters[5]); const double dist = vectorNew[0]*vectorNew[0] + vectorNew[1]*vectorNew[1] + vectorNew[2]*vectorNew[2]; if(dist > parameters[6]*parameters[6]) { const double sqrtDist = std::sqrt(dist); const double p = 1.0 - parameters[6] * (static_cast(sqrtDist / parameters[6]) + 1.0) / sqrtDist; vectorNew[0] *= p; vectorNew[1] *= p; vectorNew[2] *= p; } } protected: std::array parameters; static const size_t dimension = 3; }; struct Lorenz { void calculate(VectorConstRef o, VectorRef n); }; /* IDEA: explicitly instantiate StaticAttractorKernel, StaticAttractorKernel, ... Thereby we have very little Unravel and Lorenz classes, which do only one thing. And an abstract base-class. And only iterate() is virtual, thus calculate() can be inlined! */ #endif