{"id":20500557,"url":"https://github.com/juliaapproximation/spectralmeasures.jl","last_synced_at":"2025-03-05T19:33:49.380Z","repository":{"id":32010349,"uuid":"35581413","full_name":"JuliaApproximation/SpectralMeasures.jl","owner":"JuliaApproximation","description":"Julia package for finding the spectral measure of structured self adjoint operators","archived":false,"fork":false,"pushed_at":"2024-04-07T09:54:49.000Z","size":598,"stargazers_count":23,"open_issues_count":9,"forks_count":3,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-01-16T06:58:29.030Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JuliaApproximation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-05-14T00:28:55.000Z","updated_at":"2024-09-12T16:51:11.000Z","dependencies_parsed_at":"2024-11-13T09:16:50.127Z","dependency_job_id":null,"html_url":"https://github.com/JuliaApproximation/SpectralMeasures.jl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaApproximation%2FSpectralMeasures.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaApproximation%2FSpectralMeasures.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaApproximation%2FSpectralMeasures.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaApproximation%2FSpectralMeasures.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JuliaApproximation","download_url":"https://codeload.github.com/JuliaApproximation/SpectralMeasures.jl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242092232,"owners_count":20070484,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-15T18:21:30.048Z","updated_at":"2025-03-05T19:33:49.345Z","avatar_url":"https://github.com/JuliaApproximation.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SpectralMeasures.jl\n\nSpectralMeasures.jl is a Julia package for computing spectra and spectral measures of self-adjoint operators with structured, infinite-dimensional matrix representations. The package enables a canonical eigendecomposition for these operators, and a functional calculus too. A key point to make is that all of this is done in tailor-made data structures representing structured infinite-dimensional operators, with no error-inducing, finite-dimensional truncations.\n\n## Overview\n\nSyntactically, the familiar function for matrices, `eig`, will be implemented for as many operators as we can. It returns a multiplication operator, `D`, which acts on `Fun`s whose domain is the spectrum of the operator, and \"spectral map\", `U`, which takes vectors to `Fun`s in the same `Space` as the that associated with `D`. In Julia code, this means that if you have an operator `A`, and type\n\n```\nD,U = eigen(A)\n```\n\nthen the following identity holds (to machine precision):\n\n```\nA = U \\ D * U\n```\n\nThis is analogous to what happens in finite dimensional linear algebra, where `D` is a diagonal matrix and `U` is the matrix of eigenvectors (transposed). You can also try `eigvals(A)` or `spectrum(A)` to return the spectrum of `A` as an ApproxFun `Domain` type.\n\n\nThe operators `D` and `U` enable a functional calculus. The following is the application of the operator `exp(1.3*A)` to a random vector.\n```\nv = randn(100)\nexpAtv = U \\ exp(1.3*D) *  U * v\n```\n\nAlso, specific to infinite-dimensional operators, there is a function called `spectralmeasure`. This function produces either a `Fun` or a `RatFun` (a quotient of two `Fun`s), representing a measure supported on the spectrum of the operator --- specifically, a representation of the spectral measure from the Spectral Theorem for selfadjoint operators. At a discrete eigenvalue of the operator, the spectral measure has a Dirac delta.\n\nThe implementation of the package is based on a combination of connection coefficient matrices between orthogonal polynomials (See Webb-Olver 2018, \"Spectra of Jacobi operators via connection coefficients matrices\") and infinite dimensional QL iterations (See Olver-Webb 2018, \"The infinite dimensional QL algorithm\"  (in prep.)).\n\n## Tridiagonal operators\n\n### PertToeplitz\n\nThe type `SymTriPertToeplitz` implements an operator whose matrix is symmetric, tridiagonal, which is a finite-rank perturbation of a Toeplitz operator. The following is an example construction.\n```\nusing SpectralMeasures\nA = SymTriPertToeplitz([0.1;-0.1;1.2],[1.4;1.2],0.,0.5)\n```\nThe data structure represents the infinite matrix,\n```\nA = [ 0.1  1.4        \n      1.4 -0.1  1.2\n           1.2  1.2  0.5\n                0.5  0.0  0.5\n                     0.5  0.0  ⋱\n                           ⋱  ⋱ ]\n```\nSimple commands like `A*randn(100)` and `A[2017,2018]` work as you would expect.\n\n#### Eigendecomposition and functional calculus\n\nThe spectrum of `A` can be computed using the `eigvals` function. `spectrum` can also be used.\n\n```\neigvals(A)\n```\nreturns a `Domain` type,\n```\nPoint(-1.7082248431502554) ∪ Point(2.2839756035160352) ∪ 【-1.0,1.0】\n```\nThe spectrum of this particular operator consists of two discrete eigenvalues and continuous spectrum on the interval [-1,1].\n\nYou can use familiar syntax to compute an eigendecomposition:\n\n```\nD,U = eigen(A)\n```\n\nThe first output, `D`, is a multiplication operator, which multiplies `Fun`s with space `PointSpace([-1.70822…,2.28398…]) ∪ Ultraspherical(1)`. It has matrix representation,\n```\nD = [ -1.70822  0.0      0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ⋯\n       0.0      2.28398  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  ⋱\n       0.0      0.0      0.0  0.5  0.0  0.0  0.0  0.0  0.0  0.0  ⋱\n       0.0      0.0      0.5  0.0  0.5  0.0  0.0  0.0  0.0  0.0  ⋱\n       0.0      0.0      0.0  0.5  0.0  0.5  0.0  0.0  0.0  0.0  ⋱\n       0.0      0.0      0.0  0.0  0.5  0.0  0.5  0.0  0.0  0.0  ⋱\n       0.0      0.0      0.0  0.0  0.0  0.5  0.0  0.5  0.0  0.0  ⋱\n       0.0      0.0      0.0  0.0  0.0  0.0  0.5  0.0  0.5  0.0  ⋱\n       0.0      0.0      0.0  0.0  0.0  0.0  0.0  0.5  0.0  0.5  ⋱\n       0.0      0.0      0.0  0.0  0.0  0.0  0.0  0.0  0.5  0.0  ⋱\n        ⋮        ⋱        ⋱    ⋱   ⋱   ⋱    ⋱   ⋱   ⋱    ⋱  ⋱ ]\n```\n The second output, `U` is a an operator which maps vectors to `Fun`s in that space. It has matrix representation,\n\n```\nU = [ -0.575073   0.742758   -0.324516    0.104914   -0.0339182   0.0109656   -0.00354511   0.00114611   -0.000370532   0.000119791  ⋱\n       0.368164   0.57433     0.711466    0.164031    0.0378177   0.00871899   0.00201019   0.000463455   0.000106851   2.46348e-5   ⋱\n      -1.07598    0.160981    1.1016     -3.23631     1.29719     0.217432    -0.0841252    9.59302e-16   4.7358e-16    2.61726e-16  ⋱\n       0.235551  -0.401105   -0.206107    2.39879    -3.01888     1.21307      0.217432    -0.0841252     1.21084e-15   5.3256e-16   ⋱\n                  0.0841252  -0.160117    0.0113248   2.31467    -3.01888      1.21307      0.217432     -0.0841252     1.23512e-15  ⋱\n                              0.0350522  -0.244242    0.0113248   2.31467     -3.01888      1.21307       0.217432     -0.0841252    ⋱\n                                          0.0350522  -0.244242    0.0113248    2.31467     -3.01888       1.21307       0.217432     ⋱\n                                                      0.0350522  -0.244242     0.0113248    2.31467      -3.01888       1.21307      ⋱\n                                                                  0.0350522   -0.244242     0.0113248     2.31467      -3.01888      ⋱\n                                                                               0.0350522   -0.244242      0.0113248     2.31467      ⋱\n                                                                                             ⋱             ⋱            ⋱          ⋱ ]\n```\n\n The operator `A - U \\ D * U` has entries which are approximately zero to machine precision.\n\nFunctions of `A` applied to a vector can be computed as follows.\n\n```\nf = x -\u003e exp(1.4im*x)\nv = randn(100)\nfAv = U \\ f(D) * U * v\n```\nThe key point to note is that no finite-dimensional truncation has occurred; the entire structured operators have been used at each stage of the computation.\n\n#### Spectral measure and resolvent\n\nWe can compute the spectral measure of `A`:\n```\nμ = spectralmeasure(A)\n```\nμ is a RationalFun from the RatFun package, and has Dirac deltas at the discrete eigenvalues of A. Let us plot this.\n```\nusing Plots\nplot(μ)\n```\n\u003cimg src=images/spectralmeasure.png width=400px\u003e\n\nWe can also plot the resolvent of the operator (which is the Cauchy transform of the spectral measure):\n```\nr = principalresolvent(A)\nusing ComplexPhasePortrait\nZ = linspace(-3, 3, 600)' .+ linspace(3,-3,600)*im\nplot(portrait(r(Z),PTstepmod); xlims=(-3,3), ylims=(-3,3), aspect_ratio=1)\n```\n\u003cimg src=images/principalresolvent.png width=400px\u003e\n\nThis plot is a Wegert plot, a.k.a. a complex phase portrait. See \u003ca href=https://github.com/JuliaHolomorphic/ComplexPhasePortrait.jl\u003ehere\u003c/a\u003e for an explanation.\n\n#### QL iterations\n\nWe can compute a QL decomposition in the expected way. However, note that QL decompositions do not exist if the continuous spectrum contains zero (see Olver-Webb 2018, \"The infinite dimensional QL algorithm\"). Therefore, we must use a shift.\n```\nQ,L = ql(A+1.7082248431502554)\n```\n\nThe operators `Q` and `L` are stored in their entirety as structured operators of type `HessenbergUnitary` and `PertToeplitz`, respectively.\n```\nQ = [ -0.575073      0.818102\n       0.742758      0.52211       0.41918\n      -0.324516     -0.228114      0.859147      0.323294\n       0.104914      0.0737479    -0.277758      0.895481     0.323294\n      -0.0339182    -0.0238423     0.0897975    -0.289504     0.895481     0.323294\n       0.0109656     0.00770808   -0.029031      0.093595    -0.289504     0.895481     0.323294\n      -0.00354511   -0.00249198    0.00938557   -0.0302588    0.093595    -0.289504     0.895481    0.323294\n       0.00114611    0.000805644  -0.0030343     0.00978249  -0.0302588    0.093595    -0.289504    0.895481   0.323294\n      -0.000370532  -0.00026046    0.000980974  -0.00316262   0.00978249  -0.0302588    0.093595   -0.289504   0.895481  0.323294\n       0.000119791   8.42053e-5   -0.000317143   0.00102246  -0.00316262   0.00978249  -0.0302588   0.093595  -0.289504  0.895481  ⋱\n        ⋱             ⋱            ⋱             ⋱           ⋱            ⋱           ⋱           ⋱         ⋱       ⋱        ⋱ ]\n\nL = [ 2.22045e-16\n      2.21027      1.71128\n      0.586852     1.70511   2.86273\n                   0.387953  1.38795   1.54658\n                             0.161647  1.0       1.54658\n                                       0.161647  1.0       1.54658\n                                                 0.161647  1.0       1.54658\n                                                           0.161647  1.0       1.54658\n                                                                     0.161647  1.0       1.54658\n                                                                               0.161647  1.0      1.54658\n                                                                                          ⋱        ⋱       ⋱ ]\n```\n\nA QL iteration can be performed by forming the operator,\n```\nA2 = L*Q - 1.7082248431502554I\n```\n```\nA2 = [ -1.70822      1.81655e-16\n        1.81655e-16  0.993475     0.717334\n                     0.717334     1.46603   0.925505\n                                  0.925505  0.125423   0.5\n                                            0.5       -2.22045e-16   0.5\n                                                       0.5          -2.22045e-16   0.5\n                                                                     0.5          -2.22045e-16   0.5\n                                                                                   0.5          -2.22045e-16   0.5\n                                                                                                 0.5          -2.22045e-16   0.5\n                                                                                                               0.5          -2.22045e-16  ⋱\n                                                                                                                              ⋱           ⋱ ]\n```\nSince the shift was approximately an eigenvalue of `A`, the (1,2) entry of the QL iterate becomes approximately zero. Repeated iteration will yield convergence just like in the finite dimensional case (see Olver-Webb 2018, \"The infinite dimensional QL algorithm\" (in prep.))\n\n## Future operators\nTridiagonal bi-infinite PertToeplitz, Tridiagonal PertPeriodic. General banded operators. Work on all of these is currently in progress. Work on continuous Schrödinger operators and nonsymmetric operators is something which may be done in the distant future.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliaapproximation%2Fspectralmeasures.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuliaapproximation%2Fspectralmeasures.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliaapproximation%2Fspectralmeasures.jl/lists"}