opensrdk_linear_algebra/matrix/bd/
mod.rs1use crate::{number::Number, Matrix, MatrixError};
2use rayon::prelude::*;
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, Default, PartialEq, Hash, Serialize, Deserialize)]
6pub struct BidiagonalMatrix<T = f64>
7where
8 T: Number,
9{
10 d: Vec<T>,
11 e: Vec<T>,
12}
13
14impl<T> BidiagonalMatrix<T>
15where
16 T: Number,
17{
18 pub fn new(dim: usize) -> Self {
19 Self {
20 d: vec![T::default(); dim],
21 e: vec![T::default(); dim.max(1) - 1],
22 }
23 }
24
25 pub fn from(d: Vec<T>, e: Vec<T>) -> Result<Self, MatrixError> {
28 if d.len().max(1) - 1 != e.len() {
29 return Err(MatrixError::DimensionMismatch);
30 }
31
32 Ok(Self { d, e })
33 }
34
35 pub fn dim(&self) -> usize {
37 self.d.len()
38 }
39
40 pub fn d(&self) -> &[T] {
42 &self.d
43 }
44
45 pub fn e(&self) -> &[T] {
47 &self.e
48 }
49
50 pub fn eject(self) -> (Vec<T>, Vec<T>) {
52 (self.d, self.e)
53 }
54
55 pub fn mat(&self, upper: bool) -> Matrix<T> {
56 let n = self.d.len();
57 let mut mat = Matrix::new(n, n);
58
59 mat.elems_mut()
74 .par_iter_mut()
75 .enumerate()
76 .map(|(k, elem)| ((k / n, k % n), elem))
77 .for_each(|((i, j), elem)| {
78 if i == j {
79 *elem = self.d[i];
80 } else if i + 1 == j && upper {
81 *elem = self.e[i];
82 } else if i == j + 1 && !upper {
83 *elem = self.e[j];
84 }
85 });
86
87 mat
88 }
89}