Skip to main content

libsvm_rs/
types.rs

1/// Type of SVM formulation.
2///
3/// Matches the integer constants in the original LIBSVM (`svm.h`):
4/// `C_SVC=0, NU_SVC=1, ONE_CLASS=2, EPSILON_SVR=3, NU_SVR=4`.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
6#[repr(i32)]
7pub enum SvmType {
8    /// C-Support Vector Classification.
9    CSvc = 0,
10    /// ν-Support Vector Classification.
11    NuSvc = 1,
12    /// One-class SVM (distribution estimation / novelty detection).
13    OneClass = 2,
14    /// ε-Support Vector Regression.
15    EpsilonSvr = 3,
16    /// ν-Support Vector Regression.
17    NuSvr = 4,
18}
19
20/// Type of kernel function.
21///
22/// Matches the integer constants in the original LIBSVM (`svm.h`):
23/// `LINEAR=0, POLY=1, RBF=2, SIGMOID=3, PRECOMPUTED=4`.
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
25#[repr(i32)]
26pub enum KernelType {
27    /// `K(x,y) = x·y`
28    Linear = 0,
29    /// `K(x,y) = (γ·x·y + coef0)^degree`
30    Polynomial = 1,
31    /// `K(x,y) = exp(-γ·‖x-y‖²)`
32    Rbf = 2,
33    /// `K(x,y) = tanh(γ·x·y + coef0)`
34    Sigmoid = 3,
35    /// Kernel values supplied as a precomputed matrix.
36    Precomputed = 4,
37}
38
39/// A single sparse feature: `index:value`.
40///
41/// In the original LIBSVM, a sentinel node with `index = -1` marks the end
42/// of each instance. In this Rust port, instance length is tracked by
43/// `Vec::len()` instead, so no sentinel is needed.
44#[derive(Debug, Clone, Copy, PartialEq)]
45pub struct SvmNode {
46    /// 1-based feature index. Uses `i32` to match the original C `int` and
47    /// preserve file-format compatibility.
48    pub index: i32,
49    /// Feature value.
50    pub value: f64,
51}
52
53/// A training/test problem: a collection of labelled sparse instances.
54#[derive(Debug, Clone, PartialEq)]
55pub struct SvmProblem {
56    /// Label (class for classification, target for regression) per instance.
57    pub labels: Vec<f64>,
58    /// Sparse feature vectors, one per instance.
59    pub instances: Vec<Vec<SvmNode>>,
60}
61
62/// SVM parameters controlling the formulation, kernel, and solver.
63///
64/// Default values match the original LIBSVM defaults.
65#[derive(Debug, Clone, PartialEq)]
66pub struct SvmParameter {
67    /// SVM formulation type.
68    pub svm_type: SvmType,
69    /// Kernel function type.
70    pub kernel_type: KernelType,
71    /// Degree for polynomial kernel.
72    pub degree: i32,
73    /// γ parameter for RBF, polynomial, and sigmoid kernels.
74    /// Set to `1/num_features` when 0.
75    pub gamma: f64,
76    /// Independent term in polynomial and sigmoid kernels.
77    pub coef0: f64,
78    /// Cache memory size in MB.
79    pub cache_size: f64,
80    /// Stopping tolerance for the solver.
81    pub eps: f64,
82    /// Cost parameter C (for C-SVC, ε-SVR, ν-SVR).
83    pub c: f64,
84    /// Per-class weight overrides: `(class_label, weight)` pairs.
85    pub weight: Vec<(i32, f64)>,
86    /// ν parameter (for ν-SVC, one-class SVM, ν-SVR).
87    pub nu: f64,
88    /// ε in the ε-insensitive loss function (ε-SVR).
89    pub p: f64,
90    /// Whether to use the shrinking heuristic.
91    pub shrinking: bool,
92    /// Whether to train for probability estimates.
93    pub probability: bool,
94}
95
96impl Default for SvmParameter {
97    fn default() -> Self {
98        Self {
99            svm_type: SvmType::CSvc,
100            kernel_type: KernelType::Rbf,
101            degree: 3,
102            gamma: 0.0, // means 1/num_features
103            coef0: 0.0,
104            cache_size: 100.0,
105            eps: 0.001,
106            c: 1.0,
107            weight: Vec::new(),
108            nu: 0.5,
109            p: 0.1,
110            shrinking: true,
111            probability: false,
112        }
113    }
114}
115
116/// A trained SVM model.
117///
118/// Produced by training, or loaded from a LIBSVM model file.
119#[derive(Debug, Clone, PartialEq)]
120pub struct SvmModel {
121    /// Parameters used during training.
122    pub param: SvmParameter,
123    /// Number of classes (2 for binary, >2 for multiclass, 2 for regression).
124    pub nr_class: usize,
125    /// Support vectors (sparse feature vectors).
126    pub sv: Vec<Vec<SvmNode>>,
127    /// Support vector coefficients. For k classes, this is a
128    /// `(k-1) × num_sv` matrix stored as `Vec<Vec<f64>>`.
129    pub sv_coef: Vec<Vec<f64>>,
130    /// Bias terms (rho). One per class pair: `k*(k-1)/2` values.
131    pub rho: Vec<f64>,
132    /// Pairwise probability parameter A (Platt scaling). Empty if not trained
133    /// with probability estimates.
134    pub prob_a: Vec<f64>,
135    /// Pairwise probability parameter B (Platt scaling). Empty if not trained
136    /// with probability estimates.
137    pub prob_b: Vec<f64>,
138    /// Probability density marks (for one-class SVM).
139    pub prob_density_marks: Vec<f64>,
140    /// Original indices of support vectors in the training set (1-based).
141    pub sv_indices: Vec<usize>,
142    /// Class labels (in the order used internally).
143    pub label: Vec<i32>,
144    /// Number of support vectors per class.
145    pub n_sv: Vec<usize>,
146}