abstract class AbstractUnitsMathematicalOperator in Units of Measurement 7.2
Abstract implementation of "mathematical operator" interface.
Hierarchy
- class \AbstractUnitsMathematicalOperator implements UnitsMathematicalOperatorInterface
Expanded class hierarchy of AbstractUnitsMathematicalOperator
File
- ./
units.module, line 1289 - Provide API for managing and converting units of measurement.
View source
abstract class AbstractUnitsMathematicalOperator implements UnitsMathematicalOperatorInterface {
/**
* Definition of the underlying cTools 'operator' plugin.
*
* @var array
*/
protected $operator;
/**
* Operand #1 of this mathematical expression.
*
* @var UnitsMathematicalExpression
*/
protected $operand1;
/**
* Operand #2 of this mathematical expression.
*
* @var UnitsMathematicalExpression
*/
protected $operand2;
/**
* UnitsOperatorMathematicalExpression constructor.
*
* @param array $operator
* Definition of a cTools 'operator' plugin that represents the specific
* operator
* @param \UnitsMathematicalExpression $operand1
* Operand #1 for this mathematical expression
* @param \UnitsMathematicalExpression $operand2
* Operand #2 for this mathematical expression
*/
public function __construct($operator, UnitsMathematicalExpression $operand1, UnitsMathematicalExpression $operand2) {
$this->operator = $operator;
$this->operand1 = $operand1;
$this->operand2 = $operand2;
}
/**
* Determine physical dimension of this mathematical expression.
*
* @return array
* Dimension array of this mathematical expression
*/
public function dimension() {
$dimension_callback = ctools_plugin_get_function($this->operator, 'dimension callback');
list($evaluate1, $evaluate2) = $this
->evaluateOperands();
return $dimension_callback($this->operand1
->dimension(), $this->operand2
->dimension(), $evaluate1, $evaluate2);
}
/**
* Test whether this mathematical expression includes a dimensionless member.
*
* Whether this mathematical expression contains at least 1 dimensionless
* member.
*
* @return bool
* Whether this mathematical expression contains at least 1 dimensionless
* member
*/
public function containsDimensionlessMember() {
return $this->operand1
->containsDimensionlessMember() || $this->operand2
->containsDimensionlessMember();
}
/**
* Format a certain amount of quantity within this mathematical expression.
*
* @param float $quantity
* Quantity to be formatted
*
* @return UnitsMathematicalExpression
* Formatted quantity into this mathematical expression. Sometimes the
* mathematical expression itself must mutate in order to format the
* quantity. So the returned mathematical expression may not necessarily be
* the mathematical expression on which this method was invoked. For
* example, the expression "unit" would mutate into "1 * unit" in order to
* have a dimensionless member and therefore be able to format the $quantity
*/
public function formatQuantity($quantity) {
$contains_dimensionless1 = $this->operand1
->containsDimensionlessMember();
$contains_dimensionless2 = $this->operand2
->containsDimensionlessMember();
list($quantity1, $quantity2) = $this
->evaluateOperands();
if ($contains_dimensionless1 xor $contains_dimensionless2) {
if ($contains_dimensionless1) {
$this->operand1
->formatQuantity($quantity / $quantity2);
}
else {
$this->operand2
->formatQuantity($quantity / $quantity1);
}
}
else {
$split_quantity = ctools_plugin_get_function($this->operator, 'split quantity callback');
list($quantity1, $quantity2) = $split_quantity($quantity, $quantity1, $quantity2, $this->operator);
$this->operand1
->formatQuantity($quantity1);
$this->operand2
->formatQuantity($quantity2);
}
return $this;
}
/**
* Numerically evaluate this mathematical expression.
*
* @return float
* Numerical value of this mathematical expression
*
* @throws UnitsMathematicalExpressionDimensionException
* Exception is thrown if this mathematical expression has inconsistency in
* physical dimensions
*/
public function evaluate() {
if ($this->operator['dimension check'] && !units_dimension_equal($this->operand1
->dimension(), $this->operand2
->dimension())) {
throw new UnitsMathematicalExpressionDimensionException();
}
list($evaluate1, $evaluate2) = $this
->evaluateOperands();
$evaluate_callback = ctools_plugin_get_function($this->operator, 'evaluate callback');
return $evaluate_callback($evaluate1, $evaluate2);
}
/**
* Decompose (simplify) this mathematical expression.
*
* @return UnitsMathematicalExpression
* Decomposed (simplified) version of this mathematical expression
*/
public function decompose() {
return units_mathematical_expression_operator_construct($this->operator, $this
->operand1()
->decompose(), $this
->operand2()
->decompose());
}
/**
* Represent this mathematical expression in postfix notation.
*
* Represent this mathematical expression in postfix (reverse polish)
* notation.
*
* @param array $options
* Options regarding how to format this mathematical expression
*
* @return string
* Postfix (reverse polish) notation representation of this mathematical
* expression
*/
public function toPostfix($options = array()) {
return implode(' ', array(
$this->operand1
->toPostfix(),
$this->operand2
->toPostfix(),
$this->operator['sign'],
));
}
/**
* Represent this mathematical expression in human-friendly infix notation.
*
* @param array $options
* Options regarding how to format this mathematical expression
*
* @return string
* Human-friendly formatted version of this mathematical expression taking
* into account provided $options
*/
public function toInfix($options = array()) {
$child_options = array(
'parent precedence' => $this->operator['precedence'],
) + $options;
$output = implode(' ', array(
$this->operand1
->toInfix(array(
'operand' => 1,
) + $child_options),
$this->operator['sign'],
$this->operand2
->toInfix(array(
'operand' => 2,
) + $child_options),
));
if (isset($options['parent precedence']) && ($options['parent precedence'] > $this->operator['precedence'] || $options['operand'] == 2 && $options['parent precedence'] == $this->operator['precedence'])) {
$output = '( ' . $output . ' )';
}
return $output;
}
/**
* Whether this expression is linearly decomposable.
*
* @return bool
* Whether this expression is linearly decomposable, i.e. its decomposition
* can be plugged in into another mathematical expression via multiplication
* without losing sense
*/
public function isLinear() {
return TRUE;
}
/**
* Save the mathematical expression into database.
*
* @param int $mathematical_expression_id
* If the ID of the mathematical expression is known, under which it should
* be saved, provide it here. Otherwise it will be generated automatically
* @param int $order
* Order of this member when the mathematical expression is written down in
* postfix notation. Primarily this argument is used for internal purposes
*
* @return int
* Mathematical expression ID under which this expression has been saved in
* the database
*/
public function unitsMathematicalExpressionSave($mathematical_expression_id, &$order) {
$mathematical_expression_id = $this
->operand1()
->unitsMathematicalExpressionSave($mathematical_expression_id, $order);
$this
->operand2()
->unitsMathematicalExpressionSave($mathematical_expression_id, $order);
db_insert('units_mathematical_expression_postfix')
->fields(array(
'mathematical_expression_id' => $mathematical_expression_id,
'type' => UNITS_TOKEN_TYPE_OPERATOR,
'value_string' => $this->operator['name'],
'postfix_order' => ++$order,
))
->execute();
return $mathematical_expression_id;
}
/**
* Retrieve operand #1 from this mathematical operator.
*
* @return UnitsMathematicalExpression
* Operand #1 from this mathematical expression
*/
public function operand1() {
return $this->operand1;
}
/**
* Retrieve operand #2 from this mathematical operator.
*
* @return UnitsConstantMathematicalExpression
* Operand #2 from this mathematical expression
*/
public function operand2() {
return $this->operand2;
}
/**
* Numerically isolate a certain operand of this mathematical expression.
*
* Given result of this mathematical expression, numerically, i.e.
* dimensionlessly isolate a certain operand of this mathematical expression.
*
* @param \UnitsMathematicalExpression $equal_expression
* Result of this mathematical expression
* @param int $operand_to_isolate
* What operand of this mathematical expression to isolate. Allowed values
* are:
* - 1: to isolate operand #1
* - 2: to isolate operand #2
*
* @return UnitsConstantMathematicalExpression
* Mathematical expression to which the isolated member numerically equals
*/
public function isolateOperand(UnitsMathematicalExpression $equal_expression, $operand_to_isolate) {
$isolate_callback = ctools_plugin_get_function($this->operator, 'isolate operand callback');
if ($isolate_callback) {
list($operand1, $operand2) = $this
->evaluateOperands();
if ($operand_to_isolate == 1) {
$operand1 = $this
->operand1();
$operand2 = new UnitsConstantMathematicalExpression($operand2);
}
else {
$operand1 = new UnitsConstantMathematicalExpression($operand1);
$operand2 = $this
->operand2();
}
return $isolate_callback($operand1, $operand2, $equal_expression, $operand_to_isolate);
}
}
/**
* Numerically evaluate both operands and return them as an array.
*
* @return array
* Array of length 2: the 2 operands numerically evaluated
*/
protected function evaluateOperands() {
$evaluate1 = $this->operand1
->evaluate();
$evaluate2 = $this->operand2
->evaluate();
if (is_null($evaluate1)) {
$evaluate1 = $this->operator['transparent operand1'];
}
if (is_null($evaluate2)) {
$evaluate2 = $this->operator['transparent operand2'];
}
return array(
$evaluate1,
$evaluate2,
);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AbstractUnitsMathematicalOperator:: |
protected | property | Operand #1 of this mathematical expression. | |
AbstractUnitsMathematicalOperator:: |
protected | property | Operand #2 of this mathematical expression. | |
AbstractUnitsMathematicalOperator:: |
protected | property | Definition of the underlying cTools 'operator' plugin. | |
AbstractUnitsMathematicalOperator:: |
public | function |
Test whether this mathematical expression includes a dimensionless member. Overrides UnitsMathematicalExpression:: |
|
AbstractUnitsMathematicalOperator:: |
public | function |
Decompose (simplify) this mathematical expression. Overrides UnitsMathematicalExpression:: |
1 |
AbstractUnitsMathematicalOperator:: |
public | function |
Determine physical dimension of this mathematical expression. Overrides UnitsMathematicalExpression:: |
1 |
AbstractUnitsMathematicalOperator:: |
public | function |
Numerically evaluate this mathematical expression. Overrides UnitsMathematicalExpression:: |
1 |
AbstractUnitsMathematicalOperator:: |
protected | function | Numerically evaluate both operands and return them as an array. | |
AbstractUnitsMathematicalOperator:: |
public | function |
Format a certain amount of quantity within this mathematical expression. Overrides UnitsMathematicalExpression:: |
1 |
AbstractUnitsMathematicalOperator:: |
public | function |
Whether this expression is linearly decomposable. Overrides UnitsMathematicalExpression:: |
1 |
AbstractUnitsMathematicalOperator:: |
public | function |
Numerically isolate a certain operand of this mathematical expression. Overrides UnitsMathematicalOperatorInterface:: |
|
AbstractUnitsMathematicalOperator:: |
public | function |
Retrieve operand #1 from this mathematical operator. Overrides UnitsMathematicalOperatorInterface:: |
|
AbstractUnitsMathematicalOperator:: |
public | function |
Retrieve operand #2 from this mathematical operator. Overrides UnitsMathematicalOperatorInterface:: |
|
AbstractUnitsMathematicalOperator:: |
public | function |
Represent this mathematical expression in human-friendly infix notation. Overrides UnitsMathematicalExpression:: |
|
AbstractUnitsMathematicalOperator:: |
public | function |
Represent this mathematical expression in postfix notation. Overrides UnitsMathematicalExpression:: |
|
AbstractUnitsMathematicalOperator:: |
public | function |
Save the mathematical expression into database. Overrides UnitsMathematicalExpression:: |
|
AbstractUnitsMathematicalOperator:: |
public | function | UnitsOperatorMathematicalExpression constructor. | 1 |