# Singular Value Decomposition Implementation

**URL:** <https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060>\
**Category:** Uncategorized\
**Created:** [April 12, 2021, 7:54pm UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060 "2021-04-12T19:54:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hsnyder](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hsnyder/32/747_2.png) [@hsnyder](https://fortran-lang.discourse.group/u/hsnyder)\
**Post date:** [April 12, 2021, 7:54pm UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060/1 "2021-04-12T19:54:24Z")

</div>

Hello everyone!

Does anybody know of a good open source implementation of the singular value decomposition written in modern Fortran? I may need to modify an SVD implementation in order to support a custom matrix type that includes forward-mode automatic differentiation via overloaded operators (following the example from Arjen Markus’s book), and it would be very helpful to have an implementation that was close to useable right out of the gate.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [April 12, 2021, 8:29pm UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060/2 "2021-04-12T20:29:10Z")

</div>

Don’t know of any SVD implementations written in Modern Fortran  
but you might be better off just finding an old F77 implementation  
that has some F90 mods and then wrapping that routine with whatever  
Modern Fortran logic you need. Linpack and/or Lapack would be your  
best bet (check [www.netlib.org](http://www.netlib.org)). A routine I have used in the past is  
a slightly modified version of the SVD routine from the Forsythe, Malcolm,  
and Moler book (the modified version is from EISPACK, I think), _Computer Methods for_  
_Mathematical Computations_. The version I used ican be found as part of the FMM  
software on Ralph Carmichael’s Public Domain Programs for the Aeronautical Engineer (PDAS)  
web site ([https://www.pdas.com](https://www.pdas.com)). Go to [Computer Methods for Mathematical Computations](https://www.pdas.com/fmm.html). In addition to the SVD routine there are several other useful programs from the FMM book such as zeroin,  
quant8 etc. The download file contains the original F77 files plus some moderate refactoring  
to F90 by Carmichael. (Note the FMM routine is basically the same one found in _Numerical Recipes_)

---

<div class="post-metadata">

**Author:** ![Beliavsky](https://avatars.discourse-cdn.com/v4/letter/b/ba8739/32.png) [@Beliavsky](https://fortran-lang.discourse.group/u/Beliavsky)\
**Post date:** [April 12, 2021, 8:30pm UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060/3 "2021-04-12T20:30:42Z")

</div>

The term “modern Fortran” is not precisely defined, although I use it too. Alan Miller’s [dsvdc.f90](https://jblevins.org/mirror/amiller/) uses free source form and has argument INTENTs. From John Burkardt’s [site](https://people.sc.fsu.edu/~jburkardt/f_src/f_src.html) one can compile gfortran -std=legacy linpack\_d.f90 lapack\_d.f90 svd\_test.f90.

---

<div class="post-metadata">

**Author:** ![hsnyder](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hsnyder/32/747_2.png) [@hsnyder](https://fortran-lang.discourse.group/u/hsnyder)\
**Post date:** [April 12, 2021, 8:54pm UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060/4 "2021-04-12T20:54:54Z")

</div>

Thanks very much to both of you. I will look into the referenced implementations.

---

<div class="post-metadata">

**Author:** ![rwmsu](https://avatars.discourse-cdn.com/v4/letter/r/48db29/32.png) [@rwmsu](https://fortran-lang.discourse.group/u/rwmsu)\
**Post date:** [April 12, 2021, 10:16pm UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060/5 "2021-04-12T22:16:31Z")

</div>

@Beliavsky, completely agree about the use (and maybe misuse) of the term “modern Fortran”.  
I personally consider anything from F90 on as “modern”. My pet name for all of Fortran (sorry  
FORTRAN) before F90 is “Jurrasic Fortran” 🙂

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [April 13, 2021, 7:34am UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060/6 "2021-04-13T07:34:25Z")

</div>

When it comes to matrix operations, it is usually more efficient to use analytical matrix derivatives rather than attempt to differentiate the source code. The following reference is very useful in this regard: [http://people.maths.ox.ac.uk/~gilesm/files/NA-08-01.pdf](http://people.maths.ox.ac.uk/~gilesm/files/NA-08-01.pdf).  
With that said, the SVD derivatives look quite involved for the orthogonal factors and I have not used them before.

Since you are looking for forward-mode differentiation you may want to consider simply using the [complex step](http://www.johnlapeyre.com/posts/complex-step-differentiation/) method on something like [`zgesvd`](http://www.netlib.org/lapack/lapack-3.1.1/html/zgesvd.f.html). While requiring slightly more operations than a dual-number approach, it may end up being more efficient due to the built-in support for complex numbers in Fortran.

---

<div class="post-metadata">

**Author:** ![gardhor](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gardhor/32/88_2.png) [@gardhor](https://fortran-lang.discourse.group/u/gardhor)\
**Post date:** [April 13, 2021, 5:39pm UTC](https://fortran-lang.discourse.group/t/singular-value-decomposition-implementation/1060/7 "2021-04-13T17:39:58Z")

</div>

I think it will be tricky to modify a SVD subroutine to make it works with automatic differentiation.  
I did something similar to a diagonalisation procedure, it is not trivial. Furthermore, they are a way to use the results (eigenvalues, eigenvectors) of the matrix to get the eigenvalue and eigenvector derivatives.  
I’m not sure, it is possible to do it in a similar way for SVD, but probably, it is.
