# arpack-rs
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:
| `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
```toml
[dependencies]
arpack = "0.0.2"
```
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.)
## Current limitations
The safe wrapper currently exposes only the smallest eigenpair (`nev = 1`) with a fixed `which` selector — `"SA"` (smallest algebraic) for the real-symmetric Lanczos driver, `"SR"` (smallest real part) for the complex Arnoldi driver. Multi-eigenvalue extraction (`nev > 1`) and a configurable `which` selector are tracked at <https://github.com/ultimatile/arpack-rs/issues/1>.
## 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>