Ignore:
Timestamp:
Apr 14, 2019, 2:31:40 PM (5 years ago)
Author:
roby
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/client/modules/Elezioni/grafici/jpgraph_regstat.php

    r265 r267  
    1 <?php
     1<?php 
    22/*=======================================================================
    3  // File:        JPGRAPH_REGSTAT.PHP
    4  // Description: Regression and statistical analysis helper classes
    5  // Created:     2002-12-01
    6  // Ver:         $Id: jpgraph_regstat.php 1131 2009-03-11 20:08:24Z ljp $
    7  //
    8  // Copyright (c) Asial Corporation. All rights reserved.
    9  //========================================================================
    10  */
     3// File:        JPGRAPH_REGSTAT.PHP
     4// Description: Regression and statistical analysis helper classes
     5// Created:     2002-12-01
     6// Ver:         $Id: jpgraph_regstat.php 781 2006-10-08 08:07:47Z ljp $
     7//
     8// Copyright (c) Aditus Consulting. All rights reserved.
     9//========================================================================
     10*/
    1111
    1212//------------------------------------------------------------------------
     
    1919
    2020    private $xdata,$ydata;   // Data vectors
    21     private $y2;   // 2:nd derivate of ydata
     21    private $y2;                 // 2:nd derivate of ydata     
    2222    private $n=0;
    2323
    24     function __construct($xdata,$ydata) {
    25         $this->y2 = array();
    26         $this->xdata = $xdata;
    27         $this->ydata = $ydata;
    28 
    29         $n = count($ydata);
    30         $this->n = $n;
    31         if( $this->n !== count($xdata) ) {
    32             JpGraphError::RaiseL(19001);
    33             //('Spline: Number of X and Y coordinates must be the same');
    34         }
    35 
    36         // Natural spline 2:derivate == 0 at endpoints
    37         $this->y2[0]    = 0.0;
    38         $this->y2[$n-1] = 0.0;
    39         $delta[0] = 0.0;
    40 
    41         // Calculate 2:nd derivate
    42         for($i=1; $i < $n-1; ++$i) {
    43             $d = ($xdata[$i+1]-$xdata[$i-1]);
    44             if( $d == 0  ) {
    45                 JpGraphError::RaiseL(19002);
    46                 //('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
    47             }
    48             $s = ($xdata[$i]-$xdata[$i-1])/$d;
    49             $p = $s*$this->y2[$i-1]+2.0;
    50             $this->y2[$i] = ($s-1.0)/$p;
    51             $delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) -
    52             ($ydata[$i]-$ydata[$i-1])/($xdata[$i]-$xdata[$i-1]);
    53             $delta[$i] = (6.0*$delta[$i]/($xdata[$i+1]-$xdata[$i-1])-$s*$delta[$i-1])/$p;
    54         }
    55 
    56         // Backward substitution
    57         for( $j=$n-2; $j >= 0; --$j ) {
    58             $this->y2[$j] = $this->y2[$j]*$this->y2[$j+1] + $delta[$j];
    59         }
     24    function Spline($xdata,$ydata) {
     25        $this->y2 = array();
     26        $this->xdata = $xdata;
     27        $this->ydata = $ydata;
     28
     29        $n = count($ydata);
     30        $this->n = $n;
     31        if( $this->n !== count($xdata) ) {
     32            JpGraphError::RaiseL(19001);
     33//('Spline: Number of X and Y coordinates must be the same');
     34        }
     35
     36        // Natural spline 2:derivate == 0 at endpoints
     37        $this->y2[0]    = 0.0;
     38        $this->y2[$n-1] = 0.0;
     39        $delta[0] = 0.0;
     40
     41        // Calculate 2:nd derivate
     42        for($i=1; $i < $n-1; ++$i) {
     43            $d = ($xdata[$i+1]-$xdata[$i-1]);
     44            if( $d == 0  ) {
     45                JpGraphError::RaiseL(19002);
     46//('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
     47            }
     48            $s = ($xdata[$i]-$xdata[$i-1])/$d;
     49            $p = $s*$this->y2[$i-1]+2.0;
     50            $this->y2[$i] = ($s-1.0)/$p;
     51            $delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) -
     52                         ($ydata[$i]-$ydata[$i-1])/($xdata[$i]-$xdata[$i-1]);
     53            $delta[$i] = (6.0*$delta[$i]/($xdata[$i+1]-$xdata[$i-1])-$s*$delta[$i-1])/$p;
     54        }
     55
     56        // Backward substitution
     57        for( $j=$n-2; $j >= 0; --$j ) {
     58            $this->y2[$j] = $this->y2[$j]*$this->y2[$j+1] + $delta[$j];
     59        }
    6060    }
    6161
    6262    // Return the two new data vectors
    6363    function Get($num=50) {
    64         $n = $this->n ;
    65         $step = ($this->xdata[$n-1]-$this->xdata[0]) / ($num-1);
    66         $xnew=array();
    67         $ynew=array();
    68         $xnew[0] = $this->xdata[0];
    69         $ynew[0] = $this->ydata[0];
    70         for( $j=1; $j < $num; ++$j ) {
    71             $xnew[$j] = $xnew[0]+$j*$step;
    72             $ynew[$j] = $this->Interpolate($xnew[$j]);
    73         }
    74         return array($xnew,$ynew);
     64        $n = $this->n ;
     65        $step = ($this->xdata[$n-1]-$this->xdata[0]) / ($num-1);
     66        $xnew=array();
     67        $ynew=array();
     68        $xnew[0] = $this->xdata[0];
     69        $ynew[0] = $this->ydata[0];
     70        for( $j=1; $j < $num; ++$j ) {
     71            $xnew[$j] = $xnew[0]+$j*$step;
     72            $ynew[$j] = $this->Interpolate($xnew[$j]);
     73        }
     74        return array($xnew,$ynew);
    7575    }
    7676
     
    7878    function Interpolate($xpoint) {
    7979
    80         $max = $this->n-1;
    81         $min = 0;
    82 
    83         // Binary search to find interval
    84         while( $max-$min > 1 ) {
    85             $k = ($max+$min) / 2;
    86             if( $this->xdata[$k] > $xpoint )
    87             $max=$k;
    88             else
    89             $min=$k;
    90         }
    91 
    92         // Each interval is interpolated by a 3:degree polynom function
    93         $h = $this->xdata[$max]-$this->xdata[$min];
    94 
    95         if( $h == 0  ) {
    96             JpGraphError::RaiseL(19002);
    97             //('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
    98         }
    99 
    100 
    101         $a = ($this->xdata[$max]-$xpoint)/$h;
    102         $b = ($xpoint-$this->xdata[$min])/$h;
    103         return $a*$this->ydata[$min]+$b*$this->ydata[$max]+
    104         (($a*$a*$a-$a)*$this->y2[$min]+($b*$b*$b-$b)*$this->y2[$max])*($h*$h)/6.0;
     80        $max = $this->n-1;
     81        $min = 0;
     82
     83        // Binary search to find interval
     84        while( $max-$min > 1 ) {
     85            $k = ($max+$min) / 2;
     86            if( $this->xdata[$k] > $xpoint )
     87                $max=$k;
     88            else
     89                $min=$k;
     90        }       
     91
     92        // Each interval is interpolated by a 3:degree polynom function
     93        $h = $this->xdata[$max]-$this->xdata[$min];
     94
     95        if( $h == 0  ) {
     96            JpGraphError::RaiseL(19002);
     97//('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.');
     98        }
     99
     100
     101        $a = ($this->xdata[$max]-$xpoint)/$h;
     102        $b = ($xpoint-$this->xdata[$min])/$h;
     103        return $a*$this->ydata[$min]+$b*$this->ydata[$max]+
     104             (($a*$a*$a-$a)*$this->y2[$min]+($b*$b*$b-$b)*$this->y2[$max])*($h*$h)/6.0;
    105105    }
    106106}
     
    111111//------------------------------------------------------------------------
    112112class Bezier {
    113     /**
    114      * @author Thomas Despoix, openXtrem company
    115      * @license released under QPL
    116      * @abstract Bezier interoplated point generation,
    117      * computed from control points data sets, based on Paul Bourke algorithm :
    118      * http://local.wasp.uwa.edu.au/~pbourke/geometry/bezier/index2.html
    119      */
     113/**
     114 * @author Thomas Despoix, openXtrem company
     115 * @license released under QPL
     116 * @abstract Bezier interoplated point generation,
     117 * computed from control points data sets, based on Paul Bourke algorithm :
     118 * http://astronomy.swin.edu.au/~pbourke/curves/bezier/
     119 */
    120120    private $datax = array();
    121121    private $datay = array();
    122122    private $n=0;
    123 
    124     function __construct($datax, $datay, $attraction_factor = 1) {
    125         // Adding control point multiple time will raise their attraction power over the curve
    126         $this->n = count($datax);
    127         if( $this->n !== count($datay) ) {
    128             JpGraphError::RaiseL(19003);
    129             //('Bezier: Number of X and Y coordinates must be the same');
    130         }
    131         $idx=0;
    132         foreach($datax as $datumx) {
    133             for ($i = 0; $i < $attraction_factor; $i++) {
    134                 $this->datax[$idx++] = $datumx;
    135             }
    136         }
    137         $idx=0;
    138         foreach($datay as $datumy) {
    139             for ($i = 0; $i < $attraction_factor; $i++) {
    140                 $this->datay[$idx++] = $datumy;
    141             }
    142         }
    143         $this->n *= $attraction_factor;
    144     }
    145 
    146     /**
    147      * Return a set of data points that specifies the bezier curve with $steps points
    148      * @param $steps Number of new points to return
    149      * @return array($datax, $datay)
    150      */
     123 
     124    function Bezier($datax, $datay, $attraction_factor = 1) {
     125        // Adding control point multiple time will raise their attraction power over the curve
     126        $this->n = count($datax);
     127        if( $this->n !== count($datay) ) {
     128            JpGraphError::RaiseL(19003);
     129//('Bezier: Number of X and Y coordinates must be the same');
     130        }
     131        $idx=0;
     132        foreach($datax as $datumx) {
     133            for ($i = 0; $i < $attraction_factor; $i++) {
     134                $this->datax[$idx++] = $datumx;
     135            }
     136        }
     137        $idx=0;
     138        foreach($datay as $datumy) {
     139            for ($i = 0; $i < $attraction_factor; $i++) {
     140                $this->datay[$idx++] = $datumy;
     141            }
     142        }
     143        $this->n *= $attraction_factor;
     144    }
     145
    151146    function Get($steps) {
    152         $datax = array();
    153         $datay = array();
    154         for ($i = 0; $i < $steps; $i++) {
    155             list($datumx, $datumy) = $this->GetPoint((double) $i / (double) $steps);
    156             $datax[$i] = $datumx;
    157             $datay[$i] = $datumy;
    158         }
    159          
    160         $datax[] = end($this->datax);
    161         $datay[] = end($this->datay);
    162          
    163         return array($datax, $datay);
    164     }
    165 
    166     /**
    167      * Return one point on the bezier curve. $mu is the position on the curve where $mu is in the
    168      * range 0 $mu < 1 where 0 is tha start point and 1 is the end point. Note that every newly computed
    169      * point depends on all the existing points
    170      *
    171      * @param $mu Position on the bezier curve
    172      * @return array($x, $y)
    173      */
     147        $datax = array();
     148        $datay = array();
     149        for ($i = 0; $i < $steps; $i++) {
     150            list($datumx, $datumy) = $this->GetPoint((double) $i / (double) $steps);       
     151            $datax[] = $datumx;
     152            $datay[] = $datumy;
     153        }
     154   
     155        $datax[] = end($this->datax);
     156        $datay[] = end($this->datay);
     157   
     158        return array($datax, $datay);
     159    }
     160 
    174161    function GetPoint($mu) {
    175         $n = $this->n - 1;
    176         $k = 0;
    177         $kn = 0;
    178         $nn = 0;
    179         $nkn = 0;
    180         $blend = 0.0;
    181         $newx = 0.0;
    182         $newy = 0.0;
    183 
    184         $muk = 1.0;
    185         $munk = (double) pow(1-$mu,(double) $n);
    186 
    187         for ($k = 0; $k <= $n; $k++) {
    188             $nn = $n;
    189             $kn = $k;
    190             $nkn = $n - $k;
    191             $blend = $muk * $munk;
    192             $muk *= $mu;
    193             $munk /= (1-$mu);
    194             while ($nn >= 1) {
    195                 $blend *= $nn;
    196                 $nn--;
    197                 if ($kn > 1) {
    198                     $blend /= (double) $kn;
    199                     $kn--;
    200                 }
    201                 if ($nkn > 1) {
    202                     $blend /= (double) $nkn;
    203                     $nkn--;
    204                 }
    205             }
    206             $newx += $this->datax[$k] * $blend;
    207             $newy += $this->datay[$k] * $blend;
    208         }
    209 
    210         return array($newx, $newy);
     162        $n = $this->n - 1;
     163        $k = 0;
     164        $kn = 0;
     165        $nn = 0;
     166        $nkn = 0;
     167        $blend = 0.0;
     168        $newx = 0.0;
     169        $newy = 0.0;
     170
     171        $muk = 1.0;
     172        $munk = (double) pow(1-$mu,(double) $n);
     173
     174        for ($k = 0; $k <= $n; $k++) {
     175            $nn = $n;
     176            $kn = $k;
     177            $nkn = $n - $k;
     178            $blend = $muk * $munk;
     179            $muk *= $mu;
     180            $munk /= (1-$mu);
     181            while ($nn >= 1) {
     182                $blend *= $nn;
     183                $nn--;
     184                if ($kn > 1) {
     185                    $blend /= (double) $kn;
     186                    $kn--;
     187                }
     188                if ($nkn > 1) {
     189                    $blend /= (double) $nkn;
     190                    $nkn--;
     191                }
     192            }
     193            $newx += $this->datax[$k] * $blend;
     194            $newy += $this->datay[$k] * $blend;
     195        }
     196
     197        return array($newx, $newy);
    211198    }
    212199}
Note: See TracChangeset for help on using the changeset viewer.