matrix.php
来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PHP 代码 · 共 1,490 行 · 第 1/4 页
PHP
1,490 行
} } $this->_data[$row] = $arr; return true; }/*}}}*/ /** * Returns the column with the given index * * This method checks that matrix has been initialized and that the * column requested is not outside the range of column. * * @param integer $col * @param optional boolean $asVector whether to return a Math_Vector or a simple array. Default = false. * @access public * @return mixed an array number on success, a PEAR_Error otherwise */ function getCol ($col, $asVector=false) {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } if (is_integer($col) && $col >= $this->_num_cols) { return PEAR::raiseError('Incorrect column value'); } for ($i=0; $i < $this->_num_rows; $i++) { $ret[$i] = $this->getElement($i,$col); } if ($asVector) { $classes = get_declared_classes(); if (!in_array("math_vector", $classes) || !in_array("math_vectopop", $classes)) { return PEAR::raiseError ("Classes Math_Vector and Math_VectorOp undefined". " add \"require_once 'Math/Vector/Vector.php'\" to your script"); } return new Math_Vector($ret); } else { return $ret; } }/*}}}*/ /** * Sets the column with the given index to the array * * This method checks that the column is less than the size of the matrix * columns, and that the array size equals the number of rows in the * matrix. * * @param integer $col index of the column * @param array $arr array of numbers * @access public * @return mixed TRUE on success, a PEAR_Error otherwise */ function setCol ($col, $arr) {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } if ($col >= $this->_num_cols) { return PEAR::raiseError('Incorrect column value'); } if (count($arr) != $this->_num_cols) { return PEAR::raiseError('Incorrect size for matrix column'); } for ($i=0; $i < $this->_num_rows; $i++) { if (!is_numeric($arr[$i])) { return PEAR::raiseError('Incorrect values, expecting numbers'); } else { $err = $this->setElement($i, $col, $arr[$i]); if (PEAR::isError($err)) { return $err; } } } return true; }/*}}}*/ /** * Swaps the rows with the given indices * * @param integer $i * @param integer $j * @access public * @return mixed TRUE on success, a PEAR_Error otherwise */ function swapRows($i, $j) {/*{{{*/ $r1 = $this->getRow($i); if (PEAR::isError($r1)) { return $r1; } $r2 = $this->getRow($j); if (PEAR::isError($r2)) { return $r2; } $e = $this->setRow($j, $r1); if (PEAR::isError($e)) { return $e; } $e = $this->setRow($i, $r2); if (PEAR::isError($e)) { return $e; } return true; }/*}}}*/ /** * Swaps the columns with the given indices * * @param integer $i * @param integer $j * @access public * @return mixed TRUE on success, a PEAR_Error otherwise */ function swapCols($i, $j) {/*{{{*/ $r1 = $this->getCol($i); if (PEAR::isError($r1)) { return $r1; } $r2 = $this->getCol($j); if (PEAR::isError($r2)) { return $r2; } $e = $this->setCol($j, $r1); if (PEAR::isError($e)) { return $e; } $e = $this->setCol($i, $r2); if (PEAR::isError($e)) { return $e; } return true; }/*}}}*/ /** * Swaps a given row with a given column. Only valid for square matrices. * * @param integer $row index of row * @param integer $col index of column * @access public * @return mixed TRUE on success, a PEAR_Error otherwise */ function swapRowCol ($row, $col) {/*{{{*/ if (!$this->isSquare() || !is_int($row) || !is_int($col)) { return PEAR::raiseError("Parameters must be row and a column indices"); } $c = $this->getCol($col); if (PEAR::isError($c)) { return $c; } $r = $this->getRow($row); if (PEAR::isError($r)) { return $r; } $e = $this->setCol($col, $r); if (PEAR::isError($e)) { return $e; } $e = $this->setRow($row, $c); if (PEAR::isError($e)) { return $e; } return true; }/*}}}*/ /** * Returns the minimum value of the elements in the matrix * * @access public * @return mixed a number on success, a PEAR_Error otherwise */ function getMin () {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } else { return $this->_min; } }/*}}}*/ /** * Returns the maximum value of the elements in the matrix * * @access public * @return mixed a number on success, a PEAR_Error otherwise */ function getMax () {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } else { return $this->_max; } }/*}}}*/ /** * Gets the position of the first element with the given value * * @param numeric $val * @access public * @return mixed an array of two numbers on success, FALSE if value is not found, and PEAR_Error otherwise */ function getValueIndex ($val) {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } for ($i=0; $i < $this->_num_rows; $i++) { for ($j=0; $j < $this->_num_cols; $j++) { if ($this->_data[$i][$j] == $val) { return array($i, $j); } } } return false; }/*}}}*/ /** * Gets the position of the element with the minimum value * * @access public * @return mixed an array of two numbers on success, FALSE if value is not found, and PEAR_Error otherwise * @see getValueIndex() */ function getMinIndex () {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } else { return $this->getValueIndex($this->_min); } }/*}}}*/ /** * Gets the position of the element with the maximum value * * @access public * @return mixed an array of two numbers on success, FALSE if value is not found, and PEAR_Error otherwise * @see getValueIndex() */ function getMaxIndex () {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } else { return $this->getValueIndex($this->_max); } }/*}}}*/ /** * Transpose the matrix rows and columns * * @access public * @return mixed TRUE on success, PEAR_Error otherwise */ function transpose () {/*{{{*/ if (!$this->isSquare()) { return PEAR::raiseError("Transpose is undefined for non-sqaure matrices"); } list($nr, $nc) = $this->getSize(); $data = array(); for ($i=0; $i < $nc; $i++) { $col = $this->getCol($i); if (PEAR::isError($col)) { return $col; } else { $data[] = $col; } } return $this->setData($data); }/*}}}*/ /** * Returns the trace of the matrix. Trace = sum(e[i][j]), for all i == j * * @access public * @return mixed a number on success, PEAR_Error otherwise */ function trace() {/*{{{*/ if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } if (!$this->isSquare()) { return PEAR::raiseError('Trace undefined for non-square matrices'); } $trace = 0; for ($i=0; $i < $this->_num_rows; $i++) { $trace += $this->getElement($i, $i); } return $trace; }/*}}}*/ /** * Calculates the matrix determinant using Gaussian elimination with partial pivoting. * * At each step of the pivoting proccess, it checks that the normalized * determinant calculated so far is less than 10^-18, trying to detect * singular or ill-conditioned matrices * * @access public * @return mixed a number on success, a PEAR_Error otherwise */ function determinant() {/*{{{*/ if (!is_null($this->_det) && is_numeric($this->_det)) { return $this->_det; } if ($this->isEmpty()) { return PEAR::raiseError('Matrix has not been populated'); } if (!$this->isSquare()) { return PEAR::raiseError('Determinant undefined for non-square matrices'); } $norm = $this->norm(); if (PEAR::isError($norm)) { return $norm; } $det = 1.0; $sign = 1; // work on a copy $m = $this->clone(); list($nr, $nc) = $m->getSize(); for ($r=0; $r<$nr; $r++) { // find the maximum element in the column under the current diagonal element $ridx = $m->_maxElementIndex($r); if (PEAR::isError($ridx)) { return $ridx; } if ($ridx != $r) { $sign = -$sign; $e = $m->swapRows($r, $ridx); if (PEAR::isError($e)) { return $e; } } // pivoting element $pelement = $m->getElement($r, $r); if (PEAR::isError($pelement)) { return $pelement; } $det *= $pelement; // Is this an singular or ill-conditioned matrix? // i.e. is the normalized determinant << 1 and -> 0? if ((abs($det)/$norm) < $this->_epsilon) { return PEAR::raiseError('Probable singular or ill-conditioned matrix, normalized determinant = ' .(abs($det)/$norm)); } if ($pelement == 0) { return PEAR::raiseError('Cannot continue, pivoting element is zero'); } // zero all elements in column below the pivoting element for ($i = $r + 1; $i < $nr; $i++) { $factor = $m->getElement($i, $r) / $pelement; for ($j=$r; $j < $nc; $j++) { $val = $m->getElement($i, $j) - $factor*$m->getElement($r, $j); $e = $m->setElement($i, $j, $val); if (PEAR::isError($e)) { return $e; } } } // for debugging //echo "COLUMN: $r\n"; //echo $m->toString()."\n"; } unset($m); if ($sign < 0) { $det = -$det; } // save the value $this->_det = $det; return $det; }/*}}}*/ /** * Returns the normalized determinant = abs(determinant)/(euclidean norm) * * @access public * @return mixed a positive number on success, a PEAR_Error otherwise */ function normalizedDeterminant() {/*{{{*/ $det = $this->determinant();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?