qfall_math/rational/mat_q/vector/
is_vector.rs

1// Copyright © 2023 Niklas Siemer
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module includes all functionality to check
10//! whether a matrix represents a vector, i.e. has only one row
11//! or one column.
12//! These methods should be used to ensure that vector functions
13//! can only be called on suitably formed vector/matrices.
14
15use super::super::MatQ;
16use crate::traits::MatrixDimensions;
17
18impl MatQ {
19    /// Returns `true` if the provided [`MatQ`] has only one row,
20    /// i.e. is a row vector. Otherwise, returns `false`.
21    ///
22    /// # Examples
23    /// ```
24    /// use qfall_math::rational::MatQ;
25    /// use std::str::FromStr;
26    ///
27    /// let row_vec = MatQ::from_str("[[1, 2, 3/2]]").unwrap();
28    /// let col_vec = MatQ::from_str("[[1/4],[2],[3]]").unwrap();
29    ///
30    /// assert!(row_vec.is_row_vector());
31    /// assert!(!col_vec.is_row_vector());
32    /// ```
33    pub fn is_row_vector(&self) -> bool {
34        self.get_num_rows() == 1
35    }
36
37    /// Returns `true` if the provided [`MatQ`] has only one column,
38    /// i.e. is a column vector. Otherwise, returns `false`.
39    ///
40    /// # Examples
41    /// ```
42    /// use qfall_math::rational::MatQ;
43    /// use std::str::FromStr;
44    ///
45    /// let row_vec = MatQ::from_str("[[1/1, 2, 3]]").unwrap();
46    /// let col_vec = MatQ::from_str("[[1],[2/3],[3]]").unwrap();
47    ///
48    /// assert!(col_vec.is_column_vector());
49    /// assert!(!row_vec.is_column_vector());
50    /// ```
51    pub fn is_column_vector(&self) -> bool {
52        self.get_num_columns() == 1
53    }
54
55    /// Returns `true` if the provided [`MatQ`] has only one column or one row,
56    /// i.e. is a vector. Otherwise, returns `false`.
57    ///
58    /// # Examples
59    /// ```
60    /// use qfall_math::rational::MatQ;
61    /// use std::str::FromStr;
62    ///
63    /// let row_vec = MatQ::from_str("[[1, 2/2, 3/1]]").unwrap();
64    /// let col_vec = MatQ::from_str("[[1],[2],[3/2]]").unwrap();
65    ///
66    /// assert!(row_vec.is_vector());
67    /// assert!(col_vec.is_vector());
68    /// ```
69    pub fn is_vector(&self) -> bool {
70        self.is_column_vector() || self.is_row_vector()
71    }
72
73    /// Returns `true` if the provided [`MatQ`] has only one entry,
74    /// i.e. is a 1x1 matrix. Otherwise, returns `false`.
75    ///
76    /// # Examples
77    /// ```
78    /// use qfall_math::rational::MatQ;
79    /// use std::str::FromStr;
80    ///
81    /// let vec = MatQ::from_str("[[1/2]]").unwrap();
82    ///
83    /// assert!(vec.has_single_entry());
84    /// ```
85    pub fn has_single_entry(&self) -> bool {
86        self.is_column_vector() && self.is_row_vector()
87    }
88}
89
90#[cfg(test)]
91mod test_is_vector {
92    use super::*;
93    use std::str::FromStr;
94
95    /// Check whether matrices with `1` row or one column
96    /// get recognized as (row or column) vectors
97    #[test]
98    fn vectors_detected() {
99        let row = MatQ::from_str(&format!("[[1/1, {}]]", i64::MIN)).unwrap();
100        let col = MatQ::from_str(&format!("[[1/1],[2/1],[{}/1],[4/1]]", i64::MAX)).unwrap();
101
102        assert!(row.is_row_vector());
103        assert!(!row.is_column_vector());
104        assert!(row.is_vector());
105
106        assert!(!col.is_row_vector());
107        assert!(col.is_column_vector());
108        assert!(col.is_vector());
109    }
110
111    /// Check whether matrices with more than one row or column
112    /// don't get recognized as (row or column) vector
113    #[test]
114    fn non_vectors_detected() {
115        let mat_1 = MatQ::from_str(&format!("[[1, {}/1],[2, 3]]", i64::MIN)).unwrap();
116        let mat_2 = MatQ::from_str(&format!("[[1, {}, 3/3],[4/1, 5/1, 6/1]]", i64::MAX)).unwrap();
117        let mat_3 =
118            MatQ::from_str(&format!("[[1/1, {}/1],[2/1, 3/1],[4/1, 5/1]]", i64::MIN)).unwrap();
119        let mat_4 = MatQ::from_str("[[1/1, 0],[2, 0],[4, 0]]").unwrap();
120        let mat_5 = MatQ::from_str("[[1, 2/1, 4],[0, 0, 0]]").unwrap();
121
122        assert!(!mat_1.is_column_vector());
123        assert!(!mat_1.is_row_vector());
124        assert!(!mat_1.is_vector());
125
126        assert!(!mat_2.is_column_vector());
127        assert!(!mat_2.is_row_vector());
128        assert!(!mat_2.is_vector());
129
130        assert!(!mat_3.is_column_vector());
131        assert!(!mat_3.is_row_vector());
132        assert!(!mat_3.is_vector());
133
134        assert!(!mat_4.is_column_vector());
135        assert!(!mat_4.is_row_vector());
136        assert!(!mat_4.is_vector());
137
138        assert!(!mat_5.is_column_vector());
139        assert!(!mat_5.is_row_vector());
140        assert!(!mat_5.is_vector());
141    }
142
143    /// Check whether matrices with only one entry get recognized as single entry matrices
144    #[test]
145    fn single_entry_detected() {
146        let small = MatQ::from_str("[[1]]").unwrap();
147        let large = MatQ::from_str(&format!("[[{}/1]]", i64::MIN)).unwrap();
148
149        // check whether single entry is correctly detected
150        assert!(small.has_single_entry());
151        assert!(large.has_single_entry());
152
153        // check whether single entry is correctly detected as row and column vector
154        assert!(small.is_row_vector());
155        assert!(small.is_column_vector());
156        assert!(small.is_vector());
157
158        assert!(large.is_row_vector());
159        assert!(large.is_column_vector());
160        assert!(large.is_vector());
161    }
162
163    /// Check whether matrices with more than one entry
164    /// don't get recognized as single entry matrices
165    #[test]
166    fn non_single_entry_detected() {
167        let row = MatQ::from_str(&format!("[[1, {}]]", i64::MIN)).unwrap();
168        let col = MatQ::from_str(&format!("[[1],[{}],[3/1]]", i64::MIN)).unwrap();
169        let mat = MatQ::from_str("[[1/1, 2],[3, 4],[5, 6]]").unwrap();
170
171        assert!(!row.has_single_entry());
172        assert!(!col.has_single_entry());
173        assert!(!mat.has_single_entry());
174    }
175}