-
Notifications
You must be signed in to change notification settings - Fork 192
Exponential of a matrix #968
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
I think it is pretty much ready for review. Note that the optimizations I've mentioned (i.e. variable order for the Pade approximation, balancing, etc) wouldn't change the signature of the function. Either we take it as is and gradually improve it over time, or we improve it right away (but I won't have much time to do it right now). As you like. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @loiseaujc ! LGTM. I have some minor suggestions and some additional ones that might lead to some discussions.
Co-authored-by: Jeremie Vandenplas <[email protected]>
Update working branch with latest master features.
This reverts commit 65ad5f2.
Seems like I have issues with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds the matrix exponential function (expm
/matrix_exp
) to the stdlib_linalg
module using a scaling-and-squaring Pade approximation, along with tests, documentation, and examples.
- New
stdlib_linalg_matrix_functions
submodule implementingexpm
andmatrix_exp
(in-place and out-of-place). - Public interfaces, error handling, and constants (
log2_*
) integrated intostdlib_linalg
. - Added tests, CMake targets, an example program, and spec updates for
expm
.
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
File | Description |
---|---|
test/linalg/test_linalg_expm.fypp | New unit tests for correct computation and error handling |
test/linalg/CMakeLists.txt | Registered test_linalg_expm.fypp and added linalg_expm test |
src/stdlib_linalg_matrix_functions.fypp | Implementation of expm /matrix_exp with Pade approx. |
src/stdlib_linalg.fypp | Exposed expm and matrix_exp interfaces in the module |
src/stdlib_constants.fypp | Added log2_* constants for scaling computation |
src/CMakeLists.txt | Includes new matrix functions source file in the build |
example/linalg/example_expm.f90 | Simple example program demonstrating expm usage |
example/linalg/CMakeLists.txt | Added expm to the example registry |
doc/specs/stdlib_linalg.md | Documentation and specification for the expm interface |
Comments suppressed due to low confidence (4)
src/stdlib_linalg_matrix_functions.fypp:13
- [nitpick] The
this
parameter is set to "matrix_exponential" while the public interface names areexpm
andmatrix_exp
. Consider aligning this identifier with the interface name for consistency in error messages.
character(len=*), parameter :: this = "matrix_exponential"
src/stdlib_linalg_matrix_functions.fypp:84
- Remove the extraneous '&' in the error message string: 'Order of Pade approximation needs to be positive, order='.
err0 = linalg_state_type(this, LINALG_VALUE_ERROR, 'Order of Pade approximation &
src/stdlib_linalg_matrix_functions.fypp:82
- [nitpick] Error messages for invalid sizes differ between in-place and out-of-place interfaces (
Invalid matrix size
vsinvalid matrix sizes
). Consider standardizing on consistent wording and capitalization.
err0 = linalg_state_type(this,LINALG_VALUE_ERROR,'Invalid matrix size A=',[m, n])
test/linalg/test_linalg_expm.fypp:78
- [nitpick] Consider adding error-handling tests for the function interface
expm
(e.g., negative order or non-square inputs) to match those inmatrix_exp
.
E = expm(A)
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Following a comment by Meromorphic on the discourse here, this PR implements the matrix exponential function
expm
. It does so in a newstdlib_linalg_matrix_functions
submodule which might eventually accomodate later on implementations of other matrix functions (e.g.logm
,sqrtm
,cosm
, etc).Proposed interface
E = expm(A [, order, err])
whereA
is the inputn x n
matrix,order
(optional) is the order of the Pade approximation, anderr
of typelinalg_state_type
for error handling.Key facts
The implementation makes use of a standard "scaling and squaring" approach to compute the Pade approximation with a fixed order. It is adapted from the implementation by John Burkardt.
Progress
Possible improvements
The implementation is fully working and validated. Computational performances and/or robustness could potentially be improved eventually by considering:
order
for the Pade approximation based on the data. This is used for instance inscipy.linalg.expm
.At the end of the algorithm, the squaring step is implemented using a simple loop involving(irrelevant for this particular task since the scaling factor is chosen as a power of 2, might still be a useful function in the grand scheme of things)matmul
. Additional performances can be gained by implementing a fastmatrix_power
function (seenp.matrix_power
for instance).In practice, it has however never failed me so far.
cc @perazz, @jvdp1, @jalvesz