| [ Index ] |
PHP Cross Reference of MantisBT |
[Summary view] [Print] [Text view]
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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Jul 28 15:48:31 2011 | Cross-referenced by PHPXref 0.7 |