use crate::algebra::{
    abstr::{Field, Scalar},
    linear::matrix::General,
};
use rand::random;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// Upper triangular matrix
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
pub struct UpperTriangular<T> {
    pub(crate) matrix: General<T>,
}

impl<T> UpperTriangular<T>
where
    T: Field + Scalar,
{
    pub fn new(matrix: General<T>) -> UpperTriangular<T> {
        UpperTriangular { matrix }
    }

    pub fn dim(&self) -> (usize, usize) {
        self.matrix.dim()
    }

    pub fn new_random(m: usize) -> UpperTriangular<T> {
        let mut g = General::zero(m, m);

        for i in 0..m {
            for j in i..m {
                g[[i, j]] = T::from_f64(random());
            }
        }

        UpperTriangular { matrix: g }
    }
}
