You are here

private function EigenvalueDecomposition::tred2 in Loft Data Grids 6.2

Same name and namespace in other branches
  1. 7.2 vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php \EigenvalueDecomposition::tred2()

* Symmetric Householder reduction to tridiagonal form. * * @access private

1 call to EigenvalueDecomposition::tred2()
EigenvalueDecomposition::__construct in vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php
* Constructor: Check for symmetry, then construct the eigenvalue decomposition * * @access public *

File

vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php, line 76

Class

EigenvalueDecomposition
@package JAMA

Code

private function tred2() {

  //  This is derived from the Algol procedures tred2 by
  //  Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
  //  Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
  //  Fortran subroutine in EISPACK.
  $this->d = $this->V[$this->n - 1];

  // Householder reduction to tridiagonal form.
  for ($i = $this->n - 1; $i > 0; --$i) {
    $i_ = $i - 1;

    // Scale to avoid under/overflow.
    $h = $scale = 0.0;
    $scale += array_sum(array_map(abs, $this->d));
    if ($scale == 0.0) {
      $this->e[$i] = $this->d[$i_];
      $this->d = array_slice($this->V[$i_], 0, $i_);
      for ($j = 0; $j < $i; ++$j) {
        $this->V[$j][$i] = $this->V[$i][$j] = 0.0;
      }
    }
    else {

      // Generate Householder vector.
      for ($k = 0; $k < $i; ++$k) {
        $this->d[$k] /= $scale;
        $h += pow($this->d[$k], 2);
      }
      $f = $this->d[$i_];
      $g = sqrt($h);
      if ($f > 0) {
        $g = -$g;
      }
      $this->e[$i] = $scale * $g;
      $h = $h - $f * $g;
      $this->d[$i_] = $f - $g;
      for ($j = 0; $j < $i; ++$j) {
        $this->e[$j] = 0.0;
      }

      // Apply similarity transformation to remaining columns.
      for ($j = 0; $j < $i; ++$j) {
        $f = $this->d[$j];
        $this->V[$j][$i] = $f;
        $g = $this->e[$j] + $this->V[$j][$j] * $f;
        for ($k = $j + 1; $k <= $i_; ++$k) {
          $g += $this->V[$k][$j] * $this->d[$k];
          $this->e[$k] += $this->V[$k][$j] * $f;
        }
        $this->e[$j] = $g;
      }
      $f = 0.0;
      for ($j = 0; $j < $i; ++$j) {
        $this->e[$j] /= $h;
        $f += $this->e[$j] * $this->d[$j];
      }
      $hh = $f / (2 * $h);
      for ($j = 0; $j < $i; ++$j) {
        $this->e[$j] -= $hh * $this->d[$j];
      }
      for ($j = 0; $j < $i; ++$j) {
        $f = $this->d[$j];
        $g = $this->e[$j];
        for ($k = $j; $k <= $i_; ++$k) {
          $this->V[$k][$j] -= $f * $this->e[$k] + $g * $this->d[$k];
        }
        $this->d[$j] = $this->V[$i - 1][$j];
        $this->V[$i][$j] = 0.0;
      }
    }
    $this->d[$i] = $h;
  }

  // Accumulate transformations.
  for ($i = 0; $i < $this->n - 1; ++$i) {
    $this->V[$this->n - 1][$i] = $this->V[$i][$i];
    $this->V[$i][$i] = 1.0;
    $h = $this->d[$i + 1];
    if ($h != 0.0) {
      for ($k = 0; $k <= $i; ++$k) {
        $this->d[$k] = $this->V[$k][$i + 1] / $h;
      }
      for ($j = 0; $j <= $i; ++$j) {
        $g = 0.0;
        for ($k = 0; $k <= $i; ++$k) {
          $g += $this->V[$k][$i + 1] * $this->V[$k][$j];
        }
        for ($k = 0; $k <= $i; ++$k) {
          $this->V[$k][$j] -= $g * $this->d[$k];
        }
      }
    }
    for ($k = 0; $k <= $i; ++$k) {
      $this->V[$k][$i + 1] = 0.0;
    }
  }
  $this->d = $this->V[$this->n - 1];
  $this->V[$this->n - 1] = array_fill(0, $j, 0.0);
  $this->V[$this->n - 1][$this->n - 1] = 1.0;
  $this->e[0] = 0.0;
}