/lib/zeta/Graph/src/datasets/average.php
https://gitlab.com/OnBlox/OnBlox-Template · PHP · 375 lines · 151 code · 37 blank · 187 comment · 16 complexity · 83f21448be84c97258cee4ed0afeb2a0 MD5 · raw file
- <?php
- /**
- * File containing the ezcGraphDataSetAverage class
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * @package Graph
- * @version //autogentag//
- * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
- */
- /**
- * Extension of basic dataset to represent averation.
- * Algorithm: http://en.wikipedia.org/wiki/Least_squares
- *
- * @property int $polynomOrder
- * Maximum order of polygon to interpolate from points
- * @property int $resolution
- * Resolution used to draw line in graph
- *
- * @version //autogentag//
- * @package Graph
- * @mainclass
- */
- class ezcGraphDataSetAveragePolynom extends ezcGraphDataSet
- {
- /**
- * Source dataset to base averation on.
- *
- * @var ezcGraphDataSet
- */
- protected $source;
- /**
- * Calculated averation polynom
- *
- * @var ezcGraphPolynom
- */
- protected $polynom = false;
- /**
- * Minimum key
- *
- * @var float
- */
- protected $min = false;
- /**
- * Maximum key
- *
- * @var float
- */
- protected $max = false;
- /**
- * Position of the data iterator. Depends on the configured resolution.
- *
- * @var int
- */
- protected $position = 0;
- /**
- * Container to hold the properties
- *
- * @var array(string=>mixed)
- */
- protected $properties;
- /**
- * Constructor
- *
- * @param ezcGraphDataSet $dataset Dataset to interpolate
- * @param int $order Maximum order of interpolating polynom
- * @return void
- * @ignore
- */
- public function __construct( ezcGraphDataSet $dataset, $order = 3 )
- {
- parent::__construct();
- $this->properties['resolution'] = 100;
- $this->properties['polynomOrder'] = (int) $order;
- $this->source = $dataset;
- }
- /**
- * Options write access
- *
- * @throws ezcBasePropertyNotFoundException
- * If Option could not be found
- * @throws ezcBaseValueException
- * If value is out of range
- * @param mixed $propertyName Option name
- * @param mixed $propertyValue Option value;
- * @return mixed
- */
- public function __set( $propertyName, $propertyValue )
- {
- switch ( $propertyName ) {
- case 'polynomOrder':
- if ( !is_numeric( $propertyValue ) ||
- ( $propertyValue < 0 ) )
- {
- throw new ezcBaseValueException( $propertyName, $propertyValue, 'int > 0' );
- }
- $this->properties['polynomOrder'] = (int) $propertyValue;
- $this->polynom = false;
- break;
- case 'resolution':
- if ( !is_numeric( $propertyValue ) ||
- ( $propertyValue < 1 ) )
- {
- throw new ezcBaseValueException( $propertyName, $propertyValue, 'int > 1' );
- }
- $this->properties['resolution'] = (int) $propertyValue;
- break;
- default:
- parent::__set( $propertyName, $propertyValue );
- break;
- }
- }
- /**
- * Property get access.
- * Simply returns a given option.
- *
- * @param string $propertyName The name of the option to get.
- * @return mixed The option value.
- *
- * @throws ezcBasePropertyNotFoundException
- * If a the value for the property options is not an instance of
- */
- public function __get( $propertyName )
- {
- if ( array_key_exists( $propertyName, $this->properties ) )
- {
- return $this->properties[$propertyName];
- }
- return parent::__get( $propertyName );
- }
-
- /**
- * Build the polynom based on the given points.
- *
- * @return void
- */
- protected function buildPolynom()
- {
- $points = array();
- foreach ( $this->source as $key => $value )
- {
- if ( !is_numeric( $key ) )
- {
- throw new ezcGraphDatasetAverageInvalidKeysException();
- }
- if ( ( $this->min === false ) || ( $this->min > $key ) )
- {
- $this->min = (float) $key;
- }
- if ( ( $this->max === false ) || ( $this->max < $key ) )
- {
- $this->max = (float) $key;
- }
- $points[] = new ezcGraphCoordinate( (float) $key, (float) $value );
- }
- // Build transposed and normal Matrix out of coordiantes
- $a = new ezcGraphMatrix( count( $points ), $this->polynomOrder + 1 );
- $b = new ezcGraphMatrix( count( $points ), 1 );
- for ( $i = 0; $i <= $this->properties['polynomOrder']; ++$i )
- {
- foreach ( $points as $nr => $point )
- {
- $a->set( $nr, $i, pow( $point->x, $i ) );
- $b->set( $nr, 0, $point->y );
- }
- }
- $at = clone $a;
- $at->transpose();
-
- $left = $at->multiply( $a );
- $right = $at->multiply( $b );
- $this->polynom = $left->solveNonlinearEquatation( $right );
- }
- /**
- * Returns a polynom of the defined order witch matches the datapoints
- * using the least squares algorithm.
- *
- * @return ezcGraphPolynom Polynom
- */
- public function getPolynom()
- {
- if ( $this->polynom === false )
- {
- $this->buildPolynom();
- }
- return $this->polynom;
- }
- /**
- * Get the x coordinate for the current position
- *
- * @param int $position Position
- * @return float x coordinate
- */
- protected function getKey()
- {
- $polynom = $this->getPolynom();
- return $this->min +
- ( $this->max - $this->min ) / $this->resolution * $this->position;
- }
-
- /**
- * Returns true if the given datapoint exists
- * Allows isset() using ArrayAccess.
- *
- * @param string $key The key of the datapoint to get.
- * @return bool Wether the key exists.
- */
- public function offsetExists( $key )
- {
- $polynom = $this->getPolynom();
- return ( ( $key >= $this->min ) && ( $key <= $this->max ) );
- }
- /**
- * Returns the value for the given datapoint
- * Get an datapoint value by ArrayAccess.
- *
- * @param string $key The key of the datapoint to get.
- * @return float The datapoint value.
- */
- public function offsetGet( $key )
- {
- $polynom = $this->getPolynom();
- return $polynom->evaluate( $key );
- }
- /**
- * Throws a ezcBasePropertyPermissionException because single datapoints
- * cannot be set in average datasets.
- *
- * @param string $key The kex of a datapoint to set.
- * @param float $value The value for the datapoint.
- * @throws ezcBasePropertyPermissionException
- * Always, because access is readonly.
- * @return void
- */
- public function offsetSet( $key, $value )
- {
- throw new ezcBasePropertyPermissionException( $key, ezcBasePropertyPermissionException::READ );
- }
- /**
- * Returns the currently selected datapoint.
- *
- * This method is part of the Iterator interface to allow access to the
- * datapoints of this row by iterating over it like an array (e.g. using
- * foreach).
- *
- * @return string The currently selected datapoint.
- */
- final public function current()
- {
- $polynom = $this->getPolynom();
- return $polynom->evaluate( $this->getKey() );
- }
- /**
- * Returns the next datapoint and selects it or false on the last datapoint.
- *
- * This method is part of the Iterator interface to allow access to the
- * datapoints of this row by iterating over it like an array (e.g. using
- * foreach).
- *
- * @return float datapoint if it exists, or false.
- */
- final public function next()
- {
- if ( ++$this->position >= $this->resolution )
- {
- return false;
- }
- else
- {
- return $this->current();
- }
- }
- /**
- * Returns the key of the currently selected datapoint.
- *
- * This method is part of the Iterator interface to allow access to the
- * datapoints of this row by iterating over it like an array (e.g. using
- * foreach).
- *
- * @return string The key of the currently selected datapoint.
- */
- final public function key()
- {
- return (string) $this->getKey();
- }
- /**
- * Returns if the current datapoint is valid.
- *
- * This method is part of the Iterator interface to allow access to the
- * datapoints of this row by iterating over it like an array (e.g. using
- * foreach).
- *
- * @return bool If the current datapoint is valid
- */
- final public function valid()
- {
- $polynom = $this->getPolynom();
- if ( $this->min >= $this->max )
- {
- return false;
- }
- return ( ( $this->getKey() >= $this->min ) && ( $this->getKey() <= $this->max ) );
- }
- /**
- * Selects the very first datapoint and returns it.
- * This method is part of the Iterator interface to allow access to the
- * datapoints of this row by iterating over it like an array (e.g. using
- * foreach).
- *
- * @return float The very first datapoint.
- */
- final public function rewind()
- {
- $this->position = 0;
- }
- /**
- * Returns the number of elements in this dataset
- *
- * @return int
- */
- public function count()
- {
- return $this->resolution;
- }
- }
- ?>