void FftLib::fftshift(const RArray &invector, RArray &outvector) { // xdim is 1 since we only deal with col vectors. // xshift is 0 since we obviously never shift // vectors along the x or row axis. int64_t yshift = int64_t(floor(invector.size() / 2)); FftStrategy::circshift(invector, 1, invector.size(), 0, yshift, outvector); }
REAL lem::Math::LagrangeInterpol( const RArray& xi, const RArray& yi, REAL X, int AP ) { const int NL = AP+1; const int i0 = xi.GetFrom(); const int in = xi.GetTo(); LEM_CHECKIT_Z( xi.size()>0 ); LEM_CHECKIT_Z( in==yi.GetTo() ); LEM_CHECKIT_Z( i0==yi.GetFrom() ); LEM_CHECKIT_Z( NL<=CastSizeToInt(xi.size()) ); if(i0==in) return yi(i0); int LeftNode = FindLeftPoint( xi, X ); // Ѕудем интерполировать полиномом Ћагранжа по AP точкам. // “ак что кинем слева и справа половинки этого значени¤. int LI = LeftNode-NL/2; if( LI<i0 ) LI=i0; int RI = LI+NL; if( RI>in ) { RI=in; LI=in-NL+1; } const REAL ONE=TOREAL(1.); REAL P,Xi,S=TOREAL(0.); for( int i=LI; i<=RI; i++ ) { P=ONE; Xi=xi(i); for( int k=LI; k<=RI; k++ ) if( k != i ) P *= (X-xi(k))/(Xi-xi(k)); S += P*yi(i); } return S; }
/**************************************************************************** Ћинейна¤ интерпол¤ци¤ по таблично заданной функции (красиво сказал, а?). ѕроцедура ищет ближайшие к заданной точке узлы. ƒопускаетс¤ задание точки вне определенного диапазона узлов - результат будет корректен. *****************************************************************************/ REAL lem::Math::LinearInterpol( const RArray& xi, const RArray& yi, REAL X ) { const int i0 = xi.GetFrom(); const int in = xi.GetTo(); LEM_CHECKIT_Z( xi.size()>0 ); LEM_CHECKIT_Z( in==yi.GetTo() ); LEM_CHECKIT_Z( i0==yi.GetFrom() ); if(i0==in) return yi(i0); const int LeftNode = FindLeftPoint( xi, X ); const int RightNode = LeftNode+1; // Ќашли индексы двух узлов. const REAL xl = xi(LeftNode), yl = yi(LeftNode); const REAL xr = xi(RightNode), yr = yi(RightNode); return yl + (X-xl)/(xr-xl)*(yr-yl); }
/********************************************************** ѕараболическа¤ интерпол¤ци¤ по таблично заданной функции. ***********************************************************/ REAL lem::Math::SquareInterpol( const RArray& xi, const RArray& yi, REAL X ) { const int i0 = xi.GetFrom(); const int in = xi.GetTo(); LEM_CHECKIT_Z( xi.size()>0 ); LEM_CHECKIT_Z( in==yi.GetTo() ); LEM_CHECKIT_Z( i0==yi.GetFrom() ); if(i0==in) return yi(i0); if( xi.size()==2 ) return yi(i0) + (yi(in)-yi(i0))/(xi(in)-xi(i0)) * (X-xi(i0)); int LeftNode = FindLeftPoint( xi, X ); int RightNode = LeftNode+1; if( RightNode==in ) { LeftNode--; RightNode--; } const int ThirdNode = RightNode+1; // Ќашли индексы двух узлов. const REAL x0 = xi(LeftNode), y0 = yi(LeftNode); const REAL x1 = xi(RightNode), y1 = yi(RightNode); const REAL x2 = xi(ThirdNode), y2 = yi(ThirdNode); return SquareInterpol( x0, y0, x1, y1, x2, y2, X ); }
void CPW_Function:: buildFrom(const RArray<Unit> &train, const Unit deltaUnit, const bool cleanUp) { assert(deltaUnit>0); const size_t n = train.size(); coords.free(); coords.ensure(2*n); CVector<Unit> shift(n); for(size_t i=0;i<n;++i) { shift[i] = train[i] + deltaUnit; } size_t iShift = 0; size_t iTrain = 0; Unit curr = 0; foot = 0; while(iTrain<n) { const Unit tt = train[iTrain]; const Unit ts = shift[iShift]; if(tt<=ts) { ++curr; const Coord C(tt,curr); coords.push_back(C); ++iTrain; } else { --curr; const Coord C(ts,curr); coords.push_back(C); ++iShift; } } while(iShift<n) { --curr; const Coord C(shift[iShift++],curr); coords.push_back(C); } assert(2*n==coords.size()); if(cleanUp) removeEmptyIntervals(); }