вторник, 14 марта 2017 г.

Степенная регрессия онлайн


Расчет реализован на основе написанного на Object Pascal математического модуля DMath (автор: Dr Jean DEBORD, Laboratoire de Pharmacologie, Faculte de Medecine 2 Rue du Docteur Marcland, 87025 Limoges, France).
На практике этот вид регрессионного анализа востребован меньше, чем полиномиальная регрессия.

Искомая зависимость:
Ссылка на страницу с онлайн-расчетом:


Что имеем в результате расчета (по выбору пользователя: или вывести результат в небольшом окне, или сохранить вместе с исходными данными в RTF-файл):


Исходный код (PHP):
<?php
// Степенная регрессия
header('Content-Type^ text/html; charset=utf-8');
if ($_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest'){
if ($_POST){
$dimdata = $_POST['dimdata'];// массив данных (абцисса и ордината) из таблицы)
$deg = $_POST['deg'];// В этом расчете не используется. Передается 1.
//
// уборщик "мусора" в temp
// источник:
// http://itheap.info/blog/web-master-blog/154.html
function clearTEMP() {
      $dir = 'temp';
      $files = scandir($dir); // сканирование файлов в папке и создание списка
      unset($files[0], $files[1]); // удаление из списка (массива) элементов ".",".."
      foreach ($files as $fname) { // цикл по списку файлов
            $filename = $dir .'/'. $fname; // создаем полный путь к файлу
            if (file_exists($filename)) { // проверяем наличии файла, за это время он уже мог удалиться
                $ftime = filemtime($filename); // определяем время создания/изменения файла
                $d_time = time() - $ftime; //определяем разницу между текущим временем и временем создания файла
                if ($d_time > 600) { //условие - если время больше чем [разница в сек] (10мин)
                    @unlink($filename); // удаляем файл
                }//if
            } //if
      }//foreach
      }
//
$rcount = count($dimdata)/2;
$Lb = 0; $Ub = $rcount-1;
$ErrCode = '0';
$B0 = 0;
$B1 = 0;
$filepng = 'xx';
for ($K=0; $K<=$Ub; $K++){
      $X[$K] = $dimdata[$K*2];
      $Y[$K] = $dimdata[$K*2+1];
      $xx[$K] = $dimdata[$K*2];
      $yy[$K] = $dimdata[$K*2+1];
}
$xmin = $xx[0];
$xmax = $xx[0];
$ymin = $yy[0];
for ($K=0; $K<=$Ub; $K++){
      if($xmin > $xx[$K]){$xmin = $xx[$K];}
      if($xmax < $xx[$K]){$xmax = $xx[$K];}
      if($ymin > $yy[$K]){$ymin = $yy[$K];}
}
$delta = ($xmax - $xmin)/99;
$P = -1;         
for ($K=0; $K<=$Ub; $K++){
      if($X[$K] > 0 && $Y[$K] > 0){
            $P++;                  
            $X1[$P] = Log($X[$K]);
            $Y1[$P] = Log($Y[$K]);
            $S1[$P] = 1.0 / $Y[$K];
      }
}                      
$SW = 0.0;
      $SWX = 0.0;
      $SWY = 0.0;
      $SWX2 = 0.0;
      $SWXY = 0.0;
for ($K=0; $K<=$P; $K++){
      if($S1[$K] <= 0){
            $ErrCode = 'Квази-сингулярная матрица';
            Exit;
      }
      $W = 1.0 / ($S1[$K]*$S1[$K]);
      $WX = $W * $X1[$K];
      $SW = $SW + $W;
      $SWX = $SWX + $WX;
      $SWY = $SWY + $W * $Y1[$K];
      $SWX2 = $SWX2 + $WX * $X1[$K];
      $SWXY = $SWXY + $WX * $Y1[$K];
}
      $D = $SW * $SWX2 - $SWX*$SWX;     
if($D <= 0){
      $ErrCode = 'Квази-сингулярная матрица';
      Exit;
} else {                                                  
            $V[0][0] = $SWX2 / $D;
            $V[0][1] = - $SWX / $D;
            $V[1][0] = $V[0][1];
            $V[1][1] = $SW / $D;
            $B[0] = $V[0][0] * $SWY + $V[0][1] * $SWXY;
            $B[1] = $V[1][0] * $SWY + $V[1][1] * $SWXY;
        // Коэффициенты:
      $B0 = exp($B[0]);
            $B1 = $B[1];
      $ErrCode = '1';             
      clearTEMP();
        // Построение графика
      // Утилита PChart. Для использования в php.ini
      // необходимо подключить php_gd2.dll
      include("pChart/pData.class");
      include("pChart/pChart.class");
      // Dataset definition
      $DataSet = new pData;
      for ($K=0; $K<=$Ub; $K++){
            $DataSet->AddPoint($xx[$K],"abscise");
            $DataSet->AddPoint($yy[$K],"indata");                     
            }
      for ($K=0; $K<=99; $K++){
            $xdot = $xmin + $delta*$K;
            $DataSet->AddPoint($xdot,"abscise2");
            $DataSet->AddPoint($B0*pow($xdot, $B1),"outdata");
      }
      $DataSet->AddAllSeries();    
      $DataSet->SetAbsciseLabelSerie();    
      $DataSet->SetSerieName("Исходные данные","indata");    
      $DataSet->SetSerieName("Результат расчета","outdata");
      $DataSet->SetXAxisName("абцисса");      
      $DataSet->SetYAxisName("ордината"); 
      // Initialise the graph
      $Test = new pChart(600,233);
      $Test->setColorPalette(0,0,0,200);
      $Test->setColorPalette(1,200,0,0);    
      $Test->setFontProperties("Fonts/tahoma.ttf",8);    
      $Test->setGraphArea(70,30,580,190);    
      $Test->drawFilledRoundedRectangle(7,7,593,228,1,240,240,240);     
      $Test->drawRoundedRectangle(5,5,595,230,3,128,57,67);    
      $Test->drawGraphArea(250,250,250,FALSE); 
      $Test->drawXYScale($DataSet->GetData(),$DataSet->GetDataDescription(),"indata","abscise",100,100,100,TRUE,0);                  
      $Test->drawGrid(3,FALSE,128,57,67,0);                     
      // Draw the 0 line    
      $Test->setFontProperties("Fonts/tahoma.ttf",6);    
      $Test->drawTreshold(0,50,50,50,TRUE,TRUE);       
      // Draw the line graph 
      $Test->drawXYPlotGraph($DataSet->GetData(),$DataSet->GetDataDescription(),"indata","abscise",0,2,1,230,230,230);        
            $Test->drawXYGraph($DataSet->GetData(),$DataSet->GetDataDescription(),"outdata","abscise2",1);
      // Finish the graph    
      $Test->setFontProperties("Fonts/tahoma.ttf",8);
      $DataSet->RemoveSerie("abscise");
      $DataSet->RemoveSerie("abscise2");
      $Test->drawLegend(75,35,$DataSet->GetDataDescription(),240,240,240);    
      $Test->setFontProperties("Fonts/tahoma.ttf",10);    
      $Test->drawTitle(60,22,"Степенная регрессия",10,10,10,585);
      //
      $file = substr(md5(microtime() . rand(0, 9999)), 0, 12);
      //
      $filepng = 'temp/chart_'.$file.'.'.'png';    
      $Test->Render($filepng);          
      }
$B0 = str_replace(".", ",", $B0);
$B1 = str_replace(".", ",", $B1);
//         
echo json_encode(array($ErrCode, $B0, $B1, $filepng));
}
}
?>