. * * END LICENSE * * @author Chris Pollett (chris@pollett.org) * @license http://www.gnu.org/licenses/ GPL3 * @link http://www.seekquarry.com/ * @copyright 2009 - 2015 * @filesource */ namespace seekquarry\yioop\library\summarizers; use seekquarry\yioop\configs as C; use seekquarry\yioop\library as L; use seekquarry\yioop\library\CrawlConstants; use seekquarry\yioop\library\PhraseParser; use seekquarry\yioop\library\processors\PageProcessor; /** * Class used by the Lanczos algorithm for common matix operations. * @author Charles Bocage (charles.bocage@sjsu.edu) */ class Matrix { public $M; // number of rows public $N; // number of columns public $data; public function __construct() { $get_arguments = func_get_args(); $number_of_arguments = func_num_args(); if (method_exists($this, $method_name = '__construct'.$number_of_arguments)) { call_user_func_array(array($this, $method_name), $get_arguments); } } // create matrix based on 2d array public function __construct1($data) { $this->M = count($data); $this->N = count($data[0]); $this->data = array(); for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { $this->data[$i][$j] = $data[$i][$j]; } } } public function __construct2($M, $N) { $this->M = $M; $this->N = $N; $this->data = array(); } public function getElement($m, $n) { return $this->data[$m][$n]; } public function getRowNum() { return $this->M; } public function zeroize() { $z = new Matrix($this->M, $this->N); for ($i = 0; $i < $this->M - 1; $i++) { for ($j = 0; $j < $this->N; $j++) { $z->data[$i][$j] = 0.0; } } $z->data[$this->M - 1][0] = 0; return $z; } public function substitute() { $x = new Matrix($this->N, 1); for ($i = 0; $i < $this->M; $i++) { $x->data[$i][0] = 0.0; } $x->data[$this->N - 1][0] = 1; for ($i = $this->M - 2; $i >= 0; $i--) { $temp = $x->data[$i][0]; for ($j = ($i + 1); $j < $this->M; $j++) { $temp -= ($this->data[$i][$j] * $x->data[$j][0]); } $x->data[$i][0] = $temp / $this->data[$i][$i]; } return $x; } public function specialClone() { $m = new Matrix($this->M, $this->N); for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { $m->data[$i][$j]= $this->data[$i][$j]; } } $m->data[$this->M - 1][$this->N - 1] = 1; return $m; } public function cClone() { $m = new Matrix($this->M, $this->N); for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { $m->data[$i][$j]= $this->data[$i][$j]; } } return $m; } public function getRidOfNegativeZero() { for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { if (floatval(number_format($this->data[$i][$j], 3)) == -0.0) { $this->data[$i][$j] = 0.0; } } } } public function getColNum() { return $this->N; } public function norm() { $norm = 0.0; for ($i = 0; $i < $this->M; $i++) { $norm = $norm + pow($this->data[$i][0], 2.0); } return sqrt($norm); } public function multinorm($c) { $norm = 0.0; for ($i = 0; $i < $this->M; $i++) { $norm = $norm + pow($this->data[$i][$c], 2.0); } return sqrt($norm); } public function getMultiNorm() { $m = new Matrix($this->M, $this->N); for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { $n = $this->multinorm($j); if ($n != 0) { $m->data[$i][$j] = $this->data[$i][$j] / $n; } else { $m->data[$i][$j] = 0.0; } } } return $m; } public function transpose() { $A = new Matrix($this->N, $this->M); for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { $A->data[$j][$i] = $this->data[$i][$j]; } } return $A; } public function plus($B) { $A = $this; if ($B->M != $A->M || $B->N != $A->N) { throw new Exception("Illegal matrix dimensions."); } $C = new Matrix($this->M, $this->N); for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { $C->data[$i][$j] = $A->data[$i][$j] + $B->data[$i][$j]; } } return $C; } public function minus($B) { $A = $this; if ($B->M != $A->M || $B->N != $A->N) { throw new Exception("Illegal matrix dimensions."); } $C = new Matrix($this->M, $this->N); for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { $C->data[$i][$j] = $A->data[$i][$j] - $B->data[$i][$j]; } } return $C; } public function times($B) { $A = $this; if ($A->N != $B->M) { throw new Exception("Illegal matrix dimensions."); } $C = new Matrix($A->M, $B->N); for ($i = 0; $i < $C->M; $i++) { for ($j = 0; $j < $C->N; $j++) { for ($k = 0; $k < $A->N; $k++) { if (!isset($C->data[$i][$j])) { $C->data[$i][$j] = 0; } $C->data[$i][$j] += ($A->data[$i][$k] * $B->data[$k][$j]); } } } return $C; } public function solve() { $i = 0; $j = 0; $A = new Matrix($this->M, $this->N); for ($i = 0; $i < $this->M; $i++) { for($j = 0; $j < $this->N; $j++) { $A->data[$i][$j] = $this->data[$i][$j]; } } $step = 0; for ($p = 0; $p < $A->M; $p++) { print(">>> Step " . step . " for Gaussian Elimination.\n"); $A->show(); $max = $p; for ($i = $p + 1; $i < $A->M; $i++) { if (abs($A->data[$i][$p]) > abs($A->data[$max][$p])) { $max = $i; } } $temp = $A->data[$p]; $A->data[$p] = $A->data[$max]; $A->data[$max] = $temp; for ($i = $p + 1; $i < $A->M; $i++) { $alpha = 0.0; if ($A->data[$i][$p] == 0) { continue; } else { $alpha = $A->data[$p][$p] / $A->data[$i][$p]; } for ($j = $p; $j < $this->N; $j++) { $A->data[$i][$j] = $A->data[$p][$j] - ($alpha * $A->data[$i][$j]); $A->getRidOfNegativeZero(); //added } } $step++; } // end outer for $x = new Matrix($this->N, 1); for ($i = 0; $i < $this->M; $i++) { $x->data[$i][0] = 0; } $x->data[$this->N - 1][0] = 1; for ($i = $A->M - 2; $i >= 0; $i--) { $sum=0; for ($j = ($i + 1); $j < $A->M; $j++){ $sum += ($A->data[$i][$j] * $x->data[$j][0]); } $temp = $x->data[$i][0]; if ($A->data[$i][$i] != 0) { $x->data[$i][0] = ($temp - $sum) / $A->data[$i][$i]; } else { $x->data[$i][0] = 1; } } print(">>> After computing back-substitution for x,y,z values\n"); $x->getRidOfNegativeZero(); // added $x->show(); return x; } public function format($a) { if ($a > -0.001 && $a < 0.001) { return 0; } else { return $a; } } public function show() { for ($i = 0; $i < $this->M; $i++) { for ($j = 0; $j < $this->N; $j++) { print(number_format($this->data[$i][$j], 3)); } print("\n"); } } public function getNorm() { $m = new Matrix($this->M, 1); $n = $this->norm(); for ($i = 0; $i < $this->M; $i++) { $m->data[$i][0] = $this->data[$i][0] / $n; } return $m; } }