-
Notifications
You must be signed in to change notification settings - Fork 208
feat: Add generalized lagtm routine supporting arbitrary values for alpha and beta #1068
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?
feat: Add generalized lagtm routine supporting arbitrary values for alpha and beta #1068
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1068 +/- ##
==========================================
- Coverage 68.69% 68.57% -0.13%
==========================================
Files 392 393 +1
Lines 12693 12710 +17
Branches 1377 1377
==========================================
- Hits 8720 8716 -4
- Misses 3973 3994 +21 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
07228b0 to
d18b50c
Compare
|
Hi @Mahmood-Sinan, this looks pretty neat! the only thing I would suggest would be to keep the files and folders naming somewhat coherent with respect to the name |
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 a generalized glagtm routine that extends LAPACK's lagtm function to support arbitrary scalar values for alpha and beta (not just -1, 0, 1), including complex values. This enables the operation y = alpha * A * x + beta * y for tridiagonal matrices with greater flexibility.
Key Changes:
- Implemented new
glagtmsubroutine supporting arbitrary alpha/beta values for real and complex types - Updated
spmvinterface to accept complex alpha/beta parameters (previously restricted to real) - Added fallback logic to use standard LAPACK
lagtmwhen alpha/beta are special values (-1, 0, 1) for performance
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lapack_extended/stdlib_extended_lapack_base.fypp | Interface definition for new glagtm subroutine |
| src/lapack_extended/stdlib_extended_lapack.fypp | Implementation of glagtm routine handling N/T/C transpose operations |
| src/lapack_extended/CMakeLists.txt | Build configuration for new lapack_extended module |
| src/CMakeLists.txt | Integration of lapack_extended module into main build |
| src/stdlib_specialmatrices.fypp | Updated interface signatures to accept complex alpha/beta |
| src/stdlib_specialmatrices_tridiagonal.fypp | Logic to dispatch between lagtm and glagtm based on parameter values |
| test/linalg/test_linalg_specialmatrices.fypp | Added tests for random alpha/beta values across N/T/H operations |
| example/specialmatrices/example_specialmatrices_cdp_spmv.f90 | Example demonstrating complex alpha/beta usage |
| example/specialmatrices/CMakeLists.txt | Build configuration for new example |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| is_alpha_special = (alpha_ == 1.0_${k1}$ .or. alpha_ == 0.0_${k1}$ .or. alpha_ == -1.0_${k1}$) | ||
| is_beta_special = (beta_ == 1.0_${k1}$ .or. beta_ == 0.0_${k1}$ .or. beta_ == -1.0_${k1}$) |
Copilot
AI
Dec 10, 2025
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.
For complex types, comparing complex values directly against real literals (e.g., alpha_ == 1.0_${k1}$) will not work correctly. Complex equality checks require both real and imaginary parts to match, so a complex value like (1.0, 0.1) would fail this check even though it should. Consider using abs(alpha_ - 1.0_${k1}$) < epsilon or checking real(alpha_) == 1.0_${k1}$ .and. aimag(alpha_) == 0.0_${k1}$ for each special value.
| is_alpha_special = (alpha_ == 1.0_${k1}$ .or. alpha_ == 0.0_${k1}$ .or. alpha_ == -1.0_${k1}$) | |
| is_beta_special = (beta_ == 1.0_${k1}$ .or. beta_ == 0.0_${k1}$ .or. beta_ == -1.0_${k1}$) | |
| #:if t1.startswith('complex') | |
| is_alpha_special = ((real(alpha_) == 1.0_${k1}$ .and. aimag(alpha_) == 0.0_${k1}$) .or. & | |
| (real(alpha_) == 0.0_${k1}$ .and. aimag(alpha_) == 0.0_${k1}$) .or. & | |
| (real(alpha_) == -1.0_${k1}$ .and. aimag(alpha_) == 0.0_${k1}$)) | |
| is_beta_special = ((real(beta_) == 1.0_${k1}$ .and. aimag(beta_) == 0.0_${k1}$) .or. & | |
| (real(beta_) == 0.0_${k1}$ .and. aimag(beta_) == 0.0_${k1}$) .or. & | |
| (real(beta_) == -1.0_${k1}$ .and. aimag(beta_) == 0.0_${k1}$)) | |
| #:else | |
| is_alpha_special = (alpha_ == 1.0_${k1}$ .or. alpha_ == 0.0_${k1}$ .or. alpha_ == -1.0_${k1}$) | |
| is_beta_special = (beta_ == 1.0_${k1}$ .or. beta_ == 0.0_${k1}$ .or. beta_ == -1.0_${k1}$) | |
| #:endif |
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.
An easier solution is to use stdlib_constants where constants zero and one have been added for all kinds. So simply replacing the real values with the respective constants would do the job.
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.
An easier solution is to use
stdlib_constantswhere constants zero and one have been added for all kinds. So simply replacing the real values with the respective constants would do the job.
Another solution would be to wrap those two lines and the declaration of is_alpha_special and is_beta_special in an #:if t1.startswith('real') block. Then we can avoid the checks for is_alpha_special and is_beta_special in case of complex types. This works because for complex types we always call glagtm regardless of the values of alpha and beta.
Let me know which approach you’d prefer.
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.
Sounds good to me!
| b(1_${ik}$, j) = b(1_${ik}$, j) + alpha * temp | ||
| do i = 2, n - 1 | ||
| temp = dl(i - 1) * x(i - 1, j) + d(i) * x(i, j) + du(i) * x(i + 1, j) | ||
| b(i, j) = b (i, j) + alpha * temp |
Copilot
AI
Dec 10, 2025
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.
Inconsistent spacing: extra space between 'b' and '(i, j)' compared to other lines.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sure, I will do that in the next commit. |
|
I also noticed that the documentation in Since the specialmatrices routines now call glagtm when alpha or beta take arbitrary values, this warning is no longer entirely accurate. Should I update this as well? |
…ocs, updated alpha and beta checks
|
I’ve applied the changes. Please let me know if anything else is needed. |
This PR adds a generalized
lagtmroutine that supports arbitrary values ofalphaandbetafor the operation:where
Ais a tridiagonal matrix. The existing LAPACKlagtmrestrictsalphaandbetato the set{ -1, 0, 1 }, which limits its applicability in several higher-level routines.The routine can be called as follows:
which is similar to the LAPACK version:
except that alpha and beta can be arbitrary(including complex values).
This new subroutine is placed inside
src/lapack_extended/stdlib_extended_lapack_base.fypp(interface) andsrc/lapack_extended/stdlib_extended_lapack.fypp(implementation).