|
Posted on February 11, 2012 @ 09:16:36 PM by Paul Meagher
Here is a session in Octave demonstrating how to compute the QR decomposition of a matrix:
octave-3.2.4.exe:1> m = [1, 2; 3, 4]
m =
1 2
3 4
octave-3.2.4.exe:2> [Q R] = qr(m)
Q =
-0.31623 -0.94868
-0.94868 0.31623
R =
-3.16228 -4.42719
0.00000 -0.63246
To emulate this functional approach (versus object-oriented approach) to decomposing a matrix in PHP, we need to wrap calls to the JAMA Matrix.php object inside a qr( ) function as follows:
<?php
// Set path to JAMA Matrix object. require_once "../Matrix.php";
// Wrap JAMA matrix functionality inside a qr function. function qr($m) { $A = new Matrix($m); $QR = $A->qr(); $ans['R'] = $QR->getR(); $ans['Q'] = $QR->getQ(); return $ans; }
// Create matrix. $m = array(array(1, 2),array(3, 4));
// Qet QR decompostion of a matrix. $ans = qr($m);
// Output Q and R components of answer object. ?>
<pre> Q = <?php print_r($ans['Q']); ?> </pre>
<pre> R = <?php print_r($ans['R']); ?> </pre>
The output of this script looks like this:
Q =
Matrix Object
(
[A] => Array
(
[0] => Array
(
[1] => 0.94868329805051
[0] => -0.31622776601684
)
[1] => Array
(
[1] => -0.31622776601684
[0] => -0.94868329805051
)
)
[m] => 2
[n] => 2
)
R =
Matrix Object
(
[A] => Array
(
[0] => Array
(
[0] => -3.1622776601684
[1] => -4.4271887242357
)
[1] => Array
(
[0] => 0
[1] => 0.63245553203368
)
)
[m] => 2
[n] => 2
)
Interestingly, the answers produced by the Octave and PHP scripts differ in the signs associated with a few of the answer values. Does this matter? Well, if we take the values of Q and R output by PHP, enter them into Octave, and then multiply Q and R together, we get the original matrix back. This reconstruction of the original matrix demonstrates the correctness of the decomposition and that the decomposition of a matrix into Q and R components is not unique.
octave-3.2.4.exe:1> Q = [-0.31622, 0.94868; -0.94868, -0.31622]
Q =
-0.31622 0.94868
-0.94868 -0.31622
octave-3.2.4.exe:2> R = [-3.1622, -4.42718; 0, 0.63245]
R =
-3.16220 -4.42718
0.00000 0.63245
octave-3.2.4.exe:3> Q * R
ans =
0.99995 1.99996
2.99992 3.99998
Note that if I didn't reduce the precision of the Q and R matrix values, the output would be [1 2; 3 4] or the exact version of the original matrix.
This proof-of-concept demonstrates how we can develop a matlab/octave-like functional API for linear algrebra decompositions in PHP by incorporating calls to the JAMA library methods inside qr(), svd(), lu(), eig(), and chol() functions. A functional API for linear algebra would make doing linear algrebra in PHP much more direct, interactive and enjoyable. Object-oriented linear algebra libraries like JAMA play a supporting role, hidden behind a set of linear algebra functions like qr(), svd(), lu(), eig() and chol() for operating on matrices.
|