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
use format::compressed::Variant; use format::{Conventional, Compressed, Diagonal}; use {Element, Size}; impl<'l, T: Element> From<&'l Conventional<T>> for Compressed<T> { fn from(conventional: &'l Conventional<T>) -> Self { let (rows, columns) = conventional.dimensions(); let mut matrix = Compressed::new((rows, columns), Variant::Column); for (k, &value) in conventional.values.iter().enumerate() { if !value.is_zero() { matrix.set((k % rows, k / rows), value); } } matrix } } impl<T: Element> From<Conventional<T>> for Compressed<T> { #[inline] fn from(matrix: Conventional<T>) -> Self { (&matrix).into() } } impl<'l, T: Element> From<&'l Compressed<T>> for Conventional<T> { fn from(matrix: &'l Compressed<T>) -> Self { let &Compressed { rows, columns, variant, ref values, ref indices, ref offsets, .. } = validate!(matrix); let mut matrix = Conventional::new((rows, columns)); match variant { Variant::Row => for i in 0..rows { for k in offsets[i]..offsets[i + 1] { matrix.values[indices[k] * rows + i] = values[k]; } }, Variant::Column => for j in 0..columns { for k in offsets[j]..offsets[j + 1] { matrix.values[j * rows + indices[k]] = values[k]; } }, } matrix } } impl<T: Element> From<Compressed<T>> for Conventional<T> { #[inline] fn from(matrix: Compressed<T>) -> Self { (&matrix).into() } } impl<'l, T: Element> From<&'l Diagonal<T>> for Compressed<T> { #[inline] fn from(matrix: &'l Diagonal<T>) -> Self { matrix.clone().into() } } impl<T: Element> From<Diagonal<T>> for Compressed<T> { fn from(matrix: Diagonal<T>) -> Self { let Diagonal { rows, columns, values } = validate!(matrix); let nonzeros = values.len(); let indices = (0..nonzeros).collect(); let offsets = (0..(columns + 1)).map(|i| { if i < nonzeros { i } else { nonzeros } }).collect(); new!(rows, columns, nonzeros, Variant::Column, values, indices, offsets) } } #[cfg(test)] mod tests { use format::compressed::Variant; use prelude::*; #[test] fn from_conventional() { let matrix = Conventional::from_vec((5, 3), matrix![ 0.0, 0.0, 0.0; 1.0, 0.0, 0.0; 0.0, 0.0, 0.0; 0.0, 2.0, 0.0; 0.0, 3.0, 4.0; ]); let matrix = Compressed::from(matrix); assert_eq!(matrix, new!(5, 3, 4, Variant::Column, vec![1.0, 2.0, 3.0, 4.0], vec![1, 3, 4, 4], vec![0, 1, 3, 4])); } #[test] fn from_diagonal_tall() { let matrix = Compressed::from(Diagonal::from_vec((5, 3), vec![1.0, 2.0, 0.0])); assert_eq!(matrix, new!(5, 3, 3, Variant::Column, vec![1.0, 2.0, 0.0], vec![0, 1, 2], vec![0, 1, 2, 3])); } #[test] fn from_diagonal_wide() { let matrix = Compressed::from(Diagonal::from_vec((3, 5), vec![1.0, 0.0, 3.0])); assert_eq!(matrix, new!(3, 5, 3, Variant::Column, vec![1.0, 0.0, 3.0], vec![0, 1, 2], vec![0, 1, 2, 3, 3, 3])); } #[test] fn into_conventional() { let matrix = new!(5, 3, 3, Variant::Column, vec![1.0, 2.0, 3.0], vec![0, 1, 2], vec![0, 1, 2, 3]); let matrix = Conventional::from(matrix); assert_eq!(&*matrix, &*matrix![ 1.0, 0.0, 0.0; 0.0, 2.0, 0.0; 0.0, 0.0, 3.0; 0.0, 0.0, 0.0; 0.0, 0.0, 0.0; ]); } }