# arpack-rs
[](https://crates.io/crates/arpack)
[](https://docs.rs/arpack)
Rust bindings for [ARPACK-NG](https://github.com/opencollab/arpack-ng), a Fortran library for solving large-scale sparse eigenvalue problems via the Implicitly Restarted Arnoldi/Lanczos methods.
This workspace publishes two crates:
| Crate | Role |
|--------------|---------------------------------------------------------------------|
| `arpack-sys` | Raw FFI bindings to the C-callable wrappers (`{s,d,c,z}{na,ne,sa,se}upd_c`) introduced in ARPACK-NG 3.8.0. |
| `arpack` | Safe Rust wrapper around `arpack-sys`. |
## Status
Early scaffolding. `arpack-sys` exposes the full eigenvalue-driver surface; the safe wrapper in `arpack` is in progress.
## Supported targets
Only **64-bit-pointer-width** targets are supported. 32-bit targets fail to compile via `compile_error!` because the wrapper does not bound workspace-size arithmetic against the smaller `usize` / `isize::MAX` envelope, and 32-bit ARPACK use cases are out of scope. Open an issue if you need 32-bit support.
## Linking model
`arpack-sys` links to a system-installed ARPACK-NG (>= 3.8.0) located via `pkg-config`. There is no vendored Fortran build — install ARPACK-NG through your platform package manager:
```bash
# macOS
brew install arpack
# Debian / Ubuntu
sudo apt install libarpack2-dev pkg-config
# Fedora
sudo dnf install arpack-devel pkgconf-pkg-config
```
`pkg-config --modversion arpack` must succeed before `cargo build`.
The `arpack-sys/src/bindings.rs` file is generated by `bindgen` and committed, so downstream users do not need `bindgen` or `clang` at build time. To regenerate the bindings against a newer ARPACK-NG header, run:
```bash
./regen-bindings.sh
```
## Usage
```bash
cargo add arpack
```
Smallest eigenvalue of `diag(1, 2, 3)` via the safe wrapper:
```rust
use arpack::{Options, smallest_eigenpair_f64};
let diag = [1.0_f64, 2.0, 3.0];
let n = diag.len();
let solution = smallest_eigenpair_f64(
n,
|x, y| {
for i in 0..n {
y[i] = diag[i] * x[i];
}
},
&Options::default(),
)
.expect("ARPACK converged");
assert!((solution.eigenvalue - 1.0).abs() < 1e-9);
```
(Direct `arpack-sys` usage is also supported for callers that want to drive ARPACK manually.)
## Driver surface
Each driver family exposes two layers:
- `eigenpairs_f64` / `eigenpairs_f32` (`arpack::`, re-exported at the crate root) and `eigenpairs_c64` / `eigenpairs_c32` (`arpack::arnoldi::`) — general entry point accepting `nev >= 1` and a `Which` selector (`SmallestAlgebraic` / `LargestAlgebraic` / `SmallestRealPart` / `LargestRealPart` / `SmallestImagPart` / `LargestImagPart` / `SmallestMagnitude` / `LargestMagnitude`, restricted per driver family). Returns a `MultiEigSolution` holding up to `nev` converged eigenpairs (the raw ARPACK count is preserved in `nconv` for diagnostics; the eigenpair arrays themselves have length `min(nconv, nev)`).
- `smallest_eigenpair_f64` / `_f32` (`arpack::`) and `smallest_eigenpair_c64` / `_c32` (`arpack::arnoldi::`) — convenience wrappers fixed to `nev = 1` and the family's "smallest" mode. Returns a singular `EigSolution`.
The real non-symmetric `{s,d}{na,ne}upd_c` family is not wrapped yet.
## License
- Rust bindings (this workspace): `MIT OR Apache-2.0`
- ARPACK-NG: `BSD-3-Clause` ([upstream `COPYING`](https://github.com/opencollab/arpack-ng/blob/master/COPYING)). Dynamically linked from a system installation; not redistributed by this crate.
## References
- ARPACK-NG: <https://github.com/opencollab/arpack-ng>