[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/library/ezc/Graph/src/datasets/ -> average.php (source)

   1  <?php
   2  /**
   3   * File containing the ezcGraphDataSetAverage class
   4   *
   5   * @package Graph
   6   * @version 1.5
   7   * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
   8   * @license http://ez.no/licenses/new_bsd New BSD License
   9   */
  10  /**
  11   * Extension of basic dataset to represent averation.
  12   * Algorithm: http://en.wikipedia.org/wiki/Least_squares
  13   *
  14   * @property int $polynomOrder
  15   *           Maximum order of polygon to interpolate from points
  16   * @property int $resolution
  17   *           Resolution used to draw line in graph
  18   *
  19   * @version 1.5
  20   * @package Graph
  21   * @mainclass
  22   */
  23  class ezcGraphDataSetAveragePolynom extends ezcGraphDataSet 
  24  {
  25  
  26      /**
  27       * Source dataset to base averation on.
  28       * 
  29       * @var ezcGraphDataSet
  30       */
  31      protected $source;
  32  
  33      /**
  34       * Calculated averation polynom
  35       * 
  36       * @var ezcGraphPolynom
  37       */
  38      protected $polynom = false;
  39  
  40      /**
  41       * Minimum key
  42       * 
  43       * @var float
  44       */
  45      protected $min = false;
  46  
  47      /**
  48       * Maximum key
  49       * 
  50       * @var float
  51       */
  52      protected $max = false;
  53  
  54      /**
  55       * Position of the data iterator. Depends on the configured resolution.
  56       * 
  57       * @var int
  58       */
  59      protected $position = 0;
  60  
  61      /**
  62       * Container to hold the properties
  63       *
  64       * @var array(string=>mixed)
  65       */
  66      protected $properties;
  67  
  68      /**
  69       * Constructor
  70       * 
  71       * @param ezcGraphDataSet $dataset Dataset to interpolate
  72       * @param int $order Maximum order of interpolating polynom
  73       * @return void
  74       * @ignore
  75       */
  76      public function __construct( ezcGraphDataSet $dataset, $order = 3 )
  77      {
  78          parent::__construct();
  79  
  80          $this->properties['resolution'] = 100;
  81          $this->properties['polynomOrder'] = (int) $order;
  82  
  83          $this->source = $dataset;
  84      }
  85  
  86      /**
  87       * Options write access
  88       * 
  89       * @throws ezcBasePropertyNotFoundException
  90       *          If Option could not be found
  91       * @throws ezcBaseValueException
  92       *          If value is out of range
  93       * @param mixed $propertyName   Option name
  94       * @param mixed $propertyValue  Option value;
  95       * @return mixed
  96       */
  97      public function __set( $propertyName, $propertyValue ) 
  98      {
  99          switch ( $propertyName ) {
 100              case 'polynomOrder':
 101                  if ( !is_numeric( $propertyValue ) ||
 102                       ( $propertyValue < 0 ) )
 103                  {
 104                      throw new ezcBaseValueException( $propertyName, $propertyValue, 'int > 0' );
 105                  }
 106  
 107                  $this->properties['polynomOrder'] = (int) $propertyValue;
 108                  $this->polynom = false;
 109                  break;
 110              case 'resolution':
 111                  if ( !is_numeric( $propertyValue ) ||
 112                       ( $propertyValue < 1 ) )
 113                  {
 114                      throw new ezcBaseValueException( $propertyName, $propertyValue, 'int > 1' );
 115                  }
 116  
 117                  $this->properties['resolution'] = (int) $propertyValue;
 118                  break;
 119              default:
 120                  parent::__set( $propertyName, $propertyValue );
 121                  break;
 122          }
 123      }
 124  
 125      /**
 126       * Property get access.
 127       * Simply returns a given option.
 128       * 
 129       * @param string $propertyName The name of the option to get.
 130       * @return mixed The option value.
 131       *
 132       * @throws ezcBasePropertyNotFoundException
 133       *         If a the value for the property options is not an instance of
 134       */
 135      public function __get( $propertyName )
 136      {
 137          if ( array_key_exists( $propertyName, $this->properties ) )
 138          {
 139              return $this->properties[$propertyName];
 140          }
 141          return parent::__get( $propertyName );
 142      }
 143      
 144      /**
 145       * Build the polynom based on the given points.
 146       * 
 147       * @return void
 148       */
 149      protected function buildPolynom()
 150      {
 151          $points = array();
 152  
 153          foreach ( $this->source as $key => $value )
 154          {
 155              if ( !is_numeric( $key ) )
 156              {
 157                  throw new ezcGraphDatasetAverageInvalidKeysException();
 158              }
 159  
 160              if ( ( $this->min === false ) || ( $this->min > $key ) )
 161              {
 162                  $this->min = (float) $key;
 163              }
 164  
 165              if ( ( $this->max === false ) || ( $this->max < $key ) )
 166              {
 167                  $this->max = (float) $key;
 168              }
 169  
 170              $points[] = new ezcGraphCoordinate( (float) $key, (float) $value );
 171          }
 172  
 173          // Build transposed and normal Matrix out of coordiantes
 174          $a = new ezcGraphMatrix( count( $points ), $this->polynomOrder + 1 );
 175          $b = new ezcGraphMatrix( count( $points ), 1 );
 176  
 177          for ( $i = 0; $i <= $this->properties['polynomOrder']; ++$i )
 178          {
 179              foreach ( $points as $nr => $point )
 180              {
 181                  $a->set( $nr, $i, pow( $point->x, $i ) );
 182                  $b->set( $nr, 0, $point->y );
 183              }
 184          }
 185  
 186          $at = clone $a;
 187          $at->transpose();
 188          
 189          $left = $at->multiply( $a );
 190          $right = $at->multiply( $b );
 191  
 192          $this->polynom = $left->solveNonlinearEquatation( $right );
 193      }
 194  
 195      /**
 196       * Returns a polynom of the defined order witch matches the datapoints
 197       * using the least squares algorithm.
 198       * 
 199       * @return ezcGraphPolynom Polynom
 200       */
 201      public function getPolynom()
 202      {
 203          if ( $this->polynom === false )
 204          {
 205              $this->buildPolynom();
 206          }
 207  
 208          return $this->polynom;
 209      }
 210  
 211      /**
 212       * Get the x coordinate for the current position
 213       * 
 214       * @param int $position Position
 215       * @return float x coordinate
 216       */
 217      protected function getKey()
 218      {
 219          $polynom = $this->getPolynom();
 220          return $this->min +
 221              ( $this->max - $this->min ) / $this->resolution * $this->position;
 222      }
 223      
 224      /**
 225       * Returns true if the given datapoint exists
 226       * Allows isset() using ArrayAccess.
 227       * 
 228       * @param string $key The key of the datapoint to get.
 229       * @return bool Wether the key exists.
 230       */
 231      public function offsetExists( $key )
 232      {
 233          $polynom = $this->getPolynom();
 234          return ( ( $key >= $this->min ) && ( $key <= $this->max ) );
 235      }
 236  
 237      /**
 238       * Returns the value for the given datapoint
 239       * Get an datapoint value by ArrayAccess.
 240       * 
 241       * @param string $key The key of the datapoint to get.
 242       * @return float The datapoint value.
 243       */
 244      public function offsetGet( $key )
 245      {
 246          $polynom = $this->getPolynom();
 247          return $polynom->evaluate( $key );
 248      }
 249  
 250      /**
 251       * Throws a ezcBasePropertyPermissionException because single datapoints
 252       * cannot be set in average datasets.
 253       * 
 254       * @param string $key The kex of a datapoint to set.
 255       * @param float $value The value for the datapoint.
 256       * @throws ezcBasePropertyPermissionException
 257       *         Always, because access is readonly.
 258       * @return void
 259       */
 260      public function offsetSet( $key, $value )
 261      {
 262          throw new ezcBasePropertyPermissionException( $key, ezcBasePropertyPermissionException::READ );
 263      }
 264  
 265      /**
 266       * Returns the currently selected datapoint.
 267       *
 268       * This method is part of the Iterator interface to allow access to the 
 269       * datapoints of this row by iterating over it like an array (e.g. using
 270       * foreach).
 271       * 
 272       * @return string The currently selected datapoint.
 273       */
 274      final public function current()
 275      {
 276          $polynom = $this->getPolynom();
 277          return $polynom->evaluate( $this->getKey() );
 278      }
 279  
 280      /**
 281       * Returns the next datapoint and selects it or false on the last datapoint.
 282       *
 283       * This method is part of the Iterator interface to allow access to the 
 284       * datapoints of this row by iterating over it like an array (e.g. using
 285       * foreach).
 286       *
 287       * @return float datapoint if it exists, or false.
 288       */
 289      final public function next()
 290      {
 291          if ( ++$this->position >= $this->resolution )
 292          {
 293              return false;
 294          }
 295          else 
 296          {
 297              return $this->current();
 298          }
 299      }
 300  
 301      /**
 302       * Returns the key of the currently selected datapoint.
 303       *
 304       * This method is part of the Iterator interface to allow access to the 
 305       * datapoints of this row by iterating over it like an array (e.g. using
 306       * foreach).
 307       * 
 308       * @return string The key of the currently selected datapoint.
 309       */
 310      final public function key()
 311      {
 312          return (string) $this->getKey();
 313      }
 314  
 315      /**
 316       * Returns if the current datapoint is valid.
 317       *
 318       * This method is part of the Iterator interface to allow access to the 
 319       * datapoints of this row by iterating over it like an array (e.g. using
 320       * foreach).
 321       *
 322       * @return bool If the current datapoint is valid
 323       */
 324      final public function valid()
 325      {
 326          $polynom = $this->getPolynom();
 327  
 328          if ( $this->min >= $this->max )
 329          {
 330              return false;
 331          }
 332  
 333          return ( ( $this->getKey() >= $this->min ) && ( $this->getKey() <= $this->max ) );
 334      }
 335  
 336      /**
 337       * Selects the very first datapoint and returns it.
 338       * This method is part of the Iterator interface to allow access to the 
 339       * datapoints of this row by iterating over it like an array (e.g. using
 340       * foreach).
 341       *
 342       * @return float The very first datapoint.
 343       */
 344      final public function rewind()
 345      {
 346          $this->position = 0;
 347      }
 348  
 349      /**
 350       * Returns the number of elements in this dataset
 351       * 
 352       * @return int
 353       */
 354      public function count()
 355      {
 356          return $this->resolution;
 357      }
 358  }
 359  ?>


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7