eigenvalues method

  1. @override
List<Complex> eigenvalues()
override

Returns the eigenvalues associated to this matrix.

Eigenvalues can only be computed if the matrix is square, meaning that it must have the same number of columns and rows.

A MatrixException object is thrown if the matrix isn't square.

Implementation

@override
List<Complex> eigenvalues() {
  // Making sure that the matrix is squared
  if (!isSquareMatrix) {
    throw const MatrixException(
      'Eigenvalues can be computed on square matrices only!',
    );
  }

  // From now on, we're sure that the matrix is square. If it's 1x1 or 2x2,
  // computing the roots of the characteristic polynomial is faster and more
  // precise.
  if (rowCount == 1 || rowCount == 2) {
    return characteristicPolynomial().solutions();
  }

  // For 3x3 matrices and bigger, use the "eigendecomposition" algorithm.
  final eigenDecomposition = EigendecompositionReal(
    matrix: this,
  );

  // The 'D' matrix contains real and complex coefficients of the eigenvalues
  // so we can ignore the other 2.
  final decomposition = eigenDecomposition.decompose()[1];
  final eigenvalues = <Complex>[];

  for (var i = 0; i < decomposition.rowCount; ++i) {
    // The real value is ALWAYS in the diagonal.
    final real = decomposition(i, i);

    // The imaginary part can be either on the right or the left of the main
    // diagonal, depending on the sign.
    if (i > 0 && i < (decomposition.rowCount - 1)) {
      // Values on the left and right of the diagonal.
      final pre = decomposition(i, i - 1);
      final post = decomposition(i, i + 1);

      if (pre == 0 && post == 0) {
        eigenvalues.add(Complex.fromReal(real));
      } else {
        eigenvalues.add(Complex(real, pre == 0 ? post : pre));
      }
    } else {
      // Here the loop is either at (0,0) or at the bottom of the diagonal so
      // we need to check only one side.
      if (i == 0) {
        eigenvalues.add(Complex(real, decomposition(i, i + 1)));
      } else {
        eigenvalues.add(Complex(real, decomposition(i, i - 1)));
      }
    }
  }

  return eigenvalues;
}