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
extern crate libc;
extern crate matrix;
extern crate superlu_sys as ffi;
use matrix::format::Compressed;
use std::mem;
pub struct SuperMatrix {
raw: ffi::SuperMatrix,
}
pub trait FromSuperMatrix: Sized {
fn from_super_matrix(&SuperMatrix) -> Option<Self>;
}
impl SuperMatrix {
pub unsafe fn from_raw(raw: ffi::SuperMatrix) -> SuperMatrix {
SuperMatrix { raw: raw }
}
pub fn into_raw(self) -> ffi::SuperMatrix {
let raw = self.raw;
mem::forget(self);
raw
}
}
impl Drop for SuperMatrix {
fn drop(&mut self) {
match self.raw.Stype {
ffi::Stype_t::SLU_NC => unsafe {
ffi::Destroy_CompCol_Matrix(&mut self.raw);
},
ffi::Stype_t::SLU_NCP => unsafe {
ffi::Destroy_CompCol_Permuted(&mut self.raw);
},
ffi::Stype_t::SLU_NR => unsafe {
ffi::Destroy_CompRow_Matrix(&mut self.raw);
},
ffi::Stype_t::SLU_SC | ffi::Stype_t::SLU_SCP | ffi::Stype_t::SLU_SR => unsafe {
ffi::Destroy_SuperNode_Matrix(&mut self.raw);
},
ffi::Stype_t::SLU_DN => unsafe {
ffi::Destroy_Dense_Matrix(&mut self.raw);
},
_ => {},
}
}
}
impl FromSuperMatrix for Compressed<f64> {
fn from_super_matrix(matrix: &SuperMatrix) -> Option<Compressed<f64>> {
use matrix::format::compressed::Variant;
let raw = &matrix.raw;
let rows = raw.nrow as usize;
let columns = raw.ncol as usize;
match (raw.Stype, raw.Dtype, raw.Mtype) {
(ffi::Stype_t::SLU_NC, ffi::Dtype_t::SLU_D, ffi::Mtype_t::SLU_GE) => unsafe {
let store = &*(raw.Store as *const ffi::NCformat);
let nonzeros = store.nnz as usize;
let mut values = Vec::with_capacity(nonzeros);
let mut indices = Vec::with_capacity(nonzeros);
let mut offsets = Vec::with_capacity(columns + 1);
for i in 0..nonzeros {
values.push(*(store.nzval as *const libc::c_double).offset(i as isize));
indices.push(*store.rowind.offset(i as isize) as usize);
}
for i in 0..(columns + 1) {
offsets.push(*store.colptr.offset(i as isize) as usize);
}
Some(Compressed {
rows: rows,
columns: columns,
nonzeros: nonzeros,
variant: Variant::Column,
values: values,
indices: indices,
offsets: offsets,
})
},
(ffi::Stype_t::SLU_NC, ffi::Dtype_t::SLU_D, _) => unimplemented!(),
(ffi::Stype_t::SLU_NCP, ffi::Dtype_t::SLU_D, _) => unimplemented!(),
_ => return None,
}
}
}