Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Matrix Operations

By: a guest on Jul 2nd, 2012  |  syntax: PHP  |  size: 13.34 KB  |  views: 86  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php
  2. /*
  3. * Clase que contiene operaciones de una matriz
  4. * Fecha de Creación: 30/sept/2005
  5. * Diego Carrera - Kleber Baño
  6. * Guayaquil - Ecuador
  7. *
  8. */
  9. class matrix {
  10.         //global vars
  11.         var $NumFila;  
  12.         var $NumColumna;
  13.         var $ArrayData=array();
  14.         //advanced global vars 
  15.         var $ArrayMedia;
  16.         var $ArrayMatrizCov;
  17.  
  18.         /**
  19.          * Contructor de la clase matriz
  20.          *
  21.          * @param array $ArrayDataMatriz
  22.          * @return matrix
  23.          */
  24.         function matrix($ArrayDataMatriz) {
  25.                 $this->set_data($ArrayDataMatriz);
  26.                 if (!$this->set_properties_matrix())
  27.                  return false;
  28.         return true;
  29.         }
  30.  
  31.  
  32. /******************************************/   
  33. /*FUNCIONES DE BASICAS DE LA CLASE MATRIX */
  34.  
  35.         /**
  36.          * Setea los datos que se le da a la matriz al momento de iniciar el objeto
  37.          *
  38.          * @param array $ArrayDataMatriz
  39.          */
  40.         function set_data($ArrayDataMatriz){
  41.                 for ($i=0;$i<count($ArrayDataMatriz);$i++){
  42.                         $valor = $ArrayDataMatriz[$i];
  43.                         if (count($ArrayDataMatriz[$i])==1){
  44.                                 $this->ArrayData[$i][0] = $ArrayDataMatriz[$i];
  45.                         }
  46.                         else
  47.                         for ($j=0;$j<count($ArrayDataMatriz[$i]);$j++)
  48.                                         $this->ArrayData[$i][$j] = $ArrayDataMatriz[$i][$j];   
  49.                 }
  50.                
  51.         }
  52.  
  53.  
  54.         /**
  55.          * Setee las propiedades de la matriz como son las filas y columnas
  56.          *
  57.          * @return unknown
  58.          */
  59.         function set_properties_matrix(){
  60.                 $this->NumFila = count($this->ArrayData );
  61.                 $this->NumColumna = count($this->ArrayData[0]);
  62.                 if ($this->ValidaNumColumnasObjMatriz($this->NumFila,$this->NumColumna)){
  63.                         return true;
  64.                 }
  65.                 $this->NumColumna=null;
  66.                 $this->NumFila=null;
  67.                 return false;
  68.         }
  69.        
  70.         /**
  71.          * Setee el número de filas de la matriz
  72.          *
  73.          */
  74.         function set_NumFilas(){
  75.                 $this->NumFila = count($this->ArrayData[0] );
  76.         }
  77.        
  78.         /**
  79.          * Setee el número de columna de la matriz
  80.          *
  81.          */    
  82.         function set_NumColumnas(){
  83.                 $this->NumColumna = count($this->ArrayData);
  84.         }
  85.  
  86.         /**
  87.          * Obtiene el número de filas que tiene el objeto matriz
  88.          *
  89.          * @return integer
  90.          */
  91.         function get_NumFilas() {
  92.                 return $this->NumFila;
  93.         }
  94.  
  95.         /**
  96.          * Obtiene el número de columnas que tiene el objeto matriz
  97.          *
  98.          * @return integer
  99.          */
  100.         function get_NumColumnas()      {
  101.                 return $this->NumColumna;
  102.         }
  103.        
  104.         /**
  105.          * Obtiene el arreglo de datos de la matriz media del objeto matriz
  106.          *
  107.          * @return Arraymatriz
  108.          */
  109.         function getMediaMatrix(){
  110.                 $this->MediasMatriz();
  111.                 return $this->ArrayMedia;
  112.         }      
  113.  
  114.         /**
  115.          * Obtiene el arreglo de datos de la matriz de covarianza
  116.          *
  117.          * @param Arraydata $ArrayData
  118.          * @return ArrayData
  119.          */
  120.         function getCovarianzaMatrix($ArrayData){
  121.                 $this->ArrayMatrizCov=$this->CovarianzaMatriz($ArrayData);
  122.                 return $this->ArrayMatrizCov;
  123.         }
  124.        
  125.         /**
  126.          * Obtiene el número de filas que tiene un Arreglo de una matriz
  127.          *
  128.          * @param ArrayData $ArrayDataMatriz
  129.          * @return integer
  130.          */
  131.         function get_NumFilas_ArrayDataMatriz($ArrayDataMatriz){
  132.                 //echo "la supesta filas es ".count($ArrayDataMatriz);
  133.                 //print_r($ArrayDataMatriz);
  134.                 return count($ArrayDataMatriz);
  135.         }
  136.        
  137.         /**
  138.          * Obtiene el número de columnas que tiene un arreglo de una matriz
  139.          *
  140.          * @param ArrayData $ArrayDataMatriz
  141.          * @return integer
  142.          */
  143.         function get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz){
  144.                 //echo "la supesta columan es ".count($ArrayDataMatriz[0]);
  145.                 return count ($ArrayDataMatriz[0]);
  146.         }
  147.  
  148.  
  149.  
  150. /******************************************/   
  151. /*FUNCIONES DE VALIDACIONES DE MATRICES */
  152.  
  153.         /**
  154.          * Funcion que valida si dos matrices son iguales, es decir que tengan el mismo numero de N y M
  155.          *
  156.          * @param matrix $matrizA
  157.          * @param matrix $matrizB
  158.          * @return bool
  159.          */
  160.         function ValidaMatricesDimenIguales($ObjMatrizA, $ObjMatrizB){
  161.                 //valida que las matrices sean v&aacute;lidas
  162.                 if ($ObjMatrizA->NumFila==$ObjMatrizB->NumFila and $ObjMatrizA->NumColumna==$ObjMatrizB->NumFila)
  163.                         return true;
  164.                 else
  165.                         return false;
  166.         }
  167.                
  168.  
  169.         /**
  170.          * Funcion que valida que la matriz sea de NxN
  171.          *
  172.          * @return bool
  173.          */
  174.         function ValidaMatriz_N_x_N(){
  175.                 if ($this->NumFila == $this->NumColumna)
  176.                          return true;
  177.                          
  178.         return false;
  179.         }
  180.        
  181.         /**
  182.          * Valida que el numero de columna de una matriz.. se el mismo en todas sus filas
  183.          *
  184.          * @param integer $NumFilas
  185.          * @param integer $NumColumnas
  186.          * @return bool
  187.          */
  188.         function ValidaNumColumnasObjMatriz($NumFilas,$NumColumnas){
  189.                 for ($i=0;$i<$NumFilas;$i++){
  190.                         $columna = count($this->ArrayData [$i]);
  191.                         if ($NumColumnas != $columna)
  192.                                 return false;
  193.                 }
  194.         return true;
  195.         }
  196.        
  197.         /**
  198.          * Dado un arreglo de datos de una matriz, valida que el número de
  199.          * columnas de una matriz.. se el mismo en todas sus filas
  200.          *
  201.          * @param ArrayData $ArrayDataMatriz
  202.          * @param integer $NumFilas
  203.          * @param integer $NumColumnas
  204.          * @return unknown
  205.          */
  206.         function ValidaNumColumnasArrayDataMatriz($ArrayDataMatriz,$NumFilas,$NumColumnas){
  207.                 for ($i=0;$i<$NumFilas;$i++){
  208.                         $columna = count($ArrayDataMatriz[$i]);
  209.                         if ($NumColumnas != $columna)
  210.                                 return false;
  211.                 }
  212.         return true;
  213.         }
  214.  
  215.        
  216.        
  217.  
  218. /************************************************/     
  219. /*FUNCIONES DE OPERACIONES BASICAS CON MATRICES */
  220.  
  221.         /**
  222.          * Resta de dos matrices
  223.          * Requisito: tiene que se de iguales valores de NxM
  224.          *
  225.          * @param ArrayData $ArrayDataMatriz1
  226.          * @param ArrayData $ArrayDataMatriz2
  227.          * @return ArrayData
  228.          */
  229.         function RestaMatrices($ArrayDataMatriz1, $ArrayDataMatriz2){
  230.                 $filas1 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz1);
  231.                 $filas2 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz2);
  232.                 $columnas1 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz1);
  233.                 $columnas2 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz2);
  234.                
  235.                 for($i=0; $i<$filas1; $i++) {  
  236.                         for($j=0; $j<$columnas1; $j++){
  237.                                 $ArrayResta[$i][$j]= $ArrayDataMatriz1[$i][$j]-$ArrayDataMatriz2[$i][$j];
  238.                         }
  239.                 }
  240.                 return $ArrayResta;
  241.                
  242.         }
  243.        
  244.         /**
  245.          * Suma de dos matrices
  246.          * Requisito: tiene que se de iguales valores de NxM
  247.          *
  248.          * @param ArrayData $ArrayDataMatriz1
  249.          * @param ArrayData $ArrayDataMatriz2
  250.          * @return ArrayData
  251.          */
  252.         function SumaMatrices($ArrayDataMatriz1, $ArrayDataMatriz2){
  253.                 $filas1 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz1);
  254.                 $filas2 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz2);
  255.                 $columnas1 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz1);
  256.                 $columnas2 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz2);
  257.                
  258.                 for($i=0; $i<$filas1; $i++) {  
  259.                         for($j=0; $j<$columnas1; $j++){
  260.                                 $ArrayResta[$i][$j]= $ArrayDataMatriz1[$i][$j]+$ArrayDataMatriz2[$i][$j];
  261.                         }
  262.                 }
  263.                 return $ArrayResta;
  264.                
  265.         }      
  266.        
  267.  
  268.  
  269.         /**
  270.          * Calcula la matriz resultante de multiplicar dos matrices
  271.          * Requisito: los datos de las matrices A,B, tiene que cumplir que
  272.          * El # de columnas de A, tienen que se igual a las filas de B.
  273.          * C(pxq) = A(pxm) * B(mxq)
  274.          *
  275.          * @param ArrayData $ArrayDataMatriz1
  276.          * @param ArrayData $ArrayDataMatriz2
  277.          * @return ArrayData
  278.          */
  279.         function MultiplicacionMatrices($ArrayDataMatriz1, $ArrayDataMatriz2) {
  280.                 $filas1 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz1);
  281.                 $columnas1 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz1);
  282.  
  283.                 $columnas2 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz2);        
  284.                 $filas2 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz2);
  285.  
  286.                 for($i=0; $i<$filas1; $i++){
  287.                         for($j=0; $j<$columnas2; $j++){
  288.                                 $ArrayMultipli[$i][$j]=0; $sum=0;
  289.                                 for($M=0;$M<$columnas1;$M++){
  290.                                         $ArrayMultipli[$i][$j]  = $ArrayMultipli[$i][$j] + $ArrayDataMatriz1[$i][$M]*$ArrayDataMatriz2[$M][$j];
  291.                                 }
  292.                         }
  293.                 }
  294.                 return $ArrayMultipli;
  295.         }
  296.                
  297.         /**
  298.          * Calcula la matriz resultante al dividir una matriz para un escalar
  299.          *
  300.          * @param ArrayData $ArrayDataMatriz
  301.          * @param integer $valor
  302.          * @return ArrayData
  303.          */
  304.         function DivisionMatriz($ArrayDataMatriz, $valor) {
  305.                 $filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
  306.                 $columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
  307.  
  308.                 $matriz = array();
  309.                 for($i = 0; $i < $filas; $i++) {
  310.                         for($j = 0; $j < $columnas; $j++) {
  311.                                 $matriz[$i][$j] = $ArrayDataMatriz[$i][$j] / $valor;
  312.                         }
  313.                 }
  314.                 return $matriz;
  315.         }
  316.        
  317.         /**
  318.          * Calcula el Determinante de una matriz.
  319.          * Requisito: Todas filas deben tener el mismo número de columnas.
  320.          * Requisito: La matriz debe ser de NxN
  321.          *
  322.          * @param ArrayData $ArrayDataMatriz
  323.          * @return integer
  324.          */
  325.         function Determinante($ArrayDataMatriz) {
  326.                 $filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
  327.                 $columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
  328.                 $det = 0;
  329.                 if ($filas == 2 && $columnas == 2) {
  330.                         $det = $ArrayDataMatriz[0][0] * $ArrayDataMatriz[1][1] - $ArrayDataMatriz[0][1] * $ArrayDataMatriz[1][0];
  331.                 } else {
  332.                         $matriz = array();
  333.                         /* Recorrer las columnas pivotes */
  334.                         for($j = 0; $j < $columnas; $j++) {
  335.                                 /* Se crea una sub matriz */
  336.                                 $matriz = $this->SubMatriz($ArrayDataMatriz, 0, $j);
  337.                                 if (fmod($j, 2) == 0) {
  338.                                         $det += $ArrayDataMatriz[0][$j]*$this->Determinante($matriz);
  339.                                 } else {
  340.                                         $det -= $ArrayDataMatriz[0][$j]*$this->Determinante($matriz);
  341.                                 }
  342.                         }
  343.                 }
  344.                 return $det;
  345.         }
  346.  
  347.  
  348.         /**
  349.          * Enter description here...
  350.          *
  351.          * @param ArrayData $ArrayDataMatriz
  352.          * @param integer $pivoteX
  353.          * @param integer $pivoteY
  354.          * @return ArrayData
  355.          */
  356.         function SubMatriz($ArrayDataMatriz, $pivoteX, $pivoteY) {
  357.                 //echo "determiando SUBMATRIZ<br>";
  358.                 $filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
  359.                 $columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
  360.                 $matriz = array();
  361.                 $p = 0; // indica la fila de la nueva submatriz
  362.                 for($i = 0; $i < $filas; $i++) {
  363.                         $q = 0; // indica la columna de la nueva submatriz
  364.                         if ($pivoteX != $i) {
  365.                                 for($j = 0; $j < $columnas; $j++) {
  366.                                         if ($pivoteY != $j) {
  367.                                                 $matriz[$p][$q] = $ArrayDataMatriz[$i][$j];
  368.                                                 $q++;
  369.                                         }
  370.                                 }
  371.                                 $p++;
  372.                         }
  373.                 }
  374.                 return $matriz;
  375.         }
  376.  
  377.  
  378.         /**
  379.          * Calcula la matriz transpuesta de la matriz dada
  380.          *
  381.          * @param ArrayData $ArrayDataMatriz
  382.          * @return ArrayData
  383.          */
  384.         function Transpuesta($ArrayDataMatriz) {
  385.                 $filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
  386.                 $columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
  387.                 $ArrayTranspuesta = array();
  388.                 //echo $filas.",".$columnas;
  389.                 for($i = 0; $i < $filas; $i++) {
  390.                         for($j = 0; $j < $columnas; $j++) {
  391.                                 //echo "el dato es ".$ArrayDataMatriz[$i][$j]."<br>";
  392.                                 $ArrayTranspuesta[$j][$i] = $ArrayDataMatriz[$i][$j];
  393.                         }
  394.                 }
  395.                 return $ArrayTranspuesta;
  396.                
  397.         }
  398.  
  399.  
  400.         /**
  401.          * Calcula la matriz inversa de la matriz dada
  402.          *
  403.          * @param ArrayData $ArrayDataMatriz
  404.          * @return ArrayData
  405.          */
  406.         function InversaMatriz($ArrayDataMatriz) {
  407.                 $filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
  408.                 $columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
  409.                 //echo "determiando inversa<br>";
  410.                 $matriz = array();
  411.                 for($i = 0; $i < $filas; $i++) {
  412.                         for($j = 0; $j < $columnas; $j++) {
  413.                                 if (fmod($i + $j, 2) == 0) {
  414.                                         $matriz[$i][$j] = $this->Determinante($this->SubMatriz($ArrayDataMatriz, $i, $j));
  415.                                 } else {
  416.                                         $matriz[$i][$j] = -$this->Determinante($this->SubMatriz($ArrayDataMatriz, $i, $j));
  417.                                 }
  418.                         }
  419.                 }
  420.                 return $this->Transpuesta($this->DivisionMatriz($matriz,$this->Determinante($ArrayDataMatriz)));
  421.         }
  422.        
  423.  
  424. /**************************************************/   
  425. /*FUNCIONES DE OPERACIONES AVANZADAS CON MATRICES */
  426.        
  427.         /**
  428.          *      M = mean(A)  return la media de los valores de una dimension del arreglo
  429.          *      If A is a vector, mean(A) returns the mean value of A.
  430.          *      If A is a matrix, mean(A) treats the columns of A as vectors, returning a row vector of mean values.
  431.          *      A = [1 2 3; 3 3 6; 4 6 8; 4 7 7];
  432.          *      mean(A)= [ 3.0000    4.5000    6.000 ]
  433.          *
  434.          * @return unknown
  435.          */
  436.         function MediasMatriz(){
  437.                 //encero los valores para el arreglo que va a almacenar las medias y las sumas
  438.                 for ($j=0; $j<$this->NumColumna; $j++){
  439.                         $this->ArrayMedia[$j]=0;
  440.                         $suma_media[$j]=0;
  441.                 }
  442.                 for ($j=0; $j<$this->NumColumna; $j++){
  443.                         for ($i=0; $i<$this->NumFila; $i++){
  444.                                 $suma_media[$j]+=$this->ArrayData[$i][$j];
  445.                         }
  446.                         //echo "suma $i,$j=".$this->ArrayData[$i][$j]."<br>";
  447.                         $this->ArrayMedia[$j]=$suma_media[$j]/$this->NumFila;
  448.                         $this->ArraySumaMedia[$j]=$suma_media[$j];
  449.                 }
  450.         //retorno la matriz con los promedio de cada columna (la matriz de la media)
  451.         return true;
  452.         }
  453.        
  454.  
  455.                
  456.  
  457.         /**
  458.          * COV(X,Y)
  459.          * Calcula la covarianza entre los vectores x i y
  460.          * C = CovarianzaVector(x) where x,y  are vectors,
  461.          *
  462.          * @param array $vectorX
  463.          * @param array $vectorY
  464.          * @return integer
  465.          */
  466.         function CovarianzaVectores ($vectorX, $vectorY){
  467.                 $NumFilas = count($vectorX);
  468.                 if ($NumFilas != count($vectorY)) return null;
  469.                 $covarianza = 0;$sum=0;
  470.                 $mean_x = $this->MediaVector($vectorX);
  471.                 $mean_y = $this->MediaVector($vectorY);
  472.                 for($i = 0; $i < $NumFilas; $i++) {
  473.                         $valor = (($vectorX[$i] - $mean_x) * ($vectorY[$i] - $mean_y));
  474.                         $sum += $valor;
  475.                 }
  476.                 $covarianza = $sum / $NumFilas;
  477.                 return $covarianza;
  478.         }
  479.        
  480.        
  481.         /**
  482.          * Calcula la matriz de covarianza de una matriz A
  483.          * S = CovarianzaMatriz(x) where A es una matriz.
  484.          * Cada fila es una observacion y cada columna es una variable
  485.          * n = numero de observaciones (# filas)
  486.          * Cov (A)= A * A'
  487.         */
  488.         function CovarianzaMatriz($ArrayData){
  489.                 $transpA = $this->Transpuesta($ArrayData);
  490.                 $MatrizCov =  $this->MultiplicacionMatrices($ArrayData,$transpA);
  491.                 return $MatrizCov;
  492.         }
  493.        
  494.  
  495.  
  496.  
  497. }
  498. ?>