Location: PHPKode > scripts > Matrix > matrix/matrix.class.txt
<?php
/*
* Clase que contiene operaciones de una matriz
* Fecha de Creación: 30/sept/2005
* Diego Carrera - Kleber Baño
* Guayaquil - Ecuador
*
*/
class matrix {
	//global vars
	var $NumFila;	
	var $NumColumna;
	var $ArrayData=array();
	//advanced global vars	
	var $ArrayMedia;
	var $ArrayMatrizCov;

	/**
	 * Contructor de la clase matriz
	 *
	 * @param array $ArrayDataMatriz
	 * @return matrix
	 */
	function matrix($ArrayDataMatriz) {
		$this->set_data($ArrayDataMatriz);
		if (!$this->set_properties_matrix())
		 return false;
	return true;
	}


/******************************************/	
/*FUNCIONES DE BASICAS DE LA CLASE MATRIX */

	/**
	 * Setea los datos que se le da a la matriz al momento de iniciar el objeto
	 *
	 * @param array $ArrayDataMatriz
	 */
	function set_data($ArrayDataMatriz){
		for ($i=0;$i<count($ArrayDataMatriz);$i++){
			$valor = $ArrayDataMatriz[$i];
			if (count($ArrayDataMatriz[$i])==1){
				$this->ArrayData[$i][0] = $ArrayDataMatriz[$i];	
			}
			else
			for ($j=0;$j<count($ArrayDataMatriz[$i]);$j++)
					$this->ArrayData[$i][$j] = $ArrayDataMatriz[$i][$j];	
		}
		
	}


	/**
	 * Setee las propiedades de la matriz como son las filas y columnas
	 *
	 * @return unknown
	 */
	function set_properties_matrix(){
		$this->NumFila = count($this->ArrayData );
		$this->NumColumna = count($this->ArrayData[0]);
		if ($this->ValidaNumColumnasObjMatriz($this->NumFila,$this->NumColumna)){
			return true;
		}
		$this->NumColumna=null;
		$this->NumFila=null;
		return false;
	}
	
	/**
	 * Setee el número de filas de la matriz
	 *
	 */
	function set_NumFilas(){
		$this->NumFila = count($this->ArrayData[0] );
	}
	
	/**
	 * Setee el número de columna de la matriz
	 *
	 */	
	function set_NumColumnas(){
		$this->NumColumna = count($this->ArrayData);
	}

	/**
	 * Obtiene el número de filas que tiene el objeto matriz
	 *
	 * @return integer
	 */
	function get_NumFilas()	{
		return $this->NumFila;
	}

	/**
	 * Obtiene el número de columnas que tiene el objeto matriz
	 *
	 * @return integer
	 */
	function get_NumColumnas()	{
		return $this->NumColumna;
	}
	
	/**
	 * Obtiene el arreglo de datos de la matriz media del objeto matriz
	 *
	 * @return Arraymatriz
	 */
	function getMediaMatrix(){
		$this->MediasMatriz();
		return $this->ArrayMedia;
	}	

	/**
	 * Obtiene el arreglo de datos de la matriz de covarianza
	 *
	 * @param Arraydata $ArrayData
	 * @return ArrayData
	 */
	function getCovarianzaMatrix($ArrayData){
		$this->ArrayMatrizCov=$this->CovarianzaMatriz($ArrayData);
		return $this->ArrayMatrizCov;
	}
	
	/**
	 * Obtiene el número de filas que tiene un Arreglo de una matriz
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @return integer
	 */
	function get_NumFilas_ArrayDataMatriz($ArrayDataMatriz){
		//echo "la supesta filas es ".count($ArrayDataMatriz);
		//print_r($ArrayDataMatriz);
		return count($ArrayDataMatriz);
	}
	
	/**
	 * Obtiene el número de columnas que tiene un arreglo de una matriz
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @return integer
	 */
	function get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz){
		//echo "la supesta columan es ".count($ArrayDataMatriz[0]);
		return count ($ArrayDataMatriz[0]);
	}



/******************************************/	
/*FUNCIONES DE VALIDACIONES DE MATRICES */

	/**
	 * Funcion que valida si dos matrices son iguales, es decir que tengan el mismo numero de N y M
	 *
	 * @param matrix $matrizA
	 * @param matrix $matrizB
	 * @return bool
	 */
	function ValidaMatricesDimenIguales($ObjMatrizA, $ObjMatrizB){
		//valida que las matrices sean v&aacute;lidas
		if ($ObjMatrizA->NumFila==$ObjMatrizB->NumFila and $ObjMatrizA->NumColumna==$ObjMatrizB->NumFila)
			return true;
		else
			return false;
	}
		

	/**
	 * Funcion que valida que la matriz sea de NxN
	 *
	 * @return bool
	 */
	function ValidaMatriz_N_x_N(){
		if ($this->NumFila == $this->NumColumna)
			 return true;
			 
	return false;
	}
	
	/**
	 * Valida que el numero de columna de una matriz.. se el mismo en todas sus filas
	 *
	 * @param integer $NumFilas
	 * @param integer $NumColumnas
	 * @return bool
	 */
	function ValidaNumColumnasObjMatriz($NumFilas,$NumColumnas){
		for ($i=0;$i<$NumFilas;$i++){
			$columna = count($this->ArrayData [$i]);
			if ($NumColumnas != $columna)
				return false;
		}
	return true;
	}
	
	/**
	 * Dado un arreglo de datos de una matriz, valida que el número de 
	 * columnas de una matriz.. se el mismo en todas sus filas
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @param integer $NumFilas
	 * @param integer $NumColumnas
	 * @return unknown
	 */
	function ValidaNumColumnasArrayDataMatriz($ArrayDataMatriz,$NumFilas,$NumColumnas){
		for ($i=0;$i<$NumFilas;$i++){
			$columna = count($ArrayDataMatriz[$i]);
			if ($NumColumnas != $columna)
				return false;
		}
	return true;
	}

	
	

/************************************************/	
/*FUNCIONES DE OPERACIONES BASICAS CON MATRICES */

	/**
	 * Resta de dos matrices
	 * Requisito: tiene que se de iguales valores de NxM
	 *
	 * @param ArrayData $ArrayDataMatriz1
	 * @param ArrayData $ArrayDataMatriz2
	 * @return ArrayData
	 */
	function RestaMatrices($ArrayDataMatriz1, $ArrayDataMatriz2){
		$filas1 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz1);
		$filas2 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz2);
		$columnas1 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz1);
		$columnas2 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz2);
		
		for($i=0; $i<$filas1; $i++) {   
			for($j=0; $j<$columnas1; $j++){
				$ArrayResta[$i][$j]= $ArrayDataMatriz1[$i][$j]-$ArrayDataMatriz2[$i][$j];
			}
		}
		return $ArrayResta;
		
	}
	
	/**
	 * Suma de dos matrices
	 * Requisito: tiene que se de iguales valores de NxM
	 *
	 * @param ArrayData $ArrayDataMatriz1
	 * @param ArrayData $ArrayDataMatriz2
	 * @return ArrayData
	 */
	function SumaMatrices($ArrayDataMatriz1, $ArrayDataMatriz2){
		$filas1 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz1);
		$filas2 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz2);
		$columnas1 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz1);
		$columnas2 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz2);
		
		for($i=0; $i<$filas1; $i++) {   
			for($j=0; $j<$columnas1; $j++){
				$ArrayResta[$i][$j]= $ArrayDataMatriz1[$i][$j]+$ArrayDataMatriz2[$i][$j];
			}
		}
		return $ArrayResta;
		
	}	
	


	/**
	 * Calcula la matriz resultante de multiplicar dos matrices
	 * Requisito: los datos de las matrices A,B, tiene que cumplir que
	 * El # de columnas de A, tienen que se igual a las filas de B.
	 * C(pxq) = A(pxm) * B(mxq)
	 *
	 * @param ArrayData $ArrayDataMatriz1
	 * @param ArrayData $ArrayDataMatriz2
	 * @return ArrayData
	 */
	function MultiplicacionMatrices($ArrayDataMatriz1, $ArrayDataMatriz2) {
		$filas1 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz1);
		$columnas1 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz1);

		$columnas2 = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz2);		
		$filas2 = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz2);

		for($i=0; $i<$filas1; $i++){
			for($j=0; $j<$columnas2; $j++){
				$ArrayMultipli[$i][$j]=0; $sum=0;
				for($M=0;$M<$columnas1;$M++){
					$ArrayMultipli[$i][$j]  = $ArrayMultipli[$i][$j] + $ArrayDataMatriz1[$i][$M]*$ArrayDataMatriz2[$M][$j];
				}
			}
		}
		return $ArrayMultipli;
	}
		
	/**
	 * Calcula la matriz resultante al dividir una matriz para un escalar
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @param integer $valor
	 * @return ArrayData
	 */
	function DivisionMatriz($ArrayDataMatriz, $valor) {
		$filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
		$columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);

		$matriz = array();
		for($i = 0; $i < $filas; $i++) {
			for($j = 0; $j < $columnas; $j++) {
				$matriz[$i][$j] = $ArrayDataMatriz[$i][$j] / $valor;
			}
		}
		return $matriz;
	}
	
	/**
	 * Calcula el Determinante de una matriz.
	 * Requisito: Todas filas deben tener el mismo número de columnas.
	 * Requisito: La matriz debe ser de NxN
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @return integer
	 */
	function Determinante($ArrayDataMatriz) {
		$filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
		$columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
		$det = 0;
		if ($filas == 2 && $columnas == 2) {
			$det = $ArrayDataMatriz[0][0] * $ArrayDataMatriz[1][1] - $ArrayDataMatriz[0][1] * $ArrayDataMatriz[1][0];
		} else {
			$matriz = array();
			/* Recorrer las columnas pivotes */
			for($j = 0; $j < $columnas; $j++) {
				/* Se crea una sub matriz */
				$matriz = $this->SubMatriz($ArrayDataMatriz, 0, $j);
				if (fmod($j, 2) == 0) {
					$det += $ArrayDataMatriz[0][$j]*$this->Determinante($matriz);
				} else {
					$det -= $ArrayDataMatriz[0][$j]*$this->Determinante($matriz);
				}
			}
		}
		return $det;
	}


	/**
	 * Enter description here...
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @param integer $pivoteX
	 * @param integer $pivoteY
	 * @return ArrayData
	 */
	function SubMatriz($ArrayDataMatriz, $pivoteX, $pivoteY) {
		//echo "determiando SUBMATRIZ<br>";
		$filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
		$columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
		$matriz = array();
		$p = 0; // indica la fila de la nueva submatriz
		for($i = 0; $i < $filas; $i++) {
			$q = 0; // indica la columna de la nueva submatriz
			if ($pivoteX != $i) {
				for($j = 0; $j < $columnas; $j++) {
					if ($pivoteY != $j) {
						$matriz[$p][$q] = $ArrayDataMatriz[$i][$j];
						$q++;
					}
				}
				$p++;
			}
		}
		return $matriz;
	}


	/**
	 * Calcula la matriz transpuesta de la matriz dada
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @return ArrayData
	 */
	function Transpuesta($ArrayDataMatriz) {
		$filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
		$columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
		$ArrayTranspuesta = array();
		//echo $filas.",".$columnas;
		for($i = 0; $i < $filas; $i++) {
			for($j = 0; $j < $columnas; $j++) {
				//echo "el dato es ".$ArrayDataMatriz[$i][$j]."<br>";
				$ArrayTranspuesta[$j][$i] = $ArrayDataMatriz[$i][$j];
			}
		}
		return $ArrayTranspuesta;
		
	}


	/**
	 * Calcula la matriz inversa de la matriz dada
	 *
	 * @param ArrayData $ArrayDataMatriz
	 * @return ArrayData
	 */
	function InversaMatriz($ArrayDataMatriz) {
		$filas = $this->get_NumFilas_ArrayDataMatriz($ArrayDataMatriz);
		$columnas = $this->get_NumColumnas_ArrayDataMatriz($ArrayDataMatriz);
		//echo "determiando inversa<br>";
		$matriz = array();
		for($i = 0; $i < $filas; $i++) {
			for($j = 0; $j < $columnas; $j++) {
				if (fmod($i + $j, 2) == 0) {
					$matriz[$i][$j] = $this->Determinante($this->SubMatriz($ArrayDataMatriz, $i, $j));
				} else {
					$matriz[$i][$j] = -$this->Determinante($this->SubMatriz($ArrayDataMatriz, $i, $j));
				}
			}
		}
		return $this->Transpuesta($this->DivisionMatriz($matriz,$this->Determinante($ArrayDataMatriz)));
	}
	

/**************************************************/	
/*FUNCIONES DE OPERACIONES AVANZADAS CON MATRICES */
	
	/**
	 * 	M = mean(A)  return la media de los valores de una dimension del arreglo
	 * 	If A is a vector, mean(A) returns the mean value of A.
	 * 	If A is a matrix, mean(A) treats the columns of A as vectors, returning a row vector of mean values.
	 * 	A = [1 2 3; 3 3 6; 4 6 8; 4 7 7];
	 * 	mean(A)= [ 3.0000    4.5000    6.000 ]
	 *
	 * @return unknown
	 */
	function MediasMatriz(){
		//encero los valores para el arreglo que va a almacenar las medias y las sumas
		for ($j=0; $j<$this->NumColumna; $j++){
			$this->ArrayMedia[$j]=0;
			$suma_media[$j]=0;
		}
		for ($j=0; $j<$this->NumColumna; $j++){
			for ($i=0; $i<$this->NumFila; $i++){
				$suma_media[$j]+=$this->ArrayData[$i][$j];
			}
			//echo "suma $i,$j=".$this->ArrayData[$i][$j]."<br>";
			$this->ArrayMedia[$j]=$suma_media[$j]/$this->NumFila;
			$this->ArraySumaMedia[$j]=$suma_media[$j];
		}
	//retorno la matriz con los promedio de cada columna (la matriz de la media)
	return true;
	}
	

		

	/**
	 * COV(X,Y)
	 * Calcula la covarianza entre los vectores x i y
	 * C = CovarianzaVector(x) where x,y  are vectors, 
	 *
	 * @param array $vectorX
	 * @param array $vectorY
	 * @return integer
	 */
	function CovarianzaVectores ($vectorX, $vectorY){
		$NumFilas = count($vectorX);
		if ($NumFilas != count($vectorY)) return null;
		$covarianza = 0;$sum=0;
		$mean_x = $this->MediaVector($vectorX);
		$mean_y = $this->MediaVector($vectorY);
		for($i = 0; $i < $NumFilas; $i++) {
			$valor = (($vectorX[$i] - $mean_x) * ($vectorY[$i] - $mean_y));
			$sum += $valor;
		}
		$covarianza = $sum / $NumFilas;
		return $covarianza;
	}
	
	
	/**
	 * Calcula la matriz de covarianza de una matriz A
	 * S = CovarianzaMatriz(x) where A es una matriz.
	 * Cada fila es una observacion y cada columna es una variable
	 * n = numero de observaciones (# filas)
	 * Cov (A)= A * A'
	*/
	function CovarianzaMatriz($ArrayData){
		$transpA = $this->Transpuesta($ArrayData);
		$MatrizCov =  $this->MultiplicacionMatrices($ArrayData,$transpA);
		return $MatrizCov;
	}
	



}
?>
Return current item: Matrix