pow method

Matrix pow(
  1. num power
)

Raises this matrix to a given power. Uses eigenvalue decomposition for non-integer powers and binary exponentiation for integer powers.

Note: For non-symmetric matrices, the eigenvalues might be complex, and thus the result of raising them to a power could also be complex. In such cases, the output of this function might not be accurate.

If the matrix is not square, this method throws an ArgumentError. If a negative eigenvalue is encountered when trying to compute a fractional power, this method throws an ArgumentError.

power - the power to which this matrix should be raised. Returns a new matrix that is this matrix raised to the given power.

Implementation

Matrix pow(num power) {
  // Ensure the matrix is square
  if (rowCount != columnCount) {
    throw ArgumentError('Matrix must be square to raise it to a power.');
  }

  if (power < 0) {
    throw ArgumentError('Power must be non-negative.');
  }

  if (power == power.floor()) {
    // Use binary exponentiation for integer powers
    Matrix result = Matrix.eye(rowCount);
    Matrix base = this;
    int p = power.toInt();

    while (p > 0) {
      if (p % 2 == 1) {
        result = result * base;
      }
      base = base * base;
      p = p ~/ 2;
    }

    return result;
  } else {
    // Perform eigenvalue decomposition
    var eigenvalueDecomposition = decomposition.eigenvalueDecomposition();
    Matrix D = eigenvalueDecomposition.D;
    Matrix V = eigenvalueDecomposition.V;

    // Raise eigenvalues to the given power
    for (int i = 0; i < D.rowCount; i++) {
      if (D[i][i] < 0 && power != power.floor()) {
        throw ArgumentError(
            'Negative eigenvalue found when trying to compute fractional power.');
      }
      D[i][i] = math.pow(D[i][i], power);
    }

    // Reconstruct the matrix using the pseudo-inverse of V
    var result = V * D * V.pseudoInverse();

    return result;
  }
}