extern crate amd;
fn main() {
let n: usize = 24;
let a_p = vec![
0, 9, 15, 21, 27, 33, 39, 48, 57, 61, 70, 76, 82, 88, 94, 100, 106, 110, 119, 128, 137,
143, 152, 156, 160,
];
let a_i = vec![
0, 5, 6, 12, 13, 17, 18, 19, 21, 1, 8, 9, 13, 14, 17, 2, 6, 11, 20, 21, 22, 3, 7, 10, 15, 18, 19, 4, 7, 9, 14, 15, 16, 0, 5, 6, 12, 13, 17, 0, 2, 5, 6, 11, 12, 19, 21, 23, 3, 4, 7, 9, 14, 15, 16, 17, 18, 1, 8, 9, 14, 1, 4, 7, 8, 9, 13, 14, 17, 18, 3, 10, 18, 19, 20, 21, 2, 6, 11, 12, 21, 23, 0, 5, 6, 11, 12, 23, 0, 1, 5, 9, 13, 17, 1, 4, 7, 8, 9, 14, 3, 4, 7, 15, 16, 18, 4, 7, 15, 16, 0, 1, 5, 7, 9, 13, 17, 18, 19, 0, 3, 7, 9, 10, 15, 17, 18, 19, 0, 3, 6, 10, 17, 18, 19, 20, 21, 2, 10, 19, 20, 21, 22, 0, 2, 6, 10, 11, 19, 20, 21, 22, 2, 20, 21, 22, 6, 11, 12, 23, ];
let mut p_inv = vec![0; 24];
let control = amd::Control::default();
let mut a = [[""; 24]; 24];
println!("AMD demo, with the 24-by-24 Harwell/Boeing matrix, can_24:");
amd::control(&control);
let nz = a_p[n];
println!(
"\nInput matrix: {}-by-{}, with {} entries.
Note that for a symmetric matrix such as this one, only the
strictly lower or upper triangular parts would need to be
passed to AMD, since AMD computes the ordering of A+A'. The
diagonal entries are also not needed, since AMD ignores them.",
n, n, nz
);
for j in 0..n {
print!(
"\nColumn: {}, number of entries: {}, with row indices in
Ai [{} ... {}]:
row indices:",
j,
a_p[j + 1] - a_p[j],
a_p[j],
a_p[j + 1] - 1
);
for pj in a_p[j]..a_p[j + 1] {
let i = a_i[pj as usize];
print!(" {}", i);
}
println!();
}
println!("\nPlot of input matrix pattern:");
for j in 0..n {
for i in 0..n {
a[i][j] = "."
}
for pj in a_p[j]..a_p[j + 1] {
let i = a_i[pj as usize] as usize;
a[i][j] = "X";
}
}
print!(" ");
for j in 0..n {
print!(" {}", j % 10);
}
println!();
for i in 0..n {
print!("{}: ", i);
for j in 0..n {
print!(" {}", a[i][j]);
}
println!();
}
let (p, _p_inv, info) = amd::order(n, &a_p, &a_i, &control).unwrap();
println!(
"return value from amd::order: {:?} (should be {:?})",
info.status,
amd::Status::OK
);
amd::info(&info);
if info.status != amd::Status::OK {
println!("AMD failed");
return;
}
println!("Permutation vector:");
for k in 0..n {
let j = p[k];
p_inv[j as usize] = k;
print!(" {}", j);
}
println!();
println!();
println!("Inverse permutation vector:");
for j in 0..n {
let k = p_inv[j];
print!(" {}", k);
}
println!();
println!();
println!("\nPlot of permuted matrix pattern:");
for jnew in 0..n {
let j = p[jnew] as usize;
for inew in 0..n {
a[inew][jnew] = ".";
}
for pj in a_p[j]..a_p[j + 1] {
let i = a_i[pj as usize];
let inew = p_inv[i as usize] as usize;
a[inew][jnew] = "X";
}
}
print!(" ");
for j in 0..n {
print!(" {}", j % 10);
}
println!();
for i in 0..n {
print!("{}: ", i);
for j in 0..n {
print!(" {}", a[i][j]);
}
println!();
}
}