Взвешенное по времени МНК

 
Привет всем. Скажите, ктонибудь пробовал реализовать подобный расчёт на МКУЛЬ???? И если да то покажите код как это делается. Спасибо!!!!
 

Mihail Marchukajtes:
Привет всем. Скажите, ктонибудь пробовал реализовать подобный расчёт на МКУЛЬ???? И если да то покажите код как это делается. Спасибо!!!!

могу предположить что lsfitlinearw из библиотеки alglib может подойти 
и аналогично lsfitlinearwc для случая когда задача оптимизации с ограничениями

 
Mihail Marchukajtes:
Привет всем. Скажите, ктонибудь пробовал реализовать подобный расчёт на МКУЛЬ???? И если да то покажите код как это делается. Спасибо!!!!

А что там сложного ?

Расписываем метод МНК с "весами". Потом, при задании точек, через которые будет проходить кривая - задаем им разные веса - как правило, чем позже, тем больше. Вычисляем коэффициенты многочлена по стандартным формулам, и получаем расчет МНК, взвешенный по времени. 

Я давно себе уже написал класс, рассчитывающий регрессию линейную, параболическую и кубическую.

Ну и правильно заметили, в библиотеке alglib - скорее всего, этот метод есть.

 
Ну а кодом может кто поделится желательно для МКУЛЬ4
 
George Merts:

А что там сложного ?

Расписываем метод МНК с "весами". Потом, при задании точек, через которые будет проходить кривая - задаем им разные веса - как правило, чем позже, тем больше. Вычисляем коэффициенты многочлена по стандартным формулам, и получаем расчет МНК, взвешенный по времени. 

Я давно себе уже написал класс, рассчитывающий регрессию линейную, параболическую и кубическую.

Ну и правильно заметили, в библиотеке alglib - скорее всего, этот метод есть.

прощу прощения за навязчивый вопрос: а с Вашим классом можно ознакомиться?

я сейчас тоже нахожусь в ситуации обдумывая не написать ли свою функцию более быструю чем в алглибе 

 
Mihail Marchukajtes:
Ну а кодом может кто поделится желательно для МКУЛЬ4

У меня класс с виртуальными функциями - надо пронаследовать класс, и перегрузить эти функции. Ниже заголовочный файл, сможете пронаследовать класс, и перегрузить виртуальные функции:

enum ELSMType
{
   LSM_FLAT       = 0,
   LSM_TREND      = 1,
   LSM_PARABOLIC  = 2,
   LSM_CUBIC      = 3
};

struct SLSMPowers
{
   double   m_dThirdPower;
   double   m_dSecondPower;
   double   m_dFirstPower;
   double   m_dNullPower;
};

class CLSMBase
{
protected:
  
   // Функции, которые обязательно следует перегрузить
   // Именно эти функции возвращают число точек и их координаты.
   virtual int    _N() = 0;      // Число точек
   virtual double _X(int iIdx) = 0;  // Значение X точки с индиксом uiIdx
   virtual double _Y(int iIdx) = 0;;  // Значение Y точки с индиксом uiIdx
  
   // Функци, которые можно не перегружать, если необходимо значение по умолчанию.
   // Это функции для указания веса и полярной точки.
   virtual int    _W(int iIdx)   { return(DEFAULT_POINT_WEIGHT); };  // Значение веса точки с индексом uiIdx
   virtual int    _PolarIdx()    { return(WRONG_VALUE); }            // Индекс точки, через которую должна проходить прямая, при отрицательном значении - такой точки нет.    

   // Рассчетные функции (во всех случаях учитываются веса точек и отнимается полярная точка, если ее индекс валиден, обозначается "с" - корректированное).
   double _SummXc();
   double _SummXc2();
   double _SummXc3();
   double _SummXc4();
   double _SummXc5();
   double _SummXc6();
   double _SummX2c2();
   double _SummX3c2();
   double _SummXcYc();
   double _SummX2cXc();
   double _SummX2cYc();
   double _SummXcX2c();
   double _SummX3cX2c();
   double _SummX3cXc();
   double _SummX3cYc();
   double _SummYc();
   int    _SummW();


   // Функциии расчета для аппроксимированных значений.
   // Функции вынесены в protected-секцию, чтобы можно было организовать различные способы доступа к данным
   // Для расчетов используются перегруженные функции: _N(); _X(); _Y(); _W(); _PolarIdx().


   // Функция расчета горизонтальной прямой (по сути среднего арифметического)
   double _CountFlatLevel();        

   // Функция расчета тренда для случая, когда есть точка-полюс, через которую должна лежать прямая
   // Предполагается, что _PolarIdx() != WRONG_VALUE (проверка по ASSERT)
   double _CountPolarTrend(double & rdPolarLevel);   
  
   // Функция расчета обычной прямой c трендом
   // Предполагается, что _PolarIdx() == WRONG_VALUE (проверка по ASSERT)
   double _CountTrend(double & rdLevel);  
  
   // Функция расчета параболы для случая, когда есть точка полюс, через которую парабола должна проходить.
   // Заполняет соответствующие коэффициенты
   // Предполагается, что _PolarIdx() != WRONG_VALUE (проверка по ASSERT)
   void _CountPolarParabola(double & rdSecondPower,double & rdFirstPower,double & rdNullPower);   

   // Функция расчета параболы.
   // Заполняет соответствующие коэффициенты
   // Предполагается, что _PolarIdx() == WRONG_VALUE (проверка по ASSERT)
   void _CountParabola(double & rdSecondPower,double & rdFirstPower,double & rdNullPower);   


   // Функция расчета кубической параболы для случая, когда есть точка полюс, через которую парабола должна проходить.
   // Заполняет соответствующие коэффициенты
   // Предполагается, что _PolarIdx() != WRONG_VALUE (проверка по ASSERT)
   void _CountPolarCubic(double & rdThirdPower,double & rdSecondPower,double & rdFirstPower,double & rdNullPower);

   // Функция расчета кубической параболы.
   // Заполняет соответствующие коэффициенты
   // Предполагается, что _PolarIdx() == WRONG_VALUE (проверка по ASSERT)
   void _CountCubic(double & rdThirdPower,double & rdSecondPower,double & rdFirstPower,double & rdNullPower);

   // Функция расчета указанной кривой.
   // Заполняет соответствующие коэффициенты (несуществующие коэффициента заполняются нулями
   // В зависимости от величины, возвращаемой _PolarIdx(), вызываются полярные или обычные функции
   SLSMPowers _CountLSM(ELSMType ltType);

   // Статические функции для матричных вычислений

   // Функция вычисляет детерменант матрицы размера 3х3.
   // Значения передаются по строкам.
   static double _Determinant_3(double dX11,double dX12,double dX13,double dX21,double dX22,double dX23,double dX31,double dX32,double dX33) { return(dX11*dX22*dX33 - dX11*dX23*dX32 - dX12*dX21*dX33 + dX12*dX23*dX31 + dX13*dX21*dX32 - dX13*dX22*dX31);};
      
   // Функция вычисляет детерменант матрицы размера 4х4.
   // Значения передаются по строкам.
   static double _Determinant_4(double dX11,double dX12,double dX13,double dX14,double dX21,double dX22,double dX23,double dX24,double dX31,double dX32,double dX33,double dX34,double dX41,double dX42,double dX43,double dX44);
      
public:
   CLSMBase() {};
   ~CLSMBase() {};

   static void ZeroPowers(SLSMPowers & lpPowers) { lpPowers.m_dNullPower = 0; lpPowers.m_dFirstPower = 0; lpPowers.m_dSecondPower = 0; lpPowers.m_dThirdPower = 0; };
   static double CountLSM(double dX,SLSMPowers & lpPowers) { return(dX*(dX*(dX*lpPowers.m_dThirdPower + lpPowers.m_dSecondPower)+lpPowers.m_dFirstPower)+lpPowers.m_dNullPower); };
  
};

 

Файл имплементации нужен ? Ниже код. (Но, если совсем незнакомы с ООП, перегрузкой функций - то, боюсь, класс вам будет бесполезен)

#property library
#include <MyLib\Common\LSMBase.mqh>

double CLSMBase::_SummXc2()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);
  
   double dRes = 0;
   double dXi = EMPTY_VALUE;
  
   for(int iI=0; iI<_N(); ++iI)
      {
      dXi = _X(iI)-dX0;
      dRes += (dXi*dXi*_W(iI));
      };
     
   return(dRes);     
};

double CLSMBase::_SummXc3()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);
  
   double dRes = 0;
   double dXi = EMPTY_VALUE;
  
   for(int iI=0; iI<_N(); ++iI)
      {
      dXi = _X(iI)-dX0;
      dRes += (dXi*dXi*dXi*_W(iI));
      };
     
   return(dRes);     
};

double CLSMBase::_SummXc4()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);
  
   double dRes = 0;
   double dXi = EMPTY_VALUE;
  
   for(int iI=0; iI<_N(); ++iI)
      {
      dXi = _X(iI)-dX0;
      dRes += (dXi*dXi*dXi*dXi*_W(iI));
      };
     
   return(dRes);     
};

double CLSMBase::_SummXc5()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);
  
   double dRes = 0;
   double dXi = EMPTY_VALUE;
  
   for(int iI=0; iI<_N(); ++iI)
      {
      dXi = _X(iI)-dX0;
      dRes += (dXi*dXi*dXi*dXi*dXi*_W(iI));
      };
     
   return(dRes);     
};

double CLSMBase::_SummXc6()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);
  
   double dRes = 0;
   double dXi = EMPTY_VALUE;
  
   for(int iI=0; iI<_N(); ++iI)
      {
      dXi = _X(iI)-dX0;
      dRes += (dXi*dXi*dXi*dXi*dXi*dXi*_W(iI));
      };
     
   return(dRes);     
};

double CLSMBase::_SummXcYc()
{
   double dX0 = 0;
   double dY0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      {
      dX0 = _X(iPolarIdx);
      dY0 = _Y(iPolarIdx);
      };

   double dRes = 0;

   for(int iI=0; iI<_N(); ++iI)
      dRes += (_X(iI)-dX0)*(_Y(iI)-dY0)*_W(iI);

   return(dRes);     
};

double CLSMBase::_SummX2cYc()
{
   double dX0 = 0;
   double dY0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      {
      dX0 = _X(iPolarIdx);
      dY0 = _Y(iPolarIdx);
      };

   double dRes = 0;

   for(int iI=0; iI<_N(); ++iI)
      dRes += (_X(iI)*_X(iI)-dX0*dX0)*(_Y(iI)-dY0)*_W(iI);

   return(dRes);     
};

double CLSMBase::_SummX2cXc()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);

   double dRes = 0;

   for(int iI=0; iI<_N(); ++iI)
      dRes += (_X(iI)*_X(iI)-dX0*dX0)*(_X(iI)-dX0)*_W(iI);

   return(dRes);     
};

double CLSMBase::_SummXc()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);

   double dRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
         dRes += (_X(iI)-dX0)*_W(iI);
     
   return(dRes);     
};

double CLSMBase::_SummX2c2()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);

   double dRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
         dRes += (_X(iI)*_X(iI)-dX0*dX0)*(_X(iI)*_X(iI)-dX0*dX0)*_W(iI);
     
   return(dRes);     
};

double CLSMBase::_SummX3c2()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);

   double dRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
         dRes += (_X(iI)*_X(iI)*_X(iI)-dX0*dX0*dX0)*(_X(iI)*_X(iI)*_X(iI)-dX0*dX0*dX0)*_W(iI);
     
   return(dRes);     
};

double CLSMBase::_SummXcX2c()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);

   double dRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
         dRes += (_X(iI)-dX0)*(_X(iI)*_X(iI)-dX0*dX0)*_W(iI);
     
   return(dRes);     
};

double CLSMBase::_SummX3cX2c()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);

   double dRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
         dRes += (_X(iI)*_X(iI)*_X(iI)-dX0*dX0*dX0)*(_X(iI)*_X(iI)-dX0*dX0)*_W(iI);
     
   return(dRes);     
};

double CLSMBase::_SummX3cXc()
{
   double dX0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dX0 = _X(iPolarIdx);

   double dRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
         dRes += (_X(iI)*_X(iI)*_X(iI)-dX0*dX0*dX0)*(_X(iI)-dX0)*_W(iI);
     
   return(dRes);     
};

double CLSMBase::_SummX3cYc()
{
   double dX0 = 0;
   double dY0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      {
      dX0 = _X(iPolarIdx);
      dY0 = _Y(iPolarIdx);
      };

   double dRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
         dRes += (_X(iI)*_X(iI)*_X(iI)-dX0*dX0*dX0)*(_Y(iI)-dY0)*_W(iI);
     
   return(dRes);     
};

double CLSMBase::_SummYc()
{
   double dY0 = 0;
   int iPolarIdx = _PolarIdx();

   if(iPolarIdx>=0)
      dY0 = _Y(iPolarIdx);

   double dRes = 0;

   for(int iI=0; iI<_N(); ++iI)
      dRes += (_Y(iI)-dY0)*_W(iI);
     
   return(dRes);     
};

int CLSMBase::_SummW()
{
   int iRes = 0;
  
   for(int iI=0; iI<_N(); ++iI)
      iRes += _W(iI);
     
   return(iRes);     
};

double CLSMBase::_CountFlatLevel()
{
   double dRes = EMPTY_VALUE;
  
   double dEW = _SummW();

   if(dEW == 0)
      {
      ASSERT(false);
      return(EMPTY_VALUE);
      };
  
   return(_SummYc()/ dEW);
};


double CLSMBase::_CountPolarTrend(double & rdPolarLevel)
{
   ASSERT(_PolarIdx()>=0 && _PolarIdx()<_N());

   double dEXcYc = _SummXcYc();
   double dEXc2 = _SummXc2();
  
   if(dEXc2 == 0)
      {
      ASSERT(false);
      rdPolarLevel = EMPTY_VALUE;
      return(EMPTY_VALUE);
      };
  
   double dTrend = dEXcYc / dEXc2;
  
   rdPolarLevel = (_Y(_PolarIdx()) - dTrend * _X(_PolarIdx()));
  
   return(dTrend);
};

double CLSMBase::_CountTrend(double & rdLevel)
{
   ASSERT(_PolarIdx()== WRONG_VALUE);

   double dEYX = _SummXcYc();
   double dEW = _SummW();
   double dEX = _SummXc();
   double dEY = _SummYc();
   double dEX2 = _SummXc2();
  
   double dTrendS = (dEX2*dEW - dEX*dEX);

   if(dEW == 0 || dTrendS == 0)
      {
      ASSERT(false);
      rdLevel = EMPTY_VALUE;
      return(EMPTY_VALUE);
      };
  
   double dTrend = (dEYX * dEW - dEX*dEY)/dTrendS;  
  
   rdLevel = (dEY - dTrend * dEX)/dEW;
  
   return(dTrend);
};

void CLSMBase::_CountPolarParabola(double & rdSecondPower,double & rdFirstPower,double & rdNullPower)
{
   ASSERT(_PolarIdx()>=0 && _PolarIdx()<_N());

   double dX0 = _X(_PolarIdx());
   double dY0 = _Y(_PolarIdx());

   double dEX2cYc = _SummX2cYc();
   double dEXc2 = _SummXc2();
   double dEXcX2c = _SummXcX2c();
   double dEXcYc = _SummXcYc();
   double dEX2c2 = _SummX2c2();
  
   double dSecPowS = (dEX2c2*dEXc2 - dEXcX2c*dEXcX2c);
  
   if(dEXc2 == 0 || dSecPowS == 0)
      {
      ASSERT(false);
      rdSecondPower = EMPTY_VALUE;
      rdFirstPower = EMPTY_VALUE;
      rdNullPower = EMPTY_VALUE;
      return;
      };

  
   rdSecondPower = (dEX2cYc*dEXc2 - dEXcX2c*dEXcYc) / dSecPowS;
   rdFirstPower = (dEXcYc - rdSecondPower*dEXcX2c)/dEXc2;
   rdNullPower = dY0 - rdSecondPower*dX0*dX0 - rdFirstPower*dX0;

};   

void CLSMBase::_CountParabola(double & rdSecondPower,double & rdFirstPower,double & rdNullPower)
{
   ASSERT(_PolarIdx()== WRONG_VALUE);

   double dEXc4 = _SummXc4();
   double dEXc3 = _SummXc3();
   double dEXc2 = _SummXc2();
   double dEX2cYc = _SummX2cYc();
   double dEXc  = _SummXc();
   double dEXcYc =_SummXcYc();
   double dEW = _SummW();
   double dEYc  = _SummYc();
  
   double dDetBase = _Determinant_3(dEXc4,dEXc3,dEXc2,dEXc3,dEXc2,dEXc,dEXc2,dEXc,dEW);
  
   if(dDetBase == 0)
      {
      ASSERT(false);
      rdSecondPower = EMPTY_VALUE;
      rdFirstPower = EMPTY_VALUE;
      rdNullPower = EMPTY_VALUE;
      return;
      };

   double dDetSecond = _Determinant_3(dEX2cYc,dEXc3,dEXc2,dEXcYc,dEXc2,dEXc,dEYc,dEXc,dEW);
   double dDetFirst = _Determinant_3(dEXc4,dEX2cYc,dEXc2,dEXc3,dEXcYc,dEXc,dEXc2,dEYc,dEW);
   double dDetNull = _Determinant_3(dEXc4,dEXc3,dEX2cYc,dEXc3,dEXc2,dEXcYc,dEXc2,dEXc,dEYc);
  
   rdSecondPower = dDetSecond/dDetBase;
   rdFirstPower = dDetFirst/dDetBase;
   rdNullPower = dDetNull/dDetBase;
};   

void CLSMBase::_CountPolarCubic(double & rdThirdPower,double & rdSecondPower,double & rdFirstPower,double & rdNullPower)
{
   ASSERT(_PolarIdx()>=0 && _PolarIdx()<_N());

   double dX0 = _X(_PolarIdx());
   double dY0 = _Y(_PolarIdx());

   double dEX3c2 = _SummX3c2();
   double dEX3cX2c = _SummX3cX2c();
   double dEX3cXc = _SummX3cXc();
   double dEX3cYc = _SummX3cYc();
   double dEX2c2 = _SummX2c2();
   double dEX2cXc = _SummX2cXc();
   double dEX2cYc = _SummX2cYc();
   double dEXc2 = _SummXc2();
   double dEXcYc = _SummXcYc();

   double dDetBase = _Determinant_3(dEX3c2,dEX3cX2c,dEX3cXc,dEX3cX2c,dEX2c2,dEX2cXc,dEX3cXc,dEX2cXc,dEXc2);
  
   if(dDetBase == 0)
      {
      ASSERT(false);
      rdThirdPower = EMPTY_VALUE;
      rdSecondPower = EMPTY_VALUE;
      rdFirstPower = EMPTY_VALUE;
      rdNullPower = EMPTY_VALUE;
      return;
      };

   double dDetThird = _Determinant_3(dEX3cYc,dEX3cX2c,dEX3cXc,dEX2cYc,dEX2c2,dEX2cXc,dEXcYc,dEX2cXc,dEXc2);
   double dDetSecond = _Determinant_3(dEX3c2,dEX3cYc,dEX3cXc,dEX3cX2c,dEX2cYc,dEX2cXc,dEX3cXc,dEXcYc,dEXc2);
   double dDetFirst = _Determinant_3(dEX3c2,dEX3cX2c,dEX3cYc,dEX3cX2c,dEX2c2,dEX2cYc,dEX3cXc,dEX2cXc,dEXcYc);

   rdThirdPower = dDetThird/dDetBase;
   rdSecondPower = dDetSecond/dDetBase;
   rdFirstPower = dDetFirst/dDetBase;
   rdNullPower = dY0 - rdThirdPower*dX0*dX0*dX0 - rdSecondPower*dX0*dX0 - rdFirstPower*dX0;
  
};   

void CLSMBase::_CountCubic(double & rdThirdPower,double & rdSecondPower,double & rdFirstPower,double & rdNullPower)
{

   ASSERT(_PolarIdx()== WRONG_VALUE);

   double dEXc6 = _SummXc6();
   double dEXc5 = _SummXc5();
   double dEXc4 = _SummXc4();
   double dEXc3 = _SummXc3();
   double dEX3cYc = _SummX3cYc();
   double dEXc2 = _SummXc2();
   double dEX2cYc = _SummX2cYc();
   double dEXc =  _SummXc();
   double dEXcYc = _SummXcYc();
   double dEW =  _SummW();
   double dEYc =  _SummYc();


   double dDetBase = _Determinant_4(dEXc6,dEXc5,dEXc4,dEXc3,dEXc5,dEXc4,dEXc3,dEXc2,dEXc4,dEXc3,dEXc2,dEXc,dEXc3,dEXc2,dEXc,dEW);
  
   if(dDetBase == 0)
      {
      ASSERT(false);
      rdThirdPower = EMPTY_VALUE;
      rdSecondPower = EMPTY_VALUE;
      rdFirstPower = EMPTY_VALUE;
      rdNullPower = EMPTY_VALUE;
      return;
      };

   double dDetThird =   _Determinant_4(dEX3cYc, dEXc5,   dEXc4,   dEXc3,   dEX2cYc, dEXc4,   dEXc3,   dEXc2,   dEXcYc,  dEXc3,   dEXc2,   dEXc,    dEYc,    dEXc2,   dEXc, dEW);
   double dDetSecond =  _Determinant_4(dEXc6,   dEX3cYc, dEXc4,   dEXc3,   dEXc5,   dEX2cYc, dEXc3,   dEXc2,   dEXc4,   dEXcYc,  dEXc2,   dEXc,    dEXc3,   dEYc,    dEXc, dEW);
   double dDetFirst =   _Determinant_4(dEXc6,   dEXc5,   dEX3cYc, dEXc3,   dEXc5,   dEXc4,   dEX2cYc, dEXc2,   dEXc4,   dEXc3,   dEXcYc,  dEXc,    dEXc3,   dEXc2,   dEYc, dEW);
   double dDetNull =    _Determinant_4(dEXc6,   dEXc5,   dEXc4,   dEX3cYc, dEXc5,   dEXc4,   dEXc3,   dEX2cYc, dEXc4,   dEXc3,   dEXc2,   dEXcYc,  dEXc3,   dEXc2,   dEXc, dEYc);

   rdThirdPower = dDetThird/dDetBase;
   rdSecondPower = dDetSecond/dDetBase;
   rdFirstPower = dDetFirst/dDetBase;
   rdNullPower = dDetNull/dDetBase;
};   


double CLSMBase::_Determinant_4(double dX11,double dX12,double dX13,double dX14,double dX21,double dX22,double dX23,double dX24,double dX31,double dX32,double dX33,double dX34,double dX41,double dX42,double dX43,double dX44)
{
   double dDet11 = _Determinant_3(dX22,dX23,dX24,dX32,dX33,dX34,dX42,dX43,dX44);
   double dDet12 = _Determinant_3(dX21,dX23,dX24,dX31,dX33,dX34,dX41,dX43,dX44);
   double dDet13 = _Determinant_3(dX21,dX22,dX24,dX31,dX32,dX34,dX41,dX42,dX44);
   double dDet14 = _Determinant_3(dX21,dX22,dX23,dX31,dX32,dX33,dX41,dX42,dX43);
  
   return(dX11*dDet11-dX12*dDet12+dX13*dDet13-dX14*dDet14);
};


SLSMPowers CLSMBase::_CountLSM(ELSMType ltType)
{
   SLSMPowers lpResult;
  
   lpResult.m_dThirdPower = 0;
   lpResult.m_dSecondPower = 0;
   lpResult.m_dFirstPower = 0;
   lpResult.m_dNullPower = 0;

   switch(ltType)
      {
      case LSM_FLAT:
          lpResult.m_dNullPower = _CountFlatLevel();   
          break;
         
      case LSM_TREND:
         if(_PolarIdx() == WRONG_VALUE)
            lpResult.m_dFirstPower = _CountTrend(lpResult.m_dNullPower);  
         else
            lpResult.m_dFirstPower = _CountPolarTrend(lpResult.m_dNullPower);   
         break;
        
      case LSM_PARABOLIC:
         if(_PolarIdx() == WRONG_VALUE)
            _CountParabola(lpResult.m_dSecondPower,lpResult.m_dFirstPower,lpResult.m_dNullPower);   
         else  
            _CountPolarParabola(lpResult.m_dSecondPower,lpResult.m_dFirstPower,lpResult.m_dNullPower);   
         break;
     
      case LSM_CUBIC:
         if(_PolarIdx() == WRONG_VALUE)
            _CountCubic(lpResult.m_dThirdPower,lpResult.m_dSecondPower,lpResult.m_dFirstPower,lpResult.m_dNullPower);
         else  
            _CountPolarCubic(lpResult.m_dThirdPower,lpResult.m_dSecondPower,lpResult.m_dFirstPower,lpResult.m_dNullPower);
         break;
           
      default:
         break;
      };
     
   return(lpResult);     
};

 

Вот канал, рассчитанный с помощью данного класса (кубик):

То же место, тот же канал, но параболик:


 
George Merts:

У меня класс с виртуальными функциями - надо пронаследовать класс, и перегрузить эти функции. Ниже заголовочный файл, сможете пронаследовать класс, и перегрузить виртуальные функции:


 ...


спасибо за пример

я не уточнил: моя задача предполагает множественную регрессию y=f(x1,x1,x3...)

у Вас судя по определениям _X _Y считается 2-мерный случай 

сейчас пользуюсь тем что дает ALGLIB

при профилировании видно что большая часть времени уходит на SVD-разложение 

думал как бы так ловко вывернуться чтобы рассчитать кфц за 1 проход без Гаусса и использовать скользящие суммы

но похоже такие финты не пройдут

 
transcendreamer:


спасибо за пример

я не уточнил: моя задача предполагает множественную регрессию y=f(x1,x1,x3...)

у Вас судя по определениям _X _Y считается 2-мерный случай 

Да, у меня - двумерный случай.
 
George Merts:
Да, у меня - двумерный случай.
так или иначе - спасибо за пример - весьма поучительно