Example #1
0
// -------------------------------------------------------------------------
// One-dimentional interpolation by N nodes using Lagrange polynome.
//
//         N       N
//        ---    +---+
//        \      |   |  ( X - Xk )
// Ln(X) = >  Yi*|   | -------------
//        /      |   |  ( Xi - Xk )
//        ---    -   -
//        i=i0    k=i0
//                k!=i
//
// ¬ектора xi и yi хран¤т координаты экспериментальных точек. јргумент
// X - абсцисса точки, где необходимо найти значение аппроксимирующего
// пролинома.
// -----------------------------------------------------------------------
REAL lem::Math::LagrangeInterpol(
                                 const RArray& xi,
                                 const RArray& yi,
                                 REAL X
                                )
{
 const int i0 = xi.GetFrom();
 const int in = xi.GetTo();

 LEM_CHECKIT_Z( in==yi.GetTo() );
 LEM_CHECKIT_Z( i0==yi.GetFrom() );

 if(i0==in)
  return yi(i0);

 REAL P,Xi,S=TOREAL(0.0);
 const REAL ONE=TOREAL(1.0);

 for( int i=i0; i<=in; i++ )
  {
   P=ONE;
   Xi=xi(i);

   for( int k=i0; k<=in; k++ )
    if( k != i )
     P *= (X-xi(k))/(Xi-xi(k));

   S += P*yi(i);
  }

 return S;
}
Example #2
0
/****************************************************************************
 Ћинейна¤ интерпол¤ци¤ по таблично заданной функции (красиво сказал, а?).

 ѕроцедура ищет ближайшие к заданной точке узлы. ƒопускаетс¤ задание
 точки вне определенного диапазона узлов - результат будет корректен.
*****************************************************************************/
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);
}
Example #3
0
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;
}
Example #4
0
/**********************************************************
 ѕараболическа¤ интерпол¤ци¤ по таблично заданной функции.
***********************************************************/
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
                       );
}
Example #5
0
int lem::Math::FindLeftPoint( const RArray& xi, REAL X )
{
 const int i0 = xi.GetFrom();
 const int in = xi.GetTo();

 // »щем две точки, лежащие слева и справа от заказанной
 // абсциссы.
 const REAL xa=xi(i0), xb=xi(in);

 int LeftNode = i0 + int((X-xa)/(xb-xa));
 int irange   = (in-i0)/2+(in-i0)%2;

 if( X<=xa || X>=xb )
  {
   // “очка уже вне пределов заданных абсцисс.
   if( X<=xa )
    LeftNode=i0;
   else
    LeftNode=in-1;
  }
 else
  FOREVER
   {
    if( xi(LeftNode)<=X && xi(LeftNode+1)>=X )
     break;

    if( xi.get(LeftNode)>=X )
     {
      // »щем в левом поддиапазоне.
      if( (irange/=2) < 1 )
       irange=1;

      LeftNode -= irange;

      if( LeftNode<i0 )
       LeftNode=i0;
     }
    else
     {
      // »щем в правом поддиапазоне.
      if( (irange/=2) < 1 )
       irange=1;

      LeftNode += irange;

      if( LeftNode>in-1 )
       LeftNode=in-1;
     }
   }

 return LeftNode;
}