matrix.php

来自「视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.」· PHP 代码 · 共 1,490 行 · 第 1/4 页

PHP
1,490
字号
            }        }        if (!empty($data)) {            return $this->setData($data);        } else {            return PEAR::raiseError('Undefined error');        }    }/*}}}*/    /**     * Multiplies a vector by this matrix     *     * @param object Math_Vector $v1     * @return object an instance of Math_Vector on success, PEAR_Error otherwise     * @see getSize()     * @see getRow()     * @see Math_Vector::get()     */    function &vectorMultiply(&$v1) {/*{{{*/        if (!Math_VectorOp::isVector($v1)) {            return PEAR::raiseError ("Wrong parameter, a Math_Vector object");        }        list($nr, $nc) = $this->getSize();        $nv = $v1->size();        if ($nc != $nv) {            return PEAR::raiseError("Incompatible number of columns in matrix ($nc) must ".                        "be the same as the number of elements ($nv) in the vector");        }        $data = array();        for ($i=0; $i < $nr; $i++) {            $data[$i] = 0;            for ($j=0; $j < $nv; $j++) {                $data[$i] += $this->getElement($i,$j) * $v1->get($j);            }        }        return new Math_Vector($data);    }/*}}}*/    // Static operations    /**     * Create a matrix from a file, using data stored in the given format     *     * Lines starting with '#' will be assumed to be comments and will be skipped     *     * @static     * @access public     * @param string $filename name of file containing matrix data     * @param optional string $format one of 'serialized' (default) or 'csv'     * @return object a Math_Matrix instance on success, a PEAR_Error otherwise     */    function &readFromFile ($filename, $format='serialized') {/*{{{*/        if (!file_exists($filename) || !is_readable($filename)) {            return PEAR::raiseError('File cannot be opened for reading');        }        if (filesize($filename) == 0) {            return PEAR::raiseError('File is empty');        }        if ($format == 'serialized') {            if (function_exists("file_get_contents")) {                $objser = file_get_contents($filename);            } else {                $objser = implode("",file($filename));            }            $obj = unserialize($objser);            if (Math_Matrix::isMatrix($obj)) {                return $obj;            } else {                return PEAR::raiseError('File did not contain a Math_Matrix object');            }        } else { // assume CSV data            $data = array();            $lines = file($filename);            foreach ($lines as $line) {                if (preg_match('/^#/', $line)) {                    continue;                } else {                    $data[] = explode(',',trim($line));                }            }            $m =& new Math_Matrix();            $e = $m->setData($data);            if (PEAR::isError($e)) {                return $e;             } else {                return $m;            }        }    }/*}}}*/    /**     * Writes matrix object to a file using the given format     *     * @static     * @access public     * @param object Math_Matrix $matrix the matrix object to store     * @param string $filename name of file to contain the matrix data     * @param optional string $format one of 'serialized' (default) or 'csv'     * @return mixed TRUE on success, a PEAR_Error otherwise     */    function writeToFile (&$matrix, $filename, $format='serialized') {/*{{{*/        if (!Math_Matrix::isMatrix($matrix)) {            return PEAR::raiseError("Parameter must be a Math_Matrix object");        }        if ($matrix->isEmpty()) {            return PEAR::raiseError("Math_Matrix object is empty");        }        if ($format == 'serialized') {            $data = serialize($matrix);        } else {            $data = '';            list($nr, $nc) = $matrix->getSize();            for ($i=0; $i<$nr; $i++) {                $row = $matrix->getRow($i);                if (PEAR::isError($row)) {                    return $row;                }                $data .= implode(',', $row)."\n";            }        }        $fp = fopen($filename, "w");        if (!$fp) {            return PEAR::raiseError("Cannot write matrix to file $filename");        }        fwrite($fp, $data);        fclose($fp);        return true;    }/*}}}*/    /**     * Checks if the object is a Math_Matrix instance     *     * @static     * @access public     * @param object Math_Matrix $matrix     * @return boolean TRUE on success, FALSE otherwise     */    function isMatrix (&$matrix) {/*{{{*/        if (function_exists("is_a")) {            return is_a($matrix, "Math_Matrix");        } else {            return (get_class($matrix) == "math_matrix");        }    }/*}}}*/    /**     * Returns a Math_Matrix object of size (nrows, ncols) filled with a value     *     * @static     * @access public     * @param integer $nrows number of rows in the generated matrix     * @param integer $ncols number of columns in the generated matrix     * @param numeric $value the fill value     * @return object a Math_Matrix instance on success, PEAR_Error otherwise     */    function &makeMatrix ($nrows, $ncols, $value) {/*{{{*/        if (!is_int($nrows) && is_int($ncols) && !is_numeric($value)) {            return PEAR::raiseError('Number of rows, columns, and a numeric fill value expected');        }        for ($i=0; $i<$nrows; $i++) {            $m[$i] = explode(":",substr(str_repeat($value.":",$ncols),0,-1));        }        return new Math_Matrix($m);    }/*}}}*/    /**     * Returns the Math_Matrix object of size (nrows, ncols), filled with the value 1 (one)     *     * @static     * @access public     * @param integer $nrows number of rows in the generated matrix     * @param integer $ncols number of columns in the generated matrix     * @return object a Math_Matrix instance on success, PEAR_Error otherwise     * @see Math_Matrix::makeMatrix()     */    function &makeOne ($nrows, $ncols) {/*{{{*/        return Math_Matrix::makeMatrix ($nrows, $ncols, 1);    }/*}}}*/    /**     * Returns the Math_Matrix object of size (nrows, ncols), filled with the value 0 (zero)     *     * @static     * @access public     * @param integer $nrows number of rows in the generated matrix     * @param integer $ncols number of columns in the generated matrix     * @return object a Math_Matrix instance on success, PEAR_Error otherwise     * @see Math_Matrix::makeMatrix()     */    function &makeZero ($nrows, $ncols) {/*{{{*/        return Math_Matrix::makeMatrix ($nrows, $ncols, 0);    }/*}}}*/    /**     * Returns a square unit Math_Matrix object of the given size     *     * A unit matrix is one in which the elements follow the rules:     *  e[i][j] = 1, if i == j     *  e[i][j] = 0, if i != j     * Such a matrix is also called an 'identity matrix'     *     * @static     * @access public     * @param integer $size number of rows and columns in the generated matrix     * @return object a Math_Matrix instance     * @see Math_Matrix::makeIdentity()     */    function &makeUnit ($size) {/*{{{*/        for ($i=0; $i<$size; $i++) {            for ($j=0; $j<$size; $j++) {                if ($i == $j) {                    $data[$i][$j] = (float) 1.0;                } else {                    $data[$i][$j] = (float) 0.0;                }            }        }        return new Math_Matrix($data);    }/*}}}*/    /**     * Returns the identity matrix of the given size. An alias of Math_Matrix::makeUnit()     *     * @static     * @access public     * @param integer $size number of rows and columns in the generated matrix     * @return object a Math_Matrix instance     * @see Math_Matrix::makeUnit()     */    function &makeIdentity($size) {/*{{{*/        return Math_Matrix::makeUnit($size);    }/*}}}*/    /**     * Solves a system of linear equations: Ax = b     *     * A system such as:     * <pre>     *     a11*x1 + a12*x2 + ... + a1n*xn = b1     *     a21*x1 + a22*x2 + ... + a2n*xn = b2     *     ...     *     ak1*x1 + ak2*x2 + ... + akn*xn = bk     * </pre>     * can be rewritten as:     * <pre>     *     Ax = b     * </pre>     * where:      * - A is matrix of coefficients (aij, i=1..k, j=1..n),      * - b a vector of values (bi, i=1..k),     * - x the vector of unkowns (xi, i=1..n)     * Using: x = (Ainv)*b     * where:     * - Ainv is the inverse of A     *     * @static     * @access public     * @param object Math_Matrix $a the matrix of coefficients     * @param object Math_Vector $b the vector of values     * @return mixed a Math_Vector object on succcess, PEAR_Error otherwise     * @see vectorMultiply()     */    function solve($a, $b) {        // check that the vector classes are defined        if (!Math_Matrix::isMatrix($a) && !Math_VectorOp::isVector($b)) {            return PEAR::raiseError('Incorrect parameters, expecting a Math_Matrix and a Math_Vector');        }        $e = $a->invert();        if (PEAR::isError($e)) {            return $e;        }        return $a->vectorMultiply($b);    }    /**     * Solves a system of linear equations: Ax = b, using an iterative error correction algorithm     *     * A system such as:     * <pre>     *     a11*x1 + a12*x2 + ... + a1n*xn = b1     *     a21*x1 + a22*x2 + ... + a2n*xn = b2     *     ...     *     ak1*x1 + ak2*x2 + ... + akn*xn = bk     * </pre>     * can be rewritten as:     * <pre>     *     Ax = b     * </pre>     * where:      * - A is matrix of coefficients (aij, i=1..k, j=1..n),      * - b a vector of values (bi, i=1..k),     * - x the vector of unkowns (xi, i=1..n)     * Using: x = (Ainv)*b     * where:     * - Ainv is the inverse of A     *     * The error correction algorithm uses the approach that if:     * - xp is the approximate solution     * - bp the values obtained from pluging xp into the original equation     * We obtain     * <pre>     *     A(x - xp) = (b - bp),     *     or     *     A*xadj = (b - bp)     * </pr>     * where:     * - xadj is the adjusted value (= Ainv*(b - bp))     * therefore, we calculate iteratively new values of x using the estimated     * xadj and testing to check if we have decreased the error.     *     * @static     * @access public     * @param object Math_Matrix $a the matrix of coefficients     * @param object Math_Vector $b the vector of values     * @return mixed a Math_Vector object on succcess, PEAR_Error otherwise     * @see vectorMultiply()     * @see invert()     * @see Math_VectorOp::add()     * @see Math_VectorOp::substract()     * @see Math_VectorOp::length()     */    function solveEC($a, $b) {/*{{{*/        $ainv = $a->clone();        $e = $ainv->invert();        if (PEAR::isError($e)) {            return $e;        }        $x = $ainv->vectorMultiply($b);        if (PEAR::isError($x)) {            return $x;        }        // initial guesses        $bprime = $a->vectorMultiply($x);        if (PEAR::isError($bprime)) {            return $bprime;        }        $err = Math_VectorOp::substract($b, $bprime);        $adj = $ainv->vectorMultiply($err);        if (PEAR::isError($adj)) {            return $adj;        }        $adjnorm = $adj->length();        $xnew = $x;                // compute new solutions and test for accuracy        // iterate no more than 10 times        for ($i=0; $i<10; $i++) {            $xnew = Math_VectorOp::add($x, $adj);            $bprime = $a->vectorMultiply($xnew);            $err = Math_VectorOp::substract($b, $bprime);            $newadj = $ainv->vectorMultiply($err);            $newadjnorm = $newadj->length();            // did we improve the accuracy?            if ($newadjnorm < $adjnorm) {                $adjnorm = $newadjnorm;                $x = $xnew;                $adj = $newadj;            } else { // we did improve the accuracy, so break;                break;            }        }        return $x;    }/*}}}*/   } // end of Math_Matrix class /*}}}*/// vim: ts=4:sw=4:et:// vim6: fdl=1:?>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?