# Finding eigenvalues with the smallest magnitude using eigs

**URL:** https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130
**Category:** New to Julia
**Tags:** question
**Created:** [April 6, 2022, 11:14pm UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130 "2022-04-06T23:14:08Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![ahmed](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@ahmed](https://discourse.julialang.org/u/ahmed)
#### Post date: [April 6, 2022, 11:14pm UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/1 "2022-04-06T23:14:08Z")

</div>

I have a large Hermitian sparse matrix, and I’d like to get a few of the eigenvalues with the smallest magnitude. I’m using the “eigs” function in Arpack however I get this error message:  
“ZeroPivotException: factorization encountered one or more zero pivots. Consider switching to a pivoted LU factorization.”  
Does anyone know how to get around this error? Is it possible to tell eigs to use pivoted LU factorization instead?

---

<div class="post-metadata">

### Author: ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)
#### Post date: [April 6, 2022, 11:46pm UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/2 "2022-04-06T23:46:20Z")

</div>

If you are getting zero pivots, then you know that the matrix is singular, and therefore the eigenvalue of smallest magnitude is `0`. Perhaps you could work around this with a `try`/`catch` block? (I am unfamiliar with Arpack.)

---

<div class="post-metadata">

### Author: ![ahmed](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@ahmed](https://discourse.julialang.org/u/ahmed)
#### Post date: [April 6, 2022, 11:54pm UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/3 "2022-04-06T23:54:06Z")

</div>

Thanks for your reply. It’s indeed true that the eigenvalue with the smallest magnitude is zero(Actually more than one). But why would that be a problem for the algorithm?  
I’m unfamiliar with try/except block. Could you explain what it does?

---

<div class="post-metadata">

### Author: ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)
#### Post date: [April 7, 2022, 12:04am UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/4 "2022-04-07T00:04:37Z")

</div>

See here in the docs: [Control Flow · The Julia Language](https://docs.julialang.org/en/v1/manual/control-flow/#The-try/catch-statement)

A `try`/`catch` block (I misspoke when I wrote `try`/`except` earlier, which is the Python equivalent) basically says, “_try_ doing this calculation, and if it produces an error `e`, do this other thing.” In your case, you would try the `eigs` function, and if it catches `ZeroPivotException`, return zero. Something like

```julia
function smallestmagnitudeeigenvalue(A)
    try
        return minimum(abs.(eigs(A)))
    catch e
        if isa(e, ZeroPivotException)
            return 0.0
        else
            throw(e)
        end
    end
end

```

---

<div class="post-metadata">

### Author: ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)
#### Post date: [April 7, 2022, 2:07am UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/5 "2022-04-07T02:07:49Z")

</div>

I would say use a shift to calculate nonzero eigenvalues. Then, when you undo the shift, you can decide whether or not you are interested in the eigenvalues which would be zero or close to zero. It is possible that your matrix may have one or more zero eigenvalue, depending on the application.

---

<div class="post-metadata">

### Author: ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)
#### Post date: [April 7, 2022, 3:10am UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/6 "2022-04-07T03:10:33Z")

</div>

To elaborate: the algorithm for smallest magnitude eigenvalues is a shift-and-invert scheme. The default is to use a shift of zero, but if there are actually zero eigenvalues (or close enough to zero) this fails, so one should pick some other small shift. (If you know that your matrix is semi-definite, you should probably use “smallest real” instead.)

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [April 7, 2022, 3:40am UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/7 "2022-04-07T03:40:09Z")

</div>

Similar question here:  
[https://github.com/JuliaLinearAlgebra/Arpack.jl/issues/135](https://github.com/JuliaLinearAlgebra/Arpack.jl/issues/135)

With

```julia
ham = sparse([1, 3, 4, 1, 6, 1, 6, 3, 4, 6], [1, 1, 1, 3, 3, 4, 4, 6, 6, 6], [5.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 5.0], 6, 6)

```

this errors

```julia
eigs(ham, nev=1, which=:SM)

```

but this works

```julia
eigs(ham, nev=1, which=:SR)

```

---

<div class="post-metadata">

### Author: ![Bruno\_Amorim](https://avatars.discourse-cdn.com/v4/letter/b/f6c823/32.png) [@Bruno\_Amorim](https://discourse.julialang.org/u/Bruno_Amorim)
#### Post date: [April 7, 2022, 2:15pm UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/8 "2022-04-07T14:15:23Z")

</div>

Maybe consider using instead [KrylovKit.jl](https://github.com/Jutho/KrylovKit.jl) or [ArnoldiMethod.jl](https://github.com/JuliaLinearAlgebra/ArnoldiMethod.jl). These packages don’t implement the shift-and-invert method, but it is easy to write a function that does so as detailed here: [Transformations · ArnoldiMethod.jl](https://julialinearalgebra.github.io/ArnoldiMethod.jl/stable/usage/02_spectral_transformations.html#Shift-and-invert-with-LinearMaps.jl-1). The good thing is that you can choose the factorization that is used to solve the linear systems.

---

<div class="post-metadata">

### Author: ![ahmed](https://avatars.discourse-cdn.com/v4/letter/a/8c91f0/32.png) [@ahmed](https://discourse.julialang.org/u/ahmed)
#### Post date: [April 7, 2022, 4:24pm UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/9 "2022-04-07T16:24:00Z")

</div>

Thanks!  
Smallest real doesn’t work because the matrix has negative eigenvalues which are different than the eigenvalues with the smallest magnitude (These are the eigenvalues I’m interested in)

---

<div class="post-metadata">

### Author: ![fgerick](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fgerick/32/13228_2.png) [@fgerick](https://discourse.julialang.org/u/fgerick)
#### Post date: [April 7, 2022, 5:05pm UTC](https://discourse.julialang.org/t/finding-eigenvalues-with-the-smallest-magnitude-using-eigs/79130/10 "2022-04-07T17:05:59Z")

</div>

A quick search on google lead me to [this post](https://scicomp.stackexchange.com/a/24346). It suggests this method:

```julia
using Arpack, SparseArrays

a=sprandn(100,100,0.01)+I; a[:,1].=0; dropzeros!(a);
maxev = eigs(a,nev=1, which=:LM)[1][1]
_minev,minevec = eigs(a-maxev*I,nev=1, which=:LM)
minev = _minev[1]+maxev

```

should give you a `minev` that is approximately zero.
