Skip to content
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

FiniteRankFreeModuleMorphism: Add method SVD (singular value decomposition) #31992

Open
mkoeppe opened this issue Jun 16, 2021 · 24 comments
Open

Comments

@mkoeppe
Copy link
Contributor

mkoeppe commented Jun 16, 2021

This operation is currently available for matrices over RDF.

The version for FiniteRankFreeModuleMorphism would define a new basis on each of the domain and codomain (with an orthogonal change of basis) so that the matrix of the morphism in the new bases is the diagonal of the singular values.

Example:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M') 
sage: N = FiniteRankFreeModule(ZZ, 2, name='N') 
sage: e = M.basis('e') ; f = N.basis('f') 
sage: H = Hom(M,N) ; H 
Set of Morphisms from Rank-3 free module M over the Integer Ring to Rank-2 free module N over the Integer Ring in Category of finite dimensional modules over Integer Ring
sage: phi = H([[2,-1,3], [1,0,-4]], name='phi', latex_name=r'\phi') ; phi 
Generic morphism:
  From: Rank-3 free module M over the Integer Ring
  To:   Rank-2 free module N over the Integer Ring
sage: phi.matrix(e, f)                                                   
[ 2 -1  3]
[ 1  0 -4]
sage: f_prime = N.basis('f_prime', from_family=(f[0]-f[1], -2*f[0]+3*f[1]
# pretend that this basis is the right orthogonal matrix of the SVD...
sage: phi.matrix(e, f_prime)                                             
[ 8 -3  1]
[ 3 -1 -1]

CC: @egourgoulhon @mjungmath @honglizhaobob

Component: linear algebra

Branch/Commit: u/gh-honglizhaobob/finiterankfreemodulemorphism__add_method_svd__singular_value_decomposition_ @ 38bcecc

Issue created by migration from https://trac.sagemath.org/ticket/31992

@mkoeppe mkoeppe added this to the sage-9.4 milestone Jun 16, 2021
@mkoeppe

This comment has been minimized.

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 5, 2021

comment:2

Replying to @mkoeppe:

Sorry for asking a naive question... In the description, what does RDF refer to ("this operation is currently available for matrices over RDF")?

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jul 5, 2021

comment:3

RDF is the "real double-precision field" - equivalent of double in C.
https://doc.sagemath.org/html/en/reference/rings_numerical/sage/rings/real_double.html

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 6, 2021

comment:4

Replying to @mkoeppe:

RDF is the "real double-precision field" - equivalent of double in C.
https://doc.sagemath.org/html/en/reference/rings_numerical/sage/rings/real_double.html

Thanks professor. Additionally, in implementing the SVD, should we resort to external libraries such as numpy, or is it a better practice to use sage methods whenever possible?

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 6, 2021

comment:5

If I'm understanding correctly after reading the code, we are still working with matrices (instead of high-dimensional tensors). Suppose A is the matrix obtained from M.hom(N, some_matrix, basis=(e, f)). Let x.parent() == M, y.parent() == N. Then we have:

y = A*x
y = U * S * V_dagger * x            # do SVD on A
(U_dagger * y) = S * (V_dagger * x) # invert U
y_prime = S*x_prime                 # renamed x and y

In code, we will reassign the default bases of M and N:

M._def_basis = V
N._def_basis = U                    # certainly, this reassignment needs more
                                    # work in terms of actual implementations

such that S would be the result of hom.matrix() in this new basis.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jul 6, 2021

comment:6

Replying to @honglizhaobob:

in implementing the SVD, should we resort to external libraries such as numpy, or is it a better practice to use sage methods whenever possible?

In Sage we support a wide range of rings for the arithmetic, and consequently often use multiple libraries for the implementation and also have an in-Sage generic implementation.

The existing implementation of SVD in src/sage/matrix/matrix_double_dense.pyx just calls scipy.linalg.svd.

It would be quite useful to add a generic implementation that only uses the general methods that Sage matrices offer. In that way, we could have access to arbitrary precision and symbolic computations.

It would also be good to check what other libraries that we already use or could easily use also provide implementations of SVD.

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 6, 2021

comment:7

Replying to @mkoeppe:

Replying to @honglizhaobob:

in implementing the SVD, should we resort to external libraries such as numpy, or is it a better practice to use sage methods whenever possible?

In Sage we support a wide range of rings for the arithmetic, and consequently often use multiple libraries for the implementation and also have an in-Sage generic implementation.

The existing implementation of SVD in src/sage/matrix/matrix_double_dense.pyx just calls scipy.linalg.svd.

It would be quite useful to add a generic implementation that only uses the general methods that Sage matrices offer. In that way, we could have access to arbitrary precision and symbolic computations.

It would also be good to check what other libraries that we already use or could easily use also provide implementations of SVD.

I think currently SVD() doesn't support other fields such as ZZ, or QQ. We may be restricted to RDF if we choose to use matrix_double_dense.pyx.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jul 6, 2021

comment:8

Yes, that's right -- and that's I think also exactly what scipy.linalg.svd provides. That's why I said that it will be good to check what other implementations are available in other software. A quick search for "arbitrary precision svd" did not lead me to good results though

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 6, 2021

comment:9

Replying to @mkoeppe:

Yes, that's right -- and that's I think also exactly what scipy.linalg.svd provides. That's why I said that it will be good to check what other implementations are available in other software. A quick search for "arbitrary precision svd" did not lead me to good results though

Could we consider symbolic SVD such as in MATLAB or sympy? This way we can preserve the QQ structure, however I feel svd on ZZ will be a bit demanding..

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jul 6, 2021

comment:10

Replying to @honglizhaobob:

Could we consider symbolic SVD such as in MATLAB or sympy? This way we can preserve the QQ structure

Do you have an example or link that illustrates what you have in mind?

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 7, 2021

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 7, 2021

comment:12

Replying to @mkoeppe:

Replying to @honglizhaobob:

Could we consider symbolic SVD such as in MATLAB or sympy? This way we can preserve the QQ structure

Do you have an example or link that illustrates what you have in mind?

In sympy, by Matrix.singular_value_decomposition() which would return symbolic results: https://docs.sympy.org/latest/modules/matrices/matrices.html

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 7, 2021

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 7, 2021

comment:13

Replying to @honglizhaobob:

Pushed a preliminary version which only deals with RDF, added a method diagonalize() in FiniteRankFreeModuleMorphism.

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 8, 2021

@mjungmath
Copy link

Commit: b141a4f

@mjungmath
Copy link

comment:15

Be careful what you push. You accidentally pushed your from the built generated files. The source code you want to modify is in src/sage/.

Can you please rebase the branch accordingly?

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jul 9, 2021

Branch pushed to git repo; I updated commit sha1. This was a forced push. New commits:

38bceccedited SVD

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Jul 9, 2021

Changed commit from b141a4f to 38bcecc

@honglizhaobob
Copy link
Mannequin

honglizhaobob mannequin commented Jul 9, 2021

comment:17

Replying to @mjungmath:

Be careful what you push. You accidentally pushed your from the built generated files. The source code you want to modify is in src/sage/.

Can you please rebase the branch accordingly?

Sorry, I have reset and pushed the code again.

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jul 9, 2021

comment:18

I've opened #32171 (Matrix: Add generic SVD method using sympy)

@mjungmath
Copy link

comment:19

Replying to @honglizhaobob:

Sorry, I have reset and pushed the code again.

Don't worry. Thanks for taking care of it. :)

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jul 10, 2021

comment:20

When ready for review, please set author name here on the ticket to your full name, and set to "needs_review".

@mkoeppe
Copy link
Contributor Author

mkoeppe commented Jul 10, 2021

comment:21

The EXAMPLES section should probably be extended so that one can see the effect of the function.

Some development tools that help with this:

  • ./sage -fixdoctests src/sage/tensor/modules/free_module_morphism.py will run the doctests and update the output
  • ./sage -docbuild reference/tensor_free_modules html will build the HMTL documentation - looking at it may reveal mistakes in the markup of the docstring

@mkoeppe mkoeppe modified the milestones: sage-9.4, sage-9.5 Jul 19, 2021
@mkoeppe mkoeppe modified the milestones: sage-9.5, sage-9.6 Dec 14, 2021
@mkoeppe mkoeppe modified the milestones: sage-9.6, sage-9.7 Mar 5, 2022
@mkoeppe mkoeppe modified the milestones: sage-9.7, sage-9.8 Aug 31, 2022
@mkoeppe mkoeppe modified the milestones: sage-9.8, sage-9.9 Jan 7, 2023
@mkoeppe mkoeppe removed this from the sage-10.0 milestone Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants