# SparseIR C-API
[](https://crates.io/crates/sparse-ir-capi)
[](https://docs.rs/sparse-ir-capi)
[](https://opensource.org/licenses/MIT)
This crate provides a C API for the SparseIR library.
### Language Support
- Fortran (via ISO_C_BINDING)
- Julia (via ccall)
- Python (via ctypes)
- C/C++
- Other languages that can call C ABIs
## Features
### Currently Implemented
See the header file for the complete API: [include/sparseir/sparseir.h](include/sparseir/sparseir.h)
### Sampling: Supported Type Patterns
The C-API provides `eval` (coefficients → values) and `fit` (values → coefficients) functions with different type combinations. The suffix indicates input/output types:
- `d` = double (f64, real)
- `z` = double complex (Complex64)
#### Evaluate Functions (Coefficients → Values)
| `spir_sampling_eval_dd` | ✅ | ❌ | ❌ |
| `spir_sampling_eval_dz` | ❌ | ✅ | ✅ |
| `spir_sampling_eval_zz` | ✅ | ✅ | ✅* |
#### Fit Functions (Values → Coefficients)
| `spir_sampling_fit_dd` | ✅ | ❌ | ❌ |
| `spir_sampling_fit_zd` | ❌ | ✅* | ✅ |
| `spir_sampling_fit_zz` | ✅ | ✅ | ✅** |
\* For Matsubara (full), `fit_zd` internally fits complex coefficients and returns their real parts. This is physically correct for Green's functions where IR coefficients are guaranteed to be real by symmetry.
\*\* For Matsubara (positive_only), `fit_zz` internally fits to real coefficients and converts to complex with zero imaginary parts. This is valid because IR coefficients are guaranteed to be real for physical Green's functions.
\* For Matsubara (positive_only), `eval_zz` extracts real parts from input coefficients and evaluates. This is valid because IR coefficients are guaranteed to be real for physical Green's functions.
#### Notes
- **Tau sampling**: Uses real transformation matrix. Supports `dd` for real data, `zz` for complex data (real/imag parts transformed independently).
- **Matsubara (full)**: Uses complex transformation matrix with both positive and negative frequencies. Natural type is `zz`. The `dz` evaluate is supported for real coefficients (physically guaranteed for Green's functions).
- **Matsubara (positive_only)**: Uses only positive frequencies with complex matrix but real coefficients. Natural types are `dz` (evaluate) and `zd` (fit). Also supports `zz` variants by extracting/adding zero imaginary parts.
### Error Handling
All C-API functions use `catch_unwind()` to prevent panics from crossing the FFI boundary:
- Returns error codes instead of panicking
- Process remains stable even on internal errors
- Safe for production use
## Building
```bash
# Build shared library (.dylib on macOS, .so on Linux, .dll on Windows)
# The C header is automatically generated by cbindgen during build
cargo build --release
# Run tests
cargo test
```
### Installation
Install the header and shared library to your system:
```bash
# Install cargo-c (first time only)
cargo install cargo-c
# Install header and shared library to system directories
cargo cinstall --release
# Or install to a custom prefix
cargo cinstall --release --prefix /custom/path
```
By default, `cargo cinstall` installs to:
- **Header**: `/usr/local/include/sparse_ir_capi/sparse_ir_capi.h` (Linux/macOS)
- **Library**: `/usr/local/lib/libsparse_ir_capi.so` (Linux) or `.dylib` (macOS)
- **Static library**: `/usr/local/lib/libsparse_ir_capi.a`
- **pkg-config**: `/usr/local/lib/pkgconfig/sparse_ir_capi.pc`
After installation, you can use pkg-config to find the library:
```bash
pkg-config --cflags --libs sparse-ir-capi
```
**Note on Header Files**:
The header file `include/sparseir/sparseir.h` is automatically generated by `cbindgen` during `cargo build` with C++ compatibility enabled (`--cpp-compat` flag). The header is used directly without post-processing.
The `Cargo.toml` is configured with `generation = false` so that `cargo cinstall` uses the header from `assets/sparse_ir_capi.h`. This file is a copy of `include/sparseir/sparseir.h` and is maintained in the repository (not generated by `build.rs` to avoid `cargo publish` issues).
**Do not manually edit** `include/sparseir/sparseir.h` - it is automatically generated and will be overwritten on the next build. When the header changes, update `assets/sparse_ir_capi.h` manually or via CI/CD.
### Header Generation
The C header (`include/sparseir/sparseir.h`) is **automatically generated** from Rust source code using [cbindgen](https://github.com/mozilla/cbindgen):
- **Build time**: Header is regenerated automatically when Rust sources change
- **Manual regeneration**: `cargo build` (header is created by `build.rs`)
- **Configuration**: See `cbindgen.toml` for generation settings
**Do not edit the generated header manually** - edit the Rust source code instead!
## Usage Examples
### Julia
```julia
# Load library
const lib = "../target/release/libsparse_ir_capi.dylib"
# Create kernel
kernel_ptr = Ref{Ptr{Cvoid}}()
status = ccall((:spir_logistic_kernel_new, lib),
Int32, (Float64, Ref{Ptr{Cvoid}}),
10.0, kernel_ptr)
# Compute kernel value
result = Ref{Float64}()
status = ccall((:spir_kernel_compute, lib),
Int32, (Ptr{Cvoid}, Float64, Float64, Ref{Float64}),
kernel_ptr[], 0.5, 0.5, result)
println("K(0.5, 0.5) = ", result[])
# Release
ccall((:spir_kernel_release, lib), Cvoid, (Ptr{Cvoid},), kernel_ptr[])
```
See `examples/test_julia.jl` for a complete example.
### C
```c
#include "sparseir/sparseir.h"
#include <stdio.h>
int main() {
// libsparseir compatible API
int status;
spir_kernel* kernel = spir_logistic_kernel_new(10.0, &status);
if (kernel == NULL || status != SPIR_COMPUTATION_SUCCESS) {
fprintf(stderr, "Failed to create kernel: status = %d\n", status);
return 1;
}
double result;
status = spir_kernel_compute(kernel, 0.5, 0.5, &result);
printf("K(0.5, 0.5) = %f\n", result);
spir_kernel_release(kernel);
return 0;
}
```
## Testing
Run the Julia example:
```bash
cd examples
julia test_julia.jl
```
## Memory Management
All objects returned by `*_new()` functions **must** be released with their corresponding `*_release()` function:
- `spir_kernel_release()`
- (more to come: `spir_basis_release()`, etc.)
All objects are immutable and thread-safe.
## License
This crate is dual-licensed under the terms of the MIT license and the Apache License (Version 2.0).
- You may use this crate under the terms of either license, at your option:
- [MIT License](../LICENSE)
- [Apache License 2.0](../LICENSE-APACHE)