1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
//! [![Latest Version]][crates.io]
//! [![Rust](https://github.com/ralfbiedert/ffsvm-rust/actions/workflows/rust.yml/badge.svg?branch=master)](https://github.com/ralfbiedert/ffsvm-rust/actions/workflows/rust.yml)
//! [![deps.svg]][deps]
//! [![docs]][docs.rs]
//! ![MIT]
//!
//! # In One Sentence
//!
//! You trained a SVM using [libSVM](https://github.com/cjlin1/libsvm), now you want the highest possible performance during (real-time) classification, like games or VR.
//!
//!
//! # Highlights
//!
//! * loads almost all [libSVM](https://github.com/cjlin1/libsvm) types (C-SVC, ν-SVC, ε-SVR, ν-SVR) and kernels (linear, poly, RBF and sigmoid)
//! * produces practically same classification results as libSVM
//! * optimized for [SIMD](https://github.com/rust-lang/rfcs/pull/2366) and can be mixed seamlessly with [Rayon](https://github.com/rayon-rs/rayon)
//! * written in 100% Rust
//! * allocation-free during classification for dense SVMs
//! * **2.5x - 14x faster than libSVM for dense SVMs**
//! * extremely low classification times for small models (e.g., 128 SV, 16 dense attributes, linear ~ 500ns)
//! * successfully used in **Unity and VR** projects (Windows & Android)
//!
//!
//! Note: Currently **requires Rust nightly** (March 2019 and later), because we depend on RFC 2366 (portable SIMD). Once that stabilizes we'll also go stable.
//!
//!
//! # Usage
//!
//! Train with [libSVM](https://github.com/cjlin1/libsvm) (e.g., using the tool `svm-train`), then classify with `ffsvm-rust`.
//!
//! From Rust:
//!
//! ```rust
//! # use std::convert::TryFrom;
//! # use ffsvm::{DenseSVM, Predict, Problem, SAMPLE_MODEL, Solution};
//! # fn main() -> Result<(), ffsvm::Error> {
//! // Replace `SAMPLE_MODEL` with a `&str` to your model.
//! let svm = DenseSVM::try_from(SAMPLE_MODEL)?;
//!
//! let mut problem = Problem::from(&svm);
//! let features = problem.features();
//!
//! features[0] = 0.55838;
//! features[1] = -0.157895;
//! features[2] = 0.581292;
//! features[3] = -0.221184;
//!
//! svm.predict_value(&mut problem)?;
//!
//! assert_eq!(problem.solution(), Solution::Label(42));
//! # Ok(())
//! # }
//!
//! ```
//!
//! # Status
//! * **March 10, 2023**: Reactivated for latest Rust nightly.
//! * **June 7, 2019**: Gave up on 'no `unsafe`', but gained runtime SIMD selection.
//! * **March 10, 2019**: As soon as we can move away from nightly we'll go beta.
//! * **Aug 5, 2018**: Still in alpha, but finally on crates.io.
//! * **May 27, 2018**: We're in alpha. Successfully used internally on Windows, Mac, Android and Linux
//! on various machines and devices. Once SIMD stabilizes and we can cross-compile to WASM
//! we'll move to beta.
//! * **December 16, 2017**: We're in pre-alpha. It will probably not even work on your machine.
//!
//!
//! # Performance
//!
//! ![performance](https://raw.githubusercontent.com/ralfbiedert/ffsvm-rust/master/docs/performance_relative.v3.png)
//!
//! All performance numbers reported for the `DenseSVM`. We also have support for `SparseSVM`s, which are slower for "mostly dense" models, and faster for "mostly sparse" models (and generally on the performance level of libSVM).
//!
//! [See here for details.](https://github.com/ralfbiedert/ffsvm-rust/blob/master/docs/performance.md)
//!
//!
//! ### Tips
//!
//! * For an x-fold performance increase, create a number of `Problem` structures, and process them with [Rayon's](https://docs.rs/rayon/1.0.3/rayon/) `par_iter`.
//!
//!
//! # FAQ
//!
//! [See here for details.](https://github.com/ralfbiedert/ffsvm-rust/blob/master/docs/FAQ.md)
//!
//! [Latest Version]: https://img.shields.io/crates/v/ffsvm.svg
//! [crates.io]: https://crates.io/crates/ffsvm
//! [MIT]: https://img.shields.io/badge/license-MIT-blue.svg
//! [docs]: https://docs.rs/ffsvm/badge.svg
//! [docs.rs]: https://docs.rs/ffsvm/
//! [deps]: https://deps.rs/repo/github/ralfbiedert/ffsvm-rust
//! [deps.svg]: https://deps.rs/repo/github/ralfbiedert/ffsvm-rust/status.svg
#![feature(portable_simd)]
#![warn(clippy::all)] // Enable ALL the warnings ...
#![warn(clippy::nursery)]
#![warn(clippy::pedantic)]
#![warn(clippy::cargo)]
#![allow(clippy::cast_possible_truncation)] // All our casts are in a range where this doesn't matter.
#![allow(clippy::cast_precision_loss)]
#![allow(clippy::cast_possible_wrap)]
#![allow(clippy::module_name_repetitions)] // We do that way too often
#![allow(clippy::doc_markdown)] // Mainly for `libSVM` in the docs.
mod errors;
mod parser;
mod sparse;
mod svm;
mod util;
mod vectors;
// Set float types to largest width we support instructions sets
// (important to make sure we get max alignment of target_feature) when selecting
// dynamically.
#[allow(non_camel_case_types)]
#[doc(hidden)]
pub type f32s = simd_aligned::arch::x256::f32s;
#[doc(hidden)]
#[allow(non_camel_case_types)]
pub type f64s = simd_aligned::arch::x256::f64s;
#[doc(hidden)]
pub static SAMPLE_MODEL: &str = include_str!("sample.model");
pub use crate::{
errors::Error,
parser::{Attribute, Header, ModelFile, SupportVector},
svm::{
kernel::{KernelDense, KernelSparse, Linear, Poly, Rbf, Sigmoid},
predict::Predict,
problem::{DenseProblem, Problem, Solution, SparseProblem},
DenseSVM, SVMType, SparseSVM,
},
};