{ "cells": [ { "cell_type": "markdown", "id": "b0184a3a-d155-4ea7-82bb-d88b29ddee16", "metadata": {}, "source": [ "## The Original EigenDecompression.EigenDecompose\n", "\n", "See\n", "\n", "* https://mobile.twitter.com/realize_ss/status/1615160291108745216\n", "* https://qiita.com/lelele/items/8408410a94f5c6b8f76e" ] }, { "cell_type": "code", "execution_count": 1, "id": "9c72fb52-e0c2-4b6e-ada5-b0fba6982ae5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Eigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}}\n", "values:\n", "100-element Vector{ComplexF64}:\n", " -2.6713385149783693 - 0.5238483074100407im\n", " -2.6713385149783693 + 0.5238483074100407im\n", " -2.380694749857707 - 1.5819003151310398im\n", " -2.380694749857707 + 1.5819003151310398im\n", " -2.3445049148115737 - 0.8348768899082996im\n", " -2.3445049148115737 + 0.8348768899082996im\n", " -2.1226846073905064 - 0.22379425662578242im\n", " -2.1226846073905064 + 0.22379425662578242im\n", " -2.049294063421365 - 1.6320269189857641im\n", " -2.049294063421365 + 1.6320269189857641im\n", " -2.0178436003856652 + 0.0im\n", " -1.9229326770807857 - 1.7886924334849146im\n", " -1.9229326770807857 + 1.7886924334849146im\n", " ⋮\n", " 1.9543269536275725 + 0.5040016799489412im\n", " 1.9954076975615094 - 1.0426916311345158im\n", " 1.9954076975615094 + 1.0426916311345158im\n", " 2.0560135421866663 - 0.48888998497523045im\n", " 2.0560135421866663 + 0.48888998497523045im\n", " 2.416364338786246 + 0.0im\n", " 2.486887950907518 - 1.224341365689113im\n", " 2.486887950907518 + 1.224341365689113im\n", " 2.6754719890150778 - 0.39289719212777263im\n", " 2.6754719890150778 + 0.39289719212777263im\n", " 3.0130359977740344 + 0.0im\n", " 50.0991251975706 + 0.0im\n", "vectors:\n", "100×100 Matrix{ComplexF64}:\n", " 0.0928227+0.0727977im … 0.00480172+0.0im -0.0897557+0.0im\n", " -0.0220687+0.0949872im -0.0683635+0.0im -0.107816+0.0im\n", " -0.062205-0.0221392im 0.150972+0.0im -0.104096+0.0im\n", " -0.000929597-0.0558679im 0.21009+0.0im -0.105664+0.0im\n", " -0.0858376+0.0687551im 0.0157017+0.0im -0.0975072+0.0im\n", " 0.0620079-0.0456313im … 0.120079+0.0im -0.104935+0.0im\n", " 0.0910325-0.0859799im 0.0523112+0.0im -0.0967437+0.0im\n", " -0.0549273+0.0307295im 0.0888397+0.0im -0.106674+0.0im\n", " 0.142685+0.0105723im 0.0982881+0.0im -0.0831259+0.0im\n", " 0.0213531-0.0756764im -0.0218936+0.0im -0.0993371+0.0im\n", " -0.0338946-0.108939im … 0.0366303+0.0im -0.0905221+0.0im\n", " 0.0784134+0.105462im 0.0501874+0.0im -0.0885164+0.0im\n", " -0.0326154+0.101677im 0.0967074+0.0im -0.103145+0.0im\n", " ⋮ ⋱ \n", " 0.0293922-0.0230606im -0.0531536+0.0im -0.102552+0.0im\n", " 0.0929652+0.0773336im 0.073754+0.0im -0.0988448+0.0im\n", " 0.0585327-0.0135158im … 0.0340458+0.0im -0.100852+0.0im\n", " 0.0205471-0.0148881im -0.205876+0.0im -0.107353+0.0im\n", " 0.174649-0.0368603im -0.0668649+0.0im -0.108233+0.0im\n", " -0.0567686-0.0222343im 0.0213794+0.0im -0.100761+0.0im\n", " 0.10441-0.0925521im 0.0107639+0.0im -0.0950483+0.0im\n", " 0.0780944+0.102672im … -0.166945+0.0im -0.102682+0.0im\n", " -0.0634175-0.00904586im 0.0309103+0.0im -0.102103+0.0im\n", " -0.11412-0.0948267im 0.0745764+0.0im -0.0954268+0.0im\n", " 0.0400251+0.0790165im 0.0617443+0.0im -0.095069+0.0im\n", " 0.068089-0.00059643im -0.0551766+0.0im -0.0948394+0.0im" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using LinearAlgebra\n", "M = rand(100,100)#対角化したい行列\n", "E, P = eigen(M)" ] }, { "cell_type": "code", "execution_count": 2, "id": "f69a793a-abb9-4c47-ab07-912b4bd711de", "metadata": {}, "outputs": [ { "ename": "LoadError", "evalue": "MethodError: no method matching exp(::Eigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}})\n\n\u001b[0mClosest candidates are:\n\u001b[0m exp(\u001b[91m::Union{Float16, Float32, Float64}\u001b[39m)\n\u001b[0m\u001b[90m @\u001b[39m \u001b[90mBase\u001b[39m \u001b[90mspecial\\\u001b[39m\u001b[90m\u001b[4mexp.jl:325\u001b[24m\u001b[39m\n\u001b[0m exp(\u001b[91m::Adjoint{T, <:AbstractMatrix} where T\u001b[39m)\n\u001b[0m\u001b[90m @\u001b[39m \u001b[35mLinearAlgebra\u001b[39m \u001b[90mD:\\Julia-1.9.0-beta2\\share\\julia\\stdlib\\v1.9\\LinearAlgebra\\src\\\u001b[39m\u001b[90m\u001b[4mdense.jl:595\u001b[24m\u001b[39m\n\u001b[0m exp(\u001b[91m::Transpose{T, <:AbstractMatrix} where T\u001b[39m)\n\u001b[0m\u001b[90m @\u001b[39m \u001b[35mLinearAlgebra\u001b[39m \u001b[90mD:\\Julia-1.9.0-beta2\\share\\julia\\stdlib\\v1.9\\LinearAlgebra\\src\\\u001b[39m\u001b[90m\u001b[4mdense.jl:596\u001b[24m\u001b[39m\n\u001b[0m ...\n", "output_type": "error", "traceback": [ "MethodError: no method matching exp(::Eigen{ComplexF64, ComplexF64, Matrix{ComplexF64}, Vector{ComplexF64}})\n\n\u001b[0mClosest candidates are:\n\u001b[0m exp(\u001b[91m::Union{Float16, Float32, Float64}\u001b[39m)\n\u001b[0m\u001b[90m @\u001b[39m \u001b[90mBase\u001b[39m \u001b[90mspecial\\\u001b[39m\u001b[90m\u001b[4mexp.jl:325\u001b[24m\u001b[39m\n\u001b[0m exp(\u001b[91m::Adjoint{T, <:AbstractMatrix} where T\u001b[39m)\n\u001b[0m\u001b[90m @\u001b[39m \u001b[35mLinearAlgebra\u001b[39m \u001b[90mD:\\Julia-1.9.0-beta2\\share\\julia\\stdlib\\v1.9\\LinearAlgebra\\src\\\u001b[39m\u001b[90m\u001b[4mdense.jl:595\u001b[24m\u001b[39m\n\u001b[0m exp(\u001b[91m::Transpose{T, <:AbstractMatrix} where T\u001b[39m)\n\u001b[0m\u001b[90m @\u001b[39m \u001b[35mLinearAlgebra\u001b[39m \u001b[90mD:\\Julia-1.9.0-beta2\\share\\julia\\stdlib\\v1.9\\LinearAlgebra\\src\\\u001b[39m\u001b[90m\u001b[4mdense.jl:596\u001b[24m\u001b[39m\n\u001b[0m ...\n", "", "Stacktrace:", " [1] top-level scope", " @ In[2]:1" ] } ], "source": [ "exp(eigen(M))" ] }, { "cell_type": "code", "execution_count": 3, "id": "0ceab85b-f2a5-43b9-a45a-19bebb655d60", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Main.EigenDecompression" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "module EigenDecompression\n", "\n", "export EigenDecompose, eigDecomp\n", "using LinearAlgebra\n", "import Base.*, Base./\n", "\n", "#対角化された行列型\n", "struct EigenDecompose{T<:Number} <: AbstractMatrix{T}\n", " P::AbstractMatrix{T}\n", " D::Diagonal{T}\n", " invP::AbstractMatrix{T}\n", "end\n", "\n", "#普通のMatrixを対角化する\n", "function eigDecomp(mat::AbstractMatrix)\n", " E, P = eigen(mat)\n", " EigenDecompose(P, Diagonal(E), inv(P))\n", "end\n", "\n", "#EigenDecompose型に対する関数\n", "Base.exp(eig::EigenDecompose) = EigenDecompose(eig.P, exp(eig.D), eig.invP)\n", "*(eig::EigenDecompose, vec::AbstractVector) = eig.P * eig.D * eig.invP * vec\n", "*(eig::EigenDecompose, sc::Number) = EigenDecompose(eig.P, eig.D*sc, eig.invP)\n", "/(eig::EigenDecompose, sc::Number) = EigenDecompose(eig.P, eig.D/sc, eig.invP)\n", "\n", "#普通のMatrixに戻す\n", "Base.Array(eig::EigenDecompose) = eig.P * eig.D * eig.invP\n", "\n", "end" ] }, { "cell_type": "code", "execution_count": 4, "id": "a6f2726f-780f-4cbc-a980-e13b78f159a6", "metadata": {}, "outputs": [], "source": [ "using .EigenDecompression\n", "\n", "M = rand(100, 100)\n", "eM = eigDecomp(M)\n", "for i in 1:100\n", " v = rand(100)\n", " rnd = rand()\n", " @assert exp(M*rnd)*v ≈ exp(eM*rnd)*v\n", "end" ] }, { "cell_type": "code", "execution_count": 5, "id": "b3566c65-ea4a-48b2-9736-00e7904ebe3b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bench2 (generic function with 1 method)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "using BenchmarkTools\n", "\n", "M = rand(100, 100);\n", "\n", "#普通な方\n", "function bench1(M)\n", " for i in 1:100\n", " v = rand(100)\n", " exp(M*rand())*v\n", " end\n", "end\n", "\n", "#今回実装した方\n", "function bench2(M)\n", " eM = eigDecomp(M)\n", " for i in 1:100\n", " v = rand(100)\n", " exp(eM*rand())*v\n", " end\n", "end" ] }, { "cell_type": "code", "execution_count": 6, "id": "7ce7e7d9-dc0b-4384-8296-a0c0c884deae", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BenchmarkTools.Trial: 58 samples with 1 evaluation.\n", " Range \u001b[90m(\u001b[39m\u001b[36m\u001b[1mmin\u001b[22m\u001b[39m … \u001b[35mmax\u001b[39m\u001b[90m): \u001b[39m\u001b[36m\u001b[1m78.395 ms\u001b[22m\u001b[39m … \u001b[35m100.653 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m2.43% … 3.65%\n", " Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m86.035 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m2.82%\n", " Time \u001b[90m(\u001b[39m\u001b[32m\u001b[1mmean\u001b[22m\u001b[39m ± \u001b[32mσ\u001b[39m\u001b[90m): \u001b[39m\u001b[32m\u001b[1m87.298 ms\u001b[22m\u001b[39m ± \u001b[32m 4.854 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m3.62% ± 1.60%\n", "\n", " \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m▂\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m█\u001b[39m \u001b[39m \u001b[39m \u001b[34m \u001b[39m\u001b[39m \u001b[39m \u001b[39m \u001b[32m \u001b[39m\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \n", " \u001b[39m▄\u001b[39m▄\u001b[39m▁\u001b[39m▁\u001b[39m▄\u001b[39m▄\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m█\u001b[39m▁\u001b[39m▁\u001b[39m█\u001b[39m▄\u001b[39m▆\u001b[39m▁\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m▄\u001b[34m▆\u001b[39m\u001b[39m▄\u001b[39m▄\u001b[39m▁\u001b[32m█\u001b[39m\u001b[39m█\u001b[39m▁\u001b[39m▄\u001b[39m▄\u001b[39m▆\u001b[39m▄\u001b[39m▁\u001b[39m▄\u001b[39m▁\u001b[39m▁\u001b[39m▆\u001b[39m▁\u001b[39m▄\u001b[39m▄\u001b[39m▆\u001b[39m▁\u001b[39m▁\u001b[39m▄\u001b[39m▆\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▄\u001b[39m▆\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▄\u001b[39m \u001b[39m▁\n", " 78.4 ms\u001b[90m Histogram: frequency by time\u001b[39m 98.7 ms \u001b[0m\u001b[1m<\u001b[22m\n", "\n", " Memory estimate\u001b[90m: \u001b[39m\u001b[33m53.80 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m1900\u001b[39m." ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@benchmark bench1(M)" ] }, { "cell_type": "code", "execution_count": 7, "id": "8441c537-41ff-425b-a83b-bc7c455a1ff4", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "BenchmarkTools.Trial: 690 samples with 1 evaluation.\n", " Range \u001b[90m(\u001b[39m\u001b[36m\u001b[1mmin\u001b[22m\u001b[39m … \u001b[35mmax\u001b[39m\u001b[90m): \u001b[39m\u001b[36m\u001b[1m6.103 ms\u001b[22m\u001b[39m … \u001b[35m15.411 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmin … max\u001b[90m): \u001b[39m0.00% … 0.00%\n", " Time \u001b[90m(\u001b[39m\u001b[34m\u001b[1mmedian\u001b[22m\u001b[39m\u001b[90m): \u001b[39m\u001b[34m\u001b[1m6.824 ms \u001b[22m\u001b[39m\u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmedian\u001b[90m): \u001b[39m0.00%\n", " Time \u001b[90m(\u001b[39m\u001b[32m\u001b[1mmean\u001b[22m\u001b[39m ± \u001b[32mσ\u001b[39m\u001b[90m): \u001b[39m\u001b[32m\u001b[1m7.234 ms\u001b[22m\u001b[39m ± \u001b[32m 1.191 ms\u001b[39m \u001b[90m┊\u001b[39m GC \u001b[90m(\u001b[39mmean ± σ\u001b[90m): \u001b[39m0.48% ± 2.20%\n", "\n", " \u001b[39m \u001b[39m \u001b[39m \u001b[39m█\u001b[39m▅\u001b[39m▂\u001b[39m▁\u001b[34m \u001b[39m\u001b[39m \u001b[39m \u001b[39m \u001b[32m \u001b[39m\u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \u001b[39m \n", " \u001b[39m▃\u001b[39m▅\u001b[39m▇\u001b[39m█\u001b[39m█\u001b[39m█\u001b[39m█\u001b[34m▇\u001b[39m\u001b[39m█\u001b[39m▇\u001b[39m▆\u001b[32m▇\u001b[39m\u001b[39m▄\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▃\u001b[39m▂\u001b[39m▃\u001b[39m▂\u001b[39m▃\u001b[39m▂\u001b[39m▃\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▃\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▂\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▁\u001b[39m▂\u001b[39m \u001b[39m▃\n", " 6.1 ms\u001b[90m Histogram: frequency by time\u001b[39m 12.3 ms \u001b[0m\u001b[1m<\u001b[22m\n", "\n", " Memory estimate\u001b[90m: \u001b[39m\u001b[33m1.82 MiB\u001b[39m, allocs estimate\u001b[90m: \u001b[39m\u001b[33m1728\u001b[39m." ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "@benchmark bench2(M)" ] }, { "cell_type": "markdown", "id": "a9ecc6b7-4601-40b9-937f-05854d56f58b", "metadata": {}, "source": [ "## EigenDecomposedMatrices.EigenDecomposed" ] }, { "cell_type": "code", "execution_count": 8, "id": "57691738-e725-481e-ba43-9d7fea5b8c60", "metadata": {}, "outputs": [], "source": [ "using LinearAlgebra\n", "using BenchmarkTools" ] }, { "cell_type": "code", "execution_count": 9, "id": "a3672e5b-5030-4952-b50a-da95ef2eb11e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Main.EigenDecomposedMatrices" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "module EigenDecomposedMatrices\n", "\n", "export EigenDecomposed\n", "\n", "using LinearAlgebra\n", "using Memoization\n", "\n", "struct EigenDecomposed{\n", " T,\n", " TE<:AbstractVector{T},\n", " TP<:AbstractMatrix{T},\n", " TinvP<:AbstractMatrix{T}\n", " } <: AbstractMatrix{T}\n", " E::TE\n", " P::TP\n", " invP::TinvP\n", "end\n", "\n", "function EigenDecomposed(A::AbstractMatrix)\n", " E, P = eigen(A)\n", " invP = ishermitian(A) ? P' : inv(P)\n", " EigenDecomposed(E, P, invP)\n", "end\n", "\n", "LinearAlgebra.eigvals(ed::EigenDecomposed) = ed.E\n", "LinearAlgebra.eigvecs(ed::EigenDecomposed) = ed.P\n", "inveigvecs(ed::EigenDecomposed) = ed.invP\n", "@memoize Base.parent(ed::EigenDecomposed) = eigvecs(ed) * Diagonal(eigvals(ed)) * inveigvecs(ed)\n", "Base.convert(::Type{Array}, ed::EigenDecomposed) = convert(Array, parent(ed))\n", "for op in (:eltype, :size)\n", " @eval Base.$op(ed::EigenDecomposed) = $op(eigvecs(ed))\n", "end\n", "Base.getindex(ed::EigenDecomposed, I...) = getindex(parent(ed), I...)\n", "\n", "Base.:*(c::Number, ed::EigenDecomposed) = EigenDecomposed(c*eigvals(ed), eigvecs(ed), inveigvecs(ed))\n", "Base.:*(ed::EigenDecomposed, c::Number) = EigenDecomposed(eigvals(ed)*c, eigvecs(ed), inveigvecs(ed))\n", "Base.:\\(c::Number, ed::EigenDecomposed) = EigenDecomposed(c\\eigvals(ed), eigvecs(ed), inveigvecs(ed))\n", "Base.:/(ed::EigenDecomposed, c::Number) = EigenDecomposed(eigvals(ed)/c, eigvecs(ed), inveigvecs(ed))\n", "for T in (AbstractVector, AbstractMatrix)\n", " @eval function Base.:*(ed::EigenDecomposed, v::$T)\n", " E, P, invP = eigvals(ed), eigvecs(ed), inveigvecs(ed)\n", " P * (Diagonal(E) * (invP * v))\n", " end\n", "end\n", "\n", "function exp_old(ed::EigenDecomposed)\n", " E, P, invP = eigvals(ed), eigvecs(ed), inveigvecs(ed)\n", " expE = exp.(E)\n", " expA = P * Diagonal(expE) * invP \n", " EigenDecomposed(expE, P, invP)\n", "end\n", "\n", "LinearAlgebra.lmul!(c::Number, ed::EigenDecomposed) = lmul!(c, eigvals(ed))\n", "LinearAlgebra.rmul!(ed::EigenDecomposed, c::Number) = rmul!(eigvals(ed), c)\n", "LinearAlgebra.ldiv!(c::Number, ed::EigenDecomposed) = ldiv!(c, eigvals(ed))\n", "LinearAlgebra.rdiv!(ed::EigenDecomposed, c::Number) = rdiv!(eigvals(ed), c)\n", "\n", "for op in (:exp, :log, :sin, :cos)\n", " opE = Symbol(op, \"E\")\n", " op_eigendecomposed = Symbol(op, \"_eigendecomposed\")\n", " op_eigendecomposed! = Symbol(op_eigendecomposed, \"!\")\n", " op_eigendecomposed!_doc =\n", " \"\"\"\n", " $op_eigendecomposed!(Y, ed::EigenDecomposed, $opE=similar(ed.E), tmpY=similar(Y))\n", "\n", " returns the `$op` of `ed` and stores the result in `Y`, overwriting the existing value of `Y`. \n", " It does not overwrite `ed` and uses `$opE` and `tmpY` as workspaces.\n", " \"\"\"\n", " @eval begin\n", " @doc $op_eigendecomposed!_doc\n", " function $op_eigendecomposed!(Y, ed::EigenDecomposed, $opE=similar(ed.E), tmpY=similar(Y))\n", " E, P, invP = eigvals(ed), eigvecs(ed), inveigvecs(ed)\n", " @. $opE = $op.(E)\n", " mul!(tmpY, P, Diagonal($opE))\n", " mul!(Y, tmpY, invP)\n", " end\n", " $op_eigendecomposed(ed::EigenDecomposed) = $op_eigendecomposed!(similar(eigvecs(ed)), ed)\n", " Base.$op(ed::EigenDecomposed) = $op_eigendecomposed(ed)\n", " end\n", "end\n", "\n", "end" ] }, { "cell_type": "code", "execution_count": 10, "id": "f4402c98-850b-44e0-9407-6088e6421f19", "metadata": {}, "outputs": [ { "data": { "text/latex": [ "exp\\_eigendecomposed!(Y, ed::EigenDecomposed, expE=similar(ed.E), tmpY=similar(Y))\n", "\n", "returns the \\texttt{exp} of \\texttt{ed} and stores the result in \\texttt{Y}, overwriting the existing value of \\texttt{Y}. It does not overwrite \\texttt{ed} and uses \\texttt{expE} and \\texttt{tmpY} as workspaces.\n", "\n" ], "text/markdown": [ "exp_eigendecomposed!(Y, ed::EigenDecomposed, expE=similar(ed.E), tmpY=similar(Y))\n", "\n", "returns the `exp` of `ed` and stores the result in `Y`, overwriting the existing value of `Y`. It does not overwrite `ed` and uses `expE` and `tmpY` as workspaces.\n" ], "text/plain": [ " exp_eigendecomposed!(Y, ed::EigenDecomposed, expE=similar(ed.E),\n", " tmpY=similar(Y))\n", "\n", " returns the \u001b[36mexp\u001b[39m of \u001b[36med\u001b[39m and stores the result in \u001b[36mY\u001b[39m, overwriting the existing\n", " value of \u001b[36mY\u001b[39m. It does not overwrite \u001b[36med\u001b[39m and uses \u001b[36mexpE\u001b[39m and \u001b[36mtmpY\u001b[39m as workspaces." ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "?EigenDecomposedMatrices.exp_eigendecomposed!" ] }, { "cell_type": "code", "execution_count": 11, "id": "beb73095-1445-4318-b010-1f4c495edec6", "metadata": {}, "outputs": [ { "data": { "text/latex": [ "log\\_eigendecomposed!(Y, ed::EigenDecomposed, logE=similar(ed.E), tmpY=similar(Y))\n", "\n", "returns the \\texttt{log} of \\texttt{ed} and stores the result in \\texttt{Y}, overwriting the existing value of \\texttt{Y}. It does not overwrite \\texttt{ed} and uses \\texttt{logE} and \\texttt{tmpY} as workspaces.\n", "\n" ], "text/markdown": [ "log_eigendecomposed!(Y, ed::EigenDecomposed, logE=similar(ed.E), tmpY=similar(Y))\n", "\n", "returns the `log` of `ed` and stores the result in `Y`, overwriting the existing value of `Y`. It does not overwrite `ed` and uses `logE` and `tmpY` as workspaces.\n" ], "text/plain": [ " log_eigendecomposed!(Y, ed::EigenDecomposed, logE=similar(ed.E),\n", " tmpY=similar(Y))\n", "\n", " returns the \u001b[36mlog\u001b[39m of \u001b[36med\u001b[39m and stores the result in \u001b[36mY\u001b[39m, overwriting the existing\n", " value of \u001b[36mY\u001b[39m. It does not overwrite \u001b[36med\u001b[39m and uses \u001b[36mlogE\u001b[39m and \u001b[36mtmpY\u001b[39m as workspaces." ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "?EigenDecomposedMatrices.log_eigendecomposed!" ] }, { "cell_type": "code", "execution_count": 12, "id": "312bddb6-0a2d-4caf-8b60-d421be7143f3", "metadata": {}, "outputs": [ { "data": { "text/html": [ "# 2 methods for type constructor: