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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
use array_init::array_init;
pub struct Control {
pub prl: i32, /* print level */
pub dense_row: f64, /* dense row parameter */
pub dense_col: f64, /* dense col parameter */
pub pivot_tolerance: f64, /* threshold partial pivoting setting */
pub block_size: i32, /* BLAS-3 block size */
pub strategy: Strategy, /* umfpack strategy */
pub alloc_init: f64, /* initial allocation ratio */
pub irstep: i32, /* max # of iterative refinements */
pub compiled_with_blas: bool, /* uses the BLAS */
pub strategy_thresh_sym: f64, /* symmetry threshold */
pub ordering: Ordering, /* ordering method to use */
pub singletons: bool, /* singleton filter if true */
pub strategy_thresh_nnzdiag: f64, /* nnz(diag(A)) threshold */
pub fixq: FixQ, /* fixq */
pub amd_dense: f64, /* for AMD ordering */
pub sym_pivot_tolerance: f64, /* threshold, only for diag. entries */
pub scale: Scale, /* what row scaling to do */
pub front_alloc_init: f64, /* frontal matrix allocation ratio */
pub droptol: i32, /* drop tolerance for entries in L,U */
pub aggressive: bool, /* whether or not to use aggressive */
}
impl Control {
pub fn new() -> Self {
return Self {
prl: 1,
dense_row: 0.2,
dense_col: 0.2,
pivot_tolerance: 0.1,
block_size: 32,
strategy: Strategy::AUTO,
alloc_init: 0.7,
irstep: 2,
compiled_with_blas: true,
strategy_thresh_sym: 0.3,
ordering: Ordering::AMD,
singletons: true,
strategy_thresh_nnzdiag: 0.9,
fixq: FixQ::DEFAULT,
amd_dense: 10.0,
sym_pivot_tolerance: 0.001,
scale: Scale::SUM,
front_alloc_init: 0.5,
droptol: 0,
aggressive: true,
};
}
pub fn data(&self) -> [f64; 20] {
let mut data: [f64; 20] = array_init(|_| 0.0);
data[0] = self.prl as f64;
data[1] = self.dense_row as f64;
data[2] = self.dense_col as f64;
data[3] = self.pivot_tolerance as f64;
data[4] = self.block_size as f64;
data[5] = self.strategy.to_int() as f64;
data[6] = self.alloc_init as f64;
data[7] = self.irstep as f64;
data[8] = self.compiled_with_blas as i32 as f64;
data[9] = self.strategy_thresh_sym as f64;
data[10] = self.ordering.to_int() as f64;
data[11] = self.singletons as i32 as f64;
data[12] = self.strategy_thresh_nnzdiag as f64;
data[13] = self.fixq.to_int() as f64;
data[14] = self.amd_dense as f64;
data[15] = self.sym_pivot_tolerance as f64;
data[16] = self.scale.to_int() as f64;
data[17] = self.front_alloc_init as f64;
data[18] = self.droptol as f64;
data[19] = self.aggressive as i32 as f64;
return data;
}
}
#[allow(non_camel_case_types)]
pub enum FixQ {
NOFIXQ,
DEFAULT,
FIXQ,
}
impl FixQ {
pub fn to_int(&self) -> i32 {
match self {
FixQ::NOFIXQ => -1,
FixQ::DEFAULT => 0,
FixQ::FIXQ => 1,
}
}
}
#[allow(non_camel_case_types)]
pub enum Strategy {
THRESH_SYM, /* symmetry threshold */
THRESH_NNZDIAG, /* nnz(diag(A)) threshold */
AUTO, /* use sym. or unsym. strategy */
UNSYMMETRIC, /* COLAMD(A) coletree postorder */
OBSOLETE, /* 2-by-2 is no longer available */
SYMMETRIC, /* AMD(A+A') no coletree postorder */
}
impl Strategy {
pub fn to_int(&self) -> i32 {
match self {
Strategy::THRESH_SYM => 9,
Strategy::THRESH_NNZDIAG => 12,
Strategy::AUTO => 0,
Strategy::UNSYMMETRIC => 1,
Strategy::OBSOLETE => 2,
Strategy::SYMMETRIC => 3,
}
}
}
pub enum Scale {
NONE, /* no scaling */
SUM, /* default: divide each row by sum (abs (row))*/
MAX, /* divide each row by max (abs (row)) */
}
#[allow(non_camel_case_types)]
impl Scale {
pub fn to_int(&self) -> i32 {
match self {
Scale::NONE => 0,
Scale::SUM => 1,
Scale::MAX => 2,
}
}
}
#[allow(non_camel_case_types)]
pub enum Ordering {
CHOLMOD, /* use CHOLMOD (AMD,/COLAMD then METIS)*/
AMD, /* use AMD,/COLAMD */
GIVEN, /* user-provided Qinit */
METIS, /* use METIS */
BEST, /* try many orderings pick best */
NONE, /* natural ordering */
USER, /* user-provided function */
METIS_GUARD, /* Use METIS AMD, or COLAMD.*/
}
impl Ordering {
pub fn to_int(&self) -> i32 {
match self {
Ordering::CHOLMOD => 0,
Ordering::AMD => 1,
Ordering::GIVEN => 2,
Ordering::METIS => 3,
Ordering::BEST => 4,
Ordering::NONE => 5,
Ordering::USER => 6,
Ordering::METIS_GUARD => 7,
}
}
}