Advertisement
Deltik

Matrix.php

Aug 5th, 2011
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 11.25 KB | None | 0 0
  1. <?php
  2. /**
  3.  * Encryptext
  4.  *  Classes
  5.  *   Third-Party
  6.  *    "Class That Contains Matrix Operations"
  7.  *     By: Diego Carrera & Kleber Baño
  8.  *      Translated and Optimized By: Nick Liu <webmaster@deltik.org>
  9.  */
  10.  
  11. #### CONTENTS ####
  12. # Class Variables   - "Matrix Variable Declarations"
  13. # Class Constructor - "Matrix Class Constructor"
  14. # Access Functions  - "Getters & Setters"
  15. # Verifications     - "Matrix Checkers"
  16. # Basic Operations  - "Basic Matrix Operations"
  17. # Advanced Features - "Advanced Matrix Operations"
  18. ##################
  19.  
  20. class Matrix
  21.   {
  22.   /**
  23.    * ################################
  24.    * # Matrix Variable Declarations #
  25.    * ################################
  26.    */
  27.   // Global Variables
  28.   public $rows;
  29.   public $columns;
  30.   public $matrix = array();
  31.   // So-called "Advanced" Global Variables
  32.   public $average;
  33.   public $covariance;
  34.  
  35.   /**
  36.    * ############################
  37.    * # Matrix Class Constructor #
  38.    * ############################
  39.    */
  40.   public function Matrix($array = null)
  41.     {
  42.     if ($array == null)
  43.       return true;
  44.     $this->setMatrix($array);
  45.     if (!$this->setDimensions())
  46.       return false;
  47.     return true;
  48.     }
  49.  
  50.   /**
  51.    * ################################
  52.    * # Matrix Variable Declarations #
  53.    * ################################
  54.    */
  55.  
  56.   /**
  57.    * Really Basic Setters
  58.    */
  59.   // Set Number of Rows
  60.   public function setRows() { $this->rows = count($this->matrix); }
  61.   // Set Number of Columns
  62.   public function setColumns() { $this->columns = count($this->matrix[0]); }
  63.  
  64.   /**
  65.    * Really Basic Getters
  66.    */
  67.   // Get Number of Rows
  68.   public function getRows() { return $this->rows; }
  69.   // Get Number of Columns
  70.   public function getColumns() { return $this->columns; }
  71.   // Get Average
  72.   public function getAverage($array) { $this->average = $this->average($array); return $this->average; }
  73.   // Get Covariance
  74.   public function getCovariance($array) { $this->covariance = $this->covariance($array); return $this->covariance; }
  75.   // Get Number of Rows from Array
  76.   public function getRowsArray($array) { return count($array); }
  77.   // Get Number of Columns from Array
  78.   public function getColumnsArray($array) { return count($array[0]); }
  79.  
  80.   /**
  81.    * Set Matrix Data (called by constructor)
  82.    * @param array $array The array to be converted into a matrix object
  83.    */
  84.   private function setMatrix($array)
  85.     {
  86.     foreach ($array as $x => $array_rows)
  87.       {
  88.       foreach ($array_rows as $y => $array_cell)
  89.         {
  90.         $this->matrix[$x][$y] = $array_cell;
  91.         }
  92.       }
  93.     }
  94.  
  95.   /**
  96.    * Set the Dimensions of the Matrix
  97.    * @param null
  98.    * @returns bool Whether the configuration was successful
  99.    */
  100.   private function setDimensions()
  101.     {
  102.     $this->rows    = count($this->matrix);
  103.     $this->columns = count($this->matrix[0]);
  104.     if ($this->checkDimensionsGiven($this->rows, $this->columns))
  105.       return true;
  106.     $this->rows    = null;
  107.     $this->columns = null;
  108.     return false;
  109.     }
  110.  
  111.   /**
  112.    * ###################
  113.    * # Matrix Checkers #
  114.    * ###################
  115.    */
  116.  
  117.   /**
  118.    * Check If the Dimensions of Two Matrices Are Equal
  119.    * @param matrix $a First matrix to compare
  120.    * @param matrix $b Other matrix to compare
  121.    * @returns bool Whether the dimensions for the matrix objects are the same
  122.    */
  123.   public function checkDimensions($a, $b)
  124.     {
  125.     if ($a->rows == $b->rows && $a->columns == $b->columns)
  126.       return true;
  127.     return false;
  128.     }
  129.  
  130.   /**
  131.    * Check If Square Matrix
  132.    * @returns bool Whether this matrix object is a square in dimensions
  133.    */
  134.   public function checkSquare()
  135.     {
  136.     if ($this->rows == $this->columns)
  137.       return true;
  138.     return false;
  139.     }
  140.  
  141.   /**
  142.    * Check That This Matrix Has the Same Dimensions as Specified
  143.    * @param int $x Desired number of rows
  144.    * @param int $y Desired number of columns
  145.    * @returns bool Whether the matrix object matched dimensions
  146.    */
  147.   public function checkDimensionsGiven($x, $y)
  148.     {
  149.     for ($i = 0; $i < $x; $i ++)
  150.       {
  151.       if ($y != count($this->matrix[$i]))
  152.         return false;
  153.       }
  154.     return true;
  155.     }
  156.  
  157.   /**
  158.    * Check That the Number of Columns Is the Same in Each Row, Given an Array
  159.    * @param array $array The array to check
  160.    * @param int $x Desired number of rows
  161.    * @param int $y Desired number of columns
  162.    */
  163.   public function checkDimensionsGivenArray($array, $x, $y)
  164.     {
  165.     for ($i = 0; $i < $x; $i ++)
  166.       {
  167.       if ($y != count($array[$x]))
  168.         return false;
  169.       }
  170.     return true;
  171.     }
  172.  
  173.   /**
  174.    * ###########################
  175.    * # Basic Matrix Operations #
  176.    * ###########################
  177.    */
  178.  
  179.   /**
  180.    * Subtract Two Matrices
  181.    * @requires Matrices of the same dimension
  182.    * @param array $a Minuend matrix
  183.    * @param array $b Subtrahend matrix
  184.    * @returns array Difference matrix
  185.    */
  186.   public function subtract($a, $b)
  187.     {
  188.     foreach ($a as $x => $a_row)
  189.       {
  190.       foreach ($a[0] as $y => $a_cell)
  191.         {
  192.         $final[$x][$y] = $a[$x][$y] - $b[$x][$y];
  193.         }
  194.       }
  195.     return $final;
  196.     }
  197.   // Alias for "Subtract Two Matrices"
  198.   public function difference($a, $b) { return $this->subtract($a, $b); }
  199.   public function minus($a, $b) { return $this->subtract($a, $b); }
  200.  
  201.   /**
  202.    * Add Two Matrices
  203.    * @requires Matrices of the same dimension
  204.    * @param array $a First addend matrix
  205.    * @param array $b Other addend matrix
  206.    * @returns array Sum matrix
  207.    */
  208.   public function add($a, $b)
  209.     {
  210.     foreach ($a as $x => $a_row)
  211.       {
  212.       foreach ($a[0] as $y => $a_cell)
  213.         {
  214.         $final[$x][$y] = $a[$x][$y] + $b[$x][$y];
  215.         }
  216.       }
  217.     return $final;
  218.     }
  219.   // Alias for "Add Two Matrices"
  220.   public function sum($a, $b) { return $this->add($a, $b); }
  221.   public function plus($a, $b) { return $this->add($a, $b); }
  222.  
  223.   /**
  224.    * Multiply Two Matrices
  225.    * @requires Number of columns in $a is equal to number of rows in $b
  226.    * @param array $a Multiplicand matrix
  227.    * @param array $b Multiplier matrix
  228.    * @returns array Product matrix
  229.    */
  230.   public function multiply($a, $b)
  231.     {
  232.     // Multiplying Scalar Compatibility
  233.     if (is_numeric($b)) return $this->divide($a, 1/$b);
  234.    
  235.     // Normal Two-Matrices Multiplication
  236.     foreach ($a as $x => $a_row)
  237.       {
  238.       foreach ($b[0] as $y => $b_cell_cruft)
  239.         {
  240.         foreach ($a[0] as $z => $a_cell_cruft)
  241.           {
  242.           $final[$x][$y] = $final[$x][$y] + $a[$x][$z] * $b[$z][$y];
  243.           }
  244.         }
  245.       }
  246.     return $final;
  247.     }
  248.   // Alias for "Multiply Two Matrices"
  249.   public function product($a, $b) { return $this->multiply($a, $b); }
  250.   public function times($a, $b) { return $this->multiply($a, $b); }
  251.  
  252.   /**
  253.    * Divide a Matrix by a Scalar
  254.    * @param array $matrix Dividend matrix
  255.    * @param double $scalar Divisor scalar
  256.    * @returns array Quotient matrix
  257.    */
  258.   public function divide($matrix, $scalar)
  259.     {
  260.     foreach ($matrix as $x => $matrix_row)
  261.       {
  262.       foreach ($matrix_row as $y => $matrix_cell)
  263.         {
  264.         $final[$x][$y] = $matrix_cell / $scalar;
  265.         }
  266.       }
  267.     return $final;
  268.     }
  269.   // Alias for "Divide a Matrix by a Scalar"
  270.   public function quotient($a, $b) { return $this->divide($a, $b); }
  271.  
  272.   /**
  273.    * Determinant of a Matrix
  274.    * @requires Square matrix
  275.    * @param array $matrix Matrix to calculate the determinant of
  276.    * @returns double The determinant
  277.    */
  278.   public function determinant($matrix)
  279.     {
  280.     $rows = $this->getRowsArray($matrix);
  281.     $columns = $this->getColumnsArray($matrix);
  282.     $det = 0;
  283.     if ($rows == 1 && $columns == 1)
  284.       {
  285.       $det = $matrix[0][0];
  286.       }
  287.     elseif ($rows == 2 && $columns == 2)
  288.       {
  289.       $det = $matrix[0][0] * $matrix[1][1] - $matrix[0][1] * $matrix[1][0];
  290.       }
  291.     else
  292.       {
  293.       // Visiting the pivot columns...
  294.       for ($y = 0; $y < $columns; $y ++)
  295.         {
  296.         // This creates a sub-matrix.
  297.         $matrix_proc = $this->subMatrix($matrix, 0, $y);
  298.         if (fmod($y, 2) == 0)
  299.           $det += $matrix[0][$y] * $this->determinant($matrix_proc);
  300.         else
  301.           $det -= $matrix[0][$y] * $this->determinant($matrix_proc);
  302.         }
  303.       }
  304.     return $det;
  305.     }
  306.  
  307.   /**
  308.    * Create a Sub-Matrix
  309.    * @param array $matrix Matrix to extract from
  310.    * @param int $x X-Pivot
  311.    * @param int $y Y-Pivot
  312.    * @returns array The sub-matrix
  313.    */
  314.   public function subMatrix($matrix, $x, $y)
  315.     {
  316.     // $p is the indicator for the row of the new sub-matrix.
  317.     // $q is the indicator for the column of the new sub-matrix.
  318.     $p = 0;
  319.     foreach ($matrix as $i => $matrix_row)
  320.       {
  321.       $q = 0;
  322.       if ($x != $i)
  323.         {
  324.         foreach ($matrix_row as $j => $matrix_cell)
  325.           {
  326.           if ($y != $j)
  327.             {
  328.             $final[$p][$q] = $matrix[$i][$j];
  329.             $q ++;
  330.             }
  331.           }
  332.         $p ++;
  333.         }
  334.       }
  335.     return $final;
  336.     }
  337.  
  338.   /**
  339.    * Transpose Matrix
  340.    * @param array $matrix Matrix to transpose
  341.    * @returns array Transposed matrix
  342.    */
  343.   public function transpose($matrix)
  344.     {
  345.     foreach ($matrix as $x => $matrix_row)
  346.       {
  347.       foreach ($matrix_row as $y => $matrix_cell)
  348.         {
  349.         $final[$y][$x] = $matrix_cell;
  350.         }
  351.       }
  352.     return $final;
  353.     }
  354.  
  355.   /**
  356.    * Inverse Matrix
  357.    * @param array $matrix Matrix to invert
  358.    * @returns array Inverted matrix
  359.    */
  360.   public function inverse($matrix)
  361.     {
  362.     foreach ($matrix as $x => $matrix_row)
  363.       {
  364.       foreach ($matrix_row as $y => $matrix_cell)
  365.         {
  366.         if (fmod($x + $y, 2) == 0)
  367.           {
  368.           $final[$x][$y] = $this->determinant($this->subMatrix($matrix, $x, $y));
  369.           }
  370.         else
  371.           {
  372.           $final[$x][$y] = -$this->determinant($this->subMatrix($matrix, $x, $y));
  373.           }
  374.         }
  375.       }
  376.     return $this->transpose($this->divide($final, $this->determinant($matrix)));
  377.     }
  378.  
  379.   /**
  380.    * ############################## XXX: It appears that in the original
  381.    * # Advanced Matrix Operations # script, the author did not complete this
  382.    * ############################## section, Advanced Operation Functions for
  383.    *  Matrices. Deltik has taken no effort in completing this, as not enough
  384.    *  of it has been pre-completed for the remaining to be translated.
  385.    */
  386.  
  387.   /**
  388.    * Average of the Matrix Object
  389.    * @returns bool TRUE - Guaranteed success
  390.    */
  391.   private function average()
  392.     {
  393.     // Polish the values for the array that will store the averages and sums.
  394.     foreach ($this->matrix[0] as $y => $cell)
  395.       {
  396.       $this->average[$y] = 0;
  397.       $sums_average[$y]  = 0;
  398.       }
  399.     foreach ($this->matrix[0] as $y => $cell_cruft)
  400.       {
  401.       foreach ($this->matrix as $x => $column)
  402.         {
  403.         $sums_average[$y] += $this->matrix[$x][$y];
  404.         }
  405.       $this->average[$y] = $sums_average[$y] / $this->rows;
  406.       }
  407.     return true;
  408.     }
  409.  
  410.   /**
  411.    * Covariance of the Matrix Object
  412.    * @returns bool TRUE - Guaranteed success
  413.    */
  414.   private function covariance()
  415.     {
  416.     return $this->multiply($this->matrix, $this->transpose($this->matrix));
  417.     }
  418.   }
  419.  
  420. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement